Mercurial > public > sg101
view static/js/tiny_mce/plugins/spellchecker/editor_plugin_src.js @ 821:71db8076dc3d
Bandmap WIP: geocoding integrated with add form.
Add form works. Before submitting the form, client side JS makes
a geocode request to Google and populates hidden lat/lon fields
with the result. Successfully created a model instance on the
server side.
Still need to update admin dashboard, admin approval, and give
out badges for adding bands to the map. Once that is done, then
work on displaying the map with filtering.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Tue, 23 Sep 2014 20:40:31 -0500 |
parents | 6c182ceb7147 |
children |
line wrap: on
line source
/** * editor_plugin_src.js * * Copyright 2009, Moxiecode Systems AB * Released under LGPL License. * * License: http://tinymce.moxiecode.com/license * Contributing: http://tinymce.moxiecode.com/contributing */ (function() { var JSONRequest = tinymce.util.JSONRequest, each = tinymce.each, DOM = tinymce.DOM; tinymce.create('tinymce.plugins.SpellcheckerPlugin', { getInfo : function() { return { longname : 'Spellchecker', author : 'Moxiecode Systems AB', authorurl : 'http://tinymce.moxiecode.com', infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/spellchecker', version : tinymce.majorVersion + "." + tinymce.minorVersion }; }, init : function(ed, url) { var t = this, cm; t.url = url; t.editor = ed; t.rpcUrl = ed.getParam("spellchecker_rpc_url", "{backend}"); if (t.rpcUrl == '{backend}') { // Sniff if the browser supports native spellchecking (Don't know of a better way) if (tinymce.isIE) return; t.hasSupport = true; // Disable the context menu when spellchecking is active ed.onContextMenu.addToTop(function(ed, e) { if (t.active) return false; }); } // Register commands ed.addCommand('mceSpellCheck', function() { if (t.rpcUrl == '{backend}') { // Enable/disable native spellchecker t.editor.getBody().spellcheck = t.active = !t.active; return; } if (!t.active) { ed.setProgressState(1); t._sendRPC('checkWords', [t.selectedLang, t._getWords()], function(r) { if (r.length > 0) { t.active = 1; t._markWords(r); ed.setProgressState(0); ed.nodeChanged(); } else { ed.setProgressState(0); if (ed.getParam('spellchecker_report_no_misspellings', true)) ed.windowManager.alert('spellchecker.no_mpell'); } }); } else t._done(); }); if (ed.settings.content_css !== false) ed.contentCSS.push(url + '/css/content.css'); ed.onClick.add(t._showMenu, t); ed.onContextMenu.add(t._showMenu, t); ed.onBeforeGetContent.add(function() { if (t.active) t._removeWords(); }); ed.onNodeChange.add(function(ed, cm) { cm.setActive('spellchecker', t.active); }); ed.onSetContent.add(function() { t._done(); }); ed.onBeforeGetContent.add(function() { t._done(); }); ed.onBeforeExecCommand.add(function(ed, cmd) { if (cmd == 'mceFullScreen') t._done(); }); // Find selected language t.languages = {}; each(ed.getParam('spellchecker_languages', '+English=en,Danish=da,Dutch=nl,Finnish=fi,French=fr,German=de,Italian=it,Polish=pl,Portuguese=pt,Spanish=es,Swedish=sv', 'hash'), function(v, k) { if (k.indexOf('+') === 0) { k = k.substring(1); t.selectedLang = v; } t.languages[k] = v; }); }, createControl : function(n, cm) { var t = this, c, ed = t.editor; if (n == 'spellchecker') { // Use basic button if we use the native spellchecker if (t.rpcUrl == '{backend}') { // Create simple toggle button if we have native support if (t.hasSupport) c = cm.createButton(n, {title : 'spellchecker.desc', cmd : 'mceSpellCheck', scope : t}); return c; } c = cm.createSplitButton(n, {title : 'spellchecker.desc', cmd : 'mceSpellCheck', scope : t}); c.onRenderMenu.add(function(c, m) { m.add({title : 'spellchecker.langs', 'class' : 'mceMenuItemTitle'}).setDisabled(1); each(t.languages, function(v, k) { var o = {icon : 1}, mi; o.onclick = function() { if (v == t.selectedLang) { return; } mi.setSelected(1); t.selectedItem.setSelected(0); t.selectedItem = mi; t.selectedLang = v; }; o.title = k; mi = m.add(o); mi.setSelected(v == t.selectedLang); if (v == t.selectedLang) t.selectedItem = mi; }) }); return c; } }, // Internal functions _walk : function(n, f) { var d = this.editor.getDoc(), w; if (d.createTreeWalker) { w = d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false); while ((n = w.nextNode()) != null) f.call(this, n); } else tinymce.walk(n, f, 'childNodes'); }, _getSeparators : function() { var re = '', i, str = this.editor.getParam('spellchecker_word_separator_chars', '\\s!"#$%&()*+,-./:;<=>?@[\]^_{|}§©«®±¶·¸»¼½¾¿×÷¤\u201d\u201c'); // Build word separator regexp for (i=0; i<str.length; i++) re += '\\' + str.charAt(i); return re; }, _getWords : function() { var ed = this.editor, wl = [], tx = '', lo = {}, rawWords = []; // Get area text this._walk(ed.getBody(), function(n) { if (n.nodeType == 3) tx += n.nodeValue + ' '; }); // split the text up into individual words if (ed.getParam('spellchecker_word_pattern')) { // look for words that match the pattern rawWords = tx.match('(' + ed.getParam('spellchecker_word_pattern') + ')', 'gi'); } else { // Split words by separator tx = tx.replace(new RegExp('([0-9]|[' + this._getSeparators() + '])', 'g'), ' '); tx = tinymce.trim(tx.replace(/(\s+)/g, ' ')); rawWords = tx.split(' '); } // Build word array and remove duplicates each(rawWords, function(v) { if (!lo[v]) { wl.push(v); lo[v] = 1; } }); return wl; }, _removeWords : function(w) { var ed = this.editor, dom = ed.dom, se = ed.selection, b = se.getBookmark(); each(dom.select('span').reverse(), function(n) { if (n && (dom.hasClass(n, 'mceItemHiddenSpellWord') || dom.hasClass(n, 'mceItemHidden'))) { if (!w || dom.decode(n.innerHTML) == w) dom.remove(n, 1); } }); se.moveToBookmark(b); }, _markWords : function(wl) { var ed = this.editor, dom = ed.dom, doc = ed.getDoc(), se = ed.selection, b = se.getBookmark(), nl = [], w = wl.join('|'), re = this._getSeparators(), rx = new RegExp('(^|[' + re + '])(' + w + ')(?=[' + re + ']|$)', 'g'); // Collect all text nodes this._walk(ed.getBody(), function(n) { if (n.nodeType == 3) { nl.push(n); } }); // Wrap incorrect words in spans each(nl, function(n) { var node, elem, txt, pos, v = n.nodeValue; if (rx.test(v)) { // Encode the content v = dom.encode(v); // Create container element elem = dom.create('span', {'class' : 'mceItemHidden'}); // Following code fixes IE issues by creating text nodes // using DOM methods instead of innerHTML. // Bug #3124: <PRE> elements content is broken after spellchecking. // Bug #1408: Preceding whitespace characters are removed // @TODO: I'm not sure that both are still issues on IE9. if (tinymce.isIE) { // Enclose mispelled words with temporal tag v = v.replace(rx, '$1<mcespell>$2</mcespell>'); // Loop over the content finding mispelled words while ((pos = v.indexOf('<mcespell>')) != -1) { // Add text node for the content before the word txt = v.substring(0, pos); if (txt.length) { node = doc.createTextNode(dom.decode(txt)); elem.appendChild(node); } v = v.substring(pos+10); pos = v.indexOf('</mcespell>'); txt = v.substring(0, pos); v = v.substring(pos+11); // Add span element for the word elem.appendChild(dom.create('span', {'class' : 'mceItemHiddenSpellWord'}, txt)); } // Add text node for the rest of the content if (v.length) { node = doc.createTextNode(dom.decode(v)); elem.appendChild(node); } } else { // Other browsers preserve whitespace characters on innerHTML usage elem.innerHTML = v.replace(rx, '$1<span class="mceItemHiddenSpellWord">$2</span>'); } // Finally, replace the node with the container dom.replace(elem, n); } }); se.moveToBookmark(b); }, _showMenu : function(ed, e) { var t = this, ed = t.editor, m = t._menu, p1, dom = ed.dom, vp = dom.getViewPort(ed.getWin()), wordSpan = e.target; e = 0; // Fixes IE memory leak if (!m) { m = ed.controlManager.createDropMenu('spellcheckermenu', {'class' : 'mceNoIcons'}); t._menu = m; } if (dom.hasClass(wordSpan, 'mceItemHiddenSpellWord')) { m.removeAll(); m.add({title : 'spellchecker.wait', 'class' : 'mceMenuItemTitle'}).setDisabled(1); t._sendRPC('getSuggestions', [t.selectedLang, dom.decode(wordSpan.innerHTML)], function(r) { var ignoreRpc; m.removeAll(); if (r.length > 0) { m.add({title : 'spellchecker.sug', 'class' : 'mceMenuItemTitle'}).setDisabled(1); each(r, function(v) { m.add({title : v, onclick : function() { dom.replace(ed.getDoc().createTextNode(v), wordSpan); t._checkDone(); }}); }); m.addSeparator(); } else m.add({title : 'spellchecker.no_sug', 'class' : 'mceMenuItemTitle'}).setDisabled(1); ignoreRpc = t.editor.getParam("spellchecker_enable_ignore_rpc", ''); m.add({ title : 'spellchecker.ignore_word', onclick : function() { var word = wordSpan.innerHTML; dom.remove(wordSpan, 1); t._checkDone(); // tell the server if we need to if (ignoreRpc) { ed.setProgressState(1); t._sendRPC('ignoreWord', [t.selectedLang, word], function(r) { ed.setProgressState(0); }); } } }); m.add({ title : 'spellchecker.ignore_words', onclick : function() { var word = wordSpan.innerHTML; t._removeWords(dom.decode(word)); t._checkDone(); // tell the server if we need to if (ignoreRpc) { ed.setProgressState(1); t._sendRPC('ignoreWords', [t.selectedLang, word], function(r) { ed.setProgressState(0); }); } } }); if (t.editor.getParam("spellchecker_enable_learn_rpc")) { m.add({ title : 'spellchecker.learn_word', onclick : function() { var word = wordSpan.innerHTML; dom.remove(wordSpan, 1); t._checkDone(); ed.setProgressState(1); t._sendRPC('learnWord', [t.selectedLang, word], function(r) { ed.setProgressState(0); }); } }); } m.update(); }); p1 = dom.getPos(ed.getContentAreaContainer()); m.settings.offset_x = p1.x; m.settings.offset_y = p1.y; ed.selection.select(wordSpan); p1 = dom.getPos(wordSpan); m.showMenu(p1.x, p1.y + wordSpan.offsetHeight - vp.y); return tinymce.dom.Event.cancel(e); } else m.hideMenu(); }, _checkDone : function() { var t = this, ed = t.editor, dom = ed.dom, o; each(dom.select('span'), function(n) { if (n && dom.hasClass(n, 'mceItemHiddenSpellWord')) { o = true; return false; } }); if (!o) t._done(); }, _done : function() { var t = this, la = t.active; if (t.active) { t.active = 0; t._removeWords(); if (t._menu) t._menu.hideMenu(); if (la) t.editor.nodeChanged(); } }, _sendRPC : function(m, p, cb) { var t = this; JSONRequest.sendRPC({ url : t.rpcUrl, method : m, params : p, success : cb, error : function(e, x) { t.editor.setProgressState(0); t.editor.windowManager.alert(e.errstr || ('Error response: ' + x.responseText)); } }); } }); // Register plugin tinymce.PluginManager.add('spellchecker', tinymce.plugins.SpellcheckerPlugin); })();