Changeset 6393
- Timestamp:
- 11/01/06 09:24:01 (3 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 1 removed
- 10 modified
-
src/widget/Editor2.js (modified) (19 diffs)
-
src/widget/Editor2Plugin/ContextMenu.js (modified) (7 diffs)
-
src/widget/Editor2Plugin/FindReplace.js (modified) (1 diff)
-
src/widget/Editor2Plugin/FindReplaceDialog.js (modified) (2 diffs)
-
src/widget/Editor2Plugin/InsertImageDialog.js (modified) (1 diff)
-
src/widget/Editor2Plugin/SimpleSignalCommands.js (modified) (3 diffs)
-
src/widget/Editor2Plugin/TableOperation.js (modified) (4 diffs)
-
src/widget/Editor2Toolbar.js (modified) (17 diffs)
-
src/widget/RichText.js (modified) (2 diffs)
-
src/widget/templates/EditorToolbarLight.html (deleted)
-
src/widget/templates/EditorToolbarOneline.html (modified) (28 diffs)
-
tests/widget/Editor/EditorToolbarLight.html (added)
-
tests/widget/Editor/test_Editor2_shared.html (added)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/widget/Editor2.js
r6370 r6393 6 6 7 7 // Object: Manager of current focused Editor2 Instance and available editor2 commands 8 dojo.widget.Editor2Manager = { 8 dojo.widget.Editor2Manager = new dojo.widget.HandlerManager; 9 dojo.lang.mixin(dojo.widget.Editor2Manager, 10 { 9 11 _currentInstance: null, 10 _loadedCommands: {},11 12 12 13 // Object: state a command may be in … … 21 22 this._currentInstance = inst; 22 23 }, 23 registerCommand: function(/*String*/name, /*Object*/cmd){ 24 // summary: Register an Editor2 command 25 // name: name of the command (case insensitive) 26 // cmd: an object which implements interface dojo.widget.Editor2Command 27 name = name.toLowerCase(); 28 if(this._loadedCommands[name]){ 29 delete this._loadedCommands[name]; 30 } 31 this._loadedCommands[name] = cmd; 32 }, 33 getCommand: function(/*String*/name){ 24 getCommand: function(/*dojo.widget.Editor2*/editor,/*String*/name){ 34 25 // summary: Return Editor2 command with the given name 35 26 // name: name of the command (case insensitive) 27 var oCommand; 36 28 name = name.toLowerCase(); 37 var oCommand = this._loadedCommands[name]; 38 if(oCommand){ 39 return oCommand; 29 for(var i=0;i<this._registeredHandlers.length;i++){ 30 oCommand = this._registeredHandlers[i](editor, name); 31 if(oCommand){ 32 return oCommand; 33 } 40 34 } 41 42 35 switch(name){ 43 36 case 'htmltoggle': 44 37 //Editor2 natively provide the htmltoggle functionalitity 45 38 //and it is treated as a builtin command 46 oCommand = new dojo.widget.Editor2BrowserCommand( name);39 oCommand = new dojo.widget.Editor2BrowserCommand(editor, name); 47 40 break; 48 41 case 'formatblock': 49 oCommand = new dojo.widget.Editor2FormatBlockCommand( name);42 oCommand = new dojo.widget.Editor2FormatBlockCommand(editor, name); 50 43 break; 51 44 case 'anchor': 52 oCommand = new dojo.widget.Editor2Command( name);45 oCommand = new dojo.widget.Editor2Command(editor, name); 53 46 break; 54 47 55 48 //dialog command 56 49 case 'createlink': 57 oCommand = new dojo.widget.Editor2DialogCommand( name,50 oCommand = new dojo.widget.Editor2DialogCommand(editor, name, 58 51 {contentFile: "dojo.widget.Editor2Plugin.CreateLinkDialog", 59 52 contentClass: "Editor2CreateLinkDialog", … … 61 54 break; 62 55 case 'insertimage': 63 oCommand = new dojo.widget.Editor2DialogCommand( name,56 oCommand = new dojo.widget.Editor2DialogCommand(editor, name, 64 57 {contentFile: "dojo.widget.Editor2Plugin.InsertImageDialog", 65 58 contentClass: "Editor2InsertImageDialog", … … 71 64 if((curtInst && curtInst.queryCommandAvailable(name)) || 72 65 (!curtInst && dojo.widget.Editor2.prototype.queryCommandAvailable(name))){ 73 oCommand = new dojo.widget.Editor2BrowserCommand( name);66 oCommand = new dojo.widget.Editor2BrowserCommand(editor, name); 74 67 }else{ 75 68 dojo.debug("dojo.widget.Editor2Manager.getCommand: Unknown command "+name); … … 77 70 } 78 71 } 79 this._loadedCommands[name] = oCommand;80 72 return oCommand; 81 73 }, … … 83 75 // summary: Cleaning up. This is called automatically on page unload. 84 76 this._currentInstance = null; 85 for(var cmd in this._loadedCommands){ 86 this._loadedCommands[cmd].destory(); 87 } 77 dojo.widget.HandlerManager.prototype.destroy.call(this); 88 78 } 89 } ;79 }); 90 80 91 81 dojo.addOnUnload(dojo.widget.Editor2Manager, "destroy"); … … 94 84 // dojo.widget.Editor2Command is the base class for all command in Editor2 95 85 dojo.lang.declare("dojo.widget.Editor2Command",null, 96 function(name){ 97 // summary: Constructor of this class 86 function(editor,name){ 87 this._editor = editor; 88 this._updateTime = 0; 98 89 this._name = name; 99 90 }, … … 177 168 // in commands 178 169 dojo.lang.declare("dojo.widget.Editor2BrowserCommand", dojo.widget.Editor2Command, 179 function( name){170 function(editor,name){ 180 171 // summary: Constructor of this class 181 172 … … 187 178 { 188 179 execute: function(para){ 189 var curInst = dojo.widget.Editor2Manager.getCurrentInstance(); 190 if(curInst){ 191 curInst.execCommand(this._name, para); 192 } 180 this._editor.execCommand(this._name, para); 193 181 }, 194 182 getState: function(){ 195 var curInst = dojo.widget.Editor2Manager.getCurrentInstance();196 if(curInst){183 if(this._editor._lastStateTimestamp > this._updateTime || this._state == undefined){ 184 this._updateTime = this._editor._lastStateTimestamp; 197 185 try{ 198 if( curInst.queryCommandEnabled(this._name)){199 if( curInst.queryCommandState(this._name)){200 returndojo.widget.Editor2Manager.commandState.Latched;186 if(this._editor.queryCommandEnabled(this._name)){ 187 if(this._editor.queryCommandState(this._name)){ 188 this._state = dojo.widget.Editor2Manager.commandState.Latched; 201 189 }else{ 202 returndojo.widget.Editor2Manager.commandState.Enabled;190 this._state = dojo.widget.Editor2Manager.commandState.Enabled; 203 191 } 204 192 }else{ 205 returndojo.widget.Editor2Manager.commandState.Disabled;193 this._state = dojo.widget.Editor2Manager.commandState.Disabled; 206 194 } 207 195 }catch (e) { 208 196 //dojo.debug("exception when getting state for command "+this._name+": "+e); 209 returndojo.widget.Editor2Manager.commandState.Enabled;210 } 211 } 212 return dojo.widget.Editor2Manager.commandState.Disabled;197 this._state = dojo.widget.Editor2Manager.commandState.Enabled; 198 } 199 } 200 return this._state; 213 201 }, 214 202 getValue: function(){ 215 var curInst = dojo.widget.Editor2Manager.getCurrentInstance(); 216 if(curInst){ 217 try{ 218 return curInst.queryCommandValue(this._name); 219 }catch(e){} 220 } 203 try{ 204 return this._editor.queryCommandValue(this._name); 205 }catch(e){} 221 206 } 222 207 } … … 350 335 } 351 336 dojo.widget.Editor2Dialog.superclass.hide.call(this); 337 }, 338 //modified from ModalDialogBase.checkSize to call _sizeBackground conditionally 339 checkSize: function(){ 340 if(this.isShowing()){ 341 if(this.modal){ 342 this._sizeBackground(); 343 } 344 this.placeModalDialog(); 345 this.onResized(); 346 } 352 347 } 353 348 } … … 377 372 // the command is executed. 378 373 dojo.lang.declare("dojo.widget.Editor2DialogCommand", dojo.widget.Editor2BrowserCommand, 379 function( name, dialogParas){374 function(editor, name, dialogParas){ 380 375 this.dialogParas = dialogParas; 381 376 }, … … 396 391 } 397 392 }); 393 394 // Object: keeping track of all available share toolbar groups 395 dojo.widget.Editor2ToolbarGroups = {}; 398 396 399 397 // summary: … … 407 405 "dojo.widget.Editor2", 408 406 dojo.widget.RichText, 407 function(){ 408 this._loadedCommands={}; 409 }, 409 410 { 410 411 // // String: url to which save action should send content to … … 415 416 // closeOnSave: false, 416 417 417 // Boolean: Whether to share toolbar with other instances of Editor2418 shareToolbar: false,419 418 // Boolean: Whether the toolbar should scroll to keep it in the view 420 419 toolbarAlwaysVisible: false, … … 435 434 _htmlEditNode: null, 436 435 436 // String: 437 // This instance of editor will share the same toolbar with other editor with the same toolbarGroup. 438 // By default, toolbarGroup is empty and standalone toolbar is used for this instance. 439 toolbarGroup: '', 440 // Boolean: Whether to share toolbar with other instances of Editor2. Deprecated in favor of toolbarGroup 441 shareToolbar: false, 442 443 // String: specify which context menu set should be used for this instance. Include ContextMenu plugin to use this 444 contextMenuGroupSet: '', 445 437 446 editorOnLoad: function(){ 438 447 // summary: … … 446 455 } 447 456 448 var toolbars = dojo.widget.byType("Editor2Toolbar"); 449 if((!toolbars.length)||(!this.shareToolbar)){ 450 if(this.toolbarWidget){ 451 this.toolbarWidget.show(); 452 //re-add the toolbar to the new domNode (caused by open() on another element) 453 dojo.html.insertBefore(this.toolbarWidget.domNode, this.domNode.firstChild); 454 }else{ 455 var tbOpts = {}; 456 tbOpts.templatePath = this.toolbarTemplatePath; 457 if(this.toolbarTemplateCssPath){ 458 tbOpts.templateCssPath = this.toolbarTemplateCssPath; 457 if(this.toolbarWidget){ 458 this.toolbarWidget.show(); 459 //re-add the toolbar to the new domNode (caused by open() on another element) 460 dojo.html.insertBefore(this.toolbarWidget.domNode, this.domNode.firstChild); 461 }else{ 462 if(this.shareToolbar){ 463 dojo.deprecated("Editor2:shareToolbar is deprecated in favor of toolbarGroup", "0.5"); 464 this.toolbarGroup = 'defaultDojoToolbarGroup'; 465 } 466 if(this.toolbarGroup){ 467 if(dojo.widget.Editor2ToolbarGroups[this.toolbarGroup]){ 468 this.toolbarWidget = dojo.widget.Editor2ToolbarGroups[this.toolbarGroup]; 459 469 } 460 this.toolbarWidget = dojo.widget.createWidget("Editor2Toolbar", tbOpts, this.domNode.firstChild, "before"); 461 462 dojo.event.connect(this, "close", this.toolbarWidget, "hide"); 463 464 this.toolbarLoaded(); 465 } 466 }else{ 467 // FIXME: selecting in one shared toolbar doesn't clobber 468 // selection in the others. This is problematic. 469 this.toolbarWidget = toolbars[0]; 470 } 471 if(!this.toolbarWidget){ 472 var tbOpts = {shareGroup: this.toolbarGroup, parent: this}; 473 tbOpts.templatePath = this.toolbarTemplatePath; 474 if(this.toolbarTemplateCssPath){ 475 tbOpts.templateCssPath = this.toolbarTemplateCssPath; 476 } 477 this.toolbarWidget = dojo.widget.createWidget("Editor2Toolbar", tbOpts, this.domNode.firstChild, "before"); 478 if(this.toolbarGroup){ 479 dojo.widget.Editor2ToolbarGroups[this.toolbarGroup] = this.toolbarWidget; 480 } 481 dojo.event.connect(this, "close", this.toolbarWidget, "hide"); 482 483 this.toolbarLoaded(); 484 } 470 485 } 471 486 … … 662 677 }, 663 678 679 _lastStateTimestamp: 0, 664 680 onDisplayChanged: function(/*Object*/e){ 681 this._lastStateTimestamp = (new Date()).getTime(); 665 682 dojo.widget.Editor2.superclass.onDisplayChanged.call(this,e); 666 683 this.updateToolbar(); … … 689 706 }, 690 707 708 getCommand: function(/*String*/name){ 709 // summary: return a command associated with this instance of editor 710 if(this._loadedCommands[name]){ 711 return this._loadedCommands[name]; 712 } 713 var cmd = dojo.widget.Editor2Manager.getCommand(this, name); 714 this._loadedCommands[name] = cmd; 715 return cmd; 716 }, 691 717 // Array: Commands shortcuts. Each element can has up to 3 fields: 692 718 // 1. String: the name of the command … … 702 728 var self = this; 703 729 dojo.lang.forEach(this.shortcuts, function(item){ 704 var cmd = dojo.widget.Editor2Manager.getCommand(item[0]);730 var cmd = self.getCommand(item[0]); 705 731 if(cmd){ 706 732 self.addKeyHandler(item[1]?item[1]:item[0].charAt(0), item[2]==undefined?self.KEY_CTRL:item[2], exec(cmd)); -
trunk/src/widget/Editor2Plugin/ContextMenu.js
r5993 r6393 1 1 dojo.provide("dojo.widget.Editor2Plugin.ContextMenu"); 2 2 3 //ContextMenu plugin should be dojo.required-ed before all other plugins which 4 //support contextmenu, otherwise the menu for that plugin won't be shown 3 // summary: dojo.widget.Editor2Plugin.ContextMenu provides context menu for Editor2 widget 4 // description: 5 // This plugin should be dojo.required-ed before all other plugins which 6 // support contextmenu, otherwise the menu for that plugin won't be shown 7 // For each Editor2, what will appear in its context menu can be set by changing 8 // Editor2.contextMenuGroupSet property (by default it is empty, which means use the 9 // default contextMenu). A contextMenuGroupSet has to be registered by calling 10 // dojo.widget.Editor2Plugin.ContextMenuManager.registerGroupSet() 11 // All Editor2 with the same contextMenuGroupSet will share the same ContextMenu 5 12 6 13 dojo.require("dojo.widget.Menu2"); 7 14 8 15 dojo.event.topic.subscribe("dojo.widget.Editor2::onLoad", function(editor){ 9 var p = new dojo.widget.Editor2Plugin.ContextMenu(editor); 10 }); 16 dojo.widget.Editor2Plugin.ContextMenuManager.getContextMenu(editor); 17 // var p = new dojo.widget.Editor2Plugin.ContextMenu(); 18 }); 19 11 20 dojo.widget.Editor2Plugin.ContextMenuManager = { 12 21 menuGroups: ['Generic', 'Link', 'Anchor', 'Image', 'List', 'Table'], 22 _contextMenuGroupSets: {}, 13 23 _registeredGroups: {}, 24 _menus: {}, 14 25 registerGroup: function(name, handler){ 15 26 if(this._registeredGroups[name]){ … … 33 44 case 'Link': 34 45 case 'Image': 35 return new dojo.widget.Editor2Plugin[name+"ContextMenu "](contextmenuplugin);46 return new dojo.widget.Editor2Plugin[name+"ContextMenuGroup"](contextmenuplugin); 36 47 //TODO 37 48 case 'Anchor': 38 49 case 'List': 39 50 } 51 }, 52 registerGroupSet: function(/*String*/name, /*Array*/set){ 53 // summary: register a group set 54 // name: name of the group set 55 // set: an array of groups, such as ['Generic','Link'] 56 this._contextMenuGroupSets[name] = set; 57 }, 58 removeGroupSet: function(name){ 59 var set = this._contextMenuGroupSets[name]; 60 delete this._contextMenuGroupSets[name]; 61 return set; 62 }, 63 getContextMenu: function(editor){ 64 var set = editor.contextMenuGroupSet || 'defaultDojoEditor2MenuGroupSet'; 65 if(this._menus[set]){ 66 this._menus[set].bindEditor(editor); 67 return this._menus[set]; 68 } 69 70 var gs = (editor.contextMenuGroupSet && this._contextMenuGroupSets[editor.contextMenuGroupSet]) || this.menuGroups; 71 var menu = new dojo.widget.Editor2Plugin.ContextMenu(editor, gs); 72 this._menus[set] = menu; 73 return menu; 40 74 } 41 75 }; 42 76 43 77 dojo.declare("dojo.widget.Editor2Plugin.ContextMenu", null, 44 function(editor ){78 function(editor, gs){ 45 79 this.groups = []; 46 80 this.separators = []; … … 49 83 this.contextMenu = dojo.widget.createWidget("PopupMenu2", {}); 50 84 dojo.body().appendChild(this.contextMenu.domNode); 51 this. contextMenu.bindDomNode(this.editor.document.body);85 this.bindEditor(this.editor); 52 86 53 87 dojo.event.connect(this.contextMenu, "aboutToShow", this, "aboutToShow"); 54 88 dojo.event.connect(this.editor, "destroy", this, "destroy"); 55 89 56 this.setup( );90 this.setup(gs); 57 91 }, 58 92 { 59 setup: function(){ 60 var gs = dojo.widget.Editor2Plugin.ContextMenuManager.menuGroups; 93 bindEditor: function(editor){ 94 this.contextMenu.bindDomNode(editor.document.body); 95 }, 96 setup: function(gs){ 61 97 for(var i in gs){ 62 98 var g = dojo.widget.Editor2Plugin.ContextMenuManager.getGroup(gs[i], this); … … 100 136 dojo.widget.defineWidget( 101 137 "dojo.widget.Editor2ContextMenuItem", 102 dojo.widget.MenuItem2, { 103 command: null, 104 postCreate: function(){ 105 if(!this.command){ 106 this.command = this.caption; 107 } 108 109 dojo.widget.Editor2ContextMenuItem.superclass.postCreate.apply(this, arguments); 110 }, 111 setup: function(){ 112 this.cmd = dojo.widget.Editor2Manager.getCommand(this.command); 113 if(!this.cmd){ 114 alert("command " + this.command + " is not recognized!"); 115 } 138 dojo.widget.MenuItem2, 139 { 140 command: '', 141 buildRendering: function(){ 142 var curInst = dojo.widget.Editor2Manager.getCurrentInstance(); 143 this.caption = curInst.getCommand(this.command).getText(); 144 145 dojo.widget.Editor2ContextMenuItem.superclass.buildRendering.apply(this, arguments); 116 146 }, 117 147 onClick: function(){ 118 if(!this.cmd){ 119 this.setup(); 120 } 121 if(this.cmd){ 122 this.cmd.execute(); 148 var curInst = dojo.widget.Editor2Manager.getCurrentInstance(); 149 if(curInst){ 150 var _command = curInst.getCommand(this.command); 151 if(_command){ 152 _command.execute(); 153 } 123 154 } 124 155 }, 125 156 refresh: function(){ 126 if(!this.cmd){ 127 this.setup(); 128 } 129 if(this.cmd){ 130 if(this.cmd.getState() == dojo.widget.Editor2Manager.commandState.Disabled){ 131 this.disable(); 132 return false; 133 }else{ 134 this.enable(); 135 return true; 157 var curInst = dojo.widget.Editor2Manager.getCurrentInstance(); 158 if(curInst){ 159 var _command = curInst.getCommand(this.command); 160 if(_command){ 161 if(_command.getState() == dojo.widget.Editor2Manager.commandState.Disabled){ 162 this.disable(); 163 return false; 164 }else{ 165 this.enable(); 166 return true; 167 } 136 168 } 137 169 } … … 145 177 } 146 178 }); 147 dojo.declare("dojo.widget.Editor2Plugin.SimpleContextMenu ", null,179 dojo.declare("dojo.widget.Editor2Plugin.SimpleContextMenuGroup", null, 148 180 function(contextmenuplugin){ 149 181 this.contextMenu = contextmenuplugin.contextMenu; … … 184 216 } 185 217 }); 186 dojo.declare("dojo.widget.Editor2Plugin.GenericContextMenu ",187 dojo.widget.Editor2Plugin.SimpleContextMenu ,218 dojo.declare("dojo.widget.Editor2Plugin.GenericContextMenuGroup", 219 dojo.widget.Editor2Plugin.SimpleContextMenuGroup, 188 220 { 189 221 createItems: function(){ 190 this.items.push(dojo.widget.createWidget("Editor2ContextMenuItem", {c aption: "Cut", iconClass: "dojoE2TBIcon dojoE2TBIcon_Cut"}));191 this.items.push(dojo.widget.createWidget("Editor2ContextMenuItem", {c aption: "Copy", iconClass: "dojoE2TBIcon dojoE2TBIcon_Copy"}));192 this.items.push(dojo.widget.createWidget("Editor2ContextMenuItem", {c aption: "Paste", iconClass: "dojoE2TBIcon dojoE2TBIcon_Paste"}));193 } 194 }); 195 dojo.declare("dojo.widget.Editor2Plugin.LinkContextMenu ",196 dojo.widget.Editor2Plugin.SimpleContextMenu ,222 this.items.push(dojo.widget.createWidget("Editor2ContextMenuItem", {command: "cut", iconClass: "dojoE2TBIcon dojoE2TBIcon_Cut"})); 223 this.items.push(dojo.widget.createWidget("Editor2ContextMenuItem", {command: "copy", iconClass: "dojoE2TBIcon dojoE2TBIcon_Copy"})); 224 this.items.push(dojo.widget.createWidget("Editor2ContextMenuItem", {command: "paste", iconClass: "dojoE2TBIcon dojoE2TBIcon_Paste"})); 225 } 226 }); 227 dojo.declare("dojo.widget.Editor2Plugin.LinkContextMenuGroup", 228 dojo.widget.Editor2Plugin.SimpleContextMenuGroup, 197 229 { 198 230 createItems: function(){ 199 this.items.push(dojo.widget.createWidget("Editor2ContextMenuItem", {c aption: "Modify Link", command: 'createlink', iconClass: "dojoE2TBIcon dojoE2TBIcon_Link"}));200 this.items.push(dojo.widget.createWidget("Editor2ContextMenuItem", {c aption: "Remove Link", command: 'unlink', iconClass: "dojoE2TBIcon dojoE2TBIcon_UnLink"}));231 this.items.push(dojo.widget.createWidget("Editor2ContextMenuItem", {command: 'createlink', iconClass: "dojoE2TBIcon dojoE2TBIcon_Link"})); 232 this.items.push(dojo.widget.createWidget("Editor2ContextMenuItem", {command: 'unlink', iconClass: "dojoE2TBIcon dojoE2TBIcon_UnLink"})); 201 233 }, 202 234 checkVisibility: function(){ … … 216 248 } 217 249 }); 218 dojo.declare("dojo.widget.Editor2Plugin.ImageContextMenu ",219 dojo.widget.Editor2Plugin.SimpleContextMenu ,250 dojo.declare("dojo.widget.Editor2Plugin.ImageContextMenuGroup", 251 dojo.widget.Editor2Plugin.SimpleContextMenuGroup, 220 252 { 221 253 createItems: function(){ 222 this.items.push(dojo.widget.createWidget("Editor2ContextMenuItem", {c aption: "Edit Image", command: 'insertimage', iconClass: "dojoE2TBIcon dojoE2TBIcon_Image"}));254 this.items.push(dojo.widget.createWidget("Editor2ContextMenuItem", {command: 'insertimage', iconClass: "dojoE2TBIcon dojoE2TBIcon_Image"})); 223 255 }, 224 256 checkVisibility: function(){ -
trunk/src/widget/Editor2Plugin/FindReplace.js
r5593 r6393 13 13 }, 14 14 find: function(text, option){ 15 var curInst = dojo.widget.Editor2Manager.getCurrentInstance(); 16 if(curInst){ 17 curInst.focus(); 18 if(window.find){ //moz 19 curInst.window.find(text, 20 option & this.SearchOption.CaseSensitive ? true : false, 21 option & this.SearchOption.SearchBackwards ? true : false, 22 option & this.SearchOption.WrapSearch ? true : false, 23 option & this.SearchOption.WholeWord ? true : false 24 ); 25 }else if(dojo.body().createTextRange){ //IE 26 var range = curInst.document.body.createTextRange(); 27 var found = range.findText(text, (option&this.SearchOption.SearchBackwards)?1:-1, option ); 28 if(found){ 29 range.scrollIntoView() ; 30 range.select() ; 31 }else{ 32 alert("Can not find "+text+" in the document"); 33 } 15 this._editor.focus(); 16 if(window.find){ //moz 17 this._editor.window.find(text, 18 option & this.SearchOption.CaseSensitive ? true : false, 19 option & this.SearchOption.SearchBackwards ? true : false, 20 option & this.SearchOption.WrapSearch ? true : false, 21 option & this.SearchOption.WholeWord ? true : false 22 ); 23 }else if(dojo.body().createTextRange){ //IE 24 var range = this._editor.document.body.createTextRange(); 25 var found = range.findText(text, (option&this.SearchOption.SearchBackwards)?1:-1, option ); 26 if(found){ 27 range.scrollIntoView() ; 28 range.select() ; 34 29 }else{ 35 alert(" No idea how to search in this browser. Please submit patch if you know.");30 alert("Can not find "+text+" in the document"); 36 31 } 32 }else{ 33 alert("No idea how to search in this browser. Please submit patch if you know."); 37 34 } 38 35 } 39 36 }); 40 37 41 dojo.widget.Editor2Manager.registerCommand("Find", new dojo.widget.Editor2Plugin.FindCommand('find', 42 {contentFile: "dojo.widget.Editor2Plugin.FindReplaceDialog", 43 contentClass: "Editor2FindDialog", 44 title: "Find", width: "350px", height: "150px", modal: false})); 45 dojo.widget.Editor2Manager.registerCommand("Replace", new dojo.widget.Editor2DialogCommand('replace', 46 {contentFile: "dojo.widget.Editor2Plugin.FindReplaceDialog", 47 contentClass: "Editor2ReplaceDialog", 48 href: dojo.uri.dojoUri("src/widget/templates/Editor2/Dialog/replace.html"), 49 title: "Replace", width: "350px", height: "200px", modal: false})); 50 51 dojo.widget.Editor2Plugin.FindReplace = function(name){ 52 var name = name.toLowerCase(); 53 54 var item; 55 if(name == 'replace'){ 56 item = new dojo.widget.Editor2ToolbarButton('Replace'); 57 }else if(name == 'find') { 58 item = new dojo.widget.Editor2ToolbarButton('Find'); 38 dojo.widget.Editor2Plugin.FindReplace ={ 39 getCommand: function(editor, name){ 40 var name = name.toLowerCase(); 41 var command; 42 if(name == 'find'){ 43 command = new dojo.widget.Editor2Plugin.FindCommand(editor, 'find', 44 {contentFile: "dojo.widget.Editor2Plugin.FindReplaceDialog", 45 contentClass: "Editor2FindDialog", 46 title: "Find", width: "350px", height: "150px", modal: false}); 47 }else if(name == 'replace') { 48 command = new dojo.widget.Editor2DialogCommand(editor, 'replace', 49 {contentFile: "dojo.widget.Editor2Plugin.FindReplaceDialog", 50 contentClass: "Editor2ReplaceDialog", 51 href: dojo.uri.dojoUri("src/widget/templates/Editor2/Dialog/replace.html"), 52 title: "Replace", width: "350px", height: "200px", modal: false}); 53 } 54 55 return command; 56 }, 57 getToolbarItem: function(name){ 58 var name = name.toLowerCase(); 59 60 var item; 61 if(name == 'replace'){ 62 item = new dojo.widget.Editor2ToolbarButton('Replace'); 63 }else if(name == 'find') { 64 item = new dojo.widget.Editor2ToolbarButton('Find'); 65 } 66 67 return item; 59 68 } 60 61 return item;62 69 } 63 64 dojo.widget.Editor2ToolbarItemManager.registerHandler(dojo.widget.Editor2Plugin.FindReplace );70 dojo.widget.Editor2Manager.registerHandler(dojo.widget.Editor2Plugin.FindReplace.getCommand); 71 dojo.widget.Editor2ToolbarItemManager.registerHandler(dojo.widget.Editor2Plugin.FindReplace.getToolbarItem); -
trunk/src/widget/Editor2Plugin/FindReplaceDialog.js
r6058 r6393 1 dojo.provide("dojo.widget.Editor2Plugin.FindReplaceDialog");1 dojo.provide("dojo.widget.Editor2Plugin.FindReplaceDialog"); 2 2 3 3 dojo.widget.defineWidget( … … 8 8 9 9 find: function(){ 10 var findcmd = dojo.widget.Editor2Manager.getCommand('find'); 10 var curInst = dojo.widget.Editor2Manager.getCurrentInstance(); 11 var findcmd = curInst.getCommand('find'); 11 12 var option = 0; 12 13 -
trunk/src/widget/Editor2Plugin/InsertImageDialog.js
r6188 r6393 34 34 ok: function(){ 35 35 var curInst = dojo.widget.Editor2Manager.getCurrentInstance(); 36 var insertcmd = dojo.widget.Editor2Manager.getCommand('inserthtml');36 var insertcmd = curInst.getCommand('inserthtml'); 37 37 var option = 0; 38 38 -
trunk/src/widget/Editor2Plugin/SimpleSignalCommands.js
r6188 r6393 19 19 20 20 dojo.declare("dojo.widget.Editor2Plugin.SimpleSignalCommand", dojo.widget.Editor2Command, 21 function( name){21 function(editor, name){ 22 22 if(dojo.widget.Editor2.prototype[name] == undefined){ 23 dojo.widget.Editor2.prototype[name] = function(){ dojo.debug("Editor2::"+name);};23 dojo.widget.Editor2.prototype[name] = function(){ /*dojo.debug("Editor2::"+name);*/ }; 24 24 } 25 25 }, 26 26 { 27 27 execute: function(){ 28 var curInst = dojo.widget.Editor2Manager.getCurrentInstance(); 29 30 if(curInst){ 31 curInst[this._name](); 32 } 28 this._editor[this._name](); 33 29 } 34 30 }); … … 47 43 } 48 44 }, 49 registerAllSignalCommands: function(){ 50 for(var i=0;i<this.signals.length;i++){ 51 dojo.widget.Editor2Manager.registerCommand(this.signals[i], 52 new dojo.widget.Editor2Plugin.SimpleSignalCommand(this.signals[i])); 45 getCommand: function(editor, name){ 46 var signal; 47 dojo.lang.every(this.signals,function(s){ 48 if(s.toLowerCase() == name.toLowerCase()){ 49 signal = s; 50 return false; 51 } 52 return true; 53 }); 54 if(signal){ 55 return new dojo.widget.Editor2Plugin.SimpleSignalCommand(editor, signal); 53 56 } 54 57 } … … 58 61 dojo.lang.mixin(dojo.widget.Editor2Plugin.SimpleSignalCommands, dojo.widget.Editor2Plugin['_SimpleSignalCommands']); 59 62 } 60 61 dojo.widget.Editor2Plugin.SimpleSignalCommands.registerAllSignalCommands(); 63 dojo.widget.Editor2Manager.registerHandler(dojo.widget.Editor2Plugin.SimpleSignalCommands, 'getCommand'); 62 64 dojo.widget.Editor2ToolbarItemManager.registerHandler(dojo.widget.Editor2Plugin.SimpleSignalCommands.Handler); -
trunk/src/widget/Editor2Plugin/TableOperation.js
r6371 r6393 7 7 //are executed, so we have to insert our own trick before that point 8 8 dojo.event.topic.subscribe("dojo.widget.RichText::init", function(editor){ 9 editor.__TableOperationShowBorder = false;10 11 9 if(dojo.render.html.ie){ 12 10 //add/remove a class to a table with border=0 to show the border when loading/saving 13 11 editor.contentDomPreFilters.push(dojo.widget.Editor2Plugin.TableOperation.showIETableBorder); 14 12 editor.contentDomPostFilters.push(dojo.widget.Editor2Plugin.TableOperation.removeIEFakeClass); 15 //include the css file to show table border when border=016 // editor.__TableOperationShowBorder = true;17 // editor.addStyleSheet(dojo.uri.dojoUri("src/widget/templates/Editor2/showtableborder_ie.css"));18 // editor.editingAreaStyleSheets.push(dojo.uri.dojoUri("src/widget/templates/Editor2/showtableborder_ie.css"));19 13 } 20 dojo.event.connect(editor, "editorOnLoad", function(){ 21 dojo.widget.Editor2Plugin.TableOperation.toggleTableBorderCommand.execute(editor); 22 }); 14 //create a toggletableborder command for this editor so that tables without border can be seen 15 editor.getCommand("toggletableborder"); 16 }); 17 18 dojo.lang.declare("dojo.widget.Editor2Plugin.deleteTableCommand", dojo.widget.Editor2Command, 19 { 20 execute: function(){ 21 var table = dojo.withGlobal(this._editor.window, "getAncestorElement", dojo.html.selection, ['table']); 22 if(table){ 23 dojo.withGlobal(this._editor.window, "selectElement", dojo.html.selection, [table]); 24 this._editor.execCommand("inserthtml", " "); //Moz does not like an empty string, so a space here instead 25 } 26 }, 27 getState: function(){ 28 if(this._editor._lastStateTimestamp > this._updateTime || this._state == undefined){ 29 this._updateTime = this._editor._lastStateTimestamp; 30 var table = dojo.withGlobal(this._editor.window, "hasAncestorElement", dojo.html.selection, ['table']); 31 this._state = table ? dojo.widget.Editor2Manager.commandState.Enabled : dojo.widget.Editor2Manager.commandState.Disabled; 32 } 33 return this._state; 34 }, 35 getText: function(){ 36 return 'Delete Table'; 37 } 38 }); 39 40 dojo.lang.declare("dojo.widget.Editor2Plugin.toggleTableBorderCommand", dojo.widget.Editor2Command, 41 function(){ 42 this._showTableBorder = false; 43 dojo.event.connect(this._editor, "editorOnLoad", this, 'execute'); 44 }, 45 { 46 execute: function(){ 47 if(this._showTableBorder){ 48 this._showTableBorder = false; 49 if(dojo.render.html.moz){ 50 this._editor.removeStyleSheet(dojo.uri.dojoUri("src/widget/templates/Editor2/showtableborder_gecko.css")); 51 }else if(dojo.render.html.ie){ 52 this._editor.removeStyleSheet(dojo.uri.dojoUri("src/widget/templates/Editor2/showtableborder_ie.css")); 53 } 54 }else{ 55 this._showTableBorder = true; 56 if(dojo.render.html.moz){ 57 this._editor.addStyleSheet(dojo.uri.dojoUri("src/widget/templates/Editor2/showtableborder_gecko.css")); 58 }else if(dojo.render.html.ie){ 59 this._editor.addStyleSheet(dojo.uri.dojoUri("src/widget/templates/Editor2/showtableborder_ie.css")); 60 } 61 } 62 }, 63 getText: function(){ 64 return 'Toggle Table Border'; 65 }, 66 getState: function(){ 67 if(this._editor._lastStateTimestamp > this._updateTime || this._state == undefined){ 68 this._updateTime = this._editor._lastStateTimestamp; 69 var table = dojo.withGlobal(this._editor.window, "hasAncestorElement", dojo.html.selection, ['table']); 70 this._state = this._showTableBorder ? dojo.widget.Editor2Manager.commandState.Latched : dojo.widget.Editor2Manager.commandState.Enabled; 71 } 72 return this._state; 73 } 23 74 }); 24 75 25 76 dojo.widget.Editor2Plugin.TableOperation = { 77 getCommand: function(editor, name){ 78 switch(name.toLowerCase()){ 79 case 'toggletableborder': 80 return new dojo.widget.Editor2Plugin.toggleTableBorderCommand(editor, name); 81 case 'inserttable': 82 return new dojo.widget.Editor2DialogCommand(editor, 'inserttable', 83 {contentFile: "dojo.widget.Editor2Plugin.InsertTableDialog", 84 contentClass: "Editor2InsertTableDialog", 85 title: "Insert/Edit Table", width: "450px", height: "250px"}) 86 case 'deletetable': 87 return new dojo.widget.Editor2Plugin.deleteTableCommand(editor, name); 88 } 89 }, 26 90 getToolbarItem: function(name){ 27 91 var name = name.toLowerCase(); … … 37 101 }, 38 102 getContextMenuGroup: function(name, contextmenuplugin){ 39 return new dojo.widget.Editor2Plugin.TableContextMenu(contextmenuplugin); 40 }, 41 deleteTableCommand: { 42 execute: function(){ 43 var curInst = dojo.widget.Editor2Manager.getCurrentInstance(); 44 var table = dojo.withGlobal(curInst.window, "getAncestorElement", dojo.html.selection, ['table']); 45 if(table){ 46 dojo.withGlobal(curInst.window, "selectElement", dojo.html.selection, [table]); 47 curInst.execCommand("inserthtml", " "); //Moz does not like an empty string, so a space here instead 48 } 49 }, 50 getState: function(){ 51 var curInst = dojo.widget.Editor2Manager.getCurrentInstance(); 52 var table = dojo.withGlobal(curInst.window, "hasAncestorElement", dojo.html.selection, ['table']); 53 return table ? dojo.widget.Editor2Manager.commandState.Enabled : dojo.widget.Editor2Manager.commandState.Disabled; 54 }, 55 getText: function(){ 56 return 'Delete Table'; 57 }, 58 destory: function(){} 59 }, 60 toggleTableBorderCommand: { 61 execute: function(instance){ 62 var curInst = instance || dojo.widget.Editor2Manager.getCurrentInstance(); 63 if(curInst.__TableOperationShowBorder){ 64 curInst.__TableOperationShowBorder = false; 65 if(dojo.render.html.moz){ 66 curInst.removeStyleSheet(dojo.uri.dojoUri("src/widget/templates/Editor2/showtableborder_gecko.css")); 67 }else if(dojo.render.html.ie){ 68 curInst.removeStyleSheet(dojo.uri.dojoUri("src/widget/templates/Editor2/showtableborder_ie.css")); 69 } 70 }else{ 71 curInst.__TableOperationShowBorder = true; 72 if(dojo.render.html.moz){ 73 curInst.addStyleSheet(dojo.uri.dojoUri("src/widget/templates/Editor2/showtableborder_gecko.css")); 74 }else if(dojo.render.html.ie){ 75 curInst.addStyleSheet(dojo.uri.dojoUri("src/widget/templates/Editor2/showtableborder_ie.css")); 76 } 77 } 78 }, 79 getText: function(){ 80 return 'Toggle Table Border'; 81 }, 82 getState: function(){ 83 var curInst = dojo.widget.Editor2Manager.getCurrentInstance(); 84 return curInst.__TableOperationShowBorder ? dojo.widget.Editor2Manager.commandState.Latched : dojo.widget.Editor2Manager.commandState.Enabled; 85 }, 86 destory: function(){} 103 return new dojo.widget.Editor2Plugin.TableContextMenuGroup(contextmenuplugin); 87 104 }, 88 105 showIETableBorder: function(dom){ … … 103 120 104 121 //register commands: toggletableborder, inserttable, deletetable 105 dojo.widget.Editor2Manager.registerCommand("toggletableborder", dojo.widget.Editor2Plugin.TableOperation.toggleTableBorderCommand); 106 107 dojo.widget.Editor2Manager.registerCommand("inserttable", new dojo.widget.Editor2DialogCommand('inserttable', 108 {contentFile: "dojo.widget.Editor2Plugin.InsertTableDialog", 109 contentClass: "Editor2InsertTableDialog", 110 title: "Insert/Edit Table", width: "450px", height: "250px"})); 111 112 dojo.widget.Editor2Manager.registerCommand("deletetable", dojo.widget.Editor2Plugin.TableOperation.deleteTableCommand); 122 dojo.widget.Editor2Manager.registerHandler(dojo.widget.Editor2Plugin.TableOperation.getCommand); 113 123 114 124 //register toggletableborder and inserttable as toolbar item … … 119 129 dojo.widget.Editor2Plugin.ContextMenuManager.registerGroup('Table', dojo.widget.Editor2Plugin.TableOperation.getContextMenuGroup); 120 130 121 dojo.declare("dojo.widget.Editor2Plugin.TableContextMenu ",122 dojo.widget.Editor2Plugin.SimpleContextMenu ,131 dojo.declare("dojo.widget.Editor2Plugin.TableContextMenuGroup", 132 dojo.widget.Editor2Plugin.SimpleContextMenuGroup, 123 133 { 124 134 createItems: function(){ -
trunk/src/widget/Editor2Toolbar.js
r6370 r6393 10 10 dojo.require("dojo.widget.ColorPalette"); 11 11 12 // Object: Manager available editor2 toolbar items 13 dojo.widget.Editor2ToolbarItemManager = { 14 _registeredItemHandlers: [], 12 dojo.lang.declare("dojo.widget.HandlerManager", null, 13 function(){ 14 this._registeredHandlers=[]; 15 }, 16 { 15 17 registerHandler: function(/*Object*/obj, /*String*/func){ 16 // summary: register a toolbar itemhandler18 // summary: register a handler 17 19 // obj: object which has the function to call 18 20 // func: the function in the object 19 21 if(arguments.length == 2){ 20 this._registered ItemHandlers.push(function(){return obj[func].apply(obj, arguments);});22 this._registeredHandlers.push(function(){return obj[func].apply(obj, arguments);}); 21 23 }else{ 22 24 /* obj: Function 23 25 func: null 24 26 pId: f */ 25 // for(i in this._registeredItemHandlers){ 26 // if(func === this._registeredItemHandlers[i]){ 27 // dojo.debug("Editor2ToolbarItemManager handler "+func+" is already registered, ignored"); 28 // return; 29 // } 30 // } 31 this._registeredItemHandlers.push(obj); 27 this._registeredHandlers.push(obj); 32 28 } 33 29 }, 34 30 removeHandler: function(func){ 35 31 // summary: remove a registered handler 36 for(var i=0;i<this._registered ItemHandlers.length;i++){37 if(func === this._registered ItemHandlers[i]){38 delete this._registered ItemHandlers[i];32 for(var i=0;i<this._registeredHandlers.length;i++){ 33 if(func === this._registeredHandlers[i]){ 34 delete this._registeredHandlers[i]; 39 35 return; 40 36 } 41 37 } 42 dojo.debug(" Editor2ToolbarItemManager handler "+func+" is not registered, can not remove.");38 dojo.debug("HandlerManager handler "+func+" is not registered, can not remove."); 43 39 }, 44 40 destroy: function(){ 45 for(var i=0;i<this._registeredItemHandlers.length;i++){ 46 delete this._registeredItemHandlers[i]; 47 } 48 }, 41 for(var i=0;i<this._registeredHandlers.length;i++){ 42 delete this._registeredHandlers[i]; 43 } 44 } 45 }); 46 47 dojo.widget.Editor2ToolbarItemManager = new dojo.widget.HandlerManager; 48 dojo.lang.mixin(dojo.widget.Editor2ToolbarItemManager, 49 { 49 50 getToolbarItem: function(/*String*/name){ 50 51 // summary: return a toobar item with the given name 51 52 var item; 52 53 name = name.toLowerCase(); 53 for(var i=0;i<this._registered ItemHandlers.length;i++){54 item = this._registered ItemHandlers[i](name);54 for(var i=0;i<this._registeredHandlers.length;i++){ 55 item = this._registeredHandlers[i](name); 55 56 if(item){ 56 break; 57 } 58 } 59 60 if(!item){ 61 switch(name){ 62 //button for builtin functions 63 case 'bold': 64 case 'copy': 65 case 'cut': 66 case 'delete': 67 case 'indent': 68 case 'inserthorizontalrule': 69 case 'insertorderedlist': 70 case 'insertunorderedlist': 71 case 'italic': 72 case 'justifycenter': 73 case 'justifyfull': 74 case 'justifyleft': 75 case 'justifyright': 76 case 'outdent': 77 case 'paste': 78 case 'redo': 79 case 'removeformat': 80 case 'selectall': 81 case 'strikethrough': 82 case 'subscript': 83 case 'superscript': 84 case 'underline': 85 case 'undo': 86 case 'unlink': 87 case 'createlink': 88 case 'insertimage': 89 //extra simple buttons 90 case 'htmltoggle': 91 item = new dojo.widget.Editor2ToolbarButton(name); 92 break; 93 case 'forecolor': 94 case 'hilitecolor': 95 item = new dojo.widget.Editor2ToolbarColorPaletteButton(name); 96 break; 97 case 'plainformatblock': 98 item = new dojo.widget.Editor2ToolbarFormatBlockPlainSelect("formatblock"); 99 break; 100 case 'formatblock': 101 item = new dojo.widget.Editor2ToolbarFormatBlockSelect("formatblock"); 102 break; 103 case 'fontsize': 104 item = new dojo.widget.Editor2ToolbarFontSizeSelect("fontsize"); 105 break; 106 case 'fontname': 107 item = new dojo.widget.Editor2ToolbarFontNameSelect("fontname"); 108 break; 109 case 'inserttable': 110 case 'insertcell': 111 case 'insertcol': 112 case 'insertrow': 113 case 'deletecells': 114 case 'deletecols': 115 case 'deleterows': 116 case 'mergecells': 117 case 'splitcell': 118 dojo.debug(name + " is implemented in dojo.widget.Editor2Plugin.TableOperation, please require it first."); 119 break; 120 //TODO: 121 case 'inserthtml': 122 case 'blockdirltr': 123 case 'blockdirrtl': 124 case 'dirltr': 125 case 'dirrtl': 126 case 'inlinedirltr': 127 case 'inlinedirrtl': 128 dojo.debug("Not yet implemented toolbar item: "+name); 129 break; 130 default: 131 dojo.debug("dojo.widget.Editor2ToolbarItemManager.getToolbarItem: Unknown toolbar item: "+name); 132 } 57 return item; 58 } 59 } 60 61 switch(name){ 62 //button for builtin functions 63 case 'bold': 64 case 'copy': 65 case 'cut': 66 case 'delete': 67 case 'indent': 68 case 'inserthorizontalrule': 69 case 'insertorderedlist': 70 case 'insertunorderedlist': 71 case 'italic': 72 case 'justifycenter': 73 case 'justifyfull': 74 case 'justifyleft': 75 case 'justifyright': 76 case 'outdent': 77 case 'paste': 78 case 'redo': 79 case 'removeformat': 80 case 'selectall': 81 case 'strikethrough': 82 case 'subscript': 83 case 'superscript': 84 case 'underline': 85 case 'undo': 86 case 'unlink': 87 case 'createlink': 88 case 'insertimage': 89 //extra simple buttons 90 case 'htmltoggle': 91 item = new dojo.widget.Editor2ToolbarButton(name); 92 break; 93 case 'forecolor': 94 case 'hilitecolor': 95 item = new dojo.widget.Editor2ToolbarColorPaletteButton(name); 96 break; 97 case 'plainformatblock': 98 item = new dojo.widget.Editor2ToolbarFormatBlockPlainSelect("formatblock"); 99 break; 100 case 'formatblock': 101 item = new dojo.widget.Editor2ToolbarFormatBlockSelect("formatblock"); 102 break; 103 case 'fontsize': 104 item = new dojo.widget.Editor2ToolbarFontSizeSelect("fontsize"); 105 break; 106 case 'fontname': 107 item = new dojo.widget.Editor2ToolbarFontNameSelect("fontname"); 108 break; 109 case 'inserttable': 110 case 'insertcell': 111 case 'insertcol': 112 case 'insertrow': 113 case 'deletecells': 114 case 'deletecols': 115 case 'deleterows': 116 case 'mergecells': 117 case 'splitcell': 118 dojo.debug(name + " is implemented in dojo.widget.Editor2Plugin.TableOperation, please require it first."); 119 break; 120 //TODO: 121 case 'inserthtml': 122 case 'blockdirltr': 123 case 'blockdirrtl': 124 case 'dirltr': 125 case 'dirrtl': 126 case 'inlinedirltr': 127 case 'inlinedirrtl': 128 dojo.debug("Not yet implemented toolbar item: "+name); 129 break; 130 default: 131 dojo.debug("dojo.widget.Editor2ToolbarItemManager.getToolbarItem: Unknown toolbar item: "+name); 133 132 } 134 133 return item; 135 134 } 136 } ;135 }); 137 136 138 137 dojo.addOnUnload(dojo.widget.Editor2ToolbarItemManager, "destroy"); 139 138 // summary: 140 139 // dojo.widget.Editor2ToolbarButton is the base class for all toolbar item in Editor2Toolbar 141 dojo.declare("dojo.widget.Editor2ToolbarButton", null, {142 initializer:function(name){140 dojo.declare("dojo.widget.Editor2ToolbarButton", null, 141 function(name){ 143 142 // summary: constructor 144 143 this._name = name; 145 this._command = dojo.widget.Editor2Manager.getCommand(name); 146 }, 144 // this._command = editor.getCommand(name); 145 }, 146 { 147 147 create: function(/*DomNode*/node, /*dojo.widget.Editor2Toolbar*/toolbar, /*Boolean*/nohover){ 148 148 // summary: create the item … … 151 151 // nohover: whether this item in charge of highlight this item 152 152 this._domNode = node; 153 this._domNode.title = this._command.getText(); 153 var cmd = toolbar.parent.getCommand(this._name); //FIXME: maybe an issue if different instance has different language 154 if(cmd){ 155 this._domNode.title = cmd.getText(); 156 } 154 157 //make this unselectable: different browsers 155 158 //use different properties for this, so use 156 159 //js do it automatically 157 160 this.disableSelection(this._domNode); 161 158 162 this._parentToolbar = toolbar; 159 163 dojo.event.connect(this._domNode, 'onclick', this, 'onClick'); … … 172 176 }, 173 177 onMouseOver: function(){ 174 if(this._command.getState() != dojo.widget.Editor2Manager.commandState.Disabled){ 175 this.highlightToolbarItem(); 178 var curInst = dojo.widget.Editor2Manager.getCurrentInstance(); 179 if(curInst){ 180 var _command = curInst.getCommand(this._name); 181 if(_command && _command.getState() != dojo.widget.Editor2Manager.commandState.Disabled){ 182 this.highlightToolbarItem(); 183 } 176 184 } 177 185 }, … … 182 190 // summary: destructor 183 191 this._domNode = null; 184 delete this._command;192 // delete this._command; 185 193 this._parentToolbar = null; 186 194 }, 187 195 onClick: function(e){ 188 if(this._domNode && !this._domNode.disabled && this._ command){196 if(this._domNode && !this._domNode.disabled && this._parentToolbar.checkAvailability()){ 189 197 e.preventDefault(); 190 198 e.stopPropagation(); 191 this._command.execute(); 199 var curInst = dojo.widget.Editor2Manager.getCurrentInstance(); 200 if(curInst){ 201 var _command = curInst.getCommand(this._name); 202 if(_command){ 203 _command.execute(); 204 } 205 } 192 206 } 193 207 }, 194 208 refreshState: function(){ 195 209 // summary: update the state of the toolbar item 196 if(this._domNode && this._command){ 197 var em = dojo.widget.Editor2Manager; 198 var state = this._command.getState(); 199 if(state != this._lastState){ 200 switch(state){ 201 case em.commandState.Latched: 202 this.latchToolbarItem(); 203 break; 204 case em.commandState.Enabled: 205 this.enableToolbarItem(); 206 break; 207 case em.commandState.Disabled: 208 default: 209 this.disableToolbarItem(); 210 } 211 this._lastState = state; 212 } 213 return state; 214 } 210 var curInst = dojo.widget.Editor2Manager.getCurrentInstance(); 211 var em = dojo.widget.Editor2Manager; 212 if(curInst){ 213 var _command = curInst.getCommand(this._name); 214 if(_command){ 215 var state = _command.getState(); 216 if(state != this._lastState){ 217 switch(state){ 218 case em.commandState.Latched: 219 this.latchToolbarItem(); 220 break; 221 case em.commandState.Enabled: 222 this.enableToolbarItem(); 223 break; 224 case em.commandState.Disabled: 225 default: 226 this.disableToolbarItem(); 227 } 228 this._lastState = state; 229 } 230 } 231 } 232 return em.commandState.Enabled; 215 233 }, 216 234 … … 250 268 251 269 // summary: dojo.widget.Editor2ToolbarDropDownButton extends the basic button with a dropdown list 252 dojo.declare("dojo.widget.Editor2ToolbarDropDownButton", dojo.widget.Editor2ToolbarButton, {270 dojo.declare("dojo.widget.Editor2ToolbarDropDownButton", dojo.widget.Editor2ToolbarButton, function(){}, { 253 271 onClick: function(){ 254 if(this._domNode ){272 if(this._domNode && !this._domNode.disabled && this._parentToolbar.checkAvailability()){ 255 273 if(!this._dropdown){ 256 274 this._dropdown = dojo.widget.createWidget("PopupContainer", {}); … … 277 295 278 296 // summary: dojo.widget.Editor2ToolbarColorPaletteButton provides a dropdown color palette picker 279 dojo.declare("dojo.widget.Editor2ToolbarColorPaletteButton", dojo.widget.Editor2ToolbarDropDownButton, {297 dojo.declare("dojo.widget.Editor2ToolbarColorPaletteButton", dojo.widget.Editor2ToolbarDropDownButton, function(){}, { 280 298 onDropDownShown: function(){ 281 299 if(!this._colorpalette){ … … 296 314 setColor: function(color){ 297 315 this._dropdown.close(); 298 this._command.execute(color); 316 var curInst = dojo.widget.Editor2Manager.getCurrentInstance(); 317 if(curInst){ 318 var _command = curInst.getCommand(this._name); 319 if(_command){ 320 _command.execute(color); 321 } 322 } 299 323 } 300 324 }); 301 325 302 326 // summary: dojo.widget.Editor2ToolbarFormatBlockPlainSelect provides a simple select for setting block format 303 dojo.declare("dojo.widget.Editor2ToolbarFormatBlockPlainSelect", dojo.widget.Editor2ToolbarButton, {327 dojo.declare("dojo.widget.Editor2ToolbarFormatBlockPlainSelect", dojo.widget.Editor2ToolbarButton, function(){}, { 304 328 create: function(node, toolbar){ 329 dojo.widget.Editor2ToolbarFormatBlockPlainSelect.superclass.create.apply(this, arguments); 305 330 //TODO: check node is a select 306 331 this._domNode = node; 307 332 this.disableSelection(this._domNode); 308 this._parentToolbar = toolbar;309 333 dojo.event.connect(this._domNode, 'onchange', this, 'onChange'); 310 334 }, … … 312 336 destroy: function(){ 313 337 this._domNode = null; 314 this._command = null;315 this._parentToolbar = null;316 338 }, 317 339 318 340 onChange: function(){ 341 if(this._parentToolbar.checkAvailability()){ 342 var sv = this._domNode.value.toLowerCase(); 343 var curInst = dojo.widget.Editor2Manager.getCurrentInstance(); 344 if(curInst){ 345 var _command = curInst.getCommand(this._name); 346 if(_command){ 347 _command.execute(sv); 348 } 349 } 350 } 351 }, 352 353 refreshState: function(){ 319 354 if(this._domNode){ 320 var sv = this._domNode.value.toLowerCase();321 this._command.execute(sv);322 }323 },324 325 refreshState: function(){326 if(this._domNode && this._command){327 355 dojo.widget.Editor2ToolbarFormatBlockPlainSelect.superclass.refreshState.call(this); 328 var format = this._command.getValue(); 329 if(!format){ format = ""; } 330 dojo.lang.forEach(this._domNode.options, function(item){ 331 if(item.value.toLowerCase() == format.toLowerCase()){ 332 item.selected = true; 333 } 334 }); 356 var curInst = dojo.widget.Editor2Manager.getCurrentInstance(); 357 if(curInst){ 358 var _command = curInst.getCommand(this._name); 359 if(_command){ 360 var format = _command.getValue(); 361 if(!format){ format = ""; } 362 dojo.lang.forEach(this._domNode.options, function(item){ 363 if(item.value.toLowerCase() == format.toLowerCase()){ 364 item.selected = true; 365 } 366 }); 367 } 368 } 335 369 } 336 370 } … … 338 372 339 373 // summary: dojo.widget.Editor2ToolbarComboItem provides an external loaded dropdown list 340 dojo.declare("dojo.widget.Editor2ToolbarComboItem", dojo.widget.Editor2ToolbarDropDownButton, {374 dojo.declare("dojo.widget.Editor2ToolbarComboItem", dojo.widget.Editor2ToolbarDropDownButton, function(){}, { 341 375 href: null, 342 376 create: function(node, toolbar){ 343 dojo.widget.Editor2ToolbarComboItem.superclass.create. call(this, node, toolbar);377 dojo.widget.Editor2ToolbarComboItem.superclass.create.apply(this, arguments); 344 378 //do not use lazy initilization, as we need the local names in refreshState() 345 379 if(!this._contentPane){ … … 370 404 371 405 onChange: function(e){ 372 var name = e.currentTarget.getAttribute("dropDownItemName"); 373 this._command.execute(name); 406 if(this._parentToolbar.checkAvailability()){ 407 var name = e.currentTarget.getAttribute("dropDownItemName"); 408 var curInst = dojo.widget.Editor2Manager.getCurrentInstance(); 409 if(curInst){ 410 var _command = curInst.getCommand(this._name); 411 if(_command){ 412 _command.execute(name); 413 } 414 } 415 } 374 416 this._dropdown.close(); 375 417 }, … … 389 431 390 432 // summary: dojo.widget.Editor2ToolbarFormatBlockSelect is an improved format block setting item 391 dojo.declare("dojo.widget.Editor2ToolbarFormatBlockSelect", dojo.widget.Editor2ToolbarComboItem, {433 dojo.declare("dojo.widget.Editor2ToolbarFormatBlockSelect", dojo.widget.Editor2ToolbarComboItem, function(){}, { 392 434 href: dojo.uri.dojoUri("src/widget/templates/Editor2/EditorToolbar_FormatBlock.html"), 393 435 … … 425 467 426 468 refreshState: function(){ 427 if(this._command){ 428 //dojo.widget.Editor2ToolbarFormatBlockSelect.superclass.refreshState.call(this); 429 var format = this._command.getValue(); 430 if(format == this._lastSelectedFormat && this._blockDisplayNames){ 431 return; 432 } 433 this._lastSelectedFormat = format; 434 var label = this._domNode.getElementsByTagName("label")[0]; 435 var isSet = false; 436 if(this._blockDisplayNames){ 437 for(var name in this._blockDisplayNames){ 438 if(name == format){ 439 label.innerHTML = this._blockDisplayNames[name]; 440 isSet = true; 441 break; 469 var curInst = dojo.widget.Editor2Manager.getCurrentInstance(); 470 if(curInst){ 471 var _command = curInst.getCommand(this._name); 472 if(_command){ 473 var format = _command.getValue(); 474 if(format == this._lastSelectedFormat && this._blockDisplayNames){ 475 return; 476 } 477 this._lastSelectedFormat = format; 478 var label = this._domNode.getElementsByTagName("label")[0]; 479 var isSet = false; 480 if(this._blockDisplayNames){ 481 for(var name in this._blockDisplayNames){ 482 if(name == format){ 483 label.innerHTML = this._blockDisplayNames[name]; 484 isSet = true; 485 break; 486 } 442 487 } 443 }444 if(!isSet){445 label.innerHTML = " ";488 if(!isSet){ 489 label.innerHTML = " "; 490 } 446 491 } 447 492 } … … 451 496 452 497 // summary: dojo.widget.Editor2ToolbarFontSizeSelect provides a dropdown list for setting fontsize 453 dojo.declare("dojo.widget.Editor2ToolbarFontSizeSelect", dojo.widget.Editor2ToolbarComboItem, {498 dojo.declare("dojo.widget.Editor2ToolbarFontSizeSelect", dojo.widget.Editor2ToolbarComboItem, function(){}, { 454 499 href: dojo.uri.dojoUri("src/widget/templates/Editor2/EditorToolbar_FontSize.html"), 455 500 … … 486 531 487 532 refreshState: function(){ 488 if(this._command){ 489 //dojo.widget.Editor2ToolbarFormatBlockSelect.superclass.refreshState.call(this); 490 var size = this._command.getValue(); 491 if(size == this._lastSelectedSize && this._fontSizeDisplayNames){ 492 return; 493 } 494 this._lastSelectedSize = size; 495 var label = this._domNode.getElementsByTagName("label")[0]; 496 var isSet = false; 497 if(this._fontSizeDisplayNames){ 498 for(var name in this._fontSizeDisplayNames){ 499 if(name == size){ 500 label.innerHTML = this._fontSizeDisplayNames[name]; 501 isSet = true; 502 break; 533 var curInst = dojo.widget.Editor2Manager.getCurrentInstance(); 534 if(curInst){ 535 var _command = curInst.getCommand(this._name); 536 if(_command){ 537 var size = _command.getValue(); 538 if(size == this._lastSelectedSize && this._fontSizeDisplayNames){ 539 return; 540 } 541 this._lastSelectedSize = size; 542 var label = this._domNode.getElementsByTagName("label")[0]; 543 var isSet = false; 544 if(this._fontSizeDisplayNames){ 545 for(var name in this._fontSizeDisplayNames){ 546 if(name == size){ 547 label.innerHTML = this._fontSizeDisplayNames[name]; 548 isSet = true; 549 break; 550 } 503 551 } 504 }505 if(!isSet){506 label.innerHTML = " ";552 if(!isSet){ 553 label.innerHTML = " "; 554 } 507 555 } 508 556 } … … 512 560 513 561 // summary: dojo.widget.Editor2ToolbarFontNameSelect provides a dropdown list for setting fontname 514 dojo.declare("dojo.widget.Editor2ToolbarFontNameSelect", dojo.widget.Editor2ToolbarFontSizeSelect, {562 dojo.declare("dojo.widget.Editor2ToolbarFontNameSelect", dojo.widget.Editor2ToolbarFontSizeSelect, function(){}, { 515 563 href: dojo.uri.dojoUri("src/widget/templates/Editor2/EditorToolbar_FontName.html") 516 564 }); … … 524 572 templatePath: dojo.uri.dojoUri("src/widget/templates/EditorToolbar.html"), 525 573 templateCssPath: dojo.uri.dojoUri("src/widget/templates/EditorToolbar.css"), 526 527 // DOM Nodes528 // saveButton: null,529 574 530 575 // String: class name for latched toolbar button items … … 570 615 }, 571 616 617 shareGroup: '', 618 checkAvailability: function(){ 619 // summary: returns whether items in this toolbar can be executed 620 // description: 621 // For unshared toolbar, when clicking on a toolbar, the corresponding 622 // editor will be focused, and this function always return true. For shared 623 // toolbar, if the current focued editor is not one of the instances sharing 624 // this toolbar, this function return false, otherwise true. 625 if(!this.shareGroup){ 626 this.parent.focus(); 627 return true; 628 } 629 var curInst = dojo.widget.Editor2Manager.getCurrentInstance(); 630 if(this.shareGroup == curInst.toolbarGroup){ 631 return true; 632 } 633 return false; 634 }, 572 635 destroy: function(){ 573 636 for(var it in this.items){ -
trunk/src/widget/RichText.js
r6356 r6393 40 40 // Boolean: 41 41 // whether focusing into this instance of richtext when page onload 42 focusOnLoad: true,42 focusOnLoad: false, 43 43 44 44 // String: … … 639 639 // remove an external stylesheet for the editing area 640 640 var url=uri.toString(); 641 //if uri is relative, then convert it to absolute so that it can be resolved correctly in iframe 642 if(url.charAt(0) == '.' || (url.charAt(0) != '/' && !uri.host)){ 643 url = (new dojo.uri.Uri(dojo.global().location, url)).toString(); 644 } 641 645 var index = dojo.lang.find(this.editingAreaStyleSheets, url); 642 646 if(index == -1){ -
trunk/src/widget/templates/EditorToolbarOneline.html
r6371 r6393 4 4 <tr valign="top" align="left"> 5 5 <td> 6 <!-- htmltoggle -->7 6 <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="htmltoggle"> 8 7 <span class="dojoE2TBIcon" … … 10 9 </span> 11 10 </td> 12 <!-- wikiword -->13 <!--td>14 <span class="iconContainer" dojoAttachPoint="wikiwordButton"15 dojoOnClick="wikiwordClick; buttonClick;" style="display: none;">16 <span class="dojoE2TBIcon dojoE2TBIcon_wikiword"17 unselectable="on"> </span>18 </span>19 </td-->20 11 <td> 21 <!-- copy -->22 12 <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="copy"> 23 13 <span class="dojoE2TBIcon dojoE2TBIcon_Copy"> </span> … … 25 15 </td> 26 16 <td> 27 <!-- paste -->28 17 <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="paste"> 29 18 <span class="dojoE2TBIcon dojoE2TBIcon_Paste"> </span> … … 31 20 </td> 32 21 <td> 33 <!-- undo -->34 22 <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="undo"> 35 23 <!-- FIXME: should we have the text "undo" here? --> … … 38 26 </td> 39 27 <td> 40 <!-- redo -->41 28 <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="redo"> 42 29 <span class="dojoE2TBIcon dojoE2TBIcon_Redo"> </span> … … 44 31 </td> 45 32 <td isSpacer="true"> 46 <!-- spacer -->47 33 <span class="iconContainer"> 48 34 <span class="dojoE2TBIcon dojoE2TBIcon_Sep" style="width: 5px; min-width: 5px;"></span> … … 50 36 </td> 51 37 <td> 52 <!-- link -->53 38 <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="createlink"> 54 39 <span class="dojoE2TBIcon dojoE2TBIcon_Link"> </span> … … 56 41 </td> 57 42 <td> 58 <!-- insertimage -->59 43 <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="insertimage"> 60 44 <span class="dojoE2TBIcon dojoE2TBIcon_Image"> </span> … … 62 46 </td> 63 47 <td> 64 <!-- inserthorizontalrule -->65 48 <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="inserthorizontalrule"> 66 49 <span class="dojoE2TBIcon dojoE2TBIcon_HorizontalLine "> </span> … … 68 51 </td> 69 52 <td> 70 <!-- bold -->71 53 <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="bold"> 72 54 <span class="dojoE2TBIcon dojoE2TBIcon_Bold"> </span> … … 74 56 </td> 75 57 <td> 76 <!-- italic -->77 58 <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="italic"> 78 59 <span class="dojoE2TBIcon dojoE2TBIcon_Italic"> </span> … … 80 61 </td> 81 62 <td> 82 <!-- underline -->83 63 <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="underline"> 84 64 <span class="dojoE2TBIcon dojoE2TBIcon_Underline"> </span> … … 86 66 </td> 87 67 <td> 88 <!-- strikethrough -->89 68 <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="strikethrough"> 90 69 <span … … 93 72 </td> 94 73 <td isSpacer="true"> 95 <!-- spacer -->96 74 <span class="iconContainer"> 97 75 <span class="dojoE2TBIcon dojoE2TBIcon_Sep" … … 100 78 </td> 101 79 <td> 102 <!-- insertunorderedlist -->103 80 <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="insertunorderedlist"> 104 81 <span … … 107 84 </td> 108 85 <td> 109 <!-- insertorderedlist -->110 86 <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="insertorderedlist"> 111 87 <span … … 114 90 </td> 115 91 <td isSpacer="true"> 116 <!-- spacer -->117 92 <span class="iconContainer"> 118 93 <span class="dojoE2TBIcon dojoE2TBIcon_Sep" style="width: 5px; min-width: 5px;"></span> … … 120 95 </td> 121 96 <td> 122 <!-- indent -->123 97 <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="indent"> 124 98 <span class="dojoE2TBIcon dojoE2TBIcon_Indent" … … 127 101 </td> 128 102 <td> 129 <!-- outdent -->130 103 <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="outdent"> 131 104 <span class="dojoE2TBIcon dojoE2TBIcon_Outdent" … … 134 107 </td> 135 108 <td isSpacer="true"> 136 <!-- spacer -->137 109 <span class="iconContainer"> 138 110 <span class="dojoE2TBIcon dojoE2TBIcon_Sep" style="width: 5px; min-width: 5px;"></span> … … 140 112 </td> 141 113 <td> 142 <!-- forecolor -->143 114 <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="forecolor"> 144 115 <span class="dojoE2TBIcon dojoE2TBIcon_TextColor" … … 147 118 </td> 148 119 <td> 149 <!-- hilitecolor -->150 120 <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="hilitecolor"> 151 121 <span class="dojoE2TBIcon dojoE2TBIcon_BackgroundColor" … … 154 124 </td> 155 125 <td isSpacer="true"> 156 <!-- spacer -->157 126 <span class="iconContainer"> 158 127 <span class="dojoE2TBIcon dojoE2TBIcon_Sep" style="width: 5px; min-width: 5px;"></span> … … 160 129 </td> 161 130 <td> 162 <!-- justify left -->163 131 <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="justifyleft"> 164 132 <span class="dojoE2TBIcon dojoE2TBIcon_LeftJustify"> </span> … … 166 134 </td> 167 135 <td> 168 <!-- justify center -->169 136 <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="justifycenter"> 170 137 <span class="dojoE2TBIcon dojoE2TBIcon_CenterJustify"> </span> … … 172 139 </td> 173 140 <td> 174 <!-- justify right -->175 141 <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="justifyright"> 176 142 <span class="dojoE2TBIcon dojoE2TBIcon_RightJustify"> </span> … … 178 144 </td> 179 145 <td> 180 <!-- justify full -->181 146 <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="justifyfull"> 182 147 <span class="dojoE2TBIcon dojoE2TBIcon_BlockJustify"> </span> … … 184 149 </td> 185 150 <td> 186 <!-- font select -->187 151 <select class="dojoEditorToolbarItem" dojoETItemName="plainformatblock"> 188 152 <!-- FIXME: using "p" here inserts a paragraph in most cases! -->