diff --git a/phpgwapi/inc/class.html.inc.php b/phpgwapi/inc/class.html.inc.php index ce7942bc8d..820098ba0d 100644 --- a/phpgwapi/inc/class.html.inc.php +++ b/phpgwapi/inc/class.html.inc.php @@ -598,7 +598,11 @@ class html static function &initCKEditor($_height, $_mode) { include_once(EGW_INCLUDE_ROOT."/phpgwapi/js/ckeditor3/ckeditor_php5.php"); - + // use the lang and country information to construct a possible lang info for CKEditor UI and scayt_slang + $lang = ($GLOBALS['egw_info']['user']['preferences']['common']['spellchecker_lang'] ? $GLOBALS['egw_info']['user']['preferences']['common']['spellchecker_lang']: $GLOBALS['egw_info']['user']['preferences']['common']['lang']); + $country = $GLOBALS['egw_info']['user']['preferences']['common']['country']; + if (!(strpos($lang,'-')===false)) list($lang,$country) = explode('-',$lang); + //Get the ckeditor base url $basePath = $GLOBALS['egw_info']['server']['webserver_url'].'/phpgwapi/js/ckeditor3/'; @@ -606,7 +610,7 @@ class html $oCKeditor->returnOutput = true; $oCKeditor->config['customConfig'] = 'ckeditor.egwconfig.js'; - + $oCKeditor->config['language'] = $lang; $oCKeditor->config['resize_enabled'] = false; //switching the encoding as html entities off, as we correctly handle charsets and it messes up the wiki totally $oCKeditor->config['entities'] = true; @@ -626,14 +630,20 @@ class html $oCKeditor->config['toolbarStartupExpanded'] = false; // Now setting the admin settings -/* $spell = ''; + $spell = ''; if (isset($GLOBALS['egw_info']['server']['enabled_spellcheck'])) { $spell = '_spellcheck'; - $oFCKeditor->Config['SpellChecker'] = 'SpellerPages'; - $oFCKeditor->Config['SpellerPagesServerScript'] = 'server-scripts/spellchecker.php?'.$extra; - $oFCKeditor->Config['FirefoxSpellChecker'] = false; - }*/ + if (!empty($GLOBALS['egw_info']['server']['aspell_path']) && + is_executable($GLOBALS['egw_info']['server']['aspell_path'])) + { + $spell = '_aspell'; + $oCKeditor->config['extraPlugins'] = 'aspell'; + } + $oCKeditor->config['scayt_autoStartup']=true; + $oCKeditor->config['scayt_sLang']=$lang.'_'.strtoupper($country); + } + $oCKeditor->config['disableNativeSpellChecker'] = true; // Now setting the user preferences if (isset($GLOBALS['egw_info']['user']['preferences']['common']['rte_enter_mode'])) @@ -675,20 +685,18 @@ class html $oCKeditor->config['skin'] = $skin; - //$oCKeditor->config['spellchecker'] = 'SpellCheck'; - switch($_mode) { case 'simple': - $oCKeditor->config['toolbar'] = 'egw_simple'; + $oCKeditor->config['toolbar'] = 'egw_simple'.$spell; $oCKeditor->config['menu_groups'] = ''; break; default: case 'extended': - $oCKeditor->config['toolbar'] = 'egw_extended'; + $oCKeditor->config['toolbar'] = 'egw_extended'.$spell; break; case 'advanced': - $oCKeditor->config['toolbar'] = 'egw_advanced'; + $oCKeditor->config['toolbar'] = 'egw_advanced'.$spell; break; } return $oCKeditor; diff --git a/phpgwapi/js/ckeditor3/ckeditor.egwconfig.js b/phpgwapi/js/ckeditor3/ckeditor.egwconfig.js index f638814842..c9c49509da 100644 --- a/phpgwapi/js/ckeditor3/ckeditor.egwconfig.js +++ b/phpgwapi/js/ckeditor3/ckeditor.egwconfig.js @@ -14,6 +14,18 @@ CKEDITOR.editorConfig = function( config ) ] ; config.toolbar_egw_simple_spellcheck = [ + ['Bold','Italic','Underline'], + ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'], + ['BulletList','NumberedList','Outdent','Indent','Undo','Redo'], + ['Cut','Copy','Paste','PasteText','PasteFromWord','-','Print'], + ['Maximize','SpellChecker'], + '/', + ['Format','Font','FontSize'], + ['TextColor','BGColor'], + ['ShowBlocks','-','About'] + ] ; + + config.toolbar_egw_simple_aspell = [ ['Bold','Italic','Underline'], ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'], ['BulletList','NumberedList','Outdent','Indent','Undo','Redo'], @@ -25,6 +37,13 @@ CKEDITOR.editorConfig = function( config ) ['ShowBlocks','-','About'] ] ; +// config.toolbar_egw_simple.concat([ +// '/', +// ['Format','Font','FontSize'], +// ['TextColor','BGColor'], +// ['ShowBlocks','-','About'] +// ]); + config.toolbar_egw_extended = [ ['Bold','Italic','Underline'], ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'], @@ -40,6 +59,20 @@ CKEDITOR.editorConfig = function( config ) ] ; config.toolbar_egw_extended_spellcheck = [ + ['Bold','Italic','Underline'], + ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'], + ['BulletList','NumberedList','Outdent','Indent','Undo','Redo'], + ['Cut','Copy','Paste','PasteText','PasteFromWord','-','Print'], + ['Link','Unlink','Anchor'], + ['Find','Replace'], + ['Maximize','SpellChecker','Image','Table'], + '/', + ['Format','Font','FontSize'], + ['TextColor','BGColor'], + ['ShowBlocks','-','About'] + ] ; + + config.toolbar_egw_extended_aspell = [ ['Bold','Italic','Underline'], ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'], ['BulletList','NumberedList','Outdent','Indent','Undo','Redo'], @@ -70,6 +103,22 @@ CKEDITOR.editorConfig = function( config ) ] ; config.toolbar_egw_advanced_spellcheck = [ + ['Source','DocProps','-','Save','NewPage','Preview','-','Templates'], + ['Cut','Copy','Paste','PasteText','PasteFromWord','-','Print','SpellChecker'], + ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'], + '/', + ['Bold','Italic','Underline','Strike','-','Subscript','Superscript'], + ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'], + ['BulletList','NumberedList','-','Outdent','Indent'], + ['Link','Unlink','Anchor'], + ['Maximize','Image',/*'Flash',*/'Table','HorizontalRule',/*'Smiley',*/'SpecialChar','PageBreak'], //,'UniversalKey' + '/', + ['Style','Format','Font','FontSize'], + ['TextColor','BGColor'], + ['ShowBlocks','-','About'] + ] ; + + config.toolbar_egw_advanced_aspell = [ ['Source','DocProps','-','Save','NewPage','Preview','-','Templates'], ['Cut','Copy','Paste','PasteText','PasteFromWord','-','Print','SpellCheck'], ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'], diff --git a/phpgwapi/js/ckeditor3/egw_integration.txt b/phpgwapi/js/ckeditor3/egw_integration.txt index 8519c8c97b..78c37b5eba 100644 --- a/phpgwapi/js/ckeditor3/egw_integration.txt +++ b/phpgwapi/js/ckeditor3/egw_integration.txt @@ -28,3 +28,10 @@ Index: phpgwapi/js/ckeditor3/ckeditor_php5.php if (is_null($val)) { return 'null'; +--------------- step 3 -------------------------------------- +-added aspell as plugin, as it is not available by default anymore. + phpgwapi/js/ckeditor3/plugins/aspell +-changed phpgwapi/js/ckeditor3/plugins/aspell/spellerpages/server-scripts/spellchecker.php + to allow only configured aspell, tmp dirs and language settings +-removed other than php spellchecker pages from phpgwapi/js/ckeditor3/plugins/aspell/spellerpages/server-scripts/ +-added toolbar options to reflect the use/change of calls of SpellCheck(er) via toolbar button diff --git a/phpgwapi/js/ckeditor3/plugins/aspell/aspell.css b/phpgwapi/js/ckeditor3/plugins/aspell/aspell.css new file mode 100644 index 0000000000..fc68ae235b --- /dev/null +++ b/phpgwapi/js/ckeditor3/plugins/aspell/aspell.css @@ -0,0 +1,6 @@ + +.cke_editor .cke_button_aspell .cke_icon +{ + background-position: 0 -192px !important; +} + diff --git a/phpgwapi/js/ckeditor3/plugins/aspell/dialogs/aspell.js b/phpgwapi/js/ckeditor3/plugins/aspell/dialogs/aspell.js new file mode 100644 index 0000000000..b1f5001e17 --- /dev/null +++ b/phpgwapi/js/ckeditor3/plugins/aspell/dialogs/aspell.js @@ -0,0 +1,170 @@ + +var FCKLang; +var OnSpellerControlsLoad; + +CKEDITOR.dialog.add('aspell', function( editor ) +{ + var number = CKEDITOR.tools.getNextNumber(), + iframeId = 'cke_frame_' + number, + textareaId = 'cke_data_' + number, + interval, + errorMsg = editor.lang.spellCheck.notAvailable; + + var spellHTML = + // Input for exchanging data CK<--->spellcheck + '' + + // Spellcheck iframe + ''; + + function spellTime(dialog, errorMsg) + { + var i = 0; + return function() + { + if (typeof window.spellChecker == 'function') + { + // Call from window.setInteval expected at once. + if (typeof interval != 'undefined') + window.clearInterval(interval); + + // Create spellcheck object, set options/attributes + var oSpeller = new spellChecker(document.getElementById(textareaId)); + oSpeller.spellCheckScript = editor.plugins.aspell.path+'spellerpages/server-scripts/spellchecker.php'; + oSpeller.OnFinished = function (numChanges) { oSpeller_OnFinished(dialog, numChanges) }; + oSpeller.popUpUrl = editor.plugins.aspell.path+'spellerpages/spellchecker.html'; + oSpeller.popUpName = iframeId; + oSpeller.popUpProps = null; + + // Place language in global variable; + // A bit of a hack, but how does e.g. controls.html know which language to use? + FCKLang = {}; + // spellChecker.js + FCKLang.DlgSpellNoChanges = CKEDITOR.lang[editor.langCode].spellCheck.noChanges; + FCKLang.DlgSpellNoMispell = CKEDITOR.lang[editor.langCode].spellCheck.noMispell; + FCKLang.DlgSpellOneChange = CKEDITOR.lang[editor.langCode].spellCheck.oneChange; + FCKLang.DlgSpellManyChanges = CKEDITOR.lang[editor.langCode].spellCheck.manyChanges; + // controls.html + FCKLang.DlgSpellNotInDic = CKEDITOR.lang[editor.langCode].spellCheck.notInDic; + FCKLang.DlgSpellChangeTo = CKEDITOR.lang[editor.langCode].spellCheck.changeTo; + FCKLang.DlgSpellBtnIgnore = CKEDITOR.lang[editor.langCode].spellCheck.btnIgnore; + FCKLang.DlgSpellBtnIgnoreAll = CKEDITOR.lang[editor.langCode].spellCheck.btnIgnoreAll; + FCKLang.DlgSpellBtnReplace = CKEDITOR.lang[editor.langCode].spellCheck.btnReplace; + FCKLang.DlgSpellBtnReplaceAll = CKEDITOR.lang[editor.langCode].spellCheck.btnReplaceAll; + FCKLang.DlgSpellBtnUndo = CKEDITOR.lang[editor.langCode].spellCheck.btnUndo; + // controlWindow.js + FCKLang.DlgSpellNoSuggestions = CKEDITOR.lang[editor.langCode].spellCheck.noSuggestions; + // spellchecker.html + FCKLang.DlgSpellProgress = CKEDITOR.lang[editor.langCode].spellCheck.progress; + // End language + + // Start spellcheck! + oSpeller.openChecker(); + } + else if (i++ == 180) // Timeout: 180 * 250ms = 45s. + { + alert(errorMsg); + dialog.hide(); + } + }; + } + + function oSpeller_OnFinished(dialog, numberOCorrections) + { + if (numberOCorrections > 0) + { + editor.focus(); + editor.fire('saveSnapshot'); // Best way I could find to trigger undo steps. + dialog.getParentEditor().setData(document.getElementById(textareaId).value,function(){ + editor.fire('saveSnapshot'); // But there's a blank one between! + }); + } + dialog.hide(); + } + + // Fx and IE don't see the same sizes, it seems. That or Fx is allowing everything to grow. + var minW = 485; + var minH = 380; + if (document.all) + { + minW = 510; + minH = 405; + } + + return { + title: editor.lang.spellCheck.title, + minWidth: minW, + minHeight: minH, + buttons: [ CKEDITOR.dialog.cancelButton ], + onShow: function() + { + // Put spellcheck input and iframe in the dialog content + var contentArea = this.getContentElement('general', 'content').getElement(); + contentArea.setHtml(spellHTML); + + // Define spellcheck init function + OnSpellerControlsLoad = function (controlsWindow) + { + // Translate the dialog box texts + var spans = controlsWindow.document.getElementsByTagName('span'); + var inputs = controlsWindow.document.getElementsByTagName('input'); + var i, attr; + + for (i=0; i < spans.length; i++) + { + attr = spans[i].getAttribute && spans[i].getAttribute('fckLang'); + if (attr) + spans[i].innerHTML = FCKLang[attr]; + } + for (i=0; i < inputs.length; i++) + { + attr = inputs[i].getAttribute && inputs[i].getAttribute('fckLang'); + if (attr) + inputs[i].value = FCKLang[attr]; + } + } + + // Add spellcheck script to head + CKEDITOR.document.getHead().append(CKEDITOR.document.createElement('script', { + attributes: { + type: 'text/javascript', + src: editor.plugins.aspell.path+'spellerpages/spellChecker.js' + }})); + + // Get the data to be checked. + var sData = editor.getData(); + //CKEDITOR.document.getById(textareaId).setValue(sData); <-- doesn't work for some reason + document.getElementById(textareaId).value = sData; + + // Wait for spellcheck script to load, then execute + interval = window.setInterval(spellTime(this, errorMsg), 250); + }, + onHide: function() + { + window.ooo = undefined; + window.int_framsetLoaded = undefined; + window.framesetLoaded = undefined; + window.is_window_opened = false; + + OnSpellerControlsLoad = null; + FCKLang = null; + }, + contents: [ + { + id: 'general', + label: editor.lang.spellCheck.title, + padding: 0, + elements: [ + { + type: 'html', + id: 'content', + style: 'width:485;height:380px', + html: '
' + } + ] + } + ] + }; +}); diff --git a/phpgwapi/js/ckeditor3/plugins/aspell/plugin.js b/phpgwapi/js/ckeditor3/plugins/aspell/plugin.js new file mode 100644 index 0000000000..6ced98fafe --- /dev/null +++ b/phpgwapi/js/ckeditor3/plugins/aspell/plugin.js @@ -0,0 +1,31 @@ +/** + * Aspell plug-in for CKeditor 3.0 + * Ported from FCKeditor 2.x by Christian Boisjoli, SilenceIT + * Requires toolbar, aspell + */ + +CKEDITOR.plugins.add('aspell', { + init: function (editor) { + // Create dialog-based command named "aspell" + editor.addCommand('aspell', new CKEDITOR.dialogCommand('aspell')); + + // Add button to toolbar. Not sure why only that name works for me. + editor.ui.addButton('SpellCheck', { + label: editor.lang.spellCheck.toolbar, + command: 'aspell' + }); + + // Add link dialog code + CKEDITOR.dialog.add('aspell', this.path + 'dialogs/aspell.js'); + + // Add CSS + var aspellCSS = document.createElement('link'); + aspellCSS.setAttribute( 'rel', 'stylesheet'); + aspellCSS.setAttribute('type', 'text/css'); + aspellCSS.setAttribute('href', this.path+'aspell.css'); + document.getElementsByTagName("head")[0].appendChild(aspellCSS); + delete aspellCSS; + }, + requires: ['toolbar'] +}); + diff --git a/phpgwapi/js/ckeditor3/plugins/aspell/spellerpages/blank.html b/phpgwapi/js/ckeditor3/plugins/aspell/spellerpages/blank.html new file mode 100644 index 0000000000..e69de29bb2 diff --git a/phpgwapi/js/ckeditor3/plugins/aspell/spellerpages/controlWindow.js b/phpgwapi/js/ckeditor3/plugins/aspell/spellerpages/controlWindow.js new file mode 100644 index 0000000000..32ab75989e --- /dev/null +++ b/phpgwapi/js/ckeditor3/plugins/aspell/spellerpages/controlWindow.js @@ -0,0 +1,86 @@ +//////////////////////////////////////////////////// +// controlWindow object +//////////////////////////////////////////////////// +function controlWindow( controlForm ) { + // private properties + this._form = controlForm; + + // public properties + this.windowType = "controlWindow"; + this.noSuggestionSelection = "- No suggestions -"; + // set up the properties for elements of the given control form + this.suggestionList = this._form.sugg; + this.evaluatedText = this._form.misword; + this.replacementText = this._form.txtsugg; + this.undoButton = this._form.btnUndo; + + // public methods + this.addSuggestion = addSuggestion; + this.clearSuggestions = clearSuggestions; + this.selectDefaultSuggestion = selectDefaultSuggestion; + this.resetForm = resetForm; + this.setSuggestedText = setSuggestedText; + this.enableUndo = enableUndo; + this.disableUndo = disableUndo; +} + +function resetForm() { + if( this._form ) { + this._form.reset(); + } +} + +function setSuggestedText() { + var slct = this.suggestionList; + var txt = this.replacementText; + var str = ""; + if( (slct.options[0].text) && slct.options[0].text != this.noSuggestionSelection ) { + str = slct.options[slct.selectedIndex].text; + } + txt.value = str; +} + +function selectDefaultSuggestion() { + var slct = this.suggestionList; + var txt = this.replacementText; + if( slct.options.length == 0 ) { + this.addSuggestion( this.noSuggestionSelection ); + } else { + slct.options[0].selected = true; + } + this.setSuggestedText(); +} + +function addSuggestion( sugg_text ) { + var slct = this.suggestionList; + if( sugg_text ) { + var i = slct.options.length; + var newOption = new Option( sugg_text, 'sugg_text'+i ); + slct.options[i] = newOption; + } +} + +function clearSuggestions() { + var slct = this.suggestionList; + for( var j = slct.length - 1; j > -1; j-- ) { + if( slct.options[j] ) { + slct.options[j] = null; + } + } +} + +function enableUndo() { + if( this.undoButton ) { + if( this.undoButton.disabled == true ) { + this.undoButton.disabled = false; + } + } +} + +function disableUndo() { + if( this.undoButton ) { + if( this.undoButton.disabled == false ) { + this.undoButton.disabled = true; + } + } +} diff --git a/phpgwapi/js/ckeditor3/plugins/aspell/spellerpages/controls.html b/phpgwapi/js/ckeditor3/plugins/aspell/spellerpages/controls.html new file mode 100644 index 0000000000..39c9e68077 --- /dev/null +++ b/phpgwapi/js/ckeditor3/plugins/aspell/spellerpages/controls.html @@ -0,0 +1,153 @@ + + + + + + + + + + diff --git a/phpgwapi/js/ckeditor3/plugins/aspell/spellerpages/server-scripts/spellchecker.php b/phpgwapi/js/ckeditor3/plugins/aspell/spellerpages/server-scripts/spellchecker.php new file mode 100644 index 0000000000..fa063a1329 --- /dev/null +++ b/phpgwapi/js/ckeditor3/plugins/aspell/spellerpages/server-scripts/spellchecker.php @@ -0,0 +1,236 @@ + array( + 'currentapp' => 'home', + 'noheader' => true, + 'autocreate_session_callback' => 'deny_no_egw_session', + ) +); +// will not continue, unless the header get's included and there is a valid eGW session +require('../../../../../../../header.inc.php'); + +if (!empty($GLOBALS['egw_info']['user']['preferences']['common']['spellchecker_lang'])) +{ + $lang = $GLOBALS['egw_info']['user']['preferences']['common']['spellchecker_lang']; +} +else +{ + $lang = $GLOBALS['egw_info']['user']['preferences']['common']['lang']; +} + +$aspell_opts = '-a '.escapeshellarg('--lang='.$lang).' --encoding=utf-8 -H --rem-sgml-check=alt'; // by FredCK + +$tempfiledir = "./"; + +$spellercss = '../spellerStyle.css'; // by FredCK +$word_win_src = '../wordWindow.js'; // by FredCK + +$textinputs = $_POST['textinputs']; # array +$input_separator = "A"; + +# set the JavaScript variable to the submitted text. +# textinputs is an array, each element corresponding to the (url-encoded) +# value of the text control submitted for spell-checking +function print_textinputs_var() { + global $textinputs; + foreach( $textinputs as $key=>$val ) { + # $val = str_replace( "'", "%27", $val ); + echo "textinputs[$key] = decodeURIComponent(\"" . $val . "\");\n"; + } +} + +# make declarations for the text input index +function print_textindex_decl( $text_input_idx ) { + echo "words[$text_input_idx] = [];\n"; + echo "suggs[$text_input_idx] = [];\n"; +} + +# set an element of the JavaScript 'words' array to a misspelled word +function print_words_elem( $word, $index, $text_input_idx ) { + echo "words[$text_input_idx][$index] = '" . escape_quote( $word ) . "';\n"; +} + + +# set an element of the JavaScript 'suggs' array to a list of suggestions +function print_suggs_elem( $suggs, $index, $text_input_idx ) { + echo "suggs[$text_input_idx][$index] = ["; + foreach( $suggs as $key=>$val ) { + if( $val ) { + echo "'" . escape_quote( $val ) . "'"; + if ( $key+1 < count( $suggs )) { + echo ", "; + } + } + } + echo "];\n"; +} + +# escape single quote +function escape_quote( $str ) { + return preg_replace ( "/'/", "\\'", $str ); +} + + +# handle a server-side error. +function error_handler( $err ) { + echo "error = '" . preg_replace( "/['\\\\]/", "\\\\$0", $err ) . "';\n"; +} + +## get the list of misspelled words. Put the results in the javascript words array +## for each misspelled word, get suggestions and put in the javascript suggs array +function print_checker_results() { + + global $aspell_prog; + global $aspell_opts; + global $tempfiledir; + global $textinputs; + global $input_separator; + $aspell_err = ""; + if (!empty($GLOBALS['egw_info']['server']['aspell_path']) && + is_executable($GLOBALS['egw_info']['server']['aspell_path'])) + { + $aspell_prog = $GLOBALS['egw_info']['server']['aspell_path']; + } + else // little fallback that might save linux users + { + $aspell_prog = 'aspell'; + } + + # create temp file + // use EGroupware's temp_dir + $tempfile = tempnam( $GLOBALS['egw_info']['server']['temp_dir'], 'aspell_data_' ); + + # open temp file, add the submitted text. + if( $fh = fopen( $tempfile, 'w' )) { + for( $i = 0; $i < count( $textinputs ); $i++ ) { + $text = urldecode( $textinputs[$i] ); + + // Strip all tags for the text. (by FredCK - #339 / #681) + $text = preg_replace( "/<[^>]+>/", " ", $text ) ; + + $lines = explode( "\n", $text ); + fwrite ( $fh, "%\n" ); # exit terse mode + fwrite ( $fh, "^$input_separator\n" ); + fwrite ( $fh, "!\n" ); # enter terse mode + foreach( $lines as $key=>$value ) { + # use carat on each line to escape possible aspell commands + fwrite( $fh, "^$value\n" ); + } + } + fclose( $fh ); + + # exec aspell command - redirect STDERR to STDOUT + $cmd = "$aspell_prog $aspell_opts < $tempfile 2>&1"; + if( $aspellret = shell_exec( $cmd )) { + $linesout = explode( "\n", $aspellret ); + $index = 0; + $text_input_index = -1; + # parse each line of aspell return + foreach( $linesout as $key=>$val ) { + $chardesc = substr( $val, 0, 1 ); + # if '&', then not in dictionary but has suggestions + # if '#', then not in dictionary and no suggestions + # if '*', then it is a delimiter between text inputs + # if '@' then version info + if( $chardesc == '&' || $chardesc == '#' ) { + $line = explode( " ", $val, 5 ); + print_words_elem( $line[1], $index, $text_input_index ); + if( isset( $line[4] )) { + $suggs = explode( ", ", $line[4] ); + } else { + $suggs = array(); + } + print_suggs_elem( $suggs, $index, $text_input_index ); + $index++; + } elseif( $chardesc == '*' ) { + $text_input_index++; + print_textindex_decl( $text_input_index ); + $index = 0; + } elseif( $chardesc != '@' && $chardesc != "" ) { + # assume this is error output + $aspell_err .= $val; + } + } + if( $aspell_err ) { + $aspell_err = "Error executing `$cmd`\\n$aspell_err"; + error_handler( $aspell_err ); + } + } else { + error_handler( "System error: Aspell program execution failed (`$cmd`)" ); + } + } else { + error_handler( "System error: Could not open file '$tempfile' for writing" ); + } + + # close temp file, delete file + unlink( $tempfile ); +} + + +?> + + + + + + + + + + + + + + + diff --git a/phpgwapi/js/ckeditor3/plugins/aspell/spellerpages/spellChecker.js b/phpgwapi/js/ckeditor3/plugins/aspell/spellerpages/spellChecker.js new file mode 100644 index 0000000000..cf22262ba0 --- /dev/null +++ b/phpgwapi/js/ckeditor3/plugins/aspell/spellerpages/spellChecker.js @@ -0,0 +1,461 @@ +//////////////////////////////////////////////////// +// spellChecker.js +// +// spellChecker object +// +// This file is sourced on web pages that have a textarea object to evaluate +// for spelling. It includes the implementation for the spellCheckObject. +// +//////////////////////////////////////////////////// + + +// constructor +function spellChecker( textObject ) { + + // public properties - configurable + this.popUpUrl = '/speller/spellchecker.html'; // by FredCK +// this.popUpUrl = 'fck_spellerpages/spellerpages/spellchecker.html'; // by FredCK + this.popUpName = 'spellchecker'; + this.popUpProps = "menu=no,width=440,height=350,top=70,left=120,resizable=yes,status=yes"; // by FredCK +// this.popUpProps = null ; // by FredCK + this.spellCheckScript = '/speller/server-scripts/spellchecker.php'; // by FredCK + //this.spellCheckScript = '/cgi-bin/spellchecker.pl'; + + // values used to keep track of what happened to a word + this.replWordFlag = "R"; // single replace + this.ignrWordFlag = "I"; // single ignore + this.replAllFlag = "RA"; // replace all occurances + this.ignrAllFlag = "IA"; // ignore all occurances + this.fromReplAll = "~RA"; // an occurance of a "replace all" word + this.fromIgnrAll = "~IA"; // an occurance of a "ignore all" word + // properties set at run time + this.wordFlags = new Array(); + this.currentTextIndex = 0; + this.currentWordIndex = 0; + this.spellCheckerWin = null; + this.controlWin = null; + this.wordWin = null; + this.textArea = textObject; // deprecated + this.textInputs = arguments; + + // private methods + this._spellcheck = _spellcheck; + this._getSuggestions = _getSuggestions; + this._setAsIgnored = _setAsIgnored; + this._getTotalReplaced = _getTotalReplaced; + this._setWordText = _setWordText; + this._getFormInputs = _getFormInputs; + + // public methods + this.openChecker = openChecker; + this.startCheck = startCheck; + this.checkTextBoxes = checkTextBoxes; + this.checkTextAreas = checkTextAreas; + this.spellCheckAll = spellCheckAll; + this.ignoreWord = ignoreWord; + this.ignoreAll = ignoreAll; + this.replaceWord = replaceWord; + this.replaceAll = replaceAll; + this.terminateSpell = terminateSpell; + this.undo = undo; + + // set the current window's "speller" property to the instance of this class. + // this object can now be referenced by child windows/frames. + window.speller = this; +} + +// call this method to check all text boxes (and only text boxes) in the HTML document +function checkTextBoxes() { + this.textInputs = this._getFormInputs( "^text$" ); + this.openChecker(); +} + +// call this method to check all textareas (and only textareas ) in the HTML document +function checkTextAreas() { + this.textInputs = this._getFormInputs( "^textarea$" ); + this.openChecker(); +} + +// call this method to check all text boxes and textareas in the HTML document +function spellCheckAll() { + this.textInputs = this._getFormInputs( "^text(area)?$" ); + this.openChecker(); +} + +// call this method to check text boxe(s) and/or textarea(s) that were passed in to the +// object's constructor or to the textInputs property +function openChecker() { + this.spellCheckerWin = window.open( this.popUpUrl, this.popUpName, this.popUpProps ); + if( !this.spellCheckerWin.opener ) { + this.spellCheckerWin.opener = window; + } +} + +function startCheck( wordWindowObj, controlWindowObj ) { + + // set properties from args + this.wordWin = wordWindowObj; + this.controlWin = controlWindowObj; + + // reset properties + this.wordWin.resetForm(); + this.controlWin.resetForm(); + this.currentTextIndex = 0; + this.currentWordIndex = 0; + // initialize the flags to an array - one element for each text input + this.wordFlags = new Array( this.wordWin.textInputs.length ); + // each element will be an array that keeps track of each word in the text + for( var i=0; i