bug 213228: new toolkit independence bug, part 7: update and use the new toolkit widgetry.

menulist.xml: bug ?????, 96642, 196755, 180512 by neil, bug 201166 by jgaunt
This commit is contained in:
chanial%noos.fr 2003-08-17 11:09:50 +00:00
parent 3e24f04413
commit 36d8fb58c0

View File

@ -13,8 +13,8 @@
</binding>
<binding id="menulist" display="xul:menu"
extends="chrome://global/content/bindings/menulist.xml#menulist-base">
<content>
extends="chrome://global/content/widgets/menulist.xml#menulist-base">
<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"/>
@ -24,22 +24,28 @@
</content>
<handlers>
<handler event="command" phase="capturing"
action="if (event.originalTarget.localName == 'menuitem') this.selectedItem = event.originalTarget;"/>
<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.
var menuBox = this.boxObject.QueryInterface(Components.interfaces.nsIMenuBoxObject);
menuBox.activeChild = this.selectedItem;
}
this.menuBoxObject.activeChild = this.selectedInternal;
]]>
</handler>
</handlers>
<implementation implements="nsIDOMXULMenuListElement, nsIDOMXULSelectControlElement, nsIAccessibleProvider">
<implementation implements="nsIDOMXULMenuListElement, nsIAccessibleProvider">
<constructor>
this.setInitialSelection()
</constructor>
@ -47,24 +53,17 @@
<method name="setInitialSelection">
<body>
<![CDATA[
this.setAttribute('sizetopopup', 'pref');
if (this.childNodes.length) {
// if there was a previously selected item, be sure to set our internal
// selection memory to that item so we can un-set it properly later on
var arr = this.firstChild.getElementsByAttribute('selected', 'true');
if (arr.length)
this.selectedInternal = arr[0];
if (!this.label && this.childNodes.length) {
if (!arr.length && this.value)
arr = this.firstChild.getElementsByAttribute('value', this.value);
var popup = this.menupopup;
if (popup) {
var arr = popup.getElementsByAttribute('selected', 'true');
if (!arr.length && this.value)
arr = popup.getElementsByAttribute('value', this.value);
if (arr.length)
this.selectedItem = arr[0];
else
this.selectedIndex = 0;
}
if (arr.length)
this.selectedItem = arr[0];
else
this.selectedIndex = 0;
}
]]>
</body>
@ -73,10 +72,10 @@
<property name="value" onget="return this.getAttribute('value');">
<setter>
<![CDATA[
var arr;
if (this.childNodes.length)
arr = this.firstChild.getElementsByAttribute('value', val);
var arr = null;
var popup = this.menupopup;
if (popup)
arr = popup.getElementsByAttribute('value', val);
if (arr && arr.length)
this.selectedItem = arr[0];
@ -99,10 +98,24 @@
return val;"
onget="return this.hasAttribute('disabled');"/>
<property name="open" onset="if (val) this.setAttribute('open',true);
else this.removeAttribute('open');
return val;"
onget="return this.hasAttribute('open');"/>
<property name="open" onset="this.menuBoxObject.openMenu(val);
return val;"
onget="return this.hasAttribute('open');"/>
<property name="menupopup" readonly="true">
<getter>
<![CDATA[
var popup = this.firstChild;
while (popup && popup.localName != "menupopup")
popup = popup.nextSibling;
return popup;
]]>
</getter>
</property>
<field name="menuBoxObject" readonly="true">
this.boxObject.QueryInterface(Components.interfaces.nsIMenuBoxObject)
</field>
<field name="selectedInternal">
null
@ -112,29 +125,27 @@
<getter>
<![CDATA[
// Quick and dirty. We won't deal with hierarchical menulists yet.
if (!this.selectedItem)
if (!this.selectedItem ||
!this.selectedInternal.parentNode ||
this.selectedInternal.parentNode.parentNode != this)
return -1;
var children = this.selectedItem.parentNode.childNodes;
for (var i = 0; i < children.length; i++) {
if (children[i] == this.selectedItem)
return i;
}
var children = this.selectedInternal.parentNode.childNodes;
var i = children.length;
while (i--)
if (children[i] == this.selectedInternal)
break;
return -1;
return i;
]]>
</getter>
<setter>
<![CDATA[
if (val < 0)
var popup = this.menupopup;
if (popup && 0 <= val && val < popup.childNodes.length)
this.selectedItem = popup.childNodes[val];
else
this.selectedItem = null;
else {
var curr = this.firstChild;
while (curr && curr.localName != 'menupopup')
curr = curr.nextSibling;
if (curr && val < curr.childNodes.length)
this.selectedItem = curr.childNodes[val];
}
return val;
]]>
</setter>
@ -178,16 +189,14 @@
<parameter name="value"/>
<body>
<![CDATA[
var popup = this.getElementsByTagName("menupopup")[0];
if (popup) {
var XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
var item = document.createElementNS(XULNS, "menuitem");
item.setAttribute("label", label);
item.setAttribute("value", value);
popup.appendChild(item);
return item;
}
return null;
const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
var popup = this.menupopup ||
this.appendChild(document.createElementNS(XULNS, "menupopup"));
var item = document.createElementNS(XULNS, "menuitem");
item.setAttribute("label", label);
item.setAttribute("value", value);
popup.appendChild(item);
return item;
]]>
</body>
</method>
@ -198,20 +207,17 @@
<parameter name="value"/>
<body>
<![CDATA[
var popup = this.getElementsByTagName("menupopup")[0];
if (popup) {
var XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
var item = document.createElementNS(XULNS, "menuitem");
item.setAttribute("label", label);
item.setAttribute("value", value);
var before = popup.childNodes[index];
if (before)
popup.insertBefore(item, before);
else
popup.appendChild(item);
return item;
}
return null;
const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
var popup = this.menupopup ||
this.appendChild(document.createElementNS(XULNS, "menupopup"));
var item = document.createElementNS(XULNS, "menuitem");
item.setAttribute("label", label);
item.setAttribute("value", value);
if (index < popup.childNodes.length)
popup.insertBefore(item, popup.childNodes[index]);
else
popup.appendChild(item);
return item;
]]>
</body>
</method>
@ -220,11 +226,10 @@
<parameter name="index"/>
<body>
<![CDATA[
var popup = this.getElementsByTagName("menupopup")[0];
if (popup) {
var popup = this.menupopup;
if (popup && 0 <= index && index < popup.childNodes.length) {
var remove = popup.childNodes[index];
if (remove)
popup.removeChild(remove);
popup.removeChild(remove);
return remove;
}
return null;
@ -232,6 +237,17 @@
</body>
</method>
<method name="removeAllItems">
<body>
<![CDATA[
this.selectedInternal = null;
var popup = this.menupopup;
if (popup)
this.removeChild(popup);
]]>
</body>
</method>
<property name="accessible">
<getter>
<![CDATA[
@ -243,10 +259,10 @@
</implementation>
</binding>
<binding id="menulist-editable" extends="chrome://global/content/bindings/menulist.xml#menulist">
<content>
<xul:hbox class="menulist-editable-box" flex="1">
<html:input flex="1" class="menulist-editable-input" allowevents="true"
<binding id="menulist-editable" extends="chrome://global/content/widgets/menulist.xml#menulist">
<content sizetopopup="pref">
<xul:hbox class="menulist-editable-box textbox-input-box" xbl:inherits="context" flex="1">
<html:input class="menulist-editable-input" flex="1" anonid="input" allowevents="true"
xbl:inherits="value=label,disabled"/>
</xul:hbox>
<xul:dropmarker class="menulist-dropmarker" type="menu"/>
@ -265,18 +281,16 @@
return "";
// Find and select the menuitem that matches inputField's "value"
var inputVal = this.inputField.value;
var arr;
var arr = null;
var popup = this.menupopup;
if (this.childNodes.length)
arr = this.firstChild.getElementsByAttribute('label', inputVal);
if (popup)
arr = popup.getElementsByAttribute('label', this.inputField.value);
if (arr && arr.length)
this.setSelectionInternal(arr[0]);
else
this.setSelectionInternal(null);
return inputVal;
]]>
</body>
</method>
@ -296,35 +310,25 @@
this.selectedInternal = val;
//Do NOT change the "value", which is owned by inputField
if (!this.selectedInternal) {
this.removeAttribute('src');
return val;
}
val.setAttribute('selected', 'true');
this.setAttribute('src', val.getAttribute('src'));
if (val)
val.setAttribute('selected', 'true');
//Do NOT change the "value", which is owned by inputField
return val;
]]>
</body>
</method>
<field name="inputField" readonly="true">
<![CDATA[
var v = document.getAnonymousNodes(this);
var input = null;
for (var i = 0; i < v.length; i++) {
try {
var l = v[i].getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "input");
if (l.length > 0) {
input = l[0];
break;
}
} catch (e) {}
}
input;
]]>
</field>
<field name="mInputField">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="label" onset="this.inputField.value = val; return val;"
onget="return this.inputField.value;"/>
@ -378,82 +382,58 @@
else this.removeAttribute('disableautoselect'); return val;"
onget="return this.hasAttribute('disableautoselect');"/>
<property name="open">
<getter>
<![CDATA[
return this.getAttribute('open') == 'true';
]]>
</getter>
<setter>
<![CDATA[
var popups = this.getElementsByTagNameNS(
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
"menupopup");
if (!popups || popups.length == 0)
return val;
if (val) { // open the popup
popups[0].showPopup(this, -1, -1, "popup", "bottomleft", "topleft");
this._selectInputFieldValueInList();
this.setAttribute('open', 'true');
}
else { // hide the popup
popups[0].hidePopup();
this.removeAttribute('open');
}
return val;
]]>
</setter>
</property>
<method name="select">
<body>
this.inputField.select();
</body>
</method>
</implementation>
<handlers>
<handler event="focus" phase="capturing">
<![CDATA[
if (!this.hasAttribute('focused'))
{
this.setAttribute('focused','true');
this.suppressFocusBlur = true;
if (document.commandDispatcher.focusedElement != this.inputField)
this.inputField.focus();
this.suppressFocusBlur = false;
}
]]>
<![CDATA[
if (!this.hasAttribute('focused')) {
if (document.commandDispatcher.focusedElement != this.inputField)
this.inputField.focus();
this.setAttribute('focused','true');
}
]]>
</handler>
<handler event="blur" phase="capturing">
<![CDATA[
if (!this.suppressFocusBlur && this.hasAttribute('focused')) {
<![CDATA[
this.removeAttribute('focused');
}
]]>
]]>
</handler>
<handler event="popupshowing">
<![CDATA[
// BUG in Classic skin: doesn't shift focus when popup is opened
// so force it to inputField here
if (event.target.parentNode == this) {
// editable menulists elements aren't in the focus order,
// so when the popup opens we need to force the focus to the inputField
// 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();
if (this.selectedItem) {
if (this.selectedItem)
// Not ready for auto-setting the active child in hierarchies yet.
// For now, only do this when the outermost menupopup opens.
var menuBox = this.boxObject.QueryInterface(Components.interfaces.nsIMenuBoxObject);
menuBox.activeChild = this.selectedItem;
}
this.menuBoxObject.activeChild = this.selectedInternal;
}
]]>
</handler>
<handler event="keypress">
<![CDATA[
// open popup if key is up or down
if (event.keyCode == KeyEvent.DOM_VK_UP || event.keyCode == KeyEvent.DOM_VK_DOWN ||
(event.keyCode == KeyEvent.DOM_VK_F4 && !event.altKey && !event.ctrlKey && !event.shiftKey)) {
event.preventDefault();
this.open = true;
// open popup if key is up arrow, down arrow, or F4
if (!event.ctrlKey && !event.shiftKey) {
if (event.keyCode == KeyEvent.DOM_VK_UP ||
event.keyCode == KeyEvent.DOM_VK_DOWN ||
(event.keyCode == KeyEvent.DOM_VK_F4 && !event.altKey)) {
event.preventDefault();
this.open = true;
}
}
]]>
</handler>
@ -461,8 +441,8 @@
</binding>
<binding id="menulist-compact" display="xul:menu"
extends="chrome://global/content/bindings/menulist.xml#menulist">
<content>
extends="chrome://global/content/widgets/menulist.xml#menulist">
<content sizetopopup="false">
<xul:dropmarker class="menulist-dropmarker" type="menu"/>
<xul:image class="menulist-icon" xbl:inherits="src"/>
<xul:label class="menulist-label" xbl:inherits="value=label,crop,accesskey" crop="right" flex="1"/>