Skip to content

Commit

Permalink
fix: ensure mouse events are blocked for disabled components in Firef…
Browse files Browse the repository at this point in the history
…ox (#7107)

**Related Issue:** #7043

## Summary

This applies a workaround for Firefox not firing capture events before
non-capture ones to block mouse events when components are disabled.

### Notable changes

* added `connectInteractive`/`disconnectInteractive` utils, solely to
support Firefox
* moved user agent utils to `browser.ts`

### Additional info

* [Firefox recently fixed
this](https://bugzilla.mozilla.org/show_bug.cgi?id=1731504) to follow
the spec and it should ship in version 116.
* https://wpt.live/dom/events/EventTarget-dispatchEvent.html is the
relevant web platform test.
*
https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#useCapture
👇

> Note: For event listeners attached to the event target, the event is
in the target phase, rather than the capturing and bubbling phases.
Event listeners in the capturing phase are called before event listeners
in any non-capturing phases.
  • Loading branch information
jcfranco authored Jun 16, 2023
1 parent 91cd4e3 commit 271d985
Show file tree
Hide file tree
Showing 47 changed files with 520 additions and 89 deletions.
9 changes: 8 additions & 1 deletion packages/calcite-components/src/components/action/action.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ import {
} from "@stencil/core";
import { toAriaBoolean } from "../../utils/dom";
import { guid } from "../../utils/guid";
import { InteractiveComponent, updateHostInteraction } from "../../utils/interactive";
import {
connectInteractive,
disconnectInteractive,
InteractiveComponent,
updateHostInteraction
} from "../../utils/interactive";
import {
componentLoaded,
LoadableComponent,
Expand Down Expand Up @@ -163,6 +168,7 @@ export class Action
// --------------------------------------------------------------------------

connectedCallback(): void {
connectInteractive(this);
connectLocalized(this);
connectMessages(this);
this.mutationObserver?.observe(this.el, { childList: true, subtree: true });
Expand All @@ -180,6 +186,7 @@ export class Action
}

disconnectedCallback(): void {
disconnectInteractive(this);
disconnectLocalized(this);
disconnectMessages(this);
this.mutationObserver?.disconnect();
Expand Down
9 changes: 8 additions & 1 deletion packages/calcite-components/src/components/block/block.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ import {
} from "../../utils/conditionalSlot";
import { getSlotted, toAriaBoolean } from "../../utils/dom";
import { guid } from "../../utils/guid";
import { InteractiveComponent, updateHostInteraction } from "../../utils/interactive";
import {
connectInteractive,
disconnectInteractive,
InteractiveComponent,
updateHostInteraction
} from "../../utils/interactive";
import { connectLocalized, disconnectLocalized, LocalizedComponent } from "../../utils/locale";
import {
connectMessages,
Expand Down Expand Up @@ -143,11 +148,13 @@ export class Block

connectedCallback(): void {
connectConditionalSlotComponent(this);
connectInteractive(this);
connectLocalized(this);
connectMessages(this);
}

disconnectedCallback(): void {
disconnectInteractive(this);
disconnectLocalized(this);
disconnectMessages(this);
disconnectConditionalSlotComponent(this);
Expand Down
9 changes: 8 additions & 1 deletion packages/calcite-components/src/components/button/button.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { Build, Component, Element, h, Method, Prop, State, VNode, Watch } from "@stencil/core";
import { findAssociatedForm, FormOwner, resetForm, submitForm } from "../../utils/form";
import { InteractiveComponent, updateHostInteraction } from "../../utils/interactive";
import {
connectInteractive,
disconnectInteractive,
InteractiveComponent,
updateHostInteraction
} from "../../utils/interactive";
import { connectLabel, disconnectLabel, getLabelText, LabelableComponent } from "../../utils/label";
import {
componentLoaded,
Expand Down Expand Up @@ -175,6 +180,7 @@ export class Button
//--------------------------------------------------------------------------

async connectedCallback(): Promise<void> {
connectInteractive(this);
connectLocalized(this);
connectMessages(this);
this.hasLoader = this.loading;
Expand All @@ -185,6 +191,7 @@ export class Button

disconnectedCallback(): void {
this.mutationObserver?.disconnect();
disconnectInteractive(this);
disconnectLabel(this);
disconnectLocalized(this);
disconnectMessages(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ import {
HiddenFormInputSlot
} from "../../utils/form";
import { guid } from "../../utils/guid";
import { InteractiveComponent, updateHostInteraction } from "../../utils/interactive";
import {
connectInteractive,
disconnectInteractive,
InteractiveComponent,
updateHostInteraction
} from "../../utils/interactive";
import { isActivationKey } from "../../utils/key";
import { connectLabel, disconnectLabel, getLabelText, LabelableComponent } from "../../utils/label";
import {
Expand Down Expand Up @@ -226,11 +231,13 @@ export class Checkbox

connectedCallback(): void {
this.guid = this.el.id || `calcite-checkbox-${guid()}`;
connectInteractive(this);
connectLabel(this);
connectForm(this);
}

disconnectedCallback(): void {
disconnectInteractive(this);
disconnectLabel(this);
disconnectForm(this);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ import {
Watch
} from "@stencil/core";
import { focusElementInGroup, toAriaBoolean } from "../../utils/dom";
import { InteractiveComponent, updateHostInteraction } from "../../utils/interactive";
import {
connectInteractive,
disconnectInteractive,
InteractiveComponent,
updateHostInteraction
} from "../../utils/interactive";
import { createObserver } from "../../utils/observers";
import { Scale, SelectionMode } from "../interfaces";
import { componentLoaded, setComponentLoaded, setUpLoadableComponent } from "../../utils/loadable";
Expand Down Expand Up @@ -93,10 +98,12 @@ export class ChipGroup implements InteractiveComponent {
//--------------------------------------------------------------------------

connectedCallback(): void {
connectInteractive(this);
this.mutationObserver?.observe(this.el, { childList: true, subtree: true });
}

componentDidRender(): void {
disconnectInteractive(this);
updateHostInteraction(this);
}

Expand Down
9 changes: 8 additions & 1 deletion packages/calcite-components/src/components/chip/chip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,12 @@ import {
T9nComponent,
updateMessages
} from "../../utils/t9n";
import { InteractiveComponent, updateHostInteraction } from "../../utils/interactive";
import {
connectInteractive,
disconnectInteractive,
InteractiveComponent,
updateHostInteraction
} from "../../utils/interactive";
import { connectLocalized, disconnectLocalized, LocalizedComponent } from "../../utils/locale";
import { createObserver } from "../../utils/observers";
import { isActivationKey } from "../../utils/key";
Expand Down Expand Up @@ -196,6 +201,7 @@ export class Chip

connectedCallback(): void {
connectConditionalSlotComponent(this);
connectInteractive(this);
connectLocalized(this);
connectMessages(this);
this.setupTextContentObserver();
Expand All @@ -211,6 +217,7 @@ export class Chip

disconnectedCallback(): void {
disconnectConditionalSlotComponent(this);
disconnectInteractive(this);
disconnectLocalized(this);
disconnectMessages(this);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,12 @@ import {
toNonAlphaMode
} from "./utils";

import { InteractiveComponent, updateHostInteraction } from "../../utils/interactive";
import {
connectInteractive,
disconnectInteractive,
InteractiveComponent,
updateHostInteraction
} from "../../utils/interactive";
import { isActivationKey } from "../../utils/key";
import {
componentLoaded,
Expand Down Expand Up @@ -687,6 +692,7 @@ export class ColorPicker
}

connectedCallback(): void {
connectInteractive(this);
connectLocalized(this);
connectMessages(this);
}
Expand All @@ -698,6 +704,7 @@ export class ColorPicker
disconnectedCallback(): void {
document.removeEventListener("pointermove", this.globalPointerMoveHandler);
document.removeEventListener("pointerup", this.globalPointerUpHandler);
disconnectInteractive(this);
disconnectLocalized(this);
disconnectMessages(this);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ import {
} from "../../utils/conditionalSlot";
import { getElementProp, getSlotted } from "../../utils/dom";
import { guid } from "../../utils/guid";
import { InteractiveComponent, updateHostInteraction } from "../../utils/interactive";
import {
connectInteractive,
disconnectInteractive,
InteractiveComponent,
updateHostInteraction
} from "../../utils/interactive";
import { ComboboxChildElement } from "../combobox/interfaces";
import { getAncestors, getDepth } from "../combobox/utils";
import { Scale } from "../interfaces";
Expand Down Expand Up @@ -99,10 +104,12 @@ export class ComboboxItem implements ConditionalSlotComponent, InteractiveCompon
this.ancestors = getAncestors(this.el);
this.scale = getElementProp(this.el, "scale", this.scale);
connectConditionalSlotComponent(this);
connectInteractive(this);
}

disconnectedCallback(): void {
disconnectConditionalSlotComponent(this);
disconnectInteractive(this);
}

componentDidRender(): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,12 @@ import {
submitForm
} from "../../utils/form";
import { guid } from "../../utils/guid";
import { InteractiveComponent, updateHostInteraction } from "../../utils/interactive";
import {
connectInteractive,
disconnectInteractive,
InteractiveComponent,
updateHostInteraction
} from "../../utils/interactive";
import { connectLabel, disconnectLabel, getLabelText, LabelableComponent } from "../../utils/label";
import {
componentLoaded,
Expand Down Expand Up @@ -387,6 +392,7 @@ export class Combobox
// --------------------------------------------------------------------------

connectedCallback(): void {
connectInteractive(this);
connectLocalized(this);
connectMessages(this);
this.internalValueChangeFlag = true;
Expand Down Expand Up @@ -427,6 +433,7 @@ export class Combobox
disconnectedCallback(): void {
this.mutationObserver?.disconnect();
this.resizeObserver?.disconnect();
disconnectInteractive(this);
disconnectLabel(this);
disconnectForm(this);
disconnectFloatingUI(this, this.referenceEl, this.floatingEl);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ import {
import { dateToISO } from "../../utils/date";

import { closestElementCrossShadowBoundary, getElementDir, toAriaBoolean } from "../../utils/dom";
import { InteractiveComponent, updateHostInteraction } from "../../utils/interactive";
import {
connectInteractive,
disconnectInteractive,
InteractiveComponent,
updateHostInteraction
} from "../../utils/interactive";
import { isActivationKey } from "../../utils/key";
import { numberStringFormatter } from "../../utils/locale";
import { CSS_UTILITY } from "../../utils/resources";
Expand Down Expand Up @@ -185,10 +190,18 @@ export class DatePickerDay implements InteractiveComponent {
);
}

connectedCallback(): void {
connectInteractive(this);
}

componentDidRender(): void {
updateHostInteraction(this, this.isTabbable);
}

disconnectedCallback(): void {
disconnectInteractive(this);
}

isTabbable(): boolean {
return this.active;
}
Expand Down
11 changes: 9 additions & 2 deletions packages/calcite-components/src/components/dropdown/dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,12 @@ import {
reposition
} from "../../utils/floating-ui";
import { guid } from "../../utils/guid";
import { InteractiveComponent, updateHostInteraction } from "../../utils/interactive";
import {
connectInteractive,
disconnectInteractive,
InteractiveComponent,
updateHostInteraction
} from "../../utils/interactive";
import { isActivationKey } from "../../utils/key";
import {
componentLoaded,
Expand Down Expand Up @@ -212,6 +217,7 @@ export class Dropdown
if (this.open) {
this.openHandler(this.open);
}
connectInteractive(this);
connectOpenCloseComponent(this);
}

Expand All @@ -230,8 +236,9 @@ export class Dropdown

disconnectedCallback(): void {
this.mutationObserver?.disconnect();
disconnectFloatingUI(this, this.referenceEl, this.floatingEl);
this.resizeObserver?.disconnect();
disconnectInteractive(this);
disconnectFloatingUI(this, this.referenceEl, this.floatingEl);
disconnectOpenCloseComponent(this);
}

Expand Down
15 changes: 14 additions & 1 deletion packages/calcite-components/src/components/fab/fab.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { Component, Element, h, Method, Prop, VNode } from "@stencil/core";
import { focusElement } from "../../utils/dom";
import { InteractiveComponent, updateHostInteraction } from "../../utils/interactive";
import {
connectInteractive,
disconnectInteractive,
InteractiveComponent,
updateHostInteraction
} from "../../utils/interactive";
import {
componentLoaded,
LoadableComponent,
Expand Down Expand Up @@ -89,6 +94,10 @@ export class Fab implements InteractiveComponent, LoadableComponent {
//
//--------------------------------------------------------------------------

connectedCallback(): void {
connectInteractive(this);
}

componentWillLoad(): void {
setUpLoadableComponent(this);
}
Expand All @@ -101,6 +110,10 @@ export class Fab implements InteractiveComponent, LoadableComponent {
updateHostInteraction(this);
}

disconnectedCallback(): void {
disconnectInteractive(this);
}

// --------------------------------------------------------------------------
//
// Methods
Expand Down
9 changes: 8 additions & 1 deletion packages/calcite-components/src/components/filter/filter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ import {
} from "@stencil/core";
import { debounce } from "lodash-es";
import { filter } from "../../utils/filter";
import { InteractiveComponent, updateHostInteraction } from "../../utils/interactive";
import {
connectInteractive,
disconnectInteractive,
InteractiveComponent,
updateHostInteraction
} from "../../utils/interactive";
import {
componentLoaded,
LoadableComponent,
Expand Down Expand Up @@ -158,6 +163,7 @@ export class Filter
}

connectedCallback(): void {
connectInteractive(this);
connectLocalized(this);
connectMessages(this);
}
Expand All @@ -167,6 +173,7 @@ export class Filter
}

disconnectedCallback(): void {
disconnectInteractive(this);
disconnectLocalized(this);
disconnectMessages(this);
}
Expand Down
Loading

0 comments on commit 271d985

Please sign in to comment.