dojox/editor/plugins/SpellCheck.js

  • Provides:

    • dojox.editor.plugins.SpellCheck
  • Requires:

    • dijit.form.TextBox in common in project dijit
    • dijit.form.DropDownButton in common in project dijit
    • dijit.TooltipDialog in common in project dijit
    • dijit.form.MultiSelect in common in project dijit
    • dojo.io.script in common in project dojo
    • dijit.Menu in common in project dijit
  • dojox.editor.plugins._spellCheckControl

    • type
      Function
    • chains:
      • dijit._Widget: (prototype)
      • dijit._Widget: (call)
      • dijit._Templated: (call)
    • mixins:
      • dijit._Templated.prototype: (prototype)
    • summary
      The widget that is used for the UI of the batch spelling check
    • source: [view]
      dojo.provide("dojox.editor.plugins.SpellCheck");


      dojo.require("dijit.form.TextBox");
      dojo.require("dijit.form.DropDownButton");
      dojo.require("dijit.TooltipDialog");
      dojo.require("dijit.form.MultiSelect");
      dojo.require("dojo.io.script");
      dojo.require("dijit.Menu");


      dojo.requireLocalization("dojox.editor.plugins", "SpellCheck");


      dojo.experimental("dojox.editor.plugins.SpellCheck");


      dojo.declare("dojox.editor.plugins._spellCheckControl", [dijit._Widget, dijit._Templated], {
       // summary:
       //  The widget that is used for the UI of the batch spelling check

       
       widgetsInTemplate: true,

       
       templateString:
        "" +
         "" +
         "" +
          "" +
          "" +
          "" +
         "" +
         "" +
          "" +
          "" +
         "" +
         "" +
          "" +
          "" +
         "" +
         "" +
          "" +
          "" +
          "" +
         "" +
        "
      " +
          "
           "class='dijitEditorSpellCheckBox' dojoAttachPoint='unfoundTextBox' id='${textId}'/>
      " +
           "" +
          "
      " +
           "" +
           "
      " +
          "
      ",

       
       /*************************************************************************/
       /** Framework Methods **/
       /*************************************************************************/
       constructor: function(){
        // Indicate if the textbox ignores the text change event of the textbox
        this.ignoreChange = false;
        // Indicate if the text of the textbox is changed or not
        this.isChanged = false;
        // Indicate if the dialog is open or not
        this.isOpen = false;
        // Indicate if the dialog can be closed
        this.closable = true;
  • dojox.editor.plugins._spellCheckControl.widgetsInTemplate

    • summary
  • dojox.editor.plugins._spellCheckControl.templateString

    • summary
  • dojox.editor.plugins._spellCheckControl.postMixInProperties

    • type
      Function
    • source: [view]
        this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
        this.textId = this.id + "_textBox";
        this.selectId = this.id + "_select";
    • summary
  • dojox.editor.plugins._spellCheckControl.postCreate

    • type
      Function
    • source: [view]
        var select = this.suggestionSelect;

        
        // Customize multi-select to single select
        dojo.removeAttr(select.domNode, "multiple");
        select.addItems = function(/*Array*/ items){
         // summary:
         //  Add items to the select widget
         // items:
         //  An array of items be added to the select
         // tags:
         //  public
         var _this = this;
         var o = null;
         if(items && items.length > 0){
          dojo.forEach(items, function(item, i){
           o = dojo.create("option", {innerHTML: item, value: item}, _this.domNode);
           if(i == 0){
            o.selected = true;
           }
          });
         }
        };
        select.removeItems = function(){
         // summary:
         //  Remove all the items within the select widget
         // tags:
         //  public
         dojo.empty(this.domNode);
        };

       
        select.deselectAll = function(){
         // summary:
         //  De-select all the selected items
         // tags:
         //  public
         this.containerNode.selectedIndex = -1;
        };

        
        // Connect up all the controls with their event handler
        this.connect(this, "onKeyPress", "_cancel");
        this.connect(this.unfoundTextBox, "onKeyPress", "_enter");
        this.connect(this.unfoundTextBox, "onChange", "_unfoundTextBoxChange");
        this.connect(this.suggestionSelect, "onKeyPress", "_enter");
        this.connect(this.skipButton, "onClick", "onSkip");
        this.connect(this.skipAllButton, "onClick", "onSkipAll");
        this.connect(this.toDicButton, "onClick", "onAddToDic");
        this.connect(this.replaceButton, "onClick", "onReplace");
        this.connect(this.replaceAllButton, "onClick", "onReplaceAll");
        this.connect(this.cancelButton, "onClick", "onCancel");
    • summary
  • dojox.editor.plugins._spellCheckControl.onSkip

    • type
      Function
    • source: [view]
      dojo.provide("dojox.editor.plugins.SpellCheck");


      dojo.require("dijit.form.TextBox");
      dojo.require("dijit.form.DropDownButton");
      dojo.require("dijit.TooltipDialog");
      dojo.require("dijit.form.MultiSelect");
      dojo.require("dojo.io.script");
      dojo.require("dijit.Menu");


      dojo.requireLocalization("dojox.editor.plugins", "SpellCheck");


      dojo.experimental("dojox.editor.plugins.SpellCheck");


      dojo.declare("dojox.editor.plugins._spellCheckControl", [dijit._Widget, dijit._Templated], {
       // summary:
       //  The widget that is used for the UI of the batch spelling check

       
       widgetsInTemplate: true,

       
       templateString:
        "" +
         "" +
         "" +
          "" +
          "" +
          "" +
         "" +
         "" +
          "" +
          "" +
         "" +
         "" +
          "" +
          "" +
         "" +
         "" +
          "" +
          "" +
          "" +
         "" +
        "
      " +
          "
           "class='dijitEditorSpellCheckBox' dojoAttachPoint='unfoundTextBox' id='${textId}'/>
      " +
           "" +
          "
      " +
           "" +
           "
      " +
          "
      ",

       
       /*************************************************************************/
       /** Framework Methods **/
       /*************************************************************************/
       constructor: function(){
        // Indicate if the textbox ignores the text change event of the textbox
        this.ignoreChange = false;
        // Indicate if the text of the textbox is changed or not
        this.isChanged = false;
        // Indicate if the dialog is open or not
        this.isOpen = false;
        // Indicate if the dialog can be closed
        this.closable = true;
       },

       
       postMixInProperties: function(){
        this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
        this.textId = this.id + "_textBox";
        this.selectId = this.id + "_select";
       },

       
       postCreate: function(){
        var select = this.suggestionSelect;

        
        // Customize multi-select to single select
        dojo.removeAttr(select.domNode, "multiple");
        select.addItems = function(/*Array*/ items){
         // summary:
         //  Add items to the select widget
         // items:
         //  An array of items be added to the select
         // tags:
         //  public
         var _this = this;
         var o = null;
         if(items && items.length > 0){
          dojo.forEach(items, function(item, i){
           o = dojo.create("option", {innerHTML: item, value: item}, _this.domNode);
           if(i == 0){
            o.selected = true;
           }
          });
         }
        };
        select.removeItems = function(){
         // summary:
         //  Remove all the items within the select widget
         // tags:
         //  public
         dojo.empty(this.domNode);
        };

       
        select.deselectAll = function(){
         // summary:
         //  De-select all the selected items
         // tags:
         //  public
         this.containerNode.selectedIndex = -1;
        };

        
        // Connect up all the controls with their event handler
        this.connect(this, "onKeyPress", "_cancel");
        this.connect(this.unfoundTextBox, "onKeyPress", "_enter");
        this.connect(this.unfoundTextBox, "onChange", "_unfoundTextBoxChange");
        this.connect(this.suggestionSelect, "onKeyPress", "_enter");
        this.connect(this.skipButton, "onClick", "onSkip");
        this.connect(this.skipAllButton, "onClick", "onSkipAll");
        this.connect(this.toDicButton, "onClick", "onAddToDic");
        this.connect(this.replaceButton, "onClick", "onReplace");
        this.connect(this.replaceAllButton, "onClick", "onReplaceAll");
        this.connect(this.cancelButton, "onClick", "onCancel");
       },

       
       /*************************************************************************/
       /** Public Methods **/
       /*************************************************************************/

       
       onSkip: function(){
        // Stub for the click event of the skip button.
    • summary
  • dojox.editor.plugins._spellCheckControl.onSkipAll

    • type
      Function
    • source: [view]
      dojo.provide("dojox.editor.plugins.SpellCheck");


      dojo.require("dijit.form.TextBox");
      dojo.require("dijit.form.DropDownButton");
      dojo.require("dijit.TooltipDialog");
      dojo.require("dijit.form.MultiSelect");
      dojo.require("dojo.io.script");
      dojo.require("dijit.Menu");


      dojo.requireLocalization("dojox.editor.plugins", "SpellCheck");


      dojo.experimental("dojox.editor.plugins.SpellCheck");


      dojo.declare("dojox.editor.plugins._spellCheckControl", [dijit._Widget, dijit._Templated], {
       // summary:
       //  The widget that is used for the UI of the batch spelling check

       
       widgetsInTemplate: true,

       
       templateString:
        "" +
         "" +
         "" +
          "" +
          "" +
          "" +
         "" +
         "" +
          "" +
          "" +
         "" +
         "" +
          "" +
          "" +
         "" +
         "" +
          "" +
          "" +
          "" +
         "" +
        "
      " +
          "
           "class='dijitEditorSpellCheckBox' dojoAttachPoint='unfoundTextBox' id='${textId}'/>
      " +
           "" +
          "
      " +
           "" +
           "
      " +
          "
      ",

       
       /*************************************************************************/
       /** Framework Methods **/
       /*************************************************************************/
       constructor: function(){
        // Indicate if the textbox ignores the text change event of the textbox
        this.ignoreChange = false;
        // Indicate if the text of the textbox is changed or not
        this.isChanged = false;
        // Indicate if the dialog is open or not
        this.isOpen = false;
        // Indicate if the dialog can be closed
        this.closable = true;
       },

       
       postMixInProperties: function(){
        this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
        this.textId = this.id + "_textBox";
        this.selectId = this.id + "_select";
       },

       
       postCreate: function(){
        var select = this.suggestionSelect;

        
        // Customize multi-select to single select
        dojo.removeAttr(select.domNode, "multiple");
        select.addItems = function(/*Array*/ items){
         // summary:
         //  Add items to the select widget
         // items:
         //  An array of items be added to the select
         // tags:
         //  public
         var _this = this;
         var o = null;
         if(items && items.length > 0){
          dojo.forEach(items, function(item, i){
           o = dojo.create("option", {innerHTML: item, value: item}, _this.domNode);
           if(i == 0){
            o.selected = true;
           }
          });
         }
        };
        select.removeItems = function(){
         // summary:
         //  Remove all the items within the select widget
         // tags:
         //  public
         dojo.empty(this.domNode);
        };

       
        select.deselectAll = function(){
         // summary:
         //  De-select all the selected items
         // tags:
         //  public
         this.containerNode.selectedIndex = -1;
        };

        
        // Connect up all the controls with their event handler
        this.connect(this, "onKeyPress", "_cancel");
        this.connect(this.unfoundTextBox, "onKeyPress", "_enter");
        this.connect(this.unfoundTextBox, "onChange", "_unfoundTextBoxChange");
        this.connect(this.suggestionSelect, "onKeyPress", "_enter");
        this.connect(this.skipButton, "onClick", "onSkip");
        this.connect(this.skipAllButton, "onClick", "onSkipAll");
        this.connect(this.toDicButton, "onClick", "onAddToDic");
        this.connect(this.replaceButton, "onClick", "onReplace");
        this.connect(this.replaceAllButton, "onClick", "onReplaceAll");
        this.connect(this.cancelButton, "onClick", "onCancel");
       },

       
       /*************************************************************************/
       /** Public Methods **/
       /*************************************************************************/

       
       onSkip: function(){
        // Stub for the click event of the skip button.
       },

       
       onSkipAll: function(){
        // Stub for the click event of the skipAll button.
    • summary
  • dojox.editor.plugins._spellCheckControl.onAddToDic

    • type
      Function
    • source: [view]
      dojo.provide("dojox.editor.plugins.SpellCheck");


      dojo.require("dijit.form.TextBox");
      dojo.require("dijit.form.DropDownButton");
      dojo.require("dijit.TooltipDialog");
      dojo.require("dijit.form.MultiSelect");
      dojo.require("dojo.io.script");
      dojo.require("dijit.Menu");


      dojo.requireLocalization("dojox.editor.plugins", "SpellCheck");


      dojo.experimental("dojox.editor.plugins.SpellCheck");


      dojo.declare("dojox.editor.plugins._spellCheckControl", [dijit._Widget, dijit._Templated], {
       // summary:
       //  The widget that is used for the UI of the batch spelling check

       
       widgetsInTemplate: true,

       
       templateString:
        "" +
         "" +
         "" +
          "" +
          "" +
          "" +
         "" +
         "" +
          "" +
          "" +
         "" +
         "" +
          "" +
          "" +
         "" +
         "" +
          "" +
          "" +
          "" +
         "" +
        "
      " +
          "
           "class='dijitEditorSpellCheckBox' dojoAttachPoint='unfoundTextBox' id='${textId}'/>
      " +
           "" +
          "
      " +
           "" +
           "
      " +
          "
      ",

       
       /*************************************************************************/
       /** Framework Methods **/
       /*************************************************************************/
       constructor: function(){
        // Indicate if the textbox ignores the text change event of the textbox
        this.ignoreChange = false;
        // Indicate if the text of the textbox is changed or not
        this.isChanged = false;
        // Indicate if the dialog is open or not
        this.isOpen = false;
        // Indicate if the dialog can be closed
        this.closable = true;
       },

       
       postMixInProperties: function(){
        this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
        this.textId = this.id + "_textBox";
        this.selectId = this.id + "_select";
       },

       
       postCreate: function(){
        var select = this.suggestionSelect;

        
        // Customize multi-select to single select
        dojo.removeAttr(select.domNode, "multiple");
        select.addItems = function(/*Array*/ items){
         // summary:
         //  Add items to the select widget
         // items:
         //  An array of items be added to the select
         // tags:
         //  public
         var _this = this;
         var o = null;
         if(items && items.length > 0){
          dojo.forEach(items, function(item, i){
           o = dojo.create("option", {innerHTML: item, value: item}, _this.domNode);
           if(i == 0){
            o.selected = true;
           }
          });
         }
        };
        select.removeItems = function(){
         // summary:
         //  Remove all the items within the select widget
         // tags:
         //  public
         dojo.empty(this.domNode);
        };

       
        select.deselectAll = function(){
         // summary:
         //  De-select all the selected items
         // tags:
         //  public
         this.containerNode.selectedIndex = -1;
        };

        
        // Connect up all the controls with their event handler
        this.connect(this, "onKeyPress", "_cancel");
        this.connect(this.unfoundTextBox, "onKeyPress", "_enter");
        this.connect(this.unfoundTextBox, "onChange", "_unfoundTextBoxChange");
        this.connect(this.suggestionSelect, "onKeyPress", "_enter");
        this.connect(this.skipButton, "onClick", "onSkip");
        this.connect(this.skipAllButton, "onClick", "onSkipAll");
        this.connect(this.toDicButton, "onClick", "onAddToDic");
        this.connect(this.replaceButton, "onClick", "onReplace");
        this.connect(this.replaceAllButton, "onClick", "onReplaceAll");
        this.connect(this.cancelButton, "onClick", "onCancel");
       },

       
       /*************************************************************************/
       /** Public Methods **/
       /*************************************************************************/

       
       onSkip: function(){
        // Stub for the click event of the skip button.
       },

       
       onSkipAll: function(){
        // Stub for the click event of the skipAll button.
       },

       
       onAddToDic: function(){
        // Stub for the click event of the toDic button.
    • summary
  • dojox.editor.plugins._spellCheckControl.onReplace

    • type
      Function
    • source: [view]
      dojo.provide("dojox.editor.plugins.SpellCheck");


      dojo.require("dijit.form.TextBox");
      dojo.require("dijit.form.DropDownButton");
      dojo.require("dijit.TooltipDialog");
      dojo.require("dijit.form.MultiSelect");
      dojo.require("dojo.io.script");
      dojo.require("dijit.Menu");


      dojo.requireLocalization("dojox.editor.plugins", "SpellCheck");


      dojo.experimental("dojox.editor.plugins.SpellCheck");


      dojo.declare("dojox.editor.plugins._spellCheckControl", [dijit._Widget, dijit._Templated], {
       // summary:
       //  The widget that is used for the UI of the batch spelling check

       
       widgetsInTemplate: true,

       
       templateString:
        "" +
         "" +
         "" +
          "" +
          "" +
          "" +
         "" +
         "" +
          "" +
          "" +
         "" +
         "" +
          "" +
          "" +
         "" +
         "" +
          "" +
          "" +
          "" +
         "" +
        "
      " +
          "
           "class='dijitEditorSpellCheckBox' dojoAttachPoint='unfoundTextBox' id='${textId}'/>
      " +
           "" +
          "
      " +
           "" +
           "
      " +
          "
      ",

       
       /*************************************************************************/
       /** Framework Methods **/
       /*************************************************************************/
       constructor: function(){
        // Indicate if the textbox ignores the text change event of the textbox
        this.ignoreChange = false;
        // Indicate if the text of the textbox is changed or not
        this.isChanged = false;
        // Indicate if the dialog is open or not
        this.isOpen = false;
        // Indicate if the dialog can be closed
        this.closable = true;
       },

       
       postMixInProperties: function(){
        this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
        this.textId = this.id + "_textBox";
        this.selectId = this.id + "_select";
       },

       
       postCreate: function(){
        var select = this.suggestionSelect;

        
        // Customize multi-select to single select
        dojo.removeAttr(select.domNode, "multiple");
        select.addItems = function(/*Array*/ items){
         // summary:
         //  Add items to the select widget
         // items:
         //  An array of items be added to the select
         // tags:
         //  public
         var _this = this;
         var o = null;
         if(items && items.length > 0){
          dojo.forEach(items, function(item, i){
           o = dojo.create("option", {innerHTML: item, value: item}, _this.domNode);
           if(i == 0){
            o.selected = true;
           }
          });
         }
        };
        select.removeItems = function(){
         // summary:
         //  Remove all the items within the select widget
         // tags:
         //  public
         dojo.empty(this.domNode);
        };

       
        select.deselectAll = function(){
         // summary:
         //  De-select all the selected items
         // tags:
         //  public
         this.containerNode.selectedIndex = -1;
        };

        
        // Connect up all the controls with their event handler
        this.connect(this, "onKeyPress", "_cancel");
        this.connect(this.unfoundTextBox, "onKeyPress", "_enter");
        this.connect(this.unfoundTextBox, "onChange", "_unfoundTextBoxChange");
        this.connect(this.suggestionSelect, "onKeyPress", "_enter");
        this.connect(this.skipButton, "onClick", "onSkip");
        this.connect(this.skipAllButton, "onClick", "onSkipAll");
        this.connect(this.toDicButton, "onClick", "onAddToDic");
        this.connect(this.replaceButton, "onClick", "onReplace");
        this.connect(this.replaceAllButton, "onClick", "onReplaceAll");
        this.connect(this.cancelButton, "onClick", "onCancel");
       },

       
       /*************************************************************************/
       /** Public Methods **/
       /*************************************************************************/

       
       onSkip: function(){
        // Stub for the click event of the skip button.
       },

       
       onSkipAll: function(){
        // Stub for the click event of the skipAll button.
       },

       
       onAddToDic: function(){
        // Stub for the click event of the toDic button.
       },

       
       onReplace: function(){
        // Stub for the click event of the replace button.
    • summary
  • dojox.editor.plugins._spellCheckControl.onReplaceAll

    • type
      Function
    • source: [view]
      dojo.provide("dojox.editor.plugins.SpellCheck");


      dojo.require("dijit.form.TextBox");
      dojo.require("dijit.form.DropDownButton");
      dojo.require("dijit.TooltipDialog");
      dojo.require("dijit.form.MultiSelect");
      dojo.require("dojo.io.script");
      dojo.require("dijit.Menu");


      dojo.requireLocalization("dojox.editor.plugins", "SpellCheck");


      dojo.experimental("dojox.editor.plugins.SpellCheck");


      dojo.declare("dojox.editor.plugins._spellCheckControl", [dijit._Widget, dijit._Templated], {
       // summary:
       //  The widget that is used for the UI of the batch spelling check

       
       widgetsInTemplate: true,

       
       templateString:
        "" +
         "" +
         "" +
          "" +
          "" +
          "" +
         "" +
         "" +
          "" +
          "" +
         "" +
         "" +
          "" +
          "" +
         "" +
         "" +
          "" +
          "" +
          "" +
         "" +
        "
      " +
          "
           "class='dijitEditorSpellCheckBox' dojoAttachPoint='unfoundTextBox' id='${textId}'/>
      " +
           "" +
          "
      " +
           "" +
           "
      " +
          "
      ",

       
       /*************************************************************************/
       /** Framework Methods **/
       /*************************************************************************/
       constructor: function(){
        // Indicate if the textbox ignores the text change event of the textbox
        this.ignoreChange = false;
        // Indicate if the text of the textbox is changed or not
        this.isChanged = false;
        // Indicate if the dialog is open or not
        this.isOpen = false;
        // Indicate if the dialog can be closed
        this.closable = true;
       },

       
       postMixInProperties: function(){
        this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
        this.textId = this.id + "_textBox";
        this.selectId = this.id + "_select";
       },

       
       postCreate: function(){
        var select = this.suggestionSelect;

        
        // Customize multi-select to single select
        dojo.removeAttr(select.domNode, "multiple");
        select.addItems = function(/*Array*/ items){
         // summary:
         //  Add items to the select widget
         // items:
         //  An array of items be added to the select
         // tags:
         //  public
         var _this = this;
         var o = null;
         if(items && items.length > 0){
          dojo.forEach(items, function(item, i){
           o = dojo.create("option", {innerHTML: item, value: item}, _this.domNode);
           if(i == 0){
            o.selected = true;
           }
          });
         }
        };
        select.removeItems = function(){
         // summary:
         //  Remove all the items within the select widget
         // tags:
         //  public
         dojo.empty(this.domNode);
        };

       
        select.deselectAll = function(){
         // summary:
         //  De-select all the selected items
         // tags:
         //  public
         this.containerNode.selectedIndex = -1;
        };

        
        // Connect up all the controls with their event handler
        this.connect(this, "onKeyPress", "_cancel");
        this.connect(this.unfoundTextBox, "onKeyPress", "_enter");
        this.connect(this.unfoundTextBox, "onChange", "_unfoundTextBoxChange");
        this.connect(this.suggestionSelect, "onKeyPress", "_enter");
        this.connect(this.skipButton, "onClick", "onSkip");
        this.connect(this.skipAllButton, "onClick", "onSkipAll");
        this.connect(this.toDicButton, "onClick", "onAddToDic");
        this.connect(this.replaceButton, "onClick", "onReplace");
        this.connect(this.replaceAllButton, "onClick", "onReplaceAll");
        this.connect(this.cancelButton, "onClick", "onCancel");
       },

       
       /*************************************************************************/
       /** Public Methods **/
       /*************************************************************************/

       
       onSkip: function(){
        // Stub for the click event of the skip button.
       },

       
       onSkipAll: function(){
        // Stub for the click event of the skipAll button.
       },

       
       onAddToDic: function(){
        // Stub for the click event of the toDic button.
       },

       
       onReplace: function(){
        // Stub for the click event of the replace button.
       },

       
       onReplaceAll: function(){
        // Stub for the click event of the replaceAll button.
    • summary
  • dojox.editor.plugins._spellCheckControl.onCancel

    • type
      Function
    • source: [view]
      dojo.provide("dojox.editor.plugins.SpellCheck");


      dojo.require("dijit.form.TextBox");
      dojo.require("dijit.form.DropDownButton");
      dojo.require("dijit.TooltipDialog");
      dojo.require("dijit.form.MultiSelect");
      dojo.require("dojo.io.script");
      dojo.require("dijit.Menu");


      dojo.requireLocalization("dojox.editor.plugins", "SpellCheck");


      dojo.experimental("dojox.editor.plugins.SpellCheck");


      dojo.declare("dojox.editor.plugins._spellCheckControl", [dijit._Widget, dijit._Templated], {
       // summary:
       //  The widget that is used for the UI of the batch spelling check

       
       widgetsInTemplate: true,

       
       templateString:
        "" +
         "" +
         "" +
          "" +
          "" +
          "" +
         "" +
         "" +
          "" +
          "" +
         "" +
         "" +
          "" +
          "" +
         "" +
         "" +
          "" +
          "" +
          "" +
         "" +
        "
      " +
          "
           "class='dijitEditorSpellCheckBox' dojoAttachPoint='unfoundTextBox' id='${textId}'/>
      " +
           "" +
          "
      " +
           "" +
           "
      " +
          "
      ",

       
       /*************************************************************************/
       /** Framework Methods **/
       /*************************************************************************/
       constructor: function(){
        // Indicate if the textbox ignores the text change event of the textbox
        this.ignoreChange = false;
        // Indicate if the text of the textbox is changed or not
        this.isChanged = false;
        // Indicate if the dialog is open or not
        this.isOpen = false;
        // Indicate if the dialog can be closed
        this.closable = true;
       },

       
       postMixInProperties: function(){
        this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
        this.textId = this.id + "_textBox";
        this.selectId = this.id + "_select";
       },

       
       postCreate: function(){
        var select = this.suggestionSelect;

        
        // Customize multi-select to single select
        dojo.removeAttr(select.domNode, "multiple");
        select.addItems = function(/*Array*/ items){
         // summary:
         //  Add items to the select widget
         // items:
         //  An array of items be added to the select
         // tags:
         //  public
         var _this = this;
         var o = null;
         if(items && items.length > 0){
          dojo.forEach(items, function(item, i){
           o = dojo.create("option", {innerHTML: item, value: item}, _this.domNode);
           if(i == 0){
            o.selected = true;
           }
          });
         }
        };
        select.removeItems = function(){
         // summary:
         //  Remove all the items within the select widget
         // tags:
         //  public
         dojo.empty(this.domNode);
        };

       
        select.deselectAll = function(){
         // summary:
         //  De-select all the selected items
         // tags:
         //  public
         this.containerNode.selectedIndex = -1;
        };

        
        // Connect up all the controls with their event handler
        this.connect(this, "onKeyPress", "_cancel");
        this.connect(this.unfoundTextBox, "onKeyPress", "_enter");
        this.connect(this.unfoundTextBox, "onChange", "_unfoundTextBoxChange");
        this.connect(this.suggestionSelect, "onKeyPress", "_enter");
        this.connect(this.skipButton, "onClick", "onSkip");
        this.connect(this.skipAllButton, "onClick", "onSkipAll");
        this.connect(this.toDicButton, "onClick", "onAddToDic");
        this.connect(this.replaceButton, "onClick", "onReplace");
        this.connect(this.replaceAllButton, "onClick", "onReplaceAll");
        this.connect(this.cancelButton, "onClick", "onCancel");
       },

       
       /*************************************************************************/
       /** Public Methods **/
       /*************************************************************************/

       
       onSkip: function(){
        // Stub for the click event of the skip button.
       },

       
       onSkipAll: function(){
        // Stub for the click event of the skipAll button.
       },

       
       onAddToDic: function(){
        // Stub for the click event of the toDic button.
       },

       
       onReplace: function(){
        // Stub for the click event of the replace button.
       },

       
       onReplaceAll: function(){
        // Stub for the click event of the replaceAll button.
       },

       
       onCancel: function(){
        // Stub for the click event of the cancel button.
    • summary
  • dojox.editor.plugins._spellCheckControl.onEnter

    • type
      Function
    • source: [view]
      dojo.provide("dojox.editor.plugins.SpellCheck");


      dojo.require("dijit.form.TextBox");
      dojo.require("dijit.form.DropDownButton");
      dojo.require("dijit.TooltipDialog");
      dojo.require("dijit.form.MultiSelect");
      dojo.require("dojo.io.script");
      dojo.require("dijit.Menu");


      dojo.requireLocalization("dojox.editor.plugins", "SpellCheck");


      dojo.experimental("dojox.editor.plugins.SpellCheck");


      dojo.declare("dojox.editor.plugins._spellCheckControl", [dijit._Widget, dijit._Templated], {
       // summary:
       //  The widget that is used for the UI of the batch spelling check

       
       widgetsInTemplate: true,

       
       templateString:
        "" +
         "" +
         "" +
          "" +
          "" +
          "" +
         "" +
         "" +
          "" +
          "" +
         "" +
         "" +
          "" +
          "" +
         "" +
         "" +
          "" +
          "" +
          "" +
         "" +
        "
      " +
          "
           "class='dijitEditorSpellCheckBox' dojoAttachPoint='unfoundTextBox' id='${textId}'/>
      " +
           "" +
          "
      " +
           "" +
           "
      " +
          "
      ",

       
       /*************************************************************************/
       /** Framework Methods **/
       /*************************************************************************/
       constructor: function(){
        // Indicate if the textbox ignores the text change event of the textbox
        this.ignoreChange = false;
        // Indicate if the text of the textbox is changed or not
        this.isChanged = false;
        // Indicate if the dialog is open or not
        this.isOpen = false;
        // Indicate if the dialog can be closed
        this.closable = true;
       },

       
       postMixInProperties: function(){
        this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
        this.textId = this.id + "_textBox";
        this.selectId = this.id + "_select";
       },

       
       postCreate: function(){
        var select = this.suggestionSelect;

        
        // Customize multi-select to single select
        dojo.removeAttr(select.domNode, "multiple");
        select.addItems = function(/*Array*/ items){
         // summary:
         //  Add items to the select widget
         // items:
         //  An array of items be added to the select
         // tags:
         //  public
         var _this = this;
         var o = null;
         if(items && items.length > 0){
          dojo.forEach(items, function(item, i){
           o = dojo.create("option", {innerHTML: item, value: item}, _this.domNode);
           if(i == 0){
            o.selected = true;
           }
          });
         }
        };
        select.removeItems = function(){
         // summary:
         //  Remove all the items within the select widget
         // tags:
         //  public
         dojo.empty(this.domNode);
        };

       
        select.deselectAll = function(){
         // summary:
         //  De-select all the selected items
         // tags:
         //  public
         this.containerNode.selectedIndex = -1;
        };

        
        // Connect up all the controls with their event handler
        this.connect(this, "onKeyPress", "_cancel");
        this.connect(this.unfoundTextBox, "onKeyPress", "_enter");
        this.connect(this.unfoundTextBox, "onChange", "_unfoundTextBoxChange");
        this.connect(this.suggestionSelect, "onKeyPress", "_enter");
        this.connect(this.skipButton, "onClick", "onSkip");
        this.connect(this.skipAllButton, "onClick", "onSkipAll");
        this.connect(this.toDicButton, "onClick", "onAddToDic");
        this.connect(this.replaceButton, "onClick", "onReplace");
        this.connect(this.replaceAllButton, "onClick", "onReplaceAll");
        this.connect(this.cancelButton, "onClick", "onCancel");
       },

       
       /*************************************************************************/
       /** Public Methods **/
       /*************************************************************************/

       
       onSkip: function(){
        // Stub for the click event of the skip button.
       },

       
       onSkipAll: function(){
        // Stub for the click event of the skipAll button.
       },

       
       onAddToDic: function(){
        // Stub for the click event of the toDic button.
       },

       
       onReplace: function(){
        // Stub for the click event of the replace button.
       },

       
       onReplaceAll: function(){
        // Stub for the click event of the replaceAll button.
       },

       
       onCancel: function(){
        // Stub for the click event of the cancel button.
       },

       
       onEnter: function(){
        // Stub for the enter event of the unFound textbox.
    • summary
  • dojox.editor.plugins._spellCheckControl.focus

    • type
      Function
    • source: [view]
        this.unfoundTextBox.focus();
    • summary
      Set the focus of the control
    • tags:
  • dojox.editor.plugins._spellCheckControl._cancel

    • type
      Function
    • parameters:
      • evt: (typeof Event)
        The event object
    • source: [view]
        if(evt.keyCode == dojo.keys.ESCAPE){
         this.onCancel();
         dojo.stopEvent(evt);
        }
    • summary
      Handle the cancel event
    • tags:
  • dojox.editor.plugins._spellCheckControl._enter

    • type
      Function
    • parameters:
      • evt: (typeof Event)
        The event object
    • source: [view]
        if(evt.keyCode == dojo.keys.ENTER){
         this.onEnter();
         dojo.stopEvent(evt);
        }
    • summary
      Handle the enter event
    • tags:
  • dojox.editor.plugins._spellCheckControl._unfoundTextBoxChange

    • type
      Function
    • source: [view]
        var id = this.textId + "_label";
        if(!this.ignoreChange){
         dojo.byId(id).innerHTML = this["replaceWith"];
         this.isChanged = true;
         this.suggestionSelect.deselectAll();
        }else{
         dojo.byId(id).innerHTML = this["unfound"];
        }
    • summary
      Indicate that the Not Found textbox is changed or not
    • tags:
  • dojox.editor.plugins._spellCheckControl._setUnfoundWordAttr

    • type
      Function
    • parameters:
      • value: (typeof String)
        The value of the Not Found textbox
    • source: [view]
        value = value || "";
        this.unfoundTextBox.set("value", value);
    • summary
      Set the value of the Not Found textbox
    • tags:
  • dojox.editor.plugins._spellCheckControl._getUnfoundWordAttr

    • type
      Function
    • source: [view]
        return this.unfoundTextBox.get("value");
    • summary
      Get the value of the Not Found textbox
    • tags:
  • dojox.editor.plugins._spellCheckControl._setSuggestionListAttr

    • type
      Function
    • parameters:
      • values: (typeof Array)
        The list of the suggestion items
    • source: [view]
        var select = this.suggestionSelect;
        values = values || [];
        select.removeItems();
        select.addItems(values);
    • summary
      Set the items of the suggestion list
    • tags:
  • dojox.editor.plugins._spellCheckControl._getSelectedWordAttr

    • type
      Function
    • source: [view]
        var selected = this.suggestionSelect.getSelected();
        if(selected && selected.length > 0){
         return selected[0].value;
        }else{
         return this.unfoundTextBox.get("value");
        }
    • summary
      Get the suggested word.
      If the select box is selected, the value is the selected item's value,
      else the value the the textbox's value
    • tags:
  • dojox.editor.plugins._spellCheckControl._setDisabledAttr

    • type
      Function
    • parameters:
      • disabled: (typeof Boolean)
    • source: [view]
        this.skipButton.set("disabled", disabled);
        this.skipAllButton.set("disabled", disabled);
        this.toDicButton.set("disabled", disabled);
        this.replaceButton.set("disabled", disabled);
        this.replaceAllButton.set("disabled", disabled);
    • summary
      Enable/disable the control
    • tags:
  • dojox.editor.plugins._spellCheckControl._setInProgressAttr

    • type
      Function
    • parameters:
      • show: (typeof Boolean)
    • source: [view]
        var id = this.id + "_progressIcon",
         cmd = show ? "removeClass" : "addClass";
         dojo[cmd](id, "hidden");
    • summary
      Set the visibility of the progress icon
    • tags:
  • dojox.editor.plugins._spellCheckControl.id

    • summary
  • dojox.editor.plugins._spellCheckControl.textId

    • summary
  • dojox.editor.plugins._spellCheckControl.selectId

    • summary
  • dojox.editor.plugins._spellCheckControl.containerNode.selectedIndex

    • summary
  • dojox.editor.plugins._spellCheckControl.isChanged

    • summary
  • dojox.editor.plugins._spellCheckControl.ignoreChange

    • summary
  • dojox.editor.plugins._spellCheckControl.isOpen

    • summary
  • dojox.editor.plugins._spellCheckControl.closable

    • summary
  • dojox.editor.plugins._SpellCheckScriptMultiPart

    • type
      Function
    • summary
      It is a base network service component. It transfers text to a remote service port
      with cross domain ability enabled. It can split text into specified pieces and send
      them out one by one so that it can handle the case when the service has a limitation of
      the capability.
      The encoding is UTF-8.
      
      ACTION [public const] String
      Actions for the server-side piece to take
    • source: [view]
      dojo.provide("dojox.editor.plugins.SpellCheck");


      dojo.require("dijit.form.TextBox");
      dojo.require("dijit.form.DropDownButton");
      dojo.require("dijit.TooltipDialog");
      dojo.require("dijit.form.MultiSelect");
      dojo.require("dojo.io.script");
      dojo.require("dijit.Menu");


      dojo.requireLocalization("dojox.editor.plugins", "SpellCheck");


      dojo.experimental("dojox.editor.plugins.SpellCheck");


      dojo.declare("dojox.editor.plugins._spellCheckControl", [dijit._Widget, dijit._Templated], {
       // summary:
       //  The widget that is used for the UI of the batch spelling check

       
       widgetsInTemplate: true,

       
       templateString:
        "" +
         "" +
         "" +
          "" +
          "" +
          "" +
         "" +
         "" +
          "" +
          "" +
         "" +
         "" +
          "" +
          "" +
         "" +
         "" +
          "" +
          "" +
          "" +
         "" +
        "
      " +
          "
           "class='dijitEditorSpellCheckBox' dojoAttachPoint='unfoundTextBox' id='${textId}'/>
      " +
           "" +
          "
      " +
           "" +
           "
      " +
          "
      ",

       
       /*************************************************************************/
       /** Framework Methods **/
       /*************************************************************************/
       constructor: function(){
        // Indicate if the textbox ignores the text change event of the textbox
        this.ignoreChange = false;
        // Indicate if the text of the textbox is changed or not
        this.isChanged = false;
        // Indicate if the dialog is open or not
        this.isOpen = false;
        // Indicate if the dialog can be closed
        this.closable = true;
       },

       
       postMixInProperties: function(){
        this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
        this.textId = this.id + "_textBox";
        this.selectId = this.id + "_select";
       },

       
       postCreate: function(){
        var select = this.suggestionSelect;

        
        // Customize multi-select to single select
        dojo.removeAttr(select.domNode, "multiple");
        select.addItems = function(/*Array*/ items){
         // summary:
         //  Add items to the select widget
         // items:
         //  An array of items be added to the select
         // tags:
         //  public
         var _this = this;
         var o = null;
         if(items && items.length > 0){
          dojo.forEach(items, function(item, i){
           o = dojo.create("option", {innerHTML: item, value: item}, _this.domNode);
           if(i == 0){
            o.selected = true;
           }
          });
         }
        };
        select.removeItems = function(){
         // summary:
         //  Remove all the items within the select widget
         // tags:
         //  public
         dojo.empty(this.domNode);
        };

       
        select.deselectAll = function(){
         // summary:
         //  De-select all the selected items
         // tags:
         //  public
         this.containerNode.selectedIndex = -1;
        };

        
        // Connect up all the controls with their event handler
        this.connect(this, "onKeyPress", "_cancel");
        this.connect(this.unfoundTextBox, "onKeyPress", "_enter");
        this.connect(this.unfoundTextBox, "onChange", "_unfoundTextBoxChange");
        this.connect(this.suggestionSelect, "onKeyPress", "_enter");
        this.connect(this.skipButton, "onClick", "onSkip");
        this.connect(this.skipAllButton, "onClick", "onSkipAll");
        this.connect(this.toDicButton, "onClick", "onAddToDic");
        this.connect(this.replaceButton, "onClick", "onReplace");
        this.connect(this.replaceAllButton, "onClick", "onReplaceAll");
        this.connect(this.cancelButton, "onClick", "onCancel");
       },

       
       /*************************************************************************/
       /** Public Methods **/
       /*************************************************************************/

       
       onSkip: function(){
        // Stub for the click event of the skip button.
       },

       
       onSkipAll: function(){
        // Stub for the click event of the skipAll button.
       },

       
       onAddToDic: function(){
        // Stub for the click event of the toDic button.
       },

       
       onReplace: function(){
        // Stub for the click event of the replace button.
       },

       
       onReplaceAll: function(){
        // Stub for the click event of the replaceAll button.
       },

       
       onCancel: function(){
        // Stub for the click event of the cancel button.
       },

       
       onEnter: function(){
        // Stub for the enter event of the unFound textbox.
       },

       
       focus: function(){
        // summary:
        //  Set the focus of the control
        // tags:
        //  public
        this.unfoundTextBox.focus();
       },

       
       /*************************************************************************/
       /** Private Methods **/
       /*************************************************************************/

       
       _cancel: function(/*Event*/ evt){
        // summary:
        //  Handle the cancel event
        // evt:
        //  The event object
        // tags:
        //  private
        if(evt.keyCode == dojo.keys.ESCAPE){
         this.onCancel();
         dojo.stopEvent(evt);
        }
       },

       
       _enter: function(/*Event*/ evt){
        // summary:
        //  Handle the enter event
        // evt:
        //  The event object
        // tags:
        //  private
        if(evt.keyCode == dojo.keys.ENTER){
         this.onEnter();
         dojo.stopEvent(evt);
        }
       },

       
       _unfoundTextBoxChange: function(){
        // summary:
        //  Indicate that the Not Found textbox is changed or not
        // tags:
        //  private
        var id = this.textId + "_label";
        if(!this.ignoreChange){
         dojo.byId(id).innerHTML = this["replaceWith"];
         this.isChanged = true;
         this.suggestionSelect.deselectAll();
        }else{
         dojo.byId(id).innerHTML = this["unfound"];
        }
       },

       
       _setUnfoundWordAttr: function(/*String*/ value){
        // summary:
        //  Set the value of the Not Found textbox
        // value:
        //  The value of the Not Found textbox
        // tags:
        //  private
        value = value || "";
        this.unfoundTextBox.set("value", value);
       },

       
       _getUnfoundWordAttr: function(){
        // summary:
        //  Get the value of the Not Found textbox
        // tags:
        //  private
        return this.unfoundTextBox.get("value");
       },

       
       _setSuggestionListAttr: function(/*Array*/ values){
        // summary:
        //  Set the items of the suggestion list
        // values:
        //  The list of the suggestion items
        // tags:
        //  private
        var select = this.suggestionSelect;
        values = values || [];
        select.removeItems();
        select.addItems(values);
       },

       
       _getSelectedWordAttr: function(){
        // summary:
        //  Get the suggested word.
        //  If the select box is selected, the value is the selected item's value,
        //  else the value the the textbox's value
        // tags:
        //  private
        var selected = this.suggestionSelect.getSelected();
        if(selected && selected.length > 0){
         return selected[0].value;
        }else{
         return this.unfoundTextBox.get("value");
        }
       },

       
       _setDisabledAttr: function(/*Boolean*/ disabled){
        // summary:
        //  Enable/disable the control
        // tags:
        //  private
        this.skipButton.set("disabled", disabled);
        this.skipAllButton.set("disabled", disabled);
        this.toDicButton.set("disabled", disabled);
        this.replaceButton.set("disabled", disabled);
        this.replaceAllButton.set("disabled", disabled);
       },

       
       _setInProgressAttr: function(/*Boolean*/ show){
        // summary:
        //  Set the visibility of the progress icon
        // tags:
        //  private
        var id = this.id + "_progressIcon",
         cmd = show ? "removeClass" : "addClass";
         dojo[cmd](id, "hidden");
       }
      });


      dojo.declare("dojox.editor.plugins._SpellCheckScriptMultiPart", null, {
       // summary:
       //  It is a base network service component. It transfers text to a remote service port
       //  with cross domain ability enabled. It can split text into specified pieces and send
       //  them out one by one so that it can handle the case when the service has a limitation of
       //  the capability.
       //  The encoding is UTF-8.

       
       // ACTION [public const] String
       //  Actions for the server-side piece to take
       ACTION_QUERY: "query",
       ACTION_UPDATE: "update",

       
       // callbackHandle [public] String
       //  The callback name of JSONP
       callbackHandle: "callback",

       
       // maxBufferLength [public] Number
       //  The max number of charactors that send to the service at one time.
       maxBufferLength: 100,

       
       // delimiter [public] String
       //  A token that is used to identify the end of a word (a complete unit). It prevents the service from
       //  cutting a single word into two parts. For example:
       //   "Dojo toolkit is a ajax framework. It helps the developers buid their web applications."
       //  Without the delimiter, the sentence might be split into the follow pieces which is absolutely
       //  not the result we want.
       //   "Dojo toolkit is a ajax fram", "ework It helps the developers bu", "id their web applications"
       //  Having " " as the delimiter, we get the following correct pieces.
       //   "Dojo toolkit is a ajax framework", " It helps the developers buid", " their web applications"
       delimiter: " ",

       
       // label [public] String
       //  The leading label of the JSON response. The service will return the result like this:
       //  {response: [
       //    {
       //     text: "teest",
       //     suggestion: ["test","treat"]
       //    }
       //   ]}
       label: "response",

       
       // _timeout [private] Number
       //  Set JSONP timeout period
       _timeout: 30000,
       SEC: 1000,

       
       constructor: function(){
        // The URL of the target service
        this.serviceEndPoint = "";
        // The queue that holds all the xhr request
        this._queue = [];
        // Indicate if the component is still working. For example, waiting for collecting all
        // the responses from the service
        this.isWorking = false;
        // The extra command passed to the service
        this.exArgs = null;
        // The counter that indicate if all the responses are collected to
        // assemble the final result.
        this._counter = 0;
  • dojox.editor.plugins._SpellCheckScriptMultiPart.ACTION_QUERY

    • summary
  • dojox.editor.plugins._SpellCheckScriptMultiPart.ACTION_UPDATE

    • summary
  • dojox.editor.plugins._SpellCheckScriptMultiPart.callbackHandle

    • summary
  • dojox.editor.plugins._SpellCheckScriptMultiPart.maxBufferLength

    • summary
  • dojox.editor.plugins._SpellCheckScriptMultiPart.delimiter

    • summary
  • dojox.editor.plugins._SpellCheckScriptMultiPart.label

    • summary
  • dojox.editor.plugins._SpellCheckScriptMultiPart._timeout

    • summary
  • dojox.editor.plugins._SpellCheckScriptMultiPart.SEC

    • summary
  • dojox.editor.plugins._SpellCheckScriptMultiPart.send

    • type
      Function
    • parameters:
      • content: (typeof String)
        The text to be sent
      • action: (typeof String)
        The action the service should take. Current support actions are
        ACTION_QUERY and ACTION_UPDATE
    • source: [view]
        var _this = this,
         dt = this.delimiter,
         mbl = this.maxBufferLength,
         label = this.label,
         serviceEndPoint = this.serviceEndPoint,
         callbackParamName = this.callbackHandle,
         comms = this.exArgs,
         timeout = this._timeout,
         l = 0, r = 0;

        
        // Temparary list that holds the result returns from the service, which will be
        // assembled into a completed one.
        if(!this._result) {
         this._result = [];
        }


        action = action || this.ACTION_QUERY;


        var batchSend = function(){
         var plan = [];
         var plannedSize = 0;
         if(content && content.length > 0){
          _this.isWorking = true;
          var len = content.length;
          do{
           l = r + 1;
           if((r += mbl) > len){
            r = len;
           }else{
            // If there is no delimiter (emplty string), leave the right boundary where it is.
            // Else extend the right boundary to the first occurance of the delimiter if
            // it doesn't meet the end of the content.
            while(dt && content.charAt(r) != dt && r <= len){
             r++;
            }
           }
           // Record the information of the text slices
           plan.push({l: l, r: r});
           plannedSize++;
          }while(r < len);


          dojo.forEach(plan, function(item, index){
           var jsonpArgs = {
            url: serviceEndPoint,
            action: action,
            timeout: timeout,
            callbackParamName: callbackParamName,
            handle: function(response, ioArgs){
             if(++_this._counter <= this.size && !(response instanceof Error) &&
              response[label] && dojo.isArray(response[label])){
              // Collect the results
              var offset = this.offset;
              dojo.forEach(response[label], function(item){
               item.offset += offset;
              });
              // Put the packages in order
              _this._result[this.number]= response[label];
             }
             if(_this._counter == this.size){
              _this._finalizeCollection(this.action);
              _this.isWorking = false;
              if(_this._queue.length > 0){
               // Call the next request waiting in queue
               (_this._queue.shift())();
              }
             }
            }
           };
           jsonpArgs.content = comms ? dojo.mixin(comms, {action: action, content: content.substring(item.l - 1, item.r)}):
                   {action: action, content: content.substring(item.l - 1, item.r)};
           jsonpArgs.size = plannedSize;
           jsonpArgs.number = index; // The index of the current package
           jsonpArgs.offset = item.l - 1;
           dojo.io.script.get(jsonpArgs);
          });
         }
        };

       
        if(!_this.isWorking){
         batchSend();
        }else{
         _this._queue.push(batchSend);
        }
    • summary
      Send the content to the service port with the specified action
    • tags:
  • dojox.editor.plugins._SpellCheckScriptMultiPart._finalizeCollection

    • type
      Function
    • parameters:
      • action: (typeof The)
        action token
    • source: [view]
        var result = this._result,
         len = result.length;
        // Turn the result into a one-dimensional array
        for(var i = 0; i < len; i++){
         var temp = result.shift();
         result = result.concat(temp);
        }
        if(action == this.ACTION_QUERY){
         this.onLoad(result);
        }
        this._counter = 0;
        this._result = [];
    • summary
      Assemble the responses into one result.
    • tags:
  • dojox.editor.plugins._SpellCheckScriptMultiPart.onLoad

    • type
      Function
    • parameters:
      • data: (typeof String)
    • source: [view]
      dojo.provide("dojox.editor.plugins.SpellCheck");


      dojo.require("dijit.form.TextBox");
      dojo.require("dijit.form.DropDownButton");
      dojo.require("dijit.TooltipDialog");
      dojo.require("dijit.form.MultiSelect");
      dojo.require("dojo.io.script");
      dojo.require("dijit.Menu");


      dojo.requireLocalization("dojox.editor.plugins", "SpellCheck");


      dojo.experimental("dojox.editor.plugins.SpellCheck");


      dojo.declare("dojox.editor.plugins._spellCheckControl", [dijit._Widget, dijit._Templated], {
       // summary:
       //  The widget that is used for the UI of the batch spelling check

       
       widgetsInTemplate: true,

       
       templateString:
        "" +
         "" +
         "" +
          "" +
          "" +
          "" +
         "" +
         "" +
          "" +
          "" +
         "" +
         "" +
          "" +
          "" +
         "" +
         "" +
          "" +
          "" +
          "" +
         "" +
        "
      " +
          "
           "class='dijitEditorSpellCheckBox' dojoAttachPoint='unfoundTextBox' id='${textId}'/>
      " +
           "" +
          "
      " +
           "" +
           "
      " +
          "
      ",

       
       /*************************************************************************/
       /** Framework Methods **/
       /*************************************************************************/
       constructor: function(){
        // Indicate if the textbox ignores the text change event of the textbox
        this.ignoreChange = false;
        // Indicate if the text of the textbox is changed or not
        this.isChanged = false;
        // Indicate if the dialog is open or not
        this.isOpen = false;
        // Indicate if the dialog can be closed
        this.closable = true;
       },

       
       postMixInProperties: function(){
        this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
        this.textId = this.id + "_textBox";
        this.selectId = this.id + "_select";
       },

       
       postCreate: function(){
        var select = this.suggestionSelect;

        
        // Customize multi-select to single select
        dojo.removeAttr(select.domNode, "multiple");
        select.addItems = function(/*Array*/ items){
         // summary:
         //  Add items to the select widget
         // items:
         //  An array of items be added to the select
         // tags:
         //  public
         var _this = this;
         var o = null;
         if(items && items.length > 0){
          dojo.forEach(items, function(item, i){
           o = dojo.create("option", {innerHTML: item, value: item}, _this.domNode);
           if(i == 0){
            o.selected = true;
           }
          });
         }
        };
        select.removeItems = function(){
         // summary:
         //  Remove all the items within the select widget
         // tags:
         //  public
         dojo.empty(this.domNode);
        };

       
        select.deselectAll = function(){
         // summary:
         //  De-select all the selected items
         // tags:
         //  public
         this.containerNode.selectedIndex = -1;
        };

        
        // Connect up all the controls with their event handler
        this.connect(this, "onKeyPress", "_cancel");
        this.connect(this.unfoundTextBox, "onKeyPress", "_enter");
        this.connect(this.unfoundTextBox, "onChange", "_unfoundTextBoxChange");
        this.connect(this.suggestionSelect, "onKeyPress", "_enter");
        this.connect(this.skipButton, "onClick", "onSkip");
        this.connect(this.skipAllButton, "onClick", "onSkipAll");
        this.connect(this.toDicButton, "onClick", "onAddToDic");
        this.connect(this.replaceButton, "onClick", "onReplace");
        this.connect(this.replaceAllButton, "onClick", "onReplaceAll");
        this.connect(this.cancelButton, "onClick", "onCancel");
       },

       
       /*************************************************************************/
       /** Public Methods **/
       /*************************************************************************/

       
       onSkip: function(){
        // Stub for the click event of the skip button.
       },

       
       onSkipAll: function(){
        // Stub for the click event of the skipAll button.
       },

       
       onAddToDic: function(){
        // Stub for the click event of the toDic button.
       },

       
       onReplace: function(){
        // Stub for the click event of the replace button.
       },

       
       onReplaceAll: function(){
        // Stub for the click event of the replaceAll button.
       },

       
       onCancel: function(){
        // Stub for the click event of the cancel button.
       },

       
       onEnter: function(){
        // Stub for the enter event of the unFound textbox.
       },

       
       focus: function(){
        // summary:
        //  Set the focus of the control
        // tags:
        //  public
        this.unfoundTextBox.focus();
       },

       
       /*************************************************************************/
       /** Private Methods **/
       /*************************************************************************/

       
       _cancel: function(/*Event*/ evt){
        // summary:
        //  Handle the cancel event
        // evt:
        //  The event object
        // tags:
        //  private
        if(evt.keyCode == dojo.keys.ESCAPE){
         this.onCancel();
         dojo.stopEvent(evt);
        }
       },

       
       _enter: function(/*Event*/ evt){
        // summary:
        //  Handle the enter event
        // evt:
        //  The event object
        // tags:
        //  private
        if(evt.keyCode == dojo.keys.ENTER){
         this.onEnter();
         dojo.stopEvent(evt);
        }
       },

       
       _unfoundTextBoxChange: function(){
        // summary:
        //  Indicate that the Not Found textbox is changed or not
        // tags:
        //  private
        var id = this.textId + "_label";
        if(!this.ignoreChange){
         dojo.byId(id).innerHTML = this["replaceWith"];
         this.isChanged = true;
         this.suggestionSelect.deselectAll();
        }else{
         dojo.byId(id).innerHTML = this["unfound"];
        }
       },

       
       _setUnfoundWordAttr: function(/*String*/ value){
        // summary:
        //  Set the value of the Not Found textbox
        // value:
        //  The value of the Not Found textbox
        // tags:
        //  private
        value = value || "";
        this.unfoundTextBox.set("value", value);
       },

       
       _getUnfoundWordAttr: function(){
        // summary:
        //  Get the value of the Not Found textbox
        // tags:
        //  private
        return this.unfoundTextBox.get("value");
       },

       
       _setSuggestionListAttr: function(/*Array*/ values){
        // summary:
        //  Set the items of the suggestion list
        // values:
        //  The list of the suggestion items
        // tags:
        //  private
        var select = this.suggestionSelect;
        values = values || [];
        select.removeItems();
        select.addItems(values);
       },

       
       _getSelectedWordAttr: function(){
        // summary:
        //  Get the suggested word.
        //  If the select box is selected, the value is the selected item's value,
        //  else the value the the textbox's value
        // tags:
        //  private
        var selected = this.suggestionSelect.getSelected();
        if(selected && selected.length > 0){
         return selected[0].value;
        }else{
         return this.unfoundTextBox.get("value");
        }
       },

       
       _setDisabledAttr: function(/*Boolean*/ disabled){
        // summary:
        //  Enable/disable the control
        // tags:
        //  private
        this.skipButton.set("disabled", disabled);
        this.skipAllButton.set("disabled", disabled);
        this.toDicButton.set("disabled", disabled);
        this.replaceButton.set("disabled", disabled);
        this.replaceAllButton.set("disabled", disabled);
       },

       
       _setInProgressAttr: function(/*Boolean*/ show){
        // summary:
        //  Set the visibility of the progress icon
        // tags:
        //  private
        var id = this.id + "_progressIcon",
         cmd = show ? "removeClass" : "addClass";
         dojo[cmd](id, "hidden");
       }
      });


      dojo.declare("dojox.editor.plugins._SpellCheckScriptMultiPart", null, {
       // summary:
       //  It is a base network service component. It transfers text to a remote service port
       //  with cross domain ability enabled. It can split text into specified pieces and send
       //  them out one by one so that it can handle the case when the service has a limitation of
       //  the capability.
       //  The encoding is UTF-8.

       
       // ACTION [public const] String
       //  Actions for the server-side piece to take
       ACTION_QUERY: "query",
       ACTION_UPDATE: "update",

       
       // callbackHandle [public] String
       //  The callback name of JSONP
       callbackHandle: "callback",

       
       // maxBufferLength [public] Number
       //  The max number of charactors that send to the service at one time.
       maxBufferLength: 100,

       
       // delimiter [public] String
       //  A token that is used to identify the end of a word (a complete unit). It prevents the service from
       //  cutting a single word into two parts. For example:
       //   "Dojo toolkit is a ajax framework. It helps the developers buid their web applications."
       //  Without the delimiter, the sentence might be split into the follow pieces which is absolutely
       //  not the result we want.
       //   "Dojo toolkit is a ajax fram", "ework It helps the developers bu", "id their web applications"
       //  Having " " as the delimiter, we get the following correct pieces.
       //   "Dojo toolkit is a ajax framework", " It helps the developers buid", " their web applications"
       delimiter: " ",

       
       // label [public] String
       //  The leading label of the JSON response. The service will return the result like this:
       //  {response: [
       //    {
       //     text: "teest",
       //     suggestion: ["test","treat"]
       //    }
       //   ]}
       label: "response",

       
       // _timeout [private] Number
       //  Set JSONP timeout period
       _timeout: 30000,
       SEC: 1000,

       
       constructor: function(){
        // The URL of the target service
        this.serviceEndPoint = "";
        // The queue that holds all the xhr request
        this._queue = [];
        // Indicate if the component is still working. For example, waiting for collecting all
        // the responses from the service
        this.isWorking = false;
        // The extra command passed to the service
        this.exArgs = null;
        // The counter that indicate if all the responses are collected to
        // assemble the final result.
        this._counter = 0;
       },

       
       send: function(/*String*/ content, /*String?*/ action){
        // summary:
        //  Send the content to the service port with the specified action
        // content:
        //  The text to be sent
        // action:
        //  The action the service should take. Current support actions are
        //  ACTION_QUERY and ACTION_UPDATE
        // tags:
        //  public
        var _this = this,
         dt = this.delimiter,
         mbl = this.maxBufferLength,
         label = this.label,
         serviceEndPoint = this.serviceEndPoint,
         callbackParamName = this.callbackHandle,
         comms = this.exArgs,
         timeout = this._timeout,
         l = 0, r = 0;

        
        // Temparary list that holds the result returns from the service, which will be
        // assembled into a completed one.
        if(!this._result) {
         this._result = [];
        }


        action = action || this.ACTION_QUERY;


        var batchSend = function(){
         var plan = [];
         var plannedSize = 0;
         if(content && content.length > 0){
          _this.isWorking = true;
          var len = content.length;
          do{
           l = r + 1;
           if((r += mbl) > len){
            r = len;
           }else{
            // If there is no delimiter (emplty string), leave the right boundary where it is.
            // Else extend the right boundary to the first occurance of the delimiter if
            // it doesn't meet the end of the content.
            while(dt && content.charAt(r) != dt && r <= len){
             r++;
            }
           }
           // Record the information of the text slices
           plan.push({l: l, r: r});
           plannedSize++;
          }while(r < len);


          dojo.forEach(plan, function(item, index){
           var jsonpArgs = {
            url: serviceEndPoint,
            action: action,
            timeout: timeout,
            callbackParamName: callbackParamName,
            handle: function(response, ioArgs){
             if(++_this._counter <= this.size && !(response instanceof Error) &&
              response[label] && dojo.isArray(response[label])){
              // Collect the results
              var offset = this.offset;
              dojo.forEach(response[label], function(item){
               item.offset += offset;
              });
              // Put the packages in order
              _this._result[this.number]= response[label];
             }
             if(_this._counter == this.size){
              _this._finalizeCollection(this.action);
              _this.isWorking = false;
              if(_this._queue.length > 0){
               // Call the next request waiting in queue
               (_this._queue.shift())();
              }
             }
            }
           };
           jsonpArgs.content = comms ? dojo.mixin(comms, {action: action, content: content.substring(item.l - 1, item.r)}):
                   {action: action, content: content.substring(item.l - 1, item.r)};
           jsonpArgs.size = plannedSize;
           jsonpArgs.number = index; // The index of the current package
           jsonpArgs.offset = item.l - 1;
           dojo.io.script.get(jsonpArgs);
          });
         }
        };

       
        if(!_this.isWorking){
         batchSend();
        }else{
         _this._queue.push(batchSend);
        }
       },

       
       _finalizeCollection: function(action){
        // summary:
        //  Assemble the responses into one result.
        // action:
        //  The action token
        // tags:
        //  private
        var result = this._result,
         len = result.length;
        // Turn the result into a one-dimensional array
        for(var i = 0; i < len; i++){
         var temp = result.shift();
         result = result.concat(temp);
        }
        if(action == this.ACTION_QUERY){
         this.onLoad(result);
        }
        this._counter = 0;
        this._result = [];
       },

       
       onLoad: function(/*String*/ data){
        // Stub method for a sucessful call
    • summary
  • dojox.editor.plugins._SpellCheckScriptMultiPart.setWaitingTime

    • type
      Function
    • parameters:
      • seconds: (typeof Number)
    • source: [view]
        this._timeout = seconds * this.SEC;
    • summary
  • dojox.editor.plugins._SpellCheckScriptMultiPart._result

    • summary
  • dojox.editor.plugins._SpellCheckScriptMultiPart._counter

    • summary
  • dojox.editor.plugins._SpellCheckScriptMultiPart.serviceEndPoint

    • summary
  • dojox.editor.plugins._SpellCheckScriptMultiPart._queue

    • summary
  • dojox.editor.plugins._SpellCheckScriptMultiPart.isWorking

    • summary
  • dojox.editor.plugins._SpellCheckScriptMultiPart.exArgs

    • summary
  • dojox.editor.plugins.SpellCheck

    • type
      Function
    • chains:
      • dijit._editor._Plugin: (prototype)
      • dijit._editor._Plugin: (call)
    • summary
      This plugin provides a spelling check cabability for the editor.
      
      url [public] String
      The url of the spelling check service
    • source: [view]
      dojo.provide("dojox.editor.plugins.SpellCheck");


      dojo.require("dijit.form.TextBox");
      dojo.require("dijit.form.DropDownButton");
      dojo.require("dijit.TooltipDialog");
      dojo.require("dijit.form.MultiSelect");
      dojo.require("dojo.io.script");
      dojo.require("dijit.Menu");


      dojo.requireLocalization("dojox.editor.plugins", "SpellCheck");


      dojo.experimental("dojox.editor.plugins.SpellCheck");


      dojo.declare("dojox.editor.plugins._spellCheckControl", [dijit._Widget, dijit._Templated], {
       // summary:
       //  The widget that is used for the UI of the batch spelling check

       
       widgetsInTemplate: true,

       
       templateString:
        "" +
         "" +
         "" +
          "" +
          "" +
          "" +
         "" +
         "" +
          "" +
          "" +
         "" +
         "" +
          "" +
          "" +
         "" +
         "" +
          "" +
          "" +
          "" +
         "" +
        "
      " +
          "
           "class='dijitEditorSpellCheckBox' dojoAttachPoint='unfoundTextBox' id='${textId}'/>
      " +
           "" +
          "
      " +
           "" +
           "
      " +
          "
      ",

       
       /*************************************************************************/
       /** Framework Methods **/
       /*************************************************************************/
       constructor: function(){
        // Indicate if the textbox ignores the text change event of the textbox
        this.ignoreChange = false;
        // Indicate if the text of the textbox is changed or not
        this.isChanged = false;
        // Indicate if the dialog is open or not
        this.isOpen = false;
        // Indicate if the dialog can be closed
        this.closable = true;
       },

       
       postMixInProperties: function(){
        this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
        this.textId = this.id + "_textBox";
        this.selectId = this.id + "_select";
       },

       
       postCreate: function(){
        var select = this.suggestionSelect;

        
        // Customize multi-select to single select
        dojo.removeAttr(select.domNode, "multiple");
        select.addItems = function(/*Array*/ items){
         // summary:
         //  Add items to the select widget
         // items:
         //  An array of items be added to the select
         // tags:
         //  public
         var _this = this;
         var o = null;
         if(items && items.length > 0){
          dojo.forEach(items, function(item, i){
           o = dojo.create("option", {innerHTML: item, value: item}, _this.domNode);
           if(i == 0){
            o.selected = true;
           }
          });
         }
        };
        select.removeItems = function(){
         // summary:
         //  Remove all the items within the select widget
         // tags:
         //  public
         dojo.empty(this.domNode);
        };

       
        select.deselectAll = function(){
         // summary:
         //  De-select all the selected items
         // tags:
         //  public
         this.containerNode.selectedIndex = -1;
        };

        
        // Connect up all the controls with their event handler
        this.connect(this, "onKeyPress", "_cancel");
        this.connect(this.unfoundTextBox, "onKeyPress", "_enter");
        this.connect(this.unfoundTextBox, "onChange", "_unfoundTextBoxChange");
        this.connect(this.suggestionSelect, "onKeyPress", "_enter");
        this.connect(this.skipButton, "onClick", "onSkip");
        this.connect(this.skipAllButton, "onClick", "onSkipAll");
        this.connect(this.toDicButton, "onClick", "onAddToDic");
        this.connect(this.replaceButton, "onClick", "onReplace");
        this.connect(this.replaceAllButton, "onClick", "onReplaceAll");
        this.connect(this.cancelButton, "onClick", "onCancel");
       },

       
       /*************************************************************************/
       /** Public Methods **/
       /*************************************************************************/

       
       onSkip: function(){
        // Stub for the click event of the skip button.
       },

       
       onSkipAll: function(){
        // Stub for the click event of the skipAll button.
       },

       
       onAddToDic: function(){
        // Stub for the click event of the toDic button.
       },

       
       onReplace: function(){
        // Stub for the click event of the replace button.
       },

       
       onReplaceAll: function(){
        // Stub for the click event of the replaceAll button.
       },

       
       onCancel: function(){
        // Stub for the click event of the cancel button.
       },

       
       onEnter: function(){
        // Stub for the enter event of the unFound textbox.
       },

       
       focus: function(){
        // summary:
        //  Set the focus of the control
        // tags:
        //  public
        this.unfoundTextBox.focus();
       },

       
       /*************************************************************************/
       /** Private Methods **/
       /*************************************************************************/

       
       _cancel: function(/*Event*/ evt){
        // summary:
        //  Handle the cancel event
        // evt:
        //  The event object
        // tags:
        //  private
        if(evt.keyCode == dojo.keys.ESCAPE){
         this.onCancel();
         dojo.stopEvent(evt);
        }
       },

       
       _enter: function(/*Event*/ evt){
        // summary:
        //  Handle the enter event
        // evt:
        //  The event object
        // tags:
        //  private
        if(evt.keyCode == dojo.keys.ENTER){
         this.onEnter();
         dojo.stopEvent(evt);
        }
       },

       
       _unfoundTextBoxChange: function(){
        // summary:
        //  Indicate that the Not Found textbox is changed or not
        // tags:
        //  private
        var id = this.textId + "_label";
        if(!this.ignoreChange){
         dojo.byId(id).innerHTML = this["replaceWith"];
         this.isChanged = true;
         this.suggestionSelect.deselectAll();
        }else{
         dojo.byId(id).innerHTML = this["unfound"];
        }
       },

       
       _setUnfoundWordAttr: function(/*String*/ value){
        // summary:
        //  Set the value of the Not Found textbox
        // value:
        //  The value of the Not Found textbox
        // tags:
        //  private
        value = value || "";
        this.unfoundTextBox.set("value", value);
       },

       
       _getUnfoundWordAttr: function(){
        // summary:
        //  Get the value of the Not Found textbox
        // tags:
        //  private
        return this.unfoundTextBox.get("value");
       },

       
       _setSuggestionListAttr: function(/*Array*/ values){
        // summary:
        //  Set the items of the suggestion list
        // values:
        //  The list of the suggestion items
        // tags:
        //  private
        var select = this.suggestionSelect;
        values = values || [];
        select.removeItems();
        select.addItems(values);
       },

       
       _getSelectedWordAttr: function(){
        // summary:
        //  Get the suggested word.
        //  If the select box is selected, the value is the selected item's value,
        //  else the value the the textbox's value
        // tags:
        //  private
        var selected = this.suggestionSelect.getSelected();
        if(selected && selected.length > 0){
         return selected[0].value;
        }else{
         return this.unfoundTextBox.get("value");
        }
       },

       
       _setDisabledAttr: function(/*Boolean*/ disabled){
        // summary:
        //  Enable/disable the control
        // tags:
        //  private
        this.skipButton.set("disabled", disabled);
        this.skipAllButton.set("disabled", disabled);
        this.toDicButton.set("disabled", disabled);
        this.replaceButton.set("disabled", disabled);
        this.replaceAllButton.set("disabled", disabled);
       },

       
       _setInProgressAttr: function(/*Boolean*/ show){
        // summary:
        //  Set the visibility of the progress icon
        // tags:
        //  private
        var id = this.id + "_progressIcon",
         cmd = show ? "removeClass" : "addClass";
         dojo[cmd](id, "hidden");
       }
      });


      dojo.declare("dojox.editor.plugins._SpellCheckScriptMultiPart", null, {
       // summary:
       //  It is a base network service component. It transfers text to a remote service port
       //  with cross domain ability enabled. It can split text into specified pieces and send
       //  them out one by one so that it can handle the case when the service has a limitation of
       //  the capability.
       //  The encoding is UTF-8.

       
       // ACTION [public const] String
       //  Actions for the server-side piece to take
       ACTION_QUERY: "query",
       ACTION_UPDATE: "update",

       
       // callbackHandle [public] String
       //  The callback name of JSONP
       callbackHandle: "callback",

       
       // maxBufferLength [public] Number
       //  The max number of charactors that send to the service at one time.
       maxBufferLength: 100,

       
       // delimiter [public] String
       //  A token that is used to identify the end of a word (a complete unit). It prevents the service from
       //  cutting a single word into two parts. For example:
       //   "Dojo toolkit is a ajax framework. It helps the developers buid their web applications."
       //  Without the delimiter, the sentence might be split into the follow pieces which is absolutely
       //  not the result we want.
       //   "Dojo toolkit is a ajax fram", "ework It helps the developers bu", "id their web applications"
       //  Having " " as the delimiter, we get the following correct pieces.
       //   "Dojo toolkit is a ajax framework", " It helps the developers buid", " their web applications"
       delimiter: " ",

       
       // label [public] String
       //  The leading label of the JSON response. The service will return the result like this:
       //  {response: [
       //    {
       //     text: "teest",
       //     suggestion: ["test","treat"]
       //    }
       //   ]}
       label: "response",

       
       // _timeout [private] Number
       //  Set JSONP timeout period
       _timeout: 30000,
       SEC: 1000,

       
       constructor: function(){
        // The URL of the target service
        this.serviceEndPoint = "";
        // The queue that holds all the xhr request
        this._queue = [];
        // Indicate if the component is still working. For example, waiting for collecting all
        // the responses from the service
        this.isWorking = false;
        // The extra command passed to the service
        this.exArgs = null;
        // The counter that indicate if all the responses are collected to
        // assemble the final result.
        this._counter = 0;
       },

       
       send: function(/*String*/ content, /*String?*/ action){
        // summary:
        //  Send the content to the service port with the specified action
        // content:
        //  The text to be sent
        // action:
        //  The action the service should take. Current support actions are
        //  ACTION_QUERY and ACTION_UPDATE
        // tags:
        //  public
        var _this = this,
         dt = this.delimiter,
         mbl = this.maxBufferLength,
         label = this.label,
         serviceEndPoint = this.serviceEndPoint,
         callbackParamName = this.callbackHandle,
         comms = this.exArgs,
         timeout = this._timeout,
         l = 0, r = 0;

        
        // Temparary list that holds the result returns from the service, which will be
        // assembled into a completed one.
        if(!this._result) {
         this._result = [];
        }


        action = action || this.ACTION_QUERY;


        var batchSend = function(){
         var plan = [];
         var plannedSize = 0;
         if(content && content.length > 0){
          _this.isWorking = true;
          var len = content.length;
          do{
           l = r + 1;
           if((r += mbl) > len){
            r = len;
           }else{
            // If there is no delimiter (emplty string), leave the right boundary where it is.
            // Else extend the right boundary to the first occurance of the delimiter if
            // it doesn't meet the end of the content.
            while(dt && content.charAt(r) != dt && r <= len){
             r++;
            }
           }
           // Record the information of the text slices
           plan.push({l: l, r: r});
           plannedSize++;
          }while(r < len);


          dojo.forEach(plan, function(item, index){
           var jsonpArgs = {
            url: serviceEndPoint,
            action: action,
            timeout: timeout,
            callbackParamName: callbackParamName,
            handle: function(response, ioArgs){
             if(++_this._counter <= this.size && !(response instanceof Error) &&
              response[label] && dojo.isArray(response[label])){
              // Collect the results
              var offset = this.offset;
              dojo.forEach(response[label], function(item){
               item.offset += offset;
              });
              // Put the packages in order
              _this._result[this.number]= response[label];
             }
             if(_this._counter == this.size){
              _this._finalizeCollection(this.action);
              _this.isWorking = false;
              if(_this._queue.length > 0){
               // Call the next request waiting in queue
               (_this._queue.shift())();
              }
             }
            }
           };
           jsonpArgs.content = comms ? dojo.mixin(comms, {action: action, content: content.substring(item.l - 1, item.r)}):
                   {action: action, content: content.substring(item.l - 1, item.r)};
           jsonpArgs.size = plannedSize;
           jsonpArgs.number = index; // The index of the current package
           jsonpArgs.offset = item.l - 1;
           dojo.io.script.get(jsonpArgs);
          });
         }
        };

       
        if(!_this.isWorking){
         batchSend();
        }else{
         _this._queue.push(batchSend);
        }
       },

       
       _finalizeCollection: function(action){
        // summary:
        //  Assemble the responses into one result.
        // action:
        //  The action token
        // tags:
        //  private
        var result = this._result,
         len = result.length;
        // Turn the result into a one-dimensional array
        for(var i = 0; i < len; i++){
         var temp = result.shift();
         result = result.concat(temp);
        }
        if(action == this.ACTION_QUERY){
         this.onLoad(result);
        }
        this._counter = 0;
        this._result = [];
       },

       
       onLoad: function(/*String*/ data){
        // Stub method for a sucessful call
       },

       
       setWaitingTime: function(/*Number*/ seconds){
        this._timeout = seconds * this.SEC;
       }
      });


      dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
       // summary:
       //  This plugin provides a spelling check cabability for the editor.

       
       // url [public] String
       //  The url of the spelling check service
       url: "",

       
       // bufferLength [public] Number
       //  The max length of each XHR request. It is used to divide the large
       //  text into pieces so that the server-side piece can hold.
       bufferLength: 100,

       
       // interactive [public] Boolean
       //  Indicate if the interactive spelling check is enabled
       interactive: false,

       
       // timeout [public] Number
       //  The minutes to waiting for the response. The default value is 30 seconds.
       timeout: 30,

       
       // button [protected] dijit.form.DropDownButton
       //  The button displayed on the editor's toolbar
       button: null,

       
       // _editor [private] dijit.Editor
       //  The reference to the editor the plug-in belongs to.
       _editor: null,

       
       // exArgs [private] Object
       //  The object that holds all the parametes passed into the constructor
       exArgs: null,

       
       // _cursorSpan [private] String
       //  The span that holds the current position of the cursor
       _cursorSpan:
        "",

       
       // _cursorSelector [private] String
       //  The CSS selector of the cursor span
       _cursorSelector:
        "cursorPlaceHolder",

       
       // _incorrectWordsSpan [private] String
       //  The wrapper that marks the incorrect words
       _incorrectWordsSpan:
        "${text}",

        
       // _ignoredIncorrectStyle [private] Object
       //  The style of the ignored incorrect words
       _ignoredIncorrectStyle:
        {"cursor": "inherit", "borderBottom": "none", "backgroundColor": "transparent"},

        
       // _normalIncorrectStyle [private] Object
       //  The style of the marked incorrect words.
       _normalIncorrectStyle:
        {"cursor": "pointer", "borderBottom": "1px dotted red", "backgroundColor": "yellow"},

       
       // _highlightedIncorrectStyle [private] Object
       //  The style of the highlighted incorrect words
       _highlightedIncorrectStyle:
        {"borderBottom": "1px dotted red", "backgroundColor": "#b3b3ff"},

       
       // _selector [private] String
       //  An empty CSS class that identifies the incorrect words
       _selector: "incorrectWordPlaceHolder",

       
       // _maxItemNumber [private] Number
       //  The max number of the suggestion list items
       _maxItemNumber: 3,

       
       /*************************************************************************/
       /** Framework Methods **/
       /*************************************************************************/

       
       constructor: function(){
        // A list that holds all the spans that contains the incorrect words
        // It is used to select/replace the specified word.
        this._spanList = [];
        // The cache that stores all the words. It looks like the following
        // {
        // "word": [],
        // "wrd": ["word", "world"]
        // }
        this._cache = {};
        // Indicate if this plugin is enabled or not
        this._enabled = true;
        // The index of the _spanList
        this._iterator = 0;
  • dojox.editor.plugins.SpellCheck.url

    • summary
  • dojox.editor.plugins.SpellCheck.bufferLength

    • summary
  • dojox.editor.plugins.SpellCheck.interactive

    • summary
  • dojox.editor.plugins.SpellCheck.timeout

    • summary
  • dojox.editor.plugins.SpellCheck.button

    • summary
  • dojox.editor.plugins.SpellCheck._editor

    • summary
  • dojox.editor.plugins.SpellCheck.exArgs

    • summary
  • dojox.editor.plugins.SpellCheck._cursorSpan

    • summary
  • dojox.editor.plugins.SpellCheck._cursorSelector

    • summary
  • dojox.editor.plugins.SpellCheck._incorrectWordsSpan

    • summary
  • dojox.editor.plugins.SpellCheck._ignoredIncorrectStyle

    • type
      Object
    • summary
  • dojox.editor.plugins.SpellCheck._normalIncorrectStyle

    • type
      Object
    • summary
  • dojox.editor.plugins.SpellCheck._highlightedIncorrectStyle

    • type
      Object
    • summary
  • dojox.editor.plugins.SpellCheck._selector

    • summary
  • dojox.editor.plugins.SpellCheck._maxItemNumber

    • summary
  • dojox.editor.plugins.SpellCheck.setEditor

    • type
      Function
    • parameters:
      • editor: (typeof dijit.Editor)
    • source: [view]
        this._editor = editor;
        this._initButton();
        this._setNetwork();
        this._connectUp();
    • summary
  • dojox.editor.plugins.SpellCheck._initButton

    • type
      Function
    • source: [view]
        var _this = this,
         strings = this._strings = dojo.i18n.getLocalization("dojox.editor.plugins", "SpellCheck"),
         dialogPane = this._dialog = new dijit.TooltipDialog();

        
        dialogPane.set("content", (this._dialogContent = new dojox.editor.plugins._spellCheckControl({
         unfound: strings["unfound"],
         skip: strings["skip"],
         skipAll: strings["skipAll"],
         toDic: strings["toDic"],
         suggestions: strings["suggestions"],
         replaceWith: strings["replaceWith"],
         replace: strings["replace"],
         replaceAll: strings["replaceAll"],
         cancel: strings["cancel"]
        })));

        
        this.button = new dijit.form.DropDownButton({
         label: strings["widgetLabel"],
         showLabel: false,
         iconClass: "dijitEditorSpellCheckIcon",
         dropDown: dialogPane,
         id: dijit.getUniqueId(this.declaredClass.replace(/\./g,"_")) + "_dialogPane",
         closeDropDown: function(focus){
          // Determine if the dialog can be closed
          if(_this._dialogContent.closable){
           _this._dialogContent.isOpen = false;
           if(dojo.isIE){
            var pos = _this._iterator,
             list = _this._spanList;
            if(pos < list.length && pos >=0 ){
             dojo.style(list[pos], _this._normalIncorrectStyle);
            }
           }
           if(this._opened){
            dijit.popup.close(this.dropDown);
            if(focus){ this.focus(); }
            this._opened = false;
            this.state = "";
           }
          }
         }
        });
        _this._dialogContent.isOpen = false;

        
        dijit.setWaiState(dialogPane.domNode, "label", this._strings["widgetLabel"]);
    • summary
      Initialize the button displayed on the editor's toolbar
    • tags:
  • dojox.editor.plugins.SpellCheck._setNetwork

    • type
      Function
    • source: [view]
        var comms = this.exArgs;

        
        if(!this._service){
         var service = this._service = new dojox.editor.plugins._SpellCheckScriptMultiPart();
         service.serviceEndPoint = this.url;
         service.maxBufferLength = this.bufferLength;
         service.setWaitingTime(this.timeout);
         // Pass the other arguments directly to the service
         if(comms){
          delete comms.name;
          delete comms.url;
          delete comms.interactive;
          delete comms.timeout;
          service.exArgs = comms;
         }
        }
    • summary
      Set up the underlying network service
    • tags:
  • dojox.editor.plugins.SpellCheck._connectUp

    • type
      Function
    • source: [view]
        var editor = this._editor,
         cont = this._dialogContent;

        
        this.connect(this.button, "set", "_disabled");
        this.connect(this._service, "onLoad", "_loadData");
        this.connect(this._dialog, "onOpen", "_openDialog");
        this.connect(editor, "onKeyPress", "_keyPress");
        this.connect(editor, "onLoad", "_submitContent");
        this.connect(cont, "onSkip", "_skip");
        this.connect(cont, "onSkipAll", "_skipAll");
        this.connect(cont, "onAddToDic", "_add");
        this.connect(cont, "onReplace", "_replace");
        this.connect(cont, "onReplaceAll", "_replaceAll");
        this.connect(cont, "onCancel", "_cancel");
        this.connect(cont, "onEnter", "_enter");

        
        editor.contentPostFilters.push(this._spellCheckFilter); // Register the filter
        dojo.publish(dijit._scopeName + ".Editor.plugin.SpellCheck.getParser", [this]); // Get the language parser
        if(!this.parser){
         console.error("Can not get the word parser!");
        }
    • summary
      Connect up all the events with their event handlers
    • tags:
  • dojox.editor.plugins.SpellCheck._disabled

    • type
      Function
    • parameters:
      • name: (typeof Command)
        name
      • disabled: (typeof Command)
        argument
    • source: [view]
        if(name == "disabled"){
         if(disabled){
          this._iterator = 0;
          this._spanList = [];
         }else if(this.interactive && !disabled && this._service){
          this._submitContent(true);
         }
         this._enabled = !disabled;
        }
    • summary
      When the plugin is disabled (the button is disabled), reset all to their initial status.
      If the interactive mode is on, check the content once it is enabled.
    • tags:
  • dojox.editor.plugins.SpellCheck._keyPress

    • type
      Function
    • parameters:
      • evt: (typeof )
    • source: [view]
        if(this.interactive){
         var v = 118, V = 86,
          cc = evt.charCode;
         if(!evt.altKey && cc == dojo.keys.SPACE){
          this._submitContent();
         }else if((evt.ctrlKey && (cc == v || cc == V)) || (!evt.ctrlKey && evt.charCode)){
          this._submitContent(true);
         }
        }
    • summary
      The handler of the onKeyPress event of the editor
    • tags:
  • dojox.editor.plugins.SpellCheck._loadData

    • type
      Function
    • parameters:
      • data: (typeof Array)
        The result of the query
    • source: [view]
        var cache = this._cache,
         html = this._editor.get("value"),
         cont = this._dialogContent;

        
        this._iterator = 0;

        
        // Update the local cache
        dojo.forEach(data, function(d){
         cache[d.text] = d.suggestion;
         cache[d.text].correct = false;
        });


        if(this._enabled){
         // Mark incorrect words
         cont.closable = false;
         this._markIncorrectWords(html, cache);
         cont.closable = true;

         
         if(this._dialogContent.isOpen){
          this._iterator = -1;
          this._skip();
         }
        }
    • summary
      Apply the query result to the content
    • tags:
  • dojox.editor.plugins.SpellCheck._openDialog

    • type
      Function
    • source: [view]
        var cont = this._dialogContent;

        
        // Clear dialog content and disable it first
        cont.ignoreChange = true;
        cont.set("unfoundWord", "");
        cont.set("suggestionList", null);
        cont.set("disabled", true);
        cont.set("inProgress", true);

        
        cont.isOpen = true; // Indicate that the dialog is open
        cont.closable = false;

        
        this._submitContent();

        
        cont.closable = true;
    • summary
      The handler of the onOpen event
  • dojox.editor.plugins.SpellCheck._skip

    • type
      Function
    • parameters:
      • evt: (typeof Event)
        The event object
      • noUpdate: (typeof Boolean)
        Indicate whether to update the status of the span list or not
    • source: [view]
        var cont = this._dialogContent,
         list = this._spanList || [],
         len = list.length,
         iter = this._iterator;

        
        cont.closable = false;
        cont.isChanged = false;
        cont.ignoreChange = true;

        
        // Skip the current word
        if(!noUpdate && iter >= 0 && iter < len){
         this._skipWord(iter);
        }

        
        // Move to the next
        while(++iter < len && list[iter].edited == true){ /* do nothing */}
        if(iter < len){
         this._iterator = iter;
         this._populateDialog(iter);
         this._selectWord(iter);
        }else{
         // Reaches the end of the list
         this._iterator = -1;
         cont.set("unfoundWord", this._strings["msg"]);
         cont.set("suggestionList", null);
         cont.set("disabled", true);
         cont.set("inProgress", false);
        }

        
        setTimeout(function(){
         // When moving the focus out of the iframe in WebKit browsers, we
         // need to focus something else first. So the textbox
         // can be focused correctly.
         if(dojo.isWebKit) { cont.skipButton.focus(); }
         cont.focus();
         cont.ignoreChange = false;
         cont.closable = true;
        }, 0);
    • summary
      Ignore this word and move to the next unignored one.
    • tags:
  • dojox.editor.plugins.SpellCheck._skipAll

    • type
      Function
    • source: [view]
        this._dialogContent.closable = false;
        this._skipWordAll(this._iterator);
        this._skip();
    • summary
      Ignore all the same words
    • tags:
  • dojox.editor.plugins.SpellCheck._add

    • type
      Function
    • source: [view]
        var cont = this._dialogContent;

        
        cont.closable = false;
        cont.isOpen = true;
        this._addWord(this._iterator, cont.get("unfoundWord"));
        this._skip();
    • summary
      Add the unrecognized word into the dictionary
    • tags:
  • dojox.editor.plugins.SpellCheck._replace

    • type
      Function
    • source: [view]
        var cont = this._dialogContent,
         iter = this._iterator,
         targetWord = cont.get("selectedWord");

        
        cont.closable = false;
        this._replaceWord(iter, targetWord);
        this._skip(null, true);
    • summary
      Replace the incorrect word with the selected one,
      or the one the user types in the textbox
    • tags:
  • dojox.editor.plugins.SpellCheck._replaceAll

    • type
      Function
    • source: [view]
        var cont = this._dialogContent,
         list = this._spanList,
         len = list.length,
         word = list[this._iterator].innerHTML.toLowerCase(),
         targetWord = cont.get("selectedWord");

        
        cont.closable = false;
        for(var iter = 0; iter < len; iter++){
         // If this word is not ignored and is the same as the source word,
         // replace it.
         if(list[iter].innerHTML.toLowerCase() == word){
          this._replaceWord(iter, targetWord);
         }
        }

        
        this._skip(null, true);
    • summary
      Replace all the words with the same text
    • tags:
  • dojox.editor.plugins.SpellCheck._cancel

    • type
      Function
    • source: [view]
        this._dialogContent.closable = true;
        this._editor.focus();
    • summary
      Cancel this check action
    • tags:
  • dojox.editor.plugins.SpellCheck._enter

    • type
      Function
    • source: [view]
        if(this._dialogContent.isChanged){
         this._replace();
        }else{
         this._skip();
        }
    • summary
      Handle the ENTER event
    • tags:
  • dojox.editor.plugins.SpellCheck._query

    • type
      Function
    • parameters:
      • html: (typeof String)
        The html value of the editor
    • source: [view]
        var service = this._service,
         cache = this._cache,
         words = this.parser.parseIntoWords(this._html2Text(html)) || [];
        var content = [];
        dojo.forEach(words, function(word){
         word = word.toLowerCase();
         if(!cache[word]){
          // New word that need to be send to the server side for check
          cache[word] = [];
          cache[word].correct = true;
          content.push(word);
         }
        });
        if(content.length > 0){
         service.send(content.join(" "));
        }else if(!service.isWorking){
         this._loadData([]);
        }
    • summary
      Send the query text to the service. The query text is a string of words
      separated by space.
    • tags:
  • dojox.editor.plugins.SpellCheck._html2Text

    • type
      Function
    • parameters:
      • html: (typeof The)
        html code
    • source: [view]
        var text = [],
         isTag = false,
         len = html ? html.length : 0;

        
        for(var i = 0; i < len; i++){
         if(html.charAt(i) == "<"){ isTag = true; }
         if(isTag == true){
          text.push(" ");
         }else{
          text.push(html.charAt(i));
         }
         if(html.charAt(i) == ">"){ isTag = false; }

         
        }
        return text.join("");
    • summary
      Substitute the tag with white charactors so that the server
      can easily process the text. For example:
      &quot;&lt;a src=&quot;sample.html&quot;&gt;Hello, world!&lt;/a&gt;&quot; ==&gt;
      &quot;                     Hello, world!    &quot;
    • tags:
  • dojox.editor.plugins.SpellCheck._getBookmark

    • type
      Function
    • parameters:
      • eValue: (typeof String)
        The html value of the editor
    • source: [view]
        var ed = this._editor,
         cp = this._cursorSpan;
        ed.execCommand("inserthtml", cp);
        var nv = ed.get("value"),
         index = nv.indexOf(cp),
         i = -1;
        while(++i < index && eValue.charAt(i) == nv.charAt(i)){ /* do nothing */}
        return i;
    • summary
      Get the cursor position. It is the index of the characters
      where the cursor is.
    • tags:
  • dojox.editor.plugins.SpellCheck._moveToBookmark

    • type
      Function
    • source: [view]
        var ed = this._editor,
         cps = dojo.withGlobal(ed.window, "query", dojo, ["." + this._cursorSelector]),
         cursorSpan = cps && cps[0];
        // Find the cursor place holder
        if(cursorSpan){
         ed._sCall("selectElement", [cursorSpan]);
         ed._sCall("collapse", [true]);
         var parent = cursorSpan.parentNode;
         if(parent){ parent.removeChild(cursorSpan); }
        }
    • summary
      Move to the position when the cursor was.
    • tags:
  • dojox.editor.plugins.SpellCheck._submitContent

    • type
      Function
    • parameters:
      • delay: (typeof Boolean)
        Indicate if the action is taken immediately or not
    • source: [view]
        if(delay){
         var _this = this,
          interval = 3000;
         if(this._delayHandler){
          clearTimeout(this._delayHandler);
          this._delayHandler = null;
         }
         setTimeout(function(){ _this._query(_this._editor.get("value")); }, interval);
        }else{
         this._query(this._editor.get("value"));
        }
    • summary
      Functions to submit the content of the editor
    • tags:
  • dojox.editor.plugins.SpellCheck._populateDialog

    • type
      Function
    • parameters:
      • index: (typeof The)
        idex of the span list
    • source: [view]
        var list = this._spanList,
         cache = this._cache,
         cont = this._dialogContent;

        
        cont.set("disabled", false);
        if(index < list.length && list.length > 0){
         var word = list[index].innerHTML;
         cont.set("unfoundWord", word);
         cont.set("suggestionList", cache[word.toLowerCase()]);
         cont.set("inProgress", false);
        }
    • summary
      Populate the content of the dailog
    • tags:
  • dojox.editor.plugins.SpellCheck._markIncorrectWords

    • type
      Function
    • parameters:
      • html: (typeof String)
        The html value of the editor
      • cache: (typeof Object)
        The local word cache
    • source: [view]
        var _this = this,
         parser = this.parser,
         editor = this._editor,
         spanString = this._incorrectWordsSpan,
         nstyle = this._normalIncorrectStyle,
         selector = this._selector,
         words = parser.parseIntoWords(this._html2Text(html).toLowerCase()),
         indices = parser.getIndices(),
         bookmark = this._cursorSpan,
         bmpos = this._getBookmark(html),
         spanOffset = "".length,
         bmMarked = false,
         cArray = html.split(""),
         spanList = null;

        
        // Mark the incorrect words and cursor position
        for(var i = words.length - 1; i >= 0; i--){
         var word = words[i];
         if(cache[word] && !cache[word].correct){
          var offset = indices[i],
           len = words[i].length,
           end = offset + len;
          if(end <= bmpos && !bmMarked){
           cArray.splice(bmpos, 0, bookmark);
           bmMarked = true;
          }
          cArray.splice(offset, len, dojo.string.substitute(spanString, {text: html.substring(offset, end)}));
          if(offset < bmpos && bmpos < end && !bmMarked){
           var tmp = cArray[offset].split("");
           tmp.splice(spanOffset + bmpos - offset, 0, bookmark);
           cArray[offset] = tmp.join("");
           bmMarked = true;
          }
         }
        }
        if(!bmMarked){
         cArray.splice(bmpos, 0, bookmark);
         bmMarked = true;
        }

        
        editor.set("value", cArray.join(""));
        editor._cursorToStart = false; // HACK! But really necessary here.

        
        this._moveToBookmark();

        
        // Get the incorrect words
        spanList = this._spanList = dojo.withGlobal(editor.window, "query", dojo, ["." + this._selector]);
        dojo.forEach(spanList, function(span, i){ span.id = selector + i; });

        
        // Set them to the incorrect word style
        if(!this.interactive){ delete nstyle.cursor; }
        spanList.style(nstyle);

        
        if(this.interactive){
         // Build the context menu
         if(_this._contextMenu){
          _this._contextMenu.uninitialize();
          _this._contextMenu = null;
         }
         _this._contextMenu = new dijit.Menu({
          targetNodeIds: [editor.iframe],

          
          bindDomNode: function(/*String|DomNode*/ node){
           // summary:
           //  Attach menu to given node
           node = dojo.byId(node);

         
           var cn; // Connect node

         
           // Support context menus on iframes. Rather than binding to the iframe itself we need
           // to bind to the node inside the iframe.
           var iframe, win;
           if(node.tagName.toLowerCase() == "iframe"){
            iframe = node;
            win = this._iframeContentWindow(iframe);
            cn = dojo.withGlobal(win, dojo.body);
           }else{

            
            // To capture these events at the top level, attach to , not .
            // Otherwise right-click context menu just doesn't work.
            cn = (node == dojo.body() ? dojo.doc.documentElement : node);
           }

         

         
           // "binding" is the object to track our connection to the node (ie, the parameter to bindDomNode())
           var binding = {
            node: node,
            iframe: iframe
           };

         
           // Save info about binding in _bindings[], and make node itself record index(+1) into
           // _bindings[] array. Prefix w/_dijitMenu to avoid setting an attribute that may
           // start with a number, which fails on FF/safari.
           dojo.attr(node, "_dijitMenu" + this.id, this._bindings.push(binding));

         
           // Setup the connections to monitor click etc., unless we are connecting to an iframe which hasn't finished
           // loading yet, in which case we need to wait for the onload event first, and then connect
           // On linux Shift-F10 produces the oncontextmenu event, but on Windows it doesn't, so
           // we need to monitor keyboard events in addition to the oncontextmenu event.
           var doConnects = dojo.hitch(this, function(cn){
            return [
             // TODO: when leftClickToOpen is true then shouldn't space/enter key trigger the menu,
             // rather than shift-F10?
             dojo.connect(cn, this.leftClickToOpen ? "onclick" : "oncontextmenu", this, function(evt){
              var target = evt.target,
               strings = _this._strings;
              // Schedule context menu to be opened unless it's already been scheduled from onkeydown handler
              if(dojo.hasClass(target, selector) && !target.edited){ // Click on the incorrect word
               dojo.stopEvent(evt);

               
               // Build the on-demand menu items
               var maxNumber = _this._maxItemNumber,
                id = target.id,
                index = id.substring(selector.length),
                suggestions = cache[target.innerHTML.toLowerCase()],
                slen = suggestions.length;

                
               // Add the suggested words menu items
               this.destroyDescendants();
               if(slen == 0){
                this.addChild(new dijit.MenuItem({
                 label: strings["iMsg"],
                 disabled: true
                }));
               }else{
                for(var i = 0 ; i < maxNumber && i < slen; i++){
                 this.addChild(new dijit.MenuItem({
                  label: suggestions[i],
                  onClick: (function(){
                   var idx = index, txt = suggestions[i];
                   return function(){
                    _this._replaceWord(idx, txt);
                    editor.focus();
                   };
                  })()
                 }));
                }
               }

               
               //Add the other action menu items
               this.addChild(new dijit.MenuSeparator());
               this.addChild(new dijit.MenuItem({
                label: strings["iSkip"],
                onClick: function(){
                 _this._skipWord(index);
                 editor.focus();
                }
               }));
               this.addChild(new dijit.MenuItem({
                label: strings["iSkipAll"],
                onClick: function(){
                 _this._skipWordAll(index);
                 editor.focus();
                }
               }));
               this.addChild(new dijit.MenuSeparator());
               this.addChild(new dijit.MenuItem({
                label: strings["toDic"],
                onClick: function(){
                 _this._addWord(index);
                 editor.focus();
                }
               }));

               
               this._scheduleOpen(target, iframe, {x: evt.pageX, y: evt.pageY});
              }
             }),
             dojo.connect(cn, "onkeydown", this, function(evt){
              if(evt.shiftKey && evt.keyCode == dojo.keys.F10){
               dojo.stopEvent(evt);
               this._scheduleOpen(evt.target, iframe); // no coords - open near target node
              }
             })
            ];
           });
           binding.connects = cn ? doConnects(cn) : [];

         
           if(iframe){
            // Setup handler to [re]bind to the iframe when the contents are initially loaded,
            // and every time the contents change.
            // Need to do this b/c we are actually binding to the iframe's node.
            // Note: can't use dojo.connect(), see #9609.

         
            binding.onloadHandler = dojo.hitch(this, function(){
             // want to remove old connections, but IE throws exceptions when trying to
             // access the node because it's already gone, or at least in a state of limbo

         
             var win = this._iframeContentWindow(iframe);
              cn = dojo.withGlobal(win, dojo.body);
             binding.connects = doConnects(cn);
            });
            if(iframe.addEventListener){
             iframe.addEventListener("load", binding.onloadHandler, false);
            }else{
             iframe.attachEvent("onload", binding.onloadHandler);
            }
           }
          }
         });
        }
    • summary
      Mark the incorrect words and set up menus if available
    • tags:
  • dojox.editor.plugins.SpellCheck._selectWord

    • type
      Function
    • parameters:
      • index: (typeof The)
        index of the span list
    • source: [view]
        var list = this._spanList,
         win = this._editor.window;

        
        if(index < list.length && list.length > 0){
         dojo.withGlobal(win, "selectElement", dijit._editor.selection, [list[index]]);
         dojo.withGlobal(win, "collapse", dijit._editor.selection, [true]);
         this._findText(list[index].innerHTML, false, false);
         if(dojo.isIE){
          // Because the selection in the iframe will be lost when the outer window get the
          // focus, we need to mimic the highlight ourselves.
          dojo.style(list[index], this._highlightedIncorrectStyle);
         }
        }
    • summary
      Select the incorrect word. Move to it and highlight it
    • tags:
  • dojox.editor.plugins.SpellCheck._replaceWord

    • type
      Function
    • parameters:
      • index: (typeof The)
        index of the span list
      • text: (typeof The)
        text to be replaced with
    • source: [view]
        var list = this._spanList;

        
        list[index].innerHTML = text;
        dojo.style(list[index], this._ignoredIncorrectStyle);
        list[index].edited = true;
    • summary
      Replace the word at the given index with the text
    • tags:
  • dojox.editor.plugins.SpellCheck._skipWord

    • type
      Function
    • parameters:
      • index: (typeof The)
        index of the span list
    • source: [view]
        var list = this._spanList;

        
        dojo.style(list[index], this._ignoredIncorrectStyle);
        this._cache[list[index].innerHTML.toLowerCase()].correct = true;
        list[index].edited = true;
    • summary
      Skip the word at the index
    • tags:
  • dojox.editor.plugins.SpellCheck._skipWordAll

    • type
      Function
    • parameters:
      • index: (typeof The)
        index of the span list
      • word: (typeof String)
        If this argument is given, skip all the words that have the same text
        as the word
    • source: [view]
        var list = this._spanList,
         len = list.length;
        word = word || list[index].innerHTML.toLowerCase();

         
        for(var i = 0; i < len; i++){
         if(!list[i].edited && list[i].innerHTML.toLowerCase() == word){
          this._skipWord(i);
         }
        }
    • summary
      Skip the all the word that have the same text as the word at the index
      or the given word
    • tags:
  • dojox.editor.plugins.SpellCheck._addWord

    • type
      Function
    • parameters:
      • index: (typeof The)
        index of the span list
      • word: (typeof String)
        If this argument is given, add the word to the dictionary and
        skip all the words like it
    • source: [view]
        var service = this._service;
        service.send(word || this._spanList[index].innerHTML.toLowerCase(), service.ACTION_UPDATE);
        this._skipWordAll(index, word);
    • summary
      Add the word at the index to the dictionary
    • tags:
  • dojox.editor.plugins.SpellCheck._findText

    • type
      Function
    • parameters:
      • txt: (typeof String)
        The text to locate in the document.
      • caseSensitive: (typeof Boolean)
        Whether or ot to search case-sensitively.
      • backwards: (typeof Boolean)
        Whether or not to search backwards in the document.
    • source: [view]
        var ed = this._editor,
         win = ed.window,
         found = false;
        if(txt){
         if(win.find){
          found = win.find(txt, caseSensitive, backwards, false, false, false, false);
         }else{
          var doc = ed.document;
          if(doc.selection){
           /* IE */
           // Focus to restore position/selection,
           // then shift to search from current position.
           this._editor.focus();
           var txtRg = doc.body.createTextRange();
           var curPos = doc.selection?doc.selection.createRange():null;
           if(curPos){
            if(backwards){
             txtRg.setEndPoint("EndToStart", curPos);
            }else{
             txtRg.setEndPoint("StartToEnd", curPos);
            }
           }
           var flags = caseSensitive?4:0;
           if(backwards){
            flags = flags | 1;
           }
           //flags = flags |
           found = txtRg.findText(txt,txtRg.text.length,flags);
           if(found){
            txtRg.select();
           }
          }
         }
        }
        return found;
    • summary
      This function invokes a find with specific options
    • tags:
    • return_summary
      Boolean indicating if the content was found or not.
  • dojox.editor.plugins.SpellCheck._spellCheckFilter

    • type
      Function
    • parameters:
      • value: (typeof String)
        The html value of the editor
    • source: [view]
        var regText = /(.*?)<\/span>/g;
        return value.replace(regText, "$1");
    • summary
      Filter out the incorrect word style so that the value of the edtior
      won't include the spans that wrap around the incorrect words
    • tags:
  • dojox.editor.plugins.SpellCheck._ignoredIncorrectStyle.cursor

    • summary
  • dojox.editor.plugins.SpellCheck._ignoredIncorrectStyle.borderBottom

    • summary
  • dojox.editor.plugins.SpellCheck._ignoredIncorrectStyle.backgroundColor

    • summary
  • dojox.editor.plugins.SpellCheck._normalIncorrectStyle.cursor

    • summary
  • dojox.editor.plugins.SpellCheck._normalIncorrectStyle.borderBottom

    • summary
  • dojox.editor.plugins.SpellCheck._normalIncorrectStyle.backgroundColor

    • summary
  • dojox.editor.plugins.SpellCheck._highlightedIncorrectStyle.borderBottom

    • summary
  • dojox.editor.plugins.SpellCheck._highlightedIncorrectStyle.backgroundColor

    • summary
  • dojox.editor.plugins.SpellCheck._strings

    • summary
  • dojox.editor.plugins.SpellCheck._dialog

    • summary
  • dojox.editor.plugins.SpellCheck._dialogContent

    • summary
  • dojox.editor.plugins.SpellCheck._opened

    • summary
  • dojox.editor.plugins.SpellCheck.state

    • summary
  • dojox.editor.plugins.SpellCheck._service

    • summary
  • dojox.editor.plugins.SpellCheck._iterator

    • summary
  • dojox.editor.plugins.SpellCheck._spanList

    • summary
  • dojox.editor.plugins.SpellCheck._enabled

    • summary
  • dojox.editor.plugins.SpellCheck._dialogContent.closable

    • summary
  • dojox.editor.plugins.SpellCheck._delayHandler

    • summary
  • dojox.editor.plugins.SpellCheck._cache

    • summary
  • comms.action

    • summary
  • comms.content

    • summary
  • name

    • summary
  • o.plugin

    • summary
  • dojox.editor.plugins

    • type
      Object
    • summary
  • dojox.editor

    • type
      Object
    • summary
  • dojox

    • type
      Object
    • summary