diff --git a/wp-includes/js/tinymce/plugins/spellchecker/classes/TinyGoogleSpell.class.php b/wp-includes/js/tinymce/plugins/spellchecker/classes/TinyGoogleSpell.class.php index 8b96b04237..93caa26360 100755 --- a/wp-includes/js/tinymce/plugins/spellchecker/classes/TinyGoogleSpell.class.php +++ b/wp-includes/js/tinymce/plugins/spellchecker/classes/TinyGoogleSpell.class.php @@ -1,12 +1,10 @@ _getMatches($wordstr); for ($i=0; $iunhtmlentities(mb_substr($wordstr, $matches[$i][1], $matches[$i][2], "UTF-8")); return $words; } + function unhtmlentities($string) { + $string = preg_replace('~&#x([0-9a-f]+);~ei', 'chr(hexdec("\\1"))', $string); + $string = preg_replace('~&#([0-9]+);~e', 'chr(\\1)', $string); + + $trans_tbl = get_html_translation_table(HTML_ENTITIES); + $trans_tbl = array_flip($trans_tbl); + + return strtr($string, $trans_tbl); + } + // Returns array with suggestions or false if failed. function getSuggestion($word) { $sug = array(); @@ -34,37 +42,78 @@ class TinyGoogleSpell { $matches = $this->_getMatches($word); if (count($matches) > 0) - $sug = explode("\t", $matches[0][4]); + $sug = explode("\t", utf8_encode($this->unhtmlentities($matches[0][4]))); return $sug; } - function _getMatches($word_list) { - $xml = ""; + function _xmlChars($string) { + $trans = get_html_translation_table(HTML_ENTITIES, ENT_QUOTES); + + foreach ($trans as $k => $v) + $trans[$k] = "&#".ord($k).";"; - // Setup HTTP Client - $client = new HttpClient('www.google.com'); - $client->setUserAgent('Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR'); - $client->setHandleRedirects(false); - $client->setDebug(false); + return strtr($string, $trans); + } + + function _getMatches($word_list) { + $server = "www.google.com"; + $port = 443; + $path = "/tbproxy/spell?lang=" . $this->lang . "&hl=en"; + $host = "www.google.com"; + $url = "https://" . $server; // Setup XML request - $xml .= ''; - $xml .= ''; - $xml .= '' . htmlentities($word_list) . ''; + $xml = '' . $word_list . ''; - // Execute HTTP Post to Google - if (!$client->post('/tbproxy/spell?lang=' . $this->lang, $xml)) { - $this->errorMsg[] = 'An error occurred: ' . $client->getError(); - return array(); + $header = "POST ".$path." HTTP/1.0 \r\n"; + $header .= "MIME-Version: 1.0 \r\n"; + $header .= "Content-type: application/PTI26 \r\n"; + $header .= "Content-length: ".strlen($xml)." \r\n"; + $header .= "Content-transfer-encoding: text \r\n"; + $header .= "Request-number: 1 \r\n"; + $header .= "Document-type: Request \r\n"; + $header .= "Interface-Version: Test 1.4 \r\n"; + $header .= "Connection: close \r\n\r\n"; + $header .= $xml; + //$this->_debugData($xml); + + // Use raw sockets + $fp = fsockopen("ssl://" . $server, $port, $errno, $errstr, 30); + if ($fp) { + // Send request + fwrite($fp, $header); + + // Read response + $xml = ""; + while (!feof($fp)) + $xml .= fgets($fp, 128); + + fclose($fp); + } else { + // Use curl + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL,$url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $header); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); + $xml = curl_exec($ch); + curl_close($ch); } + //$this->_debugData($xml); + // Grab and parse content - $xml = $client->getContent(); preg_match_all('/([^<]*)<\/c>/', $xml, $matches, PREG_SET_ORDER); return $matches; } + + function _debugData($data) { + $fh = @fopen("debug.log", 'a+'); + @fwrite($fh, $data); + @fclose($fh); + } } // Setup classname, should be the same as the name of the spellchecker class diff --git a/wp-includes/js/tinymce/plugins/spellchecker/classes/TinyPspellShell.class.php b/wp-includes/js/tinymce/plugins/spellchecker/classes/TinyPspellShell.class.php index cfafa92081..d0c03e01c8 100755 --- a/wp-includes/js/tinymce/plugins/spellchecker/classes/TinyPspellShell.class.php +++ b/wp-includes/js/tinymce/plugins/spellchecker/classes/TinyPspellShell.class.php @@ -6,6 +6,7 @@ * */ + class TinyPspellShell { var $lang; var $mode; @@ -27,7 +28,11 @@ class TinyPspellShell { $this->errorMsg = array(); $this->tmpfile = tempnam($config['tinypspellshell.tmp'], "tinyspell"); - $this->cmd = "cat ". $this->tmpfile ." | " . $config['tinypspellshell.aspell'] . " -a --lang=". $this->lang; + + if(preg_match("#win#i",php_uname())) + $this->cmd = $config['tinypspellshell.aspell'] . " -a --lang=". $this->lang." --encoding=utf-8 -H < $this->tmpfile 2>&1"; + else + $this->cmd = "cat ". $this->tmpfile ." | " . $config['tinypspellshell.aspell'] . " -a --encoding=utf-8 -H --lang=". $this->lang; } // Returns array with bad words or false if failed. @@ -36,7 +41,6 @@ class TinyPspellShell { fwrite($fh, "!\n"); foreach($wordArray as $key => $value) fwrite($fh, "^" . $value . "\n"); - fclose($fh); } else { $this->errorMsg[] = "PSpell not found."; @@ -44,7 +48,8 @@ class TinyPspellShell { } $data = shell_exec($this->cmd); - @unlink($this->tmpfile); + @unlink($this->tmpfile); + $returnData = array(); $dataArr = preg_split("/\n/", $data, -1, PREG_SPLIT_NO_EMPTY); @@ -66,15 +71,22 @@ class TinyPspellShell { // Returns array with suggestions or false if failed. function getSuggestion($word) { + if (function_exists("mb_convert_encoding")) + $word = mb_convert_encoding($word, "ISO-8859-1", mb_detect_encoding($word, "UTF-8")); + else + $word = utf8_encode($word); + if ($fh = fopen($this->tmpfile, "w")) { fwrite($fh, "!\n"); fwrite($fh, "^$word\n"); fclose($fh); } else - wp_die("Error opening tmp file."); + die("Error opening tmp file."); $data = shell_exec($this->cmd); - @unlink($this->tmpfile); + + @unlink($this->tmpfile); + $returnData = array(); $dataArr = preg_split("/\n/", $data, -1, PREG_SPLIT_NO_EMPTY); @@ -94,9 +106,16 @@ class TinyPspellShell { } return $returnData; } + + function _debugData($data) { + $fh = @fopen("debug.log", 'a+'); + @fwrite($fh, $data); + @fclose($fh); + } + } // Setup classname, should be the same as the name of the spellchecker class $spellCheckerConfig['class'] = "TinyPspellShell"; -?> +?> \ No newline at end of file diff --git a/wp-includes/js/tinymce/plugins/spellchecker/config.php b/wp-includes/js/tinymce/plugins/spellchecker/config.php index a622fe93de..097d46b6bd 100755 --- a/wp-includes/js/tinymce/plugins/spellchecker/config.php +++ b/wp-includes/js/tinymce/plugins/spellchecker/config.php @@ -1,13 +1,14 @@ diff --git a/wp-includes/js/tinymce/plugins/spellchecker/css/content.css b/wp-includes/js/tinymce/plugins/spellchecker/css/content.css index fb82733cd5..c56a4538a7 100755 --- a/wp-includes/js/tinymce/plugins/spellchecker/css/content.css +++ b/wp-includes/js/tinymce/plugins/spellchecker/css/content.css @@ -1,5 +1,4 @@ .mceItemHiddenSpellWord { background: url('../images/wline.gif') repeat-x bottom left; - bo2rder-bottom: 1px dashed red; cursor: default; } diff --git a/wp-includes/js/tinymce/plugins/spellchecker/css/spellchecker.css b/wp-includes/js/tinymce/plugins/spellchecker/css/spellchecker.css index aa4a8ea3b0..f2c6ac74de 100755 --- a/wp-includes/js/tinymce/plugins/spellchecker/css/spellchecker.css +++ b/wp-includes/js/tinymce/plugins/spellchecker/css/spellchecker.css @@ -31,4 +31,5 @@ font-family: Arial, Verdana, Tahoma, Helvetica; font-weight: bold; font-size: 11px; + background-color: #FFF; } diff --git a/wp-includes/js/tinymce/plugins/spellchecker/editor_plugin.js b/wp-includes/js/tinymce/plugins/spellchecker/editor_plugin.js index 98f057ee36..9e0329cf6a 100755 --- a/wp-includes/js/tinymce/plugins/spellchecker/editor_plugin.js +++ b/wp-includes/js/tinymce/plugins/spellchecker/editor_plugin.js @@ -1,573 +1 @@ -/** - * $RCSfile: editor_plugin_src.js,v $ - * $Revision: 1.4 $ - * $Date: 2006/03/24 17:24:50 $ - * - * @author Moxiecode - * @copyright Copyright © 2004-2006, Moxiecode Systems AB, All rights reserved. - */ - -tinyMCE.importPluginLanguagePack('spellchecker', 'en,sv,nn,nb'); - -// Plucin static class -var TinyMCE_SpellCheckerPlugin = { - _contextMenu : new TinyMCE_Menu(), - _menu : new TinyMCE_Menu(), - _counter : 0, - - getInfo : function() { - return { - longname : 'Spellchecker', - author : 'Moxiecode Systems AB', - authorurl : 'http://tinymce.moxiecode.com', - infourl : 'http://tinymce.moxiecode.com/tinymce/docs/plugin_spellchecker.html', - version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion - }; - }, - - handleEvent : function(e) { - var elm = tinyMCE.isMSIE ? e.srcElement : e.target; - var inst = tinyMCE.selectedInstance, args = ''; - var self = TinyMCE_SpellCheckerPlugin; - var cm = self._contextMenu; - var p, p2, x, y, sx, sy, h, elm; - - // Handle click on word - if ((e.type == "click" || e.type == "contextmenu") && elm) { - do { - if (tinyMCE.getAttrib(elm, 'class') == "mceItemHiddenSpellWord") { - inst.spellCheckerElm = elm; - - // Setup arguments - args += 'id=' + inst.editorId + "|" + (++self._counter); - args += '&cmd=suggest&check=' + escape(elm.innerHTML); - args += '&lang=' + escape(inst.spellCheckerLang); - - elm = inst.spellCheckerElm; - p = tinyMCE.getAbsPosition(inst.iframeElement); - p2 = tinyMCE.getAbsPosition(elm); - h = parseInt(elm.offsetHeight); - sx = inst.getBody().scrollLeft; - sy = inst.getBody().scrollTop; - x = p.absLeft + p2.absLeft - sx; - y = p.absTop + p2.absTop - sy + h; - - cm.clear(); - cm.addTitle(tinyMCE.getLang('lang_spellchecker_wait', '', true)); - cm.show(); - cm.moveTo(x, y); - - inst.selection.selectNode(elm, false, false); - - self._sendAjax(self.baseURL + "/tinyspell.php", self._ajaxResponse, 'post', args); - - tinyMCE.cancelEvent(e); - return false; - } - } while ((elm = elm.parentNode)); - } - - return true; - }, - - initInstance : function(inst) { - var self = TinyMCE_SpellCheckerPlugin, m = self._menu, cm = self._contextMenu, e; - - tinyMCE.importCSS(inst.getDoc(), tinyMCE.baseURL + "/plugins/spellchecker/css/content.css"); - - if (!tinyMCE.hasMenu('spellcheckercontextmenu')) { - tinyMCE.importCSS(document, tinyMCE.baseURL + "/plugins/spellchecker/css/spellchecker.css"); - - cm.init({drop_menu : false}); - tinyMCE.addMenu('spellcheckercontextmenu', cm); - } - - if (!tinyMCE.hasMenu('spellcheckermenu')) { - m.init({}); - tinyMCE.addMenu('spellcheckermenu', m); - } - - inst.spellCheckerLang = 'en'; - self._buildSettingsMenu(inst, null); - - e = self._getBlockBoxLayer(inst).create('div', 'mceBlockBox', document.getElementById(inst.editorId + '_parent')); - self._getMsgBoxLayer(inst).create('div', 'mceMsgBox', document.getElementById(inst.editorId + '_parent')); - }, - - _getMsgBoxLayer : function(inst) { - if (!inst.spellCheckerMsgBoxL) - inst.spellCheckerMsgBoxL = new TinyMCE_Layer(inst.editorId + '_spellcheckerMsgBox', false); - - return inst.spellCheckerMsgBoxL; - }, - - _getBlockBoxLayer : function(inst) { - if (!inst.spellCheckerBoxL) - inst.spellCheckerBoxL = new TinyMCE_Layer(inst.editorId + '_spellcheckerBlockBox', false); - - return inst.spellCheckerBoxL; - }, - - _buildSettingsMenu : function(inst, lang) { - var i, ar = tinyMCE.getParam('spellchecker_languages', '+English=en').split(','), p; - var self = TinyMCE_SpellCheckerPlugin, m = self._menu, c; - - m.clear(); - m.addTitle(tinyMCE.getLang('lang_spellchecker_langs', '', true)); - - for (i=0; i'; - h += ''; - h += ''; - h += ''; - } else { - if (tinyMCE.isMSIE && !tinyMCE.isOpera) - h += ''; - else - h += ''; - - h += ''; - h += ''; - h += ''; - h += ''; - } - - return h; - }, - - _menuButtonEvent : function(e, o) { - if (o.className == 'mceMenuButtonFocus') - return; - - if (e == 'over') - o.className = o.className + ' mceMenuHover'; - else - o.className = o.className.replace(/\s.*$/, ''); - }, - - _toggleMenu : function(editor_id, id) { - var self = TinyMCE_SpellCheckerPlugin; - var e = document.getElementById(editor_id + '_spellchecker'); - var inst = tinyMCE.getInstanceById(editor_id); - - if (self._menu.isVisible()) { - tinyMCE.hideMenus(); - return; - } - - tinyMCE.lastMenuBtnClass = e.className.replace(/\s.*$/, ''); - tinyMCE.switchClass(editor_id + '_spellchecker', 'mceMenuButtonFocus'); - - self._menu.moveRelativeTo(e, 'bl'); - self._menu.moveBy(tinyMCE.isMSIE && !tinyMCE.isOpera ? 0 : 1, -1); - - if (tinyMCE.isOpera) - self._menu.moveBy(0, -2); - - self._onMenuEvent(inst, self._menu, 'show'); - - self._menu.show(); - - tinyMCE.lastSelectedMenuBtn = editor_id + '_spellchecker'; - }, - - _onMenuEvent : function(inst, m, n) { - TinyMCE_SpellCheckerPlugin._buildSettingsMenu(inst, inst.spellCheckerLang); - }, - - execCommand : function(editor_id, element, command, user_interface, value) { - var inst = tinyMCE.getInstanceById(editor_id), self = TinyMCE_SpellCheckerPlugin, args = '', co, bb, mb, nl, i, e; - - // Handle commands - switch (command) { - case "mceSpellCheck": - if (!inst.spellcheckerOn) { - inst.spellCheckerBookmark = inst.selection.getBookmark(); - - // Setup arguments - args += 'id=' + inst.editorId + "|" + (++self._counter); - args += '&cmd=spell&check=' + escape(self._getWordList(inst.getBody())).replace(/%20/g, '+'); - args += '&lang=' + escape(inst.spellCheckerLang); - - co = document.getElementById(inst.editorId + '_parent').firstChild; - bb = self._getBlockBoxLayer(inst); - bb.moveRelativeTo(co, 'tl'); - bb.resizeTo(co.offsetWidth, co.offsetHeight); - bb.show(); - - // Setup message box - mb = self._getMsgBoxLayer(inst); - e = mb.getElement(); - e.innerHTML = '' + tinyMCE.getLang('lang_spellchecker_swait', '', true) + ''; - mb.show(); - mb.moveRelativeTo(co, 'cc'); - - if (tinyMCE.isMSIE && !tinyMCE.isOpera) { - nl = co.getElementsByTagName('select'); - for (i=0; i?@[\]^_{|}§©«®±¶·¸»¼½¾¿×÷¤\u201d\u201c'); - - for (i=0; i=0; i--) { - c = tinyMCE.getAttrib(nl[i], 'class'); - - if ((c == 'mceItemHiddenSpellWord' || c == 'mceItemHidden') && (word == null || nl[i].innerHTML == word)) - self._removeWord(nl[i]); - } - - if (b) - inst.selection.moveToBookmark(b); - }, - - _checkDone : function(inst) { - var i, w = 0, nl = inst.getDoc().getElementsByTagName("span") - var self = TinyMCE_SpellCheckerPlugin; - - for (i=nl.length-1; i>=0; i--) { - c = tinyMCE.getAttrib(nl[i], 'class'); - - if (c == 'mceItemHiddenSpellWord') - w++; - } - - if (w == 0) { - self._removeWords(inst.getDoc()); - inst.spellcheckerOn = false; - tinyMCE.switchClass(inst.editorId + '_spellchecker', 'mceMenuButton'); - } - }, - - _removeWord : function(e) { - tinyMCE.setOuterHTML(e, e.innerHTML); - }, - - _markWords : function(doc, n, wl) { - var i, nv, nn, nl = tinyMCE.getNodeTree(n, new Array(), 3); - var r1, r2, r3, r4, r5, w = ''; - var re = TinyMCE_SpellCheckerPlugin._getWordSeparators(); - - for (i=0; i$1$2'); - nv = nv.replace(r3, '$1$2'); - - nn = doc.createElement('span'); - nn.className = "mceItemHidden"; - nn.innerHTML = nv; - - // Remove old text node - nl[i].parentNode.replaceChild(nn, nl[i]); - } - } - }, - - _buildMenu : function(sg, max) { - var i, self = TinyMCE_SpellCheckerPlugin, cm = self._contextMenu; - - cm.clear(); - - if (sg != null) { - cm.addTitle(tinyMCE.getLang('lang_spellchecker_sug', '', true)); - - for (i=0; i';h+='';h+='';h+='';}else{if(tinyMCE.isMSIE&&!tinyMCE.isOpera)h+='';else h+='';h+='';h+='';h+='';h+='';}return h;},_menuButtonEvent:function(e,o){var t=this;window.setTimeout(function(){t._menuButtonEvent2(e,o);},1);},_menuButtonEvent2:function(e,o){if(o.className=='mceMenuButtonFocus')return;if(e=='over')o.className=o.className+' mceMenuHover';else o.className=o.className.replace(/\s.*$/,'');},_toggleMenu:function(editor_id,id){var self=TinyMCE_SpellCheckerPlugin;var e=document.getElementById(editor_id+'_spellchecker');var inst=tinyMCE.getInstanceById(editor_id);if(self._menu.isVisible()){tinyMCE.hideMenus();return;}tinyMCE.lastMenuBtnClass=e.className.replace(/\s.*$/,'');tinyMCE.switchClass(editor_id+'_spellchecker','mceMenuButtonFocus');self._menu.moveRelativeTo(e,'bl');self._menu.moveBy(tinyMCE.isMSIE&&!tinyMCE.isOpera?0:1,-1);if(tinyMCE.isOpera)self._menu.moveBy(0,-2);self._onMenuEvent(inst,self._menu,'show');self._menu.show();tinyMCE.lastSelectedMenuBtn=editor_id+'_spellchecker';},_onMenuEvent:function(inst,m,n){TinyMCE_SpellCheckerPlugin._buildSettingsMenu(inst,inst.spellCheckerLang);},execCommand:function(editor_id,element,command,user_interface,value){var inst=tinyMCE.getInstanceById(editor_id),self=TinyMCE_SpellCheckerPlugin,args='',co,bb,mb,nl,i,e,mbs;switch(command){case"mceSpellCheck":if(!inst.spellcheckerOn){inst.spellCheckerBookmark=inst.selection.getBookmark();if(tinyMCE.isRealIE)tinyMCE.setInnerHTML(inst.getBody(),inst.getBody().innerHTML);args+='id='+inst.editorId+"|"+(++self._counter);args+='&cmd=spell&check='+encodeURIComponent(self._getWordList(inst.getBody())).replace(/\'/g,'%27');args+='&lang='+escape(inst.spellCheckerLang);co=document.getElementById(inst.editorId+'_parent').firstChild;bb=self._getBlockBoxLayer(inst);bb.moveRelativeTo(co,'tl');bb.resizeTo(co.offsetWidth,co.offsetHeight);bb.show();mb=self._getMsgBoxLayer(inst);e=mb.getElement();if(e.childNodes[0])e.removeChild(e.childNodes[0]);mbs=document.createElement("span");mbs.innerHTML=''+tinyMCE.getLang('lang_spellchecker_swait','',true)+'';e.appendChild(mbs);mb.show();mb.moveRelativeTo(co,'cc');if(tinyMCE.isMSIE&&!tinyMCE.isOpera){nl=co.getElementsByTagName('select');for(i=0;i?@[\]^_{|}\u201d\u201c');for(i=0;i0)wl[wl.length]=nl[i];}return wl.join(' ');},_removeWords:function(doc,word,cleanup){var i,c,nl=doc.getElementsByTagName("span");var self=TinyMCE_SpellCheckerPlugin;var inst=tinyMCE.selectedInstance,b=inst?inst.selection.getBookmark():null;word=typeof(word)=='undefined'?null:word;for(i=nl.length-1;i>=0;i--){c=tinyMCE.getAttrib(nl[i],'class');if((c=='mceItemHiddenSpellWord'||c=='mceItemHidden')&&(word==null||nl[i].innerHTML==word))self._removeWord(nl[i]);}if(b&&!cleanup)inst.selection.moveToBookmark(b);},_checkDone:function(inst){var self=TinyMCE_SpellCheckerPlugin;var w=self._countWords(inst);if(w==0){self._removeWords(inst.getDoc());inst.spellcheckerOn=false;tinyMCE.switchClass(inst.editorId+'_spellchecker','mceMenuButton');}},_countWords:function(inst){var i,w=0,nl=inst.getDoc().getElementsByTagName("span"),c;var self=TinyMCE_SpellCheckerPlugin;for(i=nl.length-1;i>=0;i--){c=tinyMCE.getAttrib(nl[i],'class');if(c=='mceItemHiddenSpellWord')w++;}return w;},_removeWord:function(e){if(e!=null)tinyMCE.setOuterHTML(e,e.innerHTML);},_markWords:function(doc,n,wl){var i,nv,nn,nl=tinyMCE.getNodeTree(n,new Array(),3);var r1,r2,r3,r4,r5,w='';var re=TinyMCE_SpellCheckerPlugin._getWordSeparators();for(i=0;i0)w+=wl[i]+((i==wl.length-1)?'':'|');}for(i=0;i$1$2');nv=nv.replace(r3,'$1$2');nn=doc.createElement('span');nn.className="mceItemHidden";nn.innerHTML=nv;nl[i].parentNode.replaceChild(nn,nl[i]);}}},_buildMenu:function(sg,max){var i,self=TinyMCE_SpellCheckerPlugin,cm=self._contextMenu;cm.clear();if(sg!=null){cm.addTitle(tinyMCE.getLang('lang_spellchecker_sug','',true));for(i=0;icheckWords($words); break; + case "suggest": $result = $tinyspell->getSuggestion($check); break; + default: // Just use this for now. $tinyspell->errorMsg[] = "No command."; @@ -109,19 +114,22 @@ switch($outputType) { case "xml": header('Content-type: text/xml; charset=utf-8'); - echo ''; - echo "\n"; + $body = ''; + $body .= "\n"; + if (count($result) == 0) - echo ''; + $body .= ''; else - echo ''. utf8_encode(implode(" ", $result)) .''; + $body .= ''. urlencode(implode(" ", $result)) .''; + echo $body; break; case "xmlerror"; header('Content-type: text/xml; charset=utf-8'); - echo ''; - echo "\n"; - echo 'errorMsg) .'" />'; + $body = ''; + $body .= "\n"; + $body .= 'errorMsg) .'" />'; + echo $body; break; case "html": var_dump($result); @@ -130,4 +138,5 @@ echo "Error"; break; } -?> + +?>