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.

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

mercurial