From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- toolkit/actors/SelectChild.sys.mjs | 490 +++++++++++++++++++++++++++++++++++++ 1 file changed, 490 insertions(+) create mode 100644 toolkit/actors/SelectChild.sys.mjs (limited to 'toolkit/actors/SelectChild.sys.mjs') diff --git a/toolkit/actors/SelectChild.sys.mjs b/toolkit/actors/SelectChild.sys.mjs new file mode 100644 index 0000000000..a6d96d1b79 --- /dev/null +++ b/toolkit/actors/SelectChild.sys.mjs @@ -0,0 +1,490 @@ +/* vim: set ts=2 sw=2 sts=2 et tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs"; + +const lazy = {}; + +ChromeUtils.defineESModuleGetters(lazy, { + DeferredTask: "resource://gre/modules/DeferredTask.sys.mjs", + LayoutUtils: "resource://gre/modules/LayoutUtils.sys.mjs", +}); + +const kStateActive = 0x00000001; // ElementState::ACTIVE +const kStateHover = 0x00000004; // ElementState::HOVER + +// Duplicated in SelectParent.jsm +// Please keep these lists in sync. +const SUPPORTED_OPTION_OPTGROUP_PROPERTIES = [ + "direction", + "color", + "background-color", + "text-shadow", + "text-transform", + "font-family", + "font-weight", + "font-size", + "font-style", +]; + +const SUPPORTED_SELECT_PROPERTIES = [ + ...SUPPORTED_OPTION_OPTGROUP_PROPERTIES, + "scrollbar-width", + "scrollbar-color", +]; + +// A process global state for whether or not content thinks +// that a while it was open, so + // we'll poke a DeferredTask to update the parent sometime + // in the very near future. + this._updateTimer.arm(); + }); + this.mut.observe(this.element, { + childList: true, + subtree: true, + attributes: true, + }); + + XPCOMUtils.defineLazyPreferenceGetter( + this, + "disablePopupAutohide", + "ui.popup.disable_autohide", + false + ); + }, + + uninit() { + this.element.openInParentProcess = false; + let win = this.element.ownerGlobal; + win.removeEventListener("pagehide", this, { mozSystemGroup: true }); + this.element.removeEventListener("blur", this, { mozSystemGroup: true }); + this.element.removeEventListener("transitionend", this, { + mozSystemGroup: true, + }); + this.element = null; + this.actor = null; + this.mut.disconnect(); + this._updateTimer.disarm(); + this._updateTimer = null; + gOpen = false; + }, + + showDropDown() { + this.element.openInParentProcess = true; + this._setupPseudoClassStyles(); + let rect = this._getBoundingContentRect(); + let computedStyles = getComputedStyles(this.element); + let options = this._buildOptionList(); + let defaultStyles = this.element.ownerGlobal.getDefaultComputedStyle( + this.element + ); + this.actor.sendAsyncMessage("Forms:ShowDropDown", { + isOpenedViaTouch: this.isOpenedViaTouch, + options, + rect, + custom: !this.element.nodePrincipal.isSystemPrincipal, + selectedIndex: this.element.selectedIndex, + isDarkBackground: ChromeUtils.isDarkBackground(this.element), + style: supportedStyles(computedStyles, SUPPORTED_SELECT_PROPERTIES), + defaultStyle: supportedStyles(defaultStyles, SUPPORTED_SELECT_PROPERTIES), + }); + this._clearPseudoClassStyles(); + gOpen = true; + }, + + _setupPseudoClassStyles() { + if (this._pseudoStylesSetup) { + throw new Error("pseudo styles must not be set up yet"); + } + // Do all of the things that change style at once, before we read + // any styles. + this._pseudoStylesSetup = true; + InspectorUtils.addPseudoClassLock(this.element, ":focus"); + let lockedDescendants = (this._lockedDescendants = + this.element.querySelectorAll(":checked")); + for (let child of lockedDescendants) { + // Selected options have the :checked pseudo-class, which + // we want to disable before calculating the computed + // styles since the user agent styles alter the styling + // based on :checked. + InspectorUtils.addPseudoClassLock(child, ":checked", false); + } + }, + + _clearPseudoClassStyles() { + if (!this._pseudoStylesSetup) { + throw new Error("pseudo styles must be set up already"); + } + // Undo all of the things that change style at once, after we're + // done reading styles. + InspectorUtils.clearPseudoClassLocks(this.element); + let lockedDescendants = this._lockedDescendants; + for (let child of lockedDescendants) { + InspectorUtils.clearPseudoClassLocks(child); + } + this._lockedDescendants = null; + this._pseudoStylesSetup = false; + }, + + _getBoundingContentRect() { + return lazy.LayoutUtils.getElementBoundingScreenRect(this.element); + }, + + _buildOptionList() { + if (!this._pseudoStylesSetup) { + throw new Error("pseudo styles must be set up"); + } + let uniqueStyles = []; + let options = buildOptionListForChildren(this.element, uniqueStyles); + return { options, uniqueStyles }; + }, + + _update() { + // The popup is open. + let contentHelper = currentSelectContentHelper.get(this); + if (contentHelper) { + contentHelper.handleEvent(event); + } + return; + } + + switch (event.type) { + case "mozshowdropdown": { + let contentHelper = new SelectContentHelper( + event.target, + { isOpenedViaTouch: false }, + this + ); + currentSelectContentHelper.set(this, contentHelper); + break; + } + + case "mozshowdropdown-sourcetouch": { + let contentHelper = new SelectContentHelper( + event.target, + { isOpenedViaTouch: true }, + this + ); + currentSelectContentHelper.set(this, contentHelper); + break; + } + } + } + + receiveMessage(message) { + let contentHelper = currentSelectContentHelper.get(this); + if (contentHelper) { + contentHelper.receiveMessage(message); + } + } +} -- cgit v1.2.3