[ Index ]

PHP Cross Reference of Wordpress 2.9.1

title

Body

[close]

/wp-includes/js/tinymce/plugins/spellchecker/ -> editor_plugin.js (source)

   1  /**
   2   * $Id: editor_plugin_src.js 425 2007-11-21 15:17:39Z spocke $
   3   *
   4   * @author Moxiecode
   5   * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
   6   */
   7  
   8  (function() {
   9      var JSONRequest = tinymce.util.JSONRequest, each = tinymce.each, DOM = tinymce.DOM;
  10  
  11      tinymce.create('tinymce.plugins.SpellcheckerPlugin', {
  12          getInfo : function() {
  13              return {
  14                  longname : 'Spellchecker',
  15                  author : 'Moxiecode Systems AB',
  16                  authorurl : 'http://tinymce.moxiecode.com',
  17                  infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/spellchecker',
  18                  version : tinymce.majorVersion + "." + tinymce.minorVersion
  19              };
  20          },
  21  
  22          init : function(ed, url) {
  23              var t = this, cm;
  24  
  25              t.url = url;
  26              t.editor = ed;
  27  
  28              // Register commands
  29              ed.addCommand('mceSpellCheck', function() {
  30                  if (!t.active) {
  31                      ed.setProgressState(1);
  32                      t._sendRPC('checkWords', [t.selectedLang, t._getWords()], function(r) {
  33                          if (r.length > 0) {
  34                              t.active = 1;
  35                              t._markWords(r);
  36                              ed.setProgressState(0);
  37                              ed.nodeChanged();
  38                          } else {
  39                              ed.setProgressState(0);
  40                              ed.windowManager.alert('spellchecker.no_mpell');
  41                          }
  42                      });
  43                  } else
  44                      t._done();
  45              });
  46  
  47              ed.onInit.add(function() {
  48                  if (ed.settings.content_css !== false)
  49                      ed.dom.loadCSS(url + '/css/content.css');
  50              });
  51  
  52              ed.onClick.add(t._showMenu, t);
  53              ed.onContextMenu.add(t._showMenu, t);
  54              ed.onBeforeGetContent.add(function() {
  55                  if (t.active)
  56                      t._removeWords();
  57              });
  58  
  59              ed.onNodeChange.add(function(ed, cm) {
  60                  cm.setActive('spellchecker', t.active);
  61              });
  62  
  63              ed.onSetContent.add(function() {
  64                  t._done();
  65              });
  66  
  67              ed.onBeforeGetContent.add(function() {
  68                  t._done();
  69              });
  70  
  71              ed.onBeforeExecCommand.add(function(ed, cmd) {
  72                  if (cmd == 'mceFullScreen')
  73                      t._done();
  74              });
  75  
  76              // Find selected language
  77              t.languages = {};
  78              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) {
  79                  if (k.indexOf('+') === 0) {
  80                      k = k.substring(1);
  81                      t.selectedLang = v;
  82                  }
  83  
  84                  t.languages[k] = v;
  85              });
  86          },
  87  
  88          createControl : function(n, cm) {
  89              var t = this, c, ed = t.editor;
  90  
  91              if (n == 'spellchecker') {
  92                  c = cm.createSplitButton(n, {title : 'spellchecker.desc', cmd : 'mceSpellCheck', scope : t});
  93  
  94                  c.onRenderMenu.add(function(c, m) {
  95                      m.add({title : 'spellchecker.langs', 'class' : 'mceMenuItemTitle'}).setDisabled(1);
  96                      each(t.languages, function(v, k) {
  97                          var o = {icon : 1}, mi;
  98  
  99                          o.onclick = function() {
 100                              mi.setSelected(1);
 101                              t.selectedItem.setSelected(0);
 102                              t.selectedItem = mi;
 103                              t.selectedLang = v;
 104                          };
 105  
 106                          o.title = k;
 107                          mi = m.add(o);
 108                          mi.setSelected(v == t.selectedLang);
 109  
 110                          if (v == t.selectedLang)
 111                              t.selectedItem = mi;
 112                      })
 113                  });
 114  
 115                  return c;
 116              }
 117          },
 118  
 119          // Internal functions
 120  
 121          _walk : function(n, f) {
 122              var d = this.editor.getDoc(), w;
 123  
 124              if (d.createTreeWalker) {
 125                  w = d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false);
 126  
 127                  while ((n = w.nextNode()) != null)
 128                      f.call(this, n);
 129              } else
 130                  tinymce.walk(n, f, 'childNodes');
 131          },
 132  
 133          _getSeparators : function() {
 134              var re = '', i, str = this.editor.getParam('spellchecker_word_separator_chars', '\\s!"#$%&()*+,-./:;<=>?@[\]^_{|}§©«®±¶·¸»¼½¾¿×÷¤\u201d\u201c');
 135  
 136              // Build word separator regexp
 137              for (i=0; i<str.length; i++)
 138                  re += '\\' + str.charAt(i);
 139  
 140              return re;
 141          },
 142  
 143          _getWords : function() {
 144              var ed = this.editor, wl = [], tx = '', lo = {};
 145  
 146              // Get area text
 147              this._walk(ed.getBody(), function(n) {
 148                  if (n.nodeType == 3)
 149                      tx += n.nodeValue + ' ';
 150              });
 151  
 152              // Split words by separator
 153              tx = tx.replace(new RegExp('([0-9]|[' + this._getSeparators() + '])', 'g'), ' ');
 154              tx = tinymce.trim(tx.replace(/(\s+)/g, ' '));
 155  
 156              // Build word array and remove duplicates
 157              each(tx.split(' '), function(v) {
 158                  if (!lo[v]) {
 159                      wl.push(v);
 160                      lo[v] = 1;
 161                  }
 162              });
 163  
 164              return wl;
 165          },
 166  
 167          _removeWords : function(w) {
 168              var ed = this.editor, dom = ed.dom, se = ed.selection, b = se.getBookmark();
 169  
 170              each(dom.select('span').reverse(), function(n) {
 171                  if (n && (dom.hasClass(n, 'mceItemHiddenSpellWord') || dom.hasClass(n, 'mceItemHidden'))) {
 172                      if (!w || dom.decode(n.innerHTML) == w)
 173                          dom.remove(n, 1);
 174                  }
 175              });
 176  
 177              se.moveToBookmark(b);
 178          },
 179  
 180          _markWords : function(wl) {
 181              var r1, r2, r3, r4, r5, w = '', ed = this.editor, re = this._getSeparators(), dom = ed.dom, nl = [];
 182              var se = ed.selection, b = se.getBookmark();
 183  
 184              each(wl, function(v) {
 185                  w += (w ? '|' : '') + v;
 186              });
 187  
 188              r1 = new RegExp('([' + re + '])(' + w + ')([' + re + '])', 'g');
 189              r2 = new RegExp('^(' + w + ')', 'g');
 190              r3 = new RegExp('(' + w + ')([' + re + ']?)$', 'g');
 191              r4 = new RegExp('^(' + w + ')([' + re + ']?)$', 'g');
 192              r5 = new RegExp('(' + w + ')([' + re + '])', 'g');
 193  
 194              // Collect all text nodes
 195              this._walk(this.editor.getBody(), function(n) {
 196                  if (n.nodeType == 3) {
 197                      nl.push(n);
 198                  }
 199              });
 200  
 201              // Wrap incorrect words in spans
 202              each(nl, function(n) {
 203                  var v;
 204  
 205                  if (n.nodeType == 3) {
 206                      v = n.nodeValue;
 207  
 208                      if (r1.test(v) || r2.test(v) || r3.test(v) || r4.test(v)) {
 209                          v = dom.encode(v);
 210                          v = v.replace(r5, '<span class="mceItemHiddenSpellWord">$1</span>$2');
 211                          v = v.replace(r3, '<span class="mceItemHiddenSpellWord">$1</span>$2');
 212  
 213                          dom.replace(dom.create('span', {'class' : 'mceItemHidden'}, v), n);
 214                      }
 215                  }
 216              });
 217  
 218              se.moveToBookmark(b);
 219          },
 220  
 221          _showMenu : function(ed, e) {
 222              var t = this, ed = t.editor, m = t._menu, p1, dom = ed.dom, vp = dom.getViewPort(ed.getWin());
 223  
 224              if (!m) {
 225                  p1 = DOM.getPos(ed.getContentAreaContainer());
 226                  //p2 = DOM.getPos(ed.getContainer());
 227  
 228                  m = ed.controlManager.createDropMenu('spellcheckermenu', {
 229                      offset_x : p1.x,
 230                      offset_y : p1.y,
 231                      'class' : 'mceNoIcons'
 232                  });
 233  
 234                  t._menu = m;
 235              }
 236  
 237              if (dom.hasClass(e.target, 'mceItemHiddenSpellWord')) {
 238                  m.removeAll();
 239                  m.add({title : 'spellchecker.wait', 'class' : 'mceMenuItemTitle'}).setDisabled(1);
 240  
 241                  t._sendRPC('getSuggestions', [t.selectedLang, dom.decode(e.target.innerHTML)], function(r) {
 242                      m.removeAll();
 243  
 244                      if (r.length > 0) {
 245                          m.add({title : 'spellchecker.sug', 'class' : 'mceMenuItemTitle'}).setDisabled(1);
 246                          each(r, function(v) {
 247                              m.add({title : v, onclick : function() {
 248                                  dom.replace(ed.getDoc().createTextNode(v), e.target);
 249                                  t._checkDone();
 250                              }});
 251                          });
 252  
 253                          m.addSeparator();
 254                      } else
 255                          m.add({title : 'spellchecker.no_sug', 'class' : 'mceMenuItemTitle'}).setDisabled(1);
 256  
 257                      m.add({
 258                          title : 'spellchecker.ignore_word',
 259                          onclick : function() {
 260                              dom.remove(e.target, 1);
 261                              t._checkDone();
 262                          }
 263                      });
 264  
 265                      m.add({
 266                          title : 'spellchecker.ignore_words',
 267                          onclick : function() {
 268                              t._removeWords(dom.decode(e.target.innerHTML));
 269                              t._checkDone();
 270                          }
 271                      });
 272  
 273                      m.update();
 274                  });
 275  
 276                  ed.selection.select(e.target);
 277                  p1 = dom.getPos(e.target);
 278                  m.showMenu(p1.x, p1.y + e.target.offsetHeight - vp.y);
 279  
 280                  return tinymce.dom.Event.cancel(e);
 281              } else
 282                  m.hideMenu();
 283          },
 284  
 285          _checkDone : function() {
 286              var t = this, ed = t.editor, dom = ed.dom, o;
 287  
 288              each(dom.select('span'), function(n) {
 289                  if (n && dom.hasClass(n, 'mceItemHiddenSpellWord')) {
 290                      o = true;
 291                      return false;
 292                  }
 293              });
 294  
 295              if (!o)
 296                  t._done();
 297          },
 298  
 299          _done : function() {
 300              var t = this, la = t.active;
 301  
 302              if (t.active) {
 303                  t.active = 0;
 304                  t._removeWords();
 305  
 306                  if (t._menu)
 307                      t._menu.hideMenu();
 308  
 309                  if (la)
 310                      t.editor.nodeChanged();
 311              }
 312          },
 313  
 314          _sendRPC : function(m, p, cb) {
 315              var t = this, url = t.editor.getParam("spellchecker_rpc_url", this.url+'/rpc.php');
 316  
 317              if (url == '{backend}') {
 318                  t.editor.setProgressState(0);
 319                  alert('Please specify: spellchecker_rpc_url');
 320                  return;
 321              }
 322  
 323              JSONRequest.sendRPC({
 324                  url : url,
 325                  method : m,
 326                  params : p,
 327                  success : cb,
 328                  error : function(e, x) {
 329                      t.editor.setProgressState(0);
 330                      t.editor.windowManager.alert(e.errstr || ('Error response: ' + x.responseText));
 331                  }
 332              });
 333          }
 334      });
 335  
 336      // Register plugin
 337      tinymce.PluginManager.add('spellchecker', tinymce.plugins.SpellcheckerPlugin);
 338  })();


Generated: Fri Jan 8 00:19:48 2010 Cross-referenced by PHPXref 0.7