TinyMCE: remove the 'spellchecker' plugin. It has been disabled for a while and the back-end currently doesn't work. See #24067.

Built from https://develop.svn.wordpress.org/trunk@26958


git-svn-id: http://core.svn.wordpress.org/trunk@26837 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Andrew Ozz 2014-01-15 19:07:11 +00:00
parent 0cf6bbc60a
commit 5d92ed5632
15 changed files with 6 additions and 2305 deletions

View File

@ -237,6 +237,12 @@ final class _WP_Editors {
'wpdialogs', 'wpdialogs',
) ) ); ) ) );
if ( ( $key = array_search( 'spellchecker', $plugins ) ) !== false ) {
// Remove 'spellchecker' from the internal plugins if added with 'tiny_mce_plugins' filter to prevent errors.
// It can be added with 'mce_external_plugins'.
unset( $plugins[$key] );
}
if ( ! empty( $mce_external_plugins ) ) { if ( ! empty( $mce_external_plugins ) ) {
/** /**
* This filter loads translations for external TinyMCE 3.x plugins. * This filter loads translations for external TinyMCE 3.x plugins.
@ -326,11 +332,6 @@ final class _WP_Editors {
self::$first_init['external_plugins'] = json_encode( $mce_external_plugins ); self::$first_init['external_plugins'] = json_encode( $mce_external_plugins );
} }
if ( in_array( 'spellchecker', $plugins, true ) ) {
self::$first_init['spellchecker_rpc_url'] = self::$baseurl . '/plugins/spellchecker/rpc.php';
self::$first_init['spellchecker_language'] = self::$mce_locale;
}
// WordPress default stylesheet // WordPress default stylesheet
$mce_css = array( self::$baseurl . '/skins/wordpress/wp-content.css' ); $mce_css = array( self::$baseurl . '/skins/wordpress/wp-content.css' );

View File

@ -1,33 +0,0 @@
Version 2.0.6 (2011-09-29)
Fixed incorrect position of suggestion menu.
Fixed handling of mispelled words with no suggestions in PSpellShell engine.
Fixed PSpellShell command on Windows.
Fixed bug where Javascript error is produced when enchant_dict_suggest() returns unexpected result.
Version 2.0.5 (2011-03-24)
Merged with the latest TinyMCE spellchecker version.
Version 2.0.4 (2010-12-20)
Fixed issue with the JSON class not having the correct number of parameters to ord calls.
Version 2.0.3 (2010-04-19)
Added standalone support. Will use native spellchecker for supported browsers.
Added @package phpdoc comments. Patch contributed by Jacob Santos.
Fixed some PHP missing function issue.
Version 2.0.2 (2008-04-30)
Added new EnchantSpell engine class contributed by Michel Weimerskirch.
Added new general.remote_rpc_url option, enables you to proxy requests to another server.
Fixed security hole in PSpellShell.php file if PSpellShell engine was used.
Version 2.0.1 (2008-03-07)
Fixed bug where spellchecker was auto focusing the editor in IE.
Version 2.0 (2008-01-30)
Fixed bug where the suggestions menu was placed at an incorrect location.
Version 2.0rc1 (2008-01-14)
Moved package from beta to release candidate.
Version 2.0b3 (2007-12-xx)
Fixed bug where the suggestions menu could appear at the wrong location.
Version 2.0b2 (2007-11-29)
Fixed bug where the spellchecker was removing the word when it was ignored.
Version 2.0b1 (2007-11-21)
Moved spellchecker from alpha to beta status.
Version 2.0a2 (2007-11-13)
Updated plugin so it works correctly with the TinyMCE 3.0a3 version.
Version 2.0a1 (2007-11-01)
Rewritten version for TinyMCE 3.0 this new version uses JSON RPC.

View File

@ -1,71 +0,0 @@
<?php
/**
* $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $
*
* This class was contributed by Michel Weimerskirch.
*
* @package MCManager.includes
* @author Moxiecode
* @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved.
*/
class EnchantSpell extends SpellChecker {
/**
* Spellchecks an array of words.
*
* @param String $lang Selected language code (like en_US or de_DE). Shortcodes like "en" and "de" work with enchant >= 1.4.1
* @param Array $words Array of words to check.
* @return Array of misspelled words.
*/
function &checkWords($lang, $words) {
$r = enchant_broker_init();
if (enchant_broker_dict_exists($r,$lang)) {
$d = enchant_broker_request_dict($r, $lang);
$returnData = array();
foreach($words as $key => $value) {
$correct = enchant_dict_check($d, $value);
if(!$correct) {
$returnData[] = trim($value);
}
}
return $returnData;
enchant_broker_free_dict($d);
} else {
}
enchant_broker_free($r);
}
/**
* Returns suggestions for a specific word.
*
* @param String $lang Selected language code (like en_US or de_DE). Shortcodes like "en" and "de" work with enchant >= 1.4.1
* @param String $word Specific word to get suggestions for.
* @return Array of suggestions for the specified word.
*/
function &getSuggestions($lang, $word) {
$r = enchant_broker_init();
if (enchant_broker_dict_exists($r,$lang)) {
$d = enchant_broker_request_dict($r, $lang);
$suggs = enchant_dict_suggest($d, $word);
// enchant_dict_suggest() sometimes returns NULL
if (!is_array($suggs))
$suggs = array();
enchant_broker_free_dict($d);
} else {
$suggs = array();
}
enchant_broker_free($r);
return $suggs;
}
}
?>

View File

@ -1,161 +0,0 @@
<?php
/**
* $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $
*
* @package MCManager.includes
* @author Moxiecode
* @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved.
*/
class GoogleSpell extends SpellChecker {
/**
* Spellchecks an array of words.
*
* @param {String} $lang Language code like sv or en.
* @param {Array} $words Array of words to spellcheck.
* @return {Array} Array of misspelled words.
*/
function &checkWords($lang, $words) {
$wordstr = implode(' ', $words);
$matches = $this->_getMatches($lang, $wordstr);
$words = array();
for ($i=0; $i<count($matches); $i++)
$words[] = $this->_unhtmlentities(mb_substr($wordstr, $matches[$i][1], $matches[$i][2], "UTF-8"));
return $words;
}
/**
* Returns suggestions of for a specific word.
*
* @param {String} $lang Language code like sv or en.
* @param {String} $word Specific word to get suggestions for.
* @return {Array} Array of suggestions for the specified word.
*/
function &getSuggestions($lang, $word) {
$sug = array();
$osug = array();
$matches = $this->_getMatches($lang, $word);
if (count($matches) > 0)
$sug = explode("\t", utf8_encode($this->_unhtmlentities($matches[0][4])));
// Remove empty
foreach ($sug as $item) {
if ($item)
$osug[] = $item;
}
return $osug;
}
protected function &_getMatches($lang, $str) {
$lang = preg_replace('/[^a-z\-]/i', '', $lang);
$str = preg_replace('/[\x00-\x1F\x7F]/', '', $str);
$server = "www.google.com";
$port = 443;
$path = "/tbproxy/spell?lang=" . $lang . "&hl=en";
$host = "www.google.com";
$url = "https://" . $server;
// Setup XML request
$xml = '<?xml version="1.0" encoding="utf-8" ?><spellrequest textalreadyclipped="0" ignoredups="0" ignoredigits="1" ignoreallcaps="1"><text>' . $str . '</text></spellrequest>';
$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;
// Use curl if it exists
if (function_exists('curl_init')) {
// 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);
} else {
// 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
echo "Could not open SSL connection to google.";
}
// Grab and parse content
$matches = array();
preg_match_all('/<c o="([^"]*)" l="([^"]*)" s="([^"]*)">([^<]*)<\/c>/', $xml, $matches, PREG_SET_ORDER);
return $matches;
}
protected 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);
}
}
// Patch in multibyte support
if (!function_exists('mb_substr')) {
function mb_substr($str, $start, $len = '', $encoding="UTF-8"){
$limit = strlen($str);
for ($s = 0; $start > 0;--$start) {// found the real start
if ($s >= $limit)
break;
if ($str[$s] <= "\x7F")
++$s;
else {
++$s; // skip length
while ($str[$s] >= "\x80" && $str[$s] <= "\xBF")
++$s;
}
}
if ($len == '')
return substr($str, $s);
else
for ($e = $s; $len > 0; --$len) {//found the real end
if ($e >= $limit)
break;
if ($str[$e] <= "\x7F")
++$e;
else {
++$e;//skip length
while ($str[$e] >= "\x80" && $str[$e] <= "\xBF" && $e < $limit)
++$e;
}
}
return substr($str, $s, $e - $s);
}
}
?>

