Changeset 5306

Show
Ignore:
Timestamp:
08/17/06 17:40:21 (3 years ago)
Author:
liucougar
Message:

new editor2 arrived, finally. expect a long changelog below:
fix #1046 Extensible commands in Editor2 and Editor2Toolbar
fix #1042 FormatBlock? of Editor2 in ActiveX mode does not work
fix #1280 inserttable improvements
fix #356 font size adjustment would be an essential addition to the Dojo Editor
fix #1067 Positioning of the color selection pallet, invoked from EDITOR toolbar,when "Editor" is placed in the lower part of the scrollable page
fixe #1114 [patch] Editor2, shared floating Toolbar and MSIE
(reviewed by Paul)

Location:
trunk/src/widget
Files:
20 added
5 modified

Legend:

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

    r5180 r5306  
    77dojo.require("dojo.html.*"); 
    88dojo.require("dojo.html.layout"); 
    9 dojo.require("dojo.html.iframe"); 
    109dojo.require("dojo.widget.*"); 
    1110dojo.require("dojo.widget.RichText"); 
    1211dojo.require("dojo.widget.Editor2Toolbar"); 
     12 
    1313// dojo.require("dojo.widget.ColorPalette"); 
    1414// dojo.require("dojo.string.extras"); 
    1515 
    16 //The current focused Editor2 Instance 
    17 dojo.widget.Editor2._CurrentInstance = null; 
     16//API to manage current focused Editor2 Instance 
     17dojo.widget.Editor2Manager = { 
     18        //private variables 
     19        _currentInstance: null, 
     20        _loadedCommands: {}, 
     21 
     22        destroy: function(){ 
     23                this._currentInstance = null; 
     24                for(var cmd in this._loadedCommands){ 
     25                        this._loadedCommands[cmd].destory(); 
     26                } 
     27        }, 
     28 
     29        commandState: {Disabled: 0, Latched: 1, Enabled: 2}, 
     30        //Public API 
     31        getCurrentInstance: function(){ 
     32                return this._currentInstance; 
     33        }, 
     34        setCurrentInstance: function(inst){ 
     35                this._currentInstance = inst; 
     36        }, 
     37        registerCommand: function(name, cmd){ 
     38                name = name.toLowerCase(); 
     39                if(this._loadedCommands[name]){ 
     40                        delete this._loadedCommands[name]; 
     41                } 
     42                this._loadedCommands[name] = cmd; 
     43        }, 
     44        getCommand: function(name){ 
     45                name = name.toLowerCase(); 
     46                var oCommand = this._loadedCommands[name]; 
     47                if(oCommand){ 
     48                        return oCommand; 
     49                } 
     50 
     51                switch(name){ 
     52                        case 'htmltoggle': 
     53                                //Editor2 natively provide the htmltoggle functionalitity 
     54                                //and it is treated as a builtin command  
     55                                oCommand = new dojo.widget.Editor2BrowserCommand(name); 
     56                                break; 
     57                        case 'formatblock': 
     58                                oCommand = new dojo.widget.Editor2FormatBlockCommand(name); 
     59                                break; 
     60                        case 'anchor': 
     61                                oCommand = new dojo.widget.Editor2Command(name); 
     62                                break; 
     63 
     64                        //dialog command 
     65                        case 'createlink': 
     66                                oCommand = new dojo.widget.Editor2DialogCommand(name,  
     67                                                {href: dojo.uri.dojoUri("src/widget/templates/Editor2/Dialog/createlink.html"),  
     68                                                        title: "Insert/Edit Link", width: "300px", height: "200px"}); 
     69                                break; 
     70                        case 'insertimage': 
     71                                oCommand = new dojo.widget.Editor2DialogCommand(name,  
     72                                                {href: dojo.uri.dojoUri("src/widget/templates/Editor2/Dialog/insertimage.html"),  
     73                                                        title: "Insert/Edit Image", width: "400px", height: "270px"}); 
     74                                break; 
     75                        // By default we assume that it is a builtin simple command. 
     76                        default: 
     77                                var curtInst = this.getCurrentInstance(); 
     78                                if((curtInst && curtInst.queryCommandAvailable(name)) || 
     79                                        (!curtInst && dojo.widget.Editor2.prototype.queryCommandAvailable(name))){ 
     80                                        oCommand = new dojo.widget.Editor2BrowserCommand(name); 
     81                                }else{ 
     82                                        dojo.debug("dojo.widget.Editor2Manager.getCommand: Unknown command "+name); 
     83                                        return; 
     84                                } 
     85                } 
     86                this._loadedCommands[name] = oCommand; 
     87                return oCommand; 
     88        }//, 
     89//      registerPerInstancePlugin: function(name){ 
     90//              if(!this._perInstancePlugins){ this._perInstancePlugins = []; } 
     91//              this._perInstancePlugins.push(name); 
     92//      }, 
     93//      getPlugin: function(pluginname, editor){ 
     94//              dojo.require(pluginname); 
     95//              if(dojo.lang.find(this._perInstancePlugins, pluginname) != -1){ 
     96//                      var plugin = dojo.evalObjPath(pluginname); 
     97//                      return new plugin(editor); 
     98//              } 
     99//              return null; 
     100//      } 
     101}; 
     102 
     103dojo.addOnUnload(dojo.widget.Editor2Manager, "destroy"); 
     104 
     105/* base class for all command in Editor2 */ 
     106dojo.lang.declare("dojo.widget.Editor2Command",null,{ 
     107                initializer: function(name){ 
     108                        this._name = name; 
     109                }, 
     110                //this function should be re-implemented in subclass 
     111                execute: function(para){ 
     112                        alert("Please implement your own execute() function for subclass of Editor2Command."); 
     113                }, 
     114                //default implemetation always returns Enabled 
     115                getState: function(){ 
     116                        return dojo.widget.Editor2Manager.commandState.Enabled; 
     117                }, 
     118                destory: function(){} 
     119        } 
     120); 
     121 
     122dojo.lang.declare("dojo.widget.Editor2BrowserCommand", dojo.widget.Editor2Command, { 
     123                execute: function(para){ 
     124                        var curInst = dojo.widget.Editor2Manager.getCurrentInstance(); 
     125                        if(curInst){ 
     126                                dojo.debug("execute "+this._name); 
     127                                curInst.execCommand(this._name, para); 
     128                        } 
     129                }, 
     130                getState: function(){ 
     131                        var curInst = dojo.widget.Editor2Manager.getCurrentInstance(); 
     132                        if(curInst){ 
     133                                try{ 
     134                                        if(curInst.queryCommandEnabled(this._name)){ 
     135                                                if(curInst.queryCommandState(this._name)){ 
     136                                                        return dojo.widget.Editor2Manager.commandState.Latched; 
     137                                                }else{ 
     138                                                        return dojo.widget.Editor2Manager.commandState.Enabled; 
     139                                                } 
     140                                        }else{ 
     141                                                return dojo.widget.Editor2Manager.commandState.Disabled; 
     142                                        } 
     143                                }catch (e) { 
     144                                        //dojo.debug("exception when getting state for command "+this._name+": "+e); 
     145                                        return dojo.widget.Editor2Manager.commandState.Enabled; 
     146                                } 
     147                        } 
     148                        return dojo.widget.Editor2Manager.commandState.Disabled; 
     149                }, 
     150                getValue: function(){ 
     151                        var curInst = dojo.widget.Editor2Manager.getCurrentInstance(); 
     152                        if(curInst){ 
     153                                try{ 
     154                                        return curInst.queryCommandValue(this._name); 
     155                                }catch(e){} 
     156                        } 
     157                } 
     158        } 
     159); 
     160 
     161dojo.lang.declare("dojo.widget.Editor2FormatBlockCommand", dojo.widget.Editor2BrowserCommand, { 
     162                /* In none-ActiveX mode under IE, <p> and no <p> text can not be distinguished 
     163                getCurrentValue: function(){ 
     164                        var curInst = dojo.widget.Editor2Manager.getCurrentInstance(); 
     165                        if(!curInst){ return ''; } 
     166 
     167                        var h = dojo.render.html; 
     168                         
     169                        // safari f's us for selection primitives 
     170                        if(h.safari){ return ''; } 
     171 
     172                        var selectedNode = (h.ie) ? curInst.document.selection.createRange().parentElement() : curInst.window.getSelection().anchorNode; 
     173                        // make sure we actuall have an element 
     174                        while((selectedNode)&&(selectedNode.nodeType != 1)){ 
     175                                selectedNode = selectedNode.parentNode; 
     176                        } 
     177                        if(!selectedNode){ return ''; } 
     178 
     179                        var formats = ["p", "pre", "h1", "h2", "h3", "h4", "h5", "h6", "address"]; 
     180                        // gotta run some specialized updates for the various 
     181                        // formatting options 
     182                        var type = formats[dojo.lang.find(formats, selectedNode.nodeName.toLowerCase())]; 
     183                        while((selectedNode!=curInst.editNode)&&(!type)){ 
     184                                selectedNode = selectedNode.parentNode; 
     185                                if(!selectedNode){ break; } 
     186                                type = formats[dojo.lang.find(formats, selectedNode.nodeName.toLowerCase())]; 
     187                        } 
     188                        if(!type){ 
     189                                type = ""; 
     190                        } 
     191                        return type; 
     192                }*/ 
     193        } 
     194); 
     195 
     196dojo.require("dojo.widget.FloatingPane"); 
     197dojo.widget.defineWidget( 
     198        "dojo.widget.Editor2Dialog", 
     199        [dojo.widget.FloatingPane, dojo.widget.ModalDialogBase], 
     200        { 
     201                modal: true, 
     202                templatePath: dojo.uri.dojoUri("src/widget/templates/Editor2/EditorDialog.html"), 
     203                executeScripts: true, 
     204                refreshOnShow: true, //for debug for now 
     205 
     206                width: false, 
     207                height: false, 
     208 
     209                windowState: "minimized", 
     210                displayCloseAction: true, 
     211 
     212                postCreate: function(){ 
     213                        if(this.modal){ 
     214                                dojo.widget.ModalDialogBase.prototype.postCreate.call(this); 
     215                        }else{ 
     216                                with(this.domNode.style) { 
     217                                        zIndex = 999; 
     218                                        display = "none"; 
     219                                } 
     220//                              dojo.body().appendChild(this.domNode); 
     221                        } 
     222                        dojo.widget.Editor2Dialog.superclass.postCreate.call(this); 
     223                        if(this.width && this.height){ 
     224                                with(this.domNode.style){ 
     225                                        width = this.width; 
     226                                        height = this.height; 
     227                                } 
     228                        } 
     229                }, 
     230                show: function(){ 
     231                        dojo.widget.Editor2Dialog.superclass.show.apply(this, arguments); 
     232                        if(this.modal){ 
     233                                dojo.widget.ModalDialogBase.prototype.show.call(this); 
     234                        } 
     235                        this.placeModalDialog(); 
     236                        if(this.modal){ 
     237                                //place the background div under this modal pane 
     238                                this.shared.bg.style.zIndex = this.domNode.style.zIndex-1; 
     239                        } 
     240                }, 
     241                closeWindow: function(){ 
     242                        this.hide(); 
     243                        dojo.widget.Editor2Dialog.superclass.closeWindow.apply(this, arguments); 
     244                }, 
     245                hide: function(){ 
     246                        if(this.modal){ 
     247                                dojo.widget.ModalDialogBase.prototype.hide.call(this); 
     248                        }else{ 
     249                                dojo.widget.Editor2Dialog.superclass.hide.call(this); 
     250                        } 
     251                } 
     252        } 
     253); 
     254 
     255dojo.lang.declare("dojo.widget.Editor2DialogCommand", dojo.widget.Editor2BrowserCommand,  
     256        function(name, dialogParas){ 
     257                this.dialogParas = dialogParas; 
     258        }, 
     259{ 
     260        execute: function(){ 
     261                if(!this.dialog){ 
     262                        if(!this.dialogParas.href){ 
     263                                alert("Href should be set for dojo.widget.Editor2DialogCommand.dialogParas!"); 
     264                                return; 
     265                        } 
     266                        this.dialog = dojo.widget.createWidget("Editor2Dialog", this.dialogParas); 
     267 
     268                        dojo.body().appendChild(this.dialog.domNode); 
     269 
     270                        dojo.event.connect(this, "destroy", this.dialog, "destroy"); 
     271                } 
     272                this.dialog.show(); 
     273        } 
     274}); 
     275/ 
     276//uncomment these plugins to enable them 
     277//dojo.require("dojo.widget.Editor2Plugin.FindReplace"); 
     278 
     279//ContextMenu plugin should come before all other plugins which support 
     280//contextmenu, otherwise the menu for that plugin won't be shown 
     281dojo.require("dojo.widget.Editor2Plugin.ContextMenu"); 
     282//dojo.require("dojo.widget.Editor2Plugin.TableOperation"); 
     283//dojo.require("dojo.widget.Editor2Plugin.ToolbarDndSupport"); 
    18284 
    19285dojo.widget.defineWidget( 
     
    28294                toolbarAlwaysVisible: false, 
    29295                htmlEditing: false, 
    30                 _inHtmlMode: false, 
     296                _inSourceMode: false, 
    31297                _htmlEditNode: null, 
    32298 
    33                 commandList: dojo.widget.Editor2Toolbar.prototype.commandList, 
    34299                toolbarWidget: null, 
    35300                scrollInterval: null, 
    36                 toolbarTemplatePath: null, 
    37                  
     301                toolbarTemplatePath: "src/widget/templates/Editor2/EditorToolbarFCKStyle.html", 
     302                toolbarTemplateCssPath: "src/widget/templates/Editor2/FCKDefault/EditorToolbarFCKStyle.css", 
     303 
     304                plugins: "", 
    38305 
    39306                editorOnLoad: function(){ 
     307                        dojo.profile.start("dojo.widget.Editor2::editorOnLoad"); 
     308 
     309                        dojo.event.topic.publish("dojo.widget.Editor2::preLoadingToolbar", this); 
     310                        if(this.toolbarAlwaysVisible){ 
     311                                dojo.require("dojo.widget.Editor2Plugin.AlwaysShowToolbar"); 
     312                        } 
     313 
    40314                        var toolbars = dojo.widget.byType("Editor2Toolbar"); 
    41315                        if((!toolbars.length)||(!this.shareToolbar)){ 
     
    43317                                this.toolbarTemplatePath = this.toolbarTemplatePath || "src/widget/templates/EditorToolbarOneline.html"; 
    44318                                tbOpts.templatePath = dojo.uri.dojoUri(this.toolbarTemplatePath); 
     319                                if(this.toolbarTemplateCssPath){ 
     320                                        tbOpts.templateCssPath = this.toolbarTemplateCssPath; 
     321                                } 
    45322                                if(this.toolbarWidget){ 
    46323                                        this.toolbarWidget.show(); 
     
    50327                                        dojo.event.connect(this, "close", this.toolbarWidget, "hide"); 
    51328                                        dojo.event.connect(this, "destroy", this.toolbarWidget, "destroy"); 
    52                                         this.toolbarWidget.hideUnusableButtons(this); 
    53                                 } 
    54  
    55                                 if(this.object){ 
    56                                         this.tbBgIframe = new dojo.html.BackgroundIframe(this.toolbarWidget.domNode); 
    57                                         this.tbBgIframe.iframe.style.height = "30px"; 
    58                                 } 
    59  
    60                                 // need to set position fixed to wherever this thing has landed 
    61                                 if(this.toolbarAlwaysVisible){ 
    62                                         var src = document.documentElement||window; 
    63                                         this.scrollInterval = setInterval(dojo.lang.hitch(this, "globalOnScrollHandler"), 100); 
    64                                         // dojo.event.connect(src, "onscroll", this, "globalOnScrollHandler"); 
    65                                         dojo.event.connect("before", this, "destroyRendering", this, "unhookScroller"); 
    66                                 } 
     329                                } 
     330 
     331                                this.toolbarLoaded(); 
    67332                        }else{ 
    68                                 // FIXME:       should we try harder to explicitly manage focus in 
    69                                 //                      order to prevent too many editors from all querying 
    70                                 //                      for button status concurrently? 
    71333                                // FIXME:       selecting in one shared toolbar doesn't clobber 
    72334                                //                      selection in the others. This is problematic. 
    73335                                this.toolbarWidget = toolbars[0]; 
    74336                        } 
     337 
    75338                        dojo.event.topic.registerPublisher("Editor2.clobberFocus", this, "clobberFocus"); 
    76339                        dojo.event.topic.subscribe("Editor2.clobberFocus", this, "setBlur"); 
    77                         dojo.event.connect(this.toolbarWidget.linkButton, "onclick",  
    78                                 dojo.lang.hitch(this, function(){ 
    79                                         var range; 
    80                                         if(this.document.selection){ 
    81                                                 range = this.document.selection.createRange().text; 
    82                                         }else if(dojo.render.html.mozilla){ 
    83                                                 range = this.window.getSelection().toString(); 
    84                                         } 
    85                                         if(range.length){ 
    86                                                 this.toolbarWidget.exec("createlink",  
    87                                                         prompt("Please enter the URL of the link:", "http://")); 
    88                                         }else{ 
    89                                                 alert("Please select text to link"); 
    90                                         } 
    91                                 }) 
    92                         ); 
    93  
    94                         dojo.event.connect(this.toolbarWidget, "formatSelectClick", this, "focus"); 
    95                         dojo.event.connect(this.toolbarWidget, "saveClick", this, "save"); 
    96                         dojo.event.connect(this.toolbarWidget, "insertimageClick", this, "insertImage"); 
    97                         dojo.event.connect(this, "execCommand", this, "focus"); 
    98  
    99                         if(this.htmlEditing){ 
    100                                 var tb = this.toolbarWidget.htmltoggleButton; 
    101                                 if(tb){ 
    102                                         tb.style.display = ""; 
    103                                         dojo.event.connect(this.toolbarWidget, "htmltoggleClick", 
    104                                                                                 this, "toggleHtmlEditing"); 
    105                                 } 
     340 
     341                        dojo.event.topic.publish("dojo.widget.Editor2::onLoad", this); 
     342                        dojo.profile.end("dojo.widget.Editor2::editorOnLoad"); 
     343                }, 
     344 
     345                //event for plugins to use 
     346                toolbarLoaded: function(){}, 
     347 
     348                registerLoadedPlugin: function(/*Object*/obj){ 
     349                        if(!this.loadedPlugins){ 
     350                                this.loadedPlugins = []; 
     351                        } 
     352                        this.loadedPlugins.push(obj); 
     353                }, 
     354                unregisterLoadedPlugin: function(/*Object*/obj){ 
     355                        for(var i in this.loadedPlugins){ 
     356                                if(this.loadedPlugins[i] === obj){ 
     357                                        delete this.loadedPlugins[i]; 
     358                                        return; 
     359                                } 
     360                        } 
     361                        dojo.debug("dojo.widget.Editor2.unregisterLoadedPlugin: unknow plugin object: "+obj); 
     362                }, 
     363                //override the default one to provide extra commands 
     364                execCommand: function(command, argument){ 
     365                        switch(command.toLowerCase()){ 
     366                                case 'htmltoggle': 
     367                                        this.toggleHtmlEditing(); 
     368                                        break; 
     369                                default: 
     370                                        dojo.widget.Editor2.superclass.execCommand.call(this, command, argument); 
     371                        } 
     372                }, 
     373                queryCommandEnabled: function(command, argument){ 
     374                        switch(command.toLowerCase()){ 
     375                                case 'htmltoggle': 
     376                                        return true; 
     377                                default: 
     378                                        if(this._inSourceMode){ return false;} 
     379                                        return dojo.widget.Editor2.superclass.queryCommandEnabled.call(this, command, argument); 
     380                        } 
     381                }, 
     382                queryCommandState: function(command, argument){ 
     383                        switch(command.toLowerCase()){ 
     384                                case 'htmltoggle': 
     385                                        return this._inSourceMode; 
     386                                default: 
     387                                        return dojo.widget.Editor2.superclass.queryCommandState.call(this, command, argument); 
     388                        } 
     389                }, 
     390 
     391                onClick: function(e){ 
     392                        dojo.widget.Editor2.superclass.onClick.call(this, e); 
     393                        //if Popup is used, call dojo.widget.PopupManager.onClick 
     394                        //manually when click in the editing area to close all 
     395                        //open popups (dropdowns)  
     396                        if(dojo.widget.PopupManager){ 
     397                                if(!e){ //IE 
     398                                        e = this.window.event; 
     399                                } 
     400                                dojo.widget.PopupManager.onClick(e); 
    106401                        } 
    107402                }, 
     
    111406                insertImage: function(){ dojo.debug("Editor2.insertImage"); }, 
    112407                toggleHtmlEditing: function(){ 
    113                         if(this===dojo.widget.Editor2._CurrentInstance){ 
    114                                 if(!this._inHtmlMode){ 
    115                                         this._inHtmlMode = true; 
    116                                         this.toolbarWidget.highlightButton("htmltoggle"); 
     408                        if(this===dojo.widget.Editor2Manager.getCurrentInstance()){ 
     409                                if(!this._inSourceMode){ 
     410                                        this._inSourceMode = true; 
     411 
    117412                                        if(!this._htmlEditNode){ 
    118                                                 this._htmlEditNode = document.createElement("textarea"); 
     413                                                this._htmlEditNode = dojo.doc().createElement("textarea"); 
    119414                                                dojo.html.insertBefore(this._htmlEditNode, this.domNode); 
    120415                                        } 
     
    123418                                        this._htmlEditNode.style.height = dojo.html.getBorderBox(this.editNode).height+"px"; 
    124419                                        this._htmlEditNode.value = this.editNode.innerHTML; 
    125                                         this.domNode.style.display = "none"; 
     420 
     421                                        with(this.domNode.style){ 
     422                                                if(this.object){ 
     423                                                        //activeX object doesn't like to be hidden, so move it outside of screen instead 
     424                                                        position = "absolute"; 
     425                                                        left = "-2000px"; 
     426                                                        top = "-2000px"; 
     427                                                }else{ 
     428                                                        display = "none"; 
     429                                                } 
     430                                        } 
    126431                                }else{ 
    127                                         this._inHtmlMode = false; 
    128                                         this.domNode.style.display = ""; 
    129                                         this.toolbarWidget.unhighlightButton("htmltoggle"); 
     432                                        this._inSourceMode = false; 
     433 
     434                                        //In IE activeX mode, if _htmlEditNode is focused, 
     435                                        //when toggling, an error would occur, so unfocus it 
     436                                        this._htmlEditNode.blur(); 
     437 
     438                                        with(this.domNode.style){ 
     439                                                if(this.object){ 
     440                                                        position = ""; 
     441                                                        left = ""; 
     442                                                        top = ""; 
     443                                                }else{ 
     444                                                        display = ""; 
     445                                                } 
     446                                        } 
     447 
    130448                                        dojo.lang.setTimeout(this, "replaceEditorContent", 1, this._htmlEditNode.value); 
    131449                                        this._htmlEditNode.style.display = "none"; 
    132                                         this.editNode.focus(); 
    133                                 } 
     450                                        this.focus(); 
     451                                } 
     452                                this.updateToolbar(true); 
    134453                        } 
    135454                }, 
    136455 
    137456                setFocus: function(){ 
    138                         if(dojo.widget.Editor2._CurrentInstance == this){ return; } 
    139  
    140                         if(this.toolbarWidget){ 
    141                                 this.clobberFocus(); 
    142                                 // dojo.debug("setFocus:", this); 
    143                                 dojo.widget.Editor2._CurrentInstance = this; 
    144                                 dojo.event.connect(this.toolbarWidget, "exec", this, "execCommand"); 
    145                         } 
     457                        dojo.debug("setFocus: start "+this.widgetId); 
     458                        if(dojo.widget.Editor2Manager.getCurrentInstance() === this){ return; } 
     459 
     460                        this.clobberFocus(); 
     461                         dojo.debug("setFocus:", this); 
     462                        dojo.widget.Editor2Manager.setCurrentInstance(this); 
    146463                }, 
    147464 
    148465                setBlur: function(){ 
    149                         // dojo.debug("setBlur:", this); 
    150                         dojo.event.disconnect(this.toolbarWidget, "exec", this, "execCommand"); 
    151                 }, 
    152  
    153                 _scrollSetUp: false, 
    154                 _fixEnabled: false, 
    155                 _scrollThreshold: false, 
    156                 _handleScroll: true, 
    157                 globalOnScrollHandler: function(){ 
    158                         var isIE = dojo.render.html.ie; 
    159                         if(!this._handleScroll){ return; } 
    160                         var dh = dojo.html; 
    161                         var tdn = this.toolbarWidget.domNode; 
    162                         var db = dojo.body(); 
    163                         var totalHeight = dh.getMarginBox(tdn).height; 
    164                         if(!this._scrollSetUp){ 
    165                                 this._scrollSetUp = true; 
    166                                 var editorWidth =  dh.getMarginBox(this.domNode).width;  
    167                                 this._scrollThreshold = dh.abs(tdn, false).y; 
    168                                 // dojo.debug("threshold:", this._scrollThreshold); 
    169                                 if((isIE)&&(db)&&(dh.getStyle(db, "background-image")=="none")){ 
    170                                         with(db.style){ 
    171                                                 backgroundImage = "url(" + dojo.uri.dojoUri("src/widget/templates/images/blank.gif") + ")"; 
    172                                                 backgroundAttachment = "fixed"; 
    173                                         } 
    174                                 } 
    175                         } 
    176  
    177                         var scrollPos = (window["pageYOffset"]) ? window["pageYOffset"] : (document["documentElement"]||document["body"]).scrollTop; 
    178  
    179                         // FIXME: need to have top and bottom thresholds so toolbar doesn't keep scrolling past the bottom 
    180                         if(scrollPos > this._scrollThreshold){ 
    181                                 // dojo.debug(scrollPos); 
    182                                 if(!this._fixEnabled){ 
    183                                         this.domNode.style.marginTop = totalHeight+"px"; 
    184                                         if(isIE){ 
    185                                                 // FIXME: should we just use setBehvior() here instead? 
    186                                                 var cl = dojo.html.abs(tdn).x; 
    187                                                 document.body.appendChild(tdn); 
    188                                                 tdn.style.left = cl+dojo.html.getPixelValue(document.body, "margin-left")+"px"; 
    189                                                 dojo.html.addClass(tdn, "IEFixedToolbar"); 
    190                                                 if(this.object){ 
    191                                                         dojo.html.addClass(this.tbBgIframe, "IEFixedToolbar"); 
    192                                                 } 
    193                                                  
    194                                         }else{ 
    195                                                 with(tdn.style){ 
    196                                                         position = "fixed"; 
    197                                                         top = "0px"; 
    198                                                 } 
    199                                         } 
    200                                         tdn.style.zIndex = 1000; 
    201                                         this._fixEnabled = true; 
    202                                 } 
    203                                 // if we're showing the floating toolbar, make sure that if 
    204                                 // we've scrolled past the bottom of the editor that we hide 
    205                                 // the toolbar for this instance of the editor. 
    206  
    207                                 // TODO: when we get multiple editor toolbar support working 
    208                                 // correctly, ensure that we check this against the scroll 
    209                                 // position of the bottom-most editor instance. 
    210                                 if(!dojo.render.html.safari){ 
    211                                         // safari reports a bunch of things incorrectly here 
    212                                         var eHeight = (this.height) ? parseInt(this.height) : ((this.object) ? dojo.html.getBorderBox(this.editNode).height : this._lastHeight); 
    213                                         if(scrollPos > (this._scrollThreshold+eHeight)){ 
    214                                                 tdn.style.display = "none"; 
    215                                         }else{ 
    216                                                 tdn.style.display = ""; 
    217                                         } 
    218                                 } 
    219  
    220                         }else if(this._fixEnabled){ 
    221                                 this.domNode.style.marginTop = null; 
    222                                 with(tdn.style){ 
    223                                         position = ""; 
    224                                         top = ""; 
    225                                         zIndex = ""; 
    226                                         if(isIE){ 
    227                                                 marginTop = ""; 
    228                                         } 
    229                                 } 
    230                                 if(isIE){ 
    231                                         dojo.html.removeClass(tdn, "IEFixedToolbar"); 
    232                                         dojo.html.insertBefore(tdn, this._htmlEditNode||this.domNode); 
    233                                 } 
    234                                 this._fixEnabled = false; 
    235                         } 
    236                 }, 
    237  
    238                 unhookScroller: function(){ 
    239                         this._handleScroll = false; 
    240                         clearInterval(this.scrollInterval); 
    241                         // var src = document["documentElement"]||window; 
    242                         // dojo.event.disconnect(src, "onscroll", this, "globalOnScrollHandler"); 
    243                         if(dojo.render.html.ie){ 
    244                                 dojo.html.removeClass(this.toolbarWidget.domNode, "IEFixedToolbar"); 
    245                         } 
     466                         dojo.debug("setBlur:", this); 
     467                        //dojo.event.disconnect(this.toolbarWidget, "exec", this, "execCommand"); 
    246468                }, 
    247469 
     
    271493                        // end frequency checker 
    272494 
    273                         // FIXME: SEVERE: This forEach block breaks undo on IE 
    274                         dojo.lang.forEach(this.commandList,  
    275                                 function(cmd){ 
    276                                         if((cmd == "inserthtml") || (cmd == "save")){ return; } 
    277                                         try{ 
    278                                                 if(this.queryCommandEnabled(cmd)){ 
    279                                                         if(this.queryCommandState(cmd)){ 
    280                                                                 this.toolbarWidget.highlightButton(cmd); 
    281                                                         }else{ 
    282                                                                 this.toolbarWidget.unhighlightButton(cmd); 
    283                                                         } 
    284                                                 } 
    285                                         }catch(e){ 
    286                                                 // alert(cmd+":"+e); 
    287                                         } 
    288                                 }, 
    289                                 this 
    290                         ); 
    291  
    292                         var h = dojo.render.html; 
    293                          
    294                         // safari f's us for selection primitives 
    295                         if(h.safari){ return; } 
    296  
    297                         var selectedNode = (h.ie) ? this.document.selection.createRange().parentElement() : this.window.getSelection().anchorNode; 
    298                         // make sure we actuall have an element 
    299                         while((selectedNode)&&(selectedNode.nodeType != 1)){ 
    300                                 selectedNode = selectedNode.parentNode; 
    301                         } 
    302                         if(!selectedNode){ return; } 
    303  
    304                         var formats = ["p", "pre", "h1", "h2", "h3", "h4"]; 
    305                         // gotta run some specialized updates for the various 
    306                         // formatting options 
    307                         var type = formats[dojo.lang.find(formats, selectedNode.nodeName.toLowerCase())]; 
    308                         while((selectedNode)&&(selectedNode!=this.editNode)&&(!type)){ 
    309                                 selectedNode = selectedNode.parentNode; 
    310                                 type = formats[dojo.lang.find(formats, selectedNode.nodeName.toLowerCase())]; 
    311                         } 
    312                         if(!type){ 
    313                                 type = ""; 
    314                         }else{ 
    315                                 if(type.charAt(0)=="h"){ 
    316                                         this.toolbarWidget.unhighlightButton("bold"); 
    317                                 } 
    318                         } 
    319                         this.toolbarWidget.selectFormat(type); 
    320                 }, 
    321  
    322                 updateItem: function(item) { 
    323                         try { 
    324                                 var cmd = item._name; 
    325                                 var enabled = this._richText.queryCommandEnabled(cmd); 
    326                                 item.setEnabled(enabled, false, true); 
    327  
    328                                 var active = this._richText.queryCommandState(cmd); 
    329                                 if(active && cmd == "underline") { 
    330                                         // don't activate underlining if we are on a link 
    331                                         active = !this._richText.queryCommandEnabled("unlink"); 
    332                                 } 
    333                                 item.setSelected(active, false, true); 
    334                                 return true; 
    335                         } catch(err) { 
    336                                 return false; 
    337                         } 
     495                        //TODO 
     496                        //if((cmd == "inserthtml") || (cmd == "save")){ return; } 
     497 
     498                        //IE has the habit of generating events even when this editor is blurred, prevent this 
     499                        if(dojo.widget.Editor2Manager.getCurrentInstance() !== this){ return; } 
     500 
     501                        this.toolbarWidget.update(); 
     502                }, 
     503 
     504                destroy: function(){ 
     505                        //clean all loaded plugins 
     506                        for(var index in this.loadedPlugins){ 
     507                                this.loadedPlugins[index].destroy(); 
     508                                delete this.loadedPlugins[index]; 
     509                        } 
     510                        this._htmlEditNode = null; 
     511                        this.document = null; 
     512                        this.window = null; 
     513                        this.object = null; 
     514                        dojo.widget.Editor2.superclass.destroy.call(this); 
     515                }, 
     516 
     517                onDisplayChanged: function(e){ 
     518                        dojo.widget.Editor2.superclass.onDisplayChanged.call(this,e); 
     519                        this.updateToolbar(); 
     520                }, 
     521 
     522                onLoad: function(){ 
     523                        try{ 
     524                                dojo.widget.Editor2.superclass.onLoad.call(this); 
     525                        }catch(e){ // FIXME: debug why this is throwing errors in IE! 
     526                                dojo.debug(e); 
     527                        } 
     528                        this.editorOnLoad(); 
     529                }, 
     530 
     531                onFocus: function(){ 
     532                        dojo.widget.Editor2.superclass.onFocus.call(this); 
     533                        this.setFocus(); 
    338534                }, 
    339535 
     
    344540                                if(this.saveUrl.length){ 
    345541                                        var content = {}; 
    346                                         content[this.saveArgName] = this.getHtml(); 
     542                                        content[this.saveArgName] = this.getEditorContent(); 
    347543                                        dojo.io.bind({ 
    348544                                                method: this.saveMethod, 
     
    359555                } 
    360556        }, 
    361         "html", 
    362         function(){ 
    363                 var cp = dojo.widget.Editor2.prototype; 
    364                 if(!cp._wrappersSet){ 
    365                         cp._wrappersSet = true; 
    366                  
    367                         cp.onDisplayChanged = (function(odc){ 
    368                                 return function(){ 
    369                                         try{ 
    370                                                 odc.call(this); 
    371                                                 this.updateToolbar(); 
    372                                         }catch(e){} 
    373                                 }; 
    374                         })(cp.onDisplayChanged); 
    375  
    376                         cp.onLoad = (function(ol){ 
    377                                 return function(){ 
    378                                         try{ 
    379                                                 ol.call(this); 
    380                                         }catch(e){ // FIXME: debug why this is throwing errors in IE! 
    381                                                 dojo.debug(e); 
    382                                         } 
    383                                         this.editorOnLoad(); 
    384                                 }; 
    385                         })(cp.onLoad); 
    386                          
    387                         cp.onFocus = (function(of){ 
    388                                 return function(){ 
    389                                         of.call(this); 
    390                                         this.setFocus(); 
    391                                 }; 
    392                         })(cp.onFocus); 
    393                 } 
    394         } 
     557        "html" 
    395558); 
  • trunk/src/widget/Editor2Toolbar.js

    r5167 r5306  
    77dojo.require("dojo.html.display"); 
    88dojo.require("dojo.widget.RichText"); 
     9dojo.require("dojo.widget.Menu2"); 
    910dojo.require("dojo.widget.ColorPalette"); 
     11 
     12dojo.widget.Editor2ToolbarItemManager = { 
     13        _registeredItemHandlers: [], 
     14        registerHandler: function(obj, func){ 
     15                if(arguments.length == 1){ 
     16//                      for(i in this._registeredItemHandlers){ 
     17//                              if(func === this._registeredItemHandlers[i]){ 
     18//                                      dojo.debug("Editor2ToolbarItemManager handler "+func+" is already registered, ignored"); 
     19//                                      return; 
     20//                              } 
     21//                      } 
     22                        this._registeredItemHandlers.push(obj); 
     23                }else{ 
     24                        this._registeredItemHandlers.push(function(){return obj[func].apply(obj, arguments);}); 
     25                } 
     26        }, 
     27        removeHandler: function(func){ 
     28                for(i in this._registeredItemHandlers){ 
     29                        if(func === this._registeredItemHandlers[i]){ 
     30                                delete this._registeredItemHandlers[i]; 
     31                                return; 
     32                        } 
     33                } 
     34                dojo.debug("Editor2ToolbarItemManager handler "+func+" is not registered, can not remove."); 
     35        }, 
     36        destroy: function(){ 
     37                for(var i in this._registeredItemHandlers){ 
     38                        delete this._registeredItemHandlers[i]; 
     39                } 
     40        }, 
     41        getToolbarItem: function(name){ 
     42                var item; 
     43                name = name.toLowerCase(); 
     44                for(i in this._registeredItemHandlers){ 
     45                        item = this._registeredItemHandlers[i](name); 
     46                        if(item){ 
     47                                break; 
     48                        } 
     49                } 
     50 
     51                if(!item){ 
     52                        switch(name){ 
     53                                //button for builtin functions 
     54                                case 'bold': 
     55                                case 'copy': 
     56                                case 'cut': 
     57                                case 'delete': 
     58                                case 'indent': 
     59                                case 'inserthorizontalrule': 
     60                                case 'insertorderedlist': 
     61                                case 'insertunorderedlist': 
     62                                case 'italic': 
     63                                case 'justifycenter': 
     64                                case 'justifyfull': 
     65                                case 'justifyleft':  
     66                                case 'justifyright': 
     67                                case 'outdent': 
     68                                case 'paste': 
     69                                case 'redo': 
     70                                case 'removeformat': 
     71                                case 'selectall': 
     72                                case 'strikethrough': 
     73                                case 'subscript': 
     74                                case 'superscript': 
     75                                case 'underline': 
     76                                case 'undo':  
     77                                case 'unlink': 
     78                                case 'createlink': 
     79                                case 'insertimage': 
     80                                //extra simple buttons 
     81                                case 'htmltoggle': 
     82                                        item = new dojo.widget.Editor2ToolbarButton(name); 
     83                                        break; 
     84                                case 'forecolor':  
     85                                case 'hilitecolor': 
     86                                        item = new dojo.widget.Editor2ToolbarColorPaletteButton(name); 
     87                                        break; 
     88                                case 'plainformatblock': 
     89                                        item = new dojo.widget.Editor2ToolbarFormatBlockPlainSelect("formatblock"); 
     90                                        break; 
     91                                case 'formatblock': 
     92                                        item = new dojo.widget.Editor2ToolbarFormatBlockSelect("formatblock"); 
     93                                        break; 
     94                                case 'fontsize': 
     95                                        item = new dojo.widget.Editor2ToolbarFontSizeSelect("fontsize"); 
     96                                        break; 
     97                                case 'fontname': 
     98                                        item = new dojo.widget.Editor2ToolbarFontNameSelect("fontname"); 
     99                                        break; 
     100                                case 'inserttable': 
     101                                case 'insertcell': 
     102                                case 'insertcol': 
     103                                case 'insertrow': 
     104                                case 'deletecells': 
     105                                case 'deletecols': 
     106                                case 'deleterows': 
     107                                case 'mergecells': 
     108                                case 'splitcell': 
     109                                        dojo.debug(name + " is implemented in dojo.widget.Editor2Plugin.TableOperation, please require it first."); 
     110                                        break; 
     111                                //TODO: 
     112                                case 'inserthtml': 
     113                                case 'blockdirltr': 
     114                                case 'blockdirrtl': 
     115                                case 'dirltr': 
     116                                case 'dirrtl': 
     117                                case 'inlinedirltr': 
     118                                case 'inlinedirrtl': 
     119                                        dojo.debug("Not yet implemented toolbar item: "+name); 
     120                                        break; 
     121                                default: 
     122                                        dojo.debug("dojo.widget.Editor2ToolbarItemManager.getToolbarItem: Unknown toolbar item: "+name); 
     123                        } 
     124                } 
     125                return item; 
     126        } 
     127}; 
     128 
     129dojo.addOnUnload(dojo.widget.Editor2ToolbarItemManager, "destroy"); 
     130 
     131dojo.declare("dojo.widget.Editor2ToolbarButton", null,{ 
     132        initializer: function(name){ 
     133                this._name = name; 
     134                this._command = dojo.widget.Editor2Manager.getCommand(name); 
     135        }, 
     136        create: function(node, toolbar, isMenu){ 
     137                this._domNode = node; 
     138                //make this unselectable: different browsers 
     139                //use different properties for this, so use 
     140                //js do it automatically 
     141                this.disableSelection(this._domNode); 
     142                this._parentToolbar = toolbar; 
     143                dojo.event.connect(this._domNode, 'onclick', this, 'onClick'); 
     144                if(!isMenu){ 
     145                        dojo.event.connect(this._domNode, 'onmouseover', this, 'onMouseOver'); 
     146                        dojo.event.connect(this._domNode, 'onmouseout', this, 'onMouseOut'); 
     147                } 
     148        }, 
     149        disableSelection: function(rootnode){ 
     150                dojo.html.disableSelection(rootnode); 
     151                var nodes = rootnode.all || rootnode.getElementsByTagName("*"); 
     152                for(var x=0; x<nodes.length; x++){ 
     153                        dojo.html.disableSelection(nodes[x]); 
     154                } 
     155        }, 
     156        onMouseOver: function(){ 
     157                if(this._command.getState() != dojo.widget.Editor2Manager.commandState.Disabled){ 
     158                        this.highlightToolbarItem(); 
     159                } 
     160        }, 
     161        onMouseOut: function(){ 
     162                this.unhighlightToolbarItem(); 
     163        }, 
     164        destroy: function(){ 
     165//              dojo.event.disconnect(this._domNode, 'onclick', this, 'onClick'); 
     166//              dojo.event.disconnect(this._domNode, 'onmouseover', this, 'onMouseOver'); 
     167//              dojo.event.disconnect(this._domNode, 'onmouseout', this, 'onMouseOut'); 
     168                this._domNode = null; 
     169                delete this._command; 
     170                this._parentToolbar = null; 
     171        }, 
     172        onClick: function(e){ 
     173                if(this._domNode && !this._domNode.disabled && this._command){ 
     174                        e.preventDefault(); 
     175                        e.stopPropagation(); 
     176                        this._command.execute(); 
     177                } 
     178        }, 
     179        refreshState: function(){ 
     180                if(this._domNode && this._command){ 
     181                        var em = dojo.widget.Editor2Manager; 
     182                        var state = this._command.getState(); 
     183                        if(state != this._lastState){ 
     184                                switch(state){ 
     185                                        case em.commandState.Latched: 
     186                                                this.latchToolbarItem(); 
     187                                                break; 
     188                                        case em.commandState.Enabled: 
     189                                                this.enableToolbarItem(); 
     190                                                break; 
     191                                        case em.commandState.Disabled: 
     192                                        default: 
     193                                                this.disableToolbarItem(); 
     194                                } 
     195                                this._lastState = state; 
     196                        } 
     197                        return state; 
     198                } 
     199        }, 
     200 
     201        latchToolbarItem: function(){ 
     202                this._domNode.disabled = false; 
     203                this.removeToolbarItemStyle(this._domNode); 
     204                dojo.html.addClass(this._domNode, this._parentToolbar.ToolbarLatchedItemStyle); 
     205        }, 
     206 
     207        enableToolbarItem: function(){ 
     208                this._domNode.disabled = false; 
     209                this.removeToolbarItemStyle(this._domNode); 
     210                dojo.html.addClass(this._domNode, this._parentToolbar.ToolbarEnabledItemStyle); 
     211        }, 
     212 
     213        disableToolbarItem: function(){ 
     214                this._domNode.disabled = true; 
     215                this.removeToolbarItemStyle(this._domNode); 
     216                dojo.html.addClass(this._domNode, this._parentToolbar.ToolbarDisabledItemStyle); 
     217        }, 
     218 
     219        highlightToolbarItem: function(){ 
     220                dojo.html.addClass(this._domNode, this._parentToolbar.ToolbarHighlightedItemStyle); 
     221        }, 
     222 
     223        unhighlightToolbarItem: function(){ 
     224                dojo.html.removeClass(this._domNode, this._parentToolbar.ToolbarHighlightedItemStyle); 
     225        }, 
     226 
     227        removeToolbarItemStyle: function(){ 
     228                dojo.html.removeClass(this._domNode, this._parentToolbar.ToolbarEnabledItemStyle); 
     229                dojo.html.removeClass(this._domNode, this._parentToolbar.ToolbarLatchedItemStyle); 
     230                dojo.html.removeClass(this._domNode, this._parentToolbar.ToolbarDisabledItemStyle); 
     231                this.unhighlightToolbarItem(); 
     232        } 
     233}); 
     234 
     235dojo.declare("dojo.widget.Editor2ToolbarDropDownButton", dojo.widget.Editor2ToolbarButton,{ 
     236        onClick: function(){ 
     237                if(this._domNode){ 
     238                        if(!this._dropdown){ 
     239                                this._dropdown = dojo.widget.createWidget("PopupContainer", {}); 
     240                                this._domNode.appendChild(this._dropdown.domNode); 
     241                        } 
     242                        if(this._dropdown.isShowingNow){ 
     243                                this._dropdown.close(); 
     244                        }else{ 
     245                                this.onDropDownShown();  
     246                                this._dropdown.open(this._domNode, null, this._domNode); 
     247                        } 
     248                } 
     249        }, 
     250        destroy: function(){ 
     251                this.onDropDownDestroy(); 
     252                if(this._dropdown){ 
     253                        this._dropdown.destroy(); 
     254                } 
     255                dojo.widget.Editor2ToolbarDropDownButton.superclass.destroy.call(this); 
     256        }, 
     257        onDropDownShown: function(){}, 
     258        onDropDownDestroy: function(){} 
     259}); 
     260 
     261dojo.declare("dojo.widget.Editor2ToolbarColorPaletteButton", dojo.widget.Editor2ToolbarDropDownButton,{ 
     262        onDropDownShown: function(){ 
     263                if(!this._colorpalette){ 
     264                        this._colorpalette = dojo.widget.createWidget("ColorPalette", {}); 
     265                        this._dropdown.addChild(this._colorpalette); 
     266 
     267                        this.disableSelection(this._dropdown.domNode); 
     268                        this.disableSelection(this._colorpalette.domNode); 
     269                        //do we need a destory to delete this._colorpalette manually? 
     270                        //I assume as it is added to this._dropdown via addChild, it 
     271                        //should be deleted when this._dropdown is destroyed 
     272 
     273                        dojo.event.connect(this._colorpalette, "onColorSelect", this, 'setColor'); 
     274                        dojo.event.connect(this._dropdown, "open", this, 'latchToolbarItem'); 
     275                        dojo.event.connect(this._dropdown, "close", this, 'enableToolbarItem'); 
     276                } 
     277        }, 
     278        setColor: function(color){ 
     279                this._dropdown.close(); 
     280                this._command.execute(color); 
     281        } 
     282}); 
     283 
     284dojo.declare("dojo.widget.Editor2ToolbarFormatBlockPlainSelect", dojo.widget.Editor2ToolbarButton,{ 
     285        create: function(node, toolbar){ 
     286                //TODO: check node is a select 
     287                this._domNode = node; 
     288                this.disableSelection(this._domNode); 
     289                this._parentToolbar = toolbar; 
     290                dojo.event.connect(this._domNode, 'onchange', this, 'onChange'); 
     291        }, 
     292 
     293        destroy: function(){ 
     294                this._domNode = null; 
     295                this._command = null; 
     296                this._parentToolbar = null; 
     297        }, 
     298 
     299        onChange: function(){ 
     300                if(this._domNode){ 
     301                        var sv = this._domNode.value.toLowerCase(); 
     302                        this._command.execute(sv); 
     303                } 
     304        }, 
     305 
     306        refreshState: function(){ 
     307                if(this._domNode && this._command){ 
     308                        dojo.widget.Editor2ToolbarFormatBlockPlainSelect.superclass.refreshState.call(this); 
     309                        var format = this._command.getValue(); 
     310                        if(!format){ format = ""; } 
     311                        dojo.lang.forEach(this._domNode.options, function(item){ 
     312                                if(item.value.toLowerCase() == format.toLowerCase()){ 
     313                                        item.selected = true; 
     314                                } 
     315                        }); 
     316                } 
     317        } 
     318}); 
     319 
     320dojo.declare("dojo.widget.Editor2ToolbarComboItem", dojo.widget.Editor2ToolbarDropDownButton,{ 
     321        href: null, 
     322        create: function(node, toolbar){ 
     323                dojo.widget.Editor2ToolbarComboItem.superclass.create.call(this, node, toolbar); 
     324                //do not use lazy initilization, as we need the local names in refreshState() 
     325                if(!this._contentPane){ 
     326                        dojo.require("dojo.widget.ContentPane"); 
     327                        this._contentPane = dojo.widget.createWidget("ContentPane", {preload: 'true'}); 
     328                        this._contentPane.addOnLoad(this, "setup"); 
     329                        this._contentPane.setUrl(this.href); 
     330                } 
     331        }, 
     332 
     333        onMouseOver: function(e){ 
     334                dojo.html.addClass(e.currentTarget, this._parentToolbar.ToolbarHighlightedSelectStyle); 
     335        }, 
     336        onMouseOut:function(e){ 
     337                dojo.html.removeClass(e.currentTarget, this._parentToolbar.ToolbarHighlightedSelectStyle); 
     338        }, 
     339 
     340        onDropDownShown: function(){ 
     341                if(!this._dropdown.__addedContentPage){ 
     342                        this._dropdown.addChild(this._contentPane); 
     343                        this._dropdown.__addedContentPage = true; 
     344                } 
     345        }, 
     346 
     347        //overload this to connect event 
     348        setup: function(){}, 
     349 
     350        onChange: function(e){ 
     351                var name = e.currentTarget.getAttribute("dropDownItemName"); 
     352                this._command.execute(name); 
     353                this._dropdown.close(); 
     354        }, 
     355 
     356        onMouseOverItem: function(e){ 
     357                dojo.html.addClass(e.currentTarget, this._parentToolbar.ToolbarHighlightedSelectItemStyle); 
     358        }, 
     359 
     360        onMouseOutItem: function(e){ 
     361                dojo.html.removeClass(e.currentTarget, this._parentToolbar.ToolbarHighlightedSelectItemStyle); 
     362        }, 
     363 
     364        //overload this to update GUI item 
     365        refreshState: function(){} 
     366}); 
     367 
     368dojo.declare("dojo.widget.Editor2ToolbarFormatBlockSelect", dojo.widget.Editor2ToolbarComboItem,{ 
     369        href: dojo.uri.dojoUri("src/widget/templates/Editor2/EditorToolbar_FormatBlock.html"), 
     370 
     371        setup: function(){ 
     372                dojo.widget.Editor2ToolbarFormatBlockSelect.superclass.setup.call(this); 
     373 
     374                var nodes = this._contentPane.domNode.all || this._contentPane.domNode.getElementsByTagName("*"); 
     375                this._blockNames = {}; 
     376                this._blockDisplayNames = {}; 
     377                for(var x=0; x<nodes.length; x++){ 
     378                        var node = nodes[x]; 
     379                        dojo.html.disableSelection(node); 
     380                        var name=node.getAttribute("dropDownItemName") 
     381                        if(name){ 
     382                                this._blockNames[name] = node; 
     383                                var childrennodes = node.getElementsByTagName(name); 
     384                                this._blockDisplayNames[name] = childrennodes[childrennodes.length-1].innerHTML; 
     385                        } 
     386                } 
     387                for(var name in this._blockNames){ 
     388                        dojo.event.connect(this._blockNames[name], "onclick", this, "onChange"); 
     389                        dojo.event.connect(this._blockNames[name], "onmouseover", this, "onMouseOverItem"); 
     390                        dojo.event.connect(this._blockNames[name], "onmouseout", this, "onMouseOutItem"); 
     391                } 
     392        }, 
     393 
     394        onDropDownDestroy: function(){ 
     395                if(this._blockNames){ 
     396                        for(var name in this._blockNames){ 
     397                                delete this._blockNames[name]; 
     398                                delete this._blockDisplayNames[name]; 
     399                        } 
     400                } 
     401        }, 
     402 
     403        refreshState: function(){ 
     404                if(this._command){ 
     405                        //dojo.widget.Editor2ToolbarFormatBlockSelect.superclass.refreshState.call(this); 
     406                        var format = this._command.getValue(); 
     407                        if(format == this._lastSelectedFormat && this._blockDisplayNames){ 
     408                                return; 
     409                        } 
     410                        this._lastSelectedFormat = format; 
     411                        var label = this._domNode.getElementsByTagName("label")[0]; 
     412                        var isSet = false; 
     413                        if(this._blockDisplayNames){ 
     414                                for(var name in this._blockDisplayNames){ 
     415                                        if(name == format){ 
     416                                                label.innerHTML =       this._blockDisplayNames[name]; 
     417                                                isSet = true; 
     418                                                break; 
     419                                        } 
     420                                } 
     421                                if(!isSet){ 
     422                                        label.innerHTML = "&nbsp;"; 
     423                                } 
     424                        } 
     425                } 
     426        } 
     427}); 
     428 
     429dojo.declare("dojo.widget.Editor2ToolbarFontSizeSelect", dojo.widget.Editor2ToolbarComboItem,{ 
     430        href: dojo.uri.dojoUri("src/widget/templates/Editor2/EditorToolbar_FontSize.html"), 
     431 
     432        setup: function(){ 
     433                dojo.widget.Editor2ToolbarFormatBlockSelect.superclass.setup.call(this); 
     434 
     435                var nodes = this._contentPane.domNode.all || this._contentPane.domNode.getElementsByTagName("*"); 
     436                this._fontsizes = {}; 
     437                this._fontSizeDisplayNames = {}; 
     438                for(var x=0; x<nodes.length; x++){ 
     439                        var node = nodes[x]; 
     440                        dojo.html.disableSelection(node); 
     441                        var name=node.getAttribute("dropDownItemName") 
     442                        if(name){ 
     443                                this._fontsizes[name] = node; 
     444                                this._fontSizeDisplayNames[name] = node.getElementsByTagName('font')[0].innerHTML; 
     445                        } 
     446                } 
     447                for(var name in this._fontsizes){ 
     448                        dojo.event.connect(this._fontsizes[name], "onclick", this, "onChange"); 
     449                        dojo.event.connect(this._fontsizes[name], "onmouseover", this, "onMouseOverItem"); 
     450                        dojo.event.connect(this._fontsizes[name], "onmouseout", this, "onMouseOutItem"); 
     451                } 
     452        }, 
     453 
     454        onDropDownDestroy: function(){ 
     455                if(this._fontsizes){ 
     456                        for(var name in this._fontsizes){ 
     457                                delete this._fontsizes[name]; 
     458                                delete this._fontSizeDisplayNames[name]; 
     459                        } 
     460                } 
     461        }, 
     462 
     463        refreshState: function(){ 
     464                if(this._command){ 
     465                        //dojo.widget.Editor2ToolbarFormatBlockSelect.superclass.refreshState.call(this); 
     466                        var size = this._command.getValue(); 
     467                        if(size == this._lastSelectedSize && this._fontSizeDisplayNames){ 
     468                                return; 
     469                        } 
     470                        this._lastSelectedSize = size; 
     471                        var label = this._domNode.getElementsByTagName("label")[0]; 
     472                        var isSet = false; 
     473                        if(this._fontSizeDisplayNames){ 
     474                                for(var name in this._fontSizeDisplayNames){ 
     475                                        if(name == size){ 
     476                                                label.innerHTML =       this._fontSizeDisplayNames[name]; 
     477                                                isSet = true; 
     478                                                break; 
     479                                        } 
     480                                } 
     481                                if(!isSet){ 
     482                                        label.innerHTML = "&nbsp;"; 
     483                                } 
     484                        } 
     485                } 
     486        } 
     487}); 
     488 
     489dojo.declare("dojo.widget.Editor2ToolbarFontNameSelect", dojo.widget.Editor2ToolbarFontSizeSelect,{ 
     490        href: dojo.uri.dojoUri("src/widget/templates/Editor2/EditorToolbar_FontName.html") 
     491}); 
    10492 
    11493dojo.widget.defineWidget( 
     
    13495        dojo.widget.HtmlWidget, 
    14496        { 
    15                 commandList: [ "bold", "italic", "underline", "subscript", "superscript", 
    16                         "fontname", "fontsize", "forecolor", "hilitecolor", "justifycenter", 
    17                         "justifyfull", "justifyleft", "justifyright", "cut", "copy", "paste", 
    18                         "delete", "undo", "redo", "createlink", "unlink", "removeformat", 
    19                         "inserthorizontalrule", "insertimage", "insertorderedlist", 
    20                         "insertunorderedlist", "indent", "outdent", "formatblock", "strikethrough",  
    21                         "inserthtml", "blockdirltr", "blockdirrtl", "dirltr", "dirrtl", 
    22                         "inlinedirltr", "inlinedirrtl", "inserttable", "insertcell", 
    23                         "insertcol", "insertrow", "deletecells", "deletecols", "deleterows", 
    24                         "mergecells", "splitcell" 
    25                 ], 
    26  
    27                 templatePath: dojo.uri.dojoUri("src/widget/templates/EditorToolbarOneline.html"), 
    28                 // templatePath: dojo.uri.dojoUri("src/widget/templates/EditorToolbar.html"), 
     497                templatePath: dojo.uri.dojoUri("src/widget/templates/EditorToolbar.html"), 
    29498                templateCssPath: dojo.uri.dojoUri("src/widget/templates/EditorToolbar.css"), 
    30499 
    31                 forecolorPalette: null, 
    32                 hilitecolorPalette: null, 
    33  
    34500                // DOM Nodes 
    35                 wikiwordButton: null, 
    36                 htmltoggleButton: null, 
    37                 insertimageButton: null, 
    38                 styleDropdownButton: null, 
    39                 styleDropdownContainer: null, 
    40                 copyButton: null, 
    41                 boldButton: null, 
    42                 italicButton: null, 
    43                 underlineButton: null, 
    44                 justifycenterButton: null, 
    45                 justifyleftButton: null, 
    46                 justifyfullButton: null, 
    47                 justifyrightButton: null, 
    48                 pasteButton: null, 
    49                 undoButton: null, 
    50                 redoButton: null, 
    51                 linkButton: null, 
    52                 insertunorderedlistButton: null, 
    53                 insertorderedlistButton: null, 
    54                 forecolorButton: null, 
    55                 forecolorDropDown: null, 
    56                 hilitecolorButton: null, 
    57                 hilitecolorDropDown: null, 
    58                 formatSelectBox: null, 
    59                 inserthorizontalruleButton: null, 
    60                 strikethroughButton: null, 
    61                 clickInterceptDiv: null, 
    62                 oneLineTr: null, 
    63501                saveButton: null, 
    64502 
    65                 buttonClick: function(e){ e.preventDefault(); /* dojo.debug("buttonClick"); */ }, 
    66  
    67                 buttonMouseOver: function(e){  }, 
    68                 buttonMouseOut: function(e){  }, 
    69  
     503                ToolbarLatchedItemStyle: "ToolbarButtonLatched", 
     504                ToolbarEnabledItemStyle: "ToolbarButtonEnabled", 
     505                ToolbarDisabledItemStyle: "ToolbarButtonDisabled", 
     506                ToolbarHighlightedItemStyle: "ToolbarButtonHighlighted", 
     507                ToolbarHighlightedSelectStyle: "ToolbarSelectHighlighted", 
     508                ToolbarHighlightedSelectItemStyle: "ToolbarSelectHighlightedItem", 
     509 
     510//              itemNodeType: 'span', //all the items (with attribute dojoETItemName set) defined in the toolbar should be a of this type 
     511 
     512                postCreate: function(){ 
     513                        var nodes = dojo.html.getElementsByClass("dojoEditorToolbarItem", this.domNode/*, this.itemNodeType*/); 
     514 
     515                        this.items = {}; 
     516                        for(var x=0; x<nodes.length; x++){ 
     517                                var node = nodes[x]; 
     518                                var itemname = node.getAttribute("dojoETItemName"); 
     519                                if(itemname){ 
     520                                        var item = dojo.widget.Editor2ToolbarItemManager.getToolbarItem(itemname); 
     521                                        if(item){ 
     522                                                item.create(node, this); 
     523                                                this.items[itemname.toLowerCase()] = item; 
     524                                        }else{ 
     525                                                //hide unsupported toolbar items 
     526                                                node.style.display = "none"; 
     527                                        } 
     528                                } 
     529                        } 
     530                }, 
    70531 
    71532                // event signals 
    72                 preventSelect: function(e){ if(dojo.render.html.safari){ e.preventDefault(); } }, 
    73533                wikiwordClick: function(){ }, 
    74                 insertimageClick: function(){ }, 
    75                 htmltoggleClick: function(){ }, 
     534//              insertimageClick: function(){ }, 
    76535                saveClick: function(){ }, 
    77536 
    78                 styleDropdownClick: function(){ 
    79                         dojo.debug("styleDropdownClick:", this.styleDropdownContainer); 
    80                         dojo.html.toggleShowing(this.styleDropdownContainer); 
     537                update: function(){ 
     538                        for(var cmd in this.items){ 
     539                                this.items[cmd].refreshState(); 
     540                        } 
    81541                }, 
    82542 
    83                 copyClick: function(){ this.exec("copy"); }, 
    84                 boldClick: function(){ this.exec("bold"); }, 
    85                 italicClick: function(){ this.exec("italic"); }, 
    86                 underlineClick: function(){ this.exec("underline"); }, 
    87                 justifyleftClick: function(){ this.exec("justifyleft"); }, 
    88                 justifycenterClick: function(){ this.exec("justifycenter"); }, 
    89                 justifyfullClick: function(){ this.exec("justifyfull"); }, 
    90                 justifyrightClick: function(){ this.exec("justifyright"); }, 
    91                 pasteClick: function(){ this.exec("paste"); }, 
    92                 undoClick: function(){ this.exec("undo"); }, 
    93                 redoClick: function(){ this.exec("redo"); }, 
    94                 linkClick: function(){  
    95                         // FIXME: we need to alert the user if they haven't selected any text 
    96                         // this.exec(   "createlink",  
    97                         //                      prompt("Please enter the URL of the link:", "http://")); 
    98                 }, 
    99                 insertunorderedlistClick: function(){ this.exec("insertunorderedlist"); }, 
    100                 insertorderedlistClick: function(){ this.exec("insertorderedlist"); }, 
    101                 inserthorizontalruleClick: function(){ this.exec("inserthorizontalrule"); }, 
    102                 strikethroughClick: function(){ this.exec("strikethrough"); }, 
    103  
    104                 formatSelectClick: function(){  
    105                         var sv = this.formatSelectBox.value.toLowerCase(); 
    106                         this.exec("formatblock", sv); 
    107                 }, 
    108  
    109                 normalTextClick: function(){ this.exec("formatblock", "p"); }, 
    110                 h1TextClick: function(){ this.exec("formatblock", "h1"); }, 
    111                 h2TextClick: function(){ this.exec("formatblock", "h2"); }, 
    112                 h3TextClick: function(){ this.exec("formatblock", "h3"); }, 
    113                 h4TextClick: function(){ this.exec("formatblock", "h4"); }, 
    114                 indentClick: function(){ this.exec("indent"); }, 
    115                 outdentClick: function(){ this.exec("outdent"); }, 
    116  
    117  
    118                 hideAllDropDowns: function(){ 
    119                         this.domNode.style.height = ""; 
    120                         dojo.lang.forEach(dojo.widget.byType("Editor2Toolbar"), function(tb){ 
    121                                 try{ 
    122                                         dojo.html.hide(tb.forecolorDropDown); 
    123                                         dojo.html.hide(tb.hilitecolorDropDown); 
    124                                         dojo.html.hide(tb.styleDropdownContainer); 
    125                                         if(tb.clickInterceptDiv){ 
    126                                                 dojo.html.hide(tb.clickInterceptDiv); 
    127                                         } 
    128                                 }catch(e){} 
    129                                 if(dojo.render.html.ie){ 
    130                                         try{ 
    131                                                 dojo.html.hide(tb.forecolorPalette.bgIframe); 
    132                                         }catch(e){} 
    133                                         try{ 
    134                                                 dojo.html.hide(tb.hilitecolorPalette.bgIframe); 
    135                                         }catch(e){} 
    136                                 } 
    137                         }); 
    138                 }, 
    139  
    140                 selectFormat: function(format){ 
    141                         if(this.formatSelectBox) { 
    142                                 dojo.lang.forEach(this.formatSelectBox.options, function(item){ 
    143                                         if(item.value.toLowerCase() == format.toLowerCase()){ 
    144                                                 // FIXME: SEVERE: setting selected on this item breaks the undo stack on IE 
    145                                                 item.selected = true; 
    146                                         } 
    147                                 }); 
    148                         } 
    149                 }, 
    150  
    151                 forecolorClick: function(e){ 
    152                         this.colorClick(e, "forecolor"); 
    153                 }, 
    154  
    155                 hilitecolorClick: function(e){ 
    156                         this.colorClick(e, "hilitecolor"); 
    157                 }, 
    158  
    159                 // FIXME: these methods aren't currently dealing with clicking in the 
    160                 // general document to hide the menu 
    161                 colorClick: function(e, type){ 
    162                         var h = dojo.render.html; 
    163                         this.hideAllDropDowns(); 
    164                         // FIXME: if we've been "popped out", we need to set the height of the toolbar. 
    165                         e.stopPropagation(); 
    166                         var dd = this[type+"DropDown"]; 
    167                         var pal = this[type+"Palette"]; 
    168                         dojo.html.toggleShowing(dd); 
    169                         if(!pal){ 
    170                                 pal = this[type+"Palette"] = dojo.widget.createWidget("ColorPalette", {}, dd, "first"); 
    171                                 var fcp = pal.domNode; 
    172                                 var mb = dojo.html.getMarginBox(fcp); 
    173                                 with(dd.style){ 
    174                                         width = mb.width + "px"; 
    175                                         height = mb.height + "px"; 
    176                                         zIndex = 1002; 
    177                                         position = "absolute"; 
    178                                 } 
    179  
    180                                 dojo.event.connect(     "after", 
    181                                                                         pal, "onColorSelect", 
    182                                                                         this, "exec", 
    183                                                                         function(mi){ mi.args.unshift(type); return mi.proceed(); } 
    184                                 ); 
    185  
    186                                 dojo.event.connect(     "after", 
    187                                                                         pal, "onColorSelect", 
    188                                                                         dojo.html, "toggleShowing", 
    189                                                                         this, function(mi){ mi.args.unshift(dd); return mi.proceed(); } 
    190                                 ); 
    191  
    192                                 var cid = this.clickInterceptDiv; 
    193                                 if(!cid){ 
    194                                         cid = this.clickInterceptDiv = document.createElement("div"); 
    195                                         document.body.appendChild(cid); 
    196                                         with(cid.style){ 
    197                                                 backgroundColor = "transparent"; 
    198                                                 top = left = "0px"; 
    199                                                 height = width = "100%"; 
    200                                                 position = "absolute"; 
    201                                                 border = "none"; 
    202                                                 display = "none"; 
    203                                                 zIndex = 1001; 
    204                                         } 
    205                                         dojo.event.connect(cid, "onclick", function(){ cid.style.display = "none"; }); 
    206                                 } 
    207                                 dojo.event.connect(pal, "onColorSelect", function(){ cid.style.display = "none"; }); 
    208  
    209                                 dojo.event.kwConnect({ 
    210                                         srcObj:         document.body,  
    211                                         srcFunc:        "onclick",  
    212                                         targetObj:      this, 
    213                                         targetFunc:     "hideAllDropDowns", 
    214                                         once:           true 
    215                                 }); 
    216                                 document.body.appendChild(dd); 
    217                         } 
    218                         dojo.html.toggleShowing(this.clickInterceptDiv); 
    219                         var pos = dojo.html.abs(this[type+"Button"]); 
    220                         dojo.html.placeOnScreenPoint(dd, pos.x, pos.y, 0, false); 
    221                         if(pal.bgIframe){ 
    222                                 var mb = dojo.html.getMarginBox(dd); 
    223                                 with(pal.bgIframe.style){ 
    224                                         display = "block"; 
    225                                         left = dd.style.left; 
    226                                         top = dd.style.top; 
    227                                         width = mb.width+"px"; 
    228                                         height = mb.height+"px"; 
    229                                 } 
    230                         } 
    231                 }, 
    232  
    233                 uninitialize: function(){ 
    234                         if(!dojo.render.html.ie){ 
    235                                 // apparently this causes leakage on IE! 
    236                                 dojo.event.kwDisconnect({ 
    237                                         srcObj:         document.body,  
    238                                         srcFunc:        "onclick",  
    239                                         targetObj:      this, 
    240                                         targetFunc:     "hideAllDropDowns", 
    241                                         once:           true 
    242                                 }); 
    243                         } 
    244                 }, 
     543                destroy: function(){ 
     544                        for(var it in this.items){ 
     545                                this.items[it].destroy(); 
     546                                delete this.items[it]; 
     547                        } 
     548                        dojo.widget.Editor2Toolbar.superclass.destroy.call(this); 
     549                }//, 
    245550 
    246551                // stub for observers 
    247                 exec: function(what, arg){ /* dojo.debug(what, new Date()); */ }, 
    248  
    249                 hideUnusableButtons: function(obj){ 
    250                         var op = obj||dojo.widget.RichText.prototype; 
    251                         dojo.lang.forEach(this.commandList, 
    252                                 function(cmd){ 
    253                                         if(this[cmd+"Button"]){ 
    254                                                 var cb = this[cmd+"Button"]; 
    255                                                 if(!op.queryCommandAvailable(cmd)){ 
    256                                                         cb.style.display = "none"; 
    257                                                         cb.parentNode.style.display = "none"; 
    258                                                 } 
    259                                         } 
    260                                 }, 
    261                                 this); 
    262                                 if(this.oneLineTr){ 
    263                                         var lastVisibleIsSpacer = false; 
    264                                         var lastVisible = false; 
    265                                         var tds = this.oneLineTr.getElementsByTagName("td"); 
    266                                         dojo.lang.forEach(tds, function(td){ 
    267                                                 if(td.getAttribute("isSpacer")){ 
    268                                                         if(td.style.display != "none"){ 
    269                                                                 if(lastVisibleIsSpacer){ 
    270                                                                         td.style.display = "none"; 
    271                                                                 } 
    272                                                                 lastVisibleIsSpacer = true; 
    273                                                         }else{ 
    274                                                                 lastVisible = td; 
    275                                                                 lastVisibleIsSpacer = true; 
    276                                                         } 
    277                                                 }else{ 
    278                                                         if(td.style.display != "none"){ 
    279                                                                 lastVisible = td; 
    280                                                                 lastVisibleIsSpacer = false; 
    281                                                         } 
    282                                                 } 
    283                                         }); 
    284                                 } 
    285                 }, 
    286  
    287                 highlightButton: function(name){ 
    288                         var bn = name+"Button"; 
    289                         if(this[bn]){ 
    290                                 with(this[bn].style){ 
    291                                         backgroundColor = "White"; 
    292                                         border = "1px solid #aeaeab"; 
    293                                 } 
    294                         } 
    295                 }, 
    296  
    297                 unhighlightButton: function(name){ 
    298                         var bn = name+"Button"; 
    299                         if(this[bn]){ 
    300                                 // dojo.debug("unhighlighting:", name); 
    301                                 with(this[bn].style){ 
    302                                         backgroundColor = ""; 
    303                                         border = ""; 
    304                                 } 
    305                         } 
    306                 } 
     552//              exec: function(what, arg){ /* dojo.debug(what, new Date()); */ } 
    307553        }, 
    308554        "html", 
    309555        function(){ 
    310                 // dojo.event.connect(this, "fillInTemplate", this, "hideUnusableButtons"); 
    311556                dojo.event.connect(this, "fillInTemplate", dojo.lang.hitch(this, function(){ 
    312557                        if(dojo.render.html.ie){ 
  • trunk/src/widget/RichText.js

    r5280 r5306  
    293293                                        var node = this.editNode.firstChild; 
    294294                                        while(node){ 
    295                                                 dojo.withGlobal(this.window, "selectElement", dojo.html.selection, node.firstChild); 
     295                                                dojo.withGlobal(this.window, "selectElement", dojo.html.selection, [node.firstChild]); 
    296296                                                var nativename = node.tagName.toLowerCase(); 
    297297                                                this._local2NativeFormatNames[nativename] = this.queryCommandValue("formatblock"); 
     
    622622                                '    body,html { padding: 0; margin: 0; }' + //font: ' + font + '; }' + 
    623623                                (this.height ? '' : '    body,  { overflow: hidden; }') + 
    624                                 //'    #bodywrapper {  }' + 
    625624                                '</style>' + 
    626625                                //'<base href="' + dojo.global().location + '">' + 
    627                                 '<body><div id="bodywrapper">' + html + '</div></body></html>'; 
     626                                '<body>' + html + '</body></html>'; 
    628627 
    629628                        this._cacheLocalBlockFormatNames(); 
     
    678677                                this.document = this.object.DOM; 
    679678                                this.window = this.document.parentWindow; 
    680                                 this.editNode = this.document.body.firstChild; 
     679                                this.editNode = this.document.body; 
    681680                                this.domNode.style.height = this.height ? this.height : this.minHeight; 
    682681                                this.connect(this, "onDisplayChanged", "_updateHeight"); 
     
    718717                                        dojo.event.connect("before", this, "close", unBlur, "unBlur"); 
    719718                                        dojo.event.browser.addListener(this.document, "focus", dojo.lang.hitch(this, "onFocus")); 
    720                                  
    721                                         // safari can't handle key listeners, it kills the speed 
     719 
    722720                                        var addListener = dojo.event.browser.addListener; 
    723721                                        addListener(this.document, "keypress", dojo.lang.hitch(this, "onKeyPress")); 
     
    10351033                        if(command == "formatblock"){ 
    10361034                                if(drh.safari){ command = "heading"; } 
    1037                                 if(this.object){ //IE activeX mode 
     1035                                if(this.object && joinObject.args[1]){ //IE activeX mode 
    10381036                                        joinObject.args[1] = this._native2LocalFormatNames[joinObject.args[1]]; 
    10391037                                } 
     
    11601158                        if(this.object){ 
    11611159                                switch (command) { 
     1160                                        case "hilitecolor": 
     1161                                                command = "setbackcolor"; 
     1162                                                break; 
    11621163                                        case "forecolor": 
    11631164                                        case "backcolor": 
     
    11761177                                                return; 
    11771178                                        } 
    1178                                         argument="<strike>"+range.htmlText+"<strike>"; 
     1179                                        argument=range.htmlText.strike(); 
    11791180                                }else if(command == "inserthorizontalrule"){ 
    11801181                                        command = "inserthtml"; 
     
    12511252                                 
    12521253                                // select our link and unlink 
    1253                                 var a = dojo.withGlobal(this.window, "getAncestorElement", dojo.html.selection, 'a'); 
    1254                                 dojo.withGlobal(this.window, "selectElement", dojo.html.selection, a); 
     1254                                var a = dojo.withGlobal(this.window, "getAncestorElement", dojo.html.selection, ['a']); 
     1255                                dojo.withGlobal(this.window, "selectElement", dojo.html.selection, [a]); 
    12551256                                 
    12561257                                returnValue = this.document.execCommand("unlink", false, null); 
     
    13031304                        if(this.object){ 
    13041305                                switch (command) { 
     1306                                        case "hilitecolor": 
     1307                                                command = "setbackcolor"; 
     1308                                                break; 
    13051309                                        case "forecolor": 
    13061310                                        case "backcolor": 
     
    13271331                                // mozilla returns true always 
    13281332                                if(command == "unlink" && dojo.render.html.mozilla){ 
    1329                                         return dojo.withGlobal(this.window, "hasAncestorElement", dojo.html.selection, 'a'); 
     1333                                        return dojo.withGlobal(this.window, "hasAncestorElement", dojo.html.selection, ['a']); 
    13301334                                } else if (command == "inserttable" && dojo.render.html.mozilla) { 
    13311335                                        return true; 
     
    13461350                                }else if(command == "strikethrough"){ 
    13471351                                        //check whether we are under a <strike> 
    1348                                         return dojo.withGlobal(this.window, "hasAncestorElement", dojo.html.selection, 'strike'); 
     1352                                        return dojo.withGlobal(this.window, "hasAncestorElement", dojo.html.selection, ['strike']); 
    13491353                                }else if(command == "inserthorizontalrule"){ 
    13501354                                        return false; 
     
    13931397                placeCursorAtStart: function(){ 
    13941398                        this.focus(); 
    1395                         dojo.withGlobal(this.window, "selectElementChildren", dojo.html.selection, this.editNode); 
    1396                         dojo.withGlobal(this.window, "collapse", dojo.html.selection, true); 
     1399                        //see comments in placeCursorAtEnd 
     1400                        if(dojo.render.html.moz && this.editNode.firstChild &&  
     1401                                this.editNode.firstChild.nodeType != dojo.dom.TEXT_NODE){ 
     1402                                dojo.withGlobal(this.window, "selectElementChildren", dojo.html.selection, [this.editNode.firstChild]); 
     1403                        }else{ 
     1404                                dojo.withGlobal(this.window, "selectElementChildren", dojo.html.selection, [this.editNode]); 
     1405                        } 
     1406                        dojo.withGlobal(this.window, "collapse", dojo.html.selection, [true]); 
    13971407                }, 
    13981408 
     
    14031413                        if(dojo.render.html.moz && this.editNode.lastChild &&  
    14041414                                this.editNode.lastChild.nodeType != dojo.dom.TEXT_NODE){ 
    1405                                 dojo.withGlobal(this.window, "selectElementChildren", dojo.html.selection, this.editNode.lastChild); 
     1415                                dojo.withGlobal(this.window, "selectElementChildren", dojo.html.selection, [this.editNode.lastChild]); 
    14061416                        }else{ 
    1407                                 dojo.withGlobal(this.window, "selectElementChildren", dojo.html.selection, this.editNode); 
    1408                         } 
    1409                         dojo.withGlobal(this.window, "collapse", dojo.html.selection, false); 
     1417                                dojo.withGlobal(this.window, "selectElementChildren", dojo.html.selection, [this.editNode]); 
     1418                        } 
     1419                        dojo.withGlobal(this.window, "collapse", dojo.html.selection, [false]); 
    14101420                }, 
    14111421 
     
    15221532                        }catch(e){ /* squelch */ } 
    15231533 
     1534                        if(dojo.render.html.ie && !this.object){ 
     1535                                //removing appended <P>&nbsp;</P> for IE in none-activeX mode 
     1536                                var re = new RegExp("(?:<p>&nbsp;</p>[\n\r]*)+$", "i"); 
     1537                                ec = ec.replace(re,""); 
     1538                        } 
     1539         
    15241540                        ec = this._postFilterContent(ec); 
    15251541 
  • trunk/src/widget/templates/EditorToolbar.css

    r5163 r5306  
    6767} 
    6868 
    69 span.icon { 
     69.dojoE2TBIcon { 
    7070        display: block; 
    7171        text-align: center; 
     
    7979 
    8080 
    81 span.icon[class~=icon] { 
     81.dojoE2TBIcon[class~=dojoE2TBIcon] { 
     82} 
     83 
     84.ToolbarButtonLatched { 
     85    border: #316ac5 1px solid; 
     86    background-color: #c1d2ee; 
     87} 
     88 
     89.ToolbarButtonHighlighted { 
     90    border: #316ac5 1px solid; 
     91    background-color: #dff1ff; 
     92} 
     93 
     94.ToolbarButtonDisabled{ 
     95    filter: gray() alpha(opacity=30); /* IE */ 
     96    opacity: 0.30; /* Safari, Opera and Mozilla */ 
    8297} 
    8398 
     
    96111        font-size: 14px; 
    97112} 
     113  
     114.dojoE2TBIcon_Sep { width: 5px; min-width: 5px; max-width: 5px; background-position: 0px 0px} 
     115.dojoE2TBIcon_Backcolor { background-position: -18px 0px} 
     116.dojoE2TBIcon_Bold { background-position: -36px 0px} 
     117.dojoE2TBIcon_Cancel { background-position: -54px 0px} 
     118.dojoE2TBIcon_Copy { background-position: -72px 0px} 
     119.dojoE2TBIcon_Link { background-position: -90px 0px} 
     120.dojoE2TBIcon_Cut { background-position: -108px 0px} 
     121.dojoE2TBIcon_Delete { background-position: -126px 0px} 
     122.dojoE2TBIcon_TextColor { background-position: -144px 0px} 
     123.dojoE2TBIcon_BackgroundColor { background-position: -162px 0px} 
     124.dojoE2TBIcon_Indent { background-position: -180px 0px} 
     125.dojoE2TBIcon_HorizontalLine { background-position: -198px 0px} 
     126.dojoE2TBIcon_Image { background-position: -216px 0px} 
     127.dojoE2TBIcon_NumberedList { background-position: -234px 0px} 
     128.dojoE2TBIcon_Table { background-position: -252px 0px} 
     129.dojoE2TBIcon_BulletedList { background-position: -270px 0px} 
     130.dojoE2TBIcon_Italic { background-position: -288px 0px} 
     131.dojoE2TBIcon_CenterJustify { background-position: -306px 0px} 
     132.dojoE2TBIcon_BlockJustify { background-position: -324px 0px} 
     133.dojoE2TBIcon_LeftJustify { background-position: -342px 0px} 
     134.dojoE2TBIcon_RightJustify { background-position: -360px 0px} 
     135.dojoE2TBIcon_left_to_right { background-position: -378px 0px} 
     136.dojoE2TBIcon_list_bullet_indent { background-position: -396px 0px} 
     137.dojoE2TBIcon_list_bullet_outdent { background-position: -414px 0px} 
     138.dojoE2TBIcon_list_num_indent { background-position: -432px 0px} 
     139.dojoE2TBIcon_list_num_outdent { background-position: -450px 0px} 
     140.dojoE2TBIcon_Outdent { background-position: -468px 0px} 
     141.dojoE2TBIcon_Paste { background-position: -486px 0px} 
     142.dojoE2TBIcon_Redo { background-position: -504px 0px} 
     143dojoE2TBIcon_RemoveFormat { background-position: -522px 0px} 
     144.dojoE2TBIcon_right_to_left { background-position: -540px 0px} 
     145.dojoE2TBIcon_Save { background-position: -558px 0px} 
     146.dojoE2TBIcon_Space { background-position: -576px 0px} 
     147.dojoE2TBIcon_StrikeThrough { background-position: -594px 0px} 
     148.dojoE2TBIcon_Subscript { background-position: -612px 0px} 
     149.dojoE2TBIcon_Superscript { background-position: -630px 0px} 
     150.dojoE2TBIcon_Underline { background-position: -648px 0px} 
     151.dojoE2TBIcon_Undo { background-position: -666px 0px} 
     152.dojoE2TBIcon_WikiWord { background-position: -684px 0px} 
    98153 
    99 .sep { width: 5px; min-width: 5px; max-width: 5px; background-position: 0px 0px} 
    100 .backcolor { background-position: -18px 0px} 
    101 .bold { background-position: -36px 0px} 
    102 .cancel { background-position: -54px 0px} 
    103 .copy { background-position: -72px 0px} 
    104 .createlink { background-position: -90px 0px} 
    105 .cut { background-position: -108px 0px} 
    106 .delete { background-position: -126px 0px} 
    107 .forecolor { background-position: -144px 0px} 
    108 .hilitecolor { background-position: -162px 0px} 
    109 .indent { background-position: -180px 0px} 
    110 .inserthorizontalrule { background-position: -198px 0px} 
    111 .insertimage { background-position: -216px 0px} 
    112 .insertorderedlist { background-position: -234px 0px} 
    113 .inserttable { background-position: -252px 0px} 
    114 .insertunorderedlist { background-position: -270px 0px} 
    115 .italic { background-position: -288px 0px} 
    116 .justifycenter { background-position: -306px 0px} 
    117 .justifyfull { background-position: -324px 0px} 
    118 .justifyleft { background-position: -342px 0px} 
    119 .justifyright { background-position: -360px 0px} 
    120 .left_to_right { background-position: -378px 0px} 
    121 .list_bullet_indent { background-position: -396px 0px} 
    122 .list_bullet_outdent { background-position: -414px 0px} 
    123 .list_num_indent { background-position: -432px 0px} 
    124 .list_num_outdent { background-position: -450px 0px} 
    125 .outdent { background-position: -468px 0px} 
    126 .paste { background-position: -486px 0px} 
    127 .redo { background-position: -504px 0px} 
    128 .removeformat { background-position: -522px 0px} 
    129 .right_to_left { background-position: -540px 0px} 
    130 .save { background-position: -558px 0px} 
    131 .space { background-position: -576px 0px} 
    132 .strikethrough { background-position: -594px 0px} 
    133 .subscript { background-position: -612px 0px} 
    134 .superscript { background-position: -630px 0px} 
    135 .underline { background-position: -648px 0px} 
    136 .undo { background-position: -666px 0px} 
    137 .wikiword { background-position: -684px 0px} 
    138  
  • trunk/src/widget/templates/EditorToolbarOneline.html

    r5163 r5306  
    1 <div class="EditorToolbarDomNode EditorToolbarSmallBg"  
    2         unselectable="on" dojoOnMouseDown="preventSelect"> 
     1<div class="EditorToolbarDomNode EditorToolbarSmallBg"> 
    32        <table cellpadding="1" cellspacing="0" border="0"> 
    43                <!-- 
     
    2726                --> 
    2827                <tbody> 
    29                         <tr valign="top" align="left" dojoAttachPoint="oneLineTr"> 
     28                        <tr valign="top" align="left"> 
    3029                                <td> 
    3130                                        <!-- htmltoggle --> 
    32                                         <span class="iconContainer" dojoAttachPoint="htmltoggleButton" 
    33                                                 dojoOnClick="htmltoggleClick; buttonClick;" style="display: none;"> 
    34                                                 <span title="Toggle Rich Text and HTML Markup Editing Modes" class="icon"  
    35                                                 style="background-image: none; width: 30px;"  
    36                                                 unselectable="on">&lt;h&gt;</span> 
    37                                         </span> 
    38                                 </td> 
    39                                 <td> 
    40                                         <!-- wikiword --> 
     31                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="htmltoggle"> 
     32                                                <span title="Toggle Rich Text and HTML Markup Editing Modes" class="dojoE2TBIcon"  
     33                                                style="background-image: none; width: 30px;" >&lt;h&gt;</span> 
     34                                        </span> 
     35                                </td> 
     36                                <!-- wikiword --> 
     37                                <!--td> 
    4138                                        <span class="iconContainer" dojoAttachPoint="wikiwordButton" 
    4239                                                dojoOnClick="wikiwordClick; buttonClick;" style="display: none;"> 
    43                                                 <span title="Toggle Wiki Word" class="icon wikiword"  
     40                                                <span title="Toggle Wiki Word" class="dojoE2TBIcon dojoE2TBIcon_wikiword"  
    4441                                                unselectable="on">&nbsp;</span> 
    4542                                        </span> 
     43                                </td--> 
     44                                <td> 
     45                                        <!-- copy --> 
     46                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="copy"> 
     47                                                <span title="Copy (Ctrl-C)" class="dojoE2TBIcon dojoE2TBIcon_Copy">&nbsp;</span> 
     48                                        </span> 
    4649                                </td> 
    4750                                <td> 
    4851                                        <!-- paste --> 
    49                                         <span class="iconContainer" dojoAttachPoint="copyButton" 
    50                                                 unselectable="on" dojoOnClick="copyClick; buttonClick;"> 
    51                                                 <span title="Copy (Ctrl-C)" class="icon copy" unselectable="on">&nbsp;</span> 
    52                                         </span> 
    53                                 </td> 
    54                                 <td> 
    55                                         <!-- copy --> 
    56                                         <span class="iconContainer" dojoAttachPoint="pasteButton" 
    57                                                 dojoOnClick="pasteClick; buttonClick;" unselectable="on"> 
    58                                                 <span title="Paste (Ctrl-V)" class="icon paste" unselectable="on">&nbsp;</span> 
     52                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="paste"> 
     53                                                <span title="Paste (Ctrl-V)" class="dojoE2TBIcon dojoE2TBIcon_Paste">&nbsp;</span> 
    5954                                        </span> 
    6055                                </td> 
    6156                                <td> 
    6257                                        <!-- undo --> 
    63                                         <span class="iconContainer" dojoAttachPoint="undoButton" 
    64                                                 dojoOnClick="undoClick; buttonClick;" unselectable="on"> 
     58                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="undo"> 
    6559                                                <!-- FIXME: should we have the text "undo" here? --> 
    66                                                 <span title="Undo (Ctrl-Z)" class="icon undo" unselectable="on">&nbsp;</span> 
     60                                                <span title="Undo (Ctrl-Z)" class="dojoE2TBIcon dojoE2TBIcon_Undo">&nbsp;</span> 
    6761                                        </span> 
    6862                                </td> 
    6963                                <td> 
    7064                                        <!-- redo --> 
    71                                         <span class="iconContainer" dojoAttachPoint="redoButton" 
    72                                                 dojoOnClick="redoClick; buttonClick;" unselectable="on"> 
    73                                                 <span title="Redo (Ctrl-R)" class="icon redo" unselectable="on">&nbsp;</span> 
    74                                         </span> 
    75                                 </td> 
    76                                 <td isSpacer="true"> 
    77                                         <!-- spacer --> 
    78                                         <span class="iconContainer"> 
    79                                                 <span class="icon sep" unselectable="on"  
     65                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="redo"> 
     66                                                <span title="Redo (Ctrl-R)" class="dojoE2TBIcon dojoE2TBIcon_Redo">&nbsp;</span> 
     67                                        </span> 
     68                                </td> 
     69                                <td isSpacer="true"> 
     70                                        <!-- spacer --> 
     71                                        <span class="iconContainer"> 
     72                                                <span class="dojoE2TBIcon dojoE2TBIcon_Sep"     style="width: 5px; min-width: 5px;"></span> 
     73                                        </span> 
     74                                </td> 
     75                                <td> 
     76                                        <!-- link --> 
     77                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="createlink"> 
     78                                                <span title="Create Link" class="dojoE2TBIcon dojoE2TBIcon_Link">&nbsp;</span> 
     79                                        </span> 
     80                                </td> 
     81                                <td> 
     82                                        <!-- insertimage --> 
     83                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="insertimage"> 
     84                                                <span title="Insert Image" class="dojoE2TBIcon dojoE2TBIcon_Image">&nbsp;</span> 
     85                                        </span> 
     86                                </td> 
     87                                <td> 
     88                                        <!-- inserthorizontalrule --> 
     89                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="inserthorizontalrule"> 
     90                                                <span title="Insert Horizontal Rule" class="dojoE2TBIcon dojoE2TBIcon_HorizontalLine ">&nbsp;</span> 
     91                                        </span> 
     92                                </td> 
     93                                <td> 
     94                                        <!-- bold --> 
     95                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="bold"> 
     96                                                <span title="Toggle Bold (Ctrl-B)" class="dojoE2TBIcon dojoE2TBIcon_Bold">&nbsp;</span> 
     97                                        </span> 
     98                                </td> 
     99                                <td> 
     100                                        <!-- italic --> 
     101                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="italic"> 
     102                                                <span title="Toggle Italic (Ctrl-I)" class="dojoE2TBIcon dojoE2TBIcon_Italic">&nbsp;</span> 
     103                                        </span> 
     104                                </td> 
     105                                <td> 
     106                                        <!-- underline --> 
     107                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="underline"> 
     108                                                <span title="Toggle Underline (Ctrl-U)" class="dojoE2TBIcon dojoE2TBIcon_Underline">&nbsp;</span> 
     109                                        </span> 
     110                                </td> 
     111                                <td> 
     112                                        <!-- strikethrough --> 
     113                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="strikethrough"> 
     114                                                <span title="Toggle Strike-Through"  
     115                                                        class="dojoE2TBIcon dojoE2TBIcon_StrikeThrough">&nbsp;</span> 
     116                                        </span> 
     117                                </td> 
     118                                <td isSpacer="true"> 
     119                                        <!-- spacer --> 
     120                                        <span class="iconContainer"> 
     121                                                <span class="dojoE2TBIcon dojoE2TBIcon_Sep"  
    80122                                                        style="width: 5px; min-width: 5px;"></span> 
    81123                                        </span> 
    82124                                </td> 
    83125                                <td> 
    84                                         <!-- link --> 
    85                                         <span class="iconContainer" dojoAttachPoint="linkButton" 
    86                                                 unselectable="on" dojoOnClick="linkClick; buttonClick;"> 
    87                                                 <span title="Create Link" class="icon createlink" unselectable="on">&nbsp;</span> 
    88                                         </span> 
    89                                 </td> 
    90                                 <td> 
    91                                         <!-- insertimage --> 
    92                                         <span class="iconContainer"  
    93                                                 style="display: none;" 
    94                                                 dojoAttachPoint="insertimageButton" 
    95                                                 unselectable="on" dojoOnClick="insertimageClick; buttonClick;"> 
    96                                                 <span title="Insert Image" class="icon insertimage" unselectable="on">&nbsp;</span> 
    97                                         </span> 
    98                                 </td> 
    99                                 <td> 
    100                                         <!-- inserthorizontalrule --> 
    101                                         <span class="iconContainer" dojoAttachPoint="inserthorizontalruleButton" 
    102                                                 unselectable="on" dojoOnClick="inserthorizontalruleClick; buttonClick;"> 
    103                                                 <span title="Insert Horizontal Rule" class="icon inserthorizontalrule " unselectable="on">&nbsp;</span> 
    104                                         </span> 
    105                                 </td> 
    106                                 <td> 
    107                                         <!-- bold --> 
    108                                         <span class="iconContainer" dojoAttachPoint="boldButton" 
    109                                                 unselectable="on" dojoOnClick="boldClick; buttonClick;"> 
    110                                                 <span title="Toggle Bold (Ctrl-B)" class="icon bold" unselectable="on">&nbsp;</span> 
    111                                         </span> 
    112                                 </td> 
    113                                 <td> 
    114                                         <!-- italic --> 
    115                                         <span class="iconContainer" dojoAttachPoint="italicButton" 
    116                                                 dojoOnClick="italicClick; buttonClick;"> 
    117                                                 <span title="Toggle Italic (Ctrl-I)" class="icon italic" unselectable="on">&nbsp;</span> 
    118                                         </span> 
    119                                 </td> 
    120                                 <td> 
    121                                         <!-- underline --> 
    122                                         <span class="iconContainer" dojoAttachPoint="underlineButton" 
    123                                                 dojoOnClick="underlineClick; buttonClick;"> 
    124                                                 <span title="Toggle Underline (Ctrl-U)" class="icon underline" unselectable="on">&nbsp;</span> 
    125                                         </span> 
    126                                 </td> 
    127                                 <td> 
    128                                         <!-- strikethrough --> 
    129                                         <span class="iconContainer" dojoAttachPoint="strikethroughButton" 
    130                                                 dojoOnClick="strikethroughClick; buttonClick;"> 
    131                                                 <span title="Toggle Strike-Through"  
    132                                                         class="icon strikethrough" unselectable="on">&nbsp;</span> 
    133                                         </span> 
    134                                 </td> 
    135                                 <td isSpacer="true"> 
    136                                         <!-- spacer --> 
    137                                         <span class="iconContainer"> 
    138                                                 <span class="icon sep" unselectable="on"  
    139                                                         style="width: 5px; min-width: 5px;"></span> 
    140                                         </span> 
    141                                 </td> 
    142                                 <td> 
    143126                                        <!-- insertunorderedlist --> 
    144                                         <span class="iconContainer" dojoAttachPoint="insertunorderedlistButton" 
    145                                                 unselectable="on"  
    146                                                 dojoOnClick="insertunorderedlistClick; buttonClick;"> 
     127                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="insertunorderedlist"> 
    147128                                                <span title="Insert Bullet List"  
    148                                                         class="icon insertunorderedlist" unselectable="on">&nbsp;</span> 
     129                                                        class="dojoE2TBIcon dojoE2TBIcon_BulletedList">&nbsp;</span> 
    149130                                        </span> 
    150131                                </td> 
    151132                                <td> 
    152133                                        <!-- insertorderedlist --> 
    153                                         <span class="iconContainer" dojoAttachPoint="insertorderedlistButton" 
    154                                                 unselectable="on" dojoOnClick="insertorderedlistClick; buttonClick;"> 
     134                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="insertorderedlist"> 
    155135                                                <span title="Insert Numbered List"  
    156                                                         class="icon insertorderedlist" unselectable="on">&nbsp;</span> 
    157                                         </span> 
    158                                 </td> 
    159                                 <td isSpacer="true"> 
    160                                         <!-- spacer --> 
    161                                         <span class="iconContainer"> 
    162                                                 <span class="icon sep" unselectable="on"  
    163                                                         style="width: 5px; min-width: 5px;"></span> 
     136                                                        class="dojoE2TBIcon dojoE2TBIcon_NumberedList">&nbsp;</span> 
     137                                        </span> 
     138                                </td> 
     139                                <td isSpacer="true"> 
     140                                        <!-- spacer --> 
     141                                        <span class="iconContainer"> 
     142                                                <span class="dojoE2TBIcon dojoE2TBIcon_Sep" style="width: 5px; min-width: 5px;"></span> 
    164143                                        </span> 
    165144                                </td> 
    166145                                <td> 
    167146                                        <!-- indent --> 
    168                                         <span class="iconContainer" dojoAttachPoint="indentButton" 
    169                                                 unselectable="on" dojoOnClick="indentClick; buttonClick;"> 
    170                                                 <span title="Indent Selection" class="icon indent"  
     147                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="indent"> 
     148                                                <span title="Indent Selection" class="dojoE2TBIcon dojoE2TBIcon_Indent"  
    171149                                                        unselectable="on">&nbsp;</span> 
    172150                                        </span> 
     
    174152                                <td> 
    175153                                        <!-- outdent --> 
    176                                         <span class="iconContainer" dojoAttachPoint="outdentButton" 
    177                                                 unselectable="on" dojoOnClick="outdentClick; buttonClick;"> 
    178                                                 <span title="Outdent Selection" class="icon outdent"  
    179                                                         unselectable="on">&nbsp;</span> 
    180                                         </span> 
    181                                 </td> 
    182                                 <td isSpacer="true"> 
    183                                         <!-- spacer --> 
    184                                         <span class="iconContainer"> 
    185                                                 <span class="icon sep" unselectable="on"  
    186                                                         style="width: 5px; min-width: 5px;"></span> 
     154                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="outdent"> 
     155                                                <span title="Outdent Selection" class="dojoE2TBIcon dojoE2TBIcon_Outdent"  
     156                                                        unselectable="on">&nbsp;</span> 
     157                                        </span> 
     158                                </td> 
     159                                <td isSpacer="true"> 
     160                                        <!-- spacer --> 
     161                                        <span class="iconContainer"> 
     162                                                <span class="dojoE2TBIcon dojoE2TBIcon_Sep" style="width: 5px; min-width: 5px;"></span> 
    187163                                        </span> 
    188164                                </td> 
    189165                                <td> 
    190166                                        <!-- forecolor --> 
    191                                         <span class="iconContainer" dojoAttachPoint="forecolorButton" 
    192                                                 unselectable="on" dojoOnClick="forecolorClick; buttonClick;"> 
    193                                                 <span title="Change Text Color" class="icon forecolor"  
    194                                                         unselectable="on">&nbsp;</span> 
    195                                         </span> 
    196                                         <div class="ColorDropdownContainer"  
    197                                                 style="display: none; margin-top: 22px;" 
    198                                                 dojoAttachPoint="forecolorDropDown"> 
    199                                         </div> 
     167                                        <span class="iconContainer dojoEditorToolbarItem" dojoETItemName="forecolor">