Bug 340088, provide accessible label for xul, p=surkov, r=me+aaronr
This commit is contained in:
Родитель
0d05e6ef12
Коммит
56b9a7b5d9
|
@ -226,7 +226,7 @@
|
|||
|
||||
<!-- LABEL: <ACCESKEY SUPPORT> -->
|
||||
<binding id="xformswidget-label-accesskey"
|
||||
extends="chrome://xforms/content/xforms.xml#xformswidget-label-base">
|
||||
extends="chrome://xforms/content/xforms.xml#xformswidget-label-accesskey-base">
|
||||
<content>
|
||||
<html:span anonid="implicitcontent"
|
||||
xbl:inherits="tabindex"/>
|
||||
|
@ -256,8 +256,8 @@
|
|||
this._implicitContent.textContent = val;
|
||||
textnode = this._implicitContent.firstChild;
|
||||
} else {
|
||||
// XXX: if label has element node children, we skip accesskey
|
||||
// underlining.
|
||||
// XXX: How should we handle underlining if label contains
|
||||
// non-text nodes (see bug 370483)?
|
||||
var underline = true;
|
||||
for (var node = this._labelControl.firstChild; node; node = node.nextSibling) {
|
||||
if (node.nodeType == Node.ELEMENT_NODE) {
|
||||
|
@ -279,39 +279,8 @@
|
|||
}
|
||||
|
||||
var accesskey = this._labelControl.parentNode.getAttribute("accesskey");
|
||||
if (accesskey.length == 1 && textnode) {
|
||||
this.setAccesskeyOnNode(accesskey, textnode);
|
||||
}
|
||||
},
|
||||
|
||||
setAccesskeyOnNode: function(aAccesskey, aTextNode) {
|
||||
var text = aTextNode.nodeValue;
|
||||
var location = text.indexOf(aAccesskey);
|
||||
|
||||
if (location > -1) {
|
||||
// we create a range around the character we want and surround
|
||||
// it with an <html:u>
|
||||
var range = this._ownerDocument.createRange();
|
||||
range.setStart(aTextNode, location);
|
||||
range.setEnd(aTextNode, location + 1);
|
||||
|
||||
var span = this._ownerDocument.
|
||||
createElementNS("http://www.w3.org/1999/xhtml", "span");
|
||||
span.setAttribute("class", "xf-accesskey-inline");
|
||||
range.surroundContents(span);
|
||||
} else {
|
||||
// if we didn't find the accesskey, append it to the end
|
||||
var span = this._ownerDocument.
|
||||
createElementNS("http://www.w3.org/1999/xhtml", "span");
|
||||
span.setAttribute("class", "xf-accesskey-appended");
|
||||
span.textContent = aAccesskey;
|
||||
if (aTextNode.nextSibling) {
|
||||
aTextNode.parentNode.insertBefore(span,
|
||||
aTextNode.nextSibling);
|
||||
} else {
|
||||
aTextNode.parentNode.appendChild(span);
|
||||
}
|
||||
}
|
||||
if (accesskey.length == 1 && textnode)
|
||||
this._labelControl.formatWithAccesskey(accesskey, textnode);
|
||||
}
|
||||
};
|
||||
]]>
|
||||
|
|
|
@ -224,6 +224,74 @@
|
|||
</binding>
|
||||
|
||||
|
||||
<!-- LABEL: <ACCESKEY SUPPORT> -->
|
||||
<binding id="xformswidget-label-accesskey"
|
||||
extends="chrome://xforms/content/xforms.xml#xformswidget-label-accesskey-base">
|
||||
<resources>
|
||||
<stylesheet src="chrome://xforms/skin/xforms-xul.css"/>
|
||||
</resources>
|
||||
|
||||
<content>
|
||||
<xul:label anonid="implicitcontent"
|
||||
xbl:inherits="tabindex"/>
|
||||
<xul:label anonid="explicitcontent"
|
||||
xbl:inherits="tabindex"><children/></xul:label>
|
||||
</content>
|
||||
|
||||
<implementation>
|
||||
<method name="getControlElement">
|
||||
<body>
|
||||
<![CDATA[
|
||||
return {
|
||||
_labelControl: this,
|
||||
_implicitContent: this.ownerDocument.
|
||||
getAnonymousElementByAttribute(this, 'anonid', 'implicitcontent'),
|
||||
_explicitContent: this.ownerDocument.
|
||||
getAnonymousElementByAttribute(this, 'anonid', 'explicitcontent'),
|
||||
|
||||
set value(val) {
|
||||
var textnode = null;
|
||||
|
||||
if (val != null) {
|
||||
this._explicitContent.hidden = true;
|
||||
this._implicitContent.hidden = false;
|
||||
this._implicitContent.textContent = val;
|
||||
textnode = this._implicitContent.firstChild;
|
||||
} else {
|
||||
// XXX: How should we handle underlining if label contains
|
||||
// non-text nodes (see bug 370483)?
|
||||
var underline = true;
|
||||
for (var node = this._labelControl.firstChild; node; node = node.nextSibling) {
|
||||
if (node.nodeType == Node.ELEMENT_NODE) {
|
||||
underline = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!underline) {
|
||||
this._explicitContent.hidden = false;
|
||||
this._implicitContent.hidden = true;
|
||||
this._implicitContent.textContent = '';
|
||||
return;
|
||||
}
|
||||
|
||||
this._explicitContent.hidden = true;
|
||||
this._implicitContent.hidden = false;
|
||||
this._implicitContent.textContent = this._labelControl.textContent;
|
||||
textnode = this._implicitContent.firstChild;
|
||||
}
|
||||
|
||||
var accesskey = this._labelControl.parentNode.getAttribute("accesskey");
|
||||
if (accesskey.length == 1 && textnode)
|
||||
this._labelControl.formatWithAccesskey(accesskey, textnode);
|
||||
}
|
||||
};
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
</implementation>
|
||||
</binding>
|
||||
|
||||
|
||||
<!-- TRIGGER: base widget for triggers -->
|
||||
<binding id="xformswidget-trigger-base"
|
||||
extends="chrome://xforms/content/xforms.xml#xformswidget-trigger-base">
|
||||
|
|
|
@ -444,14 +444,27 @@ html|*:root range[accesskey] > label {
|
|||
-moz-binding: url('chrome://xforms/content/xforms-xhtml.xml#xformswidget-label-accesskey');
|
||||
}
|
||||
|
||||
html|*:root html|span.xf-accesskey-inline {
|
||||
/* label widgets */
|
||||
xul|*:root input[accesskey] > label,
|
||||
xul|*:root secret[accesskey] > label,
|
||||
xul|*:root textarea[accesskey] > label,
|
||||
xul|*:root trigger[accesskey] > label,
|
||||
xul|*:root submit[accesskey] > label,
|
||||
xul|*:root select[accesskey] > label,
|
||||
xul|*:root select1[accesskey] > label,
|
||||
xul|*:root upload[accesskey] > label,
|
||||
xul|*:root range[accesskey] > label {
|
||||
-moz-binding: url('chrome://xforms/content/xforms-xul.xml#xformswidget-label-accesskey');
|
||||
}
|
||||
|
||||
html|span.xf-accesskey-inline {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
html|*:root html|span.xf-accesskey-appended:before {
|
||||
html|span.xf-accesskey-appended:before {
|
||||
content: "(";
|
||||
}
|
||||
html|*:root html|span.xf-accesskey-appended:after {
|
||||
html|span.xf-accesskey-appended:after {
|
||||
content: ")";
|
||||
}
|
||||
|
||||
|
|
|
@ -83,6 +83,9 @@
|
|||
</getter>
|
||||
</property>
|
||||
|
||||
<property name="XHTML_NS" readonly="true"
|
||||
onget="return 'http://www.w3.org/1999/xhtml';"/>
|
||||
|
||||
<!-- Dispatch UI Event to the control itself -->
|
||||
<method name="dispatchDOMUIEvent">
|
||||
<parameter name="aType"/>
|
||||
|
@ -382,6 +385,51 @@
|
|||
</binding>
|
||||
|
||||
|
||||
<!-- LABEL: <ACCESKEY SUPPORT>
|
||||
The label widget assumes successors bindings implement getElementControl()
|
||||
method what returns the object:
|
||||
{
|
||||
set value(); // set "string" value
|
||||
}
|
||||
-->
|
||||
<binding id="xformswidget-label-accesskey-base"
|
||||
extends="#xformswidget-label-base">
|
||||
|
||||
<implementation>
|
||||
<method name="formatWithAccesskey">
|
||||
<parameter name="aAccesskey"/>
|
||||
<parameter name="aTextNode"/>
|
||||
<body>
|
||||
var text = aTextNode.nodeValue;
|
||||
var location = text.indexOf(aAccesskey);
|
||||
var span = this.ownerDocument.createElementNS(this.XHTML_NS, "span");
|
||||
|
||||
if (location > -1) {
|
||||
// We create a range around the character we want and surround
|
||||
// it with an html:span.
|
||||
var range = this.ownerDocument.createRange();
|
||||
range.setStart(aTextNode, location);
|
||||
range.setEnd(aTextNode, location + 1);
|
||||
|
||||
span.setAttribute("class", "xf-accesskey-inline");
|
||||
range.surroundContents(span);
|
||||
} else {
|
||||
// If we didn't find the accesskey, append it to the end.
|
||||
span.setAttribute("class", "xf-accesskey-appended");
|
||||
span.textContent = aAccesskey;
|
||||
if (aTextNode.nextSibling) {
|
||||
aTextNode.parentNode.insertBefore(span,
|
||||
aTextNode.nextSibling);
|
||||
} else {
|
||||
aTextNode.parentNode.appendChild(span);
|
||||
}
|
||||
}
|
||||
</body>
|
||||
</method>
|
||||
</implementation>
|
||||
</binding>
|
||||
|
||||
|
||||
<!-- TRIGGER: <DEFAULT>
|
||||
The trigger widget assumes successors bindings implement getElementControl()
|
||||
method what returns the object:
|
||||
|
|
Загрузка…
Ссылка в новой задаче