Changeset 7452

Show
Ignore:
Timestamp:
02/26/07 00:42:36 (23 months ago)
Author:
liucougar
Message:

get rid of activex support in richtext as it is no long available in IE7. Custom undo support for IE will be added later;
make use of while loop instead to avoid accessing length according to: http://archive.dojotoolkit.org/nightly/bench/live_collections.html

Location:
trunk/src/widget
Files:
3 modified

Legend:

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

    r7206 r7452  
    3333                var oCommand; 
    3434                name = name.toLowerCase(); 
    35                 for(var i=0;i<this._registeredHandlers.length;i++){ 
    36                         oCommand = this._registeredHandlers[i](editor, name); 
     35                var i=0, handle, handers=this._registeredHandlers; 
     36                while(handle=handers[i++]){ 
     37                        oCommand = handle(editor, name); 
    3738                        if(oCommand){ 
    3839                                return oCommand; 
     
    357358                                                this._htmlEditNode = dojo.doc().createElement("textarea"); 
    358359                                                dojo.html.insertAfter(this._htmlEditNode, this.editorObject); 
     360                                                dojo.event.connect(this._htmlEditNode,'onfocus',this,'onFocus'); 
    359361                                        } 
    360362 
  • trunk/src/widget/Editor2Toolbar.js

    r7293 r7452  
    2929        removeHandler: function(func){ 
    3030                // summary: remove a registered handler 
    31                 for(var i=0;i<this._registeredHandlers.length;i++){ 
    32                         if(func === this._registeredHandlers[i]){ 
    33                                 delete this._registeredHandlers[i]; 
     31                var i=0,handle,handles=this._registeredHandlers; 
     32                while(handle=handles[i++]){ 
     33                        if(func === handle){ 
     34                                delete this._registeredHandlers[--i]; 
    3435                                return; 
    3536                        } 
     
    3839        }, 
    3940        destroy: function(){ 
    40                 for(var i=0;i<this._registeredHandlers.length;i++){ 
    41                         delete this._registeredHandlers[i]; 
     41                var i=this._registeredHandlers.length-1,handles=this._registeredHandlers; 
     42                while(handles[i--]){ 
     43                        delete this._registeredHandlers[i+1]; 
    4244                } 
    4345        } 
     
    5153                var item; 
    5254                name = name.toLowerCase(); 
    53                 for(var i=0;i<this._registeredHandlers.length;i++){ 
    54                         item = this._registeredHandlers[i](name); 
     55                var i=0, handle, handles=this._registeredHandlers; 
     56                while(handle=handles[i++]){ 
     57                        item = handle(name); 
    5558                        if(item){ 
    5659                                return item; 
     
    181184                // summary: disable selection on the passed node and all its children 
    182185                dojo.html.disableSelection(rootnode); 
    183                 var nodes = rootnode.all || rootnode.getElementsByTagName("*"); 
    184                 for(var x=0; x<nodes.length; x++){ 
    185                         dojo.html.disableSelection(nodes[x]); 
     186                var i=0,node,nodes = rootnode.all || rootnode.getElementsByTagName("*"); 
     187                while(node=nodes[i++]){ 
     188                        dojo.html.disableSelection(node); 
    186189                } 
    187190        }, 
     
    348351 
    349352                postCreate: function(){ 
    350                         var nodes = dojo.html.getElementsByClass("dojoEditorToolbarItem", this.domNode/*, this.itemNodeType*/); 
     353                        var i=0,node,nodes = dojo.html.getElementsByClass("dojoEditorToolbarItem", this.domNode/*, this.itemNodeType*/); 
    351354 
    352355                        this.items = {}; 
    353                         for(var x=0; x<nodes.length; x++){ 
    354                                 var node = nodes[x]; 
     356                        while(node=nodes[i++]){ 
    355357                                var itemname = node.getAttribute("dojoETItemName"); 
    356358                                if(itemname){ 
  • trunk/src/widget/RichText.js

    r7421 r7452  
    126126                isLoaded: false, 
    127127 
    128                 // useActiveX: Boolean 
    129                 //              whether to use the active-x object in IE 
    130                 useActiveX: false, 
    131  
    132128                // _SEPARATOR: String 
    133129                //              used to concat contents from multiple textareas into a single string 
     
    189185                events: ["onBlur", "onFocus", "onKeyPress", "onKeyDown", "onKeyUp", "onClick"], 
    190186 
    191                 /** 
    192                  * Transforms the node referenced in this.domNode into a rich text editing 
    193                  * node. This can result in the creation and replacement with an <iframe> if 
    194                  * designMode is used, an <object> and active-x component if inside of IE or 
    195                  * a reguler element if contentEditable is available. 
    196                  */ 
    197187                open: function (/*DomNode, optional*/element) { 
    198188                        // summary: 
    199189                        //              Transforms the node referenced in this.domNode into a rich text editing 
    200                         //              node. This can result in the creation and replacement with an <iframe> if 
    201                         //              designMode is used, an <object> and active-x component if inside of IE or 
    202                         //              a reguler element if contentEditable is available. 
     190                        //              node. This will result in the creation and replacement with an <iframe>  
     191                        //              if designMode(FF)/contentEditable(IE) is used. 
    203192 
    204193                        if(this.onLoadDeferred.fired >= 0){ 
     
    290279                                var saveTextarea = dojo.doc().getElementById("dojo.widget.RichText.savedContent"); 
    291280                                if (saveTextarea.value != "") { 
    292                                         var datas = saveTextarea.value.split(this._SEPARATOR); 
    293                                         for (var i = 0; i < datas.length; i++) { 
    294                                                 var data = datas[i].split(":"); 
     281                                        var datas = saveTextarea.value.split(this._SEPARATOR), i=0, dat; 
     282                                        while(dat=datas[i++]){ 
     283                                                var data = dat.split(":"); 
    295284                                                if (data[0] == this.saveName) { 
    296285                                                        html = data[1]; 
     
    304293                        } 
    305294 
    306                         if(h.ie70 && this.useActiveX){ 
    307                                 dojo.debug("activeX in ie70 is not currently supported, useActiveX is ignored for now."); 
    308                                 this.useActiveX = false; 
    309                         } 
    310295                        this.isClosed = false; 
    311296                        // Safari's selections go all out of whack if we do it inline, 
    312297                        // so for now IE is our only hero 
    313298                        //if (typeof document.body.contentEditable != "undefined") { 
    314                         if(this.useActiveX && h.ie){ // active-x 
    315                                 var self = this; 
    316                                 //if call _drawObject directly here, textarea replacement 
    317                                 //won't work: no content is shown. However, add a delay 
    318                                 //can workaround this. No clue why. 
    319                                 setTimeout(function(){self._drawObject(html);}, 0); 
    320                         }else if(h.ie || this._safariIsLeopard() || h.opera){ // contentEditable, easy 
     299                        if(h.ie || this._safariIsLeopard() || h.opera){ // contentEditable, easy 
    321300                                this.iframe = dojo.doc().createElement('iframe'); 
    322301                                this.iframe.src = 'javascript:void(0)'; 
     
    363342                                // elements have margins set in CSS :-( 
    364343 
     344                                //in IE, names for blockformat is locale dependent, so we cache the values here 
    365345                                //if the normal way fails, we try the hard way to get the list 
    366346                                //do not use _cacheLocalBlockFormatNames here, as it will trigger security warning in IE7 
    367347                                //in the array below, ul can not come directly after ol, otherwise the queryCommandValue returns Normal for it 
    368348                                var formats = ['p', 'pre', 'address', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ol', 'div', 'ul']; 
    369                                 var localhtml = ""; 
    370                                 for(var i=0; i<formats.length; i++){  
    371                                         if(formats[i].charAt(1) != 'l'){ 
    372                                                 localhtml += "<"+formats[i]+"><span>content</span></"+formats[i]+">"; 
     349                                var localhtml = "", format, i=0; 
     350                                while(format=formats[i++]){ 
     351                                        if(format.charAt(1) != 'l'){ 
     352                                                localhtml += "<"+format+"><span>content</span></"+format+">"; 
    373353                                        }else{ 
    374                                                 localhtml += "<"+formats[i]+"><li>content</li></"+formats[i]+">"; 
     354                                                localhtml += "<"+format+"><li>content</li></"+format+">"; 
    375355                                        } 
    376356                                } 
     
    417397                        dojo.html.addClass(this.domNode, "RichTextEditable"); 
    418398                }, 
     399 
     400                //static cache variables shared among all instance of this class 
     401                _local2NativeFormatNames: {}, 
     402                _native2LocalFormatNames: {}, 
    419403 
    420404                _hasCollapseableMargin: function(/*DomNode*/element, /*String*/side) { 
     
    673657                        this.editingAreaStyleSheets = []; 
    674658 
    675                         var text=''; 
    676                         if(files.length>0){ 
    677                                 for(var i=0;i<files.length;i++){ 
    678                                         var url = files[i]; 
    679                                         if(url){ 
    680                                                 var abstring = (new dojo.uri.Uri(dojo.global().location, url)).toString(); 
    681                                                 this.editingAreaStyleSheets.push(abstring); 
    682                                                 text += '<link rel="stylesheet" type="text/css" href="'+abstring+'"/>'  
    683                                         } 
    684                                 } 
    685                         } 
     659                        var text='', i=0, url; 
     660                        while(url=files[i++]){ 
     661                                var abstring = (new dojo.uri.Uri(dojo.global().location, url)).toString(); 
     662                                this.editingAreaStyleSheets.push(abstring); 
     663                                text += '<link rel="stylesheet" type="text/css" href="'+abstring+'"/>'  
     664                        } 
    686665                        return text; 
    687666                }, 
     
    732711                        delete this.editingAreaStyleSheets[index]; 
    733712 
    734                         var links = this.document.getElementsByTagName("link"); 
    735                         for(var i=0;i<links.length;i++){ 
    736                                 if(links[i].href == url){ 
     713                        var link, i=0, links = this.document.getElementsByTagName("link"); 
     714                        while(link=links[i++]){ 
     715                                if(link.href == url){ 
    737716                                        if(dojo.render.html.ie){//we need to empty the href first, to get IE to remove the rendered styles 
    738                                                 links[i].href=""; 
     717                                                link.href=""; 
    739718                                        } 
    740                                         dojo.html.removeNode(links[i]); 
     719                                        dojo.html.removeNode(link); 
    741720                                        break; 
    742721                                } 
     
    744723                }, 
    745724 
    746                 _drawObject: function (/*String*/html) { 
    747                         // summary: 
    748                         //              Draws an active x object, used by IE 
    749                         this.object = dojo.html.createExternalElement(dojo.doc(), "object"); 
    750  
    751                         with (this.object) { 
    752                                 classid = "clsid:2D360201-FFF5-11D1-8D03-00A0C959BC0A"; 
    753                                 width = this.inheritWidth ? this._oldWidth : "100%"; 
    754                                 style.height = this.height ? this.height : (this._oldHeight+"px"); 
    755                                 Scrollbars = this.height ? true : false; 
    756                                 Appearance = this._activeX.appearance.flat; 
    757                         } 
    758                         this.editorObject = this.object; 
    759                         this.editingArea.appendChild(this.object); 
    760  
    761                         this.object.attachEvent("DocumentComplete", dojo.lang.hitch(this, "onLoad")); 
    762                         //DisplayChanged is fired too often even no change is made, so we ignore it 
    763                         //and call onDisplayChanged manually in execCommand instead 
    764 //                      this.object.attachEvent("DisplayChanged", dojo.lang.hitch(this, "onDisplayChanged")); 
    765  
    766                         dojo.lang.forEach(this.events, function(e){ 
    767                                 this.object.attachEvent(e.toLowerCase(), dojo.lang.hitch(this, e)); 
    768                         }, this); 
    769  
    770                         this.object.DocumentHTML = '<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">' + 
    771                                 '<html><head><title></title>' + 
    772                                 '<style type="text/css">' + 
    773                                 '    body,html { padding: 0; margin: 0; }' + //font: ' + font + '; }' + 
    774                                 (this.height ? '' : '    body,  { overflow: hidden; }') + 
    775                                 '</style>' + this._applyEditingAreaStyleSheets()+ 
    776                                 //'<base href="' + dojo.global().location + '">' + 
    777                                 '</head><body><div>' + html + '<div></body></html>'; 
    778  
    779                         this._cacheLocalBlockFormatNames(); 
    780                 }, 
    781  
    782                 //static cache variables shared among all instance of this class 
    783                 _local2NativeFormatNames: {}, 
    784                 _native2LocalFormatNames: {}, 
    785                 //in IE, names for blockformat is locale dependent, so we cache the values here 
    786                 //we use activeX to obtain the list, if success or the names are already cached, 
    787                 //return true 
    788                 _cacheLocalBlockFormatNames: function(){ 
    789                         // summary: 
    790                         //              in IE, names for blockformat is locale dependent, so we cache the values here 
    791                         //              we use activeX to obtain the list, if success or the names are already cached, 
    792                         //              return true 
    793                         if(!this._native2LocalFormatNames['p']){ 
    794                                 var obj = this.object; 
    795                                 var error = false; 
    796                                 if(!obj){ 
    797                                         //create obj temporarily 
    798                                         try{ 
    799                                                 obj = dojo.html.createExternalElement(dojo.doc(), "object"); 
    800                                                 obj.classid = "clsid:2D360201-FFF5-11D1-8D03-00A0C959BC0A"; 
    801                                                 dojo.body().appendChild(obj); 
    802                                                 obj.DocumentHTML = "<html><head></head><body></body></html>"; 
    803                                         }catch(e){ error = true; } 
    804                                 } 
    805                                 try{ 
    806                                         var oNamesParm = new ActiveXObject("DEGetBlockFmtNamesParam.DEGetBlockFmtNamesParam"); 
    807                                         obj.ExecCommand(this._activeX.command['getblockformatnames'], 0, oNamesParm); 
    808                                         var vbNamesArray = new VBArray(oNamesParm.Names); 
    809                                         var localFormats = vbNamesArray.toArray(); 
    810                                         var nativeFormats = ['p', 'pre', 'address', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ol', 'ul', '', '', '','','div']; 
    811                                         for(var i=0;i<nativeFormats.length;++i){ 
    812                                                 if(nativeFormats[i].length>0){ 
    813                                                         this._local2NativeFormatNames[localFormats[i]] = nativeFormats[i]; 
    814                                                         this._native2LocalFormatNames[nativeFormats[i]] = localFormats[i]; 
    815                                                 } 
    816                                         } 
    817                                 }catch(e){ error = true; } 
    818                                 if(obj && !this.object){ 
    819                                         //delete the temporary obj 
    820                                         dojo.body().removeChild(obj); 
    821                                 } 
    822                         } 
    823                         return !error; 
    824                 }, 
    825725        /* Event handlers 
    826726         *****************/ 
     
    831731                        // summary: handler after the content of the document finishes loading 
    832732                        this.isLoaded = true; 
    833                         if (this.object){ 
    834                                 this.document = this.object.DOM; 
    835                                 this.window = this.document.parentWindow; 
    836                                 this.editNode = this.document.body.firstChild; 
    837                                 this.editingArea.style.height = this.height ? this.height : this.minHeight; 
    838                                 if(!this.height){ 
    839                                         this.connect(this, "onDisplayChanged", "_updateHeight"); 
    840                                 } 
    841                                 //pretend the object as an iframe, so that the context menu for the 
    842                                 //editor can be placed correctly when shown 
    843                                 this.window._frameElement = this.object; 
    844                         }else if (this.iframe && !dojo.render.html.ie){ 
     733                        if (this.iframe && !dojo.render.html.ie){ 
    845734                                this.editNode = this.document.body; 
    846735                                if(!this.height){ 
     
    908797                onKeyDown: function(e){ 
    909798                        // summary: Fired on keydown 
    910                         if((!e)&&(this.object)){ 
    911                                 e = dojo.event.browser.fixEvent(this.window.event); 
    912                         } 
     799 
    913800                        // dojo.debug("onkeydown:", e.keyCode); 
    914801                        // we need this event at the moment to get the events from control keys 
     
    943830                onKeyPress: function(e){ 
    944831                        // summary: Fired on keypress 
    945                         if((!e)&&(this.object)){ 
    946                                 e = dojo.event.browser.fixEvent(this.window.event); 
    947                         } 
     832 
    948833                        // handle the various key events 
    949834 
     
    1022907                        // summary: remove focus from this instance 
    1023908                        if(this.iframe) { this.window.blur(); } 
    1024                         else if(this.object) { this.document.body.blur(); } 
    1025909                        else if(this.editNode) { this.editNode.blur(); } 
    1026910                }, 
     
    1029913                        // summary: move focus to this instance 
    1030914                        if(this.iframe && !dojo.render.html.ie) { this.window.focus(); } 
    1031                         else if(this.object) { this.document.focus(); } 
    1032915                        // editNode may be hidden in display:none div, lets just punt in this case 
    1033916                        else if(this.editNode && this.editNode.focus) { this.editNode.focus(); } 
     
    1041924                onDisplayChanged: function (e){ }, 
    1042925 
    1043  
    1044         /* Formatting commands 
    1045          **********************/ 
    1046  
    1047                 // Object: IE's Active X codes: see http://www.computerbytesman.com/js/activex/dhtmledit.htm 
    1048                 _activeX: { 
    1049                         command: { 
    1050                                 bold: 5000, 
    1051                                 italic: 5023, 
    1052                                 underline: 5048, 
    1053  
    1054                                 justifycenter: 5024, 
    1055                                 justifyleft: 5025, 
    1056                                 justifyright: 5026, 
    1057  
    1058                                 cut: 5003, 
    1059                                 copy: 5002, 
    1060                                 paste: 5032, 
    1061                                 "delete": 5004, 
    1062  
    1063                                 undo: 5049, 
    1064                                 redo: 5033, 
    1065  
    1066                                 removeformat: 5034, 
    1067                                 selectall: 5035, 
    1068                                 unlink: 5050, 
    1069  
    1070                                 indent: 5018, 
    1071                                 outdent: 5031, 
    1072  
    1073                                 insertorderedlist: 5030, 
    1074                                 insertunorderedlist: 5051, 
    1075  
    1076                                 // table commands 
    1077                                 inserttable: 5022, 
    1078                                 insertcell: 5019, 
    1079                                 insertcol: 5020, 
    1080                                 insertrow: 5021, 
    1081                                 deletecells: 5005, 
    1082                                 deletecols: 5006, 
    1083                                 deleterows: 5007, 
    1084                                 mergecells: 5029, 
    1085                                 splitcell: 5047, 
    1086  
    1087                                 // the command need mapping, they don't translate directly 
    1088                                 // to the contentEditable commands 
    1089                                 setblockformat: 5043, 
    1090                                 getblockformat: 5011, 
    1091                                 getblockformatnames: 5012, 
    1092                                 setfontname: 5044, 
    1093                                 getfontname: 5013, 
    1094                                 setfontsize: 5045, 
    1095                                 getfontsize: 5014, 
    1096                                 setbackcolor: 5042, 
    1097                                 getbackcolor: 5010, 
    1098                                 setforecolor: 5046, 
    1099                                 getforecolor: 5015, 
    1100  
    1101                                 findtext: 5008, 
    1102                                 font: 5009, 
    1103                                 hyperlink: 5016, 
    1104                                 image: 5017, 
    1105  
    1106                                 lockelement: 5027, 
    1107                                 makeabsolute: 5028, 
    1108                                 sendbackward: 5036, 
    1109                                 bringforward: 5037, 
    1110                                 sendbelowtext: 5038, 
    1111                                 bringabovetext: 5039, 
    1112                                 sendtoback: 5040, 
    1113                                 bringtofront: 5041, 
    1114  
    1115                                 properties: 5052 
    1116                         }, 
    1117  
    1118                         ui: { 
    1119                                 "default": 0, 
    1120                                 prompt: 1, 
    1121                                 noprompt: 2 
    1122                         }, 
    1123  
    1124                         status: { 
    1125                                 notsupported: 0, 
    1126                                 disabled: 1, 
    1127                                 enabled: 3, 
    1128                                 latched: 7, 
    1129                                 ninched: 11 
    1130                         }, 
    1131  
    1132                         appearance: { 
    1133                                 flat: 0, 
    1134                                 inset: 1 
    1135                         }, 
    1136  
    1137                         state: { 
    1138                                 unchecked: 0, 
    1139                                 checked: 1, 
    1140                                 gray: 2 
    1141                         } 
    1142                 }, 
    1143  
    1144926                _normalizeCommand: function (/*String*/cmd){ 
    1145927                        // summary: 
     
    1152934                        if(command == "formatblock"){ 
    1153935                                if(drh.safari){ command = "heading"; } 
    1154                         }else if(this.object){ 
    1155                                 switch(command){ 
    1156                                         case "createlink": 
    1157                                                 command = "hyperlink"; 
    1158                                                 break; 
    1159                                         case "insertimage": 
    1160                                                 command = "image"; 
    1161                                                 break; 
    1162                                 } 
    1163936                        }else if(command == "hilitecolor" && !drh.mozilla){ 
    1164937                                command = "backcolor"; 
     
    12321005 
    12331006                                case "inserttable": 
    1234                                         supportedBy = isSupportedBy(mozilla | (this.object ? ie : 0)); 
     1007                                        supportedBy = isSupportedBy(mozilla | ie); 
    12351008                                        break; 
    12361009 
     
    12381011                                case "deletecells": case "deletecols": case "deleterows": 
    12391012                                case "mergecells": case "splitcell": 
    1240                                         supportedBy = isSupportedBy(this.object ? ie : 0); 
     1013                                        supportedBy = isSupportedBy(ie | mozilla); 
    12411014                                        break; 
    12421015 
     
    12571030                        var returnValue; 
    12581031 
    1259                         //focus() is required for IE (none-activeX mode) to work 
     1032                        //focus() is required for IE to work 
    12601033                        //In addition, focus() makes sure after the execution of 
    12611034                        //the command, the editor receives the focus as expected 
     
    12651038  &n