JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
vanilla ckeditor-3.2.1
[ckeditor.git] / _source / plugins / scayt / plugin.js
index cfe35d6..f64d25e 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.\r
+Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.\r
 For licensing, see LICENSE.html or http://ckeditor.com/license\r
 */\r
 \r
@@ -11,7 +11,24 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
 (function()\r
 {\r
        var commandName         = 'scaytcheck',\r
-               openPage                = '';\r
+               openPage                = '',\r
+               scayt_paused    = null,\r
+               scayt_control_id = null;\r
+\r
+       // Checks if a value exists in an array\r
+       function in_array(needle, haystack)\r
+       {\r
+               var found = false, key;\r
+               for (key in haystack)\r
+               {\r
+                       if ((haystack[key] === needle) || ( haystack[key] == needle))\r
+                       {\r
+                               found = true;\r
+                               break;\r
+                       }\r
+               }\r
+               return found;\r
+       }\r
 \r
        var onEngineLoad = function()\r
        {\r
@@ -21,22 +38,32 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                {\r
                        // Initialise Scayt instance.\r
                        var oParams = {};\r
-                       oParams.srcNodeRef = editor.document.getWindow().$.frameElement;                // Get the iframe.\r
+                       // Get the iframe.\r
+                       oParams.srcNodeRef = editor.document.getWindow().$.frameElement;\r
                        // syntax : AppName.AppVersion@AppRevision\r
-                       oParams.assocApp  = "CKEDITOR." + CKEDITOR.version + "@" + CKEDITOR.revision;\r
+                       oParams.assocApp  = 'CKEDITOR.' + CKEDITOR.version + '@' + CKEDITOR.revision;\r
+                       oParams.customerid = editor.config.scayt_customerid  || '1:WvF0D4-UtPqN1-43nkD4-NKvUm2-daQqk3-LmNiI-z7Ysb4-mwry24-T8YrS3-Q2tpq2';\r
+                       oParams.customDictionaryIds = editor.config.scayt_customDictionaryIds || '';\r
+                       oParams.userDictionaryName = editor.config.scayt_userDictionaryName || '';\r
+                       oParams.sLang = editor.config.scayt_sLang || 'en_US';\r
 \r
-                       oParams.customerid = editor.config.scayt_customerid  || "1:11111111111111111111111111111111111111";\r
-                       oParams.customDictionaryName = editor.config.scayt_customDictionaryName;\r
-                       oParams.userDictionaryName = editor.config.scayt_userDictionaryName;\r
-                       oParams.defLang = editor.scayt_defLang;\r
+                       oParams.onBeforeChange = function()\r
+                       {\r
+                               if ( !editor.checkDirty() )\r
+                                       setTimeout( function(){ editor.resetDirty(); } );\r
+                       };\r
 \r
-                       if ( CKEDITOR._scaytParams )\r
+                       var scayt_custom_params = window.scayt_custom_params;\r
+                       if ( typeof scayt_custom_params == 'object')\r
                        {\r
-                               for ( var k in CKEDITOR._scaytParams )\r
+                               for ( var k in scayt_custom_params )\r
                                {\r
-                                       oParams[ k ] = CKEDITOR._scaytParams[ k ];\r
+                                       oParams[ k ] = scayt_custom_params[ k ];\r
                                }\r
                        }\r
+                       // needs for restoring a specific scayt control settings\r
+                       if ( scayt_control_id )\r
+                               oParams.id = scayt_control_id;\r
 \r
                        var scayt_control = new window.scayt( oParams );\r
 \r
@@ -51,9 +78,19 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
 \r
                        plugin.instances[ editor.name ] = scayt_control;\r
 \r
+                       //window.scayt.uiTags\r
+                       var menuGroup = 'scaytButton';\r
+                       var uiTabs = window.scayt.uiTags;\r
+                       var fTabs  = [];\r
+\r
+                       for (var i = 0,l=4; i<l; i++)\r
+                           fTabs.push( uiTabs[i] && plugin.uiTabs[i] );\r
+\r
+                       plugin.uiTabs = fTabs;\r
                        try {\r
-                               scayt_control.setDisabled( scayt_control.paused === false );                            // I really don't know why it causes JS error in IE\r
+                               scayt_control.setDisabled( scayt_paused === false );\r
                        } catch (e) {}\r
+\r
                        editor.fire( 'showScaytState' );\r
                };\r
 \r
@@ -80,21 +117,34 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                        {\r
                                if ( (ev.data.name == 'source' ||  ev.data.name == 'newpage') && editor.mode == 'wysiwyg' )\r
                                {\r
-                                       var scayt_instanse = plugin.getScayt( editor );\r
-                                       if ( scayt_instanse )\r
+                                       var scayt_instance = plugin.getScayt( editor );\r
+                                       if ( scayt_instance )\r
                                        {\r
-                                               scayt_instanse.paused = !scayt_instanse.disabled;\r
-                                               scayt_instanse.destroy();\r
+                                               scayt_paused = scayt_instance.paused = !scayt_instance.disabled;\r
+                                               // store a control id for restore a specific scayt control settings\r
+                                               scayt_control_id = scayt_instance.id;\r
+                                               scayt_instance.destroy( true );\r
                                                delete plugin.instances[ editor.name ];\r
                                        }\r
                                }\r
                        });\r
 \r
+               editor.on( 'destroy', function( ev )\r
+                       {\r
+                               var editor = ev.editor,\r
+                                       scayt_instance = plugin.getScayt( editor );\r
+                               // store a control id for restore a specific scayt control settings\r
+                               scayt_control_id = scayt_instance.id;\r
+                               scayt_instance.destroy( true );\r
+                               delete plugin.instances[ editor.name ];\r
+                       });\r
+\r
                // Listen to data manipulation to reflect scayt markup.\r
                editor.on( 'afterSetData', function()\r
                        {\r
-                               if ( plugin.isScaytEnabled( editor ) )\r
-                                       plugin.getScayt( editor ).refresh();\r
+                               if ( plugin.isScaytEnabled( editor ) ) {\r
+                                       window.setTimeout( function(){ plugin.getScayt( editor ).refresh(); }, 10 );\r
+                               }\r
                        });\r
 \r
                // Reload spell-checking for current word after insertion completed.\r
@@ -109,10 +159,22 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                                                editor.getSelection().unlock( true );\r
 \r
                                        // Swallow any SCAYT engine errors.\r
-                                       try{\r
-                                               scayt_instance.refresh();\r
-                                       }catch( er )\r
-                                       {}\r
+                                       window.setTimeout( function(){ scayt_instance.refresh(); }, 10 );\r
+                               }\r
+                       }, this, null, 50 );\r
+\r
+               editor.on( 'insertHtml', function()\r
+                       {\r
+                               var scayt_instance = plugin.getScayt( editor );\r
+                               if ( plugin.isScaytEnabled( editor ) )\r
+                               {\r
+                                       // Unlock the selection before reload, SCAYT will take\r
+                                       // care selection update.\r
+                                       if ( CKEDITOR.env.ie )\r
+                                               editor.getSelection().unlock( true );\r
+\r
+                                       // Swallow any SCAYT engine errors.\r
+                                       window.setTimeout( function(){ scayt_instance.refresh(); },10 );\r
                                }\r
                        }, this, null, 50 );\r
 \r
