--- /dev/null
+/*\r
+Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.html or http://ckeditor.com/license\r
+*/\r
+\r
+/**\r
+ * @fileOverview Spell Check As You Type (SCAYT).\r
+ * Button name : Scayt.\r
+ */\r
+\r
+(function()\r
+{\r
+ var commandName = 'scaytcheck',\r
+ openPage = '';\r
+\r
+ var onEngineLoad = function()\r
+ {\r
+ var editor = this;\r
+\r
+ var createInstance = function() // Create new instance every time Document is created.\r
+ {\r
+ // Initialise Scayt instance.\r
+ var oParams = {};\r
+ oParams.srcNodeRef = editor.document.getWindow().$.frameElement; // Get the iframe.\r
+ // syntax : AppName.AppVersion@AppRevision\r
+ oParams.assocApp = "CKEDITOR." + CKEDITOR.version + "@" + CKEDITOR.revision;\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
+\r
+ if ( CKEDITOR._scaytParams )\r
+ {\r
+ for ( var k in CKEDITOR._scaytParams )\r
+ {\r
+ oParams[ k ] = CKEDITOR._scaytParams[ k ];\r
+ }\r
+ }\r
+\r
+ var scayt_control = new window.scayt( oParams );\r
+\r
+ // Copy config.\r
+ var lastInstance = plugin.instances[ editor.name ];\r
+ if ( lastInstance )\r
+ {\r
+ scayt_control.sLang = lastInstance.sLang;\r
+ scayt_control.option( lastInstance.option() );\r
+ scayt_control.paused = lastInstance.paused;\r
+ }\r
+\r
+ plugin.instances[ editor.name ] = scayt_control;\r
+\r
+ try {\r
+ scayt_control.setDisabled( scayt_control.paused === false ); // I really don't know why it causes JS error in IE\r
+ } catch (e) {}\r
+ editor.fire( 'showScaytState' );\r
+ };\r
+\r
+ editor.on( 'contentDom', createInstance );\r
+ editor.on( 'contentDomUnload', function()\r
+ {\r
+ // Remove scripts.\r
+ var scripts = CKEDITOR.document.getElementsByTag( 'script' ),\r
+ scaytIdRegex = /^dojoIoScript(\d+)$/i,\r
+ scaytSrcRegex = /^https?:\/\/svc\.spellchecker\.net\/spellcheck\/script\/ssrv\.cgi/i;\r
+\r
+ for ( var i=0; i < scripts.count(); i++ )\r
+ {\r
+ var script = scripts.getItem( i ),\r
+ id = script.getId(),\r
+ src = script.getAttribute( 'src' );\r
+\r
+ if ( id && src && id.match( scaytIdRegex ) && src.match( scaytSrcRegex ))\r
+ script.remove();\r
+ }\r
+ });\r
+\r
+ editor.on( 'beforeCommandExec', function( ev ) // Disable SCAYT before Source command execution.\r
+ {\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
+ {\r
+ scayt_instanse.paused = !scayt_instanse.disabled;\r
+ scayt_instanse.destroy();\r
+ delete plugin.instances[ editor.name ];\r
+ }\r
+ }\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
+ });\r
+\r
+ // Reload spell-checking for current word after insertion completed.\r
+ editor.on( 'insertElement', 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
+ try{\r
+ scayt_instance.refresh();\r
+ }catch( er )\r
+ {}\r
+ }\r
+ }, this, null, 50 );\r
+\r
+ editor.on( 'scaytDialog', function( ev ) // Communication with dialog.\r
+ {\r
+ ev.data.djConfig = window.djConfig;\r
+ ev.data.scayt_control = plugin.getScayt( editor );\r
+ ev.data.tab = openPage;\r
+ ev.data.scayt = window.scayt;\r
+ });\r
+\r
+ var dataProcessor = editor.dataProcessor,\r
+ htmlFilter = dataProcessor && dataProcessor.htmlFilter;\r
+ if ( htmlFilter )\r
+ {\r
+ htmlFilter.addRules(\r
+ {\r
+ elements :\r
+ {\r
+ span : function( element )\r
+ {\r
+ if ( element.attributes.scayt_word && element.attributes.scaytid )\r
+ {\r
+ delete element.name; // Write children, but don't write this node.\r
+ return element;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ );\r
+ }\r
+\r
+ if ( editor.document )\r
+ createInstance();\r
+ };\r
+\r
+ CKEDITOR.plugins.scayt =\r
+ {\r
+ engineLoaded : false,\r
+ instances : {},\r
+ getScayt : function( editor )\r
+ {\r
+ return this.instances[ editor.name ];\r
+ },\r
+ isScaytReady : function( editor )\r
+ {\r
+ return this.engineLoaded === true &&\r
+ 'undefined' !== typeof window.scayt && this.getScayt( editor );\r
+ },\r
+ isScaytEnabled : function( editor )\r
+ {\r
+ var scayt_instanse = this.getScayt( editor );\r
+ return ( scayt_instanse ) ? scayt_instanse.disabled === false : false;\r
+ },\r
+ loadEngine : function( editor )\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
+\r
+ CKEDITOR.on( 'scaytReady', onEngineLoad, editor );\r
+ CKEDITOR.on( 'scaytReady', function()\r
+ {\r
+ this.engineLoaded = true;\r
+ },\r
+ this,\r
+ null,\r
+ 0 ); // First to run.\r
+\r
+ this.engineLoaded = -1; // Loading in progress.\r
+\r
+ // compose scayt url\r
+ 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
+\r
+ var scaytUrl = editor.config.scayt_srcUrl || ( protocol + "//" + baseUrl );\r
+ var scaytConfigBaseUrl = plugin.parseUrl( scaytUrl ).path + "/";\r
+\r
+ CKEDITOR._djScaytConfig =\r
+ {\r
+ baseUrl: scaytConfigBaseUrl,\r
+ addOnLoad:\r
+ [\r
+ function()\r
+ {\r
+ CKEDITOR.fireOnce( "scaytReady" );\r
+ }\r
+ ],\r
+ isDebug: false\r
+ };\r
+ // Append javascript code.\r
+ CKEDITOR.document.getHead().append(\r
+ CKEDITOR.document.createElement( 'script',\r
+ {\r
+ attributes :\r
+ {\r
+ type : 'text/javascript',\r
+ src : scaytUrl\r
+ }\r
+ })\r
+ );\r
+\r
+ return null;\r
+ },\r
+ parseUrl : function ( data )\r
+ {\r
+ var match;\r
+ if ( data.match && ( match = data.match(/(.*)[\/\\](.*?\.\w+)$/) ) )\r
+ return { path: match[1], file: match[2] };\r
+ else\r
+ return data;\r
+ }\r
+ };\r
+\r
+ var plugin = CKEDITOR.plugins.scayt;\r
+\r
+ // Context menu constructing.\r
+ var addButtonCommand = function( editor, buttonName, buttonLabel, commandName, command, menugroup, menuOrder )\r
+ {\r
+ editor.addCommand( commandName, command );\r
+\r
+ // If the "menu" plugin is loaded, register the menu item.\r
+ editor.addMenuItem( commandName,\r
+ {\r
+ label : buttonLabel,\r
+ command : commandName,\r
+ group : menugroup,\r
+ order : menuOrder\r
+ });\r
+ };\r
+\r
+ var commandDefinition =\r
+ {\r
+ preserveState : true,\r
+\r
+ exec: function( editor )\r
+ {\r
+ if ( plugin.isScaytReady( editor ) )\r
+ {\r
+ var isEnabled = plugin.isScaytEnabled( editor );\r
+\r
+ this.setState( isEnabled ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_ON );\r
+\r
+ var scayt_control = plugin.getScayt( editor );\r
+ scayt_control.setDisabled( isEnabled );\r
+ }\r
+ else if ( !editor.config.scayt_autoStartup && plugin.engineLoaded >= 0 ) // Load first time\r
+ {\r
+ this.setState( CKEDITOR.TRISTATE_DISABLED );\r
+\r
+ editor.on( 'showScaytState', function()\r
+ {\r
+ this.removeListener();\r
+ this.setState( plugin.isScaytEnabled( editor ) ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF );\r
+ },\r
+ this);\r
+\r
+ plugin.loadEngine( editor );\r
+ }\r
+ }\r
+ };\r
+\r
+ // Add scayt plugin.\r
+ CKEDITOR.plugins.add( 'scayt',\r
+ {\r
+ requires : [ 'menubutton' ],\r
+\r
+ beforeInit : function( editor )\r
+ {\r
+ // Register own rbc menu group.\r
+ editor.config.menu_groups = 'scayt_suggest,scayt_moresuggest,scayt_control,' + editor.config.menu_groups;\r
+ },\r
+\r
+ init : function( editor )\r
+ {\r
+ var moreSuggestions = {};\r
+ var mainSuggestions = {};\r
+\r
+ // Scayt command.\r
+ var command = editor.addCommand( commandName, commandDefinition );\r
+\r
+ // Add Options dialog.\r
+ CKEDITOR.dialog.add( commandName, CKEDITOR.getUrl( this.path + 'dialogs/options.js' ) );\r
+\r
+ var menuGroup = 'scaytButton';\r
+ editor.addMenuGroup( menuGroup );\r
+ editor.addMenuItems(\r
+ {\r
+ scaytToggle :\r
+ {\r
+ label : editor.lang.scayt.enable,\r
+ command : commandName,\r
+ group : menuGroup\r
+ },\r
+\r
+ scaytOptions :\r
+ {\r
+ label : editor.lang.scayt.options,\r
+ group : menuGroup,\r
+ onClick : function()\r
+ {\r
+ openPage = 'options';\r
+ editor.openDialog( commandName );\r
+ }\r
+ },\r
+\r
+ scaytLangs :\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
+ {\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
+ editor.ui.add( 'Scayt', CKEDITOR.UI_MENUBUTTON,\r
+ {\r
+ label : editor.lang.scayt.title,\r
+ title : editor.lang.scayt.title,\r
+ className : 'cke_button_scayt',\r
+ onRender: function()\r
+ {\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
+ 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
+ };\r
+ }\r
+ });\r
+\r
+ // If the "contextmenu" plugin is loaded, register the listeners.\r
+ if ( editor.contextMenu && editor.addMenuItems )\r
+ {\r
+ editor.contextMenu.addListener( function( element )\r
+ {\r
+ if ( !( plugin.isScaytEnabled( editor ) && element ) )\r
+ return null;\r
+\r
+ var scayt_control = plugin.getScayt( editor ),\r
+ word = scayt_control.getWord( element.$ );\r
+\r
+ if ( !word )\r
+ return null;\r
+\r
+ var sLang = scayt_control.getLang(),\r
+ _r = {},\r
+ items_suggestion = window.scayt.getSuggestion( word, sLang );\r
+ if (!items_suggestion || !items_suggestion.length )\r
+ return null;\r
+ // Remove unused commands and menuitems\r
+ for ( i in moreSuggestions )\r
+ {\r
+ delete editor._.menuItems[ i ];\r
+ delete editor._.commands[ i ];\r
+ }\r
+ for ( i in mainSuggestions )\r
+ {\r
+ delete editor._.menuItems[ i ];\r
+ delete editor._.commands[ i ];\r
+ }\r
+ moreSuggestions = {}; // Reset items.\r
+ mainSuggestions = {};\r
+\r
+ var moreSuggestionsUnable = false;\r
+\r
+ for ( var i = 0, l = items_suggestion.length; i < l; i += 1 )\r
+ {\r
+ var commandName = 'scayt_suggestion_' + items_suggestion[i].replace( ' ', '_' );\r
+ var exec = ( function( el, s )\r
+ {\r
+ return {\r
+ exec: function()\r
+ {\r
+ scayt_control.replace(el, s);\r
+ }\r
+ };\r
+ })( element.$, items_suggestion[i] );\r
+\r
+ if ( i < editor.config.scayt_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
+ {\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
+ }\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
+ {\r
+ exec: function()\r
+ {\r
+ scayt_control.ignore( element.$ );\r
+ }\r
+ };\r
+ var ignore_all_command =\r
+ {\r
+ exec: function()\r
+ {\r
+ scayt_control.ignoreAll( element.$ );\r
+ }\r
+ };\r
+ var addword_command =\r
+ {\r
+ exec: function()\r
+ {\r
+ window.scayt.addWordToUserDictionary( element.$ );\r
+ }\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
+\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
+\r
+ if ( scayt_control.fireOnContextMenu )\r
+ scayt_control.fireOnContextMenu( editor );\r
+\r
+ return mainSuggestions;\r
+ });\r
+ }\r
+\r
+ // Start plugin\r
+ if ( editor.config.scayt_autoStartup )\r
+ {\r
+ var showInitialState = function()\r
+ {\r
+ editor.removeListener( 'showScaytState', showInitialState );\r
+ command.setState( plugin.isScaytEnabled( editor ) ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF );\r
+ };\r
+ editor.on( 'showScaytState', showInitialState );\r
+\r
+ plugin.loadEngine( editor );\r
+ }\r
+ }\r
+ });\r
+})();\r
+\r
+CKEDITOR.config.scayt_maxSuggestions = 5;\r
+CKEDITOR.config.scayt_autoStartup = false;\r