View File

@ -1,82 +0,0 @@
<?php
/**
* $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $
*
* @package MCManager.includes
* @author Moxiecode
* @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved.
*/
class PSpell extends SpellChecker {
/**
* Spellchecks an array of words.
*
* @param {String} $lang Language code like sv or en.
* @param {Array} $words Array of words to spellcheck.
* @return {Array} Array of misspelled words.
*/
function &checkWords($lang, $words) {
$plink = $this->_getPLink($lang);
$outWords = array();
foreach ($words as $word) {
if (!pspell_check($plink, trim($word)))
$outWords[] = utf8_encode($word);
}
return $outWords;
}
/**
* Returns suggestions of for a specific word.
*
* @param {String} $lang Language code like sv or en.
* @param {String} $word Specific word to get suggestions for.
* @return {Array} Array of suggestions for the specified word.
*/
function &getSuggestions($lang, $word) {
$words = pspell_suggest($this->_getPLink($lang), $word);
for ($i=0; $i<count($words); $i++)
$words[$i] = utf8_encode($words[$i]);
return $words;
}
/**
* Opens a link for pspell.
*/
function &_getPLink($lang) {
// Check for native PSpell support
if (!function_exists("pspell_new"))
$this->throwError("PSpell support not found in PHP installation.");
// Setup PSpell link
$plink = pspell_new(
$lang,
$this->_config['PSpell.spelling'],
$this->_config['PSpell.jargon'],
$this->_config['PSpell.encoding'],
$this->_config['PSpell.mode']
);
// Setup PSpell link
/* if (!$plink) {
$pspellConfig = pspell_config_create(
$lang,
$this->_config['PSpell.spelling'],
$this->_config['PSpell.jargon'],
$this->_config['PSpell.encoding']
);
$plink = pspell_new_config($pspell_config);
}*/
if (!$plink)
$this->throwError("No PSpell link found opened.");
return $plink;
}
}
?>

View File

@ -1,117 +0,0 @@
<?php
/**
* $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $
*
* @package MCManager.includes
* @author Moxiecode
* @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved.
*/
class PSpellShell extends SpellChecker {
/**
* Spellchecks an array of words.
*
* @param {String} $lang Language code like sv or en.
* @param {Array} $words Array of words to spellcheck.
* @return {Array} Array of misspelled words.
*/
function &checkWords($lang, $words) {
$cmd = $this->_getCMD($lang);
if ($fh = fopen($this->_tmpfile, "w")) {
fwrite($fh, "!\n");
foreach($words as $key => $value)
fwrite($fh, "^" . $value . "\n");
fclose($fh);
} else
$this->throwError("PSpell support was not found.");
$data = shell_exec($cmd);
@unlink($this->_tmpfile);
$returnData = array();
$dataArr = preg_split("/[\r\n]/", $data, -1, PREG_SPLIT_NO_EMPTY);
foreach ($dataArr as $dstr) {
$matches = array();
// Skip this line.
if ($dstr[0] == "@")
continue;
preg_match("/(\&|#) ([^ ]+) .*/i", $dstr, $matches);
if (!empty($matches[2]))
$returnData[] = utf8_encode(trim($matches[2]));
}
return $returnData;
}
/**
* Returns suggestions of for a specific word.
*
* @param {String} $lang Language code like sv or en.
* @param {String} $word Specific word to get suggestions for.
* @return {Array} Array of suggestions for the specified word.
*/
function &getSuggestions($lang, $word) {
$cmd = $this->_getCMD($lang);
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
$this->throwError("Error opening tmp file.");
$data = shell_exec($cmd);
@unlink($this->_tmpfile);
$returnData = array();
$dataArr = preg_split("/\n/", $data, -1, PREG_SPLIT_NO_EMPTY);
foreach($dataArr as $dstr) {
$matches = array();
// Skip this line.
if ($dstr[0] == "@")
continue;
preg_match("/\&[^:]+:(.*)/i", $dstr, $matches);
if (!empty($matches[1])) {
$words = array_slice(explode(',', $matches[1]), 0, 10);
for ($i=0; $i<count($words); $i++)
$words[$i] = trim($words[$i]);
return $words;
}
}
return array();
}
function _getCMD($lang) {
$this->_tmpfile = tempnam($this->_config['PSpellShell.tmp'], "tinyspell");
$file = $this->_tmpfile;
$lang = preg_replace("/[^-_a-z]/", "", strtolower($lang));
$bin = $this->_config['PSpellShell.aspell'];
if (preg_match("#win#i", php_uname()))
return "$bin -a --lang=$lang --encoding=utf-8 -H < $file 2>&1";
return "cat $file | $bin -a --lang=$lang --encoding=utf-8 -H";
}
}
?>

View File

@ -1,62 +0,0 @@
<?php
/**
* $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $
*
* @package MCManager.includes
* @author Moxiecode
* @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved.
*/
class SpellChecker {
/**
* Constructor.
*
* @param $config Configuration name/value array.
*/
function SpellChecker(&$config) {
$this->_config = $config;
}
/**
* Simple loopback function everything that gets in will be send back.
*
* @param $args.. Arguments.
* @return {Array} Array of all input arguments.
*/
function &loopback(/* args.. */) {
return func_get_args();
}
/**
* Spellchecks an array of words.
*
* @param {String} $lang Language code like sv or en.
* @param {Array} $words Array of words to spellcheck.
* @return {Array} Array of misspelled words.
*/
function &checkWords($lang, $words) {
return $words;
}
/**
* Returns suggestions of for a specific word.
*
* @param {String} $lang Language code like sv or en.
* @param {String} $word Specific word to get suggestions for.
* @return {Array} Array of suggestions for the specified word.
*/
function &getSuggestions($lang, $word) {
return array();
}
/**
* Throws an error message back to the user. This will stop all execution.
*
* @param {String} $str Message to send back to user.
*/
function throwError($str) {
die('{"result":null,"id":null,"error":{"errstr":"' . addslashes($str) . '","errfile":"","errline":null,"errcontext":"","level":"FATAL"}}');
}
}
?>