@@ -126,6 +188,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
 \r
                var dataProcessor = editor.dataProcessor,\r
                        htmlFilter = dataProcessor && dataProcessor.htmlFilter;\r
+\r
                if ( htmlFilter )\r
                {\r
                        htmlFilter.addRules(\r
@@ -164,15 +227,19 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                },\r
                isScaytEnabled : function( editor )\r
                {\r
-                       var scayt_instanse = this.getScayt( editor );\r
-                       return ( scayt_instanse ) ? scayt_instanse.disabled === false : false;\r
+                       var scayt_instance = this.getScayt( editor );\r
+                       return ( scayt_instance ) ? scayt_instance.disabled === false : false;\r
                },\r
                loadEngine : function( editor )\r
                {\r
+                       // SCAYT doesn't work with Opera.\r
+                       if ( CKEDITOR.env.opera )\r
+                               return null;\r
+\r
                        if ( this.engineLoaded === true )\r
                                return onEngineLoad.apply( editor );    // Add new instance.\r
                        else if ( this.engineLoaded == -1 )                     // We are waiting.\r
-                               return CKEDITOR.on( 'scaytReady', function(){ onEngineLoad.apply( editor );} ); // Use function(){} to avoid rejection as duplicate.\r
+                               return CKEDITOR.on( 'scaytReady', function(){ onEngineLoad.apply( editor ); } );        // Use function(){} to avoid rejection as duplicate.\r
 \r
                        CKEDITOR.on( 'scaytReady', onEngineLoad, editor );\r
                        CKEDITOR.on( 'scaytReady', function()\r
@@ -181,7 +248,8 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                                },\r
                                this,\r
                                null,\r
-                               0 );    // First to run.\r
+                               0\r
+                       );      // First to run.\r
 \r
                        this.engineLoaded = -1; // Loading in progress.\r
 \r
