summaryrefslogtreecommitdiff
path: root/lib/dijit/Editor.js.uncompressed.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dijit/Editor.js.uncompressed.js')
-rw-r--r--lib/dijit/Editor.js.uncompressed.js865
1 files changed, 0 insertions, 865 deletions
diff --git a/lib/dijit/Editor.js.uncompressed.js b/lib/dijit/Editor.js.uncompressed.js
deleted file mode 100644
index 9c2e30042..000000000
--- a/lib/dijit/Editor.js.uncompressed.js
+++ /dev/null
@@ -1,865 +0,0 @@
-define("dijit/Editor", [
- "require",
- "dojo/_base/array", // array.forEach
- "dojo/_base/declare", // declare
- "dojo/_base/Deferred", // Deferred
- "dojo/i18n", // i18n.getLocalization
- "dojo/dom-attr", // domAttr.set
- "dojo/dom-class", // domClass.add
- "dojo/dom-geometry",
- "dojo/dom-style", // domStyle.set, get
- "dojo/_base/event", // event.stop
- "dojo/keys", // keys.F1 keys.F15 keys.TAB
- "dojo/_base/lang", // lang.getObject lang.hitch
- "dojo/sniff", // has("ie") has("mac") has("webkit")
- "dojo/string", // string.substitute
- "dojo/topic", // topic.publish()
- "dojo/_base/window", // win.withGlobal
- "./_base/focus", // dijit.getBookmark()
- "./_Container",
- "./Toolbar",
- "./ToolbarSeparator",
- "./layout/_LayoutWidget",
- "./form/ToggleButton",
- "./_editor/_Plugin",
- "./_editor/plugins/EnterKeyHandling",
- "./_editor/html",
- "./_editor/range",
- "./_editor/RichText",
- "./main", // dijit._scopeName
- "dojo/i18n!./_editor/nls/commands"
-], function(require, array, declare, Deferred, i18n, domAttr, domClass, domGeometry, domStyle,
- event, keys, lang, has, string, topic, win,
- focusBase, _Container, Toolbar, ToolbarSeparator, _LayoutWidget, ToggleButton,
- _Plugin, EnterKeyHandling, html, rangeapi, RichText, dijit){
-
- // module:
- // dijit/Editor
-
- var Editor = declare("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(/*===== params, srcNodeRef =====*/){
- // summary:
- // Create the widget.
- // params: Object|null
- // Initial settings for any of the attributes, except readonly attributes.
- // srcNodeRef: DOMNode
- // The editor replaces the specified DOMNode.
-
- if(!lang.isArray(this.plugins)){
- this.plugins=["undo","redo","|","cut","copy","paste","|","bold","italic","underline","strikethrough","|",
- "insertOrderedList","insertUnorderedList","indent","outdent","|","justifyLeft","justifyRight","justifyCenter","justifyFull",
- 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 equivalent 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(has("ie")){
- 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 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(lang.isArray(this.extraPlugins)){
- this.plugins=this.plugins.concat(this.extraPlugins);
- }
-
- this.inherited(arguments);
-
- this.commands = i18n.getLocalization("dijit._editor", "commands", this.lang);
-
- if(!this.toolbar){
- // if we haven't been assigned a toolbar, create one
- this.toolbar = new Toolbar({
- ownerDocument: this.ownerDocument,
- dir: this.dir,
- lang: this.lang
- });
- this.header.appendChild(this.toolbar.domNode);
- }
-
- array.forEach(this.plugins, this.addPlugin, this);
-
- // Okay, denote the value can now be set.
- this.setValueDeferred.resolve(true);
-
- domClass.add(this.iframe.parentNode, "dijitEditorIFrameContainer");
- domClass.add(this.iframe, "dijitEditorIFrame");
- domAttr.set(this.iframe, "allowTransparency", true);
-
- if(has("webkit")){
- // Disable selecting the entire editor by inadvertent double-clicks.
- // on buttons, title bar, etc. Otherwise clicking too fast on
- // a button such as undo/redo selects the entire editor.
- domStyle.set(this.domNode, "KhtmlUserSelect", "none");
- }
- this.toolbar.startup();
- this.onNormalizedDisplayChanged(); //update toolbar button status
- },
- destroy: function(){
- array.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||Function*/ 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, plugin instance, or plugin constructor
- // args:
- // This object will be passed to the plugin constructor
- // index:
- // 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=lang.isString(plugin)?{name:plugin}:lang.isFunction(plugin)?{ctor:plugin}:plugin;
- if(!args.setEditor){
- var o={"args":args,"plugin":null,"editor":this};
- if(args.name){
- // search registry for a plugin factory matching args.name, if it's not there then
- // fallback to 1.0 API:
- // ask all loaded plugin modules to fill in o.plugin if they can (ie, if they implement args.name)
- // remove fallback for 2.0.
- if(_Plugin.registry[args.name]){
- o.plugin = _Plugin.registry[args.name](args);
- }else{
- topic.publish(dijit._scopeName + ".Editor.getPlugin", o); // publish
- }
- }
- if(!o.plugin){
- try{
- // TODO: remove lang.getObject() call in 2.0
- var pc = args.ctor || lang.getObject(args.name) || require(args.name);
- if(pc){
- o.plugin = new pc(args);
- }
- }catch(e){
- throw new Error(this.id + ": cannot find plugin [" + args.name + "]");
- }
- }
- if(!o.plugin){
- throw new Error(this.id + ": cannot find plugin [" + args.name + "]");
- }
- plugin=o.plugin;
- }
- if(arguments.length > 1){
- this._plugins[index] = plugin;
- }else{
- this._plugins.push(plugin);
- }
- plugin.setEditor(this);
- if(lang.isFunction(plugin.setToolbar)){
- plugin.setToolbar(this.toolbar);
- }
- },
-
- //the following 2 functions are required to make the editor play nice under a layout widget, see #4070
-
- 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
- _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 <div> 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() +
- domGeometry.getPadBorderExtents(this.iframe.parentNode).h +
- domGeometry.getMarginExtents(this.iframe.parentNode).h));
- this.editingArea.style.height = areaHeight + "px";
- if(this.iframe){
- this.iframe.style.height="100%";
- }
- this._layoutMode = true;
- },
-
- _onIEMouseDown: function(/*Event*/ e){
- // summary:
- // IE only to prevent 2 clicks to focus
- // tags:
- // private
- 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.
- if(/^rtl$/i.test(b.dir || "")){
- 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"){
- this.defer("placeCursorAtEnd");
- }
- this.inherited(arguments);
- }
- },
- onBeforeActivate: function(){
- this._restoreSelection();
- },
- onBeforeDeactivate: function(e){
- // summary:
- // Called on IE right before focus is lost. Saves the selected range.
- // tags:
- // private
- 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);
- },
-
- /* beginning of custom undo/redo support */
-
- // customUndo: Boolean
- // Whether 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.
- customUndo: true,
-
- // editActionInterval: Integer
- // When 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.
- editActionInterval: 3,
-
- beginEditing: function(cmd){
- // summary:
- // Called to note that the user has started typing alphanumeric characters, if it's not already noted.
- // Deals with saving undo; see editActionInterval parameter.
- // tags:
- // private
- if(!this._inEditing){
- this._inEditing=true;
- this._beginEditing(cmd);
- }
- if(this.editActionInterval>0){
- if(this._editTimer){
- this._editTimer.remove();
- }
- this._editTimer = this.defer("endEditing", this._editInterval);
- }
- },
-
- // TODO: declaring these in the prototype is meaningless, just create in the constructor/postCreate
- _steps:[],
- _undoedSteps:[],
-
- execCommand: function(cmd){
- // summary:
- // Main handler for executing any commands to the editor, like paste, bold, etc.
- // Called by plugins, but not meant to be called by end users.
- // tags:
- // protected
- if(this.customUndo && (cmd == 'undo' || cmd == 'redo')){
- return this[cmd]();
- }else{
- if(this.customUndo){
- this.endEditing();
- this._beginEditing();
- }
- var r = this.inherited(arguments);
- if(this.customUndo){
- this._endEditing();
- }
- return r;
- }
- },
-
- _pasteImpl: function(){
- // summary:
- // Over-ride of paste command control to make execCommand cleaner
- // tags:
- // Protected
- return this._clipboardCommand("paste");
- },
-
- _cutImpl: function(){
- // summary:
- // Over-ride of cut command control to make execCommand cleaner
- // tags:
- // Protected
- return this._clipboardCommand("cut");
- },
-
- _copyImpl: function(){
- // summary:
- // Over-ride of copy command control to make execCommand cleaner
- // tags:
- // Protected
- return this._clipboardCommand("copy");
- },
-
- _clipboardCommand: function(cmd){
- // summary:
- // Function to handle processing clipboard commands (or at least try to).
- // tags:
- // Private
- var r;
- try{
- // Try to exec the superclass exec-command and see if it works.
- r = this.document.execCommand(cmd, false, null);
- if(has("webkit") && !r){ //see #4598: webkit does not guarantee clipboard support from js
- throw { code: 1011 }; // throw an object like Mozilla's error
- }
- }catch(e){
- //TODO: when else might we get an exception? Do we need the Mozilla test below?
- if(e.code == 1011 /* Mozilla: service denied */ ||
- (e.code == 9 && has("opera") /* Opera not supported */)){
- // Warn user of platform limitation. Cannot programmatically access clipboard. See ticket #4136
- var sub = string.substitute,
- accel = {cut:'X', copy:'C', paste:'V'};
- alert(sub(this.commands.systemShortcut,
- [this.commands[cmd], sub(this.commands[has("mac") ? 'appleKey' : 'ctrlKey'], [accel[cmd]])]));
- }
- r = false;
- }
- return r;
- },
-
- queryCommandEnabled: function(cmd){
- // summary:
- // Returns true if specified editor command is enabled.
- // Used by the plugins to know when to highlight/not highlight buttons.
- // tags:
- // protected
- if(this.customUndo && (cmd == 'undo' || cmd == 'redo')){
- return cmd == 'undo' ? (this._steps.length > 1) : (this._undoedSteps.length > 0);
- }else{
- return this.inherited(arguments);
- }
- },
- _moveToBookmark: function(b){
- // summary:
- // Selects the text specified in bookmark b
- // tags:
- // private
- var bookmark = b.mark;
- var mark = b.mark;
- var col = b.isCollapsed;
- var r, sNode, eNode, sel;
- if(mark){
- if(has("ie") < 9){
- if(lang.isArray(mark)){
- //IE CONTROL, have to use the native bookmark.
- bookmark = [];
- array.forEach(mark,function(n){
- bookmark.push(rangeapi.getNode(n,this.editNode));
- },this);
- win.withGlobal(this.window,'moveToBookmark',focusBase,[{mark: bookmark, isCollapsed: col}]);
- }else{
- if(mark.startContainer && mark.endContainer){
- // Use the pseudo WC3 range API. This works better for positions
- // than the IE native bookmark code.
- sel = rangeapi.getSelection(this.window);
- if(sel && sel.removeAllRanges){
- sel.removeAllRanges();
- r = rangeapi.create(this.window);
- sNode = rangeapi.getNode(mark.startContainer,this.editNode);
- eNode = rangeapi.getNode(mark.endContainer,this.editNode);
- if(sNode && eNode){
- // Okay, we believe we found the position, so add it into the selection
- // There are cases where it may not be found, particularly in undo/redo, when
- // IE changes the underlying DOM on us (wraps text in a <p> tag or similar.
- // So, in those cases, don't bother restoring selection.
- r.setStart(sNode,mark.startOffset);
- r.setEnd(eNode,mark.endOffset);
- sel.addRange(r);
- }
- }
- }
- }
- }else{//w3c range
- sel = rangeapi.getSelection(this.window);
- if(sel && sel.removeAllRanges){
- sel.removeAllRanges();
- r = rangeapi.create(this.window);
- sNode = rangeapi.getNode(mark.startContainer,this.editNode);
- eNode = rangeapi.getNode(mark.endContainer,this.editNode);
- if(sNode && eNode){
- // Okay, we believe we found the position, so add it into the selection
- // There are cases where it may not be found, particularly in undo/redo, when
- // formatting as been done and so on, so don't restore selection then.
- r.setStart(sNode,mark.startOffset);
- r.setEnd(eNode,mark.endOffset);
- sel.addRange(r);
- }
- }
- }
- }
- },
- _changeToStep: function(from, to){
- // summary:
- // Reverts editor to "to" setting, from the undo stack.
- // tags:
- // private
- this.setValue(to.text);
- var b=to.bookmark;
- if(!b){ return; }
- this._moveToBookmark(b);
- },
- undo: function(){
- // summary:
- // Handler for editor undo (ex: ctrl-z) operation
- // tags:
- // private
- var ret = false;
- if(!this._undoRedoActive){
- this._undoRedoActive = true;
- this.endEditing(true);
- var s=this._steps.pop();
- if(s && this._steps.length>0){
- this.focus();
- this._changeToStep(s,this._steps[this._steps.length-1]);
- this._undoedSteps.push(s);
- this.onDisplayChanged();
- delete this._undoRedoActive;
- ret = true;
- }
- delete this._undoRedoActive;
- }
- return ret;
- },
- redo: function(){
- // summary:
- // Handler for editor redo (ex: ctrl-y) operation
- // tags:
- // private
- var ret = false;
- if(!this._undoRedoActive){
- this._undoRedoActive = true;
- this.endEditing(true);
- var s=this._undoedSteps.pop();
- if(s && this._steps.length>0){
- this.focus();
- this._changeToStep(this._steps[this._steps.length-1],s);
- this._steps.push(s);
- this.onDisplayChanged();
- ret = true;
- }
- delete this._undoRedoActive;
- }
- return ret;
- },
- endEditing: function(ignore_caret){
- // summary:
- // Called to note that the user has stopped typing alphanumeric characters, if it's not already noted.
- // Deals with saving undo; see editActionInterval parameter.
- // tags:
- // private
- if(this._editTimer){
- this._editTimer = this._editTimer.remove();
- }
- if(this._inEditing){
- this._endEditing(ignore_caret);
- this._inEditing=false;
- }
- },
-
- _getBookmark: function(){
- // summary:
- // Get the currently selected text
- // tags:
- // protected
- var b=win.withGlobal(this.window,focusBase.getBookmark);
- var tmp=[];
- if(b && b.mark){
- var mark = b.mark;
- if(has("ie") < 9){
- // Try to use the pseudo range API on IE for better accuracy.
- var sel = rangeapi.getSelection(this.window);
- if(!lang.isArray(mark)){
- if(sel){
- var range;
- if(sel.rangeCount){
- range = sel.getRangeAt(0);
- }
- if(range){
- b.mark = range.cloneRange();
- }else{
- b.mark = win.withGlobal(this.window,focusBase.getBookmark);
- }
- }
- }else{
- // Control ranges (img, table, etc), handle differently.
- array.forEach(b.mark,function(n){
- tmp.push(rangeapi.getIndex(n,this.editNode).o);
- },this);
- b.mark = tmp;
- }
- }
- try{
- if(b.mark && b.mark.startContainer){
- tmp=rangeapi.getIndex(b.mark.startContainer,this.editNode).o;
- b.mark={startContainer:tmp,
- startOffset:b.mark.startOffset,
- endContainer:b.mark.endContainer===b.mark.startContainer?tmp:rangeapi.getIndex(b.mark.endContainer,this.editNode).o,
- endOffset:b.mark.endOffset};
- }
- }catch(e){
- b.mark = null;
- }
- }
- return b;
- },
- _beginEditing: function(){
- // summary:
- // Called when the user starts typing alphanumeric characters.
- // Deals with saving undo; see editActionInterval parameter.
- // tags:
- // private
- if(this._steps.length === 0){
- // You want to use the editor content without post filtering
- // to make sure selection restores right for the 'initial' state.
- // and undo is called. So not using this.value, as it was 'processed'
- // and the line-up for selections may have been altered.
- this._steps.push({'text':html.getChildrenHtml(this.editNode),'bookmark':this._getBookmark()});
- }
- },
- _endEditing: function(){
- // summary:
- // Called when the user stops typing alphanumeric characters.
- // Deals with saving undo; see editActionInterval parameter.
- // tags:
- // private
-
- // Avoid filtering to make sure selections restore.
- var v = html.getChildrenHtml(this.editNode);
-
- this._undoedSteps=[];//clear undoed steps
- this._steps.push({text: v, bookmark: this._getBookmark()});
- },
- onKeyDown: function(e){
- // summary:
- // Handler for onkeydown event.
- // tags:
- // private
-
- //We need to save selection if the user TAB away from this editor
- //no need to call _saveSelection for IE, as that will be taken care of in onBeforeDeactivate
- if(!has("ie") && !this.iframe && e.keyCode == keys.TAB && !this.tabIndent){
- this._saveSelection();
- }
- if(!this.customUndo){
- this.inherited(arguments);
- return;
- }
- var k = e.keyCode;
- if(e.ctrlKey && !e.altKey){//undo and redo only if the special right Alt + z/y are not pressed #5892
- if(k == 90 || k == 122){ //z
- event.stop(e);
- this.undo();
- return;
- }else if(k == 89 || k == 121){ //y
- event.stop(e);
- this.redo();
- return;
- }
- }
- this.inherited(arguments);
-
- switch(k){
- case keys.ENTER:
- case keys.BACKSPACE:
- case keys.DELETE:
- this.beginEditing();
- break;
- case 88: //x
- case 86: //v
- if(e.ctrlKey && !e.altKey && !e.metaKey){
- this.endEditing();//end current typing step if any
- if(e.keyCode == 88){
- this.beginEditing('cut');
- }else{
- this.beginEditing('paste');
- }
- //use timeout to trigger after the paste is complete
- this.defer("endEditing", 1);
- break;
- }
- //pass through
- default:
- if(!e.ctrlKey && !e.altKey && !e.metaKey && (e.keyCode<keys.F1 || e.keyCode>keys.F15)){
- this.beginEditing();
- break;
- }
- //pass through
- case keys.ALT:
- this.endEditing();
- break;
- case keys.UP_ARROW:
- case keys.DOWN_ARROW:
- case keys.LEFT_ARROW:
- case keys.RIGHT_ARROW:
- case keys.HOME:
- case keys.END:
- case keys.PAGE_UP:
- case keys.PAGE_DOWN:
- this.endEditing(true);
- break;
- //maybe ctrl+backspace/delete, so don't endEditing when ctrl is pressed
- case keys.CTRL:
- case keys.SHIFT:
- case keys.TAB:
- break;
- }
- },
- _onBlur: function(){
- // summary:
- // Called from focus manager when focus has moved away from this editor
- // tags:
- // protected
-
- //this._saveSelection();
- this.inherited(arguments);
- this.endEditing(true);
- },
- _saveSelection: function(){
- // summary:
- // Save the currently selected text in _savedSelection attribute
- // tags:
- // private
- try{
- this._savedSelection=this._getBookmark();
- }catch(e){ /* Squelch any errors that occur if selection save occurs due to being hidden simultaneously. */}
- },
- _restoreSelection: function(){
- // summary:
- // Re-select the text specified in _savedSelection attribute;
- // see _saveSelection().
- // tags:
- // private
- if(this._savedSelection){
- // Clear off cursor to start, we're deliberately going to a selection.
- delete this._cursorToStart;
- // only restore the selection if the current range is collapsed
- // if not collapsed, then it means the editor does not lose
- // selection and there is no need to restore it
- if(win.withGlobal(this.window,'isCollapsed',focusBase)){
- this._moveToBookmark(this._savedSelection);
- }
- delete this._savedSelection;
- }
- },
-
- onClick: function(){
- // summary:
- // Handler for when editor is clicked
- // tags:
- // protected
- this.endEditing(true);
- this.inherited(arguments);
- },
-
- replaceValue: function(/*String*/ html){
- // summary:
- // over-ride of replaceValue to support custom undo and stack maintenance.
- // tags:
- // protected
- if(!this.customUndo){
- this.inherited(arguments);
- }else{
- if(this.isClosed){
- this.setValue(html);
- }else{
- this.beginEditing();
- if(!html){
- html = "&#160;"; // &nbsp;
- }
- this.setValue(html);
- this.endEditing();
- }
- }
- },
-
- _setDisabledAttr: function(/*Boolean*/ value){
- this.setValueDeferred.then(lang.hitch(this, function(){
- if((!this.disabled && value) || (!this._buttonEnabledPlugins && value)){
- // Disable editor: disable all enabled buttons and remember that list
- array.forEach(this._plugins, function(p){
- p.set("disabled", true);
- });
- }else if(this.disabled && !value){
- // Restore plugins to being active.
- array.forEach(this._plugins, function(p){
- p.set("disabled", false);
- });
- }
- }));
- this.inherited(arguments);
- },
-
- _setStateClass: function(){
- try{
- this.inherited(arguments);
-
- // Let theme set the editor's text color based on editor enabled/disabled state.
- // We need to jump through hoops because the main document (where the theme CSS is)
- // is separate from the iframe's document.
- if(this.document && this.document.body){
- domStyle.set(this.document.body, "color", domStyle.get(this.iframe, "color"));
- }
- }catch(e){ /* Squelch any errors caused by focus change if hidden during a state change */}
- }
- });
-
- // Register the "default plugins", ie, the built-in editor commands
- function simplePluginFactory(args){
- return new _Plugin({ command: args.name });
- }
- function togglePluginFactory(args){
- return new _Plugin({ buttonClass: ToggleButton, command: args.name });
- }
- lang.mixin(_Plugin.registry, {
- "undo": simplePluginFactory,
- "redo": simplePluginFactory,
- "cut": simplePluginFactory,
- "copy": simplePluginFactory,
- "paste": simplePluginFactory,
- "insertOrderedList": simplePluginFactory,
- "insertUnorderedList": simplePluginFactory,
- "indent": simplePluginFactory,
- "outdent": simplePluginFactory,
- "justifyCenter": simplePluginFactory,
- "justifyFull": simplePluginFactory,
- "justifyLeft": simplePluginFactory,
- "justifyRight": simplePluginFactory,
- "delete": simplePluginFactory,
- "selectAll": simplePluginFactory,
- "removeFormat": simplePluginFactory,
- "unlink": simplePluginFactory,
- "insertHorizontalRule": simplePluginFactory,
-
- "bold": togglePluginFactory,
- "italic": togglePluginFactory,
- "underline": togglePluginFactory,
- "strikethrough": togglePluginFactory,
- "subscript": togglePluginFactory,
- "superscript": togglePluginFactory,
-
- "|": function(){
- return new _Plugin({
- setEditor: function(editor){
- this.editor = editor;
- this.button = new ToolbarSeparator({ownerDocument: editor.ownerDocument});
- }
- });
- }
- });
-
- return Editor;
-});