2 Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
3 For licensing, see LICENSE.html or http://ckeditor.com/license
7 * @fileOverview Spell Check As You Type (SCAYT).
13 var commandName
= 'scaytcheck',
16 // Checks if a value exists in an array
17 function in_array( needle
, haystack
)
21 for ( key
in haystack
)
23 if ( haystack
[ key
] == needle
)
32 var onEngineLoad = function()
36 var createInstance = function() // Create new instance every time Document is created.
38 var config
= editor
.config
;
39 // Initialise Scayt instance.
42 oParams
.srcNodeRef
= editor
.document
.getWindow().$.frameElement
;
43 // syntax : AppName.AppVersion@AppRevision
44 oParams
.assocApp
= 'CKEDITOR.' + CKEDITOR
.version
+ '@' + CKEDITOR
.revision
;
45 oParams
.customerid
= config
.scayt_customerid
|| '1:WvF0D4-UtPqN1-43nkD4-NKvUm2-daQqk3-LmNiI-z7Ysb4-mwry24-T8YrS3-Q2tpq2';
46 oParams
.customDictionaryIds
= config
.scayt_customDictionaryIds
|| '';
47 oParams
.userDictionaryName
= config
.scayt_userDictionaryName
|| '';
48 oParams
.sLang
= config
.scayt_sLang
|| 'en_US';
50 // Introduce SCAYT onLoad callback. (#5632)
51 oParams
.onLoad = function()
53 // Draw down word marker to avoid being covered by background-color style.(#5466)
54 if ( !( CKEDITOR
.env
.ie
&& CKEDITOR
.env
.version
< 8 ) )
55 this.addStyle( this.selectorCss(), 'padding-bottom: 2px !important;' );
57 // Call scayt_control.focus when SCAYT loaded
58 // and only if editor has focus and scayt control creates at first time (#5720)
59 if ( editor
.focusManager
.hasFocus
&& !plugin
.isControlRestored( editor
) )
64 oParams
.onBeforeChange = function()
66 if ( plugin
.getScayt( editor
) && !editor
.checkDirty() )
67 setTimeout( function(){ editor
.resetDirty(); }, 0 );
70 var scayt_custom_params
= window
.scayt_custom_params
;
71 if ( typeof scayt_custom_params
== 'object' )
73 for ( var k
in scayt_custom_params
)
74 oParams
[ k
] = scayt_custom_params
[ k
];
76 // needs for restoring a specific scayt control settings
77 if ( plugin
.getControlId( editor
) )
78 oParams
.id
= plugin
.getControlId( editor
);
80 var scayt_control
= new window
.scayt( oParams
);
82 scayt_control
.afterMarkupRemove
.push( function( node
)
84 ( new CKEDITOR
.dom
.element( node
, scayt_control
.document
) ).mergeSiblings();
88 var lastInstance
= plugin
.instances
[ editor
.name
];
91 scayt_control
.sLang
= lastInstance
.sLang
;
92 scayt_control
.option( lastInstance
.option() );
93 scayt_control
.paused
= lastInstance
.paused
;
96 plugin
.instances
[ editor
.name
] = scayt_control
;
99 scayt_control
.setDisabled( plugin
.isPaused( editor
) === false );
102 editor
.fire( 'showScaytState' );
105 editor
.on( 'contentDom', createInstance
);
106 editor
.on( 'contentDomUnload', function()
109 var scripts
= CKEDITOR
.document
.getElementsByTag( 'script' ),
110 scaytIdRegex
= /^dojoIoScript(\d+)$/i,
111 scaytSrcRegex
= /^https?:\/\/svc\.spellchecker\.net\/spellcheck\/script\/ssrv\.cgi/i;
113 for ( var i
=0; i
< scripts
.count(); i
++ )
115 var script
= scripts
.getItem( i
),
117 src
= script
.getAttribute( 'src' );
119 if ( id
&& src
&& id
.match( scaytIdRegex
) && src
.match( scaytSrcRegex
))
124 editor
.on( 'beforeCommandExec', function( ev
) // Disable SCAYT before Source command execution.
126 if ( ( ev
.data
.name
== 'source' || ev
.data
.name
== 'newpage' ) && editor
.mode
== 'wysiwyg' )
128 var scayt_instance
= plugin
.getScayt( editor
);
129 if ( scayt_instance
)
131 plugin
.setPaused( editor
, !scayt_instance
.disabled
);
132 // store a control id for restore a specific scayt control settings
133 plugin
.setControlId( editor
, scayt_instance
.id
);
134 scayt_instance
.destroy( true );
135 delete plugin
.instances
[ editor
.name
];
138 // Catch on source mode switch off (#5720)
139 else if ( ev
.data
.name
== 'source' && editor
.mode
== 'source' )
140 plugin
.markControlRestore( editor
);
143 editor
.on( 'afterCommandExec', function( ev
)
145 if ( !plugin
.isScaytEnabled( editor
) )
148 if ( editor
.mode
== 'wysiwyg' && ( ev
.data
.name
== 'undo' || ev
.data
.name
== 'redo' ) )
149 window
.setTimeout( function() { plugin
.getScayt( editor
).refresh(); }, 10 );
152 editor
.on( 'destroy', function( ev
)
154 var editor
= ev
.editor
,
155 scayt_instance
= plugin
.getScayt( editor
);
157 // SCAYT instance might already get destroyed by mode switch (#5744).
158 if ( !scayt_instance
)
161 delete plugin
.instances
[ editor
.name
];
162 // store a control id for restore a specific scayt control settings
163 plugin
.setControlId( editor
, scayt_instance
.id
);
164 scayt_instance
.destroy( true );
167 // Listen to data manipulation to reflect scayt markup.
168 editor
.on( 'afterSetData', function()
170 if ( plugin
.isScaytEnabled( editor
) ) {
171 window
.setTimeout( function()
173 var instance
= plugin
.getScayt( editor
);
174 instance
&& instance
.refresh();
179 // Reload spell-checking for current word after insertion completed.
180 editor
.on( 'insertElement', function()
182 var scayt_instance
= plugin
.getScayt( editor
);
183 if ( plugin
.isScaytEnabled( editor
) )
185 // Unlock the selection before reload, SCAYT will take
186 // care selection update.
187 if ( CKEDITOR
.env
.ie
)
188 editor
.getSelection().unlock( true );
190 // Return focus to the editor and refresh SCAYT markup (#5573).
191 window
.setTimeout( function()
193 scayt_instance
.focus();
194 scayt_instance
.refresh();
199 editor
.on( 'insertHtml', function()
201 var scayt_instance
= plugin
.getScayt( editor
);
202 if ( plugin
.isScaytEnabled( editor
) )
204 // Unlock the selection before reload, SCAYT will take
205 // care selection update.
206 if ( CKEDITOR
.env
.ie
)
207 editor
.getSelection().unlock( true );
209 // Return focus to the editor (#5573)
210 // Refresh SCAYT markup
211 window
.setTimeout( function()
213 scayt_instance
.focus();
214 scayt_instance
.refresh();
219 editor
.on( 'scaytDialog', function( ev
) // Communication with dialog.
221 ev
.data
.djConfig
= window
.djConfig
;
222 ev
.data
.scayt_control
= plugin
.getScayt( editor
);
223 ev
.data
.tab
= openPage
;
224 ev
.data
.scayt
= window
.scayt
;
227 var dataProcessor
= editor
.dataProcessor
,
228 htmlFilter
= dataProcessor
&& dataProcessor
.htmlFilter
;
236 span : function( element
)
238 if ( element
.attributes
[ 'data-scayt_word' ]
239 && element
.attributes
[ 'data-scaytid' ] )
241 delete element
.name
; // Write children, but don't write this node.
250 // Override Image.equals method avoid CK snapshot module to add SCAYT markup to snapshots. (#5546)
251 var undoImagePrototype
= CKEDITOR
.plugins
.undo
.Image
.prototype;
252 undoImagePrototype
.equals
= CKEDITOR
.tools
.override( undoImagePrototype
.equals
, function( org
)
254 return function( otherImage
)
256 var thisContents
= this.contents
,
257 otherContents
= otherImage
.contents
;
258 var scayt_instance
= plugin
.getScayt( this.editor
);
259 // Making the comparison based on content without SCAYT word markers.
260 if ( scayt_instance
&& plugin
.isScaytReady( this.editor
) )
262 // scayt::reset might return value undefined. (#5742)
263 this.contents
= scayt_instance
.reset( thisContents
) || '';
264 otherImage
.contents
= scayt_instance
.reset( otherContents
) || '';
267 var retval
= org
.apply( this, arguments
);
269 this.contents
= thisContents
;
270 otherImage
.contents
= otherContents
;
275 if ( editor
.document
)
279 CKEDITOR
.plugins
.scayt
=
281 engineLoaded
: false,
283 // Data storage for SCAYT control, based on editor instances
285 setControlInfo : function( editor
, o
)
287 if ( editor
&& editor
.name
&& typeof ( this.controlInfo
[ editor
.name
] ) != 'object' )
288 this.controlInfo
[ editor
.name
] = {};
290 for ( var infoOpt
in o
)
291 this.controlInfo
[ editor
.name
][ infoOpt
] = o
[ infoOpt
];
293 isControlRestored : function( editor
)
297 this.controlInfo
[ editor
.name
] )
299 return this.controlInfo
[ editor
.name
].restored
;
303 markControlRestore : function( editor
)
305 this.setControlInfo( editor
, { restored
:true } );
307 setControlId: function( editor
, id
)
309 this.setControlInfo( editor
, { id
:id
} );
311 getControlId: function( editor
)
315 this.controlInfo
[ editor
.name
] &&
316 this.controlInfo
[ editor
.name
].id
)
318 return this.controlInfo
[ editor
.name
].id
;
322 setPaused: function( editor
, bool
)
324 this.setControlInfo( editor
, { paused
:bool
} );
326 isPaused: function( editor
)
330 this.controlInfo
[editor
.name
] )
332 return this.controlInfo
[editor
.name
].paused
;
336 getScayt : function( editor
)
338 return this.instances
[ editor
.name
];
340 isScaytReady : function( editor
)
342 return this.engineLoaded
=== true &&
343 'undefined' !== typeof window
.scayt
&& this.getScayt( editor
);
345 isScaytEnabled : function( editor
)
347 var scayt_instance
= this.getScayt( editor
);
348 return ( scayt_instance
) ? scayt_instance
.disabled
=== false : false;
350 getUiTabs : function( editor
)
354 // read UI tabs value from config
355 var configUiTabs
= editor
.config
.scayt_uiTabs
|| "1,1,1";
357 // convert string to array
358 configUiTabs
= configUiTabs
.split( ',' );
360 // "About us" should be always shown for standard config
361 configUiTabs
[3] = "1";
363 for ( var i
= 0; i
< 4; i
++ ) {
364 uiTabs
[i
] = (typeof window
.scayt
!= "undefined" && typeof window
.scayt
.uiTags
!= "undefined")
365 ? (parseInt(configUiTabs
[i
],10) && window
.scayt
.uiTags
[i
])
366 : parseInt(configUiTabs
[i
],10);
370 loadEngine : function( editor
)
372 // SCAYT doesn't work with Firefox2, Opera and AIR.
373 if ( CKEDITOR
.env
.gecko
&& CKEDITOR
.env
.version
< 10900 || CKEDITOR
.env
.opera
|| CKEDITOR
.env
.air
)
374 return editor
.fire( 'showScaytState' );
376 if ( this.engineLoaded
=== true )
377 return onEngineLoad
.apply( editor
); // Add new instance.
378 else if ( this.engineLoaded
== -1 ) // We are waiting.
379 return CKEDITOR
.on( 'scaytReady', function(){ onEngineLoad
.apply( editor
); } ); // Use function(){} to avoid rejection as duplicate.
381 CKEDITOR
.on( 'scaytReady', onEngineLoad
, editor
);
382 CKEDITOR
.on( 'scaytReady', function()
384 this.engineLoaded
= true;
391 this.engineLoaded
= -1; // Loading in progress.
394 var protocol
= document
.location
.protocol
;
395 // Default to 'http' for unknown.
396 protocol
= protocol
.search( /https?:/) != -1? protocol
: 'http:';
397 var baseUrl
= 'svc.spellchecker.net/scayt26/loader__base.js';
399 var scaytUrl
= editor
.config
.scayt_srcUrl
|| ( protocol
+ '//' + baseUrl
);
400 var scaytConfigBaseUrl
= plugin
.parseUrl( scaytUrl
).path
+ '/';
402 if( window
.scayt
== undefined )
404 CKEDITOR
._djScaytConfig
=
406 baseUrl
: scaytConfigBaseUrl
,
411 CKEDITOR
.fireOnce( 'scaytReady' );
416 // Append javascript code.
417 CKEDITOR
.document
.getHead().append(
418 CKEDITOR
.document
.createElement( 'script',
422 type
: 'text/javascript',
430 CKEDITOR
.fireOnce( 'scaytReady' );
434 parseUrl : function ( data
)
437 if ( data
.match
&& ( match
= data
.match(/(.*)[\/\\](.*?\.\w+)$/) ) )
438 return { path
: match
[1], file
: match
[2] };
444 var plugin
= CKEDITOR
.plugins
.scayt
;
446 // Context menu constructing.
447 var addButtonCommand = function( editor
, buttonName
, buttonLabel
, commandName
, command
, menugroup
, menuOrder
)
449 editor
.addCommand( commandName
, command
);
451 // If the "menu" plugin is loaded, register the menu item.
452 editor
.addMenuItem( commandName
,
455 command
: commandName
,
461 var commandDefinition
=
463 preserveState
: true,
467 exec: function( editor
)
469 if ( plugin
.isScaytReady( editor
) )
471 var isEnabled
= plugin
.isScaytEnabled( editor
);
473 this.setState( isEnabled
? CKEDITOR
.TRISTATE_OFF
: CKEDITOR
.TRISTATE_ON
);
475 var scayt_control
= plugin
.getScayt( editor
);
476 // the place where the status of editor focus should be restored
477 // after there will be ability to store its state before SCAYT button click
478 // if (storedFocusState is focused )
479 // scayt_control.focus();
481 // now focus is set certainly
482 scayt_control
.focus();
483 scayt_control
.setDisabled( isEnabled
);
485 else if ( !editor
.config
.scayt_autoStartup
&& plugin
.engineLoaded
>= 0 ) // Load first time
487 this.setState( CKEDITOR
.TRISTATE_DISABLED
);
488 plugin
.loadEngine( editor
);
494 CKEDITOR
.plugins
.add( 'scayt',
496 requires
: [ 'menubutton' ],
498 beforeInit : function( editor
)
500 var items_order
= editor
.config
.scayt_contextMenuItemsOrder
501 || 'suggest|moresuggest|control',
502 items_order_str
= "";
504 items_order
= items_order
.split( '|' );
506 if ( items_order
&& items_order
.length
)
508 for ( var pos
= 0 ; pos
< items_order
.length
; pos
++ )
509 items_order_str
+= 'scayt_' + items_order
[ pos
] + ( items_order
.length
!= parseInt( pos
, 10 ) + 1 ? ',' : '' );
512 // Put it on top of all context menu items (#5717)
513 editor
.config
.menu_groups
= items_order_str
+ ',' + editor
.config
.menu_groups
;
516 init : function( editor
)
518 // Delete span[data-scaytid] when text pasting in editor (#6921)
519 var dataFilter
= editor
.dataProcessor
&& editor
.dataProcessor
.dataFilter
;
520 var dataFilterRules
=
524 span : function( element
)
526 var attrs
= element
.attributes
;
527 if ( attrs
&& attrs
[ 'data-scaytid' ] )
532 dataFilter
&& dataFilter
.addRules( dataFilterRules
);
534 var moreSuggestions
= {},
535 mainSuggestions
= {};
538 var command
= editor
.addCommand( commandName
, commandDefinition
);
540 // Add Options dialog.
541 CKEDITOR
.dialog
.add( commandName
, CKEDITOR
.getUrl( this.path
+ 'dialogs/options.js' ) );
543 var uiTabs
= plugin
.getUiTabs( editor
);
545 var menuGroup
= 'scaytButton';
546 editor
.addMenuGroup( menuGroup
);
547 // combine menu items to render
548 var uiMenuItems
= {};
550 var lang
= editor
.lang
.scayt
;
553 uiMenuItems
.scaytToggle
=
556 command
: commandName
,
560 if ( uiTabs
[0] == 1 )
561 uiMenuItems
.scaytOptions
=
563 label
: lang
.options
,
567 openPage
= 'options';
568 editor
.openDialog( commandName
);
572 if ( uiTabs
[1] == 1 )
573 uiMenuItems
.scaytLangs
=
580 editor
.openDialog( commandName
);
583 if ( uiTabs
[2] == 1 )
584 uiMenuItems
.scaytDict
=
586 label
: lang
.dictionariesTab
,
590 openPage
= 'dictionaries';
591 editor
.openDialog( commandName
);
595 uiMenuItems
.scaytAbout
=
597 label
: editor
.lang
.scayt
.about
,
602 editor
.openDialog( commandName
);
606 editor
.addMenuItems( uiMenuItems
);
608 editor
.ui
.add( 'Scayt', CKEDITOR
.UI_MENUBUTTON
,
611 title
: CKEDITOR
.env
.opera
? lang
.opera_title
: lang
.title
,
612 className
: 'cke_button_scayt',
613 modes
: { wysiwyg
: 1 },
616 command
.on( 'state', function()
618 this.setState( command
.state
);
624 var isEnabled
= plugin
.isScaytEnabled( editor
);
626 editor
.getMenuItem( 'scaytToggle' ).label
= lang
[ isEnabled
? 'disable' : 'enable' ];
628 var uiTabs
= plugin
.getUiTabs( editor
);
631 scaytToggle
: CKEDITOR
.TRISTATE_OFF
,
632 scaytOptions
: isEnabled
&& uiTabs
[0] ? CKEDITOR
.TRISTATE_OFF
: CKEDITOR
.TRISTATE_DISABLED
,
633 scaytLangs
: isEnabled
&& uiTabs
[1] ? CKEDITOR
.TRISTATE_OFF
: CKEDITOR
.TRISTATE_DISABLED
,
634 scaytDict
: isEnabled
&& uiTabs
[2] ? CKEDITOR
.TRISTATE_OFF
: CKEDITOR
.TRISTATE_DISABLED
,
635 scaytAbout
: isEnabled
&& uiTabs
[3] ? CKEDITOR
.TRISTATE_OFF
: CKEDITOR
.TRISTATE_DISABLED
640 // If the "contextmenu" plugin is loaded, register the listeners.
641 if ( editor
.contextMenu
&& editor
.addMenuItems
)
643 editor
.contextMenu
.addListener( function( element
, selection
)
645 if ( !plugin
.isScaytEnabled( editor
)
646 || selection
.getRanges()[ 0 ].checkReadOnly() )
649 var scayt_control
= plugin
.getScayt( editor
),
650 node
= scayt_control
.getScaytNode();
655 var word
= scayt_control
.getWord( node
);
660 var sLang
= scayt_control
.getLang(),
662 items_suggestion
= window
.scayt
.getSuggestion( word
, sLang
);
663 if ( !items_suggestion
|| !items_suggestion
.length
)
665 // Remove unused commands and menuitems
666 for ( var m
in moreSuggestions
)
668 delete editor
._
.menuItems
[ m
];
669 delete editor
._
.commands
[ m
];
671 for ( m
in mainSuggestions
)
673 delete editor
._
.menuItems
[ m
];
674 delete editor
._
.commands
[ m
];
676 moreSuggestions
= {}; // Reset items.
677 mainSuggestions
= {};
679 var moreSuggestionsUnable
= editor
.config
.scayt_moreSuggestions
|| 'on';
680 var moreSuggestionsUnableAdded
= false;
682 var maxSuggestions
= editor
.config
.scayt_maxSuggestions
;
683 ( typeof maxSuggestions
!= 'number' ) && ( maxSuggestions
= 5 );
684 !maxSuggestions
&& ( maxSuggestions
= items_suggestion
.length
);
686 var contextCommands
= editor
.config
.scayt_contextCommands
|| 'all';
687 contextCommands
= contextCommands
.split( '|' );
689 for ( var i
= 0, l
= items_suggestion
.length
; i
< l
; i
+= 1 )
691 var commandName
= 'scayt_suggestion_' + items_suggestion
[i
].replace( ' ', '_' );
692 var exec
= ( function( el
, s
)
697 scayt_control
.replace( el
, s
);
700 })( node
, items_suggestion
[i
] );
702 if ( i
< maxSuggestions
)
704 addButtonCommand( editor
, 'button_' + commandName
, items_suggestion
[i
],
705 commandName
, exec
, 'scayt_suggest', i
+ 1 );
706 _r
[ commandName
] = CKEDITOR
.TRISTATE_OFF
;
707 mainSuggestions
[ commandName
] = CKEDITOR
.TRISTATE_OFF
;
709 else if ( moreSuggestionsUnable
== 'on' )
711 addButtonCommand( editor
, 'button_' + commandName
, items_suggestion
[i
],
712 commandName
, exec
, 'scayt_moresuggest', i
+ 1 );
713 moreSuggestions
[ commandName
] = CKEDITOR
.TRISTATE_OFF
;
714 moreSuggestionsUnableAdded
= true;
718 if ( moreSuggestionsUnableAdded
)
720 // Register the More suggestions group;
721 editor
.addMenuItem( 'scayt_moresuggest',
723 label
: lang
.moreSuggestions
,
724 group
: 'scayt_moresuggest',
726 getItems : function()
728 return moreSuggestions
;
731 mainSuggestions
[ 'scayt_moresuggest' ] = CKEDITOR
.TRISTATE_OFF
;
734 if ( in_array( 'all', contextCommands
) || in_array( 'ignore', contextCommands
) )
736 var ignore_command
= {
738 scayt_control
.ignore( node
);
741 addButtonCommand( editor
, 'ignore', lang
.ignore
, 'scayt_ignore', ignore_command
, 'scayt_control', 1 );
742 mainSuggestions
[ 'scayt_ignore' ] = CKEDITOR
.TRISTATE_OFF
;
745 if ( in_array( 'all', contextCommands
) || in_array( 'ignoreall', contextCommands
) )
747 var ignore_all_command
= {
749 scayt_control
.ignoreAll( node
);
752 addButtonCommand(editor
, 'ignore_all', lang
.ignoreAll
, 'scayt_ignore_all', ignore_all_command
, 'scayt_control', 2);
753 mainSuggestions
['scayt_ignore_all'] = CKEDITOR
.TRISTATE_OFF
;
756 if ( in_array( 'all', contextCommands
) || in_array( 'add', contextCommands
) )
758 var addword_command
= {
760 window
.scayt
.addWordToUserDictionary( node
);
763 addButtonCommand(editor
, 'add_word', lang
.addWord
, 'scayt_add_word', addword_command
, 'scayt_control', 3);
764 mainSuggestions
['scayt_add_word'] = CKEDITOR
.TRISTATE_OFF
;
767 if ( scayt_control
.fireOnContextMenu
)
768 scayt_control
.fireOnContextMenu( editor
);
770 return mainSuggestions
;
774 var showInitialState = function()
776 editor
.removeListener( 'showScaytState', showInitialState
);
778 if ( !CKEDITOR
.env
.opera
&& !CKEDITOR
.env
.air
)
779 command
.setState( plugin
.isScaytEnabled( editor
) ? CKEDITOR
.TRISTATE_ON
: CKEDITOR
.TRISTATE_OFF
);
781 command
.setState( CKEDITOR
.TRISTATE_DISABLED
);
784 editor
.on( 'showScaytState', showInitialState
);
786 if ( CKEDITOR
.env
.opera
|| CKEDITOR
.env
.air
)
788 editor
.on( 'instanceReady', function()
795 if ( editor
.config
.scayt_autoStartup
)
797 editor
.on( 'instanceReady', function()
799 plugin
.loadEngine( editor
);
804 afterInit : function( editor
)
806 // Prevent word marker line from displaying in elements path and been removed when cleaning format. (#3570) (#4125)
807 var elementsPathFilters
,
808 scaytFilter = function( element
)
810 if ( element
.hasAttribute( 'data-scaytid' ) )
814 if ( editor
._
.elementsPath
&& ( elementsPathFilters
= editor
._
.elementsPath
.filters
) )
815 elementsPathFilters
.push( scaytFilter
);
817 editor
.addRemoveFormatFilter
&& editor
.addRemoveFormatFilter( scaytFilter
);
824 * If enabled (true), turns on SCAYT automatically after loading the editor.
825 * @name CKEDITOR.config.scayt_autoStartup
829 * config.scayt_autoStartup = true;
833 * Defines the number of SCAYT suggestions to show in the main context menu.
834 * The possible values are:
836 * <li>0 (zero): All suggestions are displayed in the main context menu.</li>
837 * <li>Positive number: The maximum number of suggestions to shown in context
838 * menu. Other entries will be shown in "More Suggestions" sub-menu.</li>
839 * <li>Negative number: No suggestions are shown in the main context menu. All
840 * entries will be listed in the "Suggestions" sub-menu.</li>
842 * @name CKEDITOR.config.scayt_maxSuggestions
846 * // Display only three suggestions in the main context menu.
847 * config.scayt_maxSuggestions = 3;
849 * // Do not show the suggestions directly.
850 * config.scayt_maxSuggestions = -1;
854 * Sets the customer ID for SCAYT. Required for migration from free version
855 * with banner to paid version.
856 * @name CKEDITOR.config.scayt_customerid
860 * // Load SCAYT using my customer ID.
861 * config.scayt_customerid = 'your-encrypted-customer-id';
865 * Enables/disables the "More Suggestions" sub-menu in the context menu.
866 * The possible values are "on" or "off".
867 * @name CKEDITOR.config.scayt_moreSuggestions
871 * // Disables the "More Suggestions" sub-menu.
872 * config.scayt_moreSuggestions = 'off';
876 * Customizes the display of SCAYT context menu commands ("Add Word", "Ignore"
877 * and "Ignore All"). It must be a string with one or more of the following
878 * words separated by a pipe ("|"):
880 * <li>"off": disables all options.</li>
881 * <li>"all": enables all options.</li>
882 * <li>"ignore": enables the "Ignore" option.</li>
883 * <li>"ignoreall": enables the "Ignore All" option.</li>
884 * <li>"add": enables the "Add Word" option.</li>
886 * @name CKEDITOR.config.scayt_contextCommands
890 * // Show only "Add Word" and "Ignore All" in the context menu.
891 * config.scayt_contextCommands = 'add|ignoreall';
895 * Sets the default spellchecking language for SCAYT.
896 * @name CKEDITOR.config.scayt_sLang
900 * // Sets SCAYT to German.
901 * config.scayt_sLang = 'de_DE';
905 * Sets the visibility of the SCAYT tabs in the settings dialog and toolbar
906 * button. The value must contain a "1" (enabled) or "0" (disabled) number for
907 * each of the following entries, in this precise order, separated by a
908 * comma (","): "Options", "Languages" and "Dictionary".
909 * @name CKEDITOR.config.scayt_uiTabs
913 * // Hide the "Languages" tab.
914 * config.scayt_uiTabs = '1,0,1';
919 * Set the URL to SCAYT core. Required to switch to licensed version of SCAYT application.
920 * Further details at http://wiki.spellchecker.net/doku.php?id=3rd:wysiwyg:fckeditor:wscckf3l .
921 * @name CKEDITOR.config.scayt_srcUrl
925 * config.scayt_srcUrl = "http://my-host/spellcheck/lf/scayt/scayt.js";
929 * Links SCAYT to custom dictionaries. It's a string containing dictionary ids
930 * separared by commas (","). Available only for licensed version.
931 * Further details at http://wiki.spellchecker.net/doku.php?id=custom_dictionary_support .
932 * @name CKEDITOR.config.scayt_customDictionaryIds
936 * config.scayt_customDictionaryIds = '3021,3456,3478"';
940 * Makes it possible to activate a custom dictionary on SCAYT. The user
941 * dictionary name must be used. Available only for licensed version.
942 * @name CKEDITOR.config.scayt_userDictionaryName
946 * config.scayt_userDictionaryName = 'MyDictionary';
950 * Define order of placing of SCAYT context menu items by groups.
951 * It must be a string with one or more of the following
952 * words separated by a pipe ("|"):
954 * <li>'suggest' - main suggestion word list,</li>
955 * <li>'moresuggest' - more suggestions word list,</li>
956 * <li>'control' - SCAYT commands, such as 'Ignore' and 'Add Word'</li>
959 * @name CKEDITOR.config.scayt_contextMenuItemsOrder
961 * @default 'suggest|moresuggest|control'
963 * config.scayt_contextMenuItemsOrder = 'moresuggest|control|suggest';