View File

@ -1,595 +0,0 @@
<?php
/**
* $Id: JSON.php 40 2007-06-18 11:43:15Z spocke $
*
* @package MCManager.utils
* @author Moxiecode
* @copyright Copyright © 2007, Moxiecode Systems AB, All rights reserved.
*/
define('JSON_BOOL', 1);
define('JSON_INT', 2);
define('JSON_STR', 3);
define('JSON_FLOAT', 4);
define('JSON_NULL', 5);
define('JSON_START_OBJ', 6);
define('JSON_END_OBJ', 7);
define('JSON_START_ARRAY', 8);
define('JSON_END_ARRAY', 9);
define('JSON_KEY', 10);
define('JSON_SKIP', 11);
define('JSON_IN_ARRAY', 30);
define('JSON_IN_OBJECT', 40);
define('JSON_IN_BETWEEN', 50);
class Moxiecode_JSONReader {
var $_data, $_len, $_pos;
var $_value, $_token;
var $_location, $_lastLocations;
var $_needProp;
function Moxiecode_JSONReader($data) {
$this->_data = $data;
$this->_len = strlen($data);
$this->_pos = -1;
$this->_location = JSON_IN_BETWEEN;
$this->_lastLocations = array();
$this->_needProp = false;
}
function getToken() {
return $this->_token;
}
function getLocation() {
return $this->_location;
}
function getTokenName() {
switch ($this->_token) {
case JSON_BOOL:
return 'JSON_BOOL';
case JSON_INT:
return 'JSON_INT';
case JSON_STR:
return 'JSON_STR';
case JSON_FLOAT:
return 'JSON_FLOAT';
case JSON_NULL:
return 'JSON_NULL';
case JSON_START_OBJ:
return 'JSON_START_OBJ';
case JSON_END_OBJ:
return 'JSON_END_OBJ';
case JSON_START_ARRAY:
return 'JSON_START_ARRAY';
case JSON_END_ARRAY:
return 'JSON_END_ARRAY';
case JSON_KEY:
return 'JSON_KEY';
}
return 'UNKNOWN';
}
function getValue() {
return $this->_value;
}
function readToken() {
$chr = $this->read();
if ($chr != null) {
switch ($chr) {
case '[':
$this->_lastLocation[] = $this->_location;
$this->_location = JSON_IN_ARRAY;
$this->_token = JSON_START_ARRAY;
$this->_value = null;
$this->readAway();
return true;
case ']':
$this->_location = array_pop($this->_lastLocation);
$this->_token = JSON_END_ARRAY;
$this->_value = null;
$this->readAway();
if ($this->_location == JSON_IN_OBJECT)
$this->_needProp = true;
return true;
case '{':
$this->_lastLocation[] = $this->_location;
$this->_location = JSON_IN_OBJECT;
$this->_needProp = true;
$this->_token = JSON_START_OBJ;
$this->_value = null;
$this->readAway();
return true;
case '}':
$this->_location = array_pop($this->_lastLocation);
$this->_token = JSON_END_OBJ;
$this->_value = null;
$this->readAway();
if ($this->_location == JSON_IN_OBJECT)
$this->_needProp = true;
return true;
// String
case '"':
case '\'':
return $this->_readString($chr);
// Null
case 'n':
return $this->_readNull();
// Bool
case 't':
case 'f':
return $this->_readBool($chr);
default:
// Is number
if (is_numeric($chr) || $chr == '-' || $chr == '.')
return $this->_readNumber($chr);
return true;
}
}
return false;
}
function _readBool($chr) {
$this->_token = JSON_BOOL;
$this->_value = $chr == 't';
if ($chr == 't')
$this->skip(3); // rue
else
$this->skip(4); // alse
$this->readAway();
if ($this->_location == JSON_IN_OBJECT && !$this->_needProp)
$this->_needProp = true;
return true;
}
function _readNull() {
$this->_token = JSON_NULL;
$this->_value = null;
$this->skip(3); // ull
$this->readAway();
if ($this->_location == JSON_IN_OBJECT && !$this->_needProp)
$this->_needProp = true;
return true;
}
function _readString($quote) {
$output = "";
$this->_token = JSON_STR;
$endString = false;
while (($chr = $this->peek()) != -1) {
switch ($chr) {
case '\\':
// Read away slash
$this->read();
// Read escape code
$chr = $this->read();
switch ($chr) {
case 't':
$output .= "\t";
break;
case 'b':
$output .= "\b";
break;
case 'f':
$output .= "\f";
break;
case 'r':
$output .= "\r";
break;
case 'n':
$output .= "\n";
break;
case 'u':
$output .= $this->_int2utf8(hexdec($this->read(4)));
break;
default:
$output .= $chr;
break;
}
break;
case '\'':
case '"':
if ($chr == $quote)
$endString = true;
$chr = $this->read();
if ($chr != -1 && $chr != $quote)
$output .= $chr;
break;
default:
$output .= $this->read();
}
// String terminated
if ($endString)
break;
}
$this->readAway();
$this->_value = $output;
// Needed a property
if ($this->_needProp) {
$this->_token = JSON_KEY;
$this->_needProp = false;
return true;
}
if ($this->_location == JSON_IN_OBJECT && !$this->_needProp)
$this->_needProp = true;
return true;
}
function _int2utf8($int) {
$int = intval($int);
switch ($int) {
case 0:
return chr(0);
case ($int & 0x7F):
return chr($int);
case ($int & 0x7FF):
return chr(0xC0 | (($int >> 6) & 0x1F)) . chr(0x80 | ($int & 0x3F));
case ($int & 0xFFFF):
return chr(0xE0 | (($int >> 12) & 0x0F)) . chr(0x80 | (($int >> 6) & 0x3F)) . chr (0x80 | ($int & 0x3F));
case ($int & 0x1FFFFF):
return chr(0xF0 | ($int >> 18)) . chr(0x80 | (($int >> 12) & 0x3F)) . chr(0x80 | (($int >> 6) & 0x3F)) . chr(0x80 | ($int & 0x3F));
}
}
function _readNumber($start) {
$value = "";
$isFloat = false;
$this->_token = JSON_INT;
$value .= $start;
while (($chr = $this->peek()) != -1) {
if (is_numeric($chr) || $chr == '-' || $chr == '.') {
if ($chr == '.')
$isFloat = true;
$value .= $this->read();
} else
break;
}
$this->readAway();
if ($isFloat) {
$this->_token = JSON_FLOAT;
$this->_value = floatval($value);
} else
$this->_value = intval($value);
if ($this->_location == JSON_IN_OBJECT && !$this->_needProp)
$this->_needProp = true;
return true;
}
function readAway() {
while (($chr = $this->peek()) != null) {
if ($chr != ':' && $chr != ',' && $chr != ' ')
return;
$this->read();
}
}
function read($len = 1) {
if ($this->_pos < $this->_len) {
if ($len > 1) {
$str = substr($this->_data, $this->_pos + 1, $len);
$this->_pos += $len;
return $str;
} else
return $this->_data[++$this->_pos];
}
return null;
}
function skip($len) {
$this->_pos += $len;
}
function peek() {
if ($this->_pos < $this->_len)
return $this->_data[$this->_pos + 1];
return null;
}
}
/**
* This class handles JSON stuff.
*
* @package MCManager.utils
*/
class Moxiecode_JSON {
function Moxiecode_JSON() {
}
function decode($input) {
$reader = new Moxiecode_JSONReader($input);
return $this->readValue($reader);
}
function readValue(&$reader) {
$this->data = array();
$this->parents = array();
$this->cur =& $this->data;
$key = null;
$loc = JSON_IN_ARRAY;
while ($reader->readToken()) {
switch ($reader->getToken()) {
case JSON_STR:
case JSON_INT:
case JSON_BOOL:
case JSON_FLOAT:
case JSON_NULL:
switch ($reader->getLocation()) {
case JSON_IN_OBJECT:
$this->cur[$key] = $reader->getValue();
break;
case JSON_IN_ARRAY:
$this->cur[] = $reader->getValue();
break;
default:
return $reader->getValue();
}
break;
case JSON_KEY:
$key = $reader->getValue();
break;
case JSON_START_OBJ:
case JSON_START_ARRAY:
if ($loc == JSON_IN_OBJECT)
$this->addArray($key);
else
$this->addArray(null);
$cur =& $obj;
$loc = $reader->getLocation();
break;
case JSON_END_OBJ:
case JSON_END_ARRAY:
$loc = $reader->getLocation();
if (count($this->parents) > 0) {
$this->cur =& $this->parents[count($this->parents) - 1];
array_pop($this->parents);
}
break;
}
}
return $this->data[0];
}
// This method was needed since PHP is crapy and doesn't have pointers/references
function addArray($key) {
$this->parents[] =& $this->cur;
$ar = array();
if ($key)
$this->cur[$key] =& $ar;
else
$this->cur[] =& $ar;
$this->cur =& $ar;
}
function getDelim($index, &$reader) {
switch ($reader->getLocation()) {
case JSON_IN_ARRAY:
case JSON_IN_OBJECT:
if ($index > 0)
return ",";
break;
}
return "";
}
function encode($input) {
switch (gettype($input)) {
case 'boolean':
return $input ? 'true' : 'false';
case 'integer':
return (int) $input;
case 'float':
case 'double':
return (float) $input;
case 'NULL':
return 'null';
case 'string':
return $this->encodeString($input);
case 'array':
return $this->_encodeArray($input);
case 'object':
return $this->_encodeArray(get_object_vars($input));
}
return '';
}
function encodeString($input) {
// Needs to be escaped
if (preg_match('/[^a-zA-Z0-9]/', $input)) {
$output = '';
for ($i=0; $i<strlen($input); $i++) {
switch ($input[$i]) {
case "\b":
$output .= "\\b";
break;
case "\t":
$output .= "\\t";
break;
case "\f":
$output .= "\\f";
break;
case "\r":
$output .= "\\r";
break;
case "\n":
$output .= "\\n";
break;
case '\\':
$output .= "\\\\";
break;
case '\'':
$output .= "\\'";
break;
case '"':
$output .= '\"';
break;
default:
$byte = ord($input[$i]);
if (($byte & 0xE0) == 0xC0) {
$char = pack('C*', $byte, ord($input[$i + 1]));
$i += 1;
$output .= sprintf('\u%04s', bin2hex($this->_utf82utf16($char)));
} if (($byte & 0xF0) == 0xE0) {
$char = pack('C*', $byte, ord($input[$i + 1]), ord($input[$i + 2]));
$i += 2;
$output .= sprintf('\u%04s', bin2hex($this->_utf82utf16($char)));
} if (($byte & 0xF8) == 0xF0) {
$char = pack('C*', $byte, ord($input[$i + 1]), ord($input[$i + 2]), ord($input[$i + 3]));
$i += 3;
$output .= sprintf('\u%04s', bin2hex($this->_utf82utf16($char)));
} if (($byte & 0xFC) == 0xF8) {
$char = pack('C*', $byte, ord($input[$i + 1]), ord($input[$i + 2]), ord($input[$i + 3]), ord($input[$i + 4]));
$i += 4;
$output .= sprintf('\u%04s', bin2hex($this->_utf82utf16($char)));
} if (($byte & 0xFE) == 0xFC) {
$char = pack('C*', $byte, ord($input[$i + 1]), ord($input[$i + 2]), ord($input[$i + 3]), ord($input[$i + 4]), ord($input[$i + 5]));
$i += 5;
$output .= sprintf('\u%04s', bin2hex($this->_utf82utf16($char)));
} else if ($byte < 128)
$output .= $input[$i];
}
}
return '"' . $output . '"';
}
return '"' . $input . '"';
}
function _utf82utf16($utf8) {
if (function_exists('mb_convert_encoding'))
return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
switch (strlen($utf8)) {
case 1:
return $utf8;
case 2:
return chr(0x07 & (ord($utf8[0]) >> 2)) . chr((0xC0 & (ord($utf8[0]) << 6)) | (0x3F & ord($utf8[1])));
case 3:
return chr((0xF0 & (ord($utf8[0]) << 4)) | (0x0F & (ord($utf8[1]) >> 2))) . chr((0xC0 & (ord($utf8[1]) << 6)) | (0x7F & ord($utf8[2])));
}
return '';
}
function _encodeArray($input) {
$output = '';
$isIndexed = true;
$keys = array_keys($input);
for ($i=0; $i<count($keys); $i++) {
if (!is_int($keys[$i])) {
$output .= $this->encodeString($keys[$i]) . ':' . $this->encode($input[$keys[$i]]);
$isIndexed = false;
} else
$output .= $this->encode($input[$keys[$i]]);
if ($i != count($keys) - 1)
$output .= ',';
}
return $isIndexed ? '[' . $output . ']' : '{' . $output . '}';
}
}
?>

