/toolkit/content/widgets/popup.xml
http://github.com/zpao/v8monkey · XML · 552 lines · 496 code · 53 blank · 3 comment · 0 complexity · b74c3a2054b6d8987bda064125610dce MD5 · raw file
- <?xml version="1.0"?>
- <bindings id="popupBindings"
- 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="popup-base">
- <resources>
- <stylesheet src="chrome://global/skin/popup.css"/>
- </resources>
- <implementation implements="nsIDOMXULPopupElement">
- <property name="label" onget="return this.getAttribute('label');"
- onset="this.setAttribute('label', val); return val;"/>
- <property name="position" onget="return this.getAttribute('position');"
- onset="this.setAttribute('position', val); return val;"/>
- <property name="popupBoxObject">
- <getter>
- return this.boxObject.QueryInterface(Components.interfaces.nsIPopupBoxObject);
- </getter>
- </property>
- <property name="state" readonly="true"
- onget="return this.popupBoxObject.popupState"/>
- <property name="triggerNode" readonly="true"
- onget="return this.popupBoxObject.triggerNode"/>
- <property name="anchorNode" readonly="true"
- onget="return this.popupBoxObject.anchorNode"/>
- <method name="openPopup">
- <parameter name="aAnchorElement"/>
- <parameter name="aPosition"/>
- <parameter name="aX"/>
- <parameter name="aY"/>
- <parameter name="aIsContextMenu"/>
- <parameter name="aAttributesOverride"/>
- <parameter name="aTriggerEvent"/>
- <body>
- <![CDATA[
- try {
- var popupBox = this.popupBoxObject;
- if (popupBox)
- popupBox.openPopup(aAnchorElement, aPosition, aX, aY,
- aIsContextMenu, aAttributesOverride, aTriggerEvent);
- } catch(e) {}
- ]]>
- </body>
- </method>
- <method name="openPopupAtScreen">
- <parameter name="aX"/>
- <parameter name="aY"/>
- <parameter name="aIsContextMenu"/>
- <parameter name="aTriggerEvent"/>
- <body>
- <![CDATA[
- try {
- var popupBox = this.popupBoxObject;
- if (popupBox)
- popupBox.openPopupAtScreen(aX, aY, aIsContextMenu, aTriggerEvent);
- } catch(e) {}
- ]]>
- </body>
- </method>
-
- <method name="showPopup">
- <parameter name="element"/>
- <parameter name="xpos"/>
- <parameter name="ypos"/>
- <parameter name="popuptype"/>
- <parameter name="anchoralignment"/>
- <parameter name="popupalignment"/>
- <body>
- <![CDATA[
- var popupBox = null;
- var menuBox = null;
- try {
- popupBox = this.popupBoxObject;
- } catch(e) {}
- try {
- menuBox = this.parentNode.boxObject;
- } catch(e) {}
- if (menuBox instanceof Components.interfaces.nsIMenuBoxObject)
- menuBox.openMenu(true);
- else if (popupBox)
- popupBox.showPopup(element, this, xpos, ypos, popuptype, anchoralignment, popupalignment);
- ]]>
- </body>
- </method>
-
- <method name="hidePopup">
- <body>
- <![CDATA[
- var popupBox = null;
- var menuBox = null;
- try {
- popupBox = this.boxObject.QueryInterface(Components.interfaces.nsIPopupBoxObject);
- } catch(e) {}
- try {
- menuBox = this.parentNode.boxObject;
- } catch(e) {}
- if (menuBox instanceof Components.interfaces.nsIMenuBoxObject)
- menuBox.openMenu(false);
- else if (popupBox)
- popupBox.hidePopup();
- ]]>
- </body>
- </method>
- <property name="autoPosition">
- <getter>
- <![CDATA[
- return this.popupBoxObject.autoPosition;
- ]]>
- </getter>
- <setter>
- <![CDATA[
- return this.popupBoxObject.autoPosition = val;
- ]]>
- </setter>
- </property>
-
- <method name="enableKeyboardNavigator">
- <parameter name="aEnableKeyboardNavigator"/>
- <body>
- <![CDATA[
- this.popupBoxObject.enableKeyboardNavigator(aEnableKeyboardNavigator);
- ]]>
- </body>
- </method>
-
- <method name="enableRollup">
- <parameter name="aEnableRollup"/>
- <body>
- <![CDATA[
- this.popupBoxObject.enableRollup(aEnableRollup);
- ]]>
- </body>
- </method>
-
- <method name="sizeTo">
- <parameter name="aWidth"/>
- <parameter name="aHeight"/>
- <body>
- <![CDATA[
- this.popupBoxObject.sizeTo(aWidth, aHeight);
- ]]>
- </body>
- </method>
-
- <method name="moveTo">
- <parameter name="aLeft"/>
- <parameter name="aTop"/>
- <body>
- <![CDATA[
- this.popupBoxObject.moveTo(aLeft, aTop);
- ]]>
- </body>
- </method>
- <method name="getOuterScreenRect">
- <body>
- <![CDATA[
- return this.popupBoxObject.getOuterScreenRect();
- ]]>
- </body>
- </method>
- </implementation>
- </binding>
- <binding id="popup"
- extends="chrome://global/content/bindings/popup.xml#popup-base">
-
- <content>
- <xul:arrowscrollbox class="popup-internal-box" flex="1" orient="vertical"
- smoothscroll="false">
- <children/>
- </xul:arrowscrollbox>
- </content>
- <implementation implements="nsIAccessibleProvider">
- <property name="accessibleType" readonly="true">
- <getter>
- <![CDATA[
- return Components.interfaces.nsIAccessibleProvider.XULMenupopup;
- ]]>
- </getter>
- </property>
- </implementation>
- <handlers>
- <handler event="popupshowing" phase="target">
- <![CDATA[
- var array = [];
- var width = 0;
- for (var menuitem = this.firstChild; menuitem; menuitem = menuitem.nextSibling) {
- if (menuitem.localName == "menuitem" && menuitem.hasAttribute("acceltext")) {
- var accel = document.getAnonymousElementByAttribute(menuitem, "anonid", "accel");
- if (accel && accel.boxObject) {
- array.push(accel);
- if (accel.boxObject.width > width)
- width = accel.boxObject.width;
- }
- }
- }
- for (var i = 0; i < array.length; i++)
- array[i].width = width;
- ]]>
- </handler>
- </handlers>
- </binding>
- <binding id="panel"
- extends="chrome://global/content/bindings/popup.xml#popup-base">
- <!-- This separate binding for dialog-like panels - not menu, list or autocomplete popups
- exposes the popup as an alert or a pane, depending on whether it is always intended
- to get keyboard navigation when it opens -->
- <implementation implements="nsIDOMXULPopupElement, nsIAccessibleProvider">
- <property name="accessibleType" readonly="true">
- <getter>
- <![CDATA[
- return (this.getAttribute("noautofocus") == "true") ?
- Components.interfaces.nsIAccessibleProvider.XULAlert :
- Components.interfaces.nsIAccessibleProvider.XULPane;
- ]]></getter>
- </property>
- <field name="_prevFocus">0</field>
- <field name="_dragBindingAlive">true</field>
- <constructor>
- <![CDATA[
- if (this.getAttribute("backdrag") == "true" && !this._draggableStarted) {
- this._draggableStarted = true;
- try {
- let tmp = {};
- Components.utils.import("resource://gre/modules/WindowDraggingUtils.jsm", tmp);
- let draghandle = new tmp.WindowDraggingElement(this);
- draghandle.mouseDownCheck = function () this._dragBindingAlive;
- } catch (e) {}
- }
- ]]>
- </constructor>
- </implementation>
-
- <handlers>
- <handler event="popupshowing"><![CDATA[
- // Capture the previous focus before has a chance to get set inside the panel
- try {
- this._prevFocus = document.commandDispatcher.focusedElement;
- if (!this._prevFocus) // Content window has focus
- this._prevFocus = document.commandDispatcher.focusedWindow;
- } catch (ex) {
- this._prevFocus = document.activeElement;
- }
- ]]></handler>
- <handler event="popupshown"><![CDATA[
- // Fire event for accessibility APIs
- var alertEvent = document.createEvent("Events");
- alertEvent.initEvent("AlertActive", true, true);
- this.dispatchEvent(alertEvent);
- ]]></handler>
- <handler event="popuphiding"><![CDATA[
- try {
- this._currentFocus = document.commandDispatcher.focusedElement;
- } catch (e) {
- this._currentFocus = document.activeElement;
- }
- ]]></handler>
- <handler event="popuphidden"><![CDATA[
- var currentFocus = this._currentFocus;
- var prevFocus = this._prevFocus;
- this._currentFocus = null;
- this._prevFocus = null;
- if (prevFocus && currentFocus && this.getAttribute("norestorefocus") != "true") {
- // Try to restore focus
- try {
- if (document.commandDispatcher.focusedWindow != window)
- return; // Focus has already been set to a window outside of this panel
- } catch(ex) {}
- while (currentFocus) {
- if (currentFocus == this) {
- // Focus was set on an element inside this panel,
- // so we need to move it back to where it was previously
- try {
- let fm = Components.classes["@mozilla.org/focus-manager;1"]
- .getService(Components.interfaces.nsIFocusManager);
- fm.setFocus(prevFocus, fm.FLAG_NOSCROLL);
- } catch(e) {
- prevFocus.focus();
- }
- return;
- }
- currentFocus = currentFocus.parentNode;
- }
- }
- ]]></handler>
- </handlers>
- </binding>
- <binding id="arrowpanel" extends="chrome://global/content/bindings/popup.xml#panel">
- <content flip="both" side="top" position="bottomcenter topleft">
- <xul:box anonid="container" class="panel-arrowcontainer" flex="1">
- <xul:box anonid="arrowbox" class="panel-arrowbox">
- <xul:image anonid="arrow" class="panel-arrow"/>
- </xul:box>
- <xul:box class="panel-arrowcontent" flex="1">
- <xul:box class="panel-inner-arrowcontent" xbl:inherits="align,dir,orient,pack" flex="1">
- <children/>
- <xul:box class="panel-inner-arrowcontentfooter" xbl:inherits="footertype" hidden="true"/>
- </xul:box>
- </xul:box>
- </xul:box>
- </content>
- <implementation>
- <field name="_fadeTimer">null</field>
- </implementation>
- <handlers>
- <handler event="popupshowing">
- <![CDATA[
- var container = document.getAnonymousElementByAttribute(this, "anonid", "container");
- var arrowbox = document.getAnonymousElementByAttribute(this, "anonid", "arrowbox");
- var arrow = document.getAnonymousElementByAttribute(this, "anonid", "arrow");
- var anchor = this.anchorNode;
- if (!anchor) {
- arrow.hidden = true;
- return;
- }
- // Returns whether the first float is smaller than the second float or
- // equals to it in a range of epsilon.
- function smallerTo(aFloat1, aFloat2, aEpsilon)
- {
- return aFloat1 <= (aFloat2 + aEpsilon);
- }
- let popupRect = this.getBoundingClientRect();
- let popupLeft = window.mozInnerScreenX + popupRect.left;
- let popupTop = window.mozInnerScreenY + popupRect.top;
- let popupRight = popupLeft + popupRect.width;
- let popupBottom = popupTop + popupRect.height;
- let anchorRect = anchor.getBoundingClientRect();
- let anchorLeft = anchor.ownerDocument.defaultView.mozInnerScreenX + anchorRect.left;
- let anchorTop = anchor.ownerDocument.defaultView.mozInnerScreenY + anchorRect.top;
- let anchorRight = anchorLeft + anchorRect.width;
- let anchorBottom = anchorTop + anchorRect.height;
- try {
- let anchorWindow = anchor.ownerDocument.defaultView;
- if (anchorWindow != window) {
- let utils = anchorWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
- getInterface(Components.interfaces.nsIDOMWindowUtils);
- let spp = utils.screenPixelsPerCSSPixel;
- anchorLeft *= spp;
- anchorRight *= spp;
- anchorTop *= spp;
- anchorBottom *= spp;
- }
- } catch(ex) { }
- const epsilon = 0.2;
- var horizPos = smallerTo(popupRight, anchorLeft, epsilon) ? -1 : smallerTo(anchorRight, popupLeft, epsilon) ? 1 : 0;
- var vertPos = smallerTo(popupBottom, anchorTop, epsilon) ? -1 : smallerTo(anchorBottom, popupTop, epsilon) ? 1 : 0;
- var anchorClass = "";
- var hideAnchor = false;
- if (horizPos == 0) {
- container.orient = "vertical";
- arrowbox.orient = "";
- if (vertPos == 0) {
- hideAnchor = true;
- }
- else {
- let pack = "";
- // We have to guess where to position the arrow given that we don't
- // have access to the parameters passed to |openPopup|.
- // If the popup is on the left of the anchor.
- if (smallerTo(popupLeft, anchorLeft, epsilon) && smallerTo(popupRight, anchorRight, epsilon)) {
- pack = "end";
- // If the popup is on the right of the anchor.
- } else if (smallerTo(anchorLeft, popupLeft, epsilon) && smallerTo(anchorRight, popupRight, epsilon)) {
- pack = "start"; //(popupLeft + popupRect.width / 2 > anchorRight) ? "start" : "end";
- // If the popup is not on the right nor on the left.
- // Basically, that means one is above the other and one is bigger
- // than the other.
- // In that case, we can't easily choose a position for the arrow so
- // we have to guess depending on which side the popup is more close to.
- } else {
- pack = (Math.abs(popupLeft - anchorLeft) < Math.abs(popupRight - anchorRight)) ? "start" : "end";
- }
- // In RTL, everything should be inverted.
- if (window.getComputedStyle(this).direction == "rtl") {
- pack = (pack == "start") ? "end" : "start";
- }
- arrowbox.pack = pack;
- if (vertPos == 1) {
- container.dir = "";
- anchorClass = "top";
- }
- else if (vertPos == -1) {
- container.dir = "reverse";
- anchorClass = "bottom";
- }
- }
- }
- else if (vertPos == 0) {
- container.orient = "";
- arrowbox.orient = "vertical";
- if (horizPos == 0) {
- hideAnchor = true;
- }
- else {
- arrowbox.pack = popupTop + popupRect.height / 2 < anchorTop ? "end" : "start";
- if (horizPos == 1) {
- container.dir = "";
- anchorClass = "left";
- }
- else if (horizPos == -1) {
- container.dir = "reverse";
- anchorClass = "right";
- }
- }
- }
- else {
- hideAnchor = true;
- }
- arrow.hidden = hideAnchor;
- arrow.setAttribute("side", anchorClass);
- this.setAttribute("side", anchorClass);
- // set fading
- var fade = this.getAttribute("fade");
- var fadeDelay = (fade == "fast") ? 1 : fade == "slow" ? 4000 : 0;
- if (fadeDelay) {
- this._fadeTimer = setTimeout(function (self) {
- self.style.opacity = 0.2;
- }, fadeDelay, this);
- }
- ]]>
- </handler>
- <handler event="popuphiding" phase="target">
- clearTimeout(this._fadeTimer);
- this.style.removeProperty("opacity");
- </handler>
- <handler event="transitionend" phase="target">
- <![CDATA[
- if (event.propertyName == "opacity") {
- this.hidePopup();
- this.style.removeProperty("opacity");
- }
- ]]>
- </handler>
- </handlers>
- </binding>
- <binding id="tooltip" extends="chrome://global/content/bindings/popup.xml#popup-base">
- <content>
- <children>
- <xul:label class="tooltip-label" xbl:inherits="xbl:text=label" flex="1"/>
- </children>
- </content>
-
- <implementation implements="nsIAccessibleProvider">
- <property name="accessibleType" readonly="true">
- <getter>
- return Components.interfaces.nsIAccessibleProvider.XULTooltip;
- </getter>
- </property>
- <field name="_mouseOutCount">0</field>
- <field name="_isMouseOver">false</field>
-
- <property name="label"
- onget="return this.getAttribute('label');"
- onset="this.setAttribute('label', val); return val;"/>
- </implementation>
- <handlers>
- <handler event="mouseover"><![CDATA[
- var rel = event.relatedTarget;
- //dump("ENTERING " + (rel ? rel.localName : "null") + "\n");
- if (!rel)
- return;
-
- // find out if the node we entered from is one of our anonymous children
- while (rel) {
- if (rel == this)
- break;
- rel = rel.parentNode;
- }
- // if the exited node is not a descendant of ours, we are entering for the first time
- if (rel != this)
- this._isMouseOver = true;
- ]]></handler>
- <handler event="mouseout"><![CDATA[
- var rel = event.relatedTarget;
- //dump("LEAVING " + (rel ? rel.localName : "null") + "\n");
- // relatedTarget is null when the titletip is first shown: a mouseout event fires
- // because the mouse is exiting the main window and entering the titletip "window".
- // relatedTarget is also null when the mouse exits the main window completely,
- // so count how many times relatedTarget was null after titletip is first shown
- // and hide popup the 2nd time
- if (!rel) {
- ++this._mouseOutCount;
- if (this._mouseOutCount > 1)
- this.hidePopup();
- return;
- }
-
- // find out if the node we are entering is one of our anonymous children
- while (rel) {
- if (rel == this)
- break;
- rel = rel.parentNode;
- }
-
- // if the entered node is not a descendant of ours, hide the tooltip
- if (rel != this && this._isMouseOver) {
- this.hidePopup();
- }
- ]]></handler>
- <handler event="popuphiding"><![CDATA[
- this._isMouseOver = false;
- this._mouseOutCount = 0;
- ]]></handler>
- </handlers>
- </binding>
- <binding id="popup-scrollbars" extends="chrome://global/content/bindings/popup.xml#popup">
- <content>
- <xul:hbox class="popup-internal-box" flex="1" orient="vertical" style="overflow: auto;">
- <children/>
- </xul:hbox>
- </content>
- </binding>
- </bindings>