diff options
Diffstat (limited to 'browser/components/customizableui/content/panelUI.xml')
-rw-r--r-- | browser/components/customizableui/content/panelUI.xml | 509 |
1 files changed, 0 insertions, 509 deletions
diff --git a/browser/components/customizableui/content/panelUI.xml b/browser/components/customizableui/content/panelUI.xml deleted file mode 100644 index 6893bd8ff..000000000 --- a/browser/components/customizableui/content/panelUI.xml +++ /dev/null @@ -1,509 +0,0 @@ -<?xml version="1.0"?> -<!-- 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/. --> - -<bindings id="browserPanelUIBindings" - xmlns="http://www.mozilla.org/xbl" - xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" - xmlns:xbl="http://www.mozilla.org/xbl"> - - <binding id="panelmultiview"> - <resources> - <stylesheet src="chrome://browser/content/customizableui/panelUI.css"/> - </resources> - <content> - <xul:box anonid="viewContainer" class="panel-viewcontainer" xbl:inherits="panelopen,viewtype,transitioning"> - <xul:stack anonid="viewStack" xbl:inherits="viewtype,transitioning" viewtype="main" class="panel-viewstack"> - <xul:vbox anonid="mainViewContainer" class="panel-mainview" xbl:inherits="viewtype"/> - - <!-- Used to capture click events over the PanelUI-mainView if we're in - subview mode. That way, any click on the PanelUI-mainView causes us - to revert to the mainView mode, whereupon PanelUI-click-capture then - allows click events to go through it. --> - <xul:vbox anonid="clickCapturer" class="panel-clickcapturer"/> - - <!-- We manually set display: none (via a CSS attribute selector) on the - subviews that are not being displayed. We're using this over a deck - because a deck assumes the size of its largest child, regardless of - whether or not it is shown. That's not good for our case, since we - want to allow each subview to be uniquely sized. --> - <xul:vbox anonid="subViews" class="panel-subviews" xbl:inherits="panelopen"> - <children includes="panelview"/> - </xul:vbox> - </xul:stack> - </xul:box> - </content> - <implementation implements="nsIDOMEventListener"> - <field name="_clickCapturer" readonly="true"> - document.getAnonymousElementByAttribute(this, "anonid", "clickCapturer"); - </field> - <field name="_viewContainer" readonly="true"> - document.getAnonymousElementByAttribute(this, "anonid", "viewContainer"); - </field> - <field name="_mainViewContainer" readonly="true"> - document.getAnonymousElementByAttribute(this, "anonid", "mainViewContainer"); - </field> - <field name="_subViews" readonly="true"> - document.getAnonymousElementByAttribute(this, "anonid", "subViews"); - </field> - <field name="_viewStack" readonly="true"> - document.getAnonymousElementByAttribute(this, "anonid", "viewStack"); - </field> - <field name="_panel" readonly="true"> - this.parentNode; - </field> - - <field name="_currentSubView">null</field> - <field name="_anchorElement">null</field> - <field name="_mainViewHeight">0</field> - <field name="_subViewObserver">null</field> - <field name="__transitioning">false</field> - <field name="_ignoreMutations">false</field> - - <property name="showingSubView" readonly="true" - onget="return this._viewStack.getAttribute('viewtype') == 'subview'"/> - <property name="_mainViewId" onget="return this.getAttribute('mainViewId');" onset="this.setAttribute('mainViewId', val); return val;"/> - <property name="_mainView" readonly="true" - onget="return this._mainViewId ? document.getElementById(this._mainViewId) : null;"/> - <property name="showingSubViewAsMainView" readonly="true" - onget="return this.getAttribute('mainViewIsSubView') == 'true'"/> - - <property name="ignoreMutations"> - <getter> - return this._ignoreMutations; - </getter> - <setter><![CDATA[ - this._ignoreMutations = val; - if (!val && this._panel.state == "open") { - if (this.showingSubView) { - this._syncContainerWithSubView(); - } else { - this._syncContainerWithMainView(); - } - } - ]]></setter> - </property> - - <property name="_transitioning"> - <getter> - return this.__transitioning; - </getter> - <setter><![CDATA[ - this.__transitioning = val; - if (val) { - this.setAttribute("transitioning", "true"); - } else { - this.removeAttribute("transitioning"); - } - ]]></setter> - </property> - <constructor><![CDATA[ - this._clickCapturer.addEventListener("click", this); - this._panel.addEventListener("popupshowing", this); - this._panel.addEventListener("popupshown", this); - this._panel.addEventListener("popuphidden", this); - this._subViews.addEventListener("overflow", this); - this._mainViewContainer.addEventListener("overflow", this); - - // Get a MutationObserver ready to react to subview size changes. We - // only attach this MutationObserver when a subview is being displayed. - this._subViewObserver = - new MutationObserver(this._syncContainerWithSubView.bind(this)); - this._mainViewObserver = - new MutationObserver(this._syncContainerWithMainView.bind(this)); - - this._mainViewContainer.setAttribute("panelid", - this._panel.id); - - if (this._mainView) { - this.setMainView(this._mainView); - } - this.setAttribute("viewtype", "main"); - ]]></constructor> - - <destructor><![CDATA[ - if (this._mainView) { - this._mainView.removeAttribute("mainview"); - } - this._mainViewObserver.disconnect(); - this._subViewObserver.disconnect(); - this._panel.removeEventListener("popupshowing", this); - this._panel.removeEventListener("popupshown", this); - this._panel.removeEventListener("popuphidden", this); - this._subViews.removeEventListener("overflow", this); - this._mainViewContainer.removeEventListener("overflow", this); - this._clickCapturer.removeEventListener("click", this); - ]]></destructor> - - <method name="setMainView"> - <parameter name="aNewMainView"/> - <body><![CDATA[ - if (this._mainView) { - this._mainViewObserver.disconnect(); - this._subViews.appendChild(this._mainView); - this._mainView.removeAttribute("mainview"); - } - this._mainViewId = aNewMainView.id; - aNewMainView.setAttribute("mainview", "true"); - this._mainViewContainer.appendChild(aNewMainView); - ]]></body> - </method> - - <method name="showMainView"> - <body><![CDATA[ - if (this.showingSubView) { - let viewNode = this._currentSubView; - let evt = document.createEvent("CustomEvent"); - evt.initCustomEvent("ViewHiding", true, true, viewNode); - viewNode.dispatchEvent(evt); - - viewNode.removeAttribute("current"); - this._currentSubView = null; - - this._subViewObserver.disconnect(); - - this._setViewContainerHeight(this._mainViewHeight); - - this.setAttribute("viewtype", "main"); - } - - this._shiftMainView(); - ]]></body> - </method> - - <method name="showSubView"> - <parameter name="aViewId"/> - <parameter name="aAnchor"/> - <body><![CDATA[ - Task.spawn(function*() { - let viewNode = this.querySelector("#" + aViewId); - viewNode.setAttribute("current", true); - // Emit the ViewShowing event so that the widget definition has a chance - // to lazily populate the subview with things. - let detail = { - blockers: new Set(), - addBlocker(aPromise) { - this.blockers.add(aPromise); - }, - }; - - let evt = new CustomEvent("ViewShowing", { bubbles: true, cancelable: true, detail }); - viewNode.dispatchEvent(evt); - - let cancel = evt.defaultPrevented; - if (detail.blockers.size) { - try { - let results = yield Promise.all(detail.blockers); - cancel = cancel || results.some(val => val === false); - } catch (e) { - Components.utils.reportError(e); - cancel = true; - } - } - - if (cancel) { - return; - } - - this._currentSubView = viewNode; - - // Now we have to transition the panel. There are a few parts to this: - // - // 1) The main view content gets shifted so that the center of the anchor - // node is at the left-most edge of the panel. - // 2) The subview deck slides in so that it takes up almost all of the - // panel. - // 3) If the subview is taller then the main panel contents, then the panel - // must grow to meet that new height. Otherwise, it must shrink. - // - // All three of these actions make use of CSS transformations, so they - // should all occur simultaneously. - this.setAttribute("viewtype", "subview"); - this._shiftMainView(aAnchor); - - this._mainViewHeight = this._viewStack.clientHeight; - - let newHeight = this._heightOfSubview(viewNode, this._subViews); - this._setViewContainerHeight(newHeight); - - this._subViewObserver.observe(viewNode, { - attributes: true, - characterData: true, - childList: true, - subtree: true - }); - }.bind(this)); - ]]></body> - </method> - - <method name="_setViewContainerHeight"> - <parameter name="aHeight"/> - <body><![CDATA[ - let container = this._viewContainer; - this._transitioning = true; - - let onTransitionEnd = () => { - container.removeEventListener("transitionend", onTransitionEnd); - this._transitioning = false; - }; - - container.addEventListener("transitionend", onTransitionEnd); - container.style.height = `${aHeight}px`; - ]]></body> - </method> - - <method name="_shiftMainView"> - <parameter name="aAnchor"/> - <body><![CDATA[ - if (aAnchor) { - // We need to find the edge of the anchor, relative to the main panel. - // Then we need to add half the width of the anchor. This is the target - // that we need to transition to. - let anchorRect = aAnchor.getBoundingClientRect(); - let mainViewRect = this._mainViewContainer.getBoundingClientRect(); - let center = aAnchor.clientWidth / 2; - let direction = aAnchor.ownerDocument.defaultView.getComputedStyle(aAnchor, null).direction; - let edge; - if (direction == "ltr") { - edge = anchorRect.left - mainViewRect.left; - } else { - edge = mainViewRect.right - anchorRect.right; - } - - // If the anchor is an element on the far end of the mainView we - // don't want to shift the mainView too far, we would reveal empty - // space otherwise. - let cstyle = window.getComputedStyle(document.documentElement, null); - let exitSubViewGutterWidth = - cstyle.getPropertyValue("--panel-ui-exit-subview-gutter-width"); - let maxShift = mainViewRect.width - parseInt(exitSubViewGutterWidth); - let target = Math.min(maxShift, edge + center); - - let neg = direction == "ltr" ? "-" : ""; - this._mainViewContainer.style.transform = `translateX(${neg}${target}px)`; - aAnchor.setAttribute("panel-multiview-anchor", true); - } else { - this._mainViewContainer.style.transform = ""; - if (this.anchorElement) - this.anchorElement.removeAttribute("panel-multiview-anchor"); - } - this.anchorElement = aAnchor; - ]]></body> - </method> - - <method name="handleEvent"> - <parameter name="aEvent"/> - <body><![CDATA[ - if (aEvent.type.startsWith("popup") && aEvent.target != this._panel) { - // Shouldn't act on e.g. context menus being shown from within the panel. - return; - } - switch (aEvent.type) { - case "click": - if (aEvent.originalTarget == this._clickCapturer) { - this.showMainView(); - } - break; - case "overflow": - if (aEvent.target.localName == "vbox") { - // Resize the right view on the next tick. - if (this.showingSubView) { - setTimeout(this._syncContainerWithSubView.bind(this), 0); - } else if (!this.transitioning) { - setTimeout(this._syncContainerWithMainView.bind(this), 0); - } - } - break; - case "popupshowing": - this.setAttribute("panelopen", "true"); - // Bug 941196 - The panel can get taller when opening a subview. Disabling - // autoPositioning means that the panel won't jump around if an opened - // subview causes the panel to exceed the dimensions of the screen in the - // direction that the panel originally opened in. This property resets - // every time the popup closes, which is why we have to set it each time. - this._panel.autoPosition = false; - this._syncContainerWithMainView(); - - this._mainViewObserver.observe(this._mainView, { - attributes: true, - characterData: true, - childList: true, - subtree: true - }); - - break; - case "popupshown": - this._setMaxHeight(); - break; - case "popuphidden": - this.removeAttribute("panelopen"); - this._mainView.style.removeProperty("height"); - this.showMainView(); - this._mainViewObserver.disconnect(); - break; - } - ]]></body> - </method> - - <method name="_shouldSetPosition"> - <body><![CDATA[ - return this.getAttribute("nosubviews") == "true"; - ]]></body> - </method> - - <method name="_shouldSetHeight"> - <body><![CDATA[ - return this.getAttribute("nosubviews") != "true"; - ]]></body> - </method> - - <method name="_setMaxHeight"> - <body><![CDATA[ - if (!this._shouldSetHeight()) - return; - - // Ignore the mutation that'll fire when we set the height of - // the main view. - this.ignoreMutations = true; - this._mainView.style.height = - this.getBoundingClientRect().height + "px"; - this.ignoreMutations = false; - ]]></body> - </method> - <method name="_adjustContainerHeight"> - <body><![CDATA[ - if (!this.ignoreMutations && !this.showingSubView && !this._transitioning) { - let height; - if (this.showingSubViewAsMainView) { - height = this._heightOfSubview(this._mainView); - } else { - height = this._mainView.scrollHeight; - } - this._viewContainer.style.height = height + "px"; - } - ]]></body> - </method> - <method name="_syncContainerWithSubView"> - <body><![CDATA[ - // Check that this panel is still alive: - if (!this._panel || !this._panel.parentNode) { - return; - } - - if (!this.ignoreMutations && this.showingSubView) { - let newHeight = this._heightOfSubview(this._currentSubView, this._subViews); - this._viewContainer.style.height = newHeight + "px"; - } - ]]></body> - </method> - <method name="_syncContainerWithMainView"> - <body><![CDATA[ - // Check that this panel is still alive: - if (!this._panel || !this._panel.parentNode) { - return; - } - - if (this._shouldSetPosition()) { - this._panel.adjustArrowPosition(); - } - - if (this._shouldSetHeight()) { - this._adjustContainerHeight(); - } - ]]></body> - </method> - - <!-- Call this when the height of one of your views (the main view or a - subview) changes and you want the heights of the multiview and panel - to be the same as the view's height. - If the caller can give a hint of the expected height change with the - optional aExpectedChange parameter, it prevents flicker. --> - <method name="setHeightToFit"> - <parameter name="aExpectedChange"/> - <body><![CDATA[ - // Set the max-height to zero, wait until the height is actually - // updated, and then remove it. If it's not removed, weird things can - // happen, like widgets in the panel won't respond to clicks even - // though they're visible. - let count = 5; - let height = getComputedStyle(this).height; - if (aExpectedChange) - this.style.maxHeight = (parseInt(height) + aExpectedChange) + "px"; - else - this.style.maxHeight = "0"; - let interval = setInterval(() => { - if (height != getComputedStyle(this).height || --count == 0) { - clearInterval(interval); - this.style.removeProperty("max-height"); - } - }, 0); - ]]></body> - </method> - - <method name="_heightOfSubview"> - <parameter name="aSubview"/> - <parameter name="aContainerToCheck"/> - <body><![CDATA[ - function getFullHeight(element) { - // XXXgijs: unfortunately, scrollHeight rounds values, and there's no alternative - // that works with overflow: auto elements. Fortunately for us, - // we have exactly 1 (potentially) scrolling element in here (the subview body), - // and rounding 1 value is OK - rounding more than 1 and adding them means we get - // off-by-1 errors. Now we might be off by a subpixel, but we care less about that. - // So, use scrollHeight *only* if the element is vertically scrollable. - let height; - let elementCS; - if (element.scrollTopMax) { - height = element.scrollHeight; - // Bounding client rects include borders, scrollHeight doesn't: - elementCS = win.getComputedStyle(element); - height += parseFloat(elementCS.borderTopWidth) + - parseFloat(elementCS.borderBottomWidth); - } else { - height = element.getBoundingClientRect().height; - if (height > 0) { - elementCS = win.getComputedStyle(element); - } - } - if (elementCS) { - // Include margins - but not borders or paddings because they - // were dealt with above. - height += parseFloat(elementCS.marginTop) + parseFloat(elementCS.marginBottom); - } - return height; - } - let win = aSubview.ownerDocument.defaultView; - let body = aSubview.querySelector(".panel-subview-body"); - let height = getFullHeight(body || aSubview); - if (body) { - let header = aSubview.querySelector(".panel-subview-header"); - let footer = aSubview.querySelector(".panel-subview-footer"); - height += (header ? getFullHeight(header) : 0) + - (footer ? getFullHeight(footer) : 0); - } - if (aContainerToCheck) { - let containerCS = win.getComputedStyle(aContainerToCheck); - height += parseFloat(containerCS.paddingTop) + parseFloat(containerCS.paddingBottom); - } - return Math.ceil(height); - ]]></body> - </method> - - </implementation> - </binding> - - <binding id="panelview"> - <implementation> - <property name="panelMultiView" readonly="true"> - <getter><![CDATA[ - if (this.parentNode.localName != "panelmultiview") { - return document.getBindingParent(this.parentNode); - } - - return this.parentNode; - ]]></getter> - </property> - </implementation> - </binding> -</bindings> |