View File

@ -1,268 +0,0 @@
<?php
/**
* $Id: Logger.class.php 10 2007-05-27 10:55:12Z spocke $
*
* @package MCFileManager.filesystems
* @author Moxiecode
* @copyright Copyright © 2005, Moxiecode Systems AB, All rights reserved.
*/
// File type contstants
define('MC_LOGGER_DEBUG', 0);
define('MC_LOGGER_INFO', 10);
define('MC_LOGGER_WARN', 20);
define('MC_LOGGER_ERROR', 30);
define('MC_LOGGER_FATAL', 40);
/**
* Logging utility class. This class handles basic logging with levels, log rotation and custom log formats. It's
* designed to be compact but still powerful and flexible.
*/
class Moxiecode_Logger {
// Private fields
var $_path;
var $_filename;
var $_maxSize;
var $_maxFiles;
var $_maxSizeBytes;
var $_level;
var $_format;
/**
* Constructs a new logger instance.
*/
function Moxiecode_Logger() {
$this->_path = "";
$this->_filename = "{level}.log";
$this->setMaxSize("100k");
$this->_maxFiles = 10;
$this->_level = MC_LOGGER_DEBUG;
$this->_format = "[{time}] [{level}] {message}";
}
/**
* Sets the current log level, use the MC_LOGGER constants.
*
* @param int $level Log level instance for example MC_LOGGER_DEBUG.
*/
function setLevel($level) {
if (is_string($level)) {
switch (strtolower($level)) {
case "debug":
$level = MC_LOGGER_DEBUG;
break;
case "info":
$level = MC_LOGGER_INFO;
break;
case "warn":
case "warning":
$level = MC_LOGGER_WARN;
break;
case "error":
$level = MC_LOGGER_ERROR;
break;
case "fatal":
$level = MC_LOGGER_FATAL;
break;
default:
$level = MC_LOGGER_FATAL;
}
}
$this->_level = $level;
}
/**
* Returns the current log level for example MC_LOGGER_DEBUG.
*
* @return int Current log level for example MC_LOGGER_DEBUG.
*/
function getLevel() {
return $this->_level;
}
function setPath($path) {
$this->_path = $path;
}
function getPath() {
return $this->_path;
}
function setFileName($file_name) {
$this->_filename = $file_name;
}
function getFileName() {
return $this->_filename;
}
function setFormat($format) {
$this->_format = $format;
}
function getFormat() {
return $this->_format;
}
function setMaxSize($size) {
// Fix log max size
$logMaxSizeBytes = intval(preg_replace("/[^0-9]/", "", $size));
// Is KB
if (strpos((strtolower($size)), "k") > 0)
$logMaxSizeBytes *= 1024;
// Is MB
if (strpos((strtolower($size)), "m") > 0)
$logMaxSizeBytes *= (1024 * 1024);
$this->_maxSizeBytes = $logMaxSizeBytes;
$this->_maxSize = $size;
}
function getMaxSize() {
return $this->_maxSize;
}
function setMaxFiles($max_files) {
$this->_maxFiles = $max_files;
}
function getMaxFiles() {
return $this->_maxFiles;
}
function debug($msg) {
$args = func_get_args();
$this->_logMsg(MC_LOGGER_DEBUG, implode(', ', $args));
}
function info($msg) {
$args = func_get_args();
$this->_logMsg(MC_LOGGER_INFO, implode(', ', $args));
}
function warn($msg) {
$args = func_get_args();
$this->_logMsg(MC_LOGGER_WARN, implode(', ', $args));
}
function error($msg) {
$args = func_get_args();
$this->_logMsg(MC_LOGGER_ERROR, implode(', ', $args));
}
function fatal($msg) {
$args = func_get_args();
$this->_logMsg(MC_LOGGER_FATAL, implode(', ', $args));
}
function isDebugEnabled() {
return $this->_level >= MC_LOGGER_DEBUG;
}
function isInfoEnabled() {
return $this->_level >= MC_LOGGER_INFO;
}
function isWarnEnabled() {
return $this->_level >= MC_LOGGER_WARN;
}
function isErrorEnabled() {
return $this->_level >= MC_LOGGER_ERROR;
}
function isFatalEnabled() {
return $this->_level >= MC_LOGGER_FATAL;
}
function _logMsg($level, $message) {
$roll = false;
if ($level < $this->_level)
return;
$logFile = $this->toOSPath($this->_path . "/" . $this->_filename);
switch ($level) {
case MC_LOGGER_DEBUG:
$levelName = "DEBUG";
break;
case MC_LOGGER_INFO:
$levelName = "INFO";
break;
case MC_LOGGER_WARN:
$levelName = "WARN";
break;
case MC_LOGGER_ERROR:
$levelName = "ERROR";
break;
case MC_LOGGER_FATAL:
$levelName = "FATAL";
break;
}
$logFile = str_replace('{level}', strtolower($levelName), $logFile);
$text = $this->_format;
$text = str_replace('{time}', date("Y-m-d H:i:s"), $text);
$text = str_replace('{level}', strtolower($levelName), $text);
$text = str_replace('{message}', $message, $text);
$message = $text . "\r\n";
// Check filesize
if (file_exists($logFile)) {
$size = @filesize($logFile);
if ($size + strlen($message) > $this->_maxSizeBytes)
$roll = true;
}
// Roll if the size is right
if ($roll) {
for ($i=$this->_maxFiles-1; $i>=1; $i--) {
$rfile = $this->toOSPath($logFile . "." . $i);
$nfile = $this->toOSPath($logFile . "." . ($i+1));
if (@file_exists($rfile))
@rename($rfile, $nfile);
}
@rename($logFile, $this->toOSPath($logFile . ".1"));
// Delete last logfile
$delfile = $this->toOSPath($logFile . "." . ($this->_maxFiles + 1));
if (@file_exists($delfile))
@unlink($delfile);
}
// Append log line
if (($fp = @fopen($logFile, "a")) != null) {
@fputs($fp, $message);
@fflush($fp);
@fclose($fp);
}
}
/**
* Converts a Unix path to OS specific path.
*
* @param String $path Unix path to convert.
*/
function toOSPath($path) {
return str_replace("/", DIRECTORY_SEPARATOR, $path);
}
}
?>

