1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/content/widgets/textbox.xml Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,636 @@ 1.4 +<?xml version="1.0"?> 1.5 +<!-- This Source Code Form is subject to the terms of the Mozilla Public 1.6 + - License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> 1.8 + 1.9 + 1.10 +<!DOCTYPE bindings [ 1.11 + <!ENTITY % textcontextDTD SYSTEM "chrome://global/locale/textcontext.dtd" > 1.12 + %textcontextDTD; 1.13 +]> 1.14 + 1.15 +<bindings id="textboxBindings" 1.16 + xmlns="http://www.mozilla.org/xbl" 1.17 + xmlns:html="http://www.w3.org/1999/xhtml" 1.18 + xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" 1.19 + xmlns:xbl="http://www.mozilla.org/xbl"> 1.20 + 1.21 + <binding id="textbox" extends="xul:box" role="xul:textbox"> 1.22 + <resources> 1.23 + <stylesheet src="chrome://global/content/textbox.css"/> 1.24 + <stylesheet src="chrome://global/skin/textbox.css"/> 1.25 + </resources> 1.26 + 1.27 + <content> 1.28 + <children/> 1.29 + <xul:hbox class="textbox-input-box" flex="1" xbl:inherits="context,spellcheck"> 1.30 + <html:input class="textbox-input" anonid="input" 1.31 + xbl:inherits="value,type,maxlength,disabled,size,readonly,placeholder,tabindex,accesskey,noinitialfocus,mozactionhint,spellcheck"/> 1.32 + </xul:hbox> 1.33 + </content> 1.34 + 1.35 + <implementation implements="nsIDOMXULTextBoxElement, nsIDOMXULLabeledControlElement"> 1.36 + <!-- nsIDOMXULLabeledControlElement --> 1.37 + <field name="crop">""</field> 1.38 + <field name="image">""</field> 1.39 + <field name="command">""</field> 1.40 + <field name="accessKey">""</field> 1.41 + 1.42 + <field name="mInputField">null</field> 1.43 + <field name="mIgnoreClick">false</field> 1.44 + <field name="mIgnoreFocus">false</field> 1.45 + <field name="mEditor">null</field> 1.46 + 1.47 + <property name="inputField" readonly="true"> 1.48 + <getter><![CDATA[ 1.49 + if (!this.mInputField) 1.50 + this.mInputField = document.getAnonymousElementByAttribute(this, "anonid", "input"); 1.51 + return this.mInputField; 1.52 + ]]></getter> 1.53 + </property> 1.54 + 1.55 + <property name="value" onset="this.inputField.value = val; return val;" 1.56 + onget="return this.inputField.value;"/> 1.57 + <property name="defaultValue" onset="this.inputField.defaultValue = val; return val;" 1.58 + onget="return this.inputField.defaultValue;"/> 1.59 + <property name="label" onset="this.setAttribute('label', val); return val;" 1.60 + onget="return this.getAttribute('label') || 1.61 + (this.labelElement ? this.labelElement.value : 1.62 + this.placeholder);"/> 1.63 + <property name="placeholder" onset="this.inputField.placeholder = val; return val;" 1.64 + onget="return this.inputField.placeholder;"/> 1.65 + <property name="emptyText" onset="this.placeholder = val; return val;" 1.66 + onget="return this.placeholder;"/> 1.67 + <property name="type" onset="if (val) this.setAttribute('type', val); 1.68 + else this.removeAttribute('type'); return val;" 1.69 + onget="return this.getAttribute('type');"/> 1.70 + <property name="maxLength" onset="this.inputField.maxLength = val; return val;" 1.71 + onget="return this.inputField.maxLength;"/> 1.72 + <property name="disabled" onset="this.inputField.disabled = val; 1.73 + if (val) this.setAttribute('disabled', 'true'); 1.74 + else this.removeAttribute('disabled'); return val;" 1.75 + onget="return this.inputField.disabled;"/> 1.76 + <property name="tabIndex" onget="return parseInt(this.getAttribute('tabindex'));" 1.77 + onset="this.inputField.tabIndex = val; 1.78 + if (val) this.setAttribute('tabindex', val); 1.79 + else this.removeAttribute('tabindex'); return val;"/> 1.80 + <property name="size" onset="this.inputField.size = val; return val;" 1.81 + onget="return this.inputField.size;"/> 1.82 + <property name="readOnly" onset="this.inputField.readOnly = val; 1.83 + if (val) this.setAttribute('readonly', 'true'); 1.84 + else this.removeAttribute('readonly'); return val;" 1.85 + onget="return this.inputField.readOnly;"/> 1.86 + <property name="clickSelectsAll" 1.87 + onget="return this.getAttribute('clickSelectsAll') == 'true';" 1.88 + onset="if (val) this.setAttribute('clickSelectsAll', 'true'); 1.89 + else this.removeAttribute('clickSelectsAll'); return val;" /> 1.90 + 1.91 + <property name="editor" readonly="true"> 1.92 + <getter><![CDATA[ 1.93 + if (!this.mEditor) { 1.94 + const nsIDOMNSEditableElement = Components.interfaces.nsIDOMNSEditableElement; 1.95 + this.mEditor = this.inputField.QueryInterface(nsIDOMNSEditableElement).editor; 1.96 + } 1.97 + return this.mEditor; 1.98 + ]]></getter> 1.99 + </property> 1.100 + 1.101 + <method name="reset"> 1.102 + <body><![CDATA[ 1.103 + this.value = this.defaultValue; 1.104 + try { 1.105 + this.editor.transactionManager.clear(); 1.106 + return true; 1.107 + } 1.108 + catch(e) {} 1.109 + return false; 1.110 + ]]></body> 1.111 + </method> 1.112 + 1.113 + <method name="select"> 1.114 + <body> 1.115 + this.inputField.select(); 1.116 + </body> 1.117 + </method> 1.118 + 1.119 + <property name="controllers" readonly="true" onget="return this.inputField.controllers"/> 1.120 + <property name="textLength" readonly="true" 1.121 + onget="return this.inputField.textLength;"/> 1.122 + <property name="selectionStart" onset="this.inputField.selectionStart = val; return val;" 1.123 + onget="return this.inputField.selectionStart;"/> 1.124 + <property name="selectionEnd" onset="this.inputField.selectionEnd = val; return val;" 1.125 + onget="return this.inputField.selectionEnd;"/> 1.126 + 1.127 + <method name="setSelectionRange"> 1.128 + <parameter name="aSelectionStart"/> 1.129 + <parameter name="aSelectionEnd"/> 1.130 + <body> 1.131 + this.inputField.setSelectionRange( aSelectionStart, aSelectionEnd ); 1.132 + </body> 1.133 + </method> 1.134 + 1.135 + <method name="_setNewlineHandling"> 1.136 + <body><![CDATA[ 1.137 + var str = this.getAttribute("newlines"); 1.138 + if (str && this.editor) { 1.139 + const nsIPlaintextEditor = Components.interfaces.nsIPlaintextEditor; 1.140 + for (var x in nsIPlaintextEditor) { 1.141 + if (/^eNewlines/.test(x)) { 1.142 + if (str == RegExp.rightContext.toLowerCase()) { 1.143 + this.editor.QueryInterface(nsIPlaintextEditor) 1.144 + .newlineHandling = nsIPlaintextEditor[x]; 1.145 + break; 1.146 + } 1.147 + } 1.148 + } 1.149 + } 1.150 + ]]></body> 1.151 + </method> 1.152 + 1.153 + <method name="_maybeSelectAll"> 1.154 + <body><![CDATA[ 1.155 + if (!this.mIgnoreClick && this.clickSelectsAll && 1.156 + document.activeElement == this.inputField && 1.157 + this.inputField.selectionStart == this.inputField.selectionEnd) 1.158 + this.editor.selectAll(); 1.159 + ]]></body> 1.160 + </method> 1.161 + 1.162 + <constructor><![CDATA[ 1.163 + var str = this.boxObject.getProperty("value"); 1.164 + if (str) { 1.165 + this.inputField.value = str; 1.166 + this.boxObject.removeProperty("value"); 1.167 + } 1.168 + 1.169 + this._setNewlineHandling(); 1.170 + 1.171 + if (this.hasAttribute("emptytext")) 1.172 + this.placeholder = this.getAttribute("emptytext"); 1.173 + ]]></constructor> 1.174 + 1.175 + <destructor> 1.176 + <![CDATA[ 1.177 + if (this.inputField.value) 1.178 + this.boxObject.setProperty('value', this.inputField.value); 1.179 + this.mInputField = null; 1.180 + ]]> 1.181 + </destructor> 1.182 + 1.183 + </implementation> 1.184 + 1.185 + <handlers> 1.186 + <handler event="focus" phase="capturing"> 1.187 + <![CDATA[ 1.188 + if (this.hasAttribute("focused")) 1.189 + return; 1.190 + 1.191 + switch (event.originalTarget) { 1.192 + case this: 1.193 + // Forward focus to actual HTML input 1.194 + this.inputField.focus(); 1.195 + break; 1.196 + case this.inputField: 1.197 + if (this.mIgnoreFocus) { 1.198 + this.mIgnoreFocus = false; 1.199 + } else if (this.clickSelectsAll) { 1.200 + try { 1.201 + const nsIEditorIMESupport = 1.202 + Components.interfaces.nsIEditorIMESupport; 1.203 + let imeEditor = this.editor.QueryInterface(nsIEditorIMESupport); 1.204 + if (!imeEditor || !imeEditor.composing) 1.205 + this.editor.selectAll(); 1.206 + } catch (e) {} 1.207 + } 1.208 + break; 1.209 + default: 1.210 + // Allow other children (e.g. URL bar buttons) to get focus 1.211 + return; 1.212 + } 1.213 + this.setAttribute("focused", "true"); 1.214 + ]]> 1.215 + </handler> 1.216 + 1.217 + <handler event="blur" phase="capturing"> 1.218 + <![CDATA[ 1.219 + this.removeAttribute("focused"); 1.220 + 1.221 + // don't trigger clickSelectsAll when switching application windows 1.222 + if (window == window.top && 1.223 + window.constructor == ChromeWindow && 1.224 + document.activeElement == this.inputField) 1.225 + this.mIgnoreFocus = true; 1.226 + ]]> 1.227 + </handler> 1.228 + 1.229 + <handler event="mousedown"> 1.230 + <![CDATA[ 1.231 + this.mIgnoreClick = this.hasAttribute("focused"); 1.232 + 1.233 + if (!this.mIgnoreClick) { 1.234 + this.mIgnoreFocus = true; 1.235 + this.inputField.setSelectionRange(0, 0); 1.236 + if (event.originalTarget == this || 1.237 + event.originalTarget == this.inputField.parentNode) 1.238 + this.inputField.focus(); 1.239 + } 1.240 + ]]> 1.241 + </handler> 1.242 + 1.243 + <handler event="click" action="this._maybeSelectAll();"/> 1.244 + 1.245 +#ifndef XP_WIN 1.246 + <handler event="contextmenu"> 1.247 + if (!event.button) // context menu opened via keyboard shortcut 1.248 + return; 1.249 + this._maybeSelectAll(); 1.250 + // see bug 576135 comment 4 1.251 + let box = this.inputField.parentNode; 1.252 + let menu = document.getAnonymousElementByAttribute(box, "anonid", "input-box-contextmenu"); 1.253 + box._doPopupItemEnabling(menu); 1.254 + </handler> 1.255 +#endif 1.256 + </handlers> 1.257 + </binding> 1.258 + 1.259 + <binding id="timed-textbox" extends="chrome://global/content/bindings/textbox.xml#textbox"> 1.260 + <implementation> 1.261 + <constructor><![CDATA[ 1.262 + try { 1.263 + var consoleService = Components.classes["@mozilla.org/consoleservice;1"] 1.264 + .getService(Components.interfaces.nsIConsoleService); 1.265 + var scriptError = Components.classes["@mozilla.org/scripterror;1"] 1.266 + .createInstance(Components.interfaces.nsIScriptError); 1.267 + scriptError.init("Timed textboxes are deprecated. Consider using type=\"search\" instead.", 1.268 + this.ownerDocument.location.href, null, null, 1.269 + null, scriptError.warningFlag, "XUL Widgets"); 1.270 + consoleService.logMessage(scriptError); 1.271 + } catch (e) {} 1.272 + ]]></constructor> 1.273 + <field name="_timer">null</field> 1.274 + <property name="timeout" 1.275 + onset="this.setAttribute('timeout', val); return val;" 1.276 + onget="return parseInt(this.getAttribute('timeout')) || 0;"/> 1.277 + <property name="value" 1.278 + onget="return this.inputField.value;"> 1.279 + <setter><![CDATA[ 1.280 + this.inputField.value = val; 1.281 + if (this._timer) 1.282 + clearTimeout(this._timer); 1.283 + return val; 1.284 + ]]></setter> 1.285 + </property> 1.286 + <method name="_fireCommand"> 1.287 + <parameter name="me"/> 1.288 + <body> 1.289 + <![CDATA[ 1.290 + me._timer = null; 1.291 + me.doCommand(); 1.292 + ]]> 1.293 + </body> 1.294 + </method> 1.295 + </implementation> 1.296 + <handlers> 1.297 + <handler event="input"> 1.298 + <![CDATA[ 1.299 + if (this._timer) 1.300 + clearTimeout(this._timer); 1.301 + this._timer = this.timeout && setTimeout(this._fireCommand, this.timeout, this); 1.302 + ]]> 1.303 + </handler> 1.304 + <handler event="keypress" keycode="VK_RETURN"> 1.305 + <![CDATA[ 1.306 + if (this._timer) 1.307 + clearTimeout(this._timer); 1.308 + this._fireCommand(this); 1.309 + event.preventDefault(); 1.310 + ]]> 1.311 + </handler> 1.312 + </handlers> 1.313 + </binding> 1.314 + 1.315 + <binding id="search-textbox" extends="chrome://global/content/bindings/textbox.xml#textbox"> 1.316 + <content> 1.317 + <children/> 1.318 + <xul:hbox class="textbox-input-box" flex="1" xbl:inherits="context,spellcheck" align="center"> 1.319 + <html:input class="textbox-input" anonid="input" mozactionhint="search" 1.320 + xbl:inherits="value,type,maxlength,disabled,size,readonly,placeholder,tabindex,accesskey,mozactionhint,spellcheck"/> 1.321 + <xul:deck class="textbox-search-icons" anonid="search-icons"> 1.322 + <xul:image class="textbox-search-icon" 1.323 + onclick="document.getBindingParent(this)._iconClick();" 1.324 + xbl:inherits="src=image,searchbutton,disabled"/> 1.325 + <xul:image class="textbox-search-clear" 1.326 + onclick="document.getBindingParent(this)._clearSearch();" 1.327 + xbl:inherits="disabled"/> 1.328 + </xul:deck> 1.329 + </xul:hbox> 1.330 + </content> 1.331 + <implementation> 1.332 + <field name="_timer">null</field> 1.333 + <field name="_searchIcons"> 1.334 + document.getAnonymousElementByAttribute(this, "anonid", "search-icons"); 1.335 + </field> 1.336 + <property name="timeout" 1.337 + onset="this.setAttribute('timeout', val); return val;" 1.338 + onget="return parseInt(this.getAttribute('timeout')) || 500;"/> 1.339 + <property name="searchButton" 1.340 + onget="return this.getAttribute('searchbutton') == 'true';"> 1.341 + <setter><![CDATA[ 1.342 + if (val) { 1.343 + this.setAttribute("searchbutton", "true"); 1.344 + this.removeAttribute("aria-autocomplete"); 1.345 + } else { 1.346 + this.removeAttribute("searchbutton"); 1.347 + this.setAttribute("aria-autocomplete", "list"); 1.348 + } 1.349 + return val; 1.350 + ]]></setter> 1.351 + </property> 1.352 + <property name="value" 1.353 + onget="return this.inputField.value;"> 1.354 + <setter><![CDATA[ 1.355 + this.inputField.value = val; 1.356 + 1.357 + if (val) 1.358 + this._searchIcons.selectedIndex = this.searchButton ? 0 : 1; 1.359 + else 1.360 + this._searchIcons.selectedIndex = 0; 1.361 + 1.362 + if (this._timer) 1.363 + clearTimeout(this._timer); 1.364 + 1.365 + return val; 1.366 + ]]></setter> 1.367 + </property> 1.368 + <constructor><![CDATA[ 1.369 + if (this.searchButton) 1.370 + this.removeAttribute("aria-autocomplete"); 1.371 + else 1.372 + this.setAttribute("aria-autocomplete", "list"); 1.373 + ]]></constructor> 1.374 + <method name="_fireCommand"> 1.375 + <parameter name="me"/> 1.376 + <body><![CDATA[ 1.377 + if (me._timer) 1.378 + clearTimeout(me._timer); 1.379 + me._timer = null; 1.380 + me.doCommand(); 1.381 + ]]></body> 1.382 + </method> 1.383 + <method name="_iconClick"> 1.384 + <body><![CDATA[ 1.385 + if (this.searchButton) 1.386 + this._enterSearch(); 1.387 + else 1.388 + this.focus(); 1.389 + ]]></body> 1.390 + </method> 1.391 + <method name="_enterSearch"> 1.392 + <body><![CDATA[ 1.393 + if (this.disabled) 1.394 + return; 1.395 + if (this.searchButton && this.value && !this.readOnly) 1.396 + this._searchIcons.selectedIndex = 1; 1.397 + this._fireCommand(this); 1.398 + ]]></body> 1.399 + </method> 1.400 + <method name="_clearSearch"> 1.401 + <body><![CDATA[ 1.402 + if (!this.disabled && !this.readOnly && this.value) { 1.403 + this.value = ""; 1.404 + this._fireCommand(this); 1.405 + this._searchIcons.selectedIndex = 0; 1.406 + return true; 1.407 + } 1.408 + return false; 1.409 + ]]></body> 1.410 + </method> 1.411 + </implementation> 1.412 + <handlers> 1.413 + <handler event="input"> 1.414 + <![CDATA[ 1.415 + if (this.searchButton) { 1.416 + this._searchIcons.selectedIndex = 0; 1.417 + return; 1.418 + } 1.419 + if (this._timer) 1.420 + clearTimeout(this._timer); 1.421 + this._timer = this.timeout && setTimeout(this._fireCommand, this.timeout, this); 1.422 + this._searchIcons.selectedIndex = this.value ? 1 : 0; 1.423 + ]]> 1.424 + </handler> 1.425 + <handler event="keypress" keycode="VK_ESCAPE"> 1.426 + <![CDATA[ 1.427 + if (this._clearSearch()) { 1.428 + event.preventDefault(); 1.429 + event.stopPropagation(); 1.430 + } 1.431 + ]]> 1.432 + </handler> 1.433 + <handler event="keypress" keycode="VK_RETURN"> 1.434 + <![CDATA[ 1.435 + this._enterSearch(); 1.436 + event.preventDefault(); 1.437 + event.stopPropagation(); 1.438 + ]]> 1.439 + </handler> 1.440 + </handlers> 1.441 + </binding> 1.442 + 1.443 + <binding id="textarea" extends="chrome://global/content/bindings/textbox.xml#textbox"> 1.444 + <content> 1.445 + <xul:hbox class="textbox-input-box" flex="1" xbl:inherits="context,spellcheck"> 1.446 + <html:textarea class="textbox-textarea" anonid="input" 1.447 + xbl:inherits="xbl:text=value,disabled,tabindex,rows,cols,readonly,wrap,placeholder,mozactionhint,spellcheck"><children/></html:textarea> 1.448 + </xul:hbox> 1.449 + </content> 1.450 + </binding> 1.451 + 1.452 + <binding id="input-box"> 1.453 + <content context="_child"> 1.454 + <children/> 1.455 + <xul:menupopup anonid="input-box-contextmenu" 1.456 + class="textbox-contextmenu" 1.457 + onpopupshowing="var input = 1.458 + this.parentNode.getElementsByAttribute('anonid', 'input')[0]; 1.459 + if (document.commandDispatcher.focusedElement != input) 1.460 + input.focus(); 1.461 + this.parentNode._doPopupItemEnabling(this);" 1.462 + oncommand="var cmd = event.originalTarget.getAttribute('cmd'); if(cmd) { this.parentNode.doCommand(cmd); event.stopPropagation(); }"> 1.463 + <xul:menuitem label="&undoCmd.label;" accesskey="&undoCmd.accesskey;" cmd="cmd_undo"/> 1.464 + <xul:menuseparator/> 1.465 + <xul:menuitem label="&cutCmd.label;" accesskey="&cutCmd.accesskey;" cmd="cmd_cut"/> 1.466 + <xul:menuitem label="©Cmd.label;" accesskey="©Cmd.accesskey;" cmd="cmd_copy"/> 1.467 + <xul:menuitem label="&pasteCmd.label;" accesskey="&pasteCmd.accesskey;" cmd="cmd_paste"/> 1.468 + <xul:menuitem label="&deleteCmd.label;" accesskey="&deleteCmd.accesskey;" cmd="cmd_delete"/> 1.469 + <xul:menuseparator/> 1.470 + <xul:menuitem label="&selectAllCmd.label;" accesskey="&selectAllCmd.accesskey;" cmd="cmd_selectAll"/> 1.471 + </xul:menupopup> 1.472 + </content> 1.473 + 1.474 + <implementation> 1.475 + <method name="_doPopupItemEnabling"> 1.476 + <parameter name="popupNode"/> 1.477 + <body> 1.478 + <![CDATA[ 1.479 + var children = popupNode.childNodes; 1.480 + for (var i = 0; i < children.length; i++) { 1.481 + var command = children[i].getAttribute("cmd"); 1.482 + if (command) { 1.483 + var controller = document.commandDispatcher.getControllerForCommand(command); 1.484 + var enabled = controller.isCommandEnabled(command); 1.485 + if (enabled) 1.486 + children[i].removeAttribute("disabled"); 1.487 + else 1.488 + children[i].setAttribute("disabled", "true"); 1.489 + } 1.490 + } 1.491 + ]]> 1.492 + </body> 1.493 + </method> 1.494 + 1.495 + <method name="_setMenuItemVisibility"> 1.496 + <parameter name="anonid"/> 1.497 + <parameter name="visible"/> 1.498 + <body><![CDATA[ 1.499 + document.getAnonymousElementByAttribute(this, "anonid", anonid). 1.500 + hidden = ! visible; 1.501 + ]]></body> 1.502 + </method> 1.503 + 1.504 + <method name="doCommand"> 1.505 + <parameter name="command"/> 1.506 + <body> 1.507 + <![CDATA[ 1.508 + var controller = document.commandDispatcher.getControllerForCommand(command); 1.509 + controller.doCommand(command); 1.510 + ]]> 1.511 + </body> 1.512 + </method> 1.513 + </implementation> 1.514 + </binding> 1.515 + 1.516 + <binding id="input-box-spell" extends="chrome://global/content/bindings/textbox.xml#input-box"> 1.517 + <content context="_child"> 1.518 + <children/> 1.519 + <xul:menupopup anonid="input-box-contextmenu" 1.520 + class="textbox-contextmenu" 1.521 + onpopupshowing="var input = 1.522 + this.parentNode.getElementsByAttribute('anonid', 'input')[0]; 1.523 + if (document.commandDispatcher.focusedElement != input) 1.524 + input.focus(); 1.525 + this.parentNode._doPopupItemEnablingSpell(this);" 1.526 + onpopuphiding="this.parentNode._doPopupItemDisabling(this);" 1.527 + oncommand="var cmd = event.originalTarget.getAttribute('cmd'); if(cmd) { this.parentNode.doCommand(cmd); event.stopPropagation(); }"> 1.528 + <xul:menuitem label="&spellNoSuggestions.label;" anonid="spell-no-suggestions" disabled="true"/> 1.529 + <xul:menuitem label="&spellAddToDictionary.label;" accesskey="&spellAddToDictionary.accesskey;" anonid="spell-add-to-dictionary" 1.530 + oncommand="this.parentNode.parentNode.spellCheckerUI.addToDictionary();"/> 1.531 + <xul:menuitem label="&spellUndoAddToDictionary.label;" accesskey="&spellUndoAddToDictionary.accesskey;" anonid="spell-undo-add-to-dictionary" 1.532 + oncommand="this.parentNode.parentNode.spellCheckerUI.undoAddToDictionary();"/> 1.533 + <xul:menuseparator anonid="spell-suggestions-separator"/> 1.534 + <xul:menuitem label="&undoCmd.label;" accesskey="&undoCmd.accesskey;" cmd="cmd_undo"/> 1.535 + <xul:menuseparator/> 1.536 + <xul:menuitem label="&cutCmd.label;" accesskey="&cutCmd.accesskey;" cmd="cmd_cut"/> 1.537 + <xul:menuitem label="©Cmd.label;" accesskey="©Cmd.accesskey;" cmd="cmd_copy"/> 1.538 + <xul:menuitem label="&pasteCmd.label;" accesskey="&pasteCmd.accesskey;" cmd="cmd_paste"/> 1.539 + <xul:menuitem label="&deleteCmd.label;" accesskey="&deleteCmd.accesskey;" cmd="cmd_delete"/> 1.540 + <xul:menuseparator/> 1.541 + <xul:menuitem label="&selectAllCmd.label;" accesskey="&selectAllCmd.accesskey;" cmd="cmd_selectAll"/> 1.542 + <xul:menuseparator anonid="spell-check-separator"/> 1.543 + <xul:menuitem label="&spellCheckToggle.label;" type="checkbox" accesskey="&spellCheckToggle.accesskey;" anonid="spell-check-enabled" 1.544 + oncommand="this.parentNode.parentNode.spellCheckerUI.toggleEnabled();"/> 1.545 + <xul:menu label="&spellDictionaries.label;" accesskey="&spellDictionaries.accesskey;" anonid="spell-dictionaries"> 1.546 + <xul:menupopup anonid="spell-dictionaries-menu" 1.547 + onpopupshowing="event.stopPropagation();" 1.548 + onpopuphiding="event.stopPropagation();"/> 1.549 + </xul:menu> 1.550 + </xul:menupopup> 1.551 + </content> 1.552 + 1.553 + <implementation> 1.554 + <field name="_spellCheckInitialized">false</field> 1.555 + <field name="_enabledCheckbox"> 1.556 + document.getAnonymousElementByAttribute(this, "anonid", "spell-check-enabled"); 1.557 + </field> 1.558 + <field name="_suggestionsSeparator"> 1.559 + document.getAnonymousElementByAttribute(this, "anonid", "spell-no-suggestions"); 1.560 + </field> 1.561 + <field name="_dictionariesMenu"> 1.562 + document.getAnonymousElementByAttribute(this, "anonid", "spell-dictionaries-menu"); 1.563 + </field> 1.564 + 1.565 + <property name="spellCheckerUI" readonly="true"> 1.566 + <getter><![CDATA[ 1.567 + if (!this._spellCheckInitialized) { 1.568 + this._spellCheckInitialized = true; 1.569 + 1.570 + const CI = Components.interfaces; 1.571 + if (!(document instanceof CI.nsIDOMXULDocument)) 1.572 + return null; 1.573 + 1.574 + var textbox = document.getBindingParent(this); 1.575 + if (!textbox || !(textbox instanceof CI.nsIDOMXULTextBoxElement)) 1.576 + return null; 1.577 + 1.578 + try { 1.579 + Components.utils.import("resource://gre/modules/InlineSpellChecker.jsm", this); 1.580 + this.InlineSpellCheckerUI = new this.InlineSpellChecker(textbox.editor); 1.581 + } catch(ex) { } 1.582 + } 1.583 + 1.584 + return this.InlineSpellCheckerUI; 1.585 + ]]></getter> 1.586 + </property> 1.587 + 1.588 + <method name="_doPopupItemEnablingSpell"> 1.589 + <parameter name="popupNode"/> 1.590 + <body> 1.591 + <![CDATA[ 1.592 + var spellui = this.spellCheckerUI; 1.593 + if (!spellui || !spellui.canSpellCheck) { 1.594 + this._setMenuItemVisibility("spell-no-suggestions", false); 1.595 + this._setMenuItemVisibility("spell-check-enabled", false); 1.596 + this._setMenuItemVisibility("spell-check-separator", false); 1.597 + this._setMenuItemVisibility("spell-add-to-dictionary", false); 1.598 + this._setMenuItemVisibility("spell-undo-add-to-dictionary", false); 1.599 + this._setMenuItemVisibility("spell-suggestions-separator", false); 1.600 + this._setMenuItemVisibility("spell-dictionaries", false); 1.601 + return; 1.602 + } 1.603 + 1.604 + spellui.initFromEvent(document.popupRangeParent, 1.605 + document.popupRangeOffset); 1.606 + 1.607 + var enabled = spellui.enabled; 1.608 + var showUndo = spellui.canSpellCheck && spellui.canUndo(); 1.609 + this._enabledCheckbox.setAttribute("checked", enabled); 1.610 + 1.611 + var overMisspelling = spellui.overMisspelling; 1.612 + this._setMenuItemVisibility("spell-add-to-dictionary", overMisspelling); 1.613 + this._setMenuItemVisibility("spell-undo-add-to-dictionary", showUndo); 1.614 + this._setMenuItemVisibility("spell-suggestions-separator", overMisspelling || showUndo); 1.615 + 1.616 + // suggestion list 1.617 + var numsug = spellui.addSuggestionsToMenu(popupNode, this._suggestionsSeparator, 5); 1.618 + this._setMenuItemVisibility("spell-no-suggestions", overMisspelling && numsug == 0); 1.619 + 1.620 + // dictionary list 1.621 + var numdicts = spellui.addDictionaryListToMenu(this._dictionariesMenu, null); 1.622 + this._setMenuItemVisibility("spell-dictionaries", enabled && numdicts > 1); 1.623 + 1.624 + this._doPopupItemEnabling(popupNode); 1.625 + ]]> 1.626 + </body> 1.627 + </method> 1.628 + <method name="_doPopupItemDisabling"> 1.629 + <body><![CDATA[ 1.630 + if (this.spellCheckerUI) { 1.631 + this.spellCheckerUI.clearSuggestionsFromMenu(); 1.632 + this.spellCheckerUI.clearDictionaryListFromMenu(); 1.633 + } 1.634 + ]]></body> 1.635 + </method> 1.636 + </implementation> 1.637 + </binding> 1.638 + 1.639 +</bindings>