This commit is contained in:
ben%bengoodger.com 2004-12-01 04:48:44 +00:00
Родитель 9125da2795
Коммит b603528092
20 изменённых файлов: 1015 добавлений и 743 удалений

Просмотреть файл

@ -55,7 +55,7 @@
<xul:image class="autocomplete-icon" allowevents="true"/>
</children>
<xul:hbox class="textbox-input-box" flex="1" xbl:inherits="tooltiptext=inputtooltiptext">
<xul:hbox anonid="textbox-input-box" class="textbox-input-box" flex="1" xbl:inherits="tooltiptext=inputtooltiptext">
<children/>
<html:input anonid="input" class="autocomplete-textbox textbox-input"
flex="1" allowevents="true"
@ -238,17 +238,8 @@
<!-- =================== PUBLIC MEMBERS =================== -->
<property name="value"
onget="return this.mInputElt.value;">
<setter><![CDATA[
this.mIgnoreInput = true;
this.mInputElt.value = val;
this.mIgnoreInput = false;
var event = document.createEvent('Events');
event.initEvent('ValueChange', true, true);
this.mInputElt.dispatchEvent(event);
return val;
]]></setter>
</property>
onget="return this.mInputElt.value;"
onset="this.mIgnoreInput = true; this.mInputElt.value = val; this.mIgnoreInput = false; return val;"/>
<property name="focused" readonly="true"
onget="return this.getAttribute('focused') == 'true';"/>
@ -348,7 +339,7 @@
var cancel = false;
const IController = Components.interfaces.nsIAutoCompleteController;
if (!this.disableKeyNavigation && !aEvent.ctrlKey && !aEvent.altKey) {
if (!this.disableKeyNavigation) {
switch (aEvent.keyCode) {
case KeyEvent.DOM_VK_TAB:
if (this.tabScrolling && this.popup.mPopupOpen)
@ -484,11 +475,6 @@
this.tree.view.selection.select(val);
if (this.tree.treeBoxObject.height > 0)
this.tree.treeBoxObject.ensureRowIsVisible(val < 0 ? 0 : val);
// Fire select event on xul:tree so that accessibility API
// support layer can fire appropriate accessibility events.
var event = document.createEvent('Events');
event.initEvent("select", true, true);
this.tree.dispatchEvent(event);
return val;
]]></setter>
</property>

Просмотреть файл

@ -34,6 +34,11 @@
- GPL.
-->
<!DOCTYPE window [
<!ENTITY % findBarDTD SYSTEM "chrome://global/locale/findBar.dtd" >
%findBarDTD;
]>
<bindings id="browserBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
@ -144,6 +149,7 @@
<parameter name="aFlags"/>
<parameter name="aReferrerURI"/>
<parameter name="aCharset"/>
<parameter name="aPostData"/>
<body>
<![CDATA[
if (!aURI)
@ -156,7 +162,8 @@
catch (e) {
}
}
this.webNavigation.loadURI(aURI, aFlags, aReferrerURI, null, null);
this.mFavIconURL = null;
this.webNavigation.loadURI(aURI, aFlags, aReferrerURI, aPostData, null);
]]>
</body>
</method>
@ -232,6 +239,36 @@
</getter>
</property>
<field name="_fastFind">null</field>
<property name="fastFind"
readonly="true">
<getter>
<![CDATA[
if (!this._fastFind) {
var n = this.parentNode;
while (n && n.localName != "tabbrowser")
n = n.parentNode;
if (n && n.mCurrentBrowser == this)
return this._fastFind = n.fastFind
this._fastFind = Components.classes["@mozilla.org/typeaheadfind;1"]
.createInstance(Components.interfaces.nsITypeAheadFind);
this._fastFind.init(this.docShell);
}
return this._fastFind;
]]>
</getter>
</property>
<property name="findString" readonly="true">
<getter>
<![CDATA[
return this.fastFind.searchString;
]]>
</getter>
</property>
<property name="webProgress"
readonly="true"
onget="return this.docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIWebProgress);"/>
@ -349,12 +386,46 @@
</body>
</method>
<method name="findChildShell">
<parameter name="aDocShell"/>
<parameter name="aSoughtURI"/>
<body>
<![CDATA[
if (aDocShell.QueryInterface(Components.interfaces.nsIWebNavigation)
.currentURI.spec == aSoughtURI.spec)
return aDocShell;
var node = aDocShell.QueryInterface(
Components.interfaces.nsIDocShellTreeNode);
for (var i = 0; i < node.childCount; ++i) {
var docShell = node.getChildAt(i);
docShell = this.findChildShell(docShell, aSoughtURI);
if (docShell)
return docShell;
}
return null;
]]>
</body>
</method>
<method name="onLoad">
<parameter name="aEvent"/>
<body>
<![CDATA[
this.removeEventListener("load", this.handleEvent, true);
this.attachFormFill();
if (this.pageReport) {
var i = 0;
while (i < this.pageReport.length) {
if (this.findChildShell(this.docShell,
this.pageReport[i].requestingWindowURI))
i++;
else
this.pageReport.splice(i, 1);
}
if (this.pageReport.length == 0) {
this.pageReport = null;
this.updatePageReport();
}
}
]]>
</body>
</method>
@ -396,8 +467,10 @@
this.updatePageReport();
}
// The "" is a hack to force a convert to string to defeat the "liveness" of the .location property.
this.pageReport.push(evt.target.location + "");
var obj = { requestingWindowURI: evt.requestingWindowURI,
popupWindowURI: evt.popupWindowURI,
popupWindowFeatures: evt.popupWindowFeatures };
this.pageReport.push(obj);
]]>
</body>
</method>
@ -411,7 +484,7 @@
<field name="securityUI">
null
</field>
<field name="userTypedClear">
true
</field>
@ -434,8 +507,14 @@
<field name="focusedElement">
null
</field>
<field name="isShowingMessage">
false
</field>
<field name="mFavIconURL">null</field>
<constructor>
<![CDATA[
try {
@ -497,7 +576,9 @@
this.detachFormFill();
this.securityUI = null;
this._fastFind = null;
this.removeEventListener("load", this.onLoad, true);
this.removeEventListener("unload", this.onUnload, true);
this.removeEventListener("DOMPopupBlocked", this.onPopupBlocked, true);
]]>
@ -786,5 +867,142 @@
</handlers>
</binding>
<binding id="browsermessage" extends="xul:hbox">
<content align="center">
<xul:hbox anonid="messagePopupContainer" align="center" flex="1">
<xul:image anonid="messageImage" class="messageImage"/>
<xul:description anonid="messageText" class="messageText" flex="1"/>
</xul:hbox>
<xul:button anonid="messageButton" class="messageButton"/>
<xul:spacer class="tabs-right"/>
<xul:hbox hidden="true" anonid="messageClose" class="tabs-closebutton-box"
align="center" pack="end">
<xul:toolbarbutton ondblclick="event.preventBubble();"
class="tabs-closebutton close-button"
oncommand="this.parentNode.parentNode.hide();"/>
</xul:hbox>
</content>
<implementation>
<property name="type" onget="return this.getAttribute('type');"
onset="this.setAttribute('type', val); return val;"/>
<field name="_imageElement">
document.getAnonymousElementByAttribute(this, "anonid", "messageImage");
</field>
<property name="image">
<getter>
<![CDATA[
return this._imageElement.getAttribute("src");
]]>
</getter>
<setter>
<![CDATA[
this._imageElement.setAttribute("src", val);
return val;
]]>
</setter>
</property>
<field name="docShell">
null;
</field>
<field name="source">
"";
</field>
<property name="popup">
<setter>
<![CDATA[
if (val)
document.getAnonymousElementByAttribute(this, "anonid", "messagePopupContainer").setAttribute("popup", val);
else
document.getAnonymousElementByAttribute(this, "anonid", "messagePopupContainer").removeAttribute("popup");
return val;
]]>
</setter>
<getter>
<![CDATA[
return document.getAnonymousElementByAttribute(this, "anonid", "messagePopupContainer").getAttribute("popup");
]]>
</getter>
</property>
<field name="_textElement">
document.getAnonymousElementByAttribute(this, "anonid", "messageText");
</field>
<field name="_text">
"";
</field>
<property name="text">
<getter>
<![CDATA[
return this._text;
]]>
</getter>
<setter>
<![CDATA[
this._text = val;
while (this._textElement.hasChildNodes())
this._textElement.removeChild(this._textElement.firstChild);
this._textElement.appendChild(document.createTextNode(val));
return val;
]]>
</setter>
</property>
<field name="_buttonElement">
document.getAnonymousElementByAttribute(this, "anonid", "messageButton");
</field>
<property name="buttonText">
<getter>
<![CDATA[
return this._buttonElement.getAttribute("label");
]]>
</getter>
<setter>
<![CDATA[
if (val != "") {
this._buttonElement.removeAttribute("style");
this._buttonElement.setAttribute("label", val);
}
else
this._buttonElement.setAttribute("style", "max-width: 1px; visibility: hidden;");
return val;
]]>
</setter>
</property>
<property name="closeButton">
<getter>
<![CDATA[
return document.getAnonymousElementByAttribute(this, "anonid", "messageClose");
]]>
</getter>
<setter>
<![CDATA[
var elm = document.getAnonymousElementByAttribute(this, "anonid", "messageClose");
elm.hidden = !val;
return val;
]]>
</setter>
</property>
<method name="hide">
<body>
<![CDATA[
this.hidden = true;
]]>
</body>
</method>
</implementation>
<handlers>
<handler event="click">
if (event.originalTarget.getAttribute("anonid") == "messageButton") {
var os = Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
var subject = this.docShell ? this.docShell : null;
os.notifyObservers(subject, this.source, "");
}
</handler>
</handlers>
</binding>
</bindings>

Просмотреть файл

@ -167,7 +167,7 @@
}
}
var cells = this.mBox.getElementsByAttribute("color", val);
if (cells.item(0)) {
if (cells.length > 0) {
this.selectCell(cells[0]);
this.hoverCell(this.mSelectedCell);
}
@ -472,6 +472,20 @@
]]></body>
</method>
<method name="getElementByanonid">
<parameter name="aValue"/>
<body><![CDATA[
var nodes = document.getAnonymousNodes(this);
var results;
for (var i = 0; i < nodes.length; i++) {
results = nodes[i].getElementsByAttribute("anonid", aValue);
if (results.length > 0)
return results[0];
}
return null;
]]></body>
</method>
<method name="showPopup">
<body><![CDATA[
this.mPicker.parentNode.showPopup(this, -1, -1, "popup", "bottomleft", "topleft");

Просмотреть файл

@ -150,18 +150,8 @@
var focusInit =
function() {
// give focus to the first focusable element in the dialog
if (!document.commandDispatcher.focusedElement) {
if (!document.commandDispatcher.focusedElement)
document.commandDispatcher.advanceFocusIntoSubtree(document.documentElement);
var focusedElt = document.commandDispatcher.focusedElement;
if (focusedElt && focusedElt.localName == 'tab') {
// We don't want to focus on anonymous OK, Cancel, etc. buttons
document.commandDispatcher.advanceFocusIntoSubtree(focusedElt);
if (document.commandDispatcher.focusedElement.hasAttribute("dlgtype")) {
// Prefer to keep focus on label rather than focus a dialog button
focusedElt.focus();
}
}
}
};
// Give focus after onload completes, see bug 103197.
@ -215,6 +205,7 @@
for (dlgtype in buttons) {
var button = buttons[dlgtype];
button.addEventListener("command", this._handleButtonCommand, true);
// don't override custom labels with pre-defined labels on explicit buttons
if (!button.hasAttribute("label")) {

Просмотреть файл

@ -74,10 +74,10 @@
onget="return this.docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIWebBrowserFind);"/>
<property name="editingSession"
readonly="true"
onget="return this.webNavigation.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIEditingSession);"/>
onget="return this.webNavigation.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIEditingSession);"/>"
<property name="commandManager"
readonly="true"
onget="return this.webNavigation.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsICommandManager);"/>
onget="return this.webNavigation.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsICommandManager);"/>"
</implementation>
</binding>

Просмотреть файл

@ -18,27 +18,8 @@
onget="return this.getAttribute('disabled') == 'true';"/>
<property name="image" onset="return this.setAttribute('image',val);"
onget="return this.getAttribute('image');"/>
<property name="accessKey">
<getter>
<![CDATA[
return this.labelElement ? this.labelElement.accessKey : this.getAttribute('accesskey');
]]>
</getter>
<setter>
<![CDATA[
// Always store on the control
this.setAttribute('accesskey', val);
// If there is a label, change the accesskey on the labelElement
// if it's also set there
if (this.labelElement) {
this.labelElement.accessKey = val;
}
return val;
]]>
</setter>
</property>
<field name="labelElement"/>
<property name="accessKey" onset="return this.setAttribute('accesskey',val);"
onget="return this.getAttribute('accesskey');"/>
</implementation>
</binding>
@ -272,6 +253,14 @@
</content>
</binding>
<binding id="statusbarpanel-iconic-text" display="xul:button"
extends="chrome://global/content/bindings/general.xml#statusbarpanel">
<content>
<xul:image class="statusbarpanel-icon" xbl:inherits="src"/>
<xul:label class="statusbarpanel-text" xbl:inherits="value=label,crop"/>
</content>
</binding>
<binding id="image">
<implementation implements="nsIDOMXULImageElement, nsIAccessibleProvider">
<property name="src"

Просмотреть файл

@ -158,7 +158,7 @@
<setter>
<![CDATA[
var kids = this.getElementsByAttribute("value", val);
if (kids && kids.item(0))
if (kids && kids.length)
this.selectItem(kids[0]);
return val;
]]>

Просмотреть файл

@ -104,17 +104,6 @@
</content>
</binding>
<binding id="menuitem-iconic-desc-noaccel" extends="chrome://global/content/bindings/menu.xml#menuitem">
<content>
<xul:hbox class="menu-iconic-left" align="center" pack="center"
xbl:inherits="selected,disabled,checked">
<xul:image class="menu-iconic-icon" xbl:inherits="src=image,validate,src"/>
</xul:hbox>
<xul:label class="menu-iconic-text" xbl:inherits="value=label,accesskey,crop" crop="right" flex="1"/>
<xul:label class="menu-iconic-text menu-description" xbl:inherits="value=description" crop="right" flex="10000"/>
</content>
</binding>
<binding id="menu-iconic" extends="chrome://global/content/bindings/menu.xml#menuitem-base">
<content>
<xul:hbox class="menu-iconic-left" align="center" pack="center">

Просмотреть файл

@ -24,25 +24,25 @@
</content>
<handlers>
<handler event="command" phase="capturing"
action="if (event.target.parentNode.parentNode == this) this.selectedItem = event.target;"/>
<handler event="command" phase="capturing">
<![CDATA[
// XXX see bug #196755
// originalTarget is workaround for arrowscrollbox retargeting bug
if (event.originalTarget.parentNode.parentNode == this)
this.selectedItem = event.originalTarget;
]]>
</handler>
<handler event="popupshowing">
<![CDATA[
if (event.target.parentNode == this && this.selectedItem)
// XXX see bug #196755
// originalTarget is workaround for arrowscrollbox retargeting bug
if (event.originalTarget.parentNode == this && this.selectedItem)
// Not ready for auto-setting the active child in hierarchies yet.
// For now, only do this when the outermost menupopup opens.
this.menuBoxObject.activeChild = this.selectedInternal;
]]>
</handler>
<handler event="keypress" phase="target">
<![CDATA[
this.menuBoxObject.activeChild = this.selectedInternal;
if (this.menuBoxObject.handleKeyPress(event))
this.menuBoxObject.activeChild.doCommand();
]]>
</handler>
</handlers>
<implementation implements="nsIDOMXULMenuListElement, nsIAccessibleProvider">
@ -57,10 +57,10 @@
if (popup) {
var arr = popup.getElementsByAttribute('selected', 'true');
if (!arr.item(0) && this.value)
if (!arr.length && this.value)
arr = popup.getElementsByAttribute('value', this.value);
if (arr.item(0))
if (arr.length)
this.selectedItem = arr[0];
else
this.selectedIndex = 0;
@ -77,7 +77,7 @@
if (popup)
arr = popup.getElementsByAttribute('value', val);
if (arr && arr.item(0))
if (arr && arr.length)
this.selectedItem = arr[0];
else
this.setAttribute('value', val);
@ -91,9 +91,8 @@
onget="return this.getAttribute('crop');"/>
<property name="src" onset="this.setAttribute('src',val); return val;"
onget="return this.getAttribute('src');"/>
<property name="label" readonly="true" onget="return this.getAttribute('label');"/>
<property name="description" onset="this.setAttribute('description',val); return val;"
onget="return this.getAttribute('description');"/>
<property name="label" onset="this.setAttribute('label',val); return val;"
onget="return this.getAttribute('label');"/>
<property name="disabled" onset="if (val) this.setAttribute('disabled',true);
else this.removeAttribute('disabled');
return val;"
@ -171,7 +170,6 @@
this.removeAttribute('value');
this.removeAttribute('src');
this.removeAttribute('label');
this.removeAttribute('description');
return val;
}
@ -180,7 +178,6 @@
this.setAttribute('value', val.getAttribute('value'));
this.setAttribute('src', val.getAttribute('src'));
this.setAttribute('label', val.getAttribute('label'));
this.setAttribute('description', val.getAttribute('description'));
return val;
]]>
@ -190,7 +187,6 @@
<method name="appendItem">
<parameter name="label"/>
<parameter name="value"/>
<parameter name="description"/>
<body>
<![CDATA[
const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
@ -199,9 +195,6 @@
var item = document.createElementNS(XULNS, "menuitem");
item.setAttribute("label", label);
item.setAttribute("value", value);
if (description)
item.setAttribute("description", description);
popup.appendChild(item);
return item;
]]>
@ -212,7 +205,6 @@
<parameter name="index"/>
<parameter name="label"/>
<parameter name="value"/>
<parameter name="description"/>
<body>
<![CDATA[
const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
@ -221,9 +213,6 @@
var item = document.createElementNS(XULNS, "menuitem");
item.setAttribute("label", label);
item.setAttribute("value", value);
if (description)
item.setAttribute("description", description);
if (index < popup.childNodes.length)
popup.insertBefore(item, popup.childNodes[index]);
else
@ -298,7 +287,10 @@
if (popup)
arr = popup.getElementsByAttribute('label', this.inputField.value);
this.setSelectionInternal(arr ? arr.item(0) : null);
if (arr && arr.length)
this.setSelectionInternal(arr[0]);
else
this.setSelectionInternal(null);
]]>
</body>
</method>
@ -418,7 +410,9 @@
<![CDATA[
// editable menulists elements aren't in the focus order,
// so when the popup opens we need to force the focus to the inputField
if (event.target.parentNode == this) {
// XXX see bug #196755
// originalTarget is workaround for arrowscrollbox retargeting bug
if (event.originalTarget.parentNode == this) {
if (document.commandDispatcher.focusedElement != this.inputField)
this.inputField.focus();
@ -455,17 +449,5 @@
<children includes="menupopup"/>
</content>
</binding>
<binding id="menulist-description" display="xul:menu"
extends="chrome://global/content/bindings/menulist.xml#menulist">
<content sizetopopup="pref">
<xul:hbox class="menulist-label-box" flex="1">
<xul:image class="menulist-icon" xbl:inherits="src"/>
<xul:label class="menulist-label" xbl:inherits="value=label,crop,accesskey" crop="right" flex="1"/>
<xul:label class="menulist-label menulist-description" xbl:inherits="value=description" crop="right" flex="10000"/>
</xul:hbox>
<xul:dropmarker class="menulist-dropmarker" type="menu"/>
<children includes="menupopup"/>
</content>
</binding>
</bindings>

Просмотреть файл

@ -20,21 +20,8 @@
</getter>
</property>
<property name="value" onget="return this.getAttribute('value');">
<setter>
<![CDATA[
this.setAttribute("value", val);
var children = this._getRadioChildren();
for (var i = 0; i < children.length; i++) {
if (String(children[i].value) == String(val)) {
this.selectedItem = children[i];
break;
}
}
return val;
]]>
</setter>
</property>
<property name="value" onset="this.setAttribute('value',val); return val;"
onget="return this.getAttribute('value');"/>
<property name="disabled">
<getter>
<![CDATA[
@ -102,7 +89,7 @@
alreadySelected = val.getAttribute("selected") == "true";
val.setAttribute("focused", focused);
val.setAttribute("selected", "true");
this.setAttribute("value", val.value);
this.value = val.value;
}
// uncheck all other group nodes
@ -358,7 +345,7 @@
</xul:hbox>
</content>
<implementation implements="nsIDOMXULSelectControlItemElement, nsIDOMXULLabeledControlElement, nsIAccessibleProvider">
<implementation implements="nsIDOMXULSelectControlItemElement, nsIAccessibleProvider">
<constructor>
<![CDATA[
// Just clear out the parent's cached list of radio children
@ -421,14 +408,6 @@
this.radioGroup.focusedItem = this;
]]>
</handler>
<handler event="focus">
<![CDATA[
if (!this.disabled) {
this.radioGroup.focusedItem = this;
this.radioGroup.focus();
}
]]>
</handler>
</handlers>
</binding>

Просмотреть файл

@ -11,7 +11,17 @@
</content>
</binding>
<binding id="scrollbar">
<binding id="scrollbar-base">
<handlers>
<handler event="contextmenu" preventdefault="true"/>
<handler event="click" action="event.preventBubble();"/>
<handler event="dblclick" action="event.preventBubble();"/>
<handler event="command" action="event.preventBubble();"/>
<handler event="contextmenu" action="event.preventBubble();"/>
</handlers>
</binding>
<binding id="scrollbar" extends="chrome://global/content/bindings/scrollbar.xml#scrollbar-base">
<content>
<xul:scrollbarbutton sbattr="scrollbar-up-top" type="decrement" xbl:inherits="sborient=orient"/>
<xul:scrollbarbutton sbattr="scrollbar-down-top" type="increment" hidden="true" xbl:inherits="sborient=orient"/>
@ -68,10 +78,6 @@
</body>
</method>
</implementation>
<handlers>
<handler event="contextmenu" preventdefault="true"/>
</handlers>
</binding>
</bindings>

Просмотреть файл

@ -33,7 +33,7 @@
return this.stringBundle.formatStringFromName(aStringKey, aStringsArray, aStringsArray.length);
}
catch (e) {
dump("*** Failed to format string " + aStringKey + " in bundle: " + this.src + "\n");
dump("*** Failed to get string " + aStringKey + " in bundle: " + this.src + "\n");
throw e;
}
]]>

Просмотреть файл

@ -114,10 +114,10 @@
<![CDATA[({
tabbox: this,
handleEvent: function handleEvent(event) {
if (!event.isTrusted) {
// Don't let untrusted events mess with tabs.
return;
}
if (!event.isTrusted) {
// Don't let untrusted events mess with tabs.
return;
}
switch (event.keyCode) {
case event.DOM_VK_TAB:
@ -155,8 +155,8 @@
<setter>
<![CDATA[
if (val != this._eventNode) {
val.addEventListener("keypress", this._keyEventHandler, false);
this._eventNode.removeEventListener("keypress", this._keyEventHandler, false);
val.addEventListener("keypress", this._keyEventHandler, true);
this._eventNode.removeEventListener("keypress", this._keyEventHandler, true);
this._eventNode = val;
}
return val;
@ -170,11 +170,11 @@
case "window": this._eventNode = window; break;
case "document": this._eventNode = document; break;
}
this._eventNode.addEventListener("keypress", this._keyEventHandler, false);
this._eventNode.addEventListener("keypress", this._keyEventHandler, true);
</constructor>
<destructor>
this._eventNode.removeEventListener("keypress", this._keyEventHandler, false);
this._eventNode.removeEventListener("keypress", this._keyEventHandler, true);
</destructor>
</implementation>
</binding>
@ -291,23 +291,6 @@
</setter>
</property>
<method name="selectNewTab">
<parameter name="aNewTab"/>
<body>
<![CDATA[
var isTabFocused =
(document.commandDispatcher.focusedElement == this.selectedItem);
this.selectedItem = aNewTab;
if (isTabFocused) {
aNewTab.focus();
}
else if (this.getAttribute("setfocus") != "false") {
document.commandDispatcher.advanceFocusIntoSubtree(aNewTab);
}
]]>
</body>
</method>
<method name="advanceSelectedTab">
<parameter name="aDir"/>
<body>
@ -323,7 +306,11 @@
}
if (next && next != startTab) {
this.selectNewTab(next);
this.selectedItem = next;
if (this.getAttribute("setfocus") != "false") {
next.focus();
document.commandDispatcher.advanceFocusIntoSubtree(next);
}
}
]]>
</body>
@ -455,10 +442,8 @@
<binding id="tab" display="xul:button"
extends="chrome://global/content/bindings/tabbox.xml#tab-base">
<content>
<xul:hbox class="tab-middle box-inherit" xbl:inherits="align,dir,pack,orient,selected" flex="1">
<xul:image class="tab-icon" xbl:inherits="validate,src=image"/>
<xul:label class="tab-text" xbl:inherits="value=label,accesskey,crop,disabled" flex="1"/>
</xul:hbox>
<xul:image class="tab-icon" xbl:inherits="validate,src=image"/>
<xul:label class="tab-text" xbl:inherits="value=label,accesskey,crop,disabled" flex="1"/>
</content>
<implementation implements="nsIDOMXULSelectControlItemElement, nsIAccessibleProvider">
@ -515,7 +500,7 @@
<handlers>
<handler event="click" button="0">
<![CDATA[
this.parentNode.selectNewTab(this);
this.parentNode.selectedItem = this;
]]>
</handler>

Просмотреть файл

@ -51,7 +51,7 @@
<content>
<xul:stringbundle src="chrome://global/locale/tabbrowser.properties"/>
<xul:tabbox flex="1" xbl:inherits="handleCtrlPageUpDown" eventnode="document"
<xul:tabbox flex="1" eventnode="document" xbl:inherits="handleCtrlPageUpDown"
onselect="if (!('updateCurrentBrowser' in this.parentNode) || event.target.localName != 'tabpanels') return; this.parentNode.updateCurrentBrowser();">
<xul:hbox class="tabbrowser-strip chromeclass-toolbar" collapsed="true" tooltip="_child" context="_child">
<xul:tooltip onpopupshowing="event.preventBubble(); if (document.tooltipNode.hasAttribute('label')) { this.setAttribute('label', document.tooltipNode.getAttribute('label')); return true; } return false;"/>
@ -80,6 +80,7 @@
<xul:tabs class="tabbrowser-tabs" closebutton="true" flex="1"
setfocus="false"
onclick="this.parentNode.parentNode.parentNode.onTabClick(event);"
onmousedown="this.parentNode.parentNode.parentNode.updateContextTab(event);"
ondragover="nsDragAndDrop.dragOver(event, this.parentNode.parentNode.parentNode);
event.stopPropagation();"
ondragdrop="nsDragAndDrop.drop(event, this.parentNode.parentNode.parentNode);
@ -98,7 +99,11 @@
</xul:tabs>
</xul:hbox>
<xul:tabpanels flex="1" class="plain">
<xul:browser type="content-primary" disablehistory="true" xbl:inherits="tooltip=contenttooltip,contextmenu=contentcontextmenu,autocompletepopup"/>
<xul:vbox flex="1">
<xul:browsermessage hidden="true" type="top"/>
<xul:browser flex="1" type="content-primary" message="true" disablehistory="true" xbl:inherits="tooltip=contenttooltip,contextmenu=contentcontextmenu,autocompletepopup"/>
<xul:browsermessage hidden="true" type="bottom"/>
</xul:vbox>
</xul:tabpanels>
</xul:tabbox>
<children/>
@ -154,6 +159,86 @@
<field name="mModalDialogShowing">
false
</field>
<method name="getBrowserAtIndex">
<parameter name="aIndex"/>
<body>
<![CDATA[
return this.mPanelContainer.childNodes[aIndex].firstChild.nextSibling;
]]>
</body>
</method>
<method name="getBrowserIndexForDocument">
<parameter name="aDocument"/>
<body>
<![CDATA[
for (var i = 0; i < this.mPanelContainer.childNodes.length; i++) {
if (this.getBrowserAtIndex(i).contentDocument == aDocument) {
return i;
}
}
return -1;
]]>
</body>
</method>
<method name="getMessageForBrowser">
<parameter name="aBrowser"/>
<parameter name="aTopBottom"/>
<body>
<![CDATA[
return aBrowser[aTopBottom == "top" ? "previousSibling" : "nextSibling"];
]]>
</body>
</method>
<method name="showMessage">
<parameter name="aBrowser"/>
<parameter name="aIconURL"/>
<parameter name="aMessage"/>
<parameter name="aButtonLabel"/>
<parameter name="aDocShell"/>
<parameter name="aSource"/>
<parameter name="aPopup"/>
<parameter name="aTopBottom"/>
<parameter name="aShowCloseButton"/>
<body>
<![CDATA[
var message = this.getMessageForBrowser(aBrowser, aTopBottom);
message.image = aIconURL;
message.text = aMessage;
message.buttonText = aButtonLabel;
message.hidden = false;
if (aSource) {
message.source = aSource;
message.popup = null;
}
else if (aPopup) {
message.popup = aPopup;
message.source = null;
}
message.docShell = aDocShell;
message.closeButton = aShowCloseButton;
aBrowser.isShowingMessage = true;
]]>
</body>
</method>
<method name="hideMessage">
<parameter name="aBrowser"/>
<parameter name="aTopBottom"/>
<body>
<![CDATA[
if (aTopBottom != "both")
this.getMessageForBrowser(aBrowser, aTopBottom).hidden = true;
else {
this.getMessageForBrowser(aBrowser, "top").hidden = true;
this.getMessageForBrowser(aBrowser, "bottom").hidden = true;
}
]]>
</body>
</method>
<!-- A web progress listener object definition for a given tab. -->
<method name="mTabProgressListener">
@ -167,7 +252,8 @@
mTab: aTab,
mBrowser: aBrowser,
mBlank: aStartsBlank,
mIcon: "",
mIcon: null,
mLastURI: null,
onProgressChange : function (aWebProgress, aRequest,
aCurSelfProgress, aMaxSelfProgress,
@ -194,7 +280,10 @@
const nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
const nsIChannel = Components.interfaces.nsIChannel;
if (aStateFlags & nsIWebProgressListener.STATE_START &&
if (aStateFlags & nsIWebProgressListener.STATE_START)
this.mBrowser.mFavIconURL = null;
if (aStateFlags & nsIWebProgressListener.STATE_START &&
aStateFlags & nsIWebProgressListener.STATE_IS_NETWORK) {
// It's okay to clear what the user typed when we start
// loading a document. If the user types, this flag gets
@ -207,8 +296,8 @@
if (!this.mBlank) {
this.mTab.setAttribute("busy", "true");
this.mTab.label = this.mTabBrowser.mStringBundle.getString("tabs.loading");
this.mTab.removeAttribute("image");
this.mIcon = "";
this.mTab.removeAttribute("image");
this.mIcon = null;
if (this.mTabBrowser.mCurrentTab == this.mTab)
this.mTabBrowser.mIsBusy = true;
@ -227,12 +316,17 @@
this.mTab.removeAttribute("busy");
var location = aRequest.QueryInterface(nsIChannel).URI;
if (this.mIcon) {
this.mTab.setAttribute("image", this.mIcon);
this.mIcon = "";
// For keyword URIs clear the user typed value since they will be changed into real URIs
if (location.scheme == "keyword")
this.mBrowser.userTypedValue = null;
if (this.mTabBrowser.shouldLoadFavIcon(location)) {
if (this.mIcon)
this.mTab.setAttribute("image", this.mIcon);
else
this.mTabBrowser.loadFavIcon(location, "image", this.mTab);
}
else if (this.mTabBrowser.shouldLoadFavIcon(location))
this.mTabBrowser.loadFavIcon(location, "image", this.mTab);
if (this.mTab.label == this.mTabBrowser.mStringBundle.getString("tabs.loading"))
this.mTabBrowser.setTabTitle(this.mTab);
@ -248,10 +342,10 @@
p.onStateChange(aWebProgress, aRequest, aStateFlags, aStatus);
}
}
},
}
,
onLocationChange : function(aWebProgress, aRequest, aLocation)
{
onLocationChange : function(aWebProgress, aRequest, aLocation) {
// The document loaded correctly, clear the value if we should
if (this.mBrowser.userTypedClear)
this.mBrowser.userTypedValue = null;
@ -265,8 +359,7 @@
}
},
onStatusChange : function(aWebProgress, aRequest, aStatus, aMessage)
{
onStatusChange : function(aWebProgress, aRequest, aStatus, aMessage) {
if (this.mBlank)
return;
@ -298,11 +391,12 @@
return this;
throw Components.results.NS_NOINTERFACE;
}
});
});
]]>
</body>
</method>
<method name="buildFavIconString">
<parameter name="aURI"/>
<body>
@ -318,7 +412,7 @@
<body>
<![CDATA[
return (aURI && this.mPrefs.getBoolPref("browser.chrome.site_icons") &&
this.mPrefs.getBoolPref("browser.chrome.favicons") &&
this.mPrefs.getBoolPref("browser.chrome.favicons") &&
("schemeIs" in aURI) && (aURI.schemeIs("http") || aURI.schemeIs("https")));
]]>
</body>
@ -331,13 +425,8 @@
<body>
<![CDATA[
var iconURL = this.buildFavIconString(aURI);
var entry = this.openCacheEntry(iconURL, Components.interfaces.nsICache.ACCESS_READ);
if (!entry)
if (!this.isFavIconKnownMissing(iconURL))
aElt.setAttribute(aAttr, iconURL);
else {
entry.close();
entry = null;
}
]]>
</body>
</method>
@ -380,6 +469,20 @@
</body>
</method>
<method name="isFavIconKnownMissing">
<parameter name="key"/>
<body>
<![CDATA[
var e = this.openCacheEntry(key, Components.interfaces.nsICache.ACCESS_READ);
if (e) {
e.close();
return true;
}
return false;
]]>
</body>
</method>
<method name="updateTitlebar">
<body>
<![CDATA[
@ -387,9 +490,9 @@
var docTitle;
if (this.docShell.contentViewer)
docTitle = this.contentTitle;
if (!docTitle)
docTitle = this.ownerDocument.documentElement.getAttribute("titledefault");
if (!docTitle)
docTitle = this.ownerDocument.documentElement.getAttribute("titledefault");
var modifier = this.ownerDocument.documentElement.getAttribute("titlemodifier");
if (docTitle) {
@ -400,7 +503,19 @@
newTitle += sep;
}
newTitle += modifier;
this.ownerDocument.title = newTitle;
window.title = newTitle;
]]>
</body>
</method>
<method name="updateContextTab">
<parameter name="aEvent"/>
<body>
<![CDATA[
if (aEvent.originalTarget.localName == "tab")
this.mContextTab = aEvent.originalTarget;
else
this.mContextTab = document.popupNode;
]]>
</body>
</method>
@ -409,7 +524,6 @@
<parameter name="aPopupMenu"/>
<body>
<![CDATA[
this.mContextTab = document.popupNode;
var disabled = this.mPanelContainer.childNodes.length == 1;
var menuItems = aPopupMenu.getElementsByAttribute("tbattr", "tabbrowser-multiple");
for (var i = 0; i < menuItems.length; i++)
@ -421,18 +535,14 @@
<method name="updateCurrentBrowser">
<body>
<![CDATA[
var newBrowser = this.mPanelContainer.childNodes[this.mPanelContainer.selectedIndex];
var newBrowser = this.getBrowserAtIndex(this.mPanelContainer.selectedIndex);
if (this.mCurrentBrowser == newBrowser)
return;
if (this.mCurrentBrowser) {
this.mCurrentBrowser.focusedWindow = document.commandDispatcher.focusedWindow;
this.mCurrentBrowser.focusedElement = document.commandDispatcher.focusedElement;
if (this.mCurrentBrowser.focusedElement) {
// Clear focus outline before we draw on top of it
this.mCurrentBrowser.focusedElement.blur();
}
this.mCurrentBrowser.setAttribute("type", "content");
this.mCurrentBrowser.setAttribute("type", "content");
}
var updatePageReport = false;
@ -443,7 +553,7 @@
newBrowser.setAttribute("type", "content-primary");
this.mCurrentBrowser = newBrowser;
this.mCurrentTab = this.selectedTab;
if (updatePageReport)
this.mCurrentBrowser.updatePageReport();
@ -467,15 +577,21 @@
if (securityUI)
p.onSecurityChange(webProgress, null, securityUI.state);
var listener = this.mTabListeners[this.mPanelContainer.selectedIndex];
if (listener.mIcon)
p.onLinkIconAvailable(newBrowser, listener.mIcon);
if (listener.mIcon) {
if (this.isFavIconKnownMissing(listener.mIcon))
listener.mIcon = null;
else
p.onLinkIconAvailable(newBrowser, listener.mIcon);
}
}
}
this.mCurrentBrowser.userTypedClear = userTypedClear;
this._fastFind.setDocShell(this.mCurrentBrowser.docShell);
// Update the window title.
this.updateTitlebar();
// If the new tab is busy, and our current state is not busy, then
// we need to fire a start to all progress listeners.
const nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
@ -501,35 +617,24 @@
}
}
if (document.commandDispatcher.focusedElement &&
document.commandDispatcher.focusedElement.parentNode ==
this.mCurrentTab.parentNode) {
// The focus is on a tab in the same tab panel
return; // If focus was on a tab, switching tabs focuses the new tab
function setFocus(element) {
Components.lookupMethod(element, "focus").call(element);
}
var whatToFocus = window.content;
// Focus the previously focused element or window
document.commandDispatcher.suppressFocusScroll = true;
if (newBrowser.focusedElement) {
if (newBrowser.focusedElement.parentNode !=
this.mCurrentTab.parentNode) {
// Focus the remembered element unless it's in the current tab panel
whatToFocus = newBrowser.focusedElement;
try {
setFocus(newBrowser.focusedElement);
} catch (e) {
setFocus(newBrowser.focusedWindow);
}
}
else if (newBrowser.focusedWindow) {
whatToFocus = newBrowser.focusedWindow;
}
function setFocus(element) {
document.commandDispatcher.suppressFocusScroll = true;
Components.lookupMethod(element, "focus").call(element);
document.commandDispatcher.suppressFocusScroll = false;
}
// Use setTimeout to avoid focus outline ghosting.
setTimeout(setFocus, 0, whatToFocus);
else if (newBrowser.focusedWindow)
setFocus(newBrowser.focusedWindow);
else // new tab, focus our new content area
setTimeout(setFocus, 0, window.content);
document.commandDispatcher.suppressFocusScroll = false;
]]>
</body>
</method>
@ -614,31 +719,25 @@
null) != nsIContentPolicy.ACCEPT)
return;
// var browserIndex = tabBrowser.getBrowserIndexForDocument(targetDoc);
var browserIndex = -1;
if (tabBrowser.mTabbedMode) {
for (var i = 0; i < tabBrowser.mPanelContainer.childNodes.length; i++) {
if (tabBrowser.mPanelContainer.childNodes[i].contentDocument == targetDoc) {
browserIndex = i;
break;
}
}
} else {
if (tabBrowser.mCurrentBrowser.contentDocument == targetDoc)
browserIndex = 0;
}
var browserIndex = tabBrowser.getBrowserIndexForDocument(targetDoc);
// no browser? no favicon.
if (browserIndex == -1)
return;
var listener = tabBrowser.mTabListeners[browserIndex];
// there's no tab listener for non-tabbed mode browser 0
if (tabBrowser.isFavIconKnownMissing(href)) {
if (listener)
listener.mIcon = null;
return;
}
if (listener)
listener.mIcon = href;
if (tabBrowser.mProgressListeners) {
var targetBrowser = tabBrowser.mTabbedMode ? tabBrowser.mPanelContainer.childNodes[i] : tabBrowser.mCurrentBrowser;
var targetBrowser = tabBrowser.getBrowserAtIndex(browserIndex);
for (i = 0; i < tabBrowser.mProgressListeners.length; i++) {
var p = tabBrowser.mProgressListeners[i];
if (p)
@ -657,14 +756,14 @@
return;
var i = 0;
for ( ; i < this.parentNode.childNodes.length; i++) {
if (this.parentNode.childNodes[i] == this)
for ( ; i < this.parentNode.parentNode.childNodes.length; i++) {
if (this.parentNode.parentNode.childNodes[i].firstChild.nextSibling == this)
break;
}
var tabBrowser = this.parentNode.parentNode.parentNode.parentNode;
var tabBrowser = this.parentNode.parentNode.parentNode;
var tab = tabBrowser.mTabContainer.childNodes[i];
tabBrowser.setTabTitle(tab);
if (tab == tabBrowser.mCurrentTab)
@ -760,14 +859,25 @@
}
// Wire up a progress listener to our filter.
const listener = this.mTabProgressListener(this.mCurrentTab,
this.mCurrentBrowser,
false);
const listener = this.mTabProgressListener(this.mCurrentTab, this.mCurrentBrowser, false);
filter.addProgressListener(listener, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
this.mTabListeners[0] = listener;
]]>
</body>
</method>
<method name="_createMessage">
<parameter name="aType"/>
<body>
<![CDATA[
var message = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
"browsermessage");
message.hidden = true;
message.setAttribute("type", aType);
return message;
]]>
</body>
</method>
<method name="addTab">
<parameter name="aURI"/>
@ -776,14 +886,16 @@
<parameter name="aPostData"/>
<body>
<![CDATA[
var blank = (aURI == "about:blank");
if (!this.mTabbedMode)
this.enterTabbedMode();
var b = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
"browser");
var t = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
"tab");
var blank = (aURI == "about:blank");
if (blank)
t.setAttribute("label", this.mStringBundle.getString("tabs.untitled"));
else
@ -798,14 +910,21 @@
t.setAttribute("onerror", "this.parentNode.parentNode.parentNode.parentNode.addToMissedIconCache(this.getAttribute('image')); this.removeAttribute('image');");
this.mTabContainer.appendChild(t);
var b = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
"browser");
b.setAttribute("type", "content");
b.setAttribute("message", "true");
b.setAttribute("contextmenu", this.getAttribute("contentcontextmenu"));
b.setAttribute("tooltip", this.getAttribute("contenttooltip"));
b.setAttribute("autocompletepopup", this.getAttribute("autocompletepopup"));
this.mPanelContainer.appendChild(b);
// Add the Message and the Browser to the box
var vbox = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
"vbox");
vbox.setAttribute("flex", "1");
vbox.appendChild(this._createMessage("top"));
vbox.appendChild(b);
vbox.appendChild(this._createMessage("bottom"));
b.setAttribute("flex", "1");
this.mPanelContainer.appendChild(vbox);
b.addEventListener("DOMTitleChanged", this.onTitleChanged, false);
@ -823,6 +942,8 @@
b.webProgress.addProgressListener(filter, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
this.mTabListeners[position] = tabListener;
this.mTabFilters[position] = filter;
b._fastFind = this.fastFind;
if (!blank) {
// pretend the user typed this so it'll be available till
@ -840,19 +961,68 @@
</body>
</method>
<method name="warnAboutClosingTabs">
<parameter name="aAll"/>
<body>
<![CDATA[
var numTabs = this.mTabContainer.childNodes.length;
var reallyClose = true;
if (numTabs <= 1)
return reallyClose;
const pref = "browser.tabs.warnOnClose";
var shouldPrompt = this.mPrefs.getBoolPref(pref);
var reallyClose = true;
if (shouldPrompt) {
var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
.getService(Components.interfaces.nsIPromptService);
//default to true: if it were false, we wouldn't get this far
var warnOnClose = { value:true };
var bundle = this.mStringBundle;
var tabsToClose = numTabs; //number of tabs to be removed
if (!aAll)
--tabsToClose;
var messageKey = (tabsToClose == 1) ? "tabs.closeWarningOne" : "tabs.closeWarningMultiple";
var closeKey = (tabsToClose == 1) ? "tabs.closeButtonOne" : "tabs.closeButtonMultiple";
var buttonPressed = promptService.confirmEx(window,
bundle.getString('tabs.closeWarningTitle'),
bundle.getFormattedString(messageKey, [tabsToClose]),
(promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_0)
+ (promptService.BUTTON_TITLE_CANCEL * promptService.BUTTON_POS_1),
bundle.getString(closeKey),
null, null,
bundle.getString('tabs.closeWarningPromptMe'),
warnOnClose);
reallyClose = (buttonPressed == 0);
// don't set the pref unless they press OK and it's false
if (reallyClose && !warnOnClose.value)
this.mPrefs.setBoolPref(pref, false);
}
return reallyClose;
]]>
</body>
</method>
<method name="removeAllTabsBut">
<parameter name="aTab"/>
<body>
<![CDATA[
if (aTab.localName != "tab")
aTab = this.mCurrentTab;
else
this.mTabContainer.selectedItem = aTab;
if (this.warnAboutClosingTabs(false)) {
if (aTab.localName != "tab")
aTab = this.mCurrentTab;
else
this.mTabContainer.selectedItem = aTab;
var childNodes = this.mTabContainer.childNodes;
for (var i = childNodes.length - 1; i >= 0; --i) {
if (childNodes[i] != aTab)
this.removeTab(childNodes[i]);
var childNodes = this.mTabContainer.childNodes;
for (var i = childNodes.length - 1; i >= 0; --i) {
if (childNodes[i] != aTab)
this.removeTab(childNodes[i]);
}
}
}
]]>
</body>
@ -875,6 +1045,11 @@
var l = this.mTabContainer.childNodes.length;
if (l == 1) {
if (!this.mPrefs.getBoolPref("browser.tabs.autoHide")) {
// blank the tab
this.loadURI("about:blank");
return;
}
// hide the tab bar
this.mPrefs.setBoolPref("browser.tabs.forceHide", true);
this.setStripVisibilityTo(false);
@ -904,7 +1079,7 @@
// Remove the tab's filter and progress listener.
const filter = this.mTabFilters[index];
var oldBrowser = this.mPanelContainer.childNodes[index];
var oldBrowser = this.getBrowserAtIndex(index);
oldBrowser.webProgress.removeProgressListener(filter);
filter.removeProgressListener(this.mTabListeners[index]);
this.mTabFilters.splice(index, 1);
@ -938,7 +1113,7 @@
oldBrowser.destroy();
this.mTabContainer.removeChild(oldTab);
this.mPanelContainer.removeChild(oldBrowser);
this.mPanelContainer.removeChild(this.mPanelContainer.childNodes[index]);
this.selectedTab = this.mTabContainer.childNodes[newIndex];
this.mPanelContainer.selectedIndex = newIndex;
@ -955,7 +1130,7 @@
var l = this.mPanelContainer.childNodes.length;
for (var i = 0; i < l; i++) {
try {
this.mPanelContainer.childNodes[i].reload();
this.getBrowserAtIndex(i).reload();
} catch (e) {
// ignore failure to reload so others will be reloaded
}
@ -1058,7 +1233,7 @@
for (var i = 0; i < this.mTabContainer.childNodes.length; i++) {
if (this.mTabContainer.childNodes[i] == aTab) {
return this.mPanelContainer.childNodes[i];
return this.getBrowserAtIndex(i);
}
}
@ -1092,7 +1267,7 @@
<property name="browsers"
onget="return this.mPanelContainer.childNodes;"
onget="return this.mPanelContainer.getElementsByTagName('browser');"
readonly="true"/>
<!-- Drag and drop observer API -->
@ -1265,9 +1440,8 @@
<method name="attachFormFill">
<body><![CDATA[
var browsers = this.mPanelContainer.childNodes;
for (var i = 0; i < browsers.length; ++i) {
var cb = browsers[i];
for (var i = 0; i < this.mPanelContainer.childNodes.length; ++i) {
var cb = this.getBrowserAtIndex(i);
cb.attachFormFill();
}
]]></body>
@ -1275,9 +1449,8 @@
<method name="detachFormFill">
<body><![CDATA[
var browsers = this.mPanelContainer.childNodes;
for (var i = 0; i < browsers.length; ++i) {
var cb = browsers[i];
for (var i = 0; i < this.mPanelContainer.childNodes.length; ++i) {
var cb = this.getBrowserAtIndex(i);
cb.detachFormFill();
}
]]></body>
@ -1291,6 +1464,25 @@
onget="return this.mCurrentBrowser.currentURI;"
readonly="true"/>
<field name="_fastFind">null</field>
<property name="fastFind"
readonly="true">
<getter>
<![CDATA[
if (!this._fastFind) {
this._fastFind = Components.classes["@mozilla.org/typeaheadfind;1"]
.createInstance(Components.interfaces.nsITypeAheadFind);
this._fastFind.init(this.docShell);
}
return this._fastFind;
]]>
</getter>
</property>
<property name="findString"
onget="return this.mCurrentBrowser.findString;"
readonly="true"/>
<property name="docShell"
onget="return this.mCurrentBrowser.docShell"
readonly="true"/>
@ -1366,6 +1558,20 @@
]]>
</body>
</method>
<field name="_keyEventHandler" readonly="true">
<![CDATA[({
tabbrowser: this,
handleEvent: function handleEvent(aEvent) {
if (!aEvent.isTrusted) {
// Don't let untrusted events mess with tabs.
return;
}
if (aEvent.ctrlKey && aEvent.keyCode == KeyEvent.DOM_VK_F4 && this.tabbrowser.mTabBox.handleCtrlPageUpDown)
this.tabbrowser.removeCurrentTab();
}
})]]>
</field>
<property name="canFindAgain"
onget="return this.mCurrentBrowser.canFindAgain;"
@ -1384,49 +1590,55 @@
<constructor>
<![CDATA[
this.mCurrentBrowser = this.mPanelContainer.firstChild;
this.mCurrentBrowser = this.getBrowserAtIndex(0);
this.mCurrentTab = this.mTabContainer.firstChild;
this.mTabBox.handleCtrlTab = !/Mac/.test(navigator.platform);
document.addEventListener("keypress", this._keyEventHandler, false);
]]>
</constructor>
<destructor>
<![CDATA[
for (var i = 0; i < this.mTabListeners.length; ++i) {
this.mPanelContainer.childNodes[i].webProgress.removeProgressListener(this.mTabFilters[i]);
this.getBrowserAtIndex(i).webProgress.removeProgressListener(this.mTabFilters[i]);
this.mTabFilters[i].removeProgressListener(this.mTabListeners[i]);
this.mTabFilters[i] = null;
this.mTabListeners[i] = null;
this.mPanelContainer.childNodes[i].removeEventListener("DOMTitleChanged", this.onTitleChanged, false);
this.getBrowserAtIndex(i).removeEventListener("DOMTitleChanged", this.onTitleChanged, false);
}
this.mPanelContainer.removeEventListener("DOMLinkAdded", this.onLinkAdded, false);
document.removeEventListener("keypress", this._keyEventHandler, false);
]]>
</destructor>
</implementation>
<handlers>
<handler event="keypress" modifiers="control" keycode="VK_F4">
<![CDATA[
if (this.mTabBox.handleCtrlPageUpDown)
this.removeCurrentTab();
]]>
</handler>
<handler event="DOMWindowClose">
<![CDATA[
if (!event.isTrusted)
return;
const browsers = this.browsers;
if (browsers.length == 1)
const browsers = this.mPanelContainer.childNodes;
if (browsers.length == 1) {
// There's only one browser left. If a window is being
// closed and the window is *not* the window in the
// browser that's still around, prevent the event's default
// action to prevent closing a window that's being closed
// already.
if (this.getBrowserAtIndex(0).contentWindow != event.target)
event.preventDefault();
return;
}
var i = 0;
for (; i < browsers.length; ++i) {
if (browsers[i].contentWindow == event.target)
if (this.getBrowserAtIndex(i).contentWindow == event.target) {
this.removeTab(this.mTabContainer.childNodes[i]);
event.preventDefault();
break;
}
}
this.removeTab(this.mTabContainer.childNodes[i]);
event.preventDefault();
]]>
</handler>
<handler event="DOMWillOpenModalDialog">

Просмотреть файл

@ -2,9 +2,8 @@
<bindings id="textBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml">
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<!-- bound to <description>s -->
<binding id="text-base">
<implementation implements="nsIDOMXULDescriptionElement, nsIAccessibleProvider">
@ -18,7 +17,7 @@
</property>
<property name="disabled" onget="return this.hasAttribute('disabled');"
onset="if (val) this.setAttribute('disabled', 'true');
else this.removeAttribute('disabled');
else this.removeAttribute('disabled');
return val;"/>
<property name="value" onget="return this.getAttribute('value');"
onset="this.setAttribute('value', val); return val;"/>
@ -29,161 +28,14 @@
<binding id="text-label" extends="chrome://global/content/bindings/text.xml#text-base">
<implementation implements="nsIDOMXULLabelElement">
<property name="accessKey">
<getter>
<![CDATA[
var accessKey = this.getAttribute('accesskey');
return accessKey ? accessKey[0] : null;
]]>
</getter>
<setter>
<![CDATA[
this.setAttribute('accesskey', val);
return val;
]]>
</setter>
</property>
<property name="control" onget="return getAttribute('control');">
<setter>
<![CDATA[
// After this gets set, the label will use the binding #label-control
this.setAttribute('control', val);
return val;
]]>
</setter>
</property>
<property name="accessKey" onget="return this.getAttribute('accesskey');"
onset="this.setAttribute('accesskey', val); return val;"/>
<property name="control" onget="return this.getAttribute('control');"
onset="this.setAttribute('control', val); return val;"/>
</implementation>
</binding>
<binding id="label-control" extends="chrome://global/content/bindings/text.xml#text-label">
<content>
<html:span anonid="accessKeyParens"><children/></html:span>
</content>
<implementation implements="nsIDOMXULLabelElement">
<constructor>
<![CDATA[
this.formatAccessKey();
]]>
</constructor>
<method name="formatAccessKey">
<body>
<![CDATA[
var control = this.labeledControlElement;
if (!control) {
var bindingParent = document.getBindingParent(this);
if (bindingParent instanceof Components.interfaces.nsIDOMXULLabeledControlElement) {
control = bindingParent; // For controls that make the <label> an anon child
}
}
if (control) {
control.labelElement = this;
}
var afterLabel = document.getAnonymousElementByAttribute(this, "anonid", "accessKeyParens");
afterLabel.textContent = ""; // This does not clear real nodes!
var oldAccessKey = this.getElementsByAttribute('class', 'accesskey').item(0);
if (oldAccessKey) { // Clear old accesskey
if (oldAccessKey.previousSibling instanceof Text) {
oldAccessKey.previousSibling.appendData(oldAccessKey.textContent)
}
else {
oldAccessKey.parentNode.insertBefore(oldAccessKey.firstChild, oldAccessKey);
}
oldAccessKey.parentNode.removeChild(oldAccessKey);
}
var accessKey = this.accessKey;
var labelText = this.textContent;
if (!accessKey || !labelText || !control) {
return;
}
var accessKeyIndex = labelText.indexOf(accessKey);
if (accessKeyIndex < 0) { // Try again in upper case
accessKeyIndex = labelText.toUpperCase().indexOf(accessKey.toUpperCase());
}
var span = document.createElementNS("http://www.w3.org/1999/xhtml", "span");
span.className = "accesskey";
if (accessKeyIndex < 0) {
// If accesskey is not in string, append in parentheses
afterLabel.textContent = " (";
span.textContent = accessKey.toUpperCase();
afterLabel.appendChild(span);
afterLabel.appendChild(document.createTextNode(")"));
return;
}
var treeWalker = document.createTreeWalker(this, NodeFilter.SHOW_TEXT, null, true);
var accessKeyNode = treeWalker.nextNode();
while (accessKeyIndex >= accessKeyNode.length) {
accessKeyIndex -= accessKeyNode.length;
accessKeyNode = treeWalker.nextNode();
}
// Now wrap the access key in a <span class="accesskey"/>
if (accessKeyIndex) {
accessKeyNode = accessKeyNode.splitText(accessKeyIndex); // returns 2nd node from split
}
accessKeyNode.parentNode.insertBefore(span, accessKeyNode);
if (accessKeyNode.length > 1) {
accessKeyNode.splitText(1);
}
span.appendChild(accessKeyNode);
]]>
</body>
</method>
<property name="accessKey">
<getter>
<![CDATA[
var accessKey = null;
var labeledEl = this.labeledControlElement;
if (labeledEl) {
accessKey = labeledEl.getAttribute('accesskey');
}
if (!accessKey) {
accessKey = this.getAttribute('accesskey');
}
return accessKey ? accessKey[0] : null;
]]>
</getter>
<setter>
<![CDATA[
// If this label already has an accesskey attribute store it here as well
if (this.hasAttribute('accesskey')) {
this.setAttribute('accesskey', val);
}
var control = this.labeledControlElement;
if (control) {
control.setAttribute('accesskey', val);
}
this.formatAccessKey();
return val;
]]>
</setter>
</property>
<property name="labeledControlElement" readonly="true"
onget="var control = this.control; return control ? document.getElementById(control) : null;" />
<property name="control" onget="return this.getAttribute('control');">
<setter>
<![CDATA[
var control = this.labeledControlElement;
if (control) {
control.labelElement = null; // No longer pointed to be this label
}
this.setAttribute('control', val);
this.formatAccessKey();
return val;
]]>
</setter>
</property>
</implementation>
<handlers>
<handler event="click" action="if (this.disabled) return;
var controlElementID = this.getAttribute('control');
@ -194,7 +46,7 @@
controlElement.focus();
"/>
</handlers>
</binding>
</binding>
<binding id="text-link" extends="chrome://global/content/bindings/text.xml#text-label">
<handlers>

Просмотреть файл

@ -23,7 +23,7 @@
</xul:hbox>
</content>
<implementation implements="nsIAccessibleProvider, nsIDOMXULTextBoxElement">
<implementation implements="nsIAccessibleProvider, nsIDOMXULTextboxElement">
<property name="accessible">
<getter>
<![CDATA[
@ -151,7 +151,6 @@
if (this._timer)
clearTimeout(this._timer);
this._fireCommand(this);
event.preventDefault();
]]>
</handler>
</handlers>
@ -169,7 +168,8 @@
<binding id="input-box">
<content context="_child">
<children/>
<xul:menupopup onpopupshowing="if (document.commandDispatcher.focusedElement != this.parentNode.firstChild)
<xul:menupopup anonid="input-box-contextmenu"
onpopupshowing="if (document.commandDispatcher.focusedElement != this.parentNode.firstChild)
this.parentNode.firstChild.focus();
this.parentNode.doPopupItemEnabling(this);"
oncommand="this.parentNode.doCommand(event.originalTarget.getAttribute('cmd'));event.preventBubble();">
@ -190,7 +190,7 @@
<body>
<![CDATA[
var children = popupNode.childNodes;
for (var i = 0; i < children.length; i++) {
for (var i = 0; i < children.length; i++) {
var command = children[i].getAttribute("cmd");
if (command) {
var controller = document.commandDispatcher.getControllerForCommand(command);

Просмотреть файл

@ -64,7 +64,7 @@
<![CDATA[
var toolbar = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
"toolbar");
toolbar.id = "__customToolbar_" + aName.replace(" ", "");
toolbar.id = "__customToolbar_" + aName.replace(" ", "_");
toolbar.setAttribute("customizable", "true");
toolbar.setAttribute("customindex", ++this.customToolbarCount);
toolbar.setAttribute("toolbarname", aName);

Просмотреть файл

@ -35,7 +35,7 @@
<content>
<children includes="observes|template|menupopup|tooltip"/>
<xul:hbox flex="1" align="center">
<xul:box xbl:inherits="orient" flex="1">
<xul:box xbl:inherits="orient" flex="1" align="center">
<xul:image class="toolbarbutton-icon" xbl:inherits="validate,src=image,toolbarmode,buttonstyle"/>
<xul:label class="toolbarbutton-text" crop="right" flex="1"
xbl:inherits="value=label,accesskey,crop,dragover-top,toolbarmode,buttonstyle"/>

Просмотреть файл

@ -1,7 +1,5 @@
<?xml version="1.0"?>
<!DOCTYPE bindings SYSTEM "chrome://global/locale/tree.dtd">
<bindings id="treeBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
@ -21,43 +19,7 @@
</xul:treerows>
</content>
<implementation implements="nsIDOMXULTreeElement, nsIDOMXULMultiSelectControlElement, nsIAccessibleProvider">
<!-- ///////////////// nsIDOMXULTreeElement ///////////////// -->
<property name="columns"
onget="return this.treeBoxObject.columns;"/>
<property name="view"
onget="return this.treeBoxObject.view;"
onset="return this.treeBoxObject.view = val;"/>
<property name="body"
onget="return this.treeBoxObject.treeBody;"/>
<property name="editable"
onget="return this.hasAttribute('editable');"
onset="if (val) this.setAttribute('editable', 'true');
else this.removeAttribute('editable'); return val;"/>
<!-- ///////////////// nsIDOMXULControlElement ///////////////// -->
<property name="disabled"
onget="return this.hasAttribute('disabled');"
onset="if (val) this.setAttribute('disabled', 'true');
else this.removeAttribute('disabled'); return val;"/>
<!-- ///////////////// nsIDOMXULSelectControlElement ///////////////// -->
<!-- ///////////////// nsIDOMXULMultiSelectControlElement ///////////////// -->
<property name="selType"
onget="return this.getAttribute('seltype')"
onset="this.setAttribute('seltype', val); return val;"/>
<property name="currentIndex"
onget="return this.view.selection.currentIndex;"
onset="return this.view.selection.currentIndex = val;"/>
<implementation implements="nsIAccessibleProvider">
<!-- ///////////////// nsIAccessibleProvider ///////////////// -->
@ -73,14 +35,20 @@
<property name="treeBoxObject"
onget="return this.boxObject.QueryInterface(Components.interfaces.nsITreeBoxObject);"
readonly="true"/>
<property name="view"
onget="return this.treeBoxObject.view;"
onset="return this.treeBoxObject.view=val;"/>
# contentView is obsolete (see bug 202391)
<property name="contentView"
onget="return this.view; /*.QueryInterface(Components.interfaces.nsITreeContentView)*/"
onget="return this.treeBoxObject.view; /*.QueryInterface(Components.interfaces.nsITreeContentView)*/"
readonly="true"/>
# builderView is obsolete (see bug 202393)
<property name="builderView"
onget="return this.view; /*.QueryInterface(Components.interfaces.nsIXULTreeBuilder)*/"
onget="return this.treeBoxObject.view; /*.QueryInterface(Components.interfaces.nsIXULTreeBuilder)*/"
readonly="true"/>
<property name="currentIndex"
onget="return this.treeBoxObject.selection.currentIndex;"
onset="return this.treeBoxObject.selection.currentIndex=val;"/>
<field name="pageUpOrDownMovesSelection">
#ifdef XP_MACOSX
false
@ -88,6 +56,12 @@
true
#endif
</field>
<field name="selectionHead">
-1
</field>
<field name="selectionTail">
-1
</field>
<property name="enableColumnDrag"
onget="return this.hasAttribute('enableColumnDrag');"
onset="if (val) this.setAttribute('enableColumnDrag', 'true');
@ -214,31 +188,6 @@
]]></body>
</method>
<method name="changeOpenState">
<parameter name="row"/>
<!-- Optional parameter openState == true or false to set.
No openState param == toggle -->
<parameter name="openState"/>
<body><![CDATA[
if (row < 0 || !this.view.isContainer(row)) {
return false;
}
if (this.view.isContainerOpen(row) != openState) {
this.view.toggleOpenState(row);
if (row == this.currentIndex) {
// Only fire event when current row is expanded or collapsed
// because that's all the assistive technology really cares about.
var event = document.createEvent('Events');
event.initEvent('OpenStateChange', false, true);
this.dispatchEvent(event);
}
return true;
}
return false;
}
]]></body>
</method>
</implementation>
<handlers>
@ -255,14 +204,40 @@
</handler>
<handler event="focus" action="this.treeBoxObject.focused = true;"/>
<handler event="blur" action="this.treeBoxObject.focused = false;"/>
<handler event="keypress" keycode="vk_enter" action="this.changeOpenState(this.currentIndex);"/>
<handler event="keypress" keycode="vk_return" action="this.changeOpenState(this.currentIndex);"/>
<handler event="dragenter" action="this.treeBoxObject.onDragEnter(event);"/>
<handler event="dragexit" action="this.treeBoxObject.onDragExit(event);"/>
<handler event="dragover" action="this.treeBoxObject.onDragOver(event);"/>
<handler event="dragdrop" action="this.treeBoxObject.onDragDrop(event);"/>
<handler event="keypress" keycode="vk_enter">
<![CDATA[
if (this.currentIndex == -1)
return;
if (this.treeBoxObject.view.isContainer(this.currentIndex))
this.treeBoxObject.view.toggleOpenState(this.currentIndex);
]]>
</handler>
<handler event="keypress" keycode="vk_return">
<![CDATA[
if (this.currentIndex == -1)
return;
if (this.treeBoxObject.view.isContainer(this.currentIndex))
this.treeBoxObject.view.toggleOpenState(this.currentIndex);
]]>
</handler>
<handler event="keypress" keycode="vk_left">
<![CDATA[
if (!this.changeOpenState(this.currentIndex, false)) {
var parentIndex = this.view.getParentIndex(this.currentIndex);
if (this.currentIndex == -1)
return;
if (this.treeBoxObject.view.isContainer(this.currentIndex) &&
this.treeBoxObject.view.isContainerOpen(this.currentIndex)) {
this.treeBoxObject.view.toggleOpenState(this.currentIndex);
}
else {
var parentIndex = this.treeBoxObject.view.getParentIndex(this.currentIndex);
if (parentIndex >= 0) {
this.view.selection.select(parentIndex);
this.treeBoxObject.selection.select(parentIndex);
this.treeBoxObject.ensureRowIsVisible(parentIndex);
}
}
@ -270,115 +245,144 @@
</handler>
<handler event="keypress" keycode="vk_right">
<![CDATA[
var row = this.currentIndex;
if (row >= 0 && !this.changeOpenState(row, true)) {
var view = this.view;
if (row + 1 < view.rowCount &&
view.getParentIndex(row + 1) == row) {
// If already opened, select the first child.
// The getParentIndex test above ensures that the children
// are already populated and ready.
this.view.selection.timedSelect(row + 1, this._selectDelay);
this.treeBoxObject.ensureRowIsVisible(row + 1);
}
}
if (this.currentIndex == -1)
return;
if (this.treeBoxObject.view.isContainer(this.currentIndex)) {
if (!this.treeBoxObject.view.isContainerOpen(this.currentIndex))
this.treeBoxObject.view.toggleOpenState(this.currentIndex);
}
]]>
</handler>
<handler event="keypress" keycode="vk_up" modifiers="control any">
<handler event="keypress" keycode="vk_up">
<![CDATA[
if (event.ctrlKey && this.view.selection.single) {
this.treeBoxObject.scrollByLines(-1);
return;
}
var c = this.currentIndex;
if (c == -1 || c == 0)
return;
if (!event.ctrlKey)
this.view.selection.timedSelect(c - 1, this._selectDelay);
else // Ctrl+Up moves the anchor without selecting
this.currentIndex = c - 1;
this.selectionHead = -1;
this.selectionTail = -1;
this.treeBoxObject.selection.timedSelect(c-1, this._selectDelay);
this.treeBoxObject.ensureRowIsVisible(c-1);
]]>
</handler>
<handler event="keypress" keycode="vk_down" modifiers="control any">
<handler event="keypress" keycode="vk_down">
<![CDATA[
if (event.ctrlKey && this.view.selection.single) {
this.treeBoxObject.scrollByLines(1);
return;
}
var c = this.currentIndex;
try {
if (c+1 == this.view.rowCount)
return;
try { if (c+1 == this.treeBoxObject.view.rowCount)
return;
} catch (e) {}
if (!event.ctrlKey)
this.view.selection.timedSelect(c+1, this._selectDelay);
else // Ctrl+Down moves the anchor without selecting
this.currentIndex = c + 1;
this.selectionHead = -1;
this.selectionTail = -1;
this.treeBoxObject.selection.timedSelect(c+1, this._selectDelay);
this.treeBoxObject.ensureRowIsVisible(c+1);
]]>
</handler>
<handler event="keypress" keycode="vk_up" modifiers="control any, shift">
<handler event="keypress" keycode="vk_up" modifiers="shift">
<![CDATA[
if (this.view.selection.single)
if (this.treeBoxObject.selection.single)
return;
var c = this.currentIndex;
if (c == -1 || c == 0)
return;
// Extend the selection from the existing pivot, if any
this.view.selection.rangedSelect(-1, c - 1, event.ctrlKey);
if (c == this.selectionTail) {
if (this.selectionHead < this.selectionTail) {
this.treeBoxObject.selection.toggleSelect(c);
this.currentIndex = c - 1;
}
else {
this.treeBoxObject.selection.toggleSelect(c - 1);
}
}
else {
this.treeBoxObject.selection.clearSelection();
this.selectionHead = c;
this.treeBoxObject.selection.rangedSelect(c, c - 1, true);
}
this.selectionTail = c - 1;
this.treeBoxObject.ensureRowIsVisible(c - 1);
]]>
</handler>
<handler event="keypress" keycode="vk_down" modifiers="control any, shift">
<handler event="keypress" keycode="vk_down" modifiers="shift">
<![CDATA[
if (this.view.selection.single)
if (this.treeBoxObject.selection.single)
return;
var c = this.currentIndex;
try {
if (c+1 == this.view.rowCount)
return;
try { if (c+1 == this.treeBoxObject.view.rowCount)
return;
} catch (e) {}
// Extend the selection from the existing pivot, if any
this.view.selection.rangedSelect(-1, c + 1, event.ctrlKey);
if (c == this.selectionTail) {
if (this.selectionHead > this.selectionTail) {
this.treeBoxObject.selection.toggleSelect(c);
this.currentIndex = c + 1;
}
else
this.treeBoxObject.selection.toggleSelect(c + 1);
}
else {
this.treeBoxObject.selection.clearSelection();
this.selectionHead = c;
this.treeBoxObject.selection.rangedSelect(c, c + 1, true);
}
this.selectionTail = c + 1;
this.treeBoxObject.ensureRowIsVisible(c + 1);
]]>
</handler>
<handler event="keypress" keycode="vk_page_up" modifiers="control any">
<handler event="keypress" keycode="vk_up" modifiers="control">
<![CDATA[
if (this.pageUpOrDownMovesSelection == event.ctrlKey) {
var c = this.currentIndex;
if (c == -1 || c == 0)
return;
this.currentIndex = c-1;
this.treeBoxObject.ensureRowIsVisible(c-1);
]]>
</handler>
<handler event="keypress" keycode="vk_down" modifiers="control">
<![CDATA[
var c = this.currentIndex;
try { if (c+1 == this.treeBoxObject.view.rowCount)
return;
} catch (e) {}
this.currentIndex = c+1;
this.treeBoxObject.ensureRowIsVisible(c+1);
]]>
</handler>
<handler event="keypress" keycode="vk_page_up">
<![CDATA[
if (! this.pageUpOrDownMovesSelection) {
this.treeBoxObject.scrollByPages(-1);
return;
}
var c = this.currentIndex;
if (c == 0)
return;
this.selectionHead = -1;
this.selectionTail = -1;
var f = this.treeBoxObject.getFirstVisibleRow();
var i = 0;
if (f > 0) {
var p = this.treeBoxObject.getPageLength();
var p = this.treeBoxObject.getPageCount();
if (f - p >= 0)
i = c - p;
else
i = c - f;
this.treeBoxObject.scrollByPages(-1);
}
this.view.selection.timedSelect(i, this._selectDelay);
this.treeBoxObject.selection.timedSelect(i, this._selectDelay);
]]>
</handler>
<handler event="keypress" keycode="vk_page_down" modifiers="control any">
<handler event="keypress" keycode="vk_page_down">
<![CDATA[
if (this.pageUpOrDownMovesSelection == event.ctrlKey) {
if (! this.pageUpOrDownMovesSelection) {
this.treeBoxObject.scrollByPages(1);
return;
}
var c = this.currentIndex;
var l = this.view.rowCount - 1;
var l = this.treeBoxObject.view.rowCount - 1;
if (c == l)
return;
this.selectionHead = -1;
this.selectionTail = -1;
var f = this.treeBoxObject.getFirstVisibleRow();
var p = this.treeBoxObject.getPageLength();
var p = this.treeBoxObject.getPageCount();
var i = l;
var lastTopRowIndex = l - p;
if (f <= lastTopRowIndex) {
@ -388,12 +392,12 @@
i = lastTopRowIndex + c - f + 1;
this.treeBoxObject.scrollByPages(1);
}
this.view.selection.timedSelect(i, this._selectDelay);
this.treeBoxObject.selection.timedSelect(i, this._selectDelay);
]]>
</handler>
<handler event="keypress" keycode="vk_page_up" modifiers="control any, shift">
<handler event="keypress" keycode="vk_page_up" modifiers="shift">
<![CDATA[
if (this.view.selection.single)
if (this.treeBoxObject.selection.single)
return;
var c = this.currentIndex;
if (c == 0)
@ -401,27 +405,45 @@
var f = this.treeBoxObject.getFirstVisibleRow();
var i = 0;
if (f > 0) {
var p = this.treeBoxObject.getPageLength();
var p = this.treeBoxObject.getPageCount();
if (f - p >= 0)
i = c - p;
else
i = c - f;
this.treeBoxObject.scrollByPages(-1);
}
// Extend the selection from the existing pivot, if any
this.view.selection.rangedSelect(-1, i, event.ctrlKey);
if (c == this.selectionTail) {
if (this.selectionHead < this.selectionTail) {
if (i < this.selectionHead) {
this.treeBoxObject.selection.clearRange(c, this.selectionHead + 1);
this.treeBoxObject.selection.rangedSelect(this.selectionHead - 1, i, true);
}
else {
this.treeBoxObject.selection.clearRange(c, i + 1);
this.currentIndex = i;
}
}
else
this.treeBoxObject.selection.rangedSelect(c - 1, i, true);
}
else {
this.treeBoxObject.selection.clearSelection();
this.selectionHead = c;
this.treeBoxObject.selection.rangedSelect(c, i, true);
}
this.selectionTail = i;
]]>
</handler>
<handler event="keypress" keycode="vk_page_down" modifiers="control any, shift">
<handler event="keypress" keycode="vk_page_down" modifiers="shift">
<![CDATA[
if (this.view.selection.single)
if (this.treeBoxObject.selection.single)
return;
var c = this.currentIndex;
var l = this.view.rowCount - 1;
var l = this.treeBoxObject.view.rowCount - 1;
if (c == l)
return;
var f = this.treeBoxObject.getFirstVisibleRow();
var p = this.treeBoxObject.getPageLength();
var p = this.treeBoxObject.getPageCount();
var i = l;
var lastTopRowIndex = l - p;
if (f <= lastTopRowIndex) {
@ -431,53 +453,134 @@
i = lastTopRowIndex + c - f + 1;
this.treeBoxObject.scrollByPages(1);
}
// Extend the selection from the existing pivot, if any
this.view.selection.rangedSelect(-1, i, event.ctrlKey);
if (c == this.selectionTail) {
if (this.selectionHead > this.selectionTail) {
if (i > this.selectionHead) {
this.treeBoxObject.selection.clearRange(c, this.selectionHead - 1);
this.treeBoxObject.selection.rangedSelect(this.selectionHead + 1, i, true);
}
else {
this.treeBoxObject.selection.clearRange(c, i - 1);
this.currentIndex = i;
}
}
else
this.treeBoxObject.selection.rangedSelect(c + 1, i, true);
}
else {
this.treeBoxObject.selection.clearSelection();
this.selectionHead = c;
this.treeBoxObject.selection.rangedSelect(c, i, true);
}
this.selectionTail = i;
]]>
</handler>
<handler event="keypress" keycode="vk_home" modifiers="control any">
<handler event="keypress" keycode="vk_page_up" modifiers="control">
<![CDATA[
if (this.view.rowCount == 0)
var c = this.currentIndex;
if (c == 0)
return;
// Normal behaviour is to select the first row
if (!event.ctrlKey)
this.view.selection.timedSelect(0, this._selectDelay);
// In a multiselect tree Ctrl+Home moves the anchor
else if (!this.view.selection.single)
this.currentIndex = 0;
var f = this.treeBoxObject.getFirstVisibleRow();
var i = 0;
if (f > 0) {
var p = this.treeBoxObject.getPageCount();
if (f - p >= 0)
i = c - p;
else
i = c - f;
this.treeBoxObject.scrollByPages(-1);
}
this.currentIndex = i;
]]>
</handler>
<handler event="keypress" keycode="vk_page_down" modifiers="control">
<![CDATA[
var c = this.currentIndex;
var l = this.treeBoxObject.view.rowCount - 1;
if (c == l)
return;
var f = this.treeBoxObject.getFirstVisibleRow();
var p = this.treeBoxObject.getPageCount();
var i = l;
var lastTopRowIndex = l - p;
if (f <= lastTopRowIndex) {
if (f + p <= lastTopRowIndex)
i = c + p;
else
i = lastTopRowIndex + c - f + 1;
this.treeBoxObject.scrollByPages(1);
}
this.currentIndex = i;
]]>
</handler>
<handler event="keypress" keycode="vk_home">
<![CDATA[
if (this.currentIndex == 0)
return;
this.selectionHead = -1;
this.selectionTail = -1;
this.treeBoxObject.selection.select(0);
this.treeBoxObject.ensureRowIsVisible(0);
]]>
</handler>
<handler event="keypress" keycode="vk_end" modifiers="control any">
<handler event="keypress" keycode="vk_end">
<![CDATA[
var l = this.view.rowCount - 1;
if (l < 0)
var l = this.treeBoxObject.view.rowCount - 1;
if (this.currentIndex == l)
return;
// Normal behaviour is to select the last row
if (!event.ctrlKey)
this.view.selection.timedSelect(l, this._selectDelay);
// In a multiselect tree Ctrl+End moves the anchor
else if (!this.view.selection.single)
this.currentIndex = l;
this.selectionHead = -1;
this.selectionTail = -1;
this.treeBoxObject.selection.select(l);
this.treeBoxObject.ensureRowIsVisible(l);
]]>
</handler>
<handler event="keypress" keycode="vk_home" modifiers="control any, shift">
<handler event="keypress" keycode="vk_home" modifiers="shift">
<![CDATA[
if (this.view.selection.single)
if (this.treeBoxObject.selection.single)
return;
// Extend the selection from the existing pivot, if any
this.view.selection.rangedSelect(-1, 0, event.ctrlKey);
var c = this.currentIndex;
if (c == 0)
return;
if (c != this.selectionTail) {
this.treeBoxObject.selection.clearSelection();
this.selectionHead = c;
}
this.treeBoxObject.selection.rangedSelect(c, 0, true);
this.selectionTail = 0;
this.treeBoxObject.ensureRowIsVisible(0);
]]>
</handler>
<handler event="keypress" keycode="vk_end" modifiers="control any, shift">
<handler event="keypress" keycode="vk_end" modifiers="shift">
<![CDATA[
if (this.view.selection.single)
if (this.treeBoxObject.selection.single)
return;
var l = this.view.rowCount - 1;
// Extend the selection from the existing pivot, if any
this.view.selection.rangedSelect(-1, l, event.ctrlKey);
var c = this.currentIndex;
var l = this.treeBoxObject.view.rowCount - 1;
if (c == l)
return;
if (c != this.selectionTail) {
this.treeBoxObject.selection.clearSelection();
this.selectionHead = c;
}
this.treeBoxObject.selection.rangedSelect(c, l, true);
this.selectionTail = l;
this.treeBoxObject.ensureRowIsVisible(l);
]]>
</handler>
<handler event="keypress" keycode="vk_home" modifiers="control">
<![CDATA[
if (this.currentIndex == 0)
return;
this.currentIndex = 0;
this.treeBoxObject.ensureRowIsVisible(0);
]]>
</handler>
<handler event="keypress" keycode="vk_end" modifiers="control">
<![CDATA[
var l = this.treeBoxObject.view.rowCount - 1;
if (this.currentIndex == l)
return;
this.currentIndex = l;
this.treeBoxObject.ensureRowIsVisible(l);
]]>
</handler>
@ -485,8 +588,8 @@
<![CDATA[
var c = this.currentIndex;
if (event.keyCode == ' '.charCodeAt(0)) {
if (!this.view.selection.isSelected(c))
this.view.selection.toggleSelect(c);
if (!this.treeBoxObject.selection.isSelected(c))
this.treeBoxObject.selection.toggleSelect(c);
}
else if (!this.disableKeyNavigation && event.charCode > 0 &&
!event.altKey && !event.ctrlKey && !event.shiftKey && !event.metaKey) {
@ -509,8 +612,9 @@
incrementalString = incrementalString.substring(0, length);
}
var keyCol = this.columns.getKeyColumn();
var rowCount = this.view.rowCount;
var primarycol = this.treeBoxObject.getKeyColumnIndex();
var colID = this.treeBoxObject.getColumnID(primarycol);
var rowCount = this.treeBoxObject.view.rowCount;
var start = 1;
if (length > 1) {
@ -521,10 +625,12 @@
for (var i = 0; i < rowCount; i++) {
var l = (i + start + c) % rowCount;
var cellText = this.view.getCellText(l, keyCol);
var cellText = this.treeBoxObject.view.getCellText(l, colID);
cellText = cellText.substring(0, length).toLowerCase();
if (cellText == incrementalString) {
this.view.selection.timedSelect(l, this._selectDelay);
this.selectionHead = -1;
this.selectionTail = -1;
this.treeBoxObject.selection.timedSelect(l, this._selectDelay);
this.treeBoxObject.ensureRowIsVisible(l);
break;
}
@ -589,11 +695,11 @@
<handlers>
<!-- If there is no modifier key, we select on mousedown, not
click, so that drags work correctly. -->
<handler event="mousedown" clickcount="1">
<handler event="mousedown">
<![CDATA[
if (((!event.ctrlKey || !this.parentNode.pageUpOrDownMovesSelection) &&
!event.shiftKey && !event.metaKey) ||
this.parentNode.view.selection.single) {
this.parentNode.treeBoxObject.selection.single) {
var row = {};
var col = {};
var obj = {};
@ -607,19 +713,14 @@
return;
if (col.value && obj.value != "twisty") {
if (col.value.cycler)
var column = document.getElementById(col.value);
var cycler = column.hasAttribute('cycler');
if (cycler)
b.view.cycleCell(row.value, col.value);
else if (col.value.type == Components.interfaces.nsITreeColumn.TYPE_CHECKBOX) {
if (this.parentNode.editable && col.value.editable &&
b.view.isEditable(row.value, col.value)) {
var value = b.view.getCellValue(row.value, col.value);
value = value == "true" ? "false" : "true";
b.view.setCellValue(row.value, col.value, value);
}
}
else
if (!b.view.selection.isSelected(row.value)) {
b.view.selection.select(row.value);
if (!b.selection.isSelected(row.value)) {
b.selection.select(row.value);
b.ensureRowIsVisible(row.value);
}
}
@ -629,8 +730,9 @@
<!-- On a click (up+down on the same item), deselect everything
except this item. -->
<handler event="click" button="0" clickcount="1">
<handler event="click">
<![CDATA[
if (event.button != 0) return;
var row = {};
var col = {};
var obj = {};
@ -641,29 +743,29 @@
return;
if (obj.value == "twisty") {
if (b.view.selection.currentIndex >= 0 &&
if (b.selection.currentIndex >= 0 &&
b.view.isContainerOpen(row.value)) {
var parentIndex = b.view.getParentIndex(b.view.selection.currentIndex);
var parentIndex = b.view.getParentIndex(b.selection.currentIndex);
while (parentIndex >= 0 && parentIndex != row.value)
parentIndex = b.view.getParentIndex(parentIndex);
if (parentIndex == row.value)
b.view.selection.select(parentIndex);
b.selection.select(parentIndex);
}
this.parentNode.changeOpenState(row.value);
b.view.toggleOpenState(row.value);
return;
}
if (! b.view.selection.single) {
if (! this.parentNode.treeBoxObject.selection.single) {
var augment = event.ctrlKey || event.metaKey;
if (event.shiftKey) {
b.view.selection.rangedSelect(-1, row.value, augment);
b.selection.rangedSelect(-1, row.value, augment);
b.ensureRowIsVisible(row.value);
return;
}
if (augment) {
b.view.selection.toggleSelect(row.value);
b.selection.toggleSelect(row.value);
b.ensureRowIsVisible(row.value);
b.view.selection.currentIndex = row.value;
b.selection.currentIndex = row.value;
return;
}
}
@ -674,13 +776,14 @@
selected group of items */
if (!col.value) return;
var column = document.getElementById(col.value);
var cycler = column.hasAttribute('cycler');
// if the last row has changed in between the time we
// mousedown and the time we click, don't fire the select handler.
// see bug #92366
if (!col.value.cycler && this._lastSelectedRow == row.value &&
col.value.type != Components.interfaces.nsITreeColumn.TYPE_CHECKBOX) {
b.view.selection.select(row.value);
if (!cycler && this._lastSelectedRow == row.value) {
b.selection.select(row.value);
b.ensureRowIsVisible(row.value);
}
]]>
@ -689,18 +792,20 @@
<!-- double-click -->
<handler event="click" clickcount="2">
<![CDATA[
var b = this.parentNode.treeBoxObject;
var row = b.view.selection.currentIndex;
if (row == -1 || !b.view.isContainer(row))
return;
var row = {};
var col = {};
var obj = {};
var b = this.parentNode.treeBoxObject;
b.getCellAt(event.clientX, event.clientY, row, col, obj);
var col = {};
var obj = {};
b.getCellAt(event.clientX, event.clientY, {}, col, obj);
if (row.value == -1)
return;
// Cyclers and twisties respond to single clicks, not double clicks
if (!col.value.cycler && obj.value != "twisty")
this.parentNode.changeOpenState(row);
var column = document.getElementById(col.value);
var cycler = column.hasAttribute('cycler');
if (!cycler && obj.value != "twisty" && b.view.isContainer(row.value))
b.view.toggleOpenState(row.value);
]]>
</handler>
@ -763,18 +868,15 @@
var tree = col.parentNode.parentNode;
var sib;
var column;
if (col.mTargetCol) {
// remove previous insertbefore/after attributes
col.mTargetCol.removeAttribute("insertbefore");
col.mTargetCol.removeAttribute("insertafter");
column = tree.columns.getColumnFor(col.mTargetCol);
tree.treeBoxObject.invalidateColumn(column);
tree.treeBoxObject.invalidateColumn(col.mTargetCol.id);
sib = col.mTargetCol._previousVisibleColumn;
if (sib) {
sib.removeAttribute("insertafter");
column = tree.columns.getColumnFor(sib);
tree.treeBoxObject.invalidateColumn(column);
tree.treeBoxObject.invalidateColumn(sib.id);
}
col.mTargetCol = null;
col.mTargetDir = null;
@ -789,12 +891,10 @@
sib = targetCol._previousVisibleColumn;
if (sib) {
sib.setAttribute("insertafter", "true");
column = tree.columns.getColumnFor(sib);
tree.treeBoxObject.invalidateColumn(column);
tree.treeBoxObject.invalidateColumn(sib.id);
}
}
column = tree.columns.getColumnFor(targetCol);
tree.treeBoxObject.invalidateColumn(column);
tree.treeBoxObject.invalidateColumn(targetCol.id);
col.mTargetCol = targetCol;
col.mTargetDir = pos.value;
}
@ -875,20 +975,13 @@
}
}
]]></handler>
<handler event="click" button="0" phase="target">
<![CDATA[
var tree = this.parentNode.parentNode;
var column = tree.columns.getColumnFor(this);
tree.view.cycleHeader(column);
]]>
</handler>
</handlers>
</binding>
<binding id="treecol" extends="chrome://global/content/bindings/tree.xml#treecol-base">
<content>
<xul:label class="treecol-text" xbl:inherits="crop,value=label" flex="1" crop="right"/>
<xul:image class="treecol-sortdirection" xbl:inherits="sortDirection,hidden=hideheader"/>
<xul:image class="treecol-sortdirection" xbl:inherits="sortDirection"/>
</content>
<implementation implements="nsIAccessibleProvider">
<property name="accessible">
@ -900,22 +993,26 @@
</getter>
</property>
</implementation>
<handlers>
<handler event="click" button="0" phase="target" action="this.parentNode.parentNode.treeBoxObject.view.cycleHeader(this.id, this);"/>
</handlers>
</binding>
<binding id="treecol-image" extends="chrome://global/content/bindings/tree.xml#treecol-base">
<content>
<xul:image class="treecol-icon" xbl:inherits="src"/>
</content>
<handlers>
<handler event="click" button="0" action="this.parentNode.parentNode.treeBoxObject.view.cycleHeader(this.id, this)"/>
</handlers>
</binding>
<binding id="columnpicker" display="xul:button"
extends="chrome://global/content/bindings/tree.xml#tree-base">
<content>
<xul:image class="tree-columnpicker-icon"/>
<xul:menupopup anonid="popup">
<xul:menuseparator anonid="menuseparator"/>
<xul:menuitem anonid="menuitem" label="&restoreNaturalOrder.label;"/>
</xul:menupopup>
<xul:menupopup anonid="popup"/>
</content>
<implementation>
@ -923,39 +1020,27 @@
<parameter name="aPopup"/>
<body>
<![CDATA[
// We no longer cache the picker content, remove the old content.
while (aPopup.childNodes.length > 2)
aPopup.removeChild(aPopup.firstChild);
// we no longer cache the picker content.
// remove the old content
while (aPopup.hasChildNodes())
aPopup.removeChild(aPopup.lastChild);
var refChild = aPopup.firstChild;
var tree = this.parentNode.parentNode;
for (var currCol = tree.columns.getFirstColumn(); currCol;
currCol = currCol.getNext()) {
for (var currCol = this.parentNode.firstChild; currCol; currCol = currCol.nextSibling) {
// Construct an entry for each column in the row, unless
// it is not being shown.
var currElement = currCol.element;
if (!currElement.hasAttribute("ignoreincolumnpicker")) {
// it is not being shown
if (currCol.localName == "treecol" && !currCol.hasAttribute("ignoreincolumnpicker")) {
var popupChild = document.createElement("menuitem");
popupChild.setAttribute("type", "checkbox");
var columnName = currElement.getAttribute("display") ||
currElement.getAttribute("label");
var columnName = currCol.getAttribute("display") || currCol.getAttribute("label");
popupChild.setAttribute("label", columnName);
popupChild.setAttribute("colindex", currCol.index);
if (currElement.getAttribute("hidden") != "true")
popupChild.setAttribute("colid", currCol.id);
if (currCol.getAttribute("hidden") != "true")
popupChild.setAttribute("checked", "true");
if (currCol.primary)
if (currCol.getAttribute("primary") == "true")
popupChild.setAttribute("disabled", "true");
aPopup.insertBefore(popupChild, refChild);
aPopup.appendChild(popupChild);
}
}
var hidden = !tree.enableColumnDrag;
const anonids = ["menuseparator", "menuitem"];
for (var anonid in anonids) {
var element = document.getAnonymousElementByAttribute(this, "anonid", anonids[anonid]);
element.hidden = hidden;
}
]]>
</body>
</method>
@ -968,24 +1053,14 @@
var popup = document.getAnonymousElementByAttribute(this, "anonid", "popup");
this.buildPopup(popup);
popup.showPopup(this, -1, -1, "popup", "bottomright", "topright");
}
else {
var tree = this.parentNode.parentNode;
var menuitem = document.getAnonymousElementByAttribute(this, "anonid", "menuitem");
if (event.originalTarget == menuitem) {
tree.columns.restoreNaturalOrder();
tree._ensureColumnOrder();
}
else {
var colindex = event.originalTarget.getAttribute("colindex");
var column = tree.columns[colindex];
if (column) {
var element = column.element;
if (element.getAttribute("hidden") == "true")
element.setAttribute("hidden", "false");
else
element.setAttribute("hidden", "true");
}
} else {
var colid = event.originalTarget.getAttribute("colid");
var colNode = document.getElementById(colid);
if (colNode) {
if (colNode.getAttribute("hidden") == "true")
colNode.setAttribute("hidden", "false");
else
colNode.setAttribute("hidden", "true");
}
}
]]>

Просмотреть файл

@ -24,8 +24,8 @@
</content>
<implementation>
<property name="title" onget="return document.title;"
onset="return document.title = val;"/>
<property name="title" onget="return this.getAttribute('title')"
onset="this.setAttribute('title', val);"/>
<property name="canAdvance" onget="return this._canAdvance;"
onset="this._canAdvance=val; this._nextButton.setAttribute('disabled', !val);"/>
@ -118,7 +118,7 @@
<body>
<![CDATA[
var btns = this.getElementsByAttribute("dlgtype", aDlgType);
return btns.item(0) ? btns[0] : document.getAnonymousElementByAttribute(this._wizardButtons, "dlgtype", aDlgType);
return btns.length > 0 ? btns[0] : document.getAnonymousElementByAttribute(this._wizardButtons, "dlgtype", aDlgType);
]]>
</body>
</method>
@ -184,7 +184,7 @@
<parameter name="aPageId"/>
<body><![CDATA[
var els = this.getElementsByAttribute("pageid", aPageId);
return els.item(0);
return els.length > 0 ? els[0] : null;
]]></body>
</method>
@ -420,10 +420,8 @@
<content>
<xul:stack class="wizard-header-stack" flex="1">
<xul:vbox class="wizard-header-box-1">
<xul:vbox class="wizard-header-box-2">
<xul:vbox class="wizard-header-box-text">
<xul:label class="wizard-header-label" xbl:inherits="value=label"/>
</xul:vbox>
<xul:vbox class="wizard-header-box-text">
<xul:label class="wizard-header-label" xbl:inherits="value=label"/>
</xul:vbox>
</xul:vbox>
<xul:hbox class="wizard-header-box-icon">
@ -437,19 +435,15 @@
<binding id="wizard-buttons" extends="chrome://global/content/bindings/wizard.xml#wizard-base">
<content>
<xul:vbox flex="1">
<xul:hbox class="wizard-buttons-top" xbl:inherits="hidden=hidetoprow">
<xul:spacer flex="1"/>
<xul:button class="wizard-button" dlgtype="cancel"/>
<xul:button class="wizard-button" dlgtype="finish" default="true"/>
</xul:hbox>
<xul:separator class="wizard-buttons-separator groove"/>
<xul:hbox class="wizard-buttons-btm">
<xul:button class="wizard-button" dlgtype="cancel"/>
<xul:spacer flex="1"/>
<xul:button class="wizard-button wizard-nav-button" dlgtype="back"/>
<xul:hbox class="wizard-label-box" align="center">
<xul:label class="wizard-page-label" xbl:inherits="value=pagestep"/>
</xul:hbox>
<xul:button class="wizard-button wizard-nav-button" dlgtype="next" default="true" xbl:inherits="disabled=lastpage"/>
<xul:button class="wizard-button wizard-nav-button" dlgtype="next" default="true" xbl:inherits="hidden=lastpage" />
<xul:button class="wizard-button" dlgtype="finish" default="true" xbl:inherits="hidden=hidefinishbutton" />
</xul:hbox>
</xul:vbox>
</content>
@ -457,7 +451,7 @@
<implementation>
<method name="onPageChange">
<body><![CDATA[
this.setAttribute("hidetoprow", !(this.getAttribute("lastpage") == "true"));
this.setAttribute("hidefinishbutton", !(this.getAttribute("lastpage") == "true"));
]]></body>
</method>
</implementation>