define("dijit/Editor", ["dojo", "dijit", "dijit/_editor/RichText", "dijit/Toolbar", "dijit/ToolbarSeparator", "dijit/_editor/_Plugin", "dijit/_editor/plugins/EnterKeyHandling", "dijit/_editor/range", "dijit/_Container", "dojo/i18n", "dijit/layout/_LayoutWidget", "i18n!dijit/_editor/nls/commands"], function(dojo, dijit) {
dojo.declare(
 "dijit.Editor",
 dijit._editor.RichText,
 {
  // summary:
  //  A rich text Editing widget
  //
  // description:
  //  This widget provides basic WYSIWYG editing features, based on the browser's
  //  underlying rich text editing capability, accompanied by a toolbar (`dijit.Toolbar`).
  //  A plugin model is available to extend the editor's capabilities as well as the
  //  the options available in the toolbar.  Content generation may vary across
  //  browsers, and clipboard operations may have different results, to name
  //  a few limitations.  Note: this widget should not be used with the HTML
  //  <TEXTAREA> tag -- see dijit._editor.RichText for details.
  // plugins: [const] Object[]
  //  A list of plugin names (as strings) or instances (as objects)
  //  for this widget.
  //
  //  When declared in markup, it might look like:
  // | plugins="['bold',{name:'dijit._editor.plugins.FontChoice', command:'fontName', generic:true}]"
  plugins: null,
  // extraPlugins: [const] Object[]
  //  A list of extra plugin names which will be appended to plugins array
  extraPlugins: null,
  constructor: function(){
   // summary:
   //  Runs on widget initialization to setup arrays etc.
   // tags:
   //  private
   if(!dojo.isArray(this.plugins)){
    this.plugins=["undo","redo","|","cut","copy","paste","|","bold","italic","underline","strikethrough","|",
    "insertOrderedList","insertUnorderedList","indent","outdent","|","justifyLeft","justifyRight","justifyCenter","justifyFull",
    "dijit._editor.plugins.EnterKeyHandling" /*, "createLink"*/];
   }
   this._plugins=[];
   this._editInterval = this.editActionInterval * 1000;
   //IE will always lose focus when other element gets focus, while for FF and safari,
   //when no iframe is used, focus will be lost whenever another element gets focus.
   //For IE, we can connect to onBeforeDeactivate, which will be called right before
   //the focus is lost, so we can obtain the selected range. For other browsers,
   //no equivelent of onBeforeDeactivate, so we need to do two things to make sure
   //selection is properly saved before focus is lost: 1) when user clicks another
   //element in the page, in which case we listen to mousedown on the entire page and
   //see whether user clicks out of a focus editor, if so, save selection (focus will
   //only lost after onmousedown event is fired, so we can obtain correct caret pos.)
   //2) when user tabs away from the editor, which is handled in onKeyDown below.
   if(dojo.isIE){
    this.events.push("onBeforeDeactivate");
    this.events.push("onBeforeActivate");
   }
  },
  postMixInProperties: function() {
   // summary:
   // Extension to make sure a deferred is in place before certain functions
   // execute, like making sure all the plugins are properly inserted.
   // Set up a deferred so that the value isn't applied to the editor
   // until all the plugins load, needed to avoid timing condition
   // reported in #10537.
   this.setValueDeferred = new dojo.Deferred();
   this.inherited(arguments);
  }, 
  postCreate: function(){
   //for custom undo/redo, if enabled.
   this._steps=this._steps.slice(0);
   this._undoedSteps=this._undoedSteps.slice(0);
   if(dojo.isArray(this.extraPlugins)){
    this.plugins=this.plugins.concat(this.extraPlugins);
   }
   this.inherited(arguments);
   this.commands = dojo.i18n.getLocalization("dijit._editor", "commands", this.lang);
   if(!this.toolbar){
    // if we haven't been assigned a toolbar, create one
    this.toolbar = new dijit.Toolbar({
     dir: this.dir,
     lang: this.lang
    });
    this.header.appendChild(this.toolbar.domNode);
   }
   dojo.forEach(this.plugins, this.addPlugin, this);
   // Okay, denote the value can now be set.
   this.setValueDeferred.callback(true);
   dojo.addClass(this.iframe.parentNode, "dijitEditorIFrameContainer");
   dojo.addClass(this.iframe, "dijitEditorIFrame");
   dojo.attr(this.iframe, "allowTransparency", true);
   if(dojo.isWebKit){
    // Disable selecting the entire editor by inadvertant double-clicks.
    // on buttons, title bar, etc.  Otherwise clicking too fast on
    // a button such as undo/redo selects the entire editor.
    dojo.style(this.domNode, "KhtmlUserSelect", "none");
   }
   this.toolbar.startup();
   this.onNormalizedDisplayChanged(); //update toolbar button status
  },
  destroy: function(){
   dojo.forEach(this._plugins, function(p){
    if(p && p.destroy){
     p.destroy();
    }
   });
   this._plugins=[];
   this.toolbar.destroyRecursive();
   delete this.toolbar;
   this.inherited(arguments);
  },
  addPlugin: function(/*String||Object*/plugin, /*Integer?*/index){
   // summary:
   //  takes a plugin name as a string or a plugin instance and
   //  adds it to the toolbar and associates it with this editor
   //  instance. The resulting plugin is added to the Editor's
   //  plugins array. If index is passed, it's placed in the plugins
   //  array at that index. No big magic, but a nice helper for
   //  passing in plugin names via markup.
   //
   // plugin: String, args object or plugin instance
   //
   // args:
   //  This object will be passed to the plugin constructor
   //
   // index: Integer
   //  Used when creating an instance from
   //  something already in this.plugins. Ensures that the new
   //  instance is assigned to this.plugins at that index.
   var args=dojo.isString(plugin)?{name:plugin}:plugin;
   if(!args.setEditor){
    var o={"args":args,"plugin":null,"editor":this};
    dojo.publish(dijit._scopeName + ".Editor.getPlugin",[o]);
    if(!o.plugin){
     var pc = dojo.getObject(args.name);
     if(pc){
      o.plugin=new pc(args);
     }
    }
    if(!o.plugin){
     console.warn('Cannot find plugin',plugin);
     return;
    }
    plugin=o.plugin;
   }
   if(arguments.length > 1){
    this._plugins[index] = plugin;
   }else{
    this._plugins.push(plugin);
   }
   plugin.setEditor(this);
   if(dojo.isFunction(plugin.setToolbar)){
    plugin.setToolbar(this.toolbar);
   }
  },
  //the following 3 functions are required to make the editor play nice under a layout widget, see #4070
  startup: function(){
   // summary:
   //  Exists to make Editor work as a child of a layout widget.
   //  Developers don't need to call this method.
   // tags:
   //  protected
   //console.log('startup',arguments);
  },
  resize: function(size){
   // summary:
   //  Resize the editor to the specified size, see `dijit.layout._LayoutWidget.resize`
   if(size){
    // we've been given a height/width for the entire editor (toolbar + contents), calls layout()
    // to split the allocated size between the toolbar and the contents
    dijit.layout._LayoutWidget.prototype.resize.apply(this, arguments);
   }
   /*
   else{
    // do nothing, the editor is already laid out correctly.   The user has probably specified
    // the height parameter, which was used to set a size on the iframe
   }
   */
  },
  layout: function(){
   // summary:
   //  Called from `dijit.layout._LayoutWidget.resize`.  This shouldn't be called directly
   // tags:
   //  protected
   // Converts the iframe (or rather the 
 surrounding it) to take all the available space
   // except what's needed for the header (toolbars) and footer (breadcrumbs, etc).
   // A class was added to the iframe container and some themes style it, so we have to
   // calc off the added margins and padding too. See tracker: #10662
   var areaHeight = (this._contentBox.h -
    (this.getHeaderHeight() + this.getFooterHeight() +
     dojo._getPadBorderExtents(this.iframe.parentNode).h +
     dojo._getMarginExtents(this.iframe.parentNode).h));
   this.editingArea.style.height = areaHeight + "px";
   if(this.iframe){
    this.iframe.style.height="100%";
   }
   this._layoutMode = true;
                    
                    summaryCalled from `dijit.layout._LayoutWidget.resize`.  This shouldn't be called directly
dijit.Editor._onIEMouseDown
 - type
- parameters: 
- source: [view] 
                    
                       var outsideClientArea;
 // IE 8's componentFromPoint is broken, which is a shame since it
 // was smaller code, but oh well.  We have to do this brute force
 // to detect if the click was scroller or not.
 var b = this.document.body;
 var clientWidth = b.clientWidth;
 var clientHeight = b.clientHeight;
 var clientLeft = b.clientLeft;
 var offsetWidth = b.offsetWidth;
 var offsetHeight = b.offsetHeight;
 var offsetLeft = b.offsetLeft;
 
 
 //Check for vertical scroller click.
 bodyDir = b.dir ? b.dir.toLowerCase() : "";
 if(bodyDir != "rtl"){
 if(clientWidth < offsetWidth && e.x > clientWidth && e.x < offsetWidth){
 // Check the click was between width and offset width, if so, scroller
 outsideClientArea = true;
 }
 }else{
 // RTL mode, we have to go by the left offsets.
 if(e.x < clientLeft && e.x > offsetLeft){
 // Check the click was between width and offset width, if so, scroller
 outsideClientArea = true;
 }
 }
 if(!outsideClientArea){
 // Okay, might be horiz scroller, check that.
 if(clientHeight < offsetHeight && e.y > clientHeight && e.y < offsetHeight){
 // Horizontal scroller.
 outsideClientArea = true;
 }
 }
 if(!outsideClientArea){
 delete this._cursorToStart; // Remove the force to cursor to start position.
 delete this._savedSelection; // new mouse position overrides old selection
 if(e.target.tagName == "BODY"){
 setTimeout(dojo.hitch(this, "placeCursorAtEnd"), 0);
 }
 this.inherited(arguments);
 }
 
- summaryIE only to prevent 2 clicks to focus 
- tags: 
dijit.Editor.onBeforeActivate
dijit.Editor.onBeforeDeactivate
 - type
- parameters: 
- source: [view] 
                    
                       if(this.customUndo){
 this.endEditing(true);
 }
 //in IE, the selection will be lost when other elements get focus,
 //let's save focus before the editor is deactivated
 if(e.target.tagName != "BODY"){
 this._saveSelection();
 }
 //console.log('onBeforeDeactivate',this);
 
- summaryCalled on IE right before focus is lost.   Saves the selected range. 
- tags: 
dijit.Editor.customUndo
 - type
- summaryWhether we shall use custom undo/redo support instead of the native
browser support. By default, we now use custom undo.  It works better
than native browser support and provides a consistent behavior across
browsers with a minimal performance hit.  We already had the hit on
the slowest browser, IE, anyway. 
dijit.Editor.editActionInterval
 - type
- summaryWhen using customUndo, not every keystroke will be saved as a step.
Instead typing (including delete) will be grouped together: after
a user stops typing for editActionInterval seconds, a step will be
saved; if a user resume typing within editActionInterval seconds,
the timeout will be restarted. By default, editActionInterval is 3
seconds. 
dijit.Editor.beginEditing
 - type
- parameters: 
- source: [view] 
                    
                       if(!this._inEditing){
 this._inEditing=true;
 this._beginEditing(cmd);
 }
 if(this.editActionInterval>0){
 if(this._editTimer){
 clearTimeout(this._editTimer);
 }
 this._editTimer = setTimeout(dojo.hitch(this, this.endEditing), this._editInterval);
 }
 
- summaryCalled to note that the user has started typing alphanumeric characters, if it's not already noted.
Deals with saving undo; see editActionInterval parameter. 
- tags: 
dijit.Editor._steps
dijit.Editor.setValueDeferred
dijit.Editor._undoedSteps
dijit.Editor.commands
dijit.Editor.toolbar
dijit.Editor._plugins
dijit.Editor.editingArea.style.height
dijit.Editor.iframe.style.height
dijit.Editor._layoutMode
dijit.Editor._inEditing
dijit.Editor._editTimer
dijit.Editor._editInterval
args
_p
name
p
o.plugin
dijit