summaryrefslogtreecommitdiffstats
path: root/toolkit/content/widgets/button.xml
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/content/widgets/button.xml')
-rw-r--r--toolkit/content/widgets/button.xml389
1 files changed, 389 insertions, 0 deletions
diff --git a/toolkit/content/widgets/button.xml b/toolkit/content/widgets/button.xml
new file mode 100644
index 000000000..89d9d86c6
--- /dev/null
+++ b/toolkit/content/widgets/button.xml
@@ -0,0 +1,389 @@
+<?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="buttonBindings"
+ 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="button-base" extends="chrome://global/content/bindings/general.xml#basetext" role="xul:button">
+ <implementation implements="nsIDOMXULButtonElement">
+ <property name="type"
+ onget="return this.getAttribute('type');"
+ onset="this.setAttribute('type', val); return val;"/>
+
+ <property name="dlgType"
+ onget="return this.getAttribute('dlgtype');"
+ onset="this.setAttribute('dlgtype', val); return val;"/>
+
+ <property name="group"
+ onget="return this.getAttribute('group');"
+ onset="this.setAttribute('group', val); return val;"/>
+
+ <property name="open" onget="return this.hasAttribute('open');">
+ <setter><![CDATA[
+ if (this.boxObject instanceof MenuBoxObject) {
+ this.boxObject.openMenu(val);
+ } else if (val) {
+ // Fall back to just setting the attribute
+ this.setAttribute('open', 'true');
+ } else {
+ this.removeAttribute('open');
+ }
+ return val;
+ ]]></setter>
+ </property>
+
+ <property name="checked" onget="return this.hasAttribute('checked');">
+ <setter><![CDATA[
+ if (this.type == "checkbox") {
+ this.checkState = val ? 1 : 0;
+ } else if (this.type == "radio" && val) {
+ var sibs = this.parentNode.getElementsByAttribute("group", this.group);
+ for (var i = 0; i < sibs.length; ++i)
+ sibs[i].removeAttribute("checked");
+ }
+
+ if (val)
+ this.setAttribute("checked", "true");
+ else
+ this.removeAttribute("checked");
+
+ return val;
+ ]]></setter>
+ </property>
+
+ <property name="checkState">
+ <getter><![CDATA[
+ var state = this.getAttribute("checkState");
+ if (state == "")
+ return this.checked ? 1 : 0;
+ if (state == "0")
+ return 0;
+ if (state == "2")
+ return 2;
+ return 1;
+ ]]></getter>
+ <setter><![CDATA[
+ this.setAttribute("checkState", val);
+ return val;
+ ]]></setter>
+ </property>
+
+ <property name="autoCheck"
+ onget="return this.getAttribute('autoCheck') == 'true';"
+ onset="this.setAttribute('autoCheck', val); return val;"/>
+
+ <method name ="filterButtons">
+ <parameter name="node"/>
+ <body>
+ <![CDATA[
+ // if the node isn't visible, don't descend into it.
+ var cs = node.ownerDocument.defaultView.getComputedStyle(node, null);
+ if (cs.visibility != "visible" || cs.display == "none") {
+ return NodeFilter.FILTER_REJECT;
+ }
+ // but it may be a popup element, in which case we look at "state"...
+ if (cs.display == "-moz-popup" && node.state != "open") {
+ return NodeFilter.FILTER_REJECT;
+ }
+ // OK - the node seems visible, so it is a candidate.
+ if (node.localName == "button" && node.accessKey && !node.disabled)
+ return NodeFilter.FILTER_ACCEPT;
+ return NodeFilter.FILTER_SKIP;
+ ]]>
+ </body>
+ </method>
+
+ <method name="fireAccessKeyButton">
+ <parameter name="aSubtree"/>
+ <parameter name="aAccessKeyLower"/>
+ <body>
+ <![CDATA[
+ var iterator = aSubtree.ownerDocument.createTreeWalker(aSubtree,
+ NodeFilter.SHOW_ELEMENT,
+ this.filterButtons);
+ while (iterator.nextNode()) {
+ var test = iterator.currentNode;
+ if (test.accessKey.toLowerCase() == aAccessKeyLower &&
+ !test.disabled && !test.collapsed && !test.hidden) {
+ test.focus();
+ test.click();
+ return true;
+ }
+ }
+ return false;
+ ]]>
+ </body>
+ </method>
+
+ <method name="_handleClick">
+ <body>
+ <![CDATA[
+ if (!this.disabled &&
+ (this.autoCheck || !this.hasAttribute("autoCheck"))) {
+
+ if (this.type == "checkbox") {
+ this.checked = !this.checked;
+ } else if (this.type == "radio") {
+ this.checked = true;
+ }
+ }
+ ]]>
+ </body>
+ </method>
+ </implementation>
+
+ <handlers>
+ <!-- While it would seem we could do this by handling oncommand, we can't
+ because any external oncommand handlers might get called before ours,
+ and then they would see the incorrect value of checked. Additionally
+ a command attribute would redirect the command events anyway.-->
+ <handler event="click" button="0" action="this._handleClick();"/>
+ <handler event="keypress" key=" ">
+ <![CDATA[
+ this._handleClick();
+ // Prevent page from scrolling on the space key.
+ event.preventDefault();
+ ]]>
+ </handler>
+
+ <handler event="keypress">
+ <![CDATA[
+ if (this.boxObject instanceof MenuBoxObject) {
+ if (this.open)
+ return;
+ } else {
+ if (event.keyCode == KeyEvent.DOM_VK_UP ||
+ (event.keyCode == KeyEvent.DOM_VK_LEFT &&
+ document.defaultView.getComputedStyle(this.parentNode, "")
+ .direction == "ltr") ||
+ (event.keyCode == KeyEvent.DOM_VK_RIGHT &&
+ document.defaultView.getComputedStyle(this.parentNode, "")
+ .direction == "rtl")) {
+ event.preventDefault();
+ window.document.commandDispatcher.rewindFocus();
+ return;
+ }
+
+ if (event.keyCode == KeyEvent.DOM_VK_DOWN ||
+ (event.keyCode == KeyEvent.DOM_VK_RIGHT &&
+ document.defaultView.getComputedStyle(this.parentNode, "")
+ .direction == "ltr") ||
+ (event.keyCode == KeyEvent.DOM_VK_LEFT &&
+ document.defaultView.getComputedStyle(this.parentNode, "")
+ .direction == "rtl")) {
+ event.preventDefault();
+ window.document.commandDispatcher.advanceFocus();
+ return;
+ }
+ }
+
+ if (event.keyCode || event.charCode <= 32 || event.altKey ||
+ event.ctrlKey || event.metaKey)
+ return; // No printable char pressed, not a potential accesskey
+
+ // Possible accesskey pressed
+ var charPressedLower = String.fromCharCode(event.charCode).toLowerCase();
+
+ // If the accesskey of the current button is pressed, just activate it
+ if (this.accessKey.toLowerCase() == charPressedLower) {
+ this.click();
+ return;
+ }
+
+ // Search for accesskey in the list of buttons for this doc and each subdoc
+ // Get the buttons for the main document and all sub-frames
+ for (var frameCount = -1; frameCount < window.top.frames.length; frameCount++) {
+ var doc = (frameCount == -1)? window.top.document:
+ window.top.frames[frameCount].document
+ if (this.fireAccessKeyButton(doc.documentElement, charPressedLower))
+ return;
+ }
+
+ // Test anonymous buttons
+ var dlg = window.top.document;
+ var buttonBox = dlg.getAnonymousElementByAttribute(dlg.documentElement,
+ "anonid", "buttons");
+ if (buttonBox)
+ this.fireAccessKeyButton(buttonBox, charPressedLower);
+ ]]>
+ </handler>
+ </handlers>
+ </binding>
+
+ <binding id="button" display="xul:button"
+ extends="chrome://global/content/bindings/button.xml#button-base">
+ <resources>
+ <stylesheet src="chrome://global/skin/button.css"/>
+ </resources>
+
+ <content>
+ <children includes="observes|template|menupopup|panel|tooltip"/>
+ <xul:hbox class="box-inherit button-box" xbl:inherits="align,dir,pack,orient"
+ align="center" pack="center" flex="1" anonid="button-box">
+ <children>
+ <xul:image class="button-icon" xbl:inherits="src=image"/>
+ <xul:label class="button-text" xbl:inherits="value=label,accesskey,crop"/>
+ </children>
+ </xul:hbox>
+ </content>
+ </binding>
+
+ <binding id="menu" display="xul:menu"
+ extends="chrome://global/content/bindings/button.xml#button">
+ <content>
+ <children includes="observes|template|menupopup|panel|tooltip"/>
+ <xul:hbox class="box-inherit button-box" xbl:inherits="align,dir,pack,orient"
+ align="center" pack="center" flex="1">
+ <children>
+ <xul:hbox class="box-inherit" xbl:inherits="align,dir,pack,orient"
+ align="center" pack="center" flex="1">
+ <xul:image class="button-icon" xbl:inherits="src=image"/>
+ <xul:label class="button-text" xbl:inherits="value=label,accesskey,crop"/>
+ </xul:hbox>
+ <xul:dropmarker class="button-menu-dropmarker" xbl:inherits="open,disabled,label"/>
+ </children>
+ </xul:hbox>
+ </content>
+
+ <handlers>
+ <handler event="keypress" keycode="VK_RETURN" action="this.open = true;"/>
+ <handler event="keypress" key=" ">
+ <![CDATA[
+ this.open = true;
+ // Prevent page from scrolling on the space key.
+ event.preventDefault();
+ ]]>
+ </handler>
+ </handlers>
+ </binding>
+
+ <binding id="menu-button-base"
+ extends="chrome://global/content/bindings/button.xml#button-base">
+ <implementation implements="nsIDOMEventListener">
+ <constructor>
+ this.init();
+ </constructor>
+
+ <method name="init">
+ <body>
+ <![CDATA[
+ var btn = document.getAnonymousElementByAttribute(this, "anonid", "button");
+ if (!btn)
+ throw "XBL binding for <button type=\"menu-button\"/> binding must contain an element with anonid=\"button\"";
+
+ var menubuttonParent = this;
+ btn.addEventListener("mouseover", function() {
+ if (!this.disabled)
+ menubuttonParent.buttonover = true;
+ }, true);
+ btn.addEventListener("mouseout", function() {
+ menubuttonParent.buttonover = false;
+ }, true);
+ btn.addEventListener("mousedown", function() {
+ if (!this.disabled) {
+ menubuttonParent.buttondown = true;
+ document.addEventListener("mouseup", menubuttonParent, true);
+ }
+ }, true);
+ ]]>
+ </body>
+ </method>
+
+ <property name="buttonover" onget="return this.getAttribute('buttonover');">
+ <setter>
+ <![CDATA[
+ var v = val || val == "true";
+ if (!v && this.buttondown) {
+ this.buttondown = false;
+ this._pendingActive = true;
+ }
+ else if (this._pendingActive) {
+ this.buttondown = true;
+ this._pendingActive = false;
+ }
+
+ if (v)
+ this.setAttribute("buttonover", "true");
+ else
+ this.removeAttribute("buttonover");
+ return val;
+ ]]>
+ </setter>
+ </property>
+
+ <property name="buttondown" onget="return this.getAttribute('buttondown') == 'true';">
+ <setter>
+ <![CDATA[
+ if (val || val == "true")
+ this.setAttribute("buttondown", "true");
+ else
+ this.removeAttribute("buttondown");
+ return val;
+ ]]>
+ </setter>
+ </property>
+
+ <field name="_pendingActive">false</field>
+
+ <method name="handleEvent">
+ <parameter name="aEvent"/>
+ <body>
+ <![CDATA[
+ this._pendingActive = false;
+ this.buttondown = false;
+ document.removeEventListener("mouseup", this, true);
+ ]]>
+ </body>
+ </method>
+
+ </implementation>
+
+ <handlers>
+ <handler event="keypress" keycode="VK_RETURN">
+ if (event.originalTarget == this)
+ this.open = true;
+ </handler>
+ <handler event="keypress" key=" ">
+ if (event.originalTarget == this) {
+ this.open = true;
+ // Prevent page from scrolling on the space key.
+ event.preventDefault();
+ }
+ </handler>
+ </handlers>
+ </binding>
+
+ <binding id="menu-button" display="xul:menu"
+ extends="chrome://global/content/bindings/button.xml#menu-button-base">
+ <resources>
+ <stylesheet src="chrome://global/skin/button.css"/>
+ </resources>
+
+ <content>
+ <children includes="observes|template|menupopup|panel|tooltip"/>
+ <xul:button class="box-inherit button-menubutton-button"
+ anonid="button" flex="1" allowevents="true"
+ xbl:inherits="disabled,crop,image,label,accesskey,command,
+ buttonover,buttondown,align,dir,pack,orient">
+ <children/>
+ </xul:button>
+ <xul:dropmarker class="button-menubutton-dropmarker" xbl:inherits="open,disabled,label"/>
+ </content>
+ </binding>
+
+ <binding id="button-image" display="xul:button"
+ extends="chrome://global/content/bindings/button.xml#button">
+ <content>
+ <xul:image class="button-image-icon" xbl:inherits="src=image"/>
+ </content>
+ </binding>
+
+ <binding id="button-repeat" display="xul:autorepeatbutton"
+ extends="chrome://global/content/bindings/button.xml#button"/>
+
+</bindings>