Nation Notes module contributed by Z&H Healthcare.
[openemr.git] / library / custom_template / ckeditor / _source / plugins / scayt / plugin.js
blob757fd2134c8e2fc43c9d4281aa32e2312f21462e
1 /*
2 Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
3 For licensing, see LICENSE.html or http://ckeditor.com/license
4 */
6 /**
7  * @fileOverview Spell Check As You Type (SCAYT).
8  * Button name : Scayt.
9  */
11 (function()
13         var commandName  = 'scaytcheck',
14                 openPage = '';
16         // Checks if a value exists in an array
17         function in_array( needle, haystack )
18         {
19                 var found = 0,
20                         key;
21                 for ( key in haystack )
22                 {
23                         if ( haystack[ key ] == needle )
24                         {
25                                 found = 1;
26                                 break;
27                         }
28                 }
29                 return found;
30         }
32         var onEngineLoad = function()
33         {
34                 var editor = this;
36                 var createInstance = function() // Create new instance every time Document is created.
37                 {
38                         var config = editor.config;
39                         // Initialise Scayt instance.
40                         var oParams = {};
41                         // Get the iframe.
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()
52                                 {
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 ) )
60                                                 this.focus();
62                                 };
64                         oParams.onBeforeChange = function()
65                         {
66                                 if ( plugin.getScayt( editor ) && !editor.checkDirty() )
67                                         setTimeout( function(){ editor.resetDirty(); }, 0 );
68                         };
70                         var scayt_custom_params = window.scayt_custom_params;
71                         if ( typeof scayt_custom_params == 'object' )
72                         {
73                                 for ( var k in scayt_custom_params )
74                                         oParams[ k ] = scayt_custom_params[ k ];
75                         }
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 )
83                         {
84                                 ( new CKEDITOR.dom.element( node, scayt_control.document ) ).mergeSiblings();
85                         } );
87                         // Copy config.
88                         var lastInstance = plugin.instances[ editor.name ];
89                         if ( lastInstance )
90                         {
91                                 scayt_control.sLang = lastInstance.sLang;
92                                 scayt_control.option( lastInstance.option() );
93                                 scayt_control.paused = lastInstance.paused;
94                         }
96                         plugin.instances[ editor.name ] = scayt_control;
98                         //window.scayt.uiTags
99                         var menuGroup = 'scaytButton';
100                         var uiTabs = window.scayt.uiTags;
101                         var fTabs  = [];
103                         for ( var i = 0, l=4; i < l; i++ )
104                             fTabs.push( uiTabs[i] && plugin.uiTabs[i] );
106                         plugin.uiTabs = fTabs;
107                         try {
108                                 scayt_control.setDisabled( plugin.isPaused( editor ) === false );
109                         } catch (e) {}
111                         editor.fire( 'showScaytState' );
112                 };
114                 editor.on( 'contentDom', createInstance );
115                 editor.on( 'contentDomUnload', function()
116                         {
117                                 // Remove scripts.
118                                 var scripts = CKEDITOR.document.getElementsByTag( 'script' ),
119                                         scaytIdRegex =  /^dojoIoScript(\d+)$/i,
120                                         scaytSrcRegex =  /^https?:\/\/svc\.spellchecker\.net\/spellcheck\/script\/ssrv\.cgi/i;
122                                 for ( var i=0; i < scripts.count(); i++ )
123                                 {
124                                         var script = scripts.getItem( i ),
125                                                 id = script.getId(),
126                                                 src = script.getAttribute( 'src' );
128                                         if ( id && src && id.match( scaytIdRegex ) && src.match( scaytSrcRegex ))
129                                                 script.remove();
130                                 }
131                         });
133                 editor.on( 'beforeCommandExec', function( ev )          // Disable SCAYT before Source command execution.
134                         {
135                                 if ( ( ev.data.name == 'source' || ev.data.name == 'newpage' ) && editor.mode == 'wysiwyg' )
136                                 {
137                                         var scayt_instance = plugin.getScayt( editor );
138                                         if ( scayt_instance )
139                                         {
140                                                 plugin.setPaused( editor, !scayt_instance.disabled );
141                                                 // store a control id for restore a specific scayt control settings
142                                                 plugin.setControlId( editor, scayt_instance.id );
143                                                 scayt_instance.destroy( true );
144                                                 delete plugin.instances[ editor.name ];
145                                         }
146                                 }
147                                 // Catch on source mode switch off (#5720)
148                                 else if ( ev.data.name == 'source'  && editor.mode == 'source' )
149                                         plugin.markControlRestore( editor );
150                         });
152                 editor.on( 'afterCommandExec', function( ev )
153                         {
154                                 if ( !plugin.isScaytEnabled( editor ) )
155                                         return;
157                                 if ( editor.mode == 'wysiwyg' && ( ev.data.name == 'undo' || ev.data.name == 'redo' ) )
158                                         window.setTimeout( function() { plugin.getScayt( editor ).refresh(); }, 10 );
159                         });
161                 editor.on( 'destroy', function( ev )
162                         {
163                                 var editor = ev.editor,
164                                         scayt_instance = plugin.getScayt( editor );
166                                 // SCAYT instance might already get destroyed by mode switch (#5744).
167                                 if ( !scayt_instance )
168                                         return;
170                                 delete plugin.instances[ editor.name ];
171                                 // store a control id for restore a specific scayt control settings
172                                 plugin.setControlId( editor, scayt_instance.id );
173                                 scayt_instance.destroy( true );
174                         });
176                 // Listen to data manipulation to reflect scayt markup.
177                 editor.on( 'afterSetData', function()
178                         {
179                                 if ( plugin.isScaytEnabled( editor ) ) {
180                                         window.setTimeout( function()
181                                                 {
182                                                         var instance = plugin.getScayt( editor );
183                                                         instance && instance.refresh();
184                                                 }, 10 );
185                                 }
186                         });
188                 // Reload spell-checking for current word after insertion completed.
189                 editor.on( 'insertElement', function()
190                         {
191                                 var scayt_instance = plugin.getScayt( editor );
192                                 if ( plugin.isScaytEnabled( editor ) )
193                                 {
194                                         // Unlock the selection before reload, SCAYT will take
195                                         // care selection update.
196                                         if ( CKEDITOR.env.ie )
197                                                 editor.getSelection().unlock( true );
199                                         // Return focus to the editor and refresh SCAYT markup (#5573).
200                                         window.setTimeout( function()
201                                         {
202                                                 scayt_instance.focus();
203                                                 scayt_instance.refresh();
204                                         }, 10 );
205                                 }
206                         }, this, null, 50 );
208                 editor.on( 'insertHtml', function()
209                         {
210                                 var scayt_instance = plugin.getScayt( editor );
211                                 if ( plugin.isScaytEnabled( editor ) )
212                                 {
213                                         // Unlock the selection before reload, SCAYT will take
214                                         // care selection update.
215                                         if ( CKEDITOR.env.ie )
216                                                 editor.getSelection().unlock( true );
218                                         // Return focus to the editor (#5573)
219                                         // Refresh SCAYT markup
220                                         window.setTimeout( function()
221                                         {
222                                                 scayt_instance.focus();
223                                                 scayt_instance.refresh();
224                                         }, 10 );
225                                 }
226                         }, this, null, 50 );
228                 editor.on( 'scaytDialog', function( ev )        // Communication with dialog.
229                         {
230                                 ev.data.djConfig = window.djConfig;
231                                 ev.data.scayt_control = plugin.getScayt( editor );
232                                 ev.data.tab = openPage;
233                                 ev.data.scayt = window.scayt;
234                         });
236                 var dataProcessor = editor.dataProcessor,
237                         htmlFilter = dataProcessor && dataProcessor.htmlFilter;
239                 if ( htmlFilter )
240                 {
241                         htmlFilter.addRules(
242                                 {
243                                         elements :
244                                         {
245                                                 span : function( element )
246                                                 {
247                                                         if ( element.attributes[ 'data-scayt_word' ]
248                                                                         && element.attributes[ 'data-scaytid' ] )
249                                                         {
250                                                                 delete element.name;    // Write children, but don't write this node.
251                                                                 return element;
252                                                         }
253                                                 }
254                                         }
255                                 }
256                         );
257                 }
259                 // Override Image.equals method avoid CK snapshot module to add SCAYT markup to snapshots. (#5546)
260                 var undoImagePrototype = CKEDITOR.plugins.undo.Image.prototype;
261                 undoImagePrototype.equals = CKEDITOR.tools.override( undoImagePrototype.equals, function( org )
262                 {
263                         return function( otherImage )
264                         {
265                                 var thisContents = this.contents,
266                                         otherContents = otherImage.contents;
267                                 var scayt_instance = plugin.getScayt( this.editor );
268                                 // Making the comparison based on content without SCAYT word markers.
269                                 if ( scayt_instance && plugin.isScaytReady( this.editor ) )
270                                 {
271                                         // scayt::reset might return value undefined. (#5742)
272                                         this.contents = scayt_instance.reset( thisContents ) || '';
273                                         otherImage.contents = scayt_instance.reset( otherContents ) || '';
274                                 }
276                                 var retval = org.apply( this, arguments );
278                                 this.contents = thisContents;
279                                 otherImage.contents = otherContents;
280                                 return retval;
281                         };
282                 });
284                 if ( editor.document )
285                         createInstance();
286         };
288 CKEDITOR.plugins.scayt =
289         {
290                 engineLoaded : false,
291                 instances : {},
292                 // Data storage for SCAYT control, based on editor instances
293                 controlInfo : {},
294                 setControlInfo : function( editor, o )
295                 {
296                         if ( editor && editor.name && typeof ( this.controlInfo[ editor.name ] ) != 'object' )
297                                 this.controlInfo[ editor.name ] = {};
299                         for ( var infoOpt in o )
300                                 this.controlInfo[ editor.name ][ infoOpt ] = o[ infoOpt ];
301                 },
302                 isControlRestored : function( editor )
303                 {
304                         if ( editor &&
305                                         editor.name &&
306                                         this.controlInfo[ editor.name ] )
307                         {
308                                 return this.controlInfo[ editor.name ].restored ;
309                         }
310                         return false;
311                 },
312                 markControlRestore : function( editor )
313                 {
314                         this.setControlInfo( editor, { restored:true } );
315                 },
316                 setControlId: function( editor, id )
317                 {
318                         this.setControlInfo( editor, { id:id } );
319                 },
320                 getControlId: function( editor )
321                 {
322                         if ( editor &&
323                                         editor.name &&
324                                         this.controlInfo[ editor.name ] &&
325                                         this.controlInfo[ editor.name ].id )
326                         {
327                                 return this.controlInfo[ editor.name ].id;
328                         }
329                         return null;
330                 },
331                 setPaused: function( editor , bool )
332                 {
333                         this.setControlInfo( editor, { paused:bool } );
334                 },
335                 isPaused: function( editor )
336                 {
337                         if ( editor &&
338                                         editor.name &&
339                                         this.controlInfo[editor.name] )
340                         {
341                                 return this.controlInfo[editor.name].paused;
342                         }
343                         return undefined;
344                 },
345                 getScayt : function( editor )
346                 {
347                         return this.instances[ editor.name ];
348                 },
349                 isScaytReady : function( editor )
350                 {
351                         return this.engineLoaded === true &&
352                                 'undefined' !== typeof window.scayt && this.getScayt( editor );
353                 },
354                 isScaytEnabled : function( editor )
355                 {
356                         var scayt_instance = this.getScayt( editor );
357                         return ( scayt_instance ) ? scayt_instance.disabled === false : false;
358                 },
359                 loadEngine : function( editor )
360                 {
361                         // SCAYT doesn't work with Firefox2, Opera and AIR.
362                         if ( CKEDITOR.env.gecko && CKEDITOR.env.version < 10900 || CKEDITOR.env.opera || CKEDITOR.env.air )
363                                 return editor.fire( 'showScaytState' );
365                         if ( this.engineLoaded === true )
366                                 return onEngineLoad.apply( editor );    // Add new instance.
367                         else if ( this.engineLoaded == -1 )                     // We are waiting.
368                                 return CKEDITOR.on( 'scaytReady', function(){ onEngineLoad.apply( editor ); } );        // Use function(){} to avoid rejection as duplicate.
370                         CKEDITOR.on( 'scaytReady', onEngineLoad, editor );
371                         CKEDITOR.on( 'scaytReady', function()
372                                 {
373                                         this.engineLoaded = true;
374                                 },
375                                 this,
376                                 null,
377                                 0
378                         );      // First to run.
380                         this.engineLoaded = -1; // Loading in progress.
382                         // compose scayt url
383                         var protocol = document.location.protocol;
384                         // Default to 'http' for unknown.
385                         protocol = protocol.search( /https?:/) != -1? protocol : 'http:';
386                         var baseUrl  = 'svc.spellchecker.net/scayt26/loader__base.js';
388                         var scaytUrl  =  editor.config.scayt_srcUrl || ( protocol + '//' + baseUrl );
389                         var scaytConfigBaseUrl =  plugin.parseUrl( scaytUrl ).path +  '/';
391                         if( window.scayt == undefined )
392                         {
393                                 CKEDITOR._djScaytConfig =
394                                 {
395                                         baseUrl: scaytConfigBaseUrl,
396                                         addOnLoad:
397                                         [
398                                                 function()
399                                                 {
400                                                         CKEDITOR.fireOnce( 'scaytReady' );
401                                                 }
402                                         ],
403                                         isDebug: false
404                                 };
405                                 // Append javascript code.
406                                 CKEDITOR.document.getHead().append(
407                                         CKEDITOR.document.createElement( 'script',
408                                                 {
409                                                         attributes :
410                                                                 {
411                                                                         type : 'text/javascript',
412                                                                         async : 'true',
413                                                                         src : scaytUrl
414                                                                 }
415                                                 })
416                                 );
417                         }
418                         else
419                                 CKEDITOR.fireOnce( 'scaytReady' );
421                         return null;
422                 },
423                 parseUrl : function ( data )
424                 {
425                         var match;
426                         if ( data.match && ( match = data.match(/(.*)[\/\\](.*?\.\w+)$/) ) )
427                                 return { path: match[1], file: match[2] };
428                         else
429                                 return data;
430                 }
431         };
433         var plugin = CKEDITOR.plugins.scayt;
435         // Context menu constructing.
436         var addButtonCommand = function( editor, buttonName, buttonLabel, commandName, command, menugroup, menuOrder )
437         {
438                 editor.addCommand( commandName, command );
440                 // If the "menu" plugin is loaded, register the menu item.
441                 editor.addMenuItem( commandName,
442                         {
443                                 label : buttonLabel,
444                                 command : commandName,
445                                 group : menugroup,
446                                 order : menuOrder
447                         });
448         };
450         var commandDefinition =
451         {
452                 preserveState : true,
453                 editorFocus : false,
454                 canUndo : false,
456                 exec: function( editor )
457                 {
458                         if ( plugin.isScaytReady( editor ) )
459                         {
460                                 var isEnabled = plugin.isScaytEnabled( editor );
462                                 this.setState( isEnabled ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_ON );
464                                 var scayt_control = plugin.getScayt( editor );
465                                 // the place where the status of editor focus should be restored
466                                 // after there will be ability to store its state before SCAYT button click
467                                 // if (storedFocusState is focused )
468                                 //   scayt_control.focus();
469                                 //
470                                 // now focus is set certainly
471                                 scayt_control.focus();
472                                 scayt_control.setDisabled( isEnabled );
473                         }
474                         else if ( !editor.config.scayt_autoStartup && plugin.engineLoaded >= 0 )        // Load first time
475                         {
476                                 this.setState( CKEDITOR.TRISTATE_DISABLED );
477                                 plugin.loadEngine( editor );
478                         }
479                 }
480         };
482         // Add scayt plugin.
483         CKEDITOR.plugins.add( 'scayt',
484         {
485                 requires : [ 'menubutton' ],
487                 beforeInit : function( editor )
488                 {
489                         var items_order = editor.config.scayt_contextMenuItemsOrder
490                                         || 'suggest|moresuggest|control',
491                                 items_order_str = "";
493                         items_order = items_order.split( '|' );
495                         if ( items_order && items_order.length )
496                         {
497                                 for ( var pos = 0 ; pos < items_order.length ; pos++ )
498                                         items_order_str += 'scayt_' + items_order[ pos ] + ( items_order.length != parseInt( pos, 10 ) + 1 ? ',' : '' );
499                         }
501                         // Put it on top of all context menu items (#5717)
502                         editor.config.menu_groups =  items_order_str + ',' + editor.config.menu_groups;
503                 },
505                 init : function( editor )
506                 {
507                         var moreSuggestions = {},
508                                 mainSuggestions = {};
510                         // Scayt command.
511                         var command = editor.addCommand( commandName, commandDefinition );
513                         // Add Options dialog.
514                         CKEDITOR.dialog.add( commandName, CKEDITOR.getUrl( this.path + 'dialogs/options.js' ) );
515                         // read ui tags
516                         var confuiTabs = editor.config.scayt_uiTabs || '1,1,1';
517                         var uiTabs =[];
518                         // string to array convert
519                         confuiTabs = confuiTabs.split( ',' );
520                         // check array length ! always must be 3 filled with 1 or 0
521                         for ( var i=0, l=3; i < l; i++ )
522                         {
523                                 var flag = parseInt( confuiTabs[i] || '1', 10 );
524                                 uiTabs.push( flag );
525                         }
527                         var menuGroup = 'scaytButton';
528                         editor.addMenuGroup( menuGroup );
529                         // combine menu items to render
530                         var uiMuneItems = {};
532                         var lang = editor.lang.scayt;
534                         // always added
535                         uiMuneItems.scaytToggle =
536                                 {
537                                         label : lang.enable,
538                                         command : commandName,
539                                         group : menuGroup
540                                 };
542                         if ( uiTabs[0] == 1 )
543                                 uiMuneItems.scaytOptions =
544                                 {
545                                         label : lang.options,
546                                         group : menuGroup,
547                                         onClick : function()
548                                         {
549                                                 openPage = 'options';
550                                                 editor.openDialog( commandName );
551                                         }
552                                 };
554                         if ( uiTabs[1] == 1 )
555                                 uiMuneItems.scaytLangs =
556                                 {
557                                         label : lang.langs,
558                                         group : menuGroup,
559                                         onClick : function()
560                                         {
561                                                 openPage = 'langs';
562                                                 editor.openDialog( commandName );
563                                         }
564                                 };
565                         if ( uiTabs[2] == 1 )
566                                 uiMuneItems.scaytDict =
567                                 {
568                                         label : lang.dictionariesTab,
569                                         group : menuGroup,
570                                         onClick : function()
571                                         {
572                                                 openPage = 'dictionaries';
573                                                 editor.openDialog( commandName );
574                                         }
575                                 };
576                         // always added
577                         uiMuneItems.scaytAbout =
578                                 {
579                                         label : editor.lang.scayt.about,
580                                         group : menuGroup,
581                                         onClick : function()
582                                         {
583                                                 openPage = 'about';
584                                                 editor.openDialog( commandName );
585                                         }
586                                 };
588                         uiTabs[3] = 1; // about us tab is always on
589                         plugin.uiTabs = uiTabs;
591                         editor.addMenuItems( uiMuneItems );
593                                 editor.ui.add( 'Scayt', CKEDITOR.UI_MENUBUTTON,
594                                         {
595                                                 label : lang.title,
596                                                 title : CKEDITOR.env.opera ? lang.opera_title : lang.title,
597                                                 className : 'cke_button_scayt',
598                                                 modes : { wysiwyg : 1 },
599                                                 onRender: function()
600                                                 {
601                                                         command.on( 'state', function()
602                                                         {
603                                                                 this.setState( command.state );
604                                                         },
605                                                         this);
606                                                 },
607                                                 onMenu : function()
608                                                 {
609                                                         var isEnabled = plugin.isScaytEnabled( editor );
611                                                         editor.getMenuItem( 'scaytToggle' ).label = lang[ isEnabled ? 'disable' : 'enable' ];
613                                                         return {
614                                                                 scaytToggle  : CKEDITOR.TRISTATE_OFF,
615                                                                 scaytOptions : isEnabled && plugin.uiTabs[0] ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED,
616                                                                 scaytLangs   : isEnabled && plugin.uiTabs[1] ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED,
617                                                                 scaytDict    : isEnabled && plugin.uiTabs[2] ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED,
618                                                                 scaytAbout   : isEnabled && plugin.uiTabs[3] ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED
619                                                         };
620                                                 }
621                                         });
623                         // If the "contextmenu" plugin is loaded, register the listeners.
624                         if ( editor.contextMenu && editor.addMenuItems )
625                         {
626                                 editor.contextMenu.addListener( function( element, selection )
627                                         {
628                                                 if ( !plugin.isScaytEnabled( editor )
629                                                                 || selection.getRanges()[ 0 ].checkReadOnly() )
630                                                         return null;
632                                                 var scayt_control = plugin.getScayt( editor ),
633                                                         node = scayt_control.getScaytNode();
635                                                 if ( !node )
636                                                         return null;
638                                                         var word = scayt_control.getWord( node );
640                                                 if ( !word )
641                                                         return null;
643                                                 var sLang = scayt_control.getLang(),
644                                                         _r = {},
645                                                         items_suggestion = window.scayt.getSuggestion( word, sLang );
646                                                 if ( !items_suggestion || !items_suggestion.length )
647                                                         return null;
648                                                 // Remove unused commands and menuitems
649                                                 for ( i in moreSuggestions )
650                                                 {
651                                                         delete editor._.menuItems[ i ];
652                                                         delete editor._.commands[ i ];
653                                                 }
654                                                 for ( i in mainSuggestions )
655                                                 {
656                                                         delete editor._.menuItems[ i ];
657                                                         delete editor._.commands[ i ];
658                                                 }
659                                                 moreSuggestions = {};           // Reset items.
660                                                 mainSuggestions = {};
662                                                 var moreSuggestionsUnable = editor.config.scayt_moreSuggestions || 'on';
663                                                 var moreSuggestionsUnableAdded = false;
665                                                 var maxSuggestions = editor.config.scayt_maxSuggestions;
666                                                 ( typeof maxSuggestions != 'number' ) && ( maxSuggestions = 5 );
667                                                 !maxSuggestions && ( maxSuggestions = items_suggestion.length );
669                                                 var contextCommands = editor.config.scayt_contextCommands || 'all';
670                                                 contextCommands = contextCommands.split( '|' );
672                                                 for ( var i = 0, l = items_suggestion.length; i < l; i += 1 )
673                                                 {
674                                                         var commandName = 'scayt_suggestion_' + items_suggestion[i].replace( ' ', '_' );
675                                                         var exec = ( function( el, s )
676                                                                 {
677                                                                         return {
678                                                                                 exec: function()
679                                                                                 {
680                                                                                         scayt_control.replace( el, s );
681                                                                                 }
682                                                                         };
683                                                                 })( node, items_suggestion[i] );
685                                                         if ( i < maxSuggestions )
686                                                         {
687                                                                 addButtonCommand( editor, 'button_' + commandName, items_suggestion[i],
688                                                                         commandName, exec, 'scayt_suggest', i + 1 );
689                                                                 _r[ commandName ] = CKEDITOR.TRISTATE_OFF;
690                                                                 mainSuggestions[ commandName ] = CKEDITOR.TRISTATE_OFF;
691                                                         }
692                                                         else if ( moreSuggestionsUnable == 'on' )
693                                                         {
694                                                                 addButtonCommand( editor, 'button_' + commandName, items_suggestion[i],
695                                                                         commandName, exec, 'scayt_moresuggest', i + 1 );
696                                                                 moreSuggestions[ commandName ] = CKEDITOR.TRISTATE_OFF;
697                                                                 moreSuggestionsUnableAdded = true;
698                                                         }
699                                                 }
701                                                 if ( moreSuggestionsUnableAdded )
702                                                 {
703                                                         // Register the More suggestions group;
704                                                         editor.addMenuItem( 'scayt_moresuggest',
705                                                         {
706                                                                 label : lang.moreSuggestions,
707                                                                 group : 'scayt_moresuggest',
708                                                                 order : 10,
709                                                                 getItems : function()
710                                                                 {
711                                                                         return moreSuggestions;
712                                                                 }
713                                                         });
714                                                         mainSuggestions[ 'scayt_moresuggest' ] = CKEDITOR.TRISTATE_OFF;
715                                                 }
717                                                 if ( in_array( 'all', contextCommands )  || in_array( 'ignore', contextCommands)  )
718                                                 {
719                                                         var ignore_command = {
720                                                                 exec: function(){
721                                                                         scayt_control.ignore( node );
722                                                                 }
723                                                         };
724                                                         addButtonCommand( editor, 'ignore', lang.ignore, 'scayt_ignore', ignore_command, 'scayt_control', 1 );
725                                                         mainSuggestions[ 'scayt_ignore' ] = CKEDITOR.TRISTATE_OFF;
726                                                 }
728                                                 if ( in_array( 'all', contextCommands )  || in_array( 'ignoreall', contextCommands ) )
729                                                 {
730                                                         var ignore_all_command = {
731                                                                 exec: function(){
732                                                                         scayt_control.ignoreAll( node );
733                                                                 }
734                                                         };
735                                                         addButtonCommand(editor, 'ignore_all', lang.ignoreAll, 'scayt_ignore_all', ignore_all_command, 'scayt_control', 2);
736                                                         mainSuggestions['scayt_ignore_all'] = CKEDITOR.TRISTATE_OFF;
737                                                 }
739                                                 if ( in_array( 'all', contextCommands )  || in_array( 'add', contextCommands ) )
740                                                 {
741                                                         var addword_command = {
742                                                                 exec: function(){
743                                                                         window.scayt.addWordToUserDictionary( node );
744                                                                 }
745                                                         };
746                                                         addButtonCommand(editor, 'add_word', lang.addWord, 'scayt_add_word', addword_command, 'scayt_control', 3);
747                                                         mainSuggestions['scayt_add_word'] = CKEDITOR.TRISTATE_OFF;
748                                                 }
750                                                 if ( scayt_control.fireOnContextMenu )
751                                                         scayt_control.fireOnContextMenu( editor );
753                                                 return mainSuggestions;
754                                         });
755                         }
757                         var showInitialState = function()
758                                 {
759                                         editor.removeListener( 'showScaytState', showInitialState );
761                                         if ( !CKEDITOR.env.opera && !CKEDITOR.env.air )
762                                                 command.setState( plugin.isScaytEnabled( editor ) ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF );
763                                         else
764                                                 command.setState( CKEDITOR.TRISTATE_DISABLED );
765                                 };
767                         editor.on( 'showScaytState', showInitialState );
769                         if ( CKEDITOR.env.opera || CKEDITOR.env.air )
770                         {
771                                 editor.on( 'instanceReady', function()
772                                 {
773                                         showInitialState();
774                                 });
775                         }
777                         // Start plugin
778                         if ( editor.config.scayt_autoStartup )
779                         {
780                                 editor.on( 'instanceReady', function()
781                                 {
782                                         plugin.loadEngine( editor );
783                                 });
784                         }
785                 },
787                 afterInit : function( editor )
788                 {
789                         // Prevent word marker line from displaying in elements path and been removed when cleaning format. (#3570) (#4125)
790                         var elementsPathFilters,
791                                         scaytFilter = function( element )
792                                         {
793                                                 if ( element.hasAttribute( 'data-scaytid' ) )
794                                                         return false;
795                                         };
797                         if ( editor._.elementsPath && ( elementsPathFilters = editor._.elementsPath.filters ) )
798                                 elementsPathFilters.push( scaytFilter );
800                         editor.addRemoveFormatFilter && editor.addRemoveFormatFilter( scaytFilter );
802                 }
803         });
804 })();
807  * If enabled (true), turns on SCAYT automatically after loading the editor.
808  * @name CKEDITOR.config.scayt_autoStartup
809  * @type Boolean
810  * @default false
811  * @example
812  * config.scayt_autoStartup = true;
813  */
816  * Defines the number of SCAYT suggestions to show in the main context menu.
817  * The possible values are:
818  * <ul>
819  *      <li>0 (zero): All suggestions are displayed in the main context menu.</li>
820  *      <li>Positive number: The maximum number of suggestions to shown in context
821  *              menu. Other entries will be shown in "More Suggestions" sub-menu.</li>
822  *      <li>Negative number: No suggestions are shown in the main context menu. All
823  *              entries will be listed in the "Suggestions" sub-menu.</li>
824  * </ul>
825  * @name CKEDITOR.config.scayt_maxSuggestions
826  * @type Number
827  * @default 5
828  * @example
829  * // Display only three suggestions in the main context menu.
830  * config.scayt_maxSuggestions = 3;
831  * @example
832  * // Do not show the suggestions directly.
833  * config.scayt_maxSuggestions = -1;
834  */
837  * Sets the customer ID for SCAYT. Required for migration from free version
838  * with banner to paid version.
839  * @name CKEDITOR.config.scayt_customerid
840  * @type String
841  * @default ''
842  * @example
843  * // Load SCAYT using my customer ID.
844  * config.scayt_customerid  = 'your-encrypted-customer-id';
845  */
848  * Enables/disables the "More Suggestions" sub-menu in the context menu.
849  * The possible values are "on" or "off".
850  * @name CKEDITOR.config.scayt_moreSuggestions
851  * @type String
852  * @default 'on'
853  * @example
854  * // Disables the "More Suggestions" sub-menu.
855  * config.scayt_moreSuggestions = 'off';
856  */
859  * Customizes the display of SCAYT context menu commands ("Add Word", "Ignore"
860  * and "Ignore All"). It must be a string with one or more of the following
861  * words separated by a pipe ("|"):
862  * <ul>
863  *      <li>"off": disables all options.</li>
864  *      <li>"all": enables all options.</li>
865  *      <li>"ignore": enables the "Ignore" option.</li>
866  *      <li>"ignoreall": enables the "Ignore All" option.</li>
867  *      <li>"add": enables the "Add Word" option.</li>
868  * </ul>
869  * @name CKEDITOR.config.scayt_contextCommands
870  * @type String
871  * @default 'all'
872  * @example
873  * // Show only "Add Word" and "Ignore All" in the context menu.
874  * config.scayt_contextCommands = 'add|ignoreall';
875  */
878  * Sets the default spellchecking language for SCAYT.
879  * @name CKEDITOR.config.scayt_sLang
880  * @type String
881  * @default 'en_US'
882  * @example
883  * // Sets SCAYT to German.
884  * config.scayt_sLang = 'de_DE';
885  */
888  * Sets the visibility of the SCAYT tabs in the settings dialog and toolbar
889  * button. The value must contain a "1" (enabled) or "0" (disabled) number for
890  * each of the following entries, in this precise order, separated by a
891  * comma (","): "Options", "Languages" and "Dictionary".
892  * @name CKEDITOR.config.scayt_uiTabs
893  * @type String
894  * @default '1,1,1'
895  * @example
896  * // Hide the "Languages" tab.
897  * config.scayt_uiTabs = '1,0,1';
898  */
902  * Set the URL to SCAYT core. Required to switch to licensed version of SCAYT application.
903  * Further details at http://wiki.spellchecker.net/doku.php?id=3rd:wysiwyg:fckeditor:wscckf3l .
904  * @name CKEDITOR.config.scayt_srcUrl
905  * @type String
906  * @default ''
907  * @example
908  * config.scayt_srcUrl = "http://my-host/spellcheck/lf/scayt/scayt.js";
909  */
912  * Links SCAYT to custom dictionaries. It's a string containing dictionary ids
913  * separared by commas (","). Available only for licensed version.
914  * Further details at http://wiki.spellchecker.net/doku.php?id=custom_dictionary_support .
915  * @name CKEDITOR.config.scayt_customDictionaryIds
916  * @type String
917  * @default ''
918  * @example
919  * config.scayt_customDictionaryIds = '3021,3456,3478"';
920  */
923  * Makes it possible to activate a custom dictionary on SCAYT. The user
924  * dictionary name must be used. Available only for licensed version.
925  * @name CKEDITOR.config.scayt_userDictionaryName
926  * @type String
927  * @default ''
928  * @example
929  * config.scayt_userDictionaryName = 'MyDictionary';
930  */
933  * Define order of placing of SCAYT context menu items by groups.
934  * It must be a string with one or more of the following
935  * words separated by a pipe ("|"):
936  * <ul>
937  *     <li>'suggest'     - main suggestion word list,</li>
938  *     <li>'moresuggest' - more suggestions word list,</li>
939  *     <li>'control'     - SCAYT commands, such as 'Ignore' and 'Add Word'</li>
940  * </ul>
942  * @name CKEDITOR.config.scayt_contextMenuItemsOrder
943  * @type String
944  * @default 'suggest|moresuggest|control'
945  * @example
946  * config.scayt_contextMenuItemsOrder = 'moresuggest|control|suggest';
947  */