/branches/versions/aipo702b/design/htmlmock/javascript/dijit/Editor.xd.js
http://aipo.googlecode.com/ · JavaScript · 389 lines · 321 code · 18 blank · 50 comment · 50 complexity · 54ac7f7bc8fae6e5cdd863a052b20a8e MD5 · raw file
- dojo._xdResourceLoaded({
- depends: [["provide", "dijit.Editor"],
- ["require", "dijit._editor.RichText"],
- ["require", "dijit.Toolbar"],
- ["require", "dijit._editor._Plugin"],
- ["require", "dijit._Container"],
- ["require", "dojo.i18n"],
- ["requireLocalization", "dijit._editor", "commands", null, "ROOT,cs,de,es,fr,hu,it,ja,ko,pl,pt,ru,zh,zh-tw", "ROOT,cs,de,es,fr,hu,it,ja,ko,pl,pt,ru,zh,zh-tw"]],
- defineResource: function(dojo){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.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;
- });
-
- }
- }});