123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456 |
- if (!dojo._hasResource["dijit.Editor"]) { // _hasResource checks added by
- // build. Do not use _hasResource
- // directly in your code.
- dojo._hasResource["dijit.Editor"] = true;
- dojo.provide("dijit.Editor");
- dojo.require("dijit._editor.RichText");
- dojo.require("dijit.Toolbar");
- dojo.require("dijit._editor._Plugin");
- dojo.require("dijit._Container");
- dojo.require("dojo.i18n");
- dojo.requireLocalization("dijit._editor", "commands", null,
- "ko,zh,ja,zh-tw,ru,it,hu,fr,pt,pl,es,ROOT,de,cs");
- dojo.declare("dijit.Editor", dijit._editor.RichText, {
- // summary: A rich-text Editing widget
- // plugins: Array
- // a list of plugin names (as strings) or instances (as objects)
- // for this widget.
- plugins : null,
- // extraPlugins: Array
- // a list of extra plugin names which will be appended to plugins array
- extraPlugins : null,
- constructor : function() {
- this.plugins = ["undo", "redo", "|", "cut", "copy", "paste", "|",
- "bold", "italic", "underline", "strikethrough", "|",
- "insertOrderedList", "insertUnorderedList", "indent",
- "outdent", "|", "justifyLeft", "justifyRight",
- "justifyCenter", "justifyFull"/* "createLink" */];
- this._plugins = [];
- this._editInterval = this.editActionInterval * 1000;
- },
- postCreate : function() {
- // for custom undo/redo
- if (this.customUndo) {
- dojo['require']("dijit._editor.range");
- this._steps = this._steps.slice(0);
- this._undoedSteps = this._undoedSteps.slice(0);
- // this.addKeyHandler('z',this.KEY_CTRL,this.undo);
- // this.addKeyHandler('y',this.KEY_CTRL,this.redo);
- }
- if (dojo.isArray(this.extraPlugins)) {
- this.plugins = this.plugins.concat(this.extraPlugins);
- }
- // try{
- dijit.Editor.superclass.postCreate.apply(this, arguments);
- this.commands = dojo.i18n.getLocalization("dijit._editor",
- "commands", this.lang);
- if (!this.toolbar) {
- // if we haven't been assigned a toolbar, create one
- var toolbarNode = dojo.doc.createElement("div");
- dojo.place(toolbarNode, this.editingArea, "before");
- this.toolbar = new dijit.Toolbar({}, toolbarNode);
- }
- dojo.forEach(this.plugins, this.addPlugin, this);
- this.onNormalizedDisplayChanged(); // update toolbar button status
- // }catch(e){ console.debug(e); }
- },
- destroy : function() {
- dojo.forEach(this._plugins, function(p) {
- if (p.destroy) {
- p.destroy();
- }
- });
- this._plugins = [];
- this.toolbar.destroy();
- delete this.toolbar;
- this.inherited('destroy', 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. Required.
- // args: This object will be passed to the plugin constructor.
- // index:
- // Integer, optional. 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.Editor.getPlugin", [o]);
- if (!o.plugin) {
- var pc = dojo.getObject(args.name);
- if (pc) {
- o.plugin = new pc(args);
- }
- }
- if (!o.plugin) {
- console.debug('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);
- }
- },
- /* 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 only enable customUndo for IE, as it
- // has broken native undo/redo support. Note: the implementation does
- // support other browsers which have W3C DOM2 Range API.
- customUndo : dojo.isIE,
- // 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 stop 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) {
- 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);
- }
- },
- _steps : [],
- _undoedSteps : [],
- execCommand : function(cmd) {
- if (this.customUndo && (cmd == 'undo' || cmd == 'redo')) {
- return this[cmd]();
- } else {
- try {
- if (this.customUndo) {
- this.endEditing();
- this._beginEditing();
- }
- var r = this.inherited('execCommand', arguments);
- if (this.customUndo) {
- this._endEditing();
- }
- return r;
- } catch (e) {
- if (dojo.isMoz && /copy|cut|paste/.test(cmd)) {
- // Warn user of platform limitation. Cannot
- // programmatically access keyboard. See ticket #4136
- var sub = dojo.string.substitute, accel = {
- cut : 'X',
- copy : 'C',
- paste : 'V'
- }, isMac = navigator.userAgent.indexOf("Macintosh") != -1;
- alert(sub(this.commands.systemShortcutFF, [
- this.commands[cmd],
- sub( this.commands[isMac
- ? 'appleKey'
- : 'ctrlKey'],
- [accel[cmd]])]));
- }
- return false;
- }
- }
- },
- queryCommandEnabled : function(cmd) {
- if (this.customUndo && (cmd == 'undo' || cmd == 'redo')) {
- return cmd == 'undo'
- ? (this._steps.length > 1)
- : (this._undoedSteps.length > 0);
- } else {
- return this.inherited('queryCommandEnabled', arguments);
- }
- },
- _changeToStep : function(from, to) {
- this.setValue(to.text);
- var b = to.bookmark;
- if (!b) {
- return;
- }
- if (dojo.isIE) {
- if (dojo.isArray(b)) {// IE CONTROL
- var tmp = [];
- dojo.forEach(b, function(n) {
- tmp.push(dijit.range.getNode(n, this.editNode));
- }, this);
- b = tmp;
- }
- } else {// w3c range
- var r = dijit.range.create();
- r.setStart(
- dijit.range.getNode(b.startContainer, this.editNode),
- b.startOffset);
- r.setEnd(dijit.range.getNode(b.endContainer, this.editNode),
- b.endOffset);
- b = r;
- }
- dojo.withGlobal(this.window, 'moveToBookmark', dijit, [b]);
- },
- undo : function() {
- // console.log('undo');
- this.endEditing(true);
- var s = this._steps.pop();
- if (this._steps.length > 0) {
- this.focus();
- this._changeToStep(s, this._steps[this._steps.length - 1]);
- this._undoedSteps.push(s);
- this.onDisplayChanged();
- return true;
- }
- return false;
- },
- redo : function() {
- // console.log('redo');
- 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();
- return true;
- }
- return false;
- },
- endEditing : function(ignore_caret) {
- if (this._editTimer) {
- clearTimeout(this._editTimer);
- }
- if (this._inEditing) {
- this._endEditing(ignore_caret);
- this._inEditing = false;
- }
- },
- _getBookmark : function() {
- var b = dojo.withGlobal(this.window, dijit.getBookmark);
- if (dojo.isIE) {
- if (dojo.isArray(b)) {// CONTROL
- var tmp = [];
- dojo.forEach(b, function(n) {
- tmp
- .push(dijit.range.getIndex(n,
- this.editNode).o);
- }, this);
- b = tmp;
- }
- } else {// w3c range
- var tmp = dijit.range.getIndex(b.startContainer, this.editNode).o
- b = {
- startContainer : tmp,
- startOffset : b.startOffset,
- endContainer : b.endContainer === b.startContainer
- ? tmp
- : dijit.range.getIndex(b.endContainer,
- this.editNode).o,
- endOffset : b.endOffset
- };
- }
- return b;
- },
- _beginEditing : function(cmd) {
- if (this._steps.length === 0) {
- this._steps.push({
- 'text' : this.savedContent,
- 'bookmark' : this._getBookmark()
- });
- }
- },
- _endEditing : function(ignore_caret) {
- var v = this.getValue(true);
- this._undoedSteps = [];// clear undoed steps
- this._steps.push({
- 'text' : v,
- 'bookmark' : this._getBookmark()
- });
- },
- onKeyDown : function(e) {
- if (!this.customUndo) {
- this.inherited('onKeyDown', arguments);
- return;
- }
- var k = e.keyCode, ks = dojo.keys;
- if (e.ctrlKey) {
- if (k === 90 || k === 122) { // z
- dojo.stopEvent(e);
- this.undo();
- return;
- } else if (k === 89 || k === 121) { // y
- dojo.stopEvent(e);
- this.redo();
- return;
- }
- }
- this.inherited('onKeyDown', arguments);
- switch (k) {
- case ks.ENTER :
- this.beginEditing();
- break;
- case ks.BACKSPACE :
- case ks.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');
- // use timeout to trigger after the cut is complete
- setTimeout(dojo.hitch(this, this.endEditing), 1);
- } else {
- this.beginEditing('paste');
- // use timeout to trigger after the paste is
- // complete
- setTimeout(dojo.hitch(this, this.endEditing), 1);
- }
- break;
- }
- // pass through
- default :
- if (!e.ctrlKey
- && !e.altKey
- && !e.metaKey
- && (e.keyCode < dojo.keys.F1 || e.keyCode > dojo.keys.F15)) {
- this.beginEditing();
- break;
- }
- // pass through
- case ks.ALT :
- this.endEditing();
- break;
- case ks.UP_ARROW :
- case ks.DOWN_ARROW :
- case ks.LEFT_ARROW :
- case ks.RIGHT_ARROW :
- case ks.HOME :
- case ks.END :
- case ks.PAGE_UP :
- case ks.PAGE_DOWN :
- this.endEditing(true);
- break;
- // maybe ctrl+backspace/delete, so don't endEditing when ctrl is
- // pressed
- case ks.CTRL :
- case ks.SHIFT :
- case ks.TAB :
- break;
- }
- },
- _onBlur : function() {
- this.inherited('_onBlur', arguments);
- this.endEditing(true);
- },
- onClick : function() {
- this.endEditing(true);
- this.inherited('onClick', arguments);
- }
- /* end of custom undo/redo support */
- });
- /* the following code is to registered a handler to get default plugins */
- dojo.subscribe("dijit.Editor.getPlugin", null, function(o) {
- if (o.plugin) {
- return;
- }
- var args = o.args, p;
- var _p = dijit._editor._Plugin;
- var name = args.name;
- switch (name) {
- case "undo" :
- case "redo" :
- case "cut" :
- case "copy" :
- case "paste" :
- case "insertOrderedList" :
- case "insertUnorderedList" :
- case "indent" :
- case "outdent" :
- case "justifyCenter" :
- case "justifyFull" :
- case "justifyLeft" :
- case "justifyRight" :
- case "delete" :
- case "selectAll" :
- case "removeFormat" :
- p = new _p({
- command : name
- });
- break;
- case "bold" :
- case "italic" :
- case "underline" :
- case "strikethrough" :
- case "subscript" :
- case "superscript" :
- p = new _p({
- buttonClass : dijit.form.ToggleButton,
- command : name
- });
- break;
- case "|" :
- p = new _p({
- button : new dijit.ToolbarSeparator()
- });
- break;
- case "createLink" :
- // dojo['require']('dijit._editor.plugins.LinkDialog');
- p = new dijit._editor.plugins.LinkDialog({
- command : name
- });
- break;
- case "foreColor" :
- case "hiliteColor" :
- p = new dijit._editor.plugins.TextColor({
- command : name
- });
- break;
- case "fontName" :
- case "fontSize" :
- case "formatBlock" :
- p = new dijit._editor.plugins.FontChoice({
- command : name
- });
- }
- // console.log('name',name,p);
- o.plugin = p;
- });
- }
|