Changeset 6393

Show
Ignore:
Timestamp:
11/01/06 09:24:01 (3 years ago)
Author:
liucougar
Message:

Change Editor2Commands to be per instance, rather than global
Improved toolbar share support
ContextMenu? share support
All plugins are updated
Fixes #1505: two editor instances do not respect the shareToolbar:false flag
Fixes #1799: move EditorToolbarLight?.html to tests dir

Will blog this in dojo.foo soon

Location:
trunk
Files:
2 added
1 removed
10 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/widget/Editor2.js

    r6370 r6393  
    66 
    77// Object: Manager of current focused Editor2 Instance and available editor2 commands 
    8 dojo.widget.Editor2Manager = { 
     8dojo.widget.Editor2Manager = new dojo.widget.HandlerManager; 
     9dojo.lang.mixin(dojo.widget.Editor2Manager, 
     10{ 
    911        _currentInstance: null, 
    10         _loadedCommands: {}, 
    1112 
    1213        // Object: state a command may be in 
     
    2122                this._currentInstance = inst; 
    2223        }, 
    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){ 
    3425                // summary: Return Editor2 command with the given name 
    3526                // name: name of the command (case insensitive) 
     27                var oCommand; 
    3628                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                        } 
    4034                } 
    41  
    4235                switch(name){ 
    4336                        case 'htmltoggle': 
    4437                                //Editor2 natively provide the htmltoggle functionalitity 
    4538                                //and it is treated as a builtin command 
    46                                 oCommand = new dojo.widget.Editor2BrowserCommand(name); 
     39                                oCommand = new dojo.widget.Editor2BrowserCommand(editor, name); 
    4740                                break; 
    4841                        case 'formatblock': 
    49                                 oCommand = new dojo.widget.Editor2FormatBlockCommand(name); 
     42                                oCommand = new dojo.widget.Editor2FormatBlockCommand(editor, name); 
    5043                                break; 
    5144                        case 'anchor': 
    52                                 oCommand = new dojo.widget.Editor2Command(name); 
     45                                oCommand = new dojo.widget.Editor2Command(editor, name); 
    5346                                break; 
    5447 
    5548                        //dialog command 
    5649                        case 'createlink': 
    57                                 oCommand = new dojo.widget.Editor2DialogCommand(name, 
     50                                oCommand = new dojo.widget.Editor2DialogCommand(editor, name, 
    5851                                                {contentFile: "dojo.widget.Editor2Plugin.CreateLinkDialog", 
    5952                                                        contentClass: "Editor2CreateLinkDialog", 
     
    6154                                break; 
    6255                        case 'insertimage': 
    63                                 oCommand = new dojo.widget.Editor2DialogCommand(name, 
     56                                oCommand = new dojo.widget.Editor2DialogCommand(editor, name, 
    6457                                                {contentFile: "dojo.widget.Editor2Plugin.InsertImageDialog", 
    6558                                                        contentClass: "Editor2InsertImageDialog", 
     
    7164                                if((curtInst && curtInst.queryCommandAvailable(name)) || 
    7265                                        (!curtInst && dojo.widget.Editor2.prototype.queryCommandAvailable(name))){ 
    73                                         oCommand = new dojo.widget.Editor2BrowserCommand(name); 
     66                                        oCommand = new dojo.widget.Editor2BrowserCommand(editor, name); 
    7467                                }else{ 
    7568                                        dojo.debug("dojo.widget.Editor2Manager.getCommand: Unknown command "+name); 
     
    7770                                } 
    7871                } 
    79                 this._loadedCommands[name] = oCommand; 
    8072                return oCommand; 
    8173        }, 
     
    8375                // summary: Cleaning up. This is called automatically on page unload. 
    8476                this._currentInstance = null; 
    85                 for(var cmd in this._loadedCommands){ 
    86                         this._loadedCommands[cmd].destory(); 
    87                 } 
     77                dojo.widget.HandlerManager.prototype.destroy.call(this); 
    8878        } 
    89 }; 
     79}); 
    9080 
    9181dojo.addOnUnload(dojo.widget.Editor2Manager, "destroy"); 
     
    9484//              dojo.widget.Editor2Command is the base class for all command in Editor2 
    9585dojo.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; 
    9889                this._name = name; 
    9990        }, 
     
    177168//              in commands 
    178169dojo.lang.declare("dojo.widget.Editor2BrowserCommand", dojo.widget.Editor2Command,  
    179         function(name){ 
     170        function(editor,name){ 
    180171                // summary: Constructor of this class 
    181172                 
     
    187178{ 
    188179                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); 
    193181                }, 
    194182                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; 
    197185                                try{ 
    198                                         if(curInst.queryCommandEnabled(this._name)){ 
    199                                                 if(curInst.queryCommandState(this._name)){ 
    200                                                         return dojo.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; 
    201189                                                }else{ 
    202                                                         return dojo.widget.Editor2Manager.commandState.Enabled; 
     190                                                        this._state = dojo.widget.Editor2Manager.commandState.Enabled; 
    203191                                                } 
    204192                                        }else{ 
    205                                                 return dojo.widget.Editor2Manager.commandState.Disabled; 
     193                                                this._state = dojo.widget.Editor2Manager.commandState.Disabled; 
    206194                                        } 
    207195                                }catch (e) { 
    208196                                        //dojo.debug("exception when getting state for command "+this._name+": "+e); 
    209                                         return dojo.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; 
    213201                }, 
    214202                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){} 
    221206                } 
    222207        } 
     
    350335                        } 
    351336                        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                        } 
    352347                } 
    353348        } 
     
    377372//              the command is executed. 
    378373dojo.lang.declare("dojo.widget.Editor2DialogCommand", dojo.widget.Editor2BrowserCommand, 
    379         function(name, dialogParas){ 
     374        function(editor, name, dialogParas){ 
    380375                this.dialogParas = dialogParas; 
    381376        }, 
     
    396391        } 
    397392}); 
     393 
     394// Object: keeping track of all available share toolbar groups 
     395dojo.widget.Editor2ToolbarGroups = {}; 
    398396 
    399397// summary: 
     
    407405        "dojo.widget.Editor2", 
    408406        dojo.widget.RichText, 
     407        function(){ 
     408                this._loadedCommands={}; 
     409        }, 
    409410        { 
    410411//              // String: url to which save action should send content to 
     
    415416//              closeOnSave: false, 
    416417 
    417                 // Boolean: Whether to share toolbar with other instances of Editor2 
    418                 shareToolbar: false, 
    419418                // Boolean: Whether the toolbar should scroll to keep it in the view 
    420419                toolbarAlwaysVisible: false, 
     
    435434                _htmlEditNode: null, 
    436435 
     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 
    437446                editorOnLoad: function(){ 
    438447                        // summary: 
     
    446455                        } 
    447456 
    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]; 
    459469                                        } 
    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                                } 
    470485                        } 
    471486 
     
    662677                }, 
    663678 
     679                _lastStateTimestamp: 0, 
    664680                onDisplayChanged: function(/*Object*/e){ 
     681                        this._lastStateTimestamp = (new Date()).getTime(); 
    665682                        dojo.widget.Editor2.superclass.onDisplayChanged.call(this,e); 
    666683                        this.updateToolbar(); 
     
    689706                }, 
    690707 
     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                }, 
    691717                // Array: Commands shortcuts. Each element can has up to 3 fields: 
    692718                //              1. String: the name of the command 
     
    702728                        var self = this; 
    703729                        dojo.lang.forEach(this.shortcuts, function(item){ 
    704                                 var cmd = dojo.widget.Editor2Manager.getCommand(item[0]); 
     730                                var cmd = self.getCommand(item[0]); 
    705731                                if(cmd){ 
    706732                                        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  
    11dojo.provide("dojo.widget.Editor2Plugin.ContextMenu"); 
    22 
    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 
    512 
    613dojo.require("dojo.widget.Menu2"); 
    714 
    815dojo.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 
    1120dojo.widget.Editor2Plugin.ContextMenuManager = { 
    1221        menuGroups: ['Generic', 'Link', 'Anchor', 'Image', 'List', 'Table'], 
     22        _contextMenuGroupSets: {}, 
    1323        _registeredGroups: {}, 
     24        _menus: {}, 
    1425        registerGroup: function(name, handler){ 
    1526                if(this._registeredGroups[name]){ 
     
    3344                        case 'Link': 
    3445                        case 'Image': 
    35                                 return new dojo.widget.Editor2Plugin[name+"ContextMenu"](contextmenuplugin); 
     46                                return new dojo.widget.Editor2Plugin[name+"ContextMenuGroup"](contextmenuplugin); 
    3647                        //TODO 
    3748                        case 'Anchor': 
    3849                        case 'List': 
    3950                } 
     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; 
    4074        } 
    4175}; 
    4276 
    4377dojo.declare("dojo.widget.Editor2Plugin.ContextMenu", null, 
    44         function(editor){ 
     78        function(editor, gs){ 
    4579                this.groups = []; 
    4680                this.separators = []; 
     
    4983                this.contextMenu = dojo.widget.createWidget("PopupMenu2", {}); 
    5084                dojo.body().appendChild(this.contextMenu.domNode); 
    51                 this.contextMenu.bindDomNode(this.editor.document.body); 
     85                this.bindEditor(this.editor); 
    5286 
    5387                dojo.event.connect(this.contextMenu, "aboutToShow", this, "aboutToShow"); 
    5488                dojo.event.connect(this.editor, "destroy", this, "destroy"); 
    5589 
    56                 this.setup(); 
     90                this.setup(gs); 
    5791        }, 
    5892        { 
    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){ 
    6197                for(var i in gs){ 
    6298                        var g = dojo.widget.Editor2Plugin.ContextMenuManager.getGroup(gs[i], this); 
     
    100136dojo.widget.defineWidget( 
    101137        "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); 
    116146        }, 
    117147        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                        } 
    123154                } 
    124155        }, 
    125156        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                                } 
    136168                        } 
    137169                } 
     
    145177        } 
    146178}); 
    147 dojo.declare("dojo.widget.Editor2Plugin.SimpleContextMenu", null, 
     179dojo.declare("dojo.widget.Editor2Plugin.SimpleContextMenuGroup", null, 
    148180        function(contextmenuplugin){ 
    149181                this.contextMenu = contextmenuplugin.contextMenu; 
     
    184216        } 
    185217}); 
    186 dojo.declare("dojo.widget.Editor2Plugin.GenericContextMenu", 
    187         dojo.widget.Editor2Plugin.SimpleContextMenu, 
     218dojo.declare("dojo.widget.Editor2Plugin.GenericContextMenuGroup", 
     219        dojo.widget.Editor2Plugin.SimpleContextMenuGroup, 
    188220{ 
    189221        createItems: function(){ 
    190                 this.items.push(dojo.widget.createWidget("Editor2ContextMenuItem", {caption: "Cut", iconClass: "dojoE2TBIcon dojoE2TBIcon_Cut"})); 
    191                 this.items.push(dojo.widget.createWidget("Editor2ContextMenuItem", {caption: "Copy", iconClass: "dojoE2TBIcon dojoE2TBIcon_Copy"})); 
    192                 this.items.push(dojo.widget.createWidget("Editor2ContextMenuItem", {caption: "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}); 
     227dojo.declare("dojo.widget.Editor2Plugin.LinkContextMenuGroup", 
     228        dojo.widget.Editor2Plugin.SimpleContextMenuGroup, 
    197229{ 
    198230        createItems: function(){ 
    199                 this.items.push(dojo.widget.createWidget("Editor2ContextMenuItem", {caption: "Modify Link", command: 'createlink', iconClass: "dojoE2TBIcon dojoE2TBIcon_Link"})); 
    200                 this.items.push(dojo.widget.createWidget("Editor2ContextMenuItem", {caption: "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"})); 
    201233        }, 
    202234        checkVisibility: function(){ 
     
    216248        } 
    217249}); 
    218 dojo.declare("dojo.widget.Editor2Plugin.ImageContextMenu", 
    219         dojo.widget.Editor2Plugin.SimpleContextMenu, 
     250dojo.declare("dojo.widget.Editor2Plugin.ImageContextMenuGroup", 
     251        dojo.widget.Editor2Plugin.SimpleContextMenuGroup, 
    220252{ 
    221253        createItems: function(){ 
    222                 this.items.push(dojo.widget.createWidget("Editor2ContextMenuItem", {caption: "Edit Image", command: 'insertimage', iconClass: "dojoE2TBIcon dojoE2TBIcon_Image"})); 
     254                this.items.push(dojo.widget.createWidget("Editor2ContextMenuItem", {command: 'insertimage', iconClass: "dojoE2TBIcon dojoE2TBIcon_Image"})); 
    223255        }, 
    224256        checkVisibility: function(){ 
  • trunk/src/widget/Editor2Plugin/FindReplace.js

    r5593 r6393  
    1313        }, 
    1414        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() ; 
    3429                        }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"); 
    3631                        } 
     32                }else{ 
     33                        alert("No idea how to search in this browser. Please submit patch if you know."); 
    3734                } 
    3835        } 
    3936}); 
    4037 
    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'); 
     38dojo.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; 
    5968        } 
    60  
    61         return item; 
    6269} 
    63  
    64 dojo.widget.Editor2ToolbarItemManager.registerHandler(dojo.widget.Editor2Plugin.FindReplace); 
     70dojo.widget.Editor2Manager.registerHandler(dojo.widget.Editor2Plugin.FindReplace.getCommand); 
     71dojo.widget.Editor2ToolbarItemManager.registerHandler(dojo.widget.Editor2Plugin.FindReplace.getToolbarItem); 
  • trunk/src/widget/Editor2Plugin/FindReplaceDialog.js

    r6058 r6393  
    1 dojo.provide("dojo.widget.Editor2Plugin.FindReplaceDialog"); 
     1dojo.provide("dojo.widget.Editor2Plugin.FindReplaceDialog"); 
    22 
    33dojo.widget.defineWidget( 
     
    88 
    99        find: function(){ 
    10                 var findcmd = dojo.widget.Editor2Manager.getCommand('find'); 
     10                var curInst = dojo.widget.Editor2Manager.getCurrentInstance(); 
     11                var findcmd = curInst.getCommand('find'); 
    1112                var option = 0; 
    1213         
  • trunk/src/widget/Editor2Plugin/InsertImageDialog.js

    r6188 r6393  
    3434        ok: function(){ 
    3535                var curInst = dojo.widget.Editor2Manager.getCurrentInstance(); 
    36                 var insertcmd = dojo.widget.Editor2Manager.getCommand('inserthtml'); 
     36                var insertcmd = curInst.getCommand('inserthtml'); 
    3737                var option = 0; 
    3838 
  • trunk/src/widget/Editor2Plugin/SimpleSignalCommands.js

    r6188 r6393  
    1919 
    2020dojo.declare("dojo.widget.Editor2Plugin.SimpleSignalCommand", dojo.widget.Editor2Command, 
    21         function(name){ 
     21        function(editor, name){ 
    2222                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);*/ }; 
    2424                } 
    2525        }, 
    2626{ 
    2727        execute: function(){ 
    28                 var curInst = dojo.widget.Editor2Manager.getCurrentInstance(); 
    29  
    30                 if(curInst){ 
    31                         curInst[this._name](); 
    32                 } 
     28                this._editor[this._name](); 
    3329        } 
    3430}); 
     
    4743                } 
    4844        }, 
    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); 
    5356                } 
    5457        } 
     
    5861        dojo.lang.mixin(dojo.widget.Editor2Plugin.SimpleSignalCommands, dojo.widget.Editor2Plugin['_SimpleSignalCommands']); 
    5962} 
    60  
    61 dojo.widget.Editor2Plugin.SimpleSignalCommands.registerAllSignalCommands(); 
     63dojo.widget.Editor2Manager.registerHandler(dojo.widget.Editor2Plugin.SimpleSignalCommands, 'getCommand'); 
    6264dojo.widget.Editor2ToolbarItemManager.registerHandler(dojo.widget.Editor2Plugin.SimpleSignalCommands.Handler); 
  • trunk/src/widget/Editor2Plugin/TableOperation.js

    r6371 r6393  
    77//are executed, so we have to insert our own trick before that point 
    88dojo.event.topic.subscribe("dojo.widget.RichText::init", function(editor){ 
    9         editor.__TableOperationShowBorder = false; 
    10  
    119        if(dojo.render.html.ie){ 
    1210                //add/remove a class to a table with border=0 to show the border when loading/saving 
    1311                editor.contentDomPreFilters.push(dojo.widget.Editor2Plugin.TableOperation.showIETableBorder); 
    1412                editor.contentDomPostFilters.push(dojo.widget.Editor2Plugin.TableOperation.removeIEFakeClass); 
    15                 //include the css file to show table border when border=0 
    16 //              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")); 
    1913        } 
    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 
     18dojo.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 
     40dojo.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        } 
    2374}); 
    2475 
    2576dojo.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        }, 
    2690        getToolbarItem: function(name){ 
    2791                var name = name.toLowerCase(); 
     
    37101        }, 
    38102        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); 
    87104        }, 
    88105        showIETableBorder: function(dom){ 
     
    103120 
    104121//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); 
     122dojo.widget.Editor2Manager.registerHandler(dojo.widget.Editor2Plugin.TableOperation.getCommand); 
    113123 
    114124//register toggletableborder and inserttable as toolbar item 
     
    119129        dojo.widget.Editor2Plugin.ContextMenuManager.registerGroup('Table', dojo.widget.Editor2Plugin.TableOperation.getContextMenuGroup); 
    120130 
    121         dojo.declare("dojo.widget.Editor2Plugin.TableContextMenu", 
    122                 dojo.widget.Editor2Plugin.SimpleContextMenu, 
     131        dojo.declare("dojo.widget.Editor2Plugin.TableContextMenuGroup", 
     132                dojo.widget.Editor2Plugin.SimpleContextMenuGroup, 
    123133        { 
    124134                createItems: function(){ 
  • trunk/src/widget/Editor2Toolbar.js

    r6370 r6393  
    1010dojo.require("dojo.widget.ColorPalette"); 
    1111 
    12 // Object: Manager available editor2 toolbar items 
    13 dojo.widget.Editor2ToolbarItemManager = { 
    14         _registeredItemHandlers: [], 
     12dojo.lang.declare("dojo.widget.HandlerManager", null, 
     13        function(){ 
     14                this._registeredHandlers=[]; 
     15        }, 
     16{ 
    1517        registerHandler: function(/*Object*/obj, /*String*/func){ 
    16                 // summary: register a toolbar item handler 
     18                // summary: register a handler 
    1719                // obj: object which has the function to call 
    1820                // func: the function in the object 
    1921                if(arguments.length == 2){ 
    20                         this._registeredItemHandlers.push(function(){return obj[func].apply(obj, arguments);}); 
     22                        this._registeredHandlers.push(function(){return obj[func].apply(obj, arguments);}); 
    2123                }else{ 
    2224                        /* obj: Function 
    2325                            func: null 
    2426                            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); 
    3228                } 
    3329        }, 
    3430        removeHandler: function(func){ 
    3531                // summary: remove a registered handler 
    36                 for(var i=0;i<this._registeredItemHandlers.length;i++){ 
    37                         if(func === this._registeredItemHandlers[i]){ 
    38                                 delete this._registeredItemHandlers[i]; 
     32                for(var i=0;i<this._registeredHandlers.length;i++){ 
     33                        if(func === this._registeredHandlers[i]){ 
     34                                delete this._registeredHandlers[i]; 
    3935                                return; 
    4036                        } 
    4137                } 
    42                 dojo.debug("Editor2ToolbarItemManager handler "+func+" is not registered, can not remove."); 
     38                dojo.debug("HandlerManager handler "+func+" is not registered, can not remove."); 
    4339        }, 
    4440        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 
     47dojo.widget.Editor2ToolbarItemManager = new dojo.widget.HandlerManager; 
     48dojo.lang.mixin(dojo.widget.Editor2ToolbarItemManager, 
     49{ 
    4950        getToolbarItem: function(/*String*/name){ 
    5051                // summary: return a toobar item with the given name 
    5152                var item; 
    5253                name = name.toLowerCase(); 
    53                 for(var i=0;i<this._registeredItemHandlers.length;i++){ 
    54                         item = this._registeredItemHandlers[i](name); 
     54                for(var i=0;i<this._registeredHandlers.length;i++){ 
     55                        item = this._registeredHandlers[i](name); 
    5556                        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); 
    133132                } 
    134133                return item; 
    135134        } 
    136 }; 
     135}); 
    137136 
    138137dojo.addOnUnload(dojo.widget.Editor2ToolbarItemManager, "destroy"); 
    139138// summary: 
    140139//              dojo.widget.Editor2ToolbarButton is the base class for all toolbar item in Editor2Toolbar 
    141 dojo.declare("dojo.widget.Editor2ToolbarButton", null,{ 
    142         initializer: function(name){ 
     140dojo.declare("dojo.widget.Editor2ToolbarButton", null, 
     141        function(name){ 
    143142                // summary: constructor 
    144143                this._name = name; 
    145                 this._command = dojo.widget.Editor2Manager.getCommand(name); 
    146         }, 
     144//              this._command = editor.getCommand(name); 
     145        }, 
     146{ 
    147147        create: function(/*DomNode*/node, /*dojo.widget.Editor2Toolbar*/toolbar, /*Boolean*/nohover){ 
    148148                // summary: create the item 
     
    151151                // nohover: whether this item in charge of highlight this item 
    152152                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                } 
    154157                //make this unselectable: different browsers 
    155158                //use different properties for this, so use 
    156159                //js do it automatically 
    157160                this.disableSelection(this._domNode); 
     161 
    158162                this._parentToolbar = toolbar; 
    159163                dojo.event.connect(this._domNode, 'onclick', this, 'onClick'); 
     
    172176        }, 
    173177        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                        } 
    176184                } 
    177185        }, 
     
    182190                // summary: destructor 
    183191                this._domNode = null; 
    184                 delete this._command; 
     192//              delete this._command; 
    185193                this._parentToolbar = null; 
    186194        }, 
    187195        onClick: function(e){ 
    188                 if(this._domNode && !this._domNode.disabled && this._command){ 
     196                if(this._domNode && !this._domNode.disabled && this._parentToolbar.checkAvailability()){ 
    189197                        e.preventDefault(); 
    190198                        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                        } 
    192206                } 
    193207        }, 
    194208        refreshState: function(){ 
    195209                // 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; 
    215233        }, 
    216234 
     
    250268 
    251269// summary: dojo.widget.Editor2ToolbarDropDownButton extends the basic button with a dropdown list 
    252 dojo.declare("dojo.widget.Editor2ToolbarDropDownButton", dojo.widget.Editor2ToolbarButton,{ 
     270dojo.declare("dojo.widget.Editor2ToolbarDropDownButton", dojo.widget.Editor2ToolbarButton, function(){}, { 
    253271        onClick: function(){ 
    254                 if(this._domNode){ 
     272                if(this._domNode && !this._domNode.disabled && this._parentToolbar.checkAvailability()){ 
    255273                        if(!this._dropdown){ 
    256274                                this._dropdown = dojo.widget.createWidget("PopupContainer", {}); 
     
    277295 
    278296// summary: dojo.widget.Editor2ToolbarColorPaletteButton provides a dropdown color palette picker 
    279 dojo.declare("dojo.widget.Editor2ToolbarColorPaletteButton", dojo.widget.Editor2ToolbarDropDownButton,{ 
     297dojo.declare("dojo.widget.Editor2ToolbarColorPaletteButton", dojo.widget.Editor2ToolbarDropDownButton, function(){}, { 
    280298        onDropDownShown: function(){ 
    281299                if(!this._colorpalette){ 
     
    296314        setColor: function(color){ 
    297315                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                } 
    299323        } 
    300324}); 
    301325 
    302326// summary: dojo.widget.Editor2ToolbarFormatBlockPlainSelect provides a simple select for setting block format 
    303 dojo.declare("dojo.widget.Editor2ToolbarFormatBlockPlainSelect", dojo.widget.Editor2ToolbarButton,{ 
     327dojo.declare("dojo.widget.Editor2ToolbarFormatBlockPlainSelect", dojo.widget.Editor2ToolbarButton, function(){}, { 
    304328        create: function(node, toolbar){ 
     329                dojo.widget.Editor2ToolbarFormatBlockPlainSelect.superclass.create.apply(this, arguments); 
    305330                //TODO: check node is a select 
    306331                this._domNode = node; 
    307332                this.disableSelection(this._domNode); 
    308                 this._parentToolbar = toolbar; 
    309333                dojo.event.connect(this._domNode, 'onchange', this, 'onChange'); 
    310334        }, 
     
    312336        destroy: function(){ 
    313337                this._domNode = null; 
    314                 this._command = null; 
    315                 this._parentToolbar = null; 
    316338        }, 
    317339 
    318340        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(){ 
    319354                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){ 
    327355                        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                        } 
    335369                } 
    336370        } 
     
    338372 
    339373// summary: dojo.widget.Editor2ToolbarComboItem provides an external loaded dropdown list 
    340 dojo.declare("dojo.widget.Editor2ToolbarComboItem", dojo.widget.Editor2ToolbarDropDownButton,{ 
     374dojo.declare("dojo.widget.Editor2ToolbarComboItem", dojo.widget.Editor2ToolbarDropDownButton, function(){}, { 
    341375        href: null, 
    342376        create: function(node, toolbar){ 
    343                 dojo.widget.Editor2ToolbarComboItem.superclass.create.call(this, node, toolbar); 
     377                dojo.widget.Editor2ToolbarComboItem.superclass.create.apply(this, arguments); 
    344378                //do not use lazy initilization, as we need the local names in refreshState() 
    345379                if(!this._contentPane){ 
     
    370404 
    371405        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                } 
    374416                this._dropdown.close(); 
    375417        }, 
     
    389431 
    390432// summary: dojo.widget.Editor2ToolbarFormatBlockSelect is an improved format block setting item 
    391 dojo.declare("dojo.widget.Editor2ToolbarFormatBlockSelect", dojo.widget.Editor2ToolbarComboItem,{ 
     433dojo.declare("dojo.widget.Editor2ToolbarFormatBlockSelect", dojo.widget.Editor2ToolbarComboItem, function(){}, { 
    392434        href: dojo.uri.dojoUri("src/widget/templates/Editor2/EditorToolbar_FormatBlock.html"), 
    393435 
     
    425467 
    426468        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                                                } 
    442487                                        } 
    443                                 } 
    444                                 if(!isSet){ 
    445                                         label.innerHTML = "&nbsp;"; 
     488                                        if(!isSet){ 
     489                                                label.innerHTML = "&nbsp;"; 
     490                                        } 
    446491                                } 
    447492                        } 
     
    451496 
    452497// summary: dojo.widget.Editor2ToolbarFontSizeSelect provides a dropdown list for setting fontsize 
    453 dojo.declare("dojo.widget.Editor2ToolbarFontSizeSelect", dojo.widget.Editor2ToolbarComboItem,{ 
     498dojo.declare("dojo.widget.Editor2ToolbarFontSizeSelect", dojo.widget.Editor2ToolbarComboItem, function(){}, { 
    454499        href: dojo.uri.dojoUri("src/widget/templates/Editor2/EditorToolbar_FontSize.html"), 
    455500 
     
    486531 
    487532        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                                                } 
    503551                                        } 
    504                                 } 
    505                                 if(!isSet){ 
    506                                         label.innerHTML = "&nbsp;"; 
     552                                        if(!isSet){ 
     553                                                label.innerHTML = "&nbsp;"; 
     554                                        } 
    507555                                } 
    508556                        } 
     
    512560 
    513561// summary: dojo.widget.Editor2ToolbarFontNameSelect provides a dropdown list for setting fontname 
    514 dojo.declare("dojo.widget.Editor2ToolbarFontNameSelect", dojo.widget.Editor2ToolbarFontSizeSelect,{ 
     562dojo.declare("dojo.widget.Editor2ToolbarFontNameSelect", dojo.widget.Editor2ToolbarFontSizeSelect, function(){}, { 
    515563        href: dojo.uri.dojoUri("src/widget/templates/Editor2/EditorToolbar_FontName.html") 
    516564}); 
     
    524572                templatePath: dojo.uri.dojoUri("src/widget/templates/EditorToolbar.html"), 
    525573                templateCssPath: dojo.uri.dojoUri("src/widget/templates/EditorToolbar.css"), 
    526  
    527                 // DOM Nodes 
    528 //              saveButton: null, 
    529574 
    530575                // String: class name for latched toolbar button items 
     
    570615                }, 
    571616 
     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                }, 
    572635                destroy: function(){ 
    573636                        for(var it in this.items){ 
  • trunk/src/widget/RichText.js

    r6356 r6393  
    4040                // Boolean: 
    4141                //              whether focusing into this instance of richtext when page onload 
    42                 focusOnLoad: true, 
     42                focusOnLoad: false, 
    4343 
    4444                // String: 
     
    639639                        //              remove an external stylesheet for the editing area 
    640640                        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                        } 
    641645                        var index = dojo.lang.find(this.editingAreaStyleSheets, url); 
    642646                        if(index == -1){ 
  • trunk/src/widget/templates/EditorToolbarOneline.html

    r6371 r6393  
    44                        <tr valign="top" align="left"> 
    55                                <td> 
    6                                         <!-- htmltoggle --> 
    76                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="htmltoggle"> 
    87                                                <span class="dojoE2TBIcon"  
     
    109                                        </span> 
    1110                                </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">&nbsp;</span> 
    18                                         </span> 
    19                                 </td--> 
    2011                                <td> 
    21                                         <!-- copy --> 
    2212                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="copy"> 
    2313                                                <span class="dojoE2TBIcon dojoE2TBIcon_Copy">&nbsp;</span> 
     
    2515                                </td> 
    2616                                <td> 
    27                                         <!-- paste --> 
    2817                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="paste"> 
    2918                                                <span class="dojoE2TBIcon dojoE2TBIcon_Paste">&nbsp;</span> 
     
    3120                                </td> 
    3221                                <td> 
    33                                         <!-- undo --> 
    3422                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="undo"> 
    3523                                                <!-- FIXME: should we have the text "undo" here? --> 
     
    3826                                </td> 
    3927                                <td> 
    40                                         <!-- redo --> 
    4128                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="redo"> 
    4229                                                <span class="dojoE2TBIcon dojoE2TBIcon_Redo">&nbsp;</span> 
     
    4431                                </td> 
    4532                                <td isSpacer="true"> 
    46                                         <!-- spacer --> 
    4733                                        <span class="iconContainer"> 
    4834                                                <span class="dojoE2TBIcon dojoE2TBIcon_Sep"     style="width: 5px; min-width: 5px;"></span> 
     
    5036                                </td> 
    5137                                <td> 
    52                                         <!-- link --> 
    5338                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="createlink"> 
    5439                                                <span class="dojoE2TBIcon dojoE2TBIcon_Link">&nbsp;</span> 
     
    5641                                </td> 
    5742                                <td> 
    58                                         <!-- insertimage --> 
    5943                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="insertimage"> 
    6044                                                <span class="dojoE2TBIcon dojoE2TBIcon_Image">&nbsp;</span> 
     
    6246                                </td> 
    6347                                <td> 
    64                                         <!-- inserthorizontalrule --> 
    6548                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="inserthorizontalrule"> 
    6649                                                <span class="dojoE2TBIcon dojoE2TBIcon_HorizontalLine ">&nbsp;</span> 
     
    6851                                </td> 
    6952                                <td> 
    70                                         <!-- bold --> 
    7153                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="bold"> 
    7254                                                <span class="dojoE2TBIcon dojoE2TBIcon_Bold">&nbsp;</span> 
     
    7456                                </td> 
    7557                                <td> 
    76                                         <!-- italic --> 
    7758                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="italic"> 
    7859                                                <span class="dojoE2TBIcon dojoE2TBIcon_Italic">&nbsp;</span> 
     
    8061                                </td> 
    8162                                <td> 
    82                                         <!-- underline --> 
    8363                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="underline"> 
    8464                                                <span class="dojoE2TBIcon dojoE2TBIcon_Underline">&nbsp;</span> 
     
    8666                                </td> 
    8767                                <td> 
    88                                         <!-- strikethrough --> 
    8968                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="strikethrough"> 
    9069                                                <span  
     
    9372                                </td> 
    9473                                <td isSpacer="true"> 
    95                                         <!-- spacer --> 
    9674                                        <span class="iconContainer"> 
    9775                                                <span class="dojoE2TBIcon dojoE2TBIcon_Sep"  
     
    10078                                </td> 
    10179                                <td> 
    102                                         <!-- insertunorderedlist --> 
    10380                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="insertunorderedlist"> 
    10481                                                <span  
     
    10784                                </td> 
    10885                                <td> 
    109                                         <!-- insertorderedlist --> 
    11086                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="insertorderedlist"> 
    11187                                                <span  
     
    11490                                </td> 
    11591                                <td isSpacer="true"> 
    116                                         <!-- spacer --> 
    11792                                        <span class="iconContainer"> 
    11893                                                <span class="dojoE2TBIcon dojoE2TBIcon_Sep" style="width: 5px; min-width: 5px;"></span> 
     
    12095                                </td> 
    12196                                <td> 
    122                                         <!-- indent --> 
    12397                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="indent"> 
    12498                                                <span class="dojoE2TBIcon dojoE2TBIcon_Indent"  
     
    127101                                </td> 
    128102                                <td> 
    129                                         <!-- outdent --> 
    130103                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="outdent"> 
    131104                                                <span class="dojoE2TBIcon dojoE2TBIcon_Outdent"  
     
    134107                                </td> 
    135108                                <td isSpacer="true"> 
    136                                         <!-- spacer --> 
    137109                                        <span class="iconContainer"> 
    138110                                                <span class="dojoE2TBIcon dojoE2TBIcon_Sep" style="width: 5px; min-width: 5px;"></span> 
     
    140112                                </td> 
    141113                                <td> 
    142                                         <!-- forecolor --> 
    143114                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="forecolor"> 
    144115                                                <span class="dojoE2TBIcon dojoE2TBIcon_TextColor"  
     
    147118                                </td> 
    148119                                <td> 
    149                                         <!-- hilitecolor --> 
    150120                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="hilitecolor"> 
    151121                                                <span class="dojoE2TBIcon dojoE2TBIcon_BackgroundColor"  
     
    154124                                </td> 
    155125                                <td isSpacer="true"> 
    156                                         <!-- spacer --> 
    157126                                        <span class="iconContainer"> 
    158127                                                <span class="dojoE2TBIcon dojoE2TBIcon_Sep" style="width: 5px; min-width: 5px;"></span> 
     
    160129                                </td> 
    161130                                <td> 
    162                                         <!-- justify left --> 
    163131                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="justifyleft"> 
    164132                                                <span class="dojoE2TBIcon dojoE2TBIcon_LeftJustify">&nbsp;</span> 
     
    166134                                </td> 
    167135                                <td> 
    168                                         <!-- justify center --> 
    169136                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="justifycenter"> 
    170137                                                <span class="dojoE2TBIcon dojoE2TBIcon_CenterJustify">&nbsp;</span> 
     
    172139                                </td> 
    173140                                <td> 
    174                                         <!-- justify right --> 
    175141                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="justifyright"> 
    176142                                                <span class="dojoE2TBIcon dojoE2TBIcon_RightJustify">&nbsp;</span> 
     
    178144                                </td> 
    179145                                <td> 
    180                                         <!-- justify full --> 
    181146                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="justifyfull"> 
    182147                                                <span class="dojoE2TBIcon dojoE2TBIcon_BlockJustify">&nbsp;</span> 
     
    184149                                </td>    
    185150                                <td> 
    186                                         <!-- font select --> 
    187151                                        <select class="dojoEditorToolbarItem" dojoETItemName="plainformatblock"> 
    188152                                                <!-- FIXME: using "p" here inserts a paragraph in most cases! -->