!import
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1 //@line 38 "/home/visbrero/mnt/roisin/rev_control/hg/mozilla/toolkit/content/inlineSpellCheckUI.js"
2
3 var InlineSpellCheckerUI = {
4 mOverMisspelling: false,
5 mMisspelling: "",
6 mMenu: null,
7 mSpellSuggestions: [], // text of words
8 mSuggestionItems: [], // menuitem nodes
9 mDictionaryMenu: null,
10 mDictionaryNames: [], // internal dictionary names (e.g. "en-US")
11 mDictionaryItems: [],
12 mLanguageBundle: null, // language names
13 mRegionBundle: null, // region names
14
15 // Call this function to initialize for a given editor
init
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
16 init: function(aEditor)
17 {
18 this.uninit();
19 this.mEditor = aEditor;
20 try {
21 this.mInlineSpellChecker = this.mEditor.getInlineSpellChecker(true);
22 // note: this might have been NULL if there is no chance we can spellcheck
23 } catch(e) {
24 this.mInlineSpellChecker = null;
25 }
26 },
27
28 // call this to clear state
uninit
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
29 uninit: function()
30 {
31 this.mInlineSpellChecker = null;
32 this.mOverMisspelling = false;
33 this.mMisspelling = "";
34 this.mMenu = null;
35 this.mSpellSuggestions = [];
36 this.mSuggestionItems = [];
37 this.mDictionaryMenu = null;
38 this.mDictionaryNames = [];
39 this.mDictionaryItems = [];
40 },
41
42 // for each UI event, you must call this function, it will compute the
43 // word the cursor is over
initFromEvent
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
44 initFromEvent: function(rangeParent, rangeOffset)
45 {
46 this.mOverMisspelling = false;
47
48 if (!rangeParent || !this.mInlineSpellChecker)
49 return;
50
51 var selcon = this.mEditor.selectionController;
52 var spellsel = selcon.getSelection(selcon.SELECTION_SPELLCHECK);
53 if (spellsel.rangeCount == 0)
54 return; // easy case - no misspellings
55
56 var range = this.mInlineSpellChecker.getMispelledWord(rangeParent,
57 rangeOffset);
58 if (! range)
59 return; // not over a misspelled word
60
61 this.mMisspelling = range.toString();
62 this.mOverMisspelling = true;
63 this.mWordNode = rangeParent;
64 this.mWordOffset = rangeOffset;
65 },
66
67 // returns false if there should be no spellchecking UI enabled at all, true
68 // means that you can at least give the user the ability to turn it on.
get_canSpellCheck
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
69 get canSpellCheck()
70 {
71 // inline spell checker objects will be created only if there are actual
72 // dictionaries available
73 return (this.mInlineSpellChecker != null);
74 },
75
76 // Whether spellchecking is enabled in the current box
get_enabled
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
77 get enabled()
78 {
79 return (this.mInlineSpellChecker &&
80 this.mInlineSpellChecker.enableRealTimeSpell);
81 },
set_enabled
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
82 set enabled(isEnabled)
83 {
84 if (this.mInlineSpellChecker)
85 this.mEditor.setSpellcheckUserOverride(isEnabled);
86 },
87
88 // returns true if the given event is over a misspelled word
get_overMisspelling
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
89 get overMisspelling()
90 {
91 return this.mOverMisspelling;
92 },
93
94 // this prepends up to "maxNumber" suggestions at the given menu position
95 // for the word under the cursor. Returns the number of suggestions inserted.
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
96 addSuggestionsToMenu: function(menu, insertBefore, maxNumber)
97 {
98 if (! this.mInlineSpellChecker || ! this.mOverMisspelling)
99 return 0; // nothing to do
100
101 var spellchecker = this.mInlineSpellChecker.spellChecker;
102 if (! spellchecker.CheckCurrentWord(this.mMisspelling))
103 return 0; // word seems not misspelled after all (?)
104
105 this.mMenu = menu;
106 this.mSpellSuggestions = [];
107 this.mSuggestionItems = [];
108 for (var i = 0; i < maxNumber; i ++) {
109 var suggestion = spellchecker.GetSuggestedWord();
110 if (! suggestion.length)
111 break;
112 this.mSpellSuggestions.push(suggestion);
113
114 var item = document.createElement("menuitem");
115 this.mSuggestionItems.push(item);
116 item.setAttribute("label", suggestion);
117 item.setAttribute("value", suggestion);
118 // this function thing is necessary to generate a callback with the
119 // correct binding of "val" (the index in this loop).
anon:120:21
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
anon:120:48
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
120 var callback = function(me, val) { return function(evt) { me.replaceMisspelling(val); } };
121 item.addEventListener("command", callback(this, i), true);
122 item.setAttribute("class", "spell-suggestion");
123 menu.insertBefore(item, insertBefore);
124 }
125 return this.mSpellSuggestions.length;
126 },
127
128 // undoes the work of addSuggestionsToMenu for the same menu
129 // (call from popup hiding)
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
130 clearSuggestionsFromMenu: function()
131 {
132 for (var i = 0; i < this.mSuggestionItems.length; i ++) {
133 this.mMenu.removeChild(this.mSuggestionItems[i]);
134 }
135 this.mSuggestionItems = [];
136 },
137
138 // returns the number of dictionary languages. If insertBefore is NULL, this
139 // does an append to the given menu
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
140 addDictionaryListToMenu: function(menu, insertBefore)
141 {
142 this.mDictionaryMenu = menu;
143 this.mDictionaryNames = [];
144 this.mDictionaryItems = [];
145
146 if (! this.mLanguageBundle) {
147 // create the bundles for language and region
148 var bundleService = Components.classes["@mozilla.org/intl/stringbundle;1"]
149 .getService(Components.interfaces.nsIStringBundleService);
150 this.mLanguageBundle = bundleService.createBundle(
151 "chrome://global/locale/languageNames.properties");
152 this.mRegionBundle = bundleService.createBundle(
153 "chrome://global/locale/regionNames.properties");
154 }
155
156 if (! this.mInlineSpellChecker || ! this.enabled)
157 return 0;
158 var spellchecker = this.mInlineSpellChecker.spellChecker;
159 var o1 = {}, o2 = {};
160 spellchecker.GetDictionaryList(o1, o2);
161 var list = o1.value;
162 var listcount = o2.value;
163 var curlang = spellchecker.GetCurrentDictionary();
164 var isoStrArray;
165
166 for (var i = 0; i < list.length; i ++) {
167 // get the display name for this dictionary
168 isoStrArray = list[i].split("-");
169 var displayName = "";
170 if (this.mLanguageBundle && isoStrArray[0]) {
171 try {
172 displayName = this.mLanguageBundle.GetStringFromName(isoStrArray[0].toLowerCase());
173 } catch(e) {} // ignore language bundle errors
174 if (this.mRegionBundle && isoStrArray[1]) {
175 try {
176 displayName += " / " + this.mRegionBundle.GetStringFromName(isoStrArray[1].toLowerCase());
177 } catch(e) {} // ignore region bundle errors
178 if (isoStrArray[2])
179 displayName += " (" + isoStrArray[2] + ")";
180 }
181 }
182
183 // if we didn't get a name, just use the raw dictionary name
184 if (displayName.length == 0)
185 displayName = list[i];
186
187 this.mDictionaryNames.push(list[i]);
188 var item = document.createElement("menuitem");
189 item.setAttribute("label", displayName);
190 item.setAttribute("type", "checkbox");
191 this.mDictionaryItems.push(item);
192 if (curlang == list[i]) {
193 item.setAttribute("checked", "true");
194 } else {
anon:195:23
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
anon:195:50
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
195 var callback = function(me, val) { return function(evt) { me.selectDictionary(val); } };
196 item.addEventListener("command", callback(this, i), true);
197 }
198 if (insertBefore)
199 menu.insertBefore(item, insertBefore);
200 else
201 menu.appendChild(item);
202 }
203 return list.length;
204 },
205
206 // undoes the work of addDictionaryListToMenu for the menu
207 // (call on popup hiding)
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
208 clearDictionaryListFromMenu: function()
209 {
210 for (var i = 0; i < this.mDictionaryItems.length; i ++) {
211 this.mDictionaryMenu.removeChild(this.mDictionaryItems[i]);
212 }
213 this.mDictionaryItems = [];
214 },
215
216 // callback for selecting a dictionary
selectDictionary
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
217 selectDictionary: function(index)
218 {
219 if (! this.mInlineSpellChecker || index < 0 || index >= this.mDictionaryNames.length)
220 return;
221 var spellchecker = this.mInlineSpellChecker.spellChecker;
222 spellchecker.SetCurrentDictionary(this.mDictionaryNames[index]);
223 spellchecker.saveDefaultDictionary();
224 this.mInlineSpellChecker.spellCheckRange(null); // causes recheck
225 },
226
227 // callback for selecting a suggesteed replacement
replaceMisspelling
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
228 replaceMisspelling: function(index)
229 {
230 if (! this.mInlineSpellChecker || ! this.mOverMisspelling)
231 return;
232 if (index < 0 || index >= this.mSpellSuggestions.length)
233 return;
234 this.mInlineSpellChecker.replaceWord(this.mWordNode, this.mWordOffset,
235 this.mSpellSuggestions[index]);
236 },
237
238 // callback for enabling or disabling spellchecking
toggleEnabled
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
239 toggleEnabled: function()
240 {
241 this.mEditor.setSpellcheckUserOverride(!this.mInlineSpellChecker.enableRealTimeSpell);
242 },
243
244 // callback for adding the current misspelling to the user-defined dictionary
addToDictionary
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
245 addToDictionary: function()
246 {
247 this.mInlineSpellChecker.addWordToDictionary(this.mMisspelling);
248 },
ignoreWord
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
249 ignoreWord: function()
250 {
251 this.mInlineSpellChecker.ignoreWord(this.mMisspelling);
252 }
253 };