@@ -189,10 +257,10 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                        var protocol = document.location.protocol;\r
                        // Default to 'http' for unknown.\r
                        protocol = protocol.search( /https?:/) != -1? protocol : 'http:';\r
-                       var baseUrl  = "svc.spellchecker.net/spellcheck/lf/scayt/scayt1.js";\r
+                       var baseUrl  = 'svc.spellchecker.net/spellcheck31/lf/scayt/scayt22.js';\r
 \r
-                       var scaytUrl  =  editor.config.scayt_srcUrl || ( protocol + "//" + baseUrl );\r
-                       var scaytConfigBaseUrl =  plugin.parseUrl( scaytUrl ).path +  "/";\r
+                       var scaytUrl  =  editor.config.scayt_srcUrl || ( protocol + '//' + baseUrl );\r
+                       var scaytConfigBaseUrl =  plugin.parseUrl( scaytUrl ).path +  '/';\r
 \r
                        CKEDITOR._djScaytConfig =\r
                        {\r
@@ -201,7 +269,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                                [\r
                                        function()\r
                                        {\r
-                                               CKEDITOR.fireOnce( "scaytReady" );\r
+                                               CKEDITOR.fireOnce( 'scaytReady' );\r
                                        }\r
                                ],\r
                                isDebug: false\r
@@ -250,6 +318,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
        var commandDefinition =\r
        {\r
                preserveState : true,\r
+               editorFocus : false,\r
 \r
                exec: function( editor )\r
                {\r
@@ -299,51 +368,82 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
 \r
                        // Add Options dialog.\r
                        CKEDITOR.dialog.add( commandName, CKEDITOR.getUrl( this.path + 'dialogs/options.js' ) );\r
+                       // read ui tags\r
+                       var confuiTabs = editor.config.scayt_uiTabs || '1,1,1';\r
+                       var uiTabs =[];\r
+                       // string to array convert\r
+                       confuiTabs = confuiTabs.split( ',' );\r
+                       // check array length ! always must be 3 filled with 1 or 0\r
+                       for (var i=0,l=3; i<l; i++)\r
+                       {\r
+                               var flag = parseInt(confuiTabs[i] || '1' ,10);\r
+                               uiTabs.push( flag );\r
+                       }\r
 \r
                        var menuGroup = 'scaytButton';\r
                        editor.addMenuGroup( menuGroup );\r
-                       editor.addMenuItems(\r
+                       // combine menu items to render\r
+                       var uiMuneItems = {};\r
+\r
+                       // always added\r
+                       uiMuneItems.scaytToggle =\r
                                {\r
-                                       scaytToggle :\r
-                                       {\r
-                                               label : editor.lang.scayt.enable,\r
-                                               command : commandName,\r
-                                               group : menuGroup\r
-                                       },\r
+                                       label : editor.lang.scayt.enable,\r
+                                       command : commandName,\r
+                                       group : menuGroup\r
+                               };\r
 \r
-                                       scaytOptions :\r
+                       if (uiTabs[0] == 1)\r
+                               uiMuneItems.scaytOptions =\r
+                               {\r
+                                       label : editor.lang.scayt.options,\r
+                                       group : menuGroup,\r
+                                       onClick : function()\r
                                        {\r
-                                               label : editor.lang.scayt.options,\r
-                                               group : menuGroup,\r
-                                               onClick : function()\r
-                                               {\r
-                                                       openPage = 'options';\r
-                                                       editor.openDialog( commandName );\r
-                                               }\r
-                                       },\r
+                                               openPage = 'options';\r
+                                               editor.openDialog( commandName );\r
+                                       }\r
+                               };\r
 \r
-                                       scaytLangs :\r
+                       if (uiTabs[1] == 1)\r
+                               uiMuneItems.scaytLangs =\r
+                               {\r
+                                       label : editor.lang.scayt.langs,\r
+                                       group : menuGroup,\r
+                                       onClick : function()\r
                                        {\r
-                                               label : editor.lang.scayt.langs,\r
-                                               group : menuGroup,\r
-                                               onClick : function()\r
-                                               {\r
-                                                       openPage = 'langs';\r
-                                                       editor.openDialog( commandName );\r
-                                               }\r
-                                       },\r
-\r
-                                       scaytAbout :\r
+                                               openPage = 'langs';\r
+                                               editor.openDialog( commandName );\r
+                                       }\r
+                               };\r
+                       if (uiTabs[2] == 1)\r
+                               uiMuneItems.scaytDict =\r
+                               {\r
+                                       label : editor.lang.scayt.dictionariesTab,\r
+                                       group : menuGroup,\r
+                                       onClick : function()\r
                                        {\r
-                                               label : editor.lang.scayt.about,\r
-                                               group : menuGroup,\r
-                                               onClick : function()\r
-                                               {\r
-                                                       openPage = 'about';\r
-                                                       editor.openDialog( commandName );\r
-                                               }\r
+                                               openPage = 'dictionaries';\r
+                                               editor.openDialog( commandName );\r
                                        }\r
-                               });\r
+                               };\r
+                       // always added\r
+                       uiMuneItems.scaytAbout =\r
+                               {\r
+                                       label : editor.lang.scayt.about,\r
+                                       group : menuGroup,\r
+                                       onClick : function()\r
+                                       {\r
+                                               openPage = 'about';\r
+                                               editor.openDialog( commandName );\r
+                                       }\r
+                               }\r
+                       ;\r
+\r
+                       uiTabs[3] = 1; // about us tab is always on\r
+                       plugin.uiTabs = uiTabs;\r
+\r
+                       editor.addMenuItems( uiMuneItems );\r
 \r
                                editor.ui.add( 'Scayt', CKEDITOR.UI_MENUBUTTON,\r
                                        {\r
@@ -352,23 +452,24 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                                                className : 'cke_button_scayt',\r
                                                onRender: function()\r
                                                {\r
-                                               command.on( 'state', function()\r
+                                                       command.on( 'state', function()\r
                                                        {\r
                                                                this.setState( command.state );\r
                                                        },\r
                                                        this);\r
-                                       },\r
-                                       onMenu : function()\r
-                                       {\r
-                                               var isEnabled = plugin.isScaytEnabled( editor );\r
+                                               },\r
+                                               onMenu : function()\r
+                                               {\r
+                                                       var isEnabled = plugin.isScaytEnabled( editor );\r
 \r
-                                               editor.getMenuItem( 'scaytToggle' ).label = editor.lang.scayt[ isEnabled ? 'disable' : 'enable' ];\r
+                                                       editor.getMenuItem( 'scaytToggle' ).label = editor.lang.scayt[ isEnabled ? 'disable' : 'enable' ];\r
 \r
                                                        return {\r
-                                                               scaytToggle : CKEDITOR.TRISTATE_OFF,\r
-                                                               scaytOptions : isEnabled ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED,\r
-                                                               scaytLangs : isEnabled ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED,\r
-                                                               scaytAbout : isEnabled ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED\r
+                                                               scaytToggle  : CKEDITOR.TRISTATE_OFF,\r
+                                                               scaytOptions : isEnabled && plugin.uiTabs[0] ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED,\r
+                                                               scaytLangs   : isEnabled && plugin.uiTabs[1] ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED,\r
+                                                               scaytDict    : isEnabled && plugin.uiTabs[2] ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED,\r
+                                                               scaytAbout   : isEnabled && plugin.uiTabs[3] ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED\r
                                                        };\r
                                                }\r
                                        });\r
@@ -376,13 +477,18 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                        // If the "contextmenu" plugin is loaded, register the listeners.\r
                        if ( editor.contextMenu && editor.addMenuItems )\r
                        {\r
-                               editor.contextMenu.addListener( function( element )\r
+                               editor.contextMenu.addListener( function(  )\r
                                        {\r
-                                               if ( !( plugin.isScaytEnabled( editor ) && element ) )\r
+                                               if ( !plugin.isScaytEnabled( editor ) )\r
                                                        return null;\r
 \r
                                                var scayt_control = plugin.getScayt( editor ),\r
-                                                       word = scayt_control.getWord( element.$ );\r
+                                                       node = scayt_control.getScaytNode();\r
+\r
+                                               if ( !node )\r
+                                                       return null;\r
+\r
+                                                       var word = scayt_control.getWord( node );\r
 \r
                                                if ( !word )\r
                                                        return null;\r
@@ -390,7 +496,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                                                var sLang = scayt_control.getLang(),\r
                                                        _r = {},\r
                                                        items_suggestion = window.scayt.getSuggestion( word, sLang );\r
-                                               if (!items_suggestion || !items_suggestion.length )\r
+                                               if ( !items_suggestion || !items_suggestion.length )\r
                                                        return null;\r
                                                // Remove unused commands and menuitems\r
                                                for ( i in moreSuggestions )\r
@@ -406,7 +512,15 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                                                moreSuggestions = {};           // Reset items.\r
                                                mainSuggestions = {};\r
 \r
-                                               var moreSuggestionsUnable = false;\r
+                                               var moreSuggestionsUnable = editor.config.scayt_moreSuggestions || 'on';\r
+                                               var moreSuggestionsUnableAdded = false;\r
+\r
+                                               var maxSuggestions = editor.config.scayt_maxSuggestions;\r
+                                               ( typeof maxSuggestions != 'number' ) && ( maxSuggestions = 5 );\r
+                                               !maxSuggestions && ( maxSuggestions = items_suggestion.length );\r
+\r
+                                               var contextCommands = editor.config.scayt_contextCommands || 'all';\r
+                                               contextCommands = contextCommands.split( '|' );\r
 \r
                                                for ( var i = 0, l = items_suggestion.length; i < l; i += 1 )\r
                                                {\r
@@ -419,70 +533,72 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                                                                                        scayt_control.replace(el, s);\r
                                                                                }\r
                                                                        };\r
-                                                               })( element.$, items_suggestion[i] );\r
+                                                               })( node, items_suggestion[i] );\r
 \r
