Index: /FCKeditor/trunk/_dev/lint.conf =================================================================== --- /FCKeditor/trunk/_dev/lint.conf (revision 4227) +++ /FCKeditor/trunk/_dev/lint.conf (revision 4228) @@ -27,5 +27,5 @@ +useless_void # use of the void type may be unnecessary (void is always undefined) +multiple_plus_minus # unknown order of operations for successive plus (e.g. x+++y) or minus (e.g. x---y) signs -+use_of_label # use of label +-use_of_label # use of label -block_without_braces # block statement without curly braces +leading_decimal_point # leading decimal point may indicate a number or an object member Index: /FCKeditor/trunk/_dev/lint.mac.conf =================================================================== --- /FCKeditor/trunk/_dev/lint.mac.conf (revision 4227) +++ /FCKeditor/trunk/_dev/lint.mac.conf (revision 4228) @@ -27,5 +27,5 @@ +useless_void # use of the void type may be unnecessary (void is always undefined) +multiple_plus_minus # unknown order of operations for successive plus (e.g. x+++y) or minus (e.g. x---y) signs -+use_of_label # use of label +-use_of_label # use of label -block_without_braces # block statement without curly braces +leading_decimal_point # leading decimal point may indicate a number or an object member Index: /FCKeditor/trunk/editor/_source/classes/fckpanel.js =================================================================== --- /FCKeditor/trunk/editor/_source/classes/fckpanel.js (revision 4227) +++ /FCKeditor/trunk/editor/_source/classes/fckpanel.js (revision 4228) @@ -234,4 +234,7 @@ } + // Save the popup related arguments so they can be used by others (e.g. SCAYT). + this._PopupArgs = [x, y, iMainWidth, eMainNode.offsetHeight, relElement]; + // Second call: Show the Popup at the specified location, with the correct size. this._Popup.show( x, y, iMainWidth, eMainNode.offsetHeight, relElement ) ; Index: /FCKeditor/trunk/editor/_source/internals/fckcommands.js =================================================================== --- /FCKeditor/trunk/editor/_source/internals/fckcommands.js (revision 4227) +++ /FCKeditor/trunk/editor/_source/internals/fckcommands.js (revision 4228) @@ -143,4 +143,7 @@ case 'Undefined' : oCommand = new FCKUndefinedCommand() ; break ; + case 'Scayt' : oCommand = FCKScayt.CreateCommand() ; break ; + case 'ScaytContext' : oCommand = FCKScayt.CreateContextCommand() ; break ; + // By default we assume that it is a named command. default: Index: /FCKeditor/trunk/editor/_source/internals/fckscayt.js =================================================================== --- /FCKeditor/trunk/editor/_source/internals/fckscayt.js (revision 4228) +++ /FCKeditor/trunk/editor/_source/internals/fckscayt.js (revision 4228) @@ -0,0 +1,408 @@ +/* + * FCKeditor - The text editor for Internet - http://www.fckeditor.net + * Copyright (C) 2003-2009 Frederico Caldeira Knabben + * + * == BEGIN LICENSE == + * + * Licensed under the terms of any of the following licenses at your + * choice: + * + * - GNU General Public License Version 2 or later (the "GPL") + * http://www.gnu.org/licenses/gpl.html + * + * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") + * http://www.gnu.org/licenses/lgpl.html + * + * - Mozilla Public License Version 1.1 or later (the "MPL") + * http://www.mozilla.org/MPL/MPL-1.1.html + * + * == END LICENSE == + */ + +var FCKScayt; + +(function() +{ + var scaytOnLoad = [] ; + var isEngineLoaded = (top.scayt) ? true : false ; + var scaytEnable, scaytReady ; + + function ScaytEngineLoad( callback ) + { + if ( isEngineLoaded ) + return ; + + isEngineLoaded = true ; + + var init = function () + { + scayt = top.scayt ; + InitScayt() ; + var ScaytCombobox = FCKToolbarItems.LoadedItems[ 'ScaytCombobox' ] ; + ScaytCombobox && ScaytCombobox.SetEnabled( scyt_control && scyt_control.disabled) ; + InitSetup() ; + }; + + if ( top.scayt ) + { + init() ; + return ; + } + + // Compose the scayt url. + if (FCK.Config.ScaytCustomUrl) + FCK.Config.ScaytCustomUrl = new String(FCK.Config.ScaytCustomUrl).replace( new RegExp( "^http[s]*:\/\/"),"") ; + + var protocol = document.location.protocol ; + var baseUrl = FCK.Config.ScaytCustomUrl ||'svc.spellchecker.net/spellcheck3/lf/scayt/scayt4.js' ; + var scaytUrl = protocol + '//' + baseUrl ; + var scaytConfigBaseUrl = ParseUrl( scaytUrl ).path + '/' ; + + // SCAYT is targetted to CKEditor, so we need this trick to make it work here. + var CKEDITOR = top.window.CKEDITOR || ( top.window.CKEDITOR = {} ) ; + CKEDITOR._djScaytConfig = + { + baseUrl : scaytConfigBaseUrl, + addOnLoad : function() + { + init(); + }, + isDebug : false + }; + + + if ( callback ) + scaytOnLoad.push( callback ) ; + + DoLoadScript( scaytUrl ) ; + } + + /** + * DoLoadScript - load scripts with dinamic tag script creating + * @param string url + */ + function DoLoadScript( url ) + { + if (!url) + return false ; + + var s = top.document.createElement('script') ; + s.type = 'text/javascript' ; + s.src = url ; + top.document.getElementsByTagName('head')[0].appendChild(s) ; + + return true ; + } + + function ParseUrl( data ) + { + var m = data.match(/(.*)[\/\\]([^\/\\]+\.\w+)$/) ; + return m ? { path: m[1], file: m[2] } : data ; + } + + function InitScayt() + { + // Get public scayt params. + var oParams = {} ; + oParams.srcNodeRef = FCK.EditingArea.IFrame; // Get the iframe. + // syntax : AppName.AppVersion@AppRevision + //oParams.assocApp = "FCKEDITOR." + FCKeditorAPI.Varsion + "@" + FCKeditorAPI.VersionBuild; + oParams.customerid = FCK.Config.ScaytCustomerid ; + oParams.customDictionaryName = FCK.Config.ScaytCustomDictionaryName ; + oParams.userDictionaryName = FCK.Config.ScaytUserDictionaryName ; + oParams.defLang = FCK.Config.ScaytDefLang ; + + var scayt = window.scayt; + var scayt_control = window.scayt_control = new scayt( oParams ) ; + + if ( scayt_control ) + { + scayt_control.setDisabled( false ) ; + scaytReady = true; + scaytEnable = !scayt_control.disabled ; + + // set default scayt status + var ScaytCombobox = FCKToolbarItems.LoadedItems[ 'ScaytCombobox' ] ; + ScaytCombobox && ScaytCombobox.Enable() ; + ShowScaytState() ; + } + + for ( var i = 0 ; i < scaytOnLoad.length ; i++ ) + { + try + { + scaytOnLoad[i].call( this ) ; + } + catch(err) + {} + } + } + + // ### + // SCAYT command class. + var ScaytCommand = function() + { + name = 'Scayt' ; + } + + ScaytCommand.prototype.Execute = function( action ) + { + switch ( action ) + { + case 'Options' : + case 'Langs' : + case 'About' : + if ( isEngineLoaded && scaytReady && !scaytEnable ) + { + ScaytMessage( 'SCAYT is not enabled' ); + break; + } + + if ( isEngineLoaded && scaytReady ) + FCKDialog.OpenDialog( 'Scayt', 'SCAYT Settings', 'dialog/fck_scayt.html?' + action.toLowerCase(), 343, 343 ); + break; + + default : + if ( !isEngineLoaded ) + { + var me = this; + ScaytEngineLoad( function () + { + me.SetEnabled( !scayt_control.disabled ) ; + }) ; + + return true; + } + else if ( scaytReady ) + { + // Switch the current scayt state. + if ( scaytEnable ) + this.Disable() ; + else + this.Enable() ; + + ShowScaytState() ; + } + + } + + if ( !isEngineLoaded ) + return ScaytMessage( 'SCAYT is not loaded' ) || false; + + if ( !scaytReady ) + return ScaytMessage( 'SCAYT is not ready' ) || false; + + + return true; + } + + ScaytCommand.prototype.Enable = function() + { + window.scayt_control.setDisabled( false ) ; + scaytEnable = true; + + } + + ScaytCommand.prototype.Disable = function() + { + window.scayt_control.setDisabled( true ) ; + scaytEnable = false; + } + + ScaytCommand.prototype.SetEnabled = function( state ) + { + if ( state ) + this.Enable() ; + else + this.Disable() ; + + ShowScaytState() ; + return true; + } + + ScaytCommand.prototype.GetState = function() + { + return FCK_TRISTATE_OFF; + } + + function ShowScaytState() + { + var combo = FCKToolbarItems.GetItem( 'SpellCheck' ) ; + + if ( !combo ) + return; + + var bItem = combo._Combo._OuterTable.getElementsByTagName( 'img' )[1] ; + var dNode = combo._Combo.Items['trigger'] ; + + if ( scaytEnable ) + { + bItem.style.opacity = '1' ; + dNode.innerHTML = GetStatusLabel() ; + } + else + { + bItem.style.opacity = '0.5' ; + dNode.innerHTML = GetStatusLabel() ; + } + } + + function GetStatusLabel() + { + if ( !scaytReady ) + return 'Enable SCAYT' ; + + return scaytEnable ? 'Disable SCAYT' : 'Enable SCAYT' ; + } + + // ### + // Class for the toolbar item. + var ToolbarScaytComboBox = function( tooltip, style ) + { + this.Command = FCKCommands.GetCommand( 'Scayt' ) ; + this.CommandName = 'Scayt' ; + this.Label = this.GetLabel() ; + this.Tooltip = FCKLang.ScaytTitle ; + this.Style = FCK_TOOLBARITEM_ONLYTEXT ; //FCK_TOOLBARITEM_ICONTEXT OR FCK_TOOLBARITEM_ONLYTEXT + } + + ToolbarScaytComboBox.prototype = new FCKToolbarSpecialCombo ; + + //Add the items to the combo list + ToolbarScaytComboBox.prototype.CreateItems = function() + { + this._Combo.AddItem( 'Trigger', 'Enable SCAYT' ); + this._Combo.AddItem( 'Options', FCKLang.ScaytTitleOptions || "Options" ); + this._Combo.AddItem( 'Langs', FCKLang.ScaytTitleLangs || "Languages"); + this._Combo.AddItem( 'About', FCKLang.ScaytTitleAbout || "About"); + } + + // Label shown in the toolbar. + ToolbarScaytComboBox.prototype.GetLabel = function() + { + var strip = FCKConfig.SkinPath + 'fck_strip.gif'; + + return FCKBrowserInfo.IsIE ? + '
' + : + ''; + } + + function ScaytMessage( m ) + { + m && alert( m ) ; + } + + var ScaytContextCommand = function() + { + name = 'ScaytContext' ; + } + + ScaytContextCommand.prototype.Execute = function( contextInfo ) + { + var action = contextInfo && contextInfo.action, + node = action && contextInfo.node; + + if ( node ) + { + switch ( action ) + { + case 'Suggestion' : + scayt_control.replace( node, contextInfo.suggestion ) ; + break ; + case 'Ignore' : + scayt_control.ignore( node ) ; + break ; + case 'Ignore All' : + scayt_control.ignoreAll( node ) ; + break ; + case 'Add Word' : + scayt.addWordToUserDictionary( node ) ; + break ; + } + } + } + + // Register context menu listeners. + function InitSetup() + { + FCK.ContextMenu.RegisterListener( + { + AddItems : function( menu ) + { + if ( !scayt_control ) + return; + + var node = scayt_control.getScaytNode() ; + + if ( !node ) + return; + + var suggestions = scayt.getSuggestion( scayt_control.getWord( node ), scayt_control.getLang() ) ; + + if ( !suggestions || !suggestions.length ) + return; + + menu.AddSeparator() ; + + var maxSuggestions = FCK.Config.ScaytMaxSuggestions || 5 ; + var suggAveCount = ( maxSuggestions == -1 ) ? suggestions.length : maxSuggestions ; + + for ( var i = 0 ; i < suggAveCount ; i += 1) + menu.AddItem( 'ScaytContext', suggestions[i], null, false, { action : 'Suggestion', node : node, suggestion : suggestions[i] } ); + + menu.AddSeparator() ; + + menu.AddItem( 'ScaytContext', 'Ignore', null, false, { action : 'Ignore', node : node } ); + menu.AddItem( 'ScaytContext', 'Ignore All', null, false, { action : 'Ignore All', node : node } ); + menu.AddItem( 'ScaytContext', 'Add Word', null, false, { action : 'Add Word', node : node } ); + try + { + if (scaytReady && scaytEnable) + scayt_control.fireOnContextMenu( null, FCK.ContextMenu._InnerContextMenu); + + } + catch( err ) {} + } + }) ; + + FCK.Events.AttachEvent( 'OnPaste', function() + { + scayt_control.refresh() ; + return true; + } ) ; + } + + // ## + // Register event listeners. + FCK.Events.AttachEvent( 'OnAfterSetHTML', function() + { + if ( FCKConfig.SpellChecker == 'SCAYT' ) + { + if ( FCK.Config.ScaytAutoStartup ) + ScaytEngineLoad() + + ShowScaytState() ; + } + } ) ; + + // ### + // The main object that holds the SCAYT interaction in the code. + FCKScayt = + { + CreateCommand : function() + { + return new ScaytCommand(); + }, + + CreateContextCommand : function() + { + return new ScaytContextCommand(); + }, + + CreateToolbarItem : function() + { + return new ToolbarScaytComboBox() ; + } + } ; +})() ; Index: /FCKeditor/trunk/editor/_source/internals/fcktoolbaritems.js =================================================================== --- /FCKeditor/trunk/editor/_source/internals/fcktoolbaritems.js (revision 4227) +++ /FCKeditor/trunk/editor/_source/internals/fcktoolbaritems.js (revision 4228) @@ -53,5 +53,4 @@ case 'PasteWord' : oItem = new FCKToolbarButton( 'PasteWord' , FCKLang.PasteWord, null, null, false, true, 11 ) ; break ; case 'Print' : oItem = new FCKToolbarButton( 'Print' , FCKLang.Print, null, null, false, true, 12 ) ; break ; - case 'SpellCheck' : oItem = new FCKToolbarButton( 'SpellCheck', FCKLang.SpellCheck, null, null, null, null, 13 ) ; break ; case 'Undo' : oItem = new FCKToolbarButton( 'Undo' , FCKLang.Undo, null, null, false, true, 14 ) ; break ; case 'Redo' : oItem = new FCKToolbarButton( 'Redo' , FCKLang.Redo, null, null, false, true, 15 ) ; break ; @@ -114,4 +113,12 @@ case 'ShowBlocks' : oItem = new FCKToolbarButton( 'ShowBlocks' , FCKLang.ShowBlocks, null, null, null, true, 72 ) ; break ; + case 'SpellCheck' : + if ( FCKConfig.SpellChecker == 'SCAYT' ) + oItem = FCKScayt.CreateToolbarItem() ; + else + oItem = new FCKToolbarButton( 'SpellCheck', FCKLang.SpellCheck, null, null, null, null, 13 ) ; + + break ; + default: alert( FCKLang.UnknownToolbarItem.replace( /%1/g, itemName ) ) ; Index: /FCKeditor/trunk/editor/dialog/fck_scayt.html =================================================================== --- /FCKeditor/trunk/editor/dialog/fck_scayt.html (revision 4228) +++ /FCKeditor/trunk/editor/dialog/fck_scayt.html (revision 4228) @@ -0,0 +1,746 @@ + + + + +