View File

@ -1,27 +0,0 @@
<?php
/**
* config.php
*
* @package MCManager.includes
*/
// General settings
// $config['general.engine'] = 'GoogleSpell';
//$config['general.engine'] = 'PSpell';
//$config['general.engine'] = 'PSpellShell';
//$config['general.remote_rpc_url'] = 'http://some.other.site/some/url/rpc.php';
// PSpell settings
$config['PSpell.mode'] = PSPELL_FAST;
$config['PSpell.spelling'] = "";
$config['PSpell.jargon'] = "";
$config['PSpell.encoding'] = "";
// PSpellShell settings
$config['PSpellShell.mode'] = PSPELL_FAST;
$config['PSpellShell.aspell'] = '/usr/bin/aspell';
$config['PSpellShell.tmp'] = '/tmp';
// Windows PSpellShell settings
//$config['PSpellShell.aspell'] = '"c:\Program Files\Aspell\bin\aspell.exe"';
//$config['PSpellShell.tmp'] = 'c:/temp';
?>

View File

@ -1,98 +0,0 @@
<?php
/**
* general.php
*
* @package MCManager.includes
* @author Moxiecode
* @copyright Copyright © 2007, Moxiecode Systems AB, All rights reserved.
*/
@error_reporting(E_ALL ^ E_NOTICE);
$config = array();
require_once(dirname(__FILE__) . "/../classes/utils/Logger.php");
require_once(dirname(__FILE__) . "/../classes/utils/JSON.php");
require_once(dirname(__FILE__) . "/../config.php");
require_once(dirname(__FILE__) . "/../classes/SpellChecker.php");
if (isset($config['general.engine']))
require_once(dirname(__FILE__) . "/../classes/" . $config["general.engine"] . ".php");
/**
* Returns an request value by name without magic quoting.
*
* @param String $name Name of parameter to get.
* @param String $default_value Default value to return if value not found.
* @return String request value by name without magic quoting or default value.
*/
function getRequestParam($name, $default_value = false) {
if (!isset($_REQUEST[$name]))
return $default_value;
if (is_array($_REQUEST[$name])) {
$newarray = array();
foreach ($_REQUEST[$name] as $name => $value)
$newarray[$name] = $value;
return $newarray;
}
return $_REQUEST[$name];
}
function &getLogger() {
global $mcLogger, $man;
if (isset($man))
$mcLogger = $man->getLogger();
if (!$mcLogger) {
$mcLogger = new Moxiecode_Logger();
// Set logger options
$mcLogger->setPath(dirname(__FILE__) . "/../logs");
$mcLogger->setMaxSize("100kb");
$mcLogger->setMaxFiles("10");
$mcLogger->setFormat("{time} - {message}");
}
return $mcLogger;
}
function debug($msg) {
$args = func_get_args();
$log = getLogger();
$log->debug(implode(', ', $args));
}
function info($msg) {
$args = func_get_args();
$log = getLogger();
$log->info(implode(', ', $args));
}
function error($msg) {
$args = func_get_args();
$log = getLogger();
$log->error(implode(', ', $args));
}
function warn($msg) {
$args = func_get_args();
$log = getLogger();
$log->warn(implode(', ', $args));
}
function fatal($msg) {
$args = func_get_args();
$log = getLogger();
$log->fatal(implode(', ', $args));
}
?>