-                                                       if ( i < editor.config.scayt_maxSuggestions )\r
+                                                       if ( i < maxSuggestions )\r
                                                        {\r
                                                                addButtonCommand( editor, 'button_' + commandName, items_suggestion[i],\r
                                                                        commandName, exec, 'scayt_suggest', i + 1 );\r
                                                                _r[ commandName ] = CKEDITOR.TRISTATE_OFF;\r
                                                                mainSuggestions[ commandName ] = CKEDITOR.TRISTATE_OFF;\r
                                                        }\r
-                                                       else\r
+                                                       else if ( moreSuggestionsUnable == 'on' )\r
                                                        {\r
                                                                addButtonCommand( editor, 'button_' + commandName, items_suggestion[i],\r
                                                                        commandName, exec, 'scayt_moresuggest', i + 1 );\r
                                                                moreSuggestions[ commandName ] = CKEDITOR.TRISTATE_OFF;\r
-                                                               moreSuggestionsUnable = true;\r
+                                                               moreSuggestionsUnableAdded = true;\r
                                                        }\r
                                                }\r
-                                               if ( moreSuggestionsUnable )\r
-                                                       // Rgister the More suggestions group;\r
-                                                       editor.addMenuItem( 'scayt_moresuggest',\r
-                                                               {\r
-                                                                       label : editor.lang.scayt.moreSuggestions,\r
-                                                                       group : 'scayt_moresuggest',\r
-                                                                       order : 10,\r
-                                                                       getItems : function()\r
-                                                                       {\r
-                                                                               return moreSuggestions;\r
-                                                                       }\r
-                                                               });\r
 \r
