PageRenderTime 33ms CodeModel.GetById 21ms app.highlight 5ms RepoModel.GetById 1ms app.codeStats 0ms

/toolkit/content/widgets/text.xml

http://github.com/zpao/v8monkey
XML | 374 lines | 334 code | 39 blank | 1 comment | 0 complexity | 79dbab15dd10d5f233da9c74b3746f35 MD5 | raw file
  1<?xml version="1.0"?>
  2
  3<bindings id="textBindings"
  4   xmlns="http://www.mozilla.org/xbl"
  5   xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
  6   xmlns:html="http://www.w3.org/1999/xhtml">
  7
  8  <!-- bound to <description>s -->
  9  <binding id="text-base">
 10    <implementation implements="nsIDOMXULDescriptionElement, nsIAccessibleProvider">
 11      <property name="accessibleType" readonly="true">
 12        <getter>
 13          <![CDATA[
 14            return Components.interfaces.nsIAccessibleProvider.XULText;
 15          ]]>
 16        </getter>
 17      </property>
 18      <property name="disabled" onset="if (val) this.setAttribute('disabled', 'true');
 19                                       else this.removeAttribute('disabled');
 20                                       return val;"
 21                                onget="return this.getAttribute('disabled') == 'true';"/>
 22      <property name="value" onget="return this.getAttribute('value');"
 23                             onset="this.setAttribute('value', val); return val;"/>
 24      <property name="crop" onget="return this.getAttribute('crop');"
 25                            onset="this.setAttribute('crop', val); return val;"/>
 26    </implementation>
 27  </binding>
 28
 29  <binding id="text-label" extends="chrome://global/content/bindings/text.xml#text-base">
 30    <implementation implements="nsIDOMXULLabelElement">
 31      <property name="accessKey">
 32        <getter>
 33          <![CDATA[
 34            var accessKey = this.getAttribute('accesskey');
 35            return accessKey ? accessKey[0] : null;
 36          ]]>
 37        </getter>
 38        <setter>
 39          <![CDATA[
 40            this.setAttribute('accesskey', val);
 41            return val;
 42          ]]>
 43        </setter>
 44      </property>
 45
 46      <property name="control" onget="return getAttribute('control');">
 47        <setter>
 48          <![CDATA[
 49            // After this gets set, the label will use the binding #label-control
 50            this.setAttribute('control', val);
 51            return val;
 52          ]]>
 53        </setter>
 54      </property>
 55    </implementation>
 56  </binding>
 57
 58  <binding id="label-control" extends="chrome://global/content/bindings/text.xml#text-label">
 59    <content>
 60      <html:span anonid="accessKeyParens"><children/></html:span>
 61    </content>
 62    <implementation implements="nsIDOMXULLabelElement">
 63      <constructor>
 64        <![CDATA[
 65          try {
 66            var prefs = Components.classes["@mozilla.org/preferences-service;1"].
 67                                   getService(Components.interfaces.nsIPrefBranch);
 68            this.mUnderlineAccesskey = (prefs.getIntPref("ui.key.menuAccessKey") != 0);
 69
 70            const nsIPrefLocalizedString =
 71              Components.interfaces.nsIPrefLocalizedString;
 72
 73            const prefNameInsertSeparator =
 74              "intl.menuitems.insertseparatorbeforeaccesskeys";
 75            const prefNameAlwaysAppendAccessKey =
 76              "intl.menuitems.alwaysappendaccesskeys";
 77
 78            var val = prefs.getComplexValue(prefNameInsertSeparator,
 79                                            nsIPrefLocalizedString).data;
 80            this.mInsertSeparator = (val == "true");
 81
 82            val = prefs.getComplexValue(prefNameAlwaysAppendAccessKey,
 83                                        nsIPrefLocalizedString).data;
 84            this.mAlwaysAppendAccessKey = (val == "true");
 85          }
 86          catch (e) { }
 87          this.formatAccessKey();
 88        ]]>
 89      </constructor>
 90
 91      <method name="formatAccessKey">
 92        <body>
 93          <![CDATA[
 94            if (!this.mUnderlineAccesskey)
 95              return;
 96
 97            var control = this.labeledControlElement;
 98            if (!control) {
 99              var bindingParent = document.getBindingParent(this);
100              if (bindingParent instanceof Components.interfaces.nsIDOMXULLabeledControlElement) {
101                control = bindingParent; // For controls that make the <label> an anon child
102              }
103            }
104            if (control) {
105              control.labelElement = this;
106            }
107
108            var afterLabel = document.getAnonymousElementByAttribute(this, "anonid", "accessKeyParens");
109            afterLabel.textContent = ""; // This does not clear real nodes!
110
111            var oldAccessKey = this.getElementsByAttribute('class', 'accesskey').item(0);
112            if (oldAccessKey) { // Clear old accesskey
113              this.mergeElement(oldAccessKey);
114            }
115
116            var oldHiddenSpan =
117              this.getElementsByAttribute('class', 'hiddenColon').item(0);
118            if (oldHiddenSpan) {
119              this.mergeElement(oldHiddenSpan);
120            }
121
122            var accessKey = this.accessKey;
123            var labelText = this.textContent;
124            if (!accessKey || !labelText || !control) {
125              return;
126            }
127            var accessKeyIndex = -1;
128            if (!this.mAlwaysAppendAccessKey) {
129              accessKeyIndex = labelText.indexOf(accessKey);
130              if (accessKeyIndex < 0) { // Try again in upper case
131                accessKeyIndex =
132                  labelText.toUpperCase().indexOf(accessKey.toUpperCase());
133              }
134            }
135
136            const HTML_NS = "http://www.w3.org/1999/xhtml";
137            var span = document.createElementNS(HTML_NS, "span");
138            span.className = "accesskey";
139
140            // Note that if you change the following code, see the comment of
141            // nsTextBoxFrame::UpdateAccessTitle.
142
143            // If accesskey is not in string, append in parentheses
144            if (accessKeyIndex < 0) {
145              // If end is colon, we should insert before colon.
146              // i.e., "label:" -> "label(X):"
147              var colonHidden = false;
148              if (/:$/.test(labelText)) {
149                labelText = labelText.slice(0, -1);
150                var hiddenSpan = document.createElementNS(HTML_NS, "span");
151                hiddenSpan.className = "hiddenColon";
152                hiddenSpan.style.display = "none";
153                // Hide the last colon by using span element.
154                // I.e., label<span style="display:none;">:</span>
155                this.wrapChar(hiddenSpan, labelText.length);
156                colonHidden = true;
157              }
158              // If end is space(U+20),
159              // we should not add space before parentheses.
160              var endIsSpace = false;
161              if (/ $/.test(labelText)) {
162                endIsSpace = true;
163              }
164              if (this.mInsertSeparator && !endIsSpace)
165                afterLabel.textContent = " (";
166              else
167                afterLabel.textContent = "(";
168              span.textContent = accessKey.toUpperCase();
169              afterLabel.appendChild(span);
170              if (!colonHidden)
171                afterLabel.appendChild(document.createTextNode(")"));
172              else
173                afterLabel.appendChild(document.createTextNode("):"));
174              return;
175            }
176            this.wrapChar(span, accessKeyIndex);
177          ]]>
178        </body>
179      </method>
180
181      <method name="wrapChar">
182        <parameter name="element"/>
183        <parameter name="index"/>
184        <body>
185          <![CDATA[
186             var treeWalker = document.createTreeWalker(this,
187                                                        NodeFilter.SHOW_TEXT,
188                                                        null,
189                                                        true);
190             var node = treeWalker.nextNode();
191             while (index >= node.length) {
192               index -= node.length;
193               node = treeWalker.nextNode();
194             }
195             if (index) {
196               node = node.splitText(index);
197             }
198             node.parentNode.insertBefore(element, node);
199             if (node.length > 1) {
200               node.splitText(1);
201             }
202             element.appendChild(node);
203          ]]>
204        </body>
205      </method>
206
207      <method name="mergeElement">
208        <parameter name="element"/>
209        <body>
210          <![CDATA[
211            if (element.previousSibling instanceof Text) {
212              element.previousSibling.appendData(element.textContent)
213            }
214            else {
215              element.parentNode.insertBefore(element.firstChild, element);
216            }
217            element.parentNode.removeChild(element);
218          ]]>
219        </body>
220      </method>
221
222      <field name="mUnderlineAccesskey">
223        !/Mac/.test(navigator.platform)
224      </field>
225      <field name="mInsertSeparator">true</field>
226      <field name="mAlwaysAppendAccessKey">false</field>
227
228      <property name="accessKey">
229        <getter>
230          <![CDATA[
231            var accessKey = null;
232            var labeledEl = this.labeledControlElement;
233            if (labeledEl) {
234              accessKey = labeledEl.getAttribute('accesskey');
235            }
236            if (!accessKey) {
237              accessKey = this.getAttribute('accesskey');
238            }
239            return accessKey ? accessKey[0] : null;
240          ]]>
241        </getter>
242        <setter>
243          <![CDATA[
244            // If this label already has an accesskey attribute store it here as well
245            if (this.hasAttribute('accesskey')) {
246              this.setAttribute('accesskey', val);
247            }
248            var control = this.labeledControlElement;
249            if (control) {
250              control.setAttribute('accesskey', val);
251            }
252            this.formatAccessKey();
253            return val;
254          ]]>
255        </setter>
256      </property>
257
258      <property name="labeledControlElement" readonly="true"
259                onget="var control = this.control; return control ? document.getElementById(control) : null;" />
260
261      <property name="control" onget="return this.getAttribute('control');">
262        <setter>
263          <![CDATA[
264            var control = this.labeledControlElement;
265            if (control) {
266              control.labelElement = null; // No longer pointed to be this label
267            }
268            this.setAttribute('control', val);
269            this.formatAccessKey();
270            return val;
271          ]]>
272        </setter>
273      </property>
274
275    </implementation>
276
277    <handlers>
278      <handler event="click" action="if (this.disabled) return;
279                                     var controlElement = this.labeledControlElement;
280                                     if(controlElement)
281                                       controlElement.focus();
282                                    "/>
283    </handlers>
284  </binding>
285
286  <binding id="text-link" extends="chrome://global/content/bindings/text.xml#text-label">
287    <implementation implements="nsIAccessibleProvider">
288      <property name="accessibleType" readonly="true">
289        <getter>
290          <![CDATA[
291            return Components.interfaces.nsIAccessibleProvider.XULLink;
292          ]]>
293        </getter>
294      </property>
295      <property name="href" onget="return this.getAttribute('href');"
296                            onset="this.setAttribute('href', val); return val;" />
297      <method name="open">
298        <parameter name="aEvent"/>
299        <body>
300        <![CDATA[
301          var href = this.href;
302          if (!href || this.disabled || aEvent.defaultPrevented)
303            return;
304
305          var uri = null;
306          try {
307            const nsISSM = Components.interfaces.nsIScriptSecurityManager;
308            const secMan =
309                     Components.classes["@mozilla.org/scriptsecuritymanager;1"]
310                               .getService(nsISSM);
311
312            const ioService =
313                     Components.classes["@mozilla.org/network/io-service;1"]
314                               .getService(Components.interfaces.nsIIOService);
315
316            uri = ioService.newURI(href, null, null);
317
318            var nullPrincipal =
319              Components.classes["@mozilla.org/nullprincipal;1"]
320                        .createInstance(Components.interfaces.nsIPrincipal);
321            try {
322              secMan.checkLoadURIWithPrincipal(nullPrincipal, uri,
323                                               nsISSM.DISALLOW_INHERIT_PRINCIPAL)
324            }
325            catch (ex) {
326              var msg = "Error: Cannot open a " + uri.scheme + ": link using \
327                         the text-link binding.";
328              Components.utils.reportError(msg);
329              return;
330            }
331
332            const cID = "@mozilla.org/uriloader/external-protocol-service;1";
333            const nsIEPS = Components.interfaces.nsIExternalProtocolService;
334            var protocolSvc = Components.classes[cID].getService(nsIEPS);
335
336            // if the scheme is not an exposed protocol, then opening this link
337            // should be deferred to the system's external protocol handler
338            if (!protocolSvc.isExposedProtocol(uri.scheme)) {
339              protocolSvc.loadUrl(uri);
340              aEvent.preventDefault()
341              return;
342            }
343
344          }
345          catch (ex) {
346            Components.utils.reportError(ex);
347          }
348
349          // otherwise, fall back to opening the anchor directly
350          var win = window;
351          if (window instanceof Components.interfaces.nsIDOMChromeWindow) {
352            while (win.opener && !win.opener.closed)
353              win = win.opener;
354          }
355
356          if (uri)
357            win.open(uri.spec);
358          else
359            win.open(href);
360
361          aEvent.preventDefault();
362        ]]>
363        </body>
364      </method>
365    </implementation>
366
367    <handlers>
368      <handler event="click" phase="capturing" button="0" action="this.open(event)"/>
369      <handler event="keypress" preventdefault="true" keycode="VK_ENTER"  action="this.click()" />
370      <handler event="keypress" preventdefault="true" keycode="VK_RETURN" action="this.click()" />
371    </handlers>
372  </binding>
373
374</bindings>