View File

@ -1,672 +0,0 @@
/**
* Compiled inline version. (Library mode)
*/
/*jshint smarttabs:true, undef:true, latedef:true, curly:true, bitwise:true, camelcase:true */
/*globals $code */
(function(exports, undefined) {
"use strict";
var modules = {};
function require(ids, callback) {
var module, defs = [];
for (var i = 0; i < ids.length; ++i) {
module = modules[ids[i]] || resolve(ids[i]);
if (!module) {
throw 'module definition dependecy not found: ' + ids[i];
}
defs.push(module);
}
callback.apply(null, defs);
}
function define(id, dependencies, definition) {
if (typeof id !== 'string') {
throw 'invalid module definition, module id must be defined and be a string';
}
if (dependencies === undefined) {
throw 'invalid module definition, dependencies must be specified';
}
if (definition === undefined) {
throw 'invalid module definition, definition function must be specified';
}
require(dependencies, function() {
modules[id] = definition.apply(null, arguments);
});
}
function defined(id) {
return !!modules[id];
}
function resolve(id) {
var target = exports;
var fragments = id.split(/[.\/]/);
for (var fi = 0; fi < fragments.length; ++fi) {
if (!target[fragments[fi]]) {
return;
}
target = target[fragments[fi]];
}
return target;
}
function expose(ids) {
for (var i = 0; i < ids.length; i++) {
var target = exports;
var id = ids[i];
var fragments = id.split(/[.\/]/);
for (var fi = 0; fi < fragments.length - 1; ++fi) {
if (target[fragments[fi]] === undefined) {
target[fragments[fi]] = {};
}
target = target[fragments[fi]];
}
target[fragments[fragments.length - 1]] = modules[id];
}
}
// Included from: js/tinymce/plugins/spellchecker/classes/DomTextMatcher.js
/**
* DomTextMatcher.js
*
* Copyright, Moxiecode Systems AB
* Released under LGPL License.
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
/**
* This class logic for filtering text and matching words.
*
* @class tinymce.spellcheckerplugin.TextFilter
* @private
*/
define("tinymce/spellcheckerplugin/DomTextMatcher", [], function() {
// Based on work developed by: James Padolsey http://james.padolsey.com
// released under UNLICENSE that is compatible with LGPL
// TODO: Handle contentEditable edgecase:
// <p>text<span contentEditable="false">text<span contentEditable="true">text</span>text</span>text</p>
return function(regex, node, schema) {
var m, matches = [], text, count = 0, doc;
var blockElementsMap, hiddenTextElementsMap, shortEndedElementsMap;
doc = node.ownerDocument;
blockElementsMap = schema.getBlockElements(); // H1-H6, P, TD etc
hiddenTextElementsMap = schema.getWhiteSpaceElements(); // TEXTAREA, PRE, STYLE, SCRIPT
shortEndedElementsMap = schema.getShortEndedElements(); // BR, IMG, INPUT
function getMatchIndexes(m) {
if (!m[0]) {
throw 'findAndReplaceDOMText cannot handle zero-length matches';
}
var index = m.index;
return [index, index + m[0].length, [m[0]]];
}
function getText(node) {
var txt;
if (node.nodeType === 3) {
return node.data;
}
if (hiddenTextElementsMap[node.nodeName] && !blockElementsMap[node.nodeName]) {
return '';
}
txt = '';
if (blockElementsMap[node.nodeName] || shortEndedElementsMap[node.nodeName]) {
txt += '\n';
}
if ((node = node.firstChild)) {
do {
txt += getText(node);
} while ((node = node.nextSibling));
}
return txt;
}
function stepThroughMatches(node, matches, replaceFn) {
var startNode, endNode, startNodeIndex,
endNodeIndex, innerNodes = [], atIndex = 0, curNode = node,
matchLocation = matches.shift(), matchIndex = 0;
out: while (true) {
if (blockElementsMap[curNode.nodeName] || shortEndedElementsMap[curNode.nodeName]) {
atIndex++;
}
if (curNode.nodeType === 3) {
if (!endNode && curNode.length + atIndex >= matchLocation[1]) {
// We've found the ending
endNode = curNode;
endNodeIndex = matchLocation[1] - atIndex;
} else if (startNode) {
// Intersecting node
innerNodes.push(curNode);
}
if (!startNode && curNode.length + atIndex > matchLocation[0]) {
// We've found the match start
startNode = curNode;
startNodeIndex = matchLocation[0] - atIndex;
}
atIndex += curNode.length;
}
if (startNode && endNode) {
curNode = replaceFn({
startNode: startNode,
startNodeIndex: startNodeIndex,
endNode: endNode,
endNodeIndex: endNodeIndex,
innerNodes: innerNodes,
match: matchLocation[2],
matchIndex: matchIndex
});
// replaceFn has to return the node that replaced the endNode
// and then we step back so we can continue from the end of the
// match:
atIndex -= (endNode.length - endNodeIndex);
startNode = null;
endNode = null;
innerNodes = [];
matchLocation = matches.shift();
matchIndex++;
if (!matchLocation) {
break; // no more matches
}
} else if ((!hiddenTextElementsMap[curNode.nodeName] || blockElementsMap[curNode.nodeName]) && curNode.firstChild) {
// Move down
curNode = curNode.firstChild;
continue;
} else if (curNode.nextSibling) {
// Move forward:
curNode = curNode.nextSibling;
continue;
}
// Move forward or up:
while (true) {
if (curNode.nextSibling) {
curNode = curNode.nextSibling;
break;
} else if (curNode.parentNode !== node) {
curNode = curNode.parentNode;
} else {
break out;
}
}
}
}
/**
* Generates the actual replaceFn which splits up text nodes
* and inserts the replacement element.
*/
function genReplacer(nodeName) {
var makeReplacementNode;
if (typeof nodeName != 'function') {
var stencilNode = nodeName.nodeType ? nodeName : doc.createElement(nodeName);
makeReplacementNode = function(fill, matchIndex) {
var clone = stencilNode.cloneNode(false);
clone.setAttribute('data-mce-index', matchIndex);
if (fill) {
clone.appendChild(doc.createTextNode(fill));
}
return clone;
};
} else {
makeReplacementNode = nodeName;
}
return function replace(range) {
var before, after, parentNode, startNode = range.startNode,
endNode = range.endNode, matchIndex = range.matchIndex;
if (startNode === endNode) {
var node = startNode;
parentNode = node.parentNode;
if (range.startNodeIndex > 0) {
// Add `before` text node (before the match)
before = doc.createTextNode(node.data.substring(0, range.startNodeIndex));
parentNode.insertBefore(before, node);
}
// Create the replacement node:
var el = makeReplacementNode(range.match[0], matchIndex);
parentNode.insertBefore(el, node);
if (range.endNodeIndex < node.length) {
// Add `after` text node (after the match)
after = doc.createTextNode(node.data.substring(range.endNodeIndex));
parentNode.insertBefore(after, node);
}
node.parentNode.removeChild(node);
return el;
} else {
// Replace startNode -> [innerNodes...] -> endNode (in that order)
before = doc.createTextNode(startNode.data.substring(0, range.startNodeIndex));
after = doc.createTextNode(endNode.data.substring(range.endNodeIndex));
var elA = makeReplacementNode(startNode.data.substring(range.startNodeIndex), matchIndex);
var innerEls = [];
for (var i = 0, l = range.innerNodes.length; i < l; ++i) {
var innerNode = range.innerNodes[i];
var innerEl = makeReplacementNode(innerNode.data, matchIndex);
innerNode.parentNode.replaceChild(innerEl, innerNode);
innerEls.push(innerEl);
}
var elB = makeReplacementNode(endNode.data.substring(0, range.endNodeIndex), matchIndex);
parentNode = startNode.parentNode;
parentNode.insertBefore(before, startNode);
parentNode.insertBefore(elA, startNode);
parentNode.removeChild(startNode);
parentNode = endNode.parentNode;
parentNode.insertBefore(elB, endNode);
parentNode.insertBefore(after, endNode);
parentNode.removeChild(endNode);
return elB;
}
};
}
text = getText(node);
if (text && regex.global) {
while ((m = regex.exec(text))) {
matches.push(getMatchIndexes(m));
}
}
function filter(callback) {
var filteredMatches = [];
each(function(match, i) {
if (callback(match, i)) {
filteredMatches.push(match);
}
});
matches = filteredMatches;
/*jshint validthis:true*/
return this;
}
function each(callback) {
for (var i = 0, l = matches.length; i < l; i++) {
if (callback(matches[i], i) === false) {
break;
}
}
/*jshint validthis:true*/
return this;
}
function mark(replacementNode) {
if (matches.length) {
count = matches.length;
stepThroughMatches(node, matches, genReplacer(replacementNode));
}
/*jshint validthis:true*/
return this;
}
return {
text: text,
count: count,
matches: matches,
each: each,
filter: filter,
mark: mark
};
};
});
// Included from: js/tinymce/plugins/spellchecker/classes/Plugin.js
/**
* Plugin.js
*
* Copyright, Moxiecode Systems AB
* Released under LGPL License.
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
/*jshint camelcase:false */
/**
* This class contains all core logic for the spellchecker plugin.
*
* @class tinymce.spellcheckerplugin.Plugin
* @private
*/
define("tinymce/spellcheckerplugin/Plugin", [
"tinymce/spellcheckerplugin/DomTextMatcher",
"tinymce/PluginManager",
"tinymce/util/Tools",
"tinymce/ui/Menu",
"tinymce/dom/DOMUtils",
"tinymce/util/JSONRequest",
"tinymce/util/URI"
], function(DomTextMatcher, PluginManager, Tools, Menu, DOMUtils, JSONRequest, URI) {
PluginManager.add('spellchecker', function(editor, url) {
var lastSuggestions, started, suggestionsMenu, settings = editor.settings;
function isEmpty(obj) {
/*jshint unused:false*/
for (var name in obj) {
return false;
}
return true;
}
function showSuggestions(target, word) {
var items = [], suggestions = lastSuggestions[word];
Tools.each(suggestions, function(suggestion) {
items.push({
text: suggestion,
onclick: function() {
editor.insertContent(suggestion);
checkIfFinished();
}
});
});
items.push.apply(items, [
{text: '-'},
{text: 'Ignore', onclick: function() {
ignoreWord(target, word);
}},
{text: 'Ignore all', onclick: function() {
ignoreWord(target, word, true);
}},
{text: 'Finish', onclick: finish}
]);
// Render menu
suggestionsMenu = new Menu({
items: items,
context: 'contextmenu',
onautohide: function(e) {
if (e.target.className.indexOf('spellchecker') != -1) {
e.preventDefault();
}
},
onhide: function() {
suggestionsMenu.remove();
suggestionsMenu = null;
}
});
suggestionsMenu.renderTo(document.body);
// Position menu
var pos = DOMUtils.DOM.getPos(editor.getContentAreaContainer());
var targetPos = editor.dom.getPos(target);
pos.x += targetPos.x;
pos.y += targetPos.y;
suggestionsMenu.moveTo(pos.x, pos.y + target.offsetHeight);
}
function spellcheck() {
var textFilter, words = [], uniqueWords = {};
if (started) {
finish();
return;
}
started = true;
function doneCallback(suggestions) {
editor.setProgressState(false);
if (isEmpty(suggestions)) {
editor.windowManager.alert('No misspellings found');
started = false;
return;
}
lastSuggestions = suggestions;
textFilter.filter(function(match) {
return !!suggestions[match[2][0]];
}).mark(editor.dom.create('span', {
"class": 'mce-spellchecker-word',
"data-mce-bogus": 1
}));
textFilter = null;
editor.fire('SpellcheckStart');
}
// Regexp for finding word specific characters this will split words by
// spaces, quotes, copy right characters etc. It's escaped with unicode characters
// to make it easier to output scripts on servers using different encodings
// so if you add any characters outside the 128 byte range make sure to escape it
var nonWordSeparatorCharacters = editor.getParam('spellchecker_wordchar_pattern') || new RegExp("[^" +
"\\s!\"#$%&()*+,-./:;<=>?@[\\]^_{|}`" +
"\u00a7\u00a9\u00ab\u00ae\u00b1\u00b6\u00b7\u00b8\u00bb" +
"\u00bc\u00bd\u00be\u00bf\u00d7\u00f7\u00a4\u201d\u201c\u201e" +
"]+", "g");
// Find all words and make an unique words array
textFilter = new DomTextMatcher(nonWordSeparatorCharacters, editor.getBody(), editor.schema).each(function(match) {
var word = match[2][0];
// TODO: Fix so it remembers correctly spelled words
if (!uniqueWords[word]) {
// Ignore numbers and single character words
if (/^\d+$/.test(word) || word.length == 1) {
return;
}
words.push(word);
uniqueWords[word] = true;
}
});
function defaultSpellcheckCallback(method, words, doneCallback) {
JSONRequest.sendRPC({
url: new URI(url).toAbsolute(settings.spellchecker_rpc_url),
method: method,
params: {
lang: settings.spellchecker_language || "en",
words: words
},
success: function(result) {
doneCallback(result);
},
error: function(error, xhr) {
if (error == "JSON Parse error.") {
error = "Non JSON response:" + xhr.responseText;
} else {
error = "Error: " + error;
}
editor.windowManager.alert(error);
editor.setProgressState(false);
textFilter = null;
started = false;
}
});
}
editor.setProgressState(true);
var spellCheckCallback = settings.spellchecker_callback || defaultSpellcheckCallback;
spellCheckCallback("spellcheck", words, doneCallback);
}
function checkIfFinished() {
if (!editor.dom.select('span.mce-spellchecker-word').length) {
finish();
}
}
function unwrap(node) {
var parentNode = node.parentNode;
parentNode.insertBefore(node.firstChild, node);
node.parentNode.removeChild(node);
}
function ignoreWord(target, word, all) {
if (all) {
Tools.each(editor.dom.select('span.mce-spellchecker-word'), function(item) {
var text = item.innerText || item.textContent;
if (text == word) {
unwrap(item);
}
});
} else {
unwrap(target);
}
checkIfFinished();
}
function finish() {
var i, nodes, node;
started = false;
node = editor.getBody();
nodes = node.getElementsByTagName('span');
i = nodes.length;
while (i--) {
node = nodes[i];
if (node.getAttribute('data-mce-index')) {
unwrap(node);
}
}
editor.fire('SpellcheckEnd');
}
function selectMatch(index) {
var nodes, i, spanElm, spanIndex = -1, startContainer, endContainer;
index = "" + index;
nodes = editor.getBody().getElementsByTagName("span");
for (i = 0; i < nodes.length; i++) {
spanElm = nodes[i];
if (spanElm.className == "mce-spellchecker-word") {
spanIndex = spanElm.getAttribute('data-mce-index');
if (spanIndex === index) {
spanIndex = index;
if (!startContainer) {
startContainer = spanElm.firstChild;
}
endContainer = spanElm.firstChild;
}
if (spanIndex !== index && endContainer) {
break;
}
}
}
var rng = editor.dom.createRng();
rng.setStart(startContainer, 0);
rng.setEnd(endContainer, endContainer.length);
editor.selection.setRng(rng);
return rng;
}
editor.on('click', function(e) {
if (e.target.className == "mce-spellchecker-word") {
e.preventDefault();
var rng = selectMatch(e.target.getAttribute('data-mce-index'));
showSuggestions(e.target, rng.toString());
}
});
editor.addMenuItem('spellchecker', {
text: 'Spellcheck',
context: 'tools',
onclick: spellcheck,
selectable: true,
onPostRender: function() {
var self = this;
editor.on('SpellcheckStart SpellcheckEnd', function() {
self.active(started);
});
}
});
editor.addButton('spellchecker', {
tooltip: 'Spellcheck',
onclick: spellcheck,
onPostRender: function() {
var self = this;
editor.on('SpellcheckStart SpellcheckEnd', function() {
self.active(started);
});
}
});
editor.on('remove', function() {
if (suggestionsMenu) {
suggestionsMenu.remove();
suggestionsMenu = null;
}
});
});
});
expose(["tinymce/spellcheckerplugin/DomTextMatcher","tinymce/spellcheckerplugin/Plugin"]);
})(this);

