toolkit/content/widgets/text.xml

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial