Bug 1540440 - Copy and restore common bindings for suite. r=IanN
--HG-- rename : common/bindings/toolbar.xml => suite/components/bindings/toolbar.xml
This commit is contained in:
Родитель
5f8bcd56fc
Коммит
9d05642ab3
|
@ -11,10 +11,10 @@ comm.jar:
|
|||
content/communicator/bindings/general.xml (general.xml)
|
||||
content/communicator/bindings/generalBindings.xml (../../../common/bindings/generalBindings.xml)
|
||||
content/communicator/bindings/notification.xml (notification.xml)
|
||||
content/communicator/bindings/numberbox.xml (../../../common/bindings/numberbox.xml)
|
||||
content/communicator/bindings/numberbox.xml (numberbox.xml)
|
||||
content/communicator/bindings/preferences.xml (preferences.xml)
|
||||
content/communicator/bindings/spinbuttons.xml (../../../common/bindings/spinbuttons.xml)
|
||||
* content/communicator/bindings/textbox.xml (../../../common/bindings/textbox.xml)
|
||||
* content/communicator/bindings/toolbar.xml (../../../common/bindings/toolbar.xml)
|
||||
content/communicator/bindings/spinbuttons.xml (spinbuttons.xml)
|
||||
* content/communicator/bindings/textbox.xml (textbox.xml)
|
||||
content/communicator/bindings/toolbar.xml (toolbar.xml)
|
||||
content/communicator/bindings/toolbar-xpfe.xml (toolbar-xpfe.xml)
|
||||
* content/communicator/bindings/prefwindow.xml (prefwindow.xml)
|
||||
|
|
|
@ -0,0 +1,217 @@
|
|||
<?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="numberboxBindings"
|
||||
xmlns="http://www.mozilla.org/xbl"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:xbl="http://www.mozilla.org/xbl">
|
||||
|
||||
<binding id="numberbox" extends="chrome://messenger/content/textbox.xml#textbox">
|
||||
|
||||
<content>
|
||||
<xul:moz-input-box class="textbox-input-box numberbox-input-box" flex="1"
|
||||
xbl:inherits="context,disabled,focused">
|
||||
<html:input class="numberbox-input textbox-input" anonid="input"
|
||||
xbl:inherits="value,maxlength,disabled,size,readonly,placeholder,tabindex,accesskey"/>
|
||||
</xul:moz-input-box>
|
||||
<xul:spinbuttons anonid="buttons" xbl:inherits="disabled,hidden=hidespinbuttons"/>
|
||||
</content>
|
||||
|
||||
<implementation>
|
||||
<field name="_valueEntered">false</field>
|
||||
<field name="_spinButtons">null</field>
|
||||
<field name="_value">0</field>
|
||||
|
||||
<property name="spinButtons" readonly="true">
|
||||
<getter>
|
||||
<![CDATA[
|
||||
if (!this._spinButtons)
|
||||
this._spinButtons = document.getAnonymousElementByAttribute(this, "anonid", "buttons");
|
||||
return this._spinButtons;
|
||||
]]>
|
||||
</getter>
|
||||
</property>
|
||||
|
||||
<property name="value" onget="return '' + this.valueNumber"
|
||||
onset="return this.valueNumber = val;"/>
|
||||
|
||||
<property name="valueNumber">
|
||||
<getter>
|
||||
if (this._valueEntered) {
|
||||
var newval = this.inputField.value;
|
||||
this._validateValue(newval);
|
||||
}
|
||||
return this._value;
|
||||
</getter>
|
||||
<setter>
|
||||
this._validateValue(val);
|
||||
return val;
|
||||
</setter>
|
||||
</property>
|
||||
<property name="min">
|
||||
<getter>
|
||||
var min = this.getAttribute("min");
|
||||
return min ? Number(min) : 0;
|
||||
</getter>
|
||||
<setter>
|
||||
<![CDATA[
|
||||
if (typeof val == "number") {
|
||||
this.setAttribute("min", val);
|
||||
if (this.valueNumber < val)
|
||||
this._validateValue(val);
|
||||
}
|
||||
return val;
|
||||
]]>
|
||||
</setter>
|
||||
</property>
|
||||
|
||||
<property name="max">
|
||||
<getter>
|
||||
var max = this.getAttribute("max");
|
||||
return max ? Number(max) : Infinity;
|
||||
</getter>
|
||||
<setter>
|
||||
<![CDATA[
|
||||
if (typeof val != "number")
|
||||
return val;
|
||||
var min = this.min;
|
||||
if (val < min)
|
||||
val = min;
|
||||
this.setAttribute("max", val);
|
||||
if (this.valueNumber > val)
|
||||
this._validateValue(val);
|
||||
return val;
|
||||
]]>
|
||||
</setter>
|
||||
</property>
|
||||
|
||||
<method name="_modifyUp">
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (this.disabled || this.readOnly)
|
||||
return;
|
||||
var oldval = this.valueNumber;
|
||||
var newval = this._validateValue(this.valueNumber + 1);
|
||||
this.inputField.select();
|
||||
if (oldval != newval)
|
||||
this._fireChange();
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
<method name="_modifyDown">
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (this.disabled || this.readOnly)
|
||||
return;
|
||||
var oldval = this.valueNumber;
|
||||
var newval = this._validateValue(this.valueNumber - 1);
|
||||
this.inputField.select();
|
||||
if (oldval != newval)
|
||||
this._fireChange();
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="_enableDisableButtons">
|
||||
<body>
|
||||
<![CDATA[
|
||||
var buttons = this.spinButtons;
|
||||
if (this.disabled || this.readOnly) {
|
||||
buttons.decreaseDisabled = buttons.increaseDisabled = true;
|
||||
} else {
|
||||
buttons.decreaseDisabled = (this.valueNumber <= this.min);
|
||||
buttons.increaseDisabled = (this.valueNumber >= this.max);
|
||||
}
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="_validateValue">
|
||||
<parameter name="aValue"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
aValue = Number(aValue) || 0;
|
||||
aValue = Math.round(aValue);
|
||||
|
||||
var min = this.min;
|
||||
var max = this.max;
|
||||
if (aValue < min)
|
||||
aValue = min;
|
||||
else if (aValue > max)
|
||||
aValue = max;
|
||||
|
||||
this._valueEntered = false;
|
||||
this._value = Number(aValue);
|
||||
this.inputField.value = aValue;
|
||||
|
||||
this._enableDisableButtons();
|
||||
|
||||
return aValue;
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="_fireChange">
|
||||
<body>
|
||||
var evt = document.createEvent("Events");
|
||||
evt.initEvent("change", true, true);
|
||||
this.dispatchEvent(evt);
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<constructor><![CDATA[
|
||||
if (this.max < this.min)
|
||||
this.max = this.min;
|
||||
|
||||
var value = this.inputField.value || 0;
|
||||
this._validateValue(value);
|
||||
]]></constructor>
|
||||
|
||||
</implementation>
|
||||
|
||||
<handlers>
|
||||
<handler event="input" phase="capturing">
|
||||
this._valueEntered = true;
|
||||
</handler>
|
||||
|
||||
<handler event="keypress">
|
||||
<![CDATA[
|
||||
if (!event.ctrlKey && !event.metaKey && !event.altKey && event.charCode) {
|
||||
if (event.charCode == 45 && this.min < 0)
|
||||
return;
|
||||
|
||||
if (event.charCode < 48 || event.charCode > 57)
|
||||
event.preventDefault();
|
||||
}
|
||||
]]>
|
||||
</handler>
|
||||
|
||||
<handler event="keypress" keycode="VK_UP">
|
||||
this._modifyUp();
|
||||
</handler>
|
||||
|
||||
<handler event="keypress" keycode="VK_DOWN">
|
||||
this._modifyDown();
|
||||
</handler>
|
||||
|
||||
<handler event="up" preventdefault="true">
|
||||
this._modifyUp();
|
||||
</handler>
|
||||
|
||||
<handler event="down" preventdefault="true">
|
||||
this._modifyDown();
|
||||
</handler>
|
||||
|
||||
<handler event="change">
|
||||
if (event.originalTarget == this.inputField) {
|
||||
var newval = this.inputField.value;
|
||||
this._validateValue(newval);
|
||||
}
|
||||
</handler>
|
||||
</handlers>
|
||||
|
||||
</binding>
|
||||
</bindings>
|
|
@ -0,0 +1,92 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!-- 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="spinbuttonsBindings"
|
||||
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="spinbuttons"
|
||||
extends="chrome://global/content/bindings/general.xml#basecontrol">
|
||||
|
||||
<content>
|
||||
<xul:vbox class="spinbuttons-box" flex="1">
|
||||
<xul:button anonid="increaseButton" type="repeat" flex="1"
|
||||
class="spinbuttons-button spinbuttons-up"
|
||||
xbl:inherits="disabled,disabled=increasedisabled"/>
|
||||
<xul:button anonid="decreaseButton" type="repeat" flex="1"
|
||||
class="spinbuttons-button spinbuttons-down"
|
||||
xbl:inherits="disabled,disabled=decreasedisabled"/>
|
||||
</xul:vbox>
|
||||
</content>
|
||||
|
||||
<implementation>
|
||||
<property name="_increaseButton" readonly="true">
|
||||
<getter>
|
||||
return document.getAnonymousElementByAttribute(this, "anonid", "increaseButton");
|
||||
</getter>
|
||||
</property>
|
||||
<property name="_decreaseButton" readonly="true">
|
||||
<getter>
|
||||
return document.getAnonymousElementByAttribute(this, "anonid", "decreaseButton");
|
||||
</getter>
|
||||
</property>
|
||||
|
||||
<property name="increaseDisabled"
|
||||
onget="return this._increaseButton.getAttribute('disabled') == 'true';"
|
||||
onset="if (val) this._increaseButton.setAttribute('disabled', 'true');
|
||||
else this._increaseButton.removeAttribute('disabled'); return val;"/>
|
||||
<property name="decreaseDisabled"
|
||||
onget="return this._decreaseButton.getAttribute('disabled') == 'true';"
|
||||
onset="if (val) this._decreaseButton.setAttribute('disabled', 'true');
|
||||
else this._decreaseButton.removeAttribute('disabled'); return val;"/>
|
||||
</implementation>
|
||||
|
||||
<handlers>
|
||||
<handler event="mousedown">
|
||||
<![CDATA[
|
||||
// on the Mac, the native theme draws the spinbutton as a single widget
|
||||
// so a state attribute is set based on where the mouse button was pressed
|
||||
if (event.originalTarget == this._increaseButton)
|
||||
this.setAttribute("state", "up");
|
||||
else if (event.originalTarget == this._decreaseButton)
|
||||
this.setAttribute("state", "down");
|
||||
]]>
|
||||
</handler>
|
||||
|
||||
<handler event="mouseup">
|
||||
this.removeAttribute("state");
|
||||
</handler>
|
||||
<handler event="mouseout">
|
||||
this.removeAttribute("state");
|
||||
</handler>
|
||||
|
||||
<handler event="command">
|
||||
<![CDATA[
|
||||
var eventname;
|
||||
if (event.originalTarget == this._increaseButton)
|
||||
eventname = "up";
|
||||
else if (event.originalTarget == this._decreaseButton)
|
||||
eventname = "down";
|
||||
|
||||
var evt = document.createEvent("Events");
|
||||
evt.initEvent(eventname, true, true);
|
||||
var cancel = this.dispatchEvent(evt);
|
||||
|
||||
if (this.hasAttribute("on" + eventname)) {
|
||||
var fn = new Function("event", this.getAttribute("on" + eventname));
|
||||
if (!fn.call(this, event))
|
||||
cancel = true;
|
||||
}
|
||||
|
||||
return !cancel;
|
||||
]]>
|
||||
</handler>
|
||||
|
||||
</handlers>
|
||||
</binding>
|
||||
|
||||
</bindings>
|
|
@ -0,0 +1,252 @@
|
|||
<?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/. -->
|
||||
|
||||
<!-- This files relies on these specific Chrome/XBL globals -->
|
||||
<!-- globals ChromeWindow -->
|
||||
|
||||
<!DOCTYPE bindings [
|
||||
<!ENTITY % textcontextDTD SYSTEM "chrome://global/locale/textcontext.dtd" >
|
||||
%textcontextDTD;
|
||||
]>
|
||||
|
||||
<bindings id="textboxBindings"
|
||||
xmlns="http://www.mozilla.org/xbl"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:xbl="http://www.mozilla.org/xbl">
|
||||
|
||||
<binding id="textbox">
|
||||
|
||||
<content>
|
||||
<children/>
|
||||
<xul:moz-input-box class="textbox-input-box" flex="1"
|
||||
xbl:inherits="context,spellcheck">
|
||||
<html:input class="textbox-input" anonid="input"
|
||||
xbl:inherits="value,type,maxlength,disabled,size,readonly,placeholder,tabindex,accesskey,noinitialfocus,mozactionhint,spellcheck"/>
|
||||
</xul:moz-input-box>
|
||||
</content>
|
||||
|
||||
<implementation implements="nsIDOMXULLabeledControlElement">
|
||||
<!-- nsIDOMXULLabeledControlElement -->
|
||||
<field name="crop">""</field>
|
||||
<field name="image">""</field>
|
||||
<field name="command">""</field>
|
||||
<field name="accessKey">""</field>
|
||||
|
||||
<field name="mInputField">null</field>
|
||||
<field name="mIgnoreClick">false</field>
|
||||
<field name="mIgnoreFocus">false</field>
|
||||
<field name="mEditor">null</field>
|
||||
|
||||
<property name="inputField" readonly="true">
|
||||
<getter><![CDATA[
|
||||
if (!this.mInputField)
|
||||
this.mInputField = document.getAnonymousElementByAttribute(this, "anonid", "input");
|
||||
return this.mInputField;
|
||||
]]></getter>
|
||||
</property>
|
||||
|
||||
<property name="value" onset="this.inputField.value = val; return val;"
|
||||
onget="return this.inputField.value;"/>
|
||||
<property name="defaultValue" onset="this.inputField.defaultValue = val; return val;"
|
||||
onget="return this.inputField.defaultValue;"/>
|
||||
<property name="label" onset="this.setAttribute('label', val); return val;"
|
||||
onget="return this.getAttribute('label') ||
|
||||
(this.labelElement ? this.labelElement.value :
|
||||
this.placeholder);"/>
|
||||
<property name="placeholder" onset="this.inputField.placeholder = val; return val;"
|
||||
onget="return this.inputField.placeholder;"/>
|
||||
<property name="emptyText" onset="this.placeholder = val; return val;"
|
||||
onget="return this.placeholder;"/>
|
||||
<property name="type" onset="if (val) this.setAttribute('type', val);
|
||||
else this.removeAttribute('type'); return val;"
|
||||
onget="return this.getAttribute('type');"/>
|
||||
<property name="maxLength" onset="this.inputField.maxLength = val; return val;"
|
||||
onget="return this.inputField.maxLength;"/>
|
||||
<property name="disabled" onset="this.inputField.disabled = val;
|
||||
if (val) this.setAttribute('disabled', 'true');
|
||||
else this.removeAttribute('disabled'); return val;"
|
||||
onget="return this.inputField.disabled;"/>
|
||||
<property name="tabIndex" onget="return parseInt(this.getAttribute('tabindex'));"
|
||||
onset="this.inputField.tabIndex = val;
|
||||
if (val) this.setAttribute('tabindex', val);
|
||||
else this.removeAttribute('tabindex'); return val;"/>
|
||||
<property name="size" onset="this.inputField.size = val; return val;"
|
||||
onget="return this.inputField.size;"/>
|
||||
<property name="readOnly" onset="this.inputField.readOnly = val;
|
||||
if (val) this.setAttribute('readonly', 'true');
|
||||
else this.removeAttribute('readonly'); return val;"
|
||||
onget="return this.inputField.readOnly;"/>
|
||||
<property name="clickSelectsAll"
|
||||
onget="return this.getAttribute('clickSelectsAll') == 'true';"
|
||||
onset="if (val) this.setAttribute('clickSelectsAll', 'true');
|
||||
else this.removeAttribute('clickSelectsAll'); return val;" />
|
||||
|
||||
<property name="editor" readonly="true">
|
||||
<getter><![CDATA[
|
||||
if (!this.mEditor) {
|
||||
this.mEditor = this.inputField.editor;
|
||||
}
|
||||
return this.mEditor;
|
||||
]]></getter>
|
||||
</property>
|
||||
|
||||
<method name="reset">
|
||||
<body><![CDATA[
|
||||
this.value = this.defaultValue;
|
||||
try {
|
||||
this.editor.transactionManager.clear();
|
||||
return true;
|
||||
} catch (e) {}
|
||||
return false;
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="select">
|
||||
<body>
|
||||
this.inputField.select();
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<property name="controllers" readonly="true" onget="return this.inputField.controllers"/>
|
||||
<property name="textLength" readonly="true"
|
||||
onget="return this.inputField.textLength;"/>
|
||||
<property name="selectionStart" onset="this.inputField.selectionStart = val; return val;"
|
||||
onget="return this.inputField.selectionStart;"/>
|
||||
<property name="selectionEnd" onset="this.inputField.selectionEnd = val; return val;"
|
||||
onget="return this.inputField.selectionEnd;"/>
|
||||
|
||||
<method name="setSelectionRange">
|
||||
<parameter name="aSelectionStart"/>
|
||||
<parameter name="aSelectionEnd"/>
|
||||
<body>
|
||||
this.inputField.setSelectionRange(aSelectionStart, aSelectionEnd);
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="_setNewlineHandling">
|
||||
<body><![CDATA[
|
||||
var str = this.getAttribute("newlines");
|
||||
if (str && this.editor) {
|
||||
for (let x in Ci.nsIPlaintextEditor) {
|
||||
if (/^eNewlines/.test(x)) {
|
||||
if (str == RegExp.rightContext.toLowerCase()) {
|
||||
this.editor.QueryInterface(Ci.nsIPlaintextEditor)
|
||||
.newlineHandling = Ci.nsIPlaintextEditor[x];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="_maybeSelectAll">
|
||||
<body><![CDATA[
|
||||
if (!this.mIgnoreClick && this.clickSelectsAll &&
|
||||
document.activeElement == this.inputField &&
|
||||
this.inputField.selectionStart == this.inputField.selectionEnd)
|
||||
this.editor.selectAll();
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<constructor><![CDATA[
|
||||
var str = this.boxObject.getProperty("value");
|
||||
if (str) {
|
||||
this.inputField.value = str;
|
||||
this.boxObject.removeProperty("value");
|
||||
}
|
||||
|
||||
this._setNewlineHandling();
|
||||
|
||||
if (this.hasAttribute("emptytext"))
|
||||
this.placeholder = this.getAttribute("emptytext");
|
||||
]]></constructor>
|
||||
|
||||
<destructor>
|
||||
<![CDATA[
|
||||
var field = this.inputField;
|
||||
if (field && field.value)
|
||||
this.boxObject.setProperty("value", field.value);
|
||||
this.mInputField = null;
|
||||
]]>
|
||||
</destructor>
|
||||
|
||||
</implementation>
|
||||
|
||||
<handlers>
|
||||
<handler event="focus" phase="capturing">
|
||||
<![CDATA[
|
||||
if (this.hasAttribute("focused"))
|
||||
return;
|
||||
|
||||
switch (event.originalTarget) {
|
||||
case this:
|
||||
// Forward focus to actual HTML input
|
||||
this.inputField.focus();
|
||||
break;
|
||||
case this.inputField:
|
||||
if (this.mIgnoreFocus) {
|
||||
this.mIgnoreFocus = false;
|
||||
} else if (this.clickSelectsAll) {
|
||||
try {
|
||||
if (!this.editor || !this.editor.composing)
|
||||
this.editor.selectAll();
|
||||
} catch (e) {}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Allow other children (e.g. URL bar buttons) to get focus
|
||||
return;
|
||||
}
|
||||
this.setAttribute("focused", "true");
|
||||
]]>
|
||||
</handler>
|
||||
|
||||
<handler event="blur" phase="capturing">
|
||||
<![CDATA[
|
||||
this.removeAttribute("focused");
|
||||
|
||||
// don't trigger clickSelectsAll when switching application windows
|
||||
if (window == window.top &&
|
||||
window.isChromeWindow &&
|
||||
document.activeElement == this.inputField)
|
||||
this.mIgnoreFocus = true;
|
||||
]]>
|
||||
</handler>
|
||||
|
||||
<handler event="mousedown">
|
||||
<![CDATA[
|
||||
this.mIgnoreClick = this.hasAttribute("focused");
|
||||
|
||||
if (!this.mIgnoreClick) {
|
||||
this.mIgnoreFocus = true;
|
||||
this.inputField.setSelectionRange(0, 0);
|
||||
if (event.originalTarget == this ||
|
||||
event.originalTarget == this.inputField.parentNode)
|
||||
this.inputField.focus();
|
||||
}
|
||||
]]>
|
||||
</handler>
|
||||
|
||||
<handler event="click" action="this._maybeSelectAll();"/>
|
||||
|
||||
#ifndef XP_WIN
|
||||
<handler event="contextmenu">
|
||||
// Only care about context clicks on the textbox itself.
|
||||
if (event.target != this)
|
||||
return;
|
||||
|
||||
if (!event.button) // context menu opened via keyboard shortcut
|
||||
return;
|
||||
this._maybeSelectAll();
|
||||
// see bug 576135 comment 4
|
||||
let box = this.inputField.parentNode;
|
||||
box._doPopupItemEnabling(box.menupopup);
|
||||
</handler>
|
||||
#endif
|
||||
</handlers>
|
||||
</binding>
|
||||
</bindings>
|
|
@ -0,0 +1,579 @@
|
|||
<?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="toolbarBindings"
|
||||
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="toolbox">
|
||||
<implementation>
|
||||
<field name="palette">
|
||||
null
|
||||
</field>
|
||||
|
||||
<field name="toolbarset">
|
||||
null
|
||||
</field>
|
||||
|
||||
<field name="customToolbarCount">
|
||||
0
|
||||
</field>
|
||||
|
||||
<field name="externalToolbars">
|
||||
[]
|
||||
</field>
|
||||
|
||||
<!-- Set by customizeToolbar.js -->
|
||||
<property name="customizing">
|
||||
<getter><![CDATA[
|
||||
return this.getAttribute("customizing") == "true";
|
||||
]]></getter>
|
||||
<setter><![CDATA[
|
||||
if (val)
|
||||
this.setAttribute("customizing", "true");
|
||||
else
|
||||
this.removeAttribute("customizing");
|
||||
return val;
|
||||
]]></setter>
|
||||
</property>
|
||||
|
||||
<constructor>
|
||||
<![CDATA[
|
||||
// Look to see if there is a toolbarset.
|
||||
this.toolbarset = this.firstChild;
|
||||
while (this.toolbarset && this.toolbarset.localName != "toolbarset")
|
||||
this.toolbarset = this.toolbarset.nextSibling;
|
||||
|
||||
if (this.toolbarset) {
|
||||
// Create each toolbar described by the toolbarset.
|
||||
var index = 0;
|
||||
while (this.toolbarset.hasAttribute("toolbar" + (++index))) {
|
||||
var toolbarInfo = this.toolbarset.getAttribute("toolbar" + index);
|
||||
var infoSplit = toolbarInfo.split(":");
|
||||
this.appendCustomToolbar(infoSplit[0], infoSplit[1]);
|
||||
}
|
||||
}
|
||||
]]>
|
||||
</constructor>
|
||||
|
||||
<method name="appendCustomToolbar">
|
||||
<parameter name="aName"/>
|
||||
<parameter name="aCurrentSet"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (!this.toolbarset)
|
||||
return null;
|
||||
var toolbar = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
|
||||
"toolbar");
|
||||
toolbar.id = "__customToolbar_" + aName.replace(" ", "_");
|
||||
toolbar.setAttribute("customizable", "true");
|
||||
toolbar.setAttribute("customindex", ++this.customToolbarCount);
|
||||
toolbar.setAttribute("toolbarname", aName);
|
||||
toolbar.setAttribute("currentset", aCurrentSet);
|
||||
toolbar.setAttribute("mode", this.getAttribute("mode"));
|
||||
toolbar.setAttribute("iconsize", this.getAttribute("iconsize"));
|
||||
toolbar.setAttribute("context", this.toolbarset.getAttribute("context"));
|
||||
toolbar.setAttribute("class", "chromeclass-toolbar");
|
||||
|
||||
this.insertBefore(toolbar, this.toolbarset);
|
||||
return toolbar;
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
</implementation>
|
||||
</binding>
|
||||
|
||||
<binding id="toolbar" role="xul:toolbar">
|
||||
<implementation>
|
||||
<property name="toolbarName"
|
||||
onget="return this.getAttribute('toolbarname');"
|
||||
onset="this.setAttribute('toolbarname', val); return val;"/>
|
||||
|
||||
<field name="_toolbox">null</field>
|
||||
<property name="toolbox" readonly="true">
|
||||
<getter><![CDATA[
|
||||
if (this._toolbox)
|
||||
return this._toolbox;
|
||||
|
||||
let toolboxId = this.getAttribute("toolboxid");
|
||||
if (toolboxId) {
|
||||
let toolbox = document.getElementById(toolboxId);
|
||||
if (!toolbox) {
|
||||
let tbName = this.toolbarName;
|
||||
if (tbName)
|
||||
tbName = " (" + tbName + ")";
|
||||
else
|
||||
tbName = "";
|
||||
throw new Error(`toolbar ID ${this.id}${tbName}: toolboxid attribute '${toolboxId}' points to a toolbox that doesn't exist`);
|
||||
}
|
||||
|
||||
if (!toolbox.externalToolbars.includes(this))
|
||||
toolbox.externalToolbars.push(this);
|
||||
|
||||
return this._toolbox = toolbox;
|
||||
}
|
||||
|
||||
return this._toolbox = (this.parentNode &&
|
||||
this.parentNode.localName == "toolbox") ?
|
||||
this.parentNode : null;
|
||||
]]></getter>
|
||||
</property>
|
||||
|
||||
<constructor>
|
||||
<![CDATA[
|
||||
if (document.readyState == "complete") {
|
||||
this._init();
|
||||
} else {
|
||||
// Need to wait until XUL overlays are loaded. See bug 554279.
|
||||
let self = this;
|
||||
document.addEventListener("readystatechange", function listener(event) {
|
||||
if (document.readyState != "complete")
|
||||
return;
|
||||
document.removeEventListener("readystatechange", listener);
|
||||
self._init();
|
||||
});
|
||||
}
|
||||
]]>
|
||||
</constructor>
|
||||
|
||||
<method name="_init">
|
||||
<body>
|
||||
<![CDATA[
|
||||
// Searching for the toolbox palette in the toolbar binding because
|
||||
// toolbars are constructed first.
|
||||
var toolbox = this.toolbox;
|
||||
if (!toolbox)
|
||||
return;
|
||||
|
||||
if (!toolbox.palette) {
|
||||
// Look to see if there is a toolbarpalette.
|
||||
var node = toolbox.firstChild;
|
||||
while (node) {
|
||||
if (node.localName == "toolbarpalette")
|
||||
break;
|
||||
node = node.nextSibling;
|
||||
}
|
||||
|
||||
if (!node)
|
||||
return;
|
||||
|
||||
// Hold on to the palette but remove it from the document.
|
||||
toolbox.palette = node;
|
||||
toolbox.removeChild(node);
|
||||
}
|
||||
|
||||
// Build up our contents from the palette.
|
||||
var currentSet = this.getAttribute("currentset");
|
||||
if (!currentSet)
|
||||
currentSet = this.getAttribute("defaultset");
|
||||
if (currentSet)
|
||||
this.currentSet = currentSet;
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="_idFromNode">
|
||||
<parameter name="aNode"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (aNode.getAttribute("skipintoolbarset") == "true")
|
||||
return "";
|
||||
|
||||
switch (aNode.localName) {
|
||||
case "toolbarseparator":
|
||||
return "separator";
|
||||
case "toolbarspring":
|
||||
return "spring";
|
||||
case "toolbarspacer":
|
||||
return "spacer";
|
||||
default:
|
||||
return aNode.id;
|
||||
}
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<property name="currentSet">
|
||||
<getter>
|
||||
<![CDATA[
|
||||
var node = this.firstChild;
|
||||
var currentSet = [];
|
||||
while (node) {
|
||||
var id = this._idFromNode(node);
|
||||
if (id) {
|
||||
currentSet.push(id);
|
||||
}
|
||||
node = node.nextSibling;
|
||||
}
|
||||
|
||||
return currentSet.join(",") || "__empty";
|
||||
]]>
|
||||
</getter>
|
||||
|
||||
<setter>
|
||||
<![CDATA[
|
||||
if (val == this.currentSet)
|
||||
return val;
|
||||
|
||||
var ids = (val == "__empty") ? [] : val.split(",");
|
||||
|
||||
var nodeidx = 0;
|
||||
var paletteItems = { }, added = { };
|
||||
|
||||
var palette = this.toolbox ? this.toolbox.palette : null;
|
||||
|
||||
// build a cache of items in the toolbarpalette
|
||||
var paletteChildren = palette ? palette.childNodes : [];
|
||||
for (let c = 0; c < paletteChildren.length; c++) {
|
||||
let curNode = paletteChildren[c];
|
||||
paletteItems[curNode.id] = curNode;
|
||||
}
|
||||
|
||||
var children = this.childNodes;
|
||||
|
||||
// iterate over the ids to use on the toolbar
|
||||
for (let i = 0; i < ids.length; i++) {
|
||||
let id = ids[i];
|
||||
// iterate over the existing nodes on the toolbar. nodeidx is the
|
||||
// spot where we want to insert items.
|
||||
let found = false;
|
||||
for (let c = nodeidx; c < children.length; c++) {
|
||||
let curNode = children[c];
|
||||
if (this._idFromNode(curNode) == id) {
|
||||
// the node already exists. If c equals nodeidx, we haven't
|
||||
// iterated yet, so the item is already in the right position.
|
||||
// Otherwise, insert it here.
|
||||
if (c != nodeidx) {
|
||||
this.insertBefore(curNode, children[nodeidx]);
|
||||
}
|
||||
|
||||
added[curNode.id] = true;
|
||||
nodeidx++;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
// move on to the next id
|
||||
continue;
|
||||
}
|
||||
|
||||
// the node isn't already on the toolbar, so add a new one.
|
||||
var nodeToAdd = paletteItems[id] || this._getToolbarItem(id);
|
||||
if (nodeToAdd && !(nodeToAdd.id in added)) {
|
||||
added[nodeToAdd.id] = true;
|
||||
this.insertBefore(nodeToAdd, children[nodeidx] || null);
|
||||
nodeToAdd.setAttribute("removable", "true");
|
||||
nodeidx++;
|
||||
}
|
||||
}
|
||||
|
||||
// remove any leftover removable nodes
|
||||
for (let i = children.length - 1; i >= nodeidx; i--) {
|
||||
let curNode = children[i];
|
||||
|
||||
let curNodeId = this._idFromNode(curNode);
|
||||
// skip over fixed items
|
||||
if (curNodeId && curNode.getAttribute("removable") == "true") {
|
||||
if (palette)
|
||||
palette.appendChild(curNode);
|
||||
else
|
||||
this.removeChild(curNode);
|
||||
}
|
||||
}
|
||||
|
||||
return val;
|
||||
]]>
|
||||
</setter>
|
||||
</property>
|
||||
|
||||
<field name="_newElementCount">0</field>
|
||||
<method name="_getToolbarItem">
|
||||
<parameter name="aId"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
const XUL_NS = "http://www.mozilla.org/keymaster/" +
|
||||
"gatekeeper/there.is.only.xul";
|
||||
|
||||
var newItem = null;
|
||||
switch (aId) {
|
||||
// Handle special cases
|
||||
case "separator":
|
||||
case "spring":
|
||||
case "spacer":
|
||||
newItem = document.createElementNS(XUL_NS, "toolbar" + aId);
|
||||
// Due to timers resolution Date.now() can be the same for
|
||||
// elements created in small timeframes. So ids are
|
||||
// differentiated through a unique count suffix.
|
||||
newItem.id = aId + Date.now() + (++this._newElementCount);
|
||||
if (aId == "spring")
|
||||
newItem.flex = 1;
|
||||
break;
|
||||
default:
|
||||
var toolbox = this.toolbox;
|
||||
if (!toolbox)
|
||||
break;
|
||||
|
||||
// look for an item with the same id, as the item may be
|
||||
// in a different toolbar.
|
||||
var item = document.getElementById(aId);
|
||||
if (item && item.parentNode &&
|
||||
item.parentNode.localName == "toolbar" &&
|
||||
item.parentNode.toolbox == toolbox) {
|
||||
newItem = item;
|
||||
break;
|
||||
}
|
||||
|
||||
if (toolbox.palette) {
|
||||
// Attempt to locate an item with a matching ID within
|
||||
// the palette.
|
||||
let paletteItem = this.toolbox.palette.firstChild;
|
||||
while (paletteItem) {
|
||||
if (paletteItem.id == aId) {
|
||||
newItem = paletteItem;
|
||||
break;
|
||||
}
|
||||
paletteItem = paletteItem.nextSibling;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return newItem;
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="insertItem">
|
||||
<parameter name="aId"/>
|
||||
<parameter name="aBeforeElt"/>
|
||||
<parameter name="aWrapper"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
var newItem = this._getToolbarItem(aId);
|
||||
if (!newItem)
|
||||
return null;
|
||||
|
||||
var insertItem = newItem;
|
||||
// make sure added items are removable
|
||||
newItem.setAttribute("removable", "true");
|
||||
|
||||
// Wrap the item in another node if so inclined.
|
||||
if (aWrapper) {
|
||||
aWrapper.appendChild(newItem);
|
||||
insertItem = aWrapper;
|
||||
}
|
||||
|
||||
// Insert the palette item into the toolbar.
|
||||
if (aBeforeElt)
|
||||
this.insertBefore(insertItem, aBeforeElt);
|
||||
else
|
||||
this.appendChild(insertItem);
|
||||
|
||||
return newItem;
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="hasCustomInteractiveItems">
|
||||
<parameter name="aCurrentSet"/>
|
||||
<body><![CDATA[
|
||||
if (aCurrentSet == "__empty")
|
||||
return false;
|
||||
|
||||
var defaultOrNoninteractive = (this.getAttribute("defaultset") || "")
|
||||
.split(",")
|
||||
.concat(["separator", "spacer", "spring"]);
|
||||
return aCurrentSet.split(",").some(item => !defaultOrNoninteractive.includes(item));
|
||||
]]></body>
|
||||
</method>
|
||||
</implementation>
|
||||
</binding>
|
||||
|
||||
<binding id="toolbar-menubar-autohide"
|
||||
extends="chrome://communicator/content/bindings/toolbar.xml#toolbar">
|
||||
<implementation>
|
||||
<constructor>
|
||||
this._setInactive();
|
||||
</constructor>
|
||||
<destructor>
|
||||
this._setActive();
|
||||
</destructor>
|
||||
|
||||
<field name="_inactiveTimeout">null</field>
|
||||
|
||||
<field name="_contextMenuListener"><![CDATA[({
|
||||
toolbar: this,
|
||||
contextMenu: null,
|
||||
|
||||
get active() {
|
||||
return !!this.contextMenu;
|
||||
},
|
||||
|
||||
init(event) {
|
||||
var node = event.target;
|
||||
while (node != this.toolbar) {
|
||||
if (node.localName == "menupopup")
|
||||
return;
|
||||
node = node.parentNode;
|
||||
}
|
||||
|
||||
var contextMenuId = this.toolbar.getAttribute("context");
|
||||
if (!contextMenuId)
|
||||
return;
|
||||
|
||||
this.contextMenu = document.getElementById(contextMenuId);
|
||||
if (!this.contextMenu)
|
||||
return;
|
||||
|
||||
this.contextMenu.addEventListener("popupshown", this);
|
||||
this.contextMenu.addEventListener("popuphiding", this);
|
||||
this.toolbar.addEventListener("mousemove", this);
|
||||
},
|
||||
handleEvent(event) {
|
||||
switch (event.type) {
|
||||
case "popupshown":
|
||||
this.toolbar.removeEventListener("mousemove", this);
|
||||
break;
|
||||
case "popuphiding":
|
||||
case "mousemove":
|
||||
this.toolbar._setInactiveAsync();
|
||||
this.toolbar.removeEventListener("mousemove", this);
|
||||
this.contextMenu.removeEventListener("popuphiding", this);
|
||||
this.contextMenu.removeEventListener("popupshown", this);
|
||||
this.contextMenu = null;
|
||||
break;
|
||||
}
|
||||
},
|
||||
})]]></field>
|
||||
|
||||
<method name="_setInactive">
|
||||
<body><![CDATA[
|
||||
this.setAttribute("inactive", "true");
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="_setInactiveAsync">
|
||||
<body><![CDATA[
|
||||
this._inactiveTimeout = setTimeout(function(self) {
|
||||
if (self.getAttribute("autohide") == "true") {
|
||||
self._inactiveTimeout = null;
|
||||
self._setInactive();
|
||||
}
|
||||
}, 0, this);
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="_setActive">
|
||||
<body><![CDATA[
|
||||
if (this._inactiveTimeout) {
|
||||
clearTimeout(this._inactiveTimeout);
|
||||
this._inactiveTimeout = null;
|
||||
}
|
||||
this.removeAttribute("inactive");
|
||||
]]></body>
|
||||
</method>
|
||||
</implementation>
|
||||
|
||||
<handlers>
|
||||
<handler event="DOMMenuBarActive" action="this._setActive();"/>
|
||||
<handler event="popupshowing" action="this._setActive();"/>
|
||||
<handler event="mousedown" button="2" action="this._contextMenuListener.init(event);"/>
|
||||
<handler event="DOMMenuBarInactive"><![CDATA[
|
||||
if (!this._contextMenuListener.active)
|
||||
this._setInactiveAsync();
|
||||
]]></handler>
|
||||
</handlers>
|
||||
</binding>
|
||||
|
||||
<binding id="menubar" role="xul:menubar">
|
||||
<implementation>
|
||||
<field name="_active">false</field>
|
||||
<field name="_statusbar">null</field>
|
||||
<field name="_originalStatusText">null</field>
|
||||
<property name="statusbar" onget="return this.getAttribute('statusbar');"
|
||||
onset="this.setAttribute('statusbar', val); return val;"/>
|
||||
<method name="_updateStatusText">
|
||||
<parameter name="itemText"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (!this._active)
|
||||
return;
|
||||
var newText = itemText ? itemText : this._originalStatusText;
|
||||
if (newText != this._statusbar.label)
|
||||
this._statusbar.label = newText;
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
</implementation>
|
||||
<handlers>
|
||||
<handler event="DOMMenuBarActive">
|
||||
<![CDATA[
|
||||
if (!this.statusbar) return;
|
||||
this._statusbar = document.getElementById(this.statusbar);
|
||||
if (!this._statusbar)
|
||||
return;
|
||||
this._active = true;
|
||||
this._originalStatusText = this._statusbar.label;
|
||||
]]>
|
||||
</handler>
|
||||
<handler event="DOMMenuBarInactive">
|
||||
<![CDATA[
|
||||
if (!this._active)
|
||||
return;
|
||||
this._active = false;
|
||||
this._statusbar.label = this._originalStatusText;
|
||||
]]>
|
||||
</handler>
|
||||
<handler event="DOMMenuItemActive">this._updateStatusText(event.target.statusText);</handler>
|
||||
<handler event="DOMMenuItemInactive">this._updateStatusText("");</handler>
|
||||
</handlers>
|
||||
</binding>
|
||||
|
||||
<binding id="toolbarpaletteitem">
|
||||
<content>
|
||||
<xul:hbox class="toolbarpaletteitem-box" flex="1" xbl:inherits="type,place">
|
||||
<children/>
|
||||
</xul:hbox>
|
||||
</content>
|
||||
</binding>
|
||||
|
||||
<binding id="toolbarpaletteitem-palette"
|
||||
extends="chrome://communicator/content/bindings/toolbar.xml#toolbarpaletteitem">
|
||||
<content>
|
||||
<xul:hbox class="toolbarpaletteitem-box" xbl:inherits="type,place">
|
||||
<children/>
|
||||
</xul:hbox>
|
||||
<xul:label xbl:inherits="value=title"/>
|
||||
</content>
|
||||
</binding>
|
||||
|
||||
<binding id="toolbarpaletteitem-palette-wrapping-label"
|
||||
extends="chrome://communicator/content/bindings/toolbar.xml#toolbarpaletteitem">
|
||||
<content>
|
||||
<xul:hbox class="toolbarpaletteitem-box" xbl:inherits="type,place">
|
||||
<children/>
|
||||
</xul:hbox>
|
||||
<xul:label xbl:inherits="xbl:text=title"/>
|
||||
</content>
|
||||
</binding>
|
||||
|
||||
<binding id="menu-button"
|
||||
extends="chrome://global/content/bindings/button.xml#button-base">
|
||||
|
||||
<content>
|
||||
<children includes="observes|template|menupopup|panel|tooltip"/>
|
||||
<xul:toolbarbutton class="box-inherit toolbarbutton-menubutton-button"
|
||||
anonid="button" flex="1" allowevents="true"
|
||||
xbl:inherits="disabled,crop,image,label,accesskey,command,wrap,badge,
|
||||
align,dir,pack,orient,tooltiptext=buttontooltiptext"/>
|
||||
<xul:dropmarker type="menu-button" class="toolbarbutton-menubutton-dropmarker"
|
||||
anonid="dropmarker" xbl:inherits="align,dir,pack,orient,disabled,label,open,consumeanchor"/>
|
||||
</content>
|
||||
</binding>
|
||||
|
||||
</bindings>
|
Загрузка…
Ссылка в новой задаче