www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | Submodules | README | LICENSE

timedtextarea.xml (10945B)


      1 <?xml version="1.0"?>
      2 <!--
      3 	A combination of Mozilla's textarea, timed-textbox, input-box, and
      4 	input-box-spell bindings, with the timed-textbox's Return key
      5 	event handler removed
      6 	
      7 	Note: It would be much nicer if a) Mozilla offered this natively or
      8 	b) we just extended the timed-textbox binding directly, but since it's based
      9 	on html:input rather than html:textarea, doing so breaks things in various
     10 	ways (though it may be possible with some tweaking)
     11 	
     12 	Also note: spellcheck code here is a slightly adjusted version
     13 	of a patch by Neil Deakin on Bugzilla that wasn't 	approved in time for
     14 	Firefox 2.0 (https://bugzilla.mozilla.org/show_bug.cgi?id=346787).
     15 	When there's native support for spellcheck="true" in XUL,	we'll hopefully be
     16 	able to use that, though it'll still need to work as a timed textarea...
     17 -->
     18 
     19 <!DOCTYPE bindings [
     20   <!ENTITY % textcontextDTD SYSTEM "chrome://global/locale/textcontext.dtd" >
     21   %textcontextDTD;
     22   
     23   <!-- These aren't yet included in textcontext.dtd in Minefield, so we reproduce them here
     24   		(rather than including the massive browser.dtd) -->
     25   <!ENTITY spellAddToDictionary.label "Add to dictionary">
     26   <!ENTITY spellAddToDictionary.accesskey "o">
     27   <!ENTITY spellEnable.label "Spell check this field">
     28   <!ENTITY spellEnable.accesskey "S">
     29   <!ENTITY spellNoSuggestions.label "(No spelling suggestions)">
     30   <!ENTITY spellDictionaries.label "Languages">
     31   <!ENTITY spellDictionaries.accesskey "l">
     32   <!ENTITY spellAddDictionaries.label "Add dictionaries...">
     33   <!ENTITY spellAddDictionaries.accesskey "A">
     34 ]>
     35 
     36 <bindings 	xmlns="http://www.mozilla.org/xbl"
     37 			xmlns:html="http://www.w3.org/1999/xhtml"
     38 			xmlns:xbl="http://www.mozilla.org/xbl"
     39 			xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
     40 	<binding id="timed-textarea" extends="chrome://global/content/bindings/textbox.xml#textbox">
     41 		<implementation>
     42 			<field name="mInputField">null</field>
     43 			<property name="inputField" readonly="true">
     44 				<getter><![CDATA[
     45 				  if (!this.mInputField)
     46 					this.mInputField = document.getAnonymousElementByAttribute(this, "anonid", "input");
     47 				  return this.mInputField;
     48 				]]></getter>
     49 			</property>
     50 		  
     51 			<field name="_timer">null</field>
     52 			<property name="timeout"
     53 					onset="this.setAttribute('timeout', val); return val;"
     54 					onget="return parseInt(this.getAttribute('timeout')) || 0;"/>
     55 			<property name="value">
     56 				<getter>
     57 				  return this.inputField.value;
     58 				</getter>
     59 				<setter>
     60 				  <![CDATA[
     61 					this.inputField.value = val;
     62 					if (this._timer)
     63 					  clearTimeout(this._timer);
     64 					return val;
     65 				  ]]>
     66 				</setter>
     67 			</property>
     68 			<method name="_fireCommand">
     69 				<parameter name="me"/>
     70 				<body>
     71 				  <![CDATA[
     72 					me._timer = null;
     73 					me.doCommand();
     74 				  ]]>
     75 				</body>
     76 			</method>
     77 			
     78 			
     79 			<!-- Spellcheck code -->
     80 			<field name="_spellCheckInitialized">false</field>
     81 			<property name="spellCheckerUI" readonly="true">
     82 				<getter><![CDATA[
     83 				  if (!this._spellCheckInitialized) {
     84 					this._spellCheckInitialized = true;
     85 				
     86 					const CI = Components.interfaces;
     87 					if (!document instanceof CI.nsIDOMXULDocument)
     88 					  return null;
     89 				
     90 					var textbox = this;
     91 					
     92 					if (!textbox || !textbox instanceof CI.nsIDOMXULTextBoxElement)
     93 					  return null;
     94 				
     95 					try {
     96 					  var loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"].
     97 									 getService(CI.mozIJSSubScriptLoader);
     98 					  loader.loadSubScript("chrome://global/content/inlineSpellCheckUI.js", this);
     99 					  
    100 					  if ("InlineSpellCheckerUI" in this)
    101 						this.InlineSpellCheckerUI.init(
    102 							textbox.inputField.QueryInterface(CI.nsIDOMNSEditableElement).editor
    103 						);
    104 					} catch(ex) {
    105 						// this throws an error on window open...
    106 					}
    107 				  }
    108 				
    109 				  return this.InlineSpellCheckerUI;
    110 				]]></getter>
    111 			</property>
    112 			
    113 			<constructor>
    114 			<![CDATA[
    115 			  // can't initialize the spell checker in the constructor as not
    116 			  // everything is initialized and the editor will fail to create the
    117 			  // inline spell checker object
    118 			  setTimeout(this._delayedInitSpellCheck, 0, this)
    119 			  
    120 				// oninput doesn't seem to fire on text drag
    121 				this.inputField.addEventListener('dragdrop', function(event) {
    122 					document.getBindingParent(event.target).doInput();
    123 				}, false);
    124 			]]>
    125 			</constructor>
    126 			
    127 			<method name="_delayedInitSpellCheck">
    128 				<parameter name="me"/>
    129 				<body><![CDATA[
    130 				  var spellui = me.spellCheckerUI;
    131 				  if (spellui)
    132 					spellui.enabled = true;
    133 				]]></body>
    134 			</method>
    135 			
    136 			<method name="_doPopupItemEnabling">
    137 				<parameter name="popupNode"/>
    138 				<body>
    139 				<![CDATA[
    140 					var children = popupNode.childNodes;
    141 					for (var i = 0; i < children.length; i++) {
    142 						var command = children[i].getAttribute("cmd");
    143 						if (command) {
    144 							var controller = document.commandDispatcher.getControllerForCommand(command);
    145 							var enabled = controller.isCommandEnabled(command);
    146 							if (enabled) {
    147 								children[i].removeAttribute("disabled");
    148 							}
    149 							else {
    150 								children[i].setAttribute("disabled", "true");
    151 							}
    152 						}
    153 					}
    154 				]]>
    155 				</body>
    156 			</method>
    157 			
    158 			<method name="_doPopupItemEnablingSpell">
    159 				<parameter name="popupNode"/>
    160 				<body>
    161 				  <![CDATA[
    162 					var spellui = this.spellCheckerUI;
    163 					if (!spellui || !spellui.canSpellCheck) {
    164 					  this._setMenuItemVisibility("spell-no-suggestions", false);
    165 					  this._setMenuItemVisibility("spell-check-enabled", false);
    166 					  this._setMenuItemVisibility("spell-check-separator", false);
    167 					  this._setMenuItemVisibility("spell-add-to-dictionary", false);
    168 					  this._setMenuItemVisibility("spell-suggestions-separator", false);
    169 					  this._setMenuItemVisibility("spell-dictionaries", false);
    170 					  return;
    171 					}
    172 				
    173 					spellui.initFromEvent(document.popupRangeParent,
    174 										  document.popupRangeOffset);
    175 				
    176 					var enabled = spellui.enabled;
    177 					document.getAnonymousElementByAttribute(this, "anonid",
    178 					  "spell-check-enabled").setAttribute("checked", enabled);
    179 				
    180 					var overMisspelling = spellui.overMisspelling;
    181 					this._setMenuItemVisibility("spell-add-to-dictionary", overMisspelling);
    182 					this._setMenuItemVisibility("spell-suggestions-separator", overMisspelling);
    183 				
    184 					// suggestion list
    185 					var suggestionsSeparator = document.getAnonymousElementByAttribute(this,
    186 												 "anonid", "spell-add-to-dictionary");
    187 					var numsug = spellui.addSuggestionsToMenu(popupNode, suggestionsSeparator, 5);
    188 					this._setMenuItemVisibility("spell-no-suggestions", overMisspelling && numsug == 0);
    189 				
    190 					// dictionary list
    191 					var dictmenu = document.getAnonymousElementByAttribute(this, "anonid",
    192 									 "spell-dictionaries-menu");
    193 					var addsep = document.getAnonymousElementByAttribute(this, "anonid",
    194 									 "spell-language-separator");
    195 					
    196 					var numdicts = spellui.addDictionaryListToMenu(dictmenu, addsep);
    197 					this._setMenuItemVisibility("spell-dictionaries", enabled);
    198 					
    199 					this._doPopupItemEnabling(popupNode);
    200 				  ]]>
    201 				</body>
    202 			</method>
    203 			
    204 			<method name="_doPopupItemDisabling">
    205 				<body><![CDATA[
    206 				  if (this.spellCheckerUI) {
    207 					this.spellCheckerUI.clearSuggestionsFromMenu();
    208 					this.spellCheckerUI.clearDictionaryListFromMenu();
    209 				  }
    210 				]]></body>
    211 			</method>
    212 			
    213 			<method name="_setMenuItemVisibility">
    214 				<parameter name="anonid"/>
    215 				<parameter name="visible"/>
    216 				<body><![CDATA[
    217 				  document.getAnonymousElementByAttribute(this, "anonid", anonid).
    218 					hidden = ! visible;
    219 				]]></body>
    220 			</method>
    221 			
    222 			
    223 			<method name="doTextCommand">
    224 				<parameter name="command"/>
    225 					<body>
    226 					<![CDATA[
    227 					var controller = document.commandDispatcher.getControllerForCommand(command);
    228 					controller.doCommand(command);
    229 					]]>
    230 				</body>
    231 			</method>
    232 			
    233 			<method name="doInput">
    234 				<body>
    235 				<![CDATA[
    236 					if (this._timer) {
    237 						clearTimeout(this._timer);
    238 					}
    239 					this._timer = this.timeout && setTimeout(this._fireCommand, this.timeout, this);
    240 				]]>
    241 				</body>
    242 			</method>
    243 		</implementation>
    244 		
    245 		
    246 		<handlers>
    247 			<handler event="input">
    248 			<![CDATA[
    249 				this.doInput();
    250 			]]>
    251 			</handler>
    252 		</handlers>
    253 		
    254 		
    255 		<content context="_child">
    256 			<xul:hbox class="textbox-input-box" flex="1">
    257 				<html:textarea class="textbox-textarea" flex="1" anonid="input"
    258 					xbl:inherits="onfocus,onblur,xbl:text=value,disabled,tabindex,rows,cols,readonly,wrap"><children/></html:textarea>
    259 				<xul:menupopup anonid="input-box-contextmenu"
    260 								onpopupshowing="if (document.commandDispatcher.focusedElement != this.parentNode.firstChild) { this.parentNode.firstChild.focus(); } this.parentNode.parentNode._doPopupItemEnablingSpell(this);"
    261 								onpopuphiding="this.parentNode.parentNode._doPopupItemDisabling(this);"
    262 								oncommand="var cmd = event.originalTarget.getAttribute('cmd'); if(cmd) { this.parentNode.parentNode.doTextCommand(cmd); event.stopPropagation(); }">
    263 					<xul:menuitem label="&spellNoSuggestions.label;" anonid="spell-no-suggestions" disabled="true"/>
    264 					<xul:menuitem label="&spellAddToDictionary.label;" accesskey="&spellAddToDictionary.accesskey;" anonid="spell-add-to-dictionary"
    265 									oncommand="this.parentNode.parentNode.parentNode.spellCheckerUI.addToDictionary();"/>
    266 					<xul:menuseparator anonid="spell-suggestions-separator"/>
    267 					<xul:menuitem label="&undoCmd.label;" accesskey="&undoCmd.accesskey;" cmd="cmd_undo"/>
    268 					<xul:menuseparator/>
    269 					<xul:menuitem label="&cutCmd.label;" accesskey="&cutCmd.accesskey;" cmd="cmd_cut"/>
    270 					<xul:menuitem label="&copyCmd.label;" accesskey="&copyCmd.accesskey;" cmd="cmd_copy"/>
    271 					<xul:menuitem label="&pasteCmd.label;" accesskey="&pasteCmd.accesskey;" cmd="cmd_paste"/>
    272 					<xul:menuitem label="&deleteCmd.label;" accesskey="&deleteCmd.accesskey;" cmd="cmd_delete"/>
    273 					<xul:menuseparator/>
    274 					<xul:menuitem label="&selectAllCmd.label;" accesskey="&selectAllCmd.accesskey;" cmd="cmd_selectAll"/>
    275 					<xul:menuseparator anonid="spell-check-separator"/>
    276 					<xul:menuitem label="&spellEnable.label;" type="checkbox" accesskey="&spellEnable.accesskey;" anonid="spell-check-enabled"
    277 									oncommand="this.parentNode.parentNode.parentNode.spellCheckerUI.toggleEnabled();"/>
    278 					<xul:menu label="&spellDictionaries.label;" accesskey="&spellDictionaries.accesskey;" anonid="spell-dictionaries">
    279 						<xul:menupopup anonid="spell-dictionaries-menu"
    280 										onpopupshowing="event.stopPropagation();"
    281 										onpopuphiding="event.stopPropagation();">
    282 							<xul:menuseparator anonid="spell-language-separator"/>
    283 							<xul:menuitem anonid="spell-add-dictionaries-main" label="&spellAddDictionaries.label;"
    284 											accesskey="&spellAddDictionaries.accesskey;"
    285 											oncommand="nsContextMenu.prototype.addDictionaries();"/>
    286 						</xul:menupopup>
    287 					</xul:menu>
    288 				</xul:menupopup>
    289 			</xul:hbox>
    290 		  
    291 		</content>
    292 	</binding>
    293 </bindings>