-\r
-                                               var ignore_command =\r
+                                               if ( moreSuggestionsUnableAdded )\r
                                                {\r
-                                                       exec: function()\r
-                                                       {\r
-                                                               scayt_control.ignore( element.$ );\r
-                                                       }\r
-                                               };\r
-                                               var ignore_all_command =\r
-                                               {\r
-                                                       exec: function()\r
+                                                       // Register the More suggestions group;\r
+                                                       editor.addMenuItem( 'scayt_moresuggest',\r
                                                        {\r
-                                                               scayt_control.ignoreAll( element.$ );\r
-                                                       }\r
-                                               };\r
-                                               var addword_command =\r
+                                                               label : editor.lang.scayt.moreSuggestions,\r
+                                                               group : 'scayt_moresuggest',\r
+                                                               order : 10,\r
+                                                               getItems : function()\r
+                                                               {\r
+                                                                       return moreSuggestions;\r
+                                                               }\r
+                                                       });\r
+                                                       mainSuggestions[ 'scayt_moresuggest' ] = CKEDITOR.TRISTATE_OFF;\r
+                                               }\r
+\r
+                                               if ( in_array( 'all', contextCommands )  || in_array( 'ignore', contextCommands)  )\r
                                                {\r
-                                                       exec: function()\r
-                                                       {\r
-                                                               window.scayt.addWordToUserDictionary( element.$ );\r
-                                                       }\r
-                                               };\r
+                                                       var ignore_command = {\r
+                                                               exec: function(){\r
+                                                                       scayt_control.ignore( node );\r
+                                                               }\r
+                                                       };\r
+                                                       addButtonCommand( editor, 'ignore', editor.lang.scayt.ignore, 'scayt_ignore', ignore_command, 'scayt_control', 1 );\r
+                                                       mainSuggestions[ 'scayt_ignore' ] = CKEDITOR.TRISTATE_OFF;\r
+                                               }\r
 \r