File diff suppressed because one or more lines are too long

View File

@ -1,113 +0,0 @@
<?php
/**
* $Id: rpc.php 915 2008-09-03 08:45:28Z spocke $
*
* @package MCManager.includes
* @author Moxiecode
* @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved.
*/
require_once("./includes/general.php");
// Set RPC response headers
header('Content-Type: text/plain');
header('Content-Encoding: UTF-8');
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
$raw = "";
// Try param
if (isset($_POST["json_data"]))
$raw = getRequestParam("json_data");
// Try globals array
if (!$raw && isset($_GLOBALS) && isset($_GLOBALS["HTTP_RAW_POST_DATA"]))
$raw = $_GLOBALS["HTTP_RAW_POST_DATA"];
// Try globals variable
if (!$raw && isset($HTTP_RAW_POST_DATA))
$raw = $HTTP_RAW_POST_DATA;
// Try stream
if (!$raw) {
if (!function_exists('file_get_contents')) {
$fp = fopen("php://input", "r");
if ($fp) {
$raw = "";
while (!feof($fp))
$raw = fread($fp, 1024);
fclose($fp);
}
} else
$raw = "" . file_get_contents("php://input");
}
// No input data
if (!$raw)
die('{"result":null,"id":null,"error":{"errstr":"Could not get raw post data.","errfile":"","errline":null,"errcontext":"","level":"FATAL"}}');
// Passthrough request to remote server
if (isset($config['general.remote_rpc_url'])) {
$url = parse_url($config['general.remote_rpc_url']);
// Setup request
$req = "POST " . $url["path"] . " HTTP/1.0\r\n";
$req .= "Connection: close\r\n";
$req .= "Host: " . $url['host'] . "\r\n";
$req .= "Content-Length: " . strlen($raw) . "\r\n";
$req .= "\r\n" . $raw;
if (!isset($url['port']) || !$url['port'])
$url['port'] = 80;
$errno = $errstr = "";
$socket = fsockopen($url['host'], intval($url['port']), $errno, $errstr, 30);
if ($socket) {
// Send request headers
fputs($socket, $req);
// Read response headers and data
$resp = "";
while (!feof($socket))
$resp .= fgets($socket, 4096);
fclose($socket);
// Split response header/data
$resp = explode("\r\n\r\n", $resp);
echo $resp[1]; // Output body
}
die();
}
// Get JSON data
$json = new Moxiecode_JSON();
$input = $json->decode($raw);
// Execute RPC
if (isset($config['general.engine'])) {
$spellchecker = new $config['general.engine']($config);
$result = call_user_func_array(array($spellchecker, $input['method']), $input['params']);
} else {
// die('{"result":null,"id":null,"error":{"errstr":"You must choose an spellchecker engine in the config.php file.","errfile":"","errline":null,"errcontext":"","level":"FATAL"}}');
die('{"error":"You must choose spellchecker engine in the config.php file."}');
}
// Request and response id should always be the same
$output = array(
"id" => $input->id,
"result" => $result,
"error" => null
);
// Return JSON encoded string
echo $json->encode($output);
?>