-                                               addButtonCommand( editor, 'ignore', editor.lang.scayt.ignore,\r
-                                                       'scayt_ignore', ignore_command, 'scayt_control', 1);\r
-                                               addButtonCommand( editor, 'ignore_all', editor.lang.scayt.ignoreAll,\r
-                                                       'scayt_ignore_all', ignore_all_command, 'scayt_control', 2);\r
-                                               addButtonCommand( editor, 'add_word', editor.lang.scayt.addWord,\r
-                                                       'scayt_add_word', addword_command, 'scayt_control', 3);\r
+                                               if ( in_array( 'all', contextCommands )  || in_array( 'ignoreall', contextCommands ) )\r
+                                               {\r
+                                                       var ignore_all_command = {\r
+                                                               exec: function(){\r
+                                                                       scayt_control.ignoreAll( node );\r
+                                                               }\r
+                                                       };\r
+                                                       addButtonCommand(editor, 'ignore_all', editor.lang.scayt.ignoreAll, 'scayt_ignore_all', ignore_all_command, 'scayt_control', 2);\r
+                                                       mainSuggestions['scayt_ignore_all'] = CKEDITOR.TRISTATE_OFF;\r
+                                               }\r
 \r
-                                               mainSuggestions[ 'scayt_moresuggest' ] = CKEDITOR.TRISTATE_OFF;\r
-                                               mainSuggestions[ 'scayt_ignore' ] = CKEDITOR.TRISTATE_OFF;\r
-                                               mainSuggestions[ 'scayt_ignore_all' ] = CKEDITOR.TRISTATE_OFF;\r
-                                               mainSuggestions[ 'scayt_add_word' ] = CKEDITOR.TRISTATE_OFF;\r
+                                               if ( in_array( 'all', contextCommands )  || in_array( 'add', contextCommands ) )\r
+                                               {\r
+                                                       var addword_command = {\r
+                                                               exec: function(){\r
+                                                                       window.scayt.addWordToUserDictionary( node );\r
+                                                               }\r
+                                                       };\r
+                                                       addButtonCommand(editor, 'add_word', editor.lang.scayt.addWord, 'scayt_add_word', addword_command, 'scayt_control', 3);\r
+                                                       mainSuggestions['scayt_add_word'] = CKEDITOR.TRISTATE_OFF;\r
+                                               }\r
 \r
                                                if ( scayt_control.fireOnContextMenu )\r
                                                        scayt_control.fireOnContextMenu( editor );\r
@@ -500,12 +616,152 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                                        command.setState( plugin.isScaytEnabled( editor ) ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF );\r
                                };\r
                                editor.on( 'showScaytState', showInitialState );\r
+                               editor.on( 'instanceReady', function()\r
+                               {\r
+                                       plugin.loadEngine( editor );\r
+                               });\r
+                       }\r
+               },\r
 \r
-                               plugin.loadEngine( editor );\r
+               afterInit : function( editor )\r
+               {\r
+                       // Prevent word marker line from displaying in elements path. (#3570)\r
+                       var elementsPathFilters;\r
+                       if ( editor._.elementsPath && ( elementsPathFilters = editor._.elementsPath.filters ) )\r
+                       {\r
+                               elementsPathFilters.push( function( element )\r
+                               {\r
+                                       if ( element.hasAttribute( 'scaytid' ) )\r
+                                               return false;\r
+                               } );\r
                        }\r
+\r
                }\r
        });\r
 })();\r
 \r
-CKEDITOR.config.scayt_maxSuggestions =  5;\r
-CKEDITOR.config.scayt_autoStartup = false;\r
+/**\r
+ * If enabled (true), turns on SCAYT automatically after loading the editor.\r
+ * @name CKEDITOR.config.scayt_autoStartup\r
+ * @type Boolean\r
+ * @default false\r
+ * @example\r
+ * config.scayt_autoStartup = true;\r
+ */\r
+\r
+/**\r
+ * Defines the number of SCAYT suggestions to show in the main context menu.\r
+ * The possible values are:\r
+ * <ul>\r
+ *     <li>0 (zero): All suggestions are displayed in the main context menu.</li>\r
+ *     <li>Positive number: The maximum number of suggestions to shown in context\r
+ *             menu. Other entries will be shown in "More Suggestions" sub-menu.</li>\r
+ *     <li>Negative number: No suggestions are shown in the main context menu. All\r
+ *             entries will be listed in the "Suggestions" sub-menu.</li>\r
+ * </ul>\r
+ * @name CKEDITOR.config.scayt_maxSuggestions\r
+ * @type Number\r
+ * @default 5\r
+ * @example\r
+ * // Display only three suggestions in the main context menu.\r
+ * config.scayt_maxSuggestions = 3;\r
+ * @example\r
+ * // Do not show the suggestions directly.\r
+ * config.scayt_maxSuggestions = -1;\r
+ */\r
+\r
+/**\r
+ * Sets the customer ID for SCAYT. Required for migration from free version\r
+ * with banner to paid version.\r
+ * @name CKEDITOR.config.scayt_customerid\r
+ * @type String\r
+ * @default ''\r
+ * @example\r
+ * // Load SCAYT using my customer ID.\r
+ * config.scayt_customerid  = 'your-encrypted-customer-id';\r
+ */\r
+\r
+/**\r
+ * Enables/disables the "More Suggestions" sub-menu in the context menu.\r
+ * The possible values are "on" or "off".\r
+ * @name CKEDITOR.config.scayt_moreSuggestions\r
+ * @type String\r
+ * @default 'on'\r
+ * @example\r
+ * // Disables the "More Suggestions" sub-menu.\r
+ * config.scayt_moreSuggestions = 'off';\r
+ */\r
+\r
+/**\r
+ * Customizes the display of SCAYT context menu commands ("Add Word", "Ignore"\r
+ * and "Ignore All"). It must be a string with one or more of the following\r
+ * words separated by a pipe ("|"):\r
+ * <ul>\r
+ *     <li>"off": disables all options.</li>\r
+ *     <li>"all": enables all options.</li>\r
+ *     <li>"ignore": enables the "Ignore" option.</li>\r
+ *     <li>"ignoreall": enables the "Ignore All" option.</li>\r
+ *     <li>"add": enables the "Add Word" option.</li>\r
+ * </ul>\r
+ * @name CKEDITOR.config.scayt_contextCommands\r
+ * @type String\r
+ * @default 'all'\r
+ * @example\r
+ * // Show only "Add Word" and "Ignore All" in the context menu.\r
+ * config.scayt_contextCommands = 'add|ignoreall';\r
+ */\r
+\r
+/**\r
+ * Sets the default spellchecking language for SCAYT.\r
+ * @name CKEDITOR.config.scayt_sLang\r
+ * @type String\r
+ * @default 'en_US'\r
+ * @example\r
+ * // Sets SCAYT to German.\r
+ * config.scayt_sLang = 'de_DE';\r
+ */\r
+\r
+/**\r
+ * Sets the visibility of the SCAYT tabs in the settings dialog and toolbar\r
+ * button. The value must contain a "1" (enabled) or "0" (disabled) number for\r
+ * each of the following entries, in this precise order, separated by a\r
+ * comma (","): "Options", "Languages" and "Dictionary".\r
+ * @name CKEDITOR.config.scayt_uiTabs\r
+ * @type String\r
+ * @default '1,1,1'\r
+ * @example\r
+ * // Hide the "Languages" tab.\r
+ * config.scayt_uiTabs = '1,0,1';\r
+ */\r
+\r
+\r
+/**\r
+ * Set the URL to SCAYT core. Required to switch to licensed version of SCAYT application.\r
+ * Further details at http://wiki.spellchecker.net/doku.php?id=3rd:wysiwyg:fckeditor:wscckf3l .\r
+ * @name CKEDITOR.config.scayt_srcUrl\r
+ * @type String\r
+ * @default ''\r
+ * @example\r
+ * config.scayt_srcUrl = "http://my-host/spellcheck/lf/scayt/scayt.js";\r
+ */\r
+\r
+/**\r
+ * Links SCAYT to custom dictionaries. It's a string containing dictionary ids\r
+ * separared by commas (","). Available only for licensed version.\r
+ * Further details at http://wiki.spellchecker.net/doku.php?id=custom_dictionary_support .\r
+ * @name CKEDITOR.config.scayt_customDictionaryIds\r
+ * @type String\r
+ * @default ''\r
+ * @example\r
+ * config.scayt_customDictionaryIds = '3021,3456,3478"';\r
+ */\r
+\r
+/**\r
+ * Makes it possible to activate a custom dictionary on SCAYT. The user\r
+ * dictionary name must be used. Available only for licensed version.\r
+ * @name CKEDITOR.config.scayt_userDictionaryName\r
+ * @type String\r
+ * @default ''\r
+ * @example\r
+ * config.scayt_userDictionaryName = 'MyDictionary';\r
+ */\r