summaryrefslogtreecommitdiff
path: root/lib/dijit/_editor/plugins
diff options
context:
space:
mode:
authorAndrew Dolgov <[email protected]>2011-11-08 20:40:44 +0400
committerAndrew Dolgov <[email protected]>2011-11-08 20:40:44 +0400
commit81bea17aefb26859f825b9293c7c99192874806e (patch)
treefb244408ca271affa2899adb634788802c9a89d8 /lib/dijit/_editor/plugins
parent870a70e109ac9e80a88047044530de53d0404ec7 (diff)
upgrade Dojo to 1.6.1
Diffstat (limited to 'lib/dijit/_editor/plugins')
-rw-r--r--lib/dijit/_editor/plugins/AlwaysShowToolbar.js293
-rw-r--r--lib/dijit/_editor/plugins/EnterKeyHandling.js1007
-rw-r--r--lib/dijit/_editor/plugins/FontChoice.js812
-rw-r--r--lib/dijit/_editor/plugins/FullScreen.js647
-rw-r--r--lib/dijit/_editor/plugins/LinkDialog.js714
-rw-r--r--lib/dijit/_editor/plugins/NewPage.js93
-rw-r--r--lib/dijit/_editor/plugins/Print.js166
-rw-r--r--lib/dijit/_editor/plugins/TabIndent.js80
-rw-r--r--lib/dijit/_editor/plugins/TextColor.js143
-rw-r--r--lib/dijit/_editor/plugins/ToggleDir.js98
-rw-r--r--lib/dijit/_editor/plugins/ViewSource.js844
11 files changed, 3208 insertions, 1689 deletions
diff --git a/lib/dijit/_editor/plugins/AlwaysShowToolbar.js b/lib/dijit/_editor/plugins/AlwaysShowToolbar.js
index 1e0e2ed3f..9d0b7ded8 100644
--- a/lib/dijit/_editor/plugins/AlwaysShowToolbar.js
+++ b/lib/dijit/_editor/plugins/AlwaysShowToolbar.js
@@ -1,119 +1,190 @@
/*
- Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
-if(!dojo._hasResource["dijit._editor.plugins.AlwaysShowToolbar"]){
-dojo._hasResource["dijit._editor.plugins.AlwaysShowToolbar"]=true;
+if(!dojo._hasResource["dijit._editor.plugins.AlwaysShowToolbar"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._editor.plugins.AlwaysShowToolbar"] = true;
dojo.provide("dijit._editor.plugins.AlwaysShowToolbar");
-dojo.declare("dijit._editor.plugins.AlwaysShowToolbar",dijit._editor._Plugin,{_handleScroll:true,setEditor:function(e){
-if(!e.iframe){
-return;
-}
-this.editor=e;
-e.onLoadDeferred.addCallback(dojo.hitch(this,this.enable));
-},enable:function(d){
-this._updateHeight();
-this.connect(window,"onscroll","globalOnScrollHandler");
-this.connect(this.editor,"onNormalizedDisplayChanged","_updateHeight");
-return d;
-},_updateHeight:function(){
-var e=this.editor;
-if(!e.isLoaded){
-return;
-}
-if(e.height){
-return;
-}
-var _1=dojo.marginBox(e.editNode).h;
-if(dojo.isOpera){
-_1=e.editNode.scrollHeight;
-}
-if(!_1){
-_1=dojo.marginBox(e.document.body).h;
-}
-if(_1==0){
-return;
-}
-if(dojo.isIE<=7&&this.editor.minHeight){
-var _2=parseInt(this.editor.minHeight);
-if(_1<_2){
-_1=_2;
-}
-}
-if(_1!=this._lastHeight){
-this._lastHeight=_1;
-dojo.marginBox(e.iframe,{h:this._lastHeight});
-}
-},_lastHeight:0,globalOnScrollHandler:function(){
-var _3=dojo.isIE<7;
-if(!this._handleScroll){
-return;
-}
-var _4=this.editor.header;
-var db=dojo.body;
-if(!this._scrollSetUp){
-this._scrollSetUp=true;
-this._scrollThreshold=dojo.position(_4,true).y;
-}
-var _5=dojo._docScroll().y;
-var s=_4.style;
-if(_5>this._scrollThreshold&&_5<this._scrollThreshold+this._lastHeight){
-if(!this._fixEnabled){
-var _6=dojo.marginBox(_4);
-this.editor.iframe.style.marginTop=_6.h+"px";
-if(_3){
-s.left=dojo.position(_4).x;
-if(_4.previousSibling){
-this._IEOriginalPos=["after",_4.previousSibling];
-}else{
-if(_4.nextSibling){
-this._IEOriginalPos=["before",_4.nextSibling];
-}else{
-this._IEOriginalPos=["last",_4.parentNode];
-}
-}
-dojo.body().appendChild(_4);
-dojo.addClass(_4,"dijitIEFixedToolbar");
-}else{
-s.position="fixed";
-s.top="0px";
-}
-dojo.marginBox(_4,{w:_6.w});
-s.zIndex=2000;
-this._fixEnabled=true;
-}
-var _7=(this.height)?parseInt(this.editor.height):this.editor._lastHeight;
-s.display=(_5>this._scrollThreshold+_7)?"none":"";
-}else{
-if(this._fixEnabled){
-this.editor.iframe.style.marginTop="";
-s.position="";
-s.top="";
-s.zIndex="";
-s.display="";
-if(_3){
-s.left="";
-dojo.removeClass(_4,"dijitIEFixedToolbar");
-if(this._IEOriginalPos){
-dojo.place(_4,this._IEOriginalPos[1],this._IEOriginalPos[0]);
-this._IEOriginalPos=null;
-}else{
-dojo.place(_4,this.editor.iframe,"before");
-}
-}
-s.width="";
-this._fixEnabled=false;
-}
-}
-},destroy:function(){
-this._IEOriginalPos=null;
-this._handleScroll=false;
-dojo.forEach(this._connects,dojo.disconnect);
-if(dojo.isIE<7){
-dojo.removeClass(this.editor.header,"dijitIEFixedToolbar");
-}
-}});
+dojo.require("dijit._editor._Plugin");
+
+
+dojo.declare("dijit._editor.plugins.AlwaysShowToolbar", dijit._editor._Plugin,
+ {
+ // summary:
+ // This plugin is required for Editors in auto-expand mode.
+ // It handles the auto-expansion as the user adds/deletes text,
+ // and keeps the editor's toolbar visible even when the top of the editor
+ // has scrolled off the top of the viewport (usually when editing a long
+ // document).
+ // description:
+ // Specify this in extraPlugins (or plugins) parameter and also set
+ // height to "".
+ // example:
+ // | <div dojoType="dijit.Editor" height=""
+ // | extraPlugins="['dijit._editor.plugins.AlwaysShowToolbar']">
+
+ // _handleScroll: Boolean
+ // Enables/disables the handler for scroll events
+ _handleScroll: true,
+
+ setEditor: function(e){
+ // Overrides _Plugin.setEditor().
+ if(!e.iframe){
+ console.log('Port AlwaysShowToolbar plugin to work with Editor without iframe');
+ return;
+ }
+
+ this.editor = e;
+
+ e.onLoadDeferred.addCallback(dojo.hitch(this, this.enable));
+ },
+
+ enable: function(d){
+ // summary:
+ // Enable plugin. Called when Editor has finished initializing.
+ // tags:
+ // private
+
+ this._updateHeight();
+ this.connect(window, 'onscroll', "globalOnScrollHandler");
+ this.connect(this.editor, 'onNormalizedDisplayChanged', "_updateHeight");
+ return d;
+ },
+
+ _updateHeight: function(){
+ // summary:
+ // Updates the height of the editor area to fit the contents.
+ var e = this.editor;
+ if(!e.isLoaded){ return; }
+ if(e.height){ return; }
+
+ var height = dojo._getMarginSize(e.editNode).h;
+ if(dojo.isOpera){
+ height = e.editNode.scrollHeight;
+ }
+ // console.debug('height',height);
+ // alert(this.editNode);
+
+ //height maybe zero in some cases even though the content is not empty,
+ //we try the height of body instead
+ if(!height){
+ height = dojo._getMarginSize(e.document.body).h;
+ }
+
+ if(height == 0){
+ console.debug("Can not figure out the height of the editing area!");
+ return; //prevent setting height to 0
+ }
+ if(dojo.isIE <= 7 && this.editor.minHeight){
+ var min = parseInt(this.editor.minHeight);
+ if(height < min){ height = min; }
+ }
+ if(height != this._lastHeight){
+ this._lastHeight = height;
+ // this.editorObject.style.height = this._lastHeight + "px";
+ dojo.marginBox(e.iframe, { h: this._lastHeight });
+ }
+ },
+
+ // _lastHeight: Integer
+ // Height in px of the editor at the last time we did sizing
+ _lastHeight: 0,
+
+ globalOnScrollHandler: function(){
+ // summary:
+ // Handler for scroll events that bubbled up to <html>
+ // tags:
+ // private
+
+ var isIE6 = dojo.isIE < 7;
+ if(!this._handleScroll){ return; }
+ var tdn = this.editor.header;
+ var db = dojo.body;
+
+ if(!this._scrollSetUp){
+ this._scrollSetUp = true;
+ this._scrollThreshold = dojo.position(tdn, true).y;
+// console.log("threshold:", this._scrollThreshold);
+ //what's this for?? comment out for now
+// if((isIE6)&&(db)&&(dojo.style(db, "backgroundIimage")=="none")){
+// db.style.backgroundImage = "url(" + dojo.uri.moduleUri("dijit", "templates/blank.gif") + ")";
+// db.style.backgroundAttachment = "fixed";
+// }
+ }
+
+ var scrollPos = dojo._docScroll().y;
+ var s = tdn.style;
+
+ if(scrollPos > this._scrollThreshold && scrollPos < this._scrollThreshold+this._lastHeight){
+ // dojo.debug(scrollPos);
+ if(!this._fixEnabled){
+ var tdnbox = dojo._getMarginSize(tdn);
+ this.editor.iframe.style.marginTop = tdnbox.h+"px";
+
+ if(isIE6){
+ s.left = dojo.position(tdn).x;
+ if(tdn.previousSibling){
+ this._IEOriginalPos = ['after',tdn.previousSibling];
+ }else if(tdn.nextSibling){
+ this._IEOriginalPos = ['before',tdn.nextSibling];
+ }else{
+ this._IEOriginalPos = ['last',tdn.parentNode];
+ }
+ dojo.body().appendChild(tdn);
+ dojo.addClass(tdn,'dijitIEFixedToolbar');
+ }else{
+ s.position = "fixed";
+ s.top = "0px";
+ }
+
+ dojo.marginBox(tdn, { w: tdnbox.w });
+ s.zIndex = 2000;
+ this._fixEnabled = true;
+ }
+ // if we're showing the floating toolbar, make sure that if
+ // we've scrolled past the bottom of the editor that we hide
+ // the toolbar for this instance of the editor.
+
+ // TODO: when we get multiple editor toolbar support working
+ // correctly, ensure that we check this against the scroll
+ // position of the bottom-most editor instance.
+ var eHeight = (this.height) ? parseInt(this.editor.height) : this.editor._lastHeight;
+ s.display = (scrollPos > this._scrollThreshold+eHeight) ? "none" : "";
+ }else if(this._fixEnabled){
+ this.editor.iframe.style.marginTop = '';
+ s.position = "";
+ s.top = "";
+ s.zIndex = "";
+ s.display = "";
+ if(isIE6){
+ s.left = "";
+ dojo.removeClass(tdn,'dijitIEFixedToolbar');
+ if(this._IEOriginalPos){
+ dojo.place(tdn, this._IEOriginalPos[1], this._IEOriginalPos[0]);
+ this._IEOriginalPos = null;
+ }else{
+ dojo.place(tdn, this.editor.iframe, 'before');
+ }
+ }
+ s.width = "";
+ this._fixEnabled = false;
+ }
+ },
+
+ destroy: function(){
+ // Overrides _Plugin.destroy(). TODO: call this.inherited() rather than repeating code.
+ this._IEOriginalPos = null;
+ this._handleScroll = false;
+ dojo.forEach(this._connects, dojo.disconnect);
+// clearInterval(this.scrollInterval);
+
+ if(dojo.isIE < 7){
+ dojo.removeClass(this.editor.header, 'dijitIEFixedToolbar');
+ }
+ }
+});
+
}
diff --git a/lib/dijit/_editor/plugins/EnterKeyHandling.js b/lib/dijit/_editor/plugins/EnterKeyHandling.js
index 51a8fdde8..670d491ae 100644
--- a/lib/dijit/_editor/plugins/EnterKeyHandling.js
+++ b/lib/dijit/_editor/plugins/EnterKeyHandling.js
@@ -1,423 +1,604 @@
/*
- Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
-if(!dojo._hasResource["dijit._editor.plugins.EnterKeyHandling"]){
-dojo._hasResource["dijit._editor.plugins.EnterKeyHandling"]=true;
+if(!dojo._hasResource["dijit._editor.plugins.EnterKeyHandling"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._editor.plugins.EnterKeyHandling"] = true;
dojo.provide("dijit._editor.plugins.EnterKeyHandling");
dojo.require("dojo.window");
-dojo.declare("dijit._editor.plugins.EnterKeyHandling",dijit._editor._Plugin,{blockNodeForEnter:"BR",constructor:function(_1){
-if(_1){
-dojo.mixin(this,_1);
-}
-},setEditor:function(_2){
-this.editor=_2;
-if(this.blockNodeForEnter=="BR"){
-if(dojo.isIE){
-_2.contentDomPreFilters.push(dojo.hitch(this,"regularPsToSingleLinePs"));
-_2.contentDomPostFilters.push(dojo.hitch(this,"singleLinePsToRegularPs"));
-_2.onLoadDeferred.addCallback(dojo.hitch(this,"_fixNewLineBehaviorForIE"));
-}else{
-_2.onLoadDeferred.addCallback(dojo.hitch(this,function(d){
-try{
-this.editor.document.execCommand("insertBrOnReturn",false,true);
-}
-catch(e){
-}
-return d;
-}));
-}
-}else{
-if(this.blockNodeForEnter){
-dojo["require"]("dijit._editor.range");
-var h=dojo.hitch(this,this.handleEnterKey);
-_2.addKeyHandler(13,0,0,h);
-_2.addKeyHandler(13,0,1,h);
-this.connect(this.editor,"onKeyPressed","onKeyPressed");
-}
-}
-},onKeyPressed:function(e){
-if(this._checkListLater){
-if(dojo.withGlobal(this.editor.window,"isCollapsed",dijit)){
-var _3=dojo.withGlobal(this.editor.window,"getAncestorElement",dijit._editor.selection,["LI"]);
-if(!_3){
-dijit._editor.RichText.prototype.execCommand.call(this.editor,"formatblock",this.blockNodeForEnter);
-var _4=dojo.withGlobal(this.editor.window,"getAncestorElement",dijit._editor.selection,[this.blockNodeForEnter]);
-if(_4){
-_4.innerHTML=this.bogusHtmlContent;
-if(dojo.isIE){
-var r=this.editor.document.selection.createRange();
-r.move("character",-1);
-r.select();
-}
-}else{
-console.error("onKeyPressed: Cannot find the new block node");
-}
-}else{
-if(dojo.isMoz){
-if(_3.parentNode.parentNode.nodeName=="LI"){
-_3=_3.parentNode.parentNode;
-}
-}
-var fc=_3.firstChild;
-if(fc&&fc.nodeType==1&&(fc.nodeName=="UL"||fc.nodeName=="OL")){
-_3.insertBefore(fc.ownerDocument.createTextNode(" "),fc);
-var _5=dijit.range.create(this.editor.window);
-_5.setStart(_3.firstChild,0);
-var _6=dijit.range.getSelection(this.editor.window,true);
-_6.removeAllRanges();
-_6.addRange(_5);
-}
-}
-}
-this._checkListLater=false;
-}
-if(this._pressedEnterInBlock){
-if(this._pressedEnterInBlock.previousSibling){
-this.removeTrailingBr(this._pressedEnterInBlock.previousSibling);
-}
-delete this._pressedEnterInBlock;
-}
-},bogusHtmlContent:"&nbsp;",blockNodes:/^(?:P|H1|H2|H3|H4|H5|H6|LI)$/,handleEnterKey:function(e){
-var _7,_8,_9,_a=this.editor.document,br;
-if(e.shiftKey){
-var _b=dojo.withGlobal(this.editor.window,"getParentElement",dijit._editor.selection);
-var _c=dijit.range.getAncestor(_b,this.blockNodes);
-if(_c){
-if(!e.shiftKey&&_c.tagName=="LI"){
-return true;
-}
-_7=dijit.range.getSelection(this.editor.window);
-_8=_7.getRangeAt(0);
-if(!_8.collapsed){
-_8.deleteContents();
-_7=dijit.range.getSelection(this.editor.window);
-_8=_7.getRangeAt(0);
-}
-if(dijit.range.atBeginningOfContainer(_c,_8.startContainer,_8.startOffset)){
-if(e.shiftKey){
-br=_a.createElement("br");
-_9=dijit.range.create(this.editor.window);
-_c.insertBefore(br,_c.firstChild);
-_9.setStartBefore(br.nextSibling);
-_7.removeAllRanges();
-_7.addRange(_9);
-}else{
-dojo.place(br,_c,"before");
-}
-}else{
-if(dijit.range.atEndOfContainer(_c,_8.startContainer,_8.startOffset)){
-_9=dijit.range.create(this.editor.window);
-br=_a.createElement("br");
-if(e.shiftKey){
-_c.appendChild(br);
-_c.appendChild(_a.createTextNode(" "));
-_9.setStart(_c.lastChild,0);
-}else{
-dojo.place(br,_c,"after");
-_9.setStartAfter(_c);
-}
-_7.removeAllRanges();
-_7.addRange(_9);
-}else{
-return true;
-}
-}
-}else{
-dijit._editor.RichText.prototype.execCommand.call(this.editor,"inserthtml","<br>");
-}
-return false;
-}
-var _d=true;
-_7=dijit.range.getSelection(this.editor.window);
-_8=_7.getRangeAt(0);
-if(!_8.collapsed){
-_8.deleteContents();
-_7=dijit.range.getSelection(this.editor.window);
-_8=_7.getRangeAt(0);
-}
-var _e=dijit.range.getBlockAncestor(_8.endContainer,null,this.editor.editNode);
-var _f=_e.blockNode;
-if((this._checkListLater=(_f&&(_f.nodeName=="LI"||_f.parentNode.nodeName=="LI")))){
-if(dojo.isMoz){
-this._pressedEnterInBlock=_f;
-}
-if(/^(\s|&nbsp;|\xA0|<span\b[^>]*\bclass=['"]Apple-style-span['"][^>]*>(\s|&nbsp;|\xA0)<\/span>)?(<br>)?$/.test(_f.innerHTML)){
-_f.innerHTML="";
-if(dojo.isWebKit){
-_9=dijit.range.create(this.editor.window);
-_9.setStart(_f,0);
-_7.removeAllRanges();
-_7.addRange(_9);
-}
-this._checkListLater=false;
-}
-return true;
-}
-if(!_e.blockNode||_e.blockNode===this.editor.editNode){
-try{
-dijit._editor.RichText.prototype.execCommand.call(this.editor,"formatblock",this.blockNodeForEnter);
-}
-catch(e2){
-}
-_e={blockNode:dojo.withGlobal(this.editor.window,"getAncestorElement",dijit._editor.selection,[this.blockNodeForEnter]),blockContainer:this.editor.editNode};
-if(_e.blockNode){
-if(_e.blockNode!=this.editor.editNode&&(!(_e.blockNode.textContent||_e.blockNode.innerHTML).replace(/^\s+|\s+$/g,"").length)){
-this.removeTrailingBr(_e.blockNode);
-return false;
-}
-}else{
-_e.blockNode=this.editor.editNode;
-}
-_7=dijit.range.getSelection(this.editor.window);
-_8=_7.getRangeAt(0);
-}
-var _10=_a.createElement(this.blockNodeForEnter);
-_10.innerHTML=this.bogusHtmlContent;
-this.removeTrailingBr(_e.blockNode);
-if(dijit.range.atEndOfContainer(_e.blockNode,_8.endContainer,_8.endOffset)){
-if(_e.blockNode===_e.blockContainer){
-_e.blockNode.appendChild(_10);
-}else{
-dojo.place(_10,_e.blockNode,"after");
-}
-_d=false;
-_9=dijit.range.create(this.editor.window);
-_9.setStart(_10,0);
-_7.removeAllRanges();
-_7.addRange(_9);
-if(this.editor.height){
-dojo.window.scrollIntoView(_10);
-}
-}else{
-if(dijit.range.atBeginningOfContainer(_e.blockNode,_8.startContainer,_8.startOffset)){
-dojo.place(_10,_e.blockNode,_e.blockNode===_e.blockContainer?"first":"before");
-if(_10.nextSibling&&this.editor.height){
-_9=dijit.range.create(this.editor.window);
-_9.setStart(_10.nextSibling,0);
-_7.removeAllRanges();
-_7.addRange(_9);
-dojo.window.scrollIntoView(_10.nextSibling);
-}
-_d=false;
-}else{
-if(_e.blockNode===_e.blockContainer){
-_e.blockNode.appendChild(_10);
-}else{
-dojo.place(_10,_e.blockNode,"after");
-}
-_d=false;
-if(_e.blockNode.style){
-if(_10.style){
-if(_e.blockNode.style.cssText){
-_10.style.cssText=_e.blockNode.style.cssText;
-}
-}
-}
-var rs=_8.startContainer;
-if(rs&&rs.nodeType==3){
-var _11,_12;
-var txt=rs.nodeValue;
-var _13=_a.createTextNode(txt.substring(0,_8.startOffset));
-var _14=_a.createTextNode(txt.substring(_8.startOffset,txt.length));
-dojo.place(_13,rs,"before");
-dojo.place(_14,rs,"after");
-dojo.destroy(rs);
-var _15=_13.parentNode;
-while(_15!==_e.blockNode){
-var tg=_15.tagName;
-var _16=_a.createElement(tg);
-if(_15.style){
-if(_16.style){
-if(_15.style.cssText){
-_16.style.cssText=_15.style.cssText;
-}
-}
-}
-_11=_14;
-while(_11){
-_12=_11.nextSibling;
-_16.appendChild(_11);
-_11=_12;
-}
-dojo.place(_16,_15,"after");
-_13=_15;
-_14=_16;
-_15=_15.parentNode;
-}
-_11=_14;
-if(_11.nodeType==1||(_11.nodeType==3&&_11.nodeValue)){
-_10.innerHTML="";
-}
-while(_11){
-_12=_11.nextSibling;
-_10.appendChild(_11);
-_11=_12;
-}
-}
-_9=dijit.range.create(this.editor.window);
-_9.setStart(_10,0);
-_7.removeAllRanges();
-_7.addRange(_9);
-if(this.editor.height){
-dijit.scrollIntoView(_10);
-}
-if(dojo.isMoz){
-this._pressedEnterInBlock=_e.blockNode;
-}
-}
-}
-return _d;
-},removeTrailingBr:function(_17){
-var _18=/P|DIV|LI/i.test(_17.tagName)?_17:dijit._editor.selection.getParentOfType(_17,["P","DIV","LI"]);
-if(!_18){
-return;
-}
-if(_18.lastChild){
-if((_18.childNodes.length>1&&_18.lastChild.nodeType==3&&/^[\s\xAD]*$/.test(_18.lastChild.nodeValue))||_18.lastChild.tagName=="BR"){
-dojo.destroy(_18.lastChild);
-}
-}
-if(!_18.childNodes.length){
-_18.innerHTML=this.bogusHtmlContent;
-}
-},_fixNewLineBehaviorForIE:function(d){
-var doc=this.editor.document;
-if(doc.__INSERTED_EDITIOR_NEWLINE_CSS===undefined){
-var _19=dojo.create("style",{type:"text/css"},doc.getElementsByTagName("head")[0]);
-_19.styleSheet.cssText="p{margin:0;}";
-this.editor.document.__INSERTED_EDITIOR_NEWLINE_CSS=true;
-}
-return d;
-},regularPsToSingleLinePs:function(_1a,_1b){
-function _1c(el){
-function _1d(_1e){
-var _1f=_1e[0].ownerDocument.createElement("p");
-_1e[0].parentNode.insertBefore(_1f,_1e[0]);
-dojo.forEach(_1e,function(_20){
-_1f.appendChild(_20);
-});
-};
-var _21=0;
-var _22=[];
-var _23;
-while(_21<el.childNodes.length){
-_23=el.childNodes[_21];
-if(_23.nodeType==3||(_23.nodeType==1&&_23.nodeName!="BR"&&dojo.style(_23,"display")!="block")){
-_22.push(_23);
-}else{
-var _24=_23.nextSibling;
-if(_22.length){
-_1d(_22);
-_21=(_21+1)-_22.length;
-if(_23.nodeName=="BR"){
-dojo.destroy(_23);
-}
-}
-_22=[];
-}
-_21++;
-}
-if(_22.length){
-_1d(_22);
-}
-};
-function _25(el){
-var _26=null;
-var _27=[];
-var _28=el.childNodes.length-1;
-for(var i=_28;i>=0;i--){
-_26=el.childNodes[i];
-if(_26.nodeName=="BR"){
-var _29=_26.ownerDocument.createElement("p");
-dojo.place(_29,el,"after");
-if(_27.length==0&&i!=_28){
-_29.innerHTML="&nbsp;";
-}
-dojo.forEach(_27,function(_2a){
-_29.appendChild(_2a);
-});
-dojo.destroy(_26);
-_27=[];
-}else{
-_27.unshift(_26);
-}
-}
-};
-var _2b=[];
-var ps=_1a.getElementsByTagName("p");
-dojo.forEach(ps,function(p){
-_2b.push(p);
+dojo.require("dijit._editor._Plugin");
+dojo.require("dijit._editor.range");
+
+
+dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
+ // summary:
+ // This plugin tries to make all browsers behave consistently with regard to
+ // how ENTER behaves in the editor window. It traps the ENTER key and alters
+ // the way DOM is constructed in certain cases to try to commonize the generated
+ // DOM and behaviors across browsers.
+ //
+ // description:
+ // This plugin has three modes:
+ //
+ // * blockModeForEnter=BR
+ // * blockModeForEnter=DIV
+ // * blockModeForEnter=P
+ //
+ // In blockModeForEnter=P, the ENTER key starts a new
+ // paragraph, and shift-ENTER starts a new line in the current paragraph.
+ // For example, the input:
+ //
+ // | first paragraph <shift-ENTER>
+ // | second line of first paragraph <ENTER>
+ // | second paragraph
+ //
+ // will generate:
+ //
+ // | <p>
+ // | first paragraph
+ // | <br/>
+ // | second line of first paragraph
+ // | </p>
+ // | <p>
+ // | second paragraph
+ // | </p>
+ //
+ // In BR and DIV mode, the ENTER key conceptually goes to a new line in the
+ // current paragraph, and users conceptually create a new paragraph by pressing ENTER twice.
+ // For example, if the user enters text into an editor like this:
+ //
+ // | one <ENTER>
+ // | two <ENTER>
+ // | three <ENTER>
+ // | <ENTER>
+ // | four <ENTER>
+ // | five <ENTER>
+ // | six <ENTER>
+ //
+ // It will appear on the screen as two 'paragraphs' of three lines each. Markupwise, this generates:
+ //
+ // BR:
+ // | one<br/>
+ // | two<br/>
+ // | three<br/>
+ // | <br/>
+ // | four<br/>
+ // | five<br/>
+ // | six<br/>
+ //
+ // DIV:
+ // | <div>one</div>
+ // | <div>two</div>
+ // | <div>three</div>
+ // | <div>&nbsp;</div>
+ // | <div>four</div>
+ // | <div>five</div>
+ // | <div>six</div>
+
+ // blockNodeForEnter: String
+ // This property decides the behavior of Enter key. It can be either P,
+ // DIV, BR, or empty (which means disable this feature). Anything else
+ // will trigger errors. The default is 'BR'
+ //
+ // See class description for more details.
+ blockNodeForEnter: 'BR',
+
+ constructor: function(args){
+ if(args){
+ if("blockNodeForEnter" in args){
+ args.blockNodeForEnter = args.blockNodeForEnter.toUpperCase();
+ }
+ dojo.mixin(this,args);
+ }
+ },
+
+ setEditor: function(editor){
+ // Overrides _Plugin.setEditor().
+ if(this.editor === editor) { return; }
+ this.editor = editor;
+ if(this.blockNodeForEnter == 'BR'){
+ // While Moz has a mode tht mostly works, it's still a little different,
+ // So, try to just have a common mode and be consistent. Which means
+ // we need to enable customUndo, if not already enabled.
+ this.editor.customUndo = true;
+ editor.onLoadDeferred.addCallback(dojo.hitch(this,function(d){
+ this.connect(editor.document, "onkeypress", function(e){
+ if(e.charOrCode == dojo.keys.ENTER){
+ // Just do it manually. The handleEnterKey has a shift mode that
+ // Always acts like <br>, so just use it.
+ var ne = dojo.mixin({},e);
+ ne.shiftKey = true;
+ if(!this.handleEnterKey(ne)){
+ dojo.stopEvent(e);
+ }
+ }
+ });
+ return d;
+ }));
+ }else if(this.blockNodeForEnter){
+ // add enter key handler
+ // FIXME: need to port to the new event code!!
+ var h = dojo.hitch(this,this.handleEnterKey);
+ editor.addKeyHandler(13, 0, 0, h); //enter
+ editor.addKeyHandler(13, 0, 1, h); //shift+enter
+ this.connect(this.editor,'onKeyPressed','onKeyPressed');
+ }
+ },
+ onKeyPressed: function(e){
+ // summary:
+ // Handler for keypress events.
+ // tags:
+ // private
+ if(this._checkListLater){
+ if(dojo.withGlobal(this.editor.window, 'isCollapsed', dijit)){
+ var liparent=dojo.withGlobal(this.editor.window, 'getAncestorElement', dijit._editor.selection, ['LI']);
+ if(!liparent){
+ // circulate the undo detection code by calling RichText::execCommand directly
+ dijit._editor.RichText.prototype.execCommand.call(this.editor, 'formatblock',this.blockNodeForEnter);
+ // set the innerHTML of the new block node
+ var block = dojo.withGlobal(this.editor.window, 'getAncestorElement', dijit._editor.selection, [this.blockNodeForEnter]);
+ if(block){
+ block.innerHTML=this.bogusHtmlContent;
+ if(dojo.isIE){
+ // move to the start by moving backwards one char
+ var r = this.editor.document.selection.createRange();
+ r.move('character',-1);
+ r.select();
+ }
+ }else{
+ console.error('onKeyPressed: Cannot find the new block node'); // FIXME
+ }
+ }else{
+ if(dojo.isMoz){
+ if(liparent.parentNode.parentNode.nodeName == 'LI'){
+ liparent=liparent.parentNode.parentNode;
+ }
+ }
+ var fc=liparent.firstChild;
+ if(fc && fc.nodeType == 1 && (fc.nodeName == 'UL' || fc.nodeName == 'OL')){
+ liparent.insertBefore(fc.ownerDocument.createTextNode('\xA0'),fc);
+ var newrange = dijit.range.create(this.editor.window);
+ newrange.setStart(liparent.firstChild,0);
+ var selection = dijit.range.getSelection(this.editor.window, true);
+ selection.removeAllRanges();
+ selection.addRange(newrange);
+ }
+ }
+ }
+ this._checkListLater = false;
+ }
+ if(this._pressedEnterInBlock){
+ // the new created is the original current P, so we have previousSibling below
+ if(this._pressedEnterInBlock.previousSibling){
+ this.removeTrailingBr(this._pressedEnterInBlock.previousSibling);
+ }
+ delete this._pressedEnterInBlock;
+ }
+ },
+
+ // bogusHtmlContent: [private] String
+ // HTML to stick into a new empty block
+ bogusHtmlContent: '&nbsp;',
+
+ // blockNodes: [private] Regex
+ // Regex for testing if a given tag is a block level (display:block) tag
+ blockNodes: /^(?:P|H1|H2|H3|H4|H5|H6|LI)$/,
+
+ handleEnterKey: function(e){
+ // summary:
+ // Handler for enter key events when blockModeForEnter is DIV or P.
+ // description:
+ // Manually handle enter key event to make the behavior consistent across
+ // all supported browsers. See class description for details.
+ // tags:
+ // private
+
+ var selection, range, newrange, startNode, endNode, brNode, doc=this.editor.document,br,rs,txt;
+ if(e.shiftKey){ // shift+enter always generates <br>
+ var parent = dojo.withGlobal(this.editor.window, "getParentElement", dijit._editor.selection);
+ var header = dijit.range.getAncestor(parent,this.blockNodes);
+ if(header){
+ if(header.tagName == 'LI'){
+ return true; // let browser handle
+ }
+ selection = dijit.range.getSelection(this.editor.window);
+ range = selection.getRangeAt(0);
+ if(!range.collapsed){
+ range.deleteContents();
+ selection = dijit.range.getSelection(this.editor.window);
+ range = selection.getRangeAt(0);
+ }
+ if(dijit.range.atBeginningOfContainer(header, range.startContainer, range.startOffset)){
+ br=doc.createElement('br');
+ newrange = dijit.range.create(this.editor.window);
+ header.insertBefore(br,header.firstChild);
+ newrange.setStartBefore(br.nextSibling);
+ selection.removeAllRanges();
+ selection.addRange(newrange);
+ }else if(dijit.range.atEndOfContainer(header, range.startContainer, range.startOffset)){
+ newrange = dijit.range.create(this.editor.window);
+ br=doc.createElement('br');
+ header.appendChild(br);
+ header.appendChild(doc.createTextNode('\xA0'));
+ newrange.setStart(header.lastChild,0);
+ selection.removeAllRanges();
+ selection.addRange(newrange);
+ }else{
+ rs = range.startContainer;
+ if(rs && rs.nodeType == 3){
+ // Text node, we have to split it.
+ txt = rs.nodeValue;
+ dojo.withGlobal(this.editor.window, function(){
+ startNode = doc.createTextNode(txt.substring(0, range.startOffset));
+ endNode = doc.createTextNode(txt.substring(range.startOffset));
+ brNode = doc.createElement("br");
+
+ if(endNode.nodeValue == "" && dojo.isWebKit){
+ endNode = doc.createTextNode('\xA0')
+ }
+ dojo.place(startNode, rs, "after");
+ dojo.place(brNode, startNode, "after");
+ dojo.place(endNode, brNode, "after");
+ dojo.destroy(rs);
+ newrange = dijit.range.create(dojo.gobal);
+ newrange.setStart(endNode,0);
+ selection.removeAllRanges();
+ selection.addRange(newrange);
+ });
+ return false;
+ }
+ return true; // let browser handle
+ }
+ }else{
+ selection = dijit.range.getSelection(this.editor.window);
+ if(selection.rangeCount){
+ range = selection.getRangeAt(0);
+ if(range && range.startContainer){
+ if(!range.collapsed){
+ range.deleteContents();
+ selection = dijit.range.getSelection(this.editor.window);
+ range = selection.getRangeAt(0);
+ }
+ rs = range.startContainer;
+ if(rs && rs.nodeType == 3){
+ // Text node, we have to split it.
+ dojo.withGlobal(this.editor.window, dojo.hitch(this, function(){
+ var endEmpty = false;
+
+ var offset = range.startOffset;
+ if(rs.length < offset){
+ //We are not splitting the right node, try to locate the correct one
+ ret = this._adjustNodeAndOffset(rs, offset);
+ rs = ret.node;
+ offset = ret.offset;
+ }
+ txt = rs.nodeValue;
+
+ startNode = doc.createTextNode(txt.substring(0, offset));
+ endNode = doc.createTextNode(txt.substring(offset));
+ brNode = doc.createElement("br");
+
+ if(!endNode.length){
+ endNode = doc.createTextNode('\xA0');
+ endEmpty = true;
+ }
+
+ if(startNode.length){
+ dojo.place(startNode, rs, "after");
+ }else{
+ startNode = rs;
+ }
+ dojo.place(brNode, startNode, "after");
+ dojo.place(endNode, brNode, "after");
+ dojo.destroy(rs);
+ newrange = dijit.range.create(dojo.gobal);
+ newrange.setStart(endNode,0);
+ newrange.setEnd(endNode, endNode.length);
+ selection.removeAllRanges();
+ selection.addRange(newrange);
+ if(endEmpty && !dojo.isWebKit){
+ dijit._editor.selection.remove();
+ }else{
+ dijit._editor.selection.collapse(true);
+ }
+ }));
+ }else{
+ dojo.withGlobal(this.editor.window, dojo.hitch(this, function(){
+ var brNode = doc.createElement("br");
+ rs.appendChild(brNode);
+ var endNode = doc.createTextNode('\xA0');
+ rs.appendChild(endNode);
+ newrange = dijit.range.create(dojo.global);
+ newrange.setStart(endNode,0);
+ newrange.setEnd(endNode, endNode.length);
+ selection.removeAllRanges();
+ selection.addRange(newrange);
+ dijit._editor.selection.collapse(true);
+ }));
+ }
+ }
+ }else{
+ // don't change this: do not call this.execCommand, as that may have other logic in subclass
+ dijit._editor.RichText.prototype.execCommand.call(this.editor, 'inserthtml', '<br>');
+ }
+ }
+ return false;
+ }
+ var _letBrowserHandle = true;
+
+ // first remove selection
+ selection = dijit.range.getSelection(this.editor.window);
+ range = selection.getRangeAt(0);
+ if(!range.collapsed){
+ range.deleteContents();
+ selection = dijit.range.getSelection(this.editor.window);
+ range = selection.getRangeAt(0);
+ }
+
+ var block = dijit.range.getBlockAncestor(range.endContainer, null, this.editor.editNode);
+ var blockNode = block.blockNode;
+
+ // if this is under a LI or the parent of the blockNode is LI, just let browser to handle it
+ if((this._checkListLater = (blockNode && (blockNode.nodeName == 'LI' || blockNode.parentNode.nodeName == 'LI')))){
+ if(dojo.isMoz){
+ // press enter in middle of P may leave a trailing <br/>, let's remove it later
+ this._pressedEnterInBlock = blockNode;
+ }
+ // if this li only contains spaces, set the content to empty so the browser will outdent this item
+ if(/^(\s|&nbsp;|\xA0|<span\b[^>]*\bclass=['"]Apple-style-span['"][^>]*>(\s|&nbsp;|\xA0)<\/span>)?(<br>)?$/.test(blockNode.innerHTML)){
+ // empty LI node
+ blockNode.innerHTML = '';
+ if(dojo.isWebKit){ // WebKit tosses the range when innerHTML is reset
+ newrange = dijit.range.create(this.editor.window);
+ newrange.setStart(blockNode, 0);
+ selection.removeAllRanges();
+ selection.addRange(newrange);
+ }
+ this._checkListLater = false; // nothing to check since the browser handles outdent
+ }
+ return true;
+ }
+
+ // text node directly under body, let's wrap them in a node
+ if(!block.blockNode || block.blockNode===this.editor.editNode){
+ try{
+ dijit._editor.RichText.prototype.execCommand.call(this.editor, 'formatblock',this.blockNodeForEnter);
+ }catch(e2){ /*squelch FF3 exception bug when editor content is a single BR*/ }
+ // get the newly created block node
+ // FIXME
+ block = {blockNode:dojo.withGlobal(this.editor.window, "getAncestorElement", dijit._editor.selection, [this.blockNodeForEnter]),
+ blockContainer: this.editor.editNode};
+ if(block.blockNode){
+ if(block.blockNode != this.editor.editNode &&
+ (!(block.blockNode.textContent || block.blockNode.innerHTML).replace(/^\s+|\s+$/g, "").length)){
+ this.removeTrailingBr(block.blockNode);
+ return false;
+ }
+ }else{ // we shouldn't be here if formatblock worked
+ block.blockNode = this.editor.editNode;
+ }
+ selection = dijit.range.getSelection(this.editor.window);
+ range = selection.getRangeAt(0);
+ }
+
+ var newblock = doc.createElement(this.blockNodeForEnter);
+ newblock.innerHTML=this.bogusHtmlContent;
+ this.removeTrailingBr(block.blockNode);
+ var endOffset = range.endOffset;
+ var node = range.endContainer;
+ if(node.length < endOffset){
+ //We are not checking the right node, try to locate the correct one
+ var ret = this._adjustNodeAndOffset(node, endOffset);
+ node = ret.node;
+ endOffset = ret.offset;
+ }
+ if(dijit.range.atEndOfContainer(block.blockNode, node, endOffset)){
+ if(block.blockNode === block.blockContainer){
+ block.blockNode.appendChild(newblock);
+ }else{
+ dojo.place(newblock, block.blockNode, "after");
+ }
+ _letBrowserHandle = false;
+ // lets move caret to the newly created block
+ newrange = dijit.range.create(this.editor.window);
+ newrange.setStart(newblock, 0);
+ selection.removeAllRanges();
+ selection.addRange(newrange);
+ if(this.editor.height){
+ dojo.window.scrollIntoView(newblock);
+ }
+ }else if(dijit.range.atBeginningOfContainer(block.blockNode,
+ range.startContainer, range.startOffset)){
+ dojo.place(newblock, block.blockNode, block.blockNode === block.blockContainer ? "first" : "before");
+ if(newblock.nextSibling && this.editor.height){
+ // position input caret - mostly WebKit needs this
+ newrange = dijit.range.create(this.editor.window);
+ newrange.setStart(newblock.nextSibling, 0);
+ selection.removeAllRanges();
+ selection.addRange(newrange);
+ // browser does not scroll the caret position into view, do it manually
+ dojo.window.scrollIntoView(newblock.nextSibling);
+ }
+ _letBrowserHandle = false;
+ }else{ //press enter in the middle of P/DIV/Whatever/
+ if(block.blockNode === block.blockContainer){
+ block.blockNode.appendChild(newblock);
+ }else{
+ dojo.place(newblock, block.blockNode, "after");
+ }
+ _letBrowserHandle = false;
+
+ // Clone any block level styles.
+ if(block.blockNode.style){
+ if(newblock.style){
+ if(block.blockNode.style.cssText){
+ newblock.style.cssText = block.blockNode.style.cssText;
+ }
+ }
+ }
+
+ // Okay, we probably have to split.
+ rs = range.startContainer;
+ var firstNodeMoved;
+ if(rs && rs.nodeType == 3){
+ // Text node, we have to split it.
+ var nodeToMove, tNode;
+ endOffset = range.endOffset;
+ if(rs.length < endOffset){
+ //We are not splitting the right node, try to locate the correct one
+ ret = this._adjustNodeAndOffset(rs, endOffset);
+ rs = ret.node;
+ endOffset = ret.offset;
+ }
+
+ txt = rs.nodeValue;
+ startNode = doc.createTextNode(txt.substring(0, endOffset));
+ endNode = doc.createTextNode(txt.substring(endOffset, txt.length));
+
+ // Place the split, then remove original nodes.
+ dojo.place(startNode, rs, "before");
+ dojo.place(endNode, rs, "after");
+ dojo.destroy(rs);
+
+ // Okay, we split the text. Now we need to see if we're
+ // parented to the block element we're splitting and if
+ // not, we have to split all the way up. Ugh.
+ var parentC = startNode.parentNode;
+ while(parentC !== block.blockNode){
+ var tg = parentC.tagName;
+ var newTg = doc.createElement(tg);
+ // Clone over any 'style' data.
+ if(parentC.style){
+ if(newTg.style){
+ if(parentC.style.cssText){
+ newTg.style.cssText = parentC.style.cssText;
+ }
+ }
+ }
+ // If font also need to clone over any font data.
+ if(parentC.tagName === "FONT"){
+ if(parentC.color){
+ newTg.color = parentC.color;
+ }
+ if(parentC.face){
+ newTg.face = parentC.face;
+ }
+ if(parentC.size){ // this check was necessary on IE
+ newTg.size = parentC.size;
+ }
+ }
+
+ nodeToMove = endNode;
+ while(nodeToMove){
+ tNode = nodeToMove.nextSibling;
+ newTg.appendChild(nodeToMove);
+ nodeToMove = tNode;
+ }
+ dojo.place(newTg, parentC, "after");
+ startNode = parentC;
+ endNode = newTg;
+ parentC = parentC.parentNode;
+ }
+
+ // Lastly, move the split out tags to the new block.
+ // as they should now be split properly.
+ nodeToMove = endNode;
+ if(nodeToMove.nodeType == 1 || (nodeToMove.nodeType == 3 && nodeToMove.nodeValue)){
+ // Non-blank text and non-text nodes need to clear out that blank space
+ // before moving the contents.
+ newblock.innerHTML = "";
+ }
+ firstNodeMoved = nodeToMove;
+ while(nodeToMove){
+ tNode = nodeToMove.nextSibling;
+ newblock.appendChild(nodeToMove);
+ nodeToMove = tNode;
+ }
+ }
+
+ //lets move caret to the newly created block
+ newrange = dijit.range.create(this.editor.window);
+ var nodeForCursor;
+ var innerMostFirstNodeMoved = firstNodeMoved;
+ if(this.blockNodeForEnter !== 'BR'){
+ while(innerMostFirstNodeMoved){
+ nodeForCursor = innerMostFirstNodeMoved;
+ tNode = innerMostFirstNodeMoved.firstChild;
+ innerMostFirstNodeMoved = tNode;
+ }
+ if(nodeForCursor && nodeForCursor.parentNode){
+ newblock = nodeForCursor.parentNode;
+ newrange.setStart(newblock, 0);
+ selection.removeAllRanges();
+ selection.addRange(newrange);
+ if(this.editor.height){
+ dijit.scrollIntoView(newblock);
+ }
+ if(dojo.isMoz){
+ // press enter in middle of P may leave a trailing <br/>, let's remove it later
+ this._pressedEnterInBlock = block.blockNode;
+ }
+ }else{
+ _letBrowserHandle = true;
+ }
+ }else{
+ newrange.setStart(newblock, 0);
+ selection.removeAllRanges();
+ selection.addRange(newrange);
+ if(this.editor.height){
+ dijit.scrollIntoView(newblock);
+ }
+ if(dojo.isMoz){
+ // press enter in middle of P may leave a trailing <br/>, let's remove it later
+ this._pressedEnterInBlock = block.blockNode;
+ }
+ }
+ }
+ return _letBrowserHandle;
+ },
+
+ _adjustNodeAndOffset: function(/*DomNode*/node, /*Int*/offset){
+ // summary:
+ // In the case there are multiple text nodes in a row the offset may not be within the node. If the offset is larger than the node length, it will attempt to find
+ // the next text sibling until it locates the text node in which the offset refers to
+ // node:
+ // The node to check.
+ // offset:
+ // The position to find within the text node
+ // tags:
+ // private.
+ while(node.length < offset && node.nextSibling && node.nextSibling.nodeType==3){
+ //Adjust the offset and node in the case of multiple text nodes in a row
+ offset = offset - node.length;
+ node = node.nextSibling;
+ }
+ var ret = {"node": node, "offset": offset};
+ return ret;
+ },
+
+ removeTrailingBr: function(container){
+ // summary:
+ // If last child of container is a <br>, then remove it.
+ // tags:
+ // private
+ var para = /P|DIV|LI/i.test(container.tagName) ?
+ container : dijit._editor.selection.getParentOfType(container,['P','DIV','LI']);
+
+ if(!para){ return; }
+ if(para.lastChild){
+ if((para.childNodes.length > 1 && para.lastChild.nodeType == 3 && /^[\s\xAD]*$/.test(para.lastChild.nodeValue)) ||
+ para.lastChild.tagName=='BR'){
+
+ dojo.destroy(para.lastChild);
+ }
+ }
+ if(!para.childNodes.length){
+ para.innerHTML=this.bogusHtmlContent;
+ }
+ }
});
-dojo.forEach(_2b,function(p){
-var _2c=p.previousSibling;
-if((_2c)&&(_2c.nodeType==1)&&(_2c.nodeName=="P"||dojo.style(_2c,"display")!="block")){
-var _2d=p.parentNode.insertBefore(this.document.createElement("p"),p);
-_2d.innerHTML=_1b?"":"&nbsp;";
-}
-_25(p);
-},this.editor);
-_1c(_1a);
-return _1a;
-},singleLinePsToRegularPs:function(_2e){
-function _2f(_30){
-var ps=_30.getElementsByTagName("p");
-var _31=[];
-for(var i=0;i<ps.length;i++){
-var p=ps[i];
-var _32=false;
-for(var k=0;k<_31.length;k++){
-if(_31[k]===p.parentNode){
-_32=true;
-break;
-}
-}
-if(!_32){
-_31.push(p.parentNode);
-}
-}
-return _31;
-};
-function _33(_34){
-return (!_34.childNodes.length||_34.innerHTML=="&nbsp;");
-};
-var _35=_2f(_2e);
-for(var i=0;i<_35.length;i++){
-var _36=_35[i];
-var _37=null;
-var _38=_36.firstChild;
-var _39=null;
-while(_38){
-if(_38.nodeType!=1||_38.tagName!="P"||(_38.getAttributeNode("style")||{}).specified){
-_37=null;
-}else{
-if(_33(_38)){
-_39=_38;
-_37=null;
-}else{
-if(_37==null){
-_37=_38;
-}else{
-if((!_37.lastChild||_37.lastChild.nodeName!="BR")&&(_38.firstChild)&&(_38.firstChild.nodeName!="BR")){
-_37.appendChild(this.editor.document.createElement("br"));
-}
-while(_38.firstChild){
-_37.appendChild(_38.firstChild);
-}
-_39=_38;
-}
-}
-}
-_38=_38.nextSibling;
-if(_39){
-dojo.destroy(_39);
-_39=null;
-}
-}
-}
-return _2e;
-}});
+
}
diff --git a/lib/dijit/_editor/plugins/FontChoice.js b/lib/dijit/_editor/plugins/FontChoice.js
index c5578e3fb..ef91fd676 100644
--- a/lib/dijit/_editor/plugins/FontChoice.js
+++ b/lib/dijit/_editor/plugins/FontChoice.js
@@ -1,12 +1,12 @@
/*
- Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
-if(!dojo._hasResource["dijit._editor.plugins.FontChoice"]){
-dojo._hasResource["dijit._editor.plugins.FontChoice"]=true;
+if(!dojo._hasResource["dijit._editor.plugins.FontChoice"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._editor.plugins.FontChoice"] = true;
dojo.provide("dijit._editor.plugins.FontChoice");
dojo.require("dijit._editor._Plugin");
dojo.require("dijit._editor.range");
@@ -14,252 +14,570 @@ dojo.require("dijit._editor.selection");
dojo.require("dijit.form.FilteringSelect");
dojo.require("dojo.data.ItemFileReadStore");
dojo.require("dojo.i18n");
-dojo.requireLocalization("dijit._editor","FontChoice",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw");
-dojo.declare("dijit._editor.plugins._FontDropDown",[dijit._Widget,dijit._Templated],{label:"",widgetsInTemplate:true,plainText:false,templateString:"<span style='white-space: nowrap' class='dijit dijitReset dijitInline'>"+"<label class='dijitLeft dijitInline' for='${selectId}'>${label}</label>"+"<input dojoType='dijit.form.FilteringSelect' required=false labelType=html labelAttr=label searchAttr=name "+"tabIndex='-1' id='${selectId}' dojoAttachPoint='select' value=''/>"+"</span>",postMixInProperties:function(){
-this.inherited(arguments);
-this.strings=dojo.i18n.getLocalization("dijit._editor","FontChoice");
-this.label=this.strings[this.command];
-this.id=dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
-this.selectId=this.id+"_select";
-this.inherited(arguments);
-},postCreate:function(){
-var _1=dojo.map(this.values,function(_2){
-var _3=this.strings[_2]||_2;
-return {label:this.getLabel(_2,_3),name:_3,value:_2};
-},this);
-this.select.store=new dojo.data.ItemFileReadStore({data:{identifier:"value",items:_1}});
-this.select.set("value","",false);
-this.disabled=this.select.get("disabled");
-},_setValueAttr:function(_4,_5){
-_5=_5!==false?true:false;
-this.select.set("value",dojo.indexOf(this.values,_4)<0?"":_4,_5);
-if(!_5){
-this.select._lastValueReported=null;
-}
-},_getValueAttr:function(){
-return this.select.get("value");
-},focus:function(){
-this.select.focus();
-},_setDisabledAttr:function(_6){
-this.disabled=_6;
-this.select.set("disabled",_6);
-}});
-dojo.declare("dijit._editor.plugins._FontNameDropDown",dijit._editor.plugins._FontDropDown,{generic:false,command:"fontName",postMixInProperties:function(){
-if(!this.values){
-this.values=this.generic?["serif","sans-serif","monospace","cursive","fantasy"]:["Arial","Times New Roman","Comic Sans MS","Courier New"];
-}
-this.inherited(arguments);
-},getLabel:function(_7,_8){
-if(this.plainText){
-return _8;
-}else{
-return "<div style='font-family: "+_7+"'>"+_8+"</div>";
-}
-},_setValueAttr:function(_9,_a){
-_a=_a!==false?true:false;
-if(this.generic){
-var _b={"Arial":"sans-serif","Helvetica":"sans-serif","Myriad":"sans-serif","Times":"serif","Times New Roman":"serif","Comic Sans MS":"cursive","Apple Chancery":"cursive","Courier":"monospace","Courier New":"monospace","Papyrus":"fantasy"};
-_9=_b[_9]||_9;
-}
-this.inherited(arguments,[_9,_a]);
-}});
-dojo.declare("dijit._editor.plugins._FontSizeDropDown",dijit._editor.plugins._FontDropDown,{command:"fontSize",values:[1,2,3,4,5,6,7],getLabel:function(_c,_d){
-if(this.plainText){
-return _d;
-}else{
-return "<font size="+_c+"'>"+_d+"</font>";
-}
-},_setValueAttr:function(_e,_f){
-_f=_f!==false?true:false;
-if(_e.indexOf&&_e.indexOf("px")!=-1){
-var _10=parseInt(_e,10);
-_e={10:1,13:2,16:3,18:4,24:5,32:6,48:7}[_10]||_e;
-}
-this.inherited(arguments,[_e,_f]);
-}});
-dojo.declare("dijit._editor.plugins._FormatBlockDropDown",dijit._editor.plugins._FontDropDown,{command:"formatBlock",values:["noFormat","p","h1","h2","h3","pre"],postCreate:function(){
-this.inherited(arguments);
-this.set("value","noFormat",false);
-},getLabel:function(_11,_12){
-if(this.plainText){
-return _12;
-}else{
-return "<"+_11+">"+_12+"</"+_11+">";
-}
-},_execCommand:function(_13,_14,_15){
-if(_15==="noFormat"){
-var _16;
-var end;
-var sel=dijit.range.getSelection(_13.window);
-if(sel&&sel.rangeCount>0){
-var _17=sel.getRangeAt(0);
-var _18,tag;
-if(_17){
-_16=_17.startContainer;
-end=_17.endContainer;
-while(_16&&_16!==_13.editNode&&_16!==_13.document.body&&_16.nodeType!==1){
-_16=_16.parentNode;
-}
-while(end&&end!==_13.editNode&&end!==_13.document.body&&end.nodeType!==1){
-end=end.parentNode;
-}
-var _19=dojo.hitch(this,function(_1a,_1b){
-if(_1a.childNodes&&_1a.childNodes.length){
-var i;
-for(i=0;i<_1a.childNodes.length;i++){
-var c=_1a.childNodes[i];
-if(c.nodeType==1){
-if(dojo.withGlobal(_13.window,"inSelection",dijit._editor.selection,[c])){
-var tag=c.tagName?c.tagName.toLowerCase():"";
-if(dojo.indexOf(this.values,tag)!==-1){
-_1b.push(c);
-}
-_19(c,_1b);
-}
-}
-}
-}
+dojo.requireLocalization("dijit._editor", "FontChoice", null, "ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,kk,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw");
+
+
+dojo.declare("dijit._editor.plugins._FontDropDown",
+ [dijit._Widget, dijit._Templated],{
+ // summary:
+ // Base class for widgets that contains a label (like "Font:")
+ // and a FilteringSelect drop down to pick a value.
+ // Used as Toolbar entry.
+
+ // label: [public] String
+ // The label to apply to this particular FontDropDown.
+ label: "",
+
+ // widgetsInTemplate: [public] boolean
+ // Over-ride denoting the template has widgets to parse.
+ widgetsInTemplate: true,
+
+ // plainText: [public] boolean
+ // Flag to indicate that the returned label should be plain text
+ // instead of an example.
+ plainText: false,
+
+ // templateString: [public] String
+ // The template used to construct the labeled dropdown.
+ templateString:
+ "<span style='white-space: nowrap' class='dijit dijitReset dijitInline'>" +
+ "<label class='dijitLeft dijitInline' for='${selectId}'>${label}</label>" +
+ "<input dojoType='dijit.form.FilteringSelect' required='false' labelType='html' labelAttr='label' searchAttr='name' " +
+ "tabIndex='-1' id='${selectId}' dojoAttachPoint='select' value=''/>" +
+ "</span>",
+
+ postMixInProperties: function(){
+ // summary:
+ // Over-ride to set specific properties.
+ this.inherited(arguments);
+
+ this.strings = dojo.i18n.getLocalization("dijit._editor", "FontChoice");
+
+ // Set some substitution variables used in the template
+ this.label = this.strings[this.command];
+ this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
+ this.selectId = this.id + "_select";
+
+ this.inherited(arguments);
+ },
+
+ postCreate: function(){
+ // summary:
+ // Over-ride for the default postCreate action
+ // This establishes the filtering selects and the like.
+
+ // Initialize the list of items in the drop down by creating data store with items like:
+ // {value: 1, name: "xx-small", label: "<font size=1>xx-small</font-size>" }
+ var items = dojo.map(this.values, function(value){
+ var name = this.strings[value] || value;
+ return {
+ label: this.getLabel(value, name),
+ name: name,
+ value: value
+ };
+ }, this);
+
+ this.select.store = new dojo.data.ItemFileReadStore({
+ data: {
+ identifier: "value",
+ items: items
+ }
+ });
+
+ this.select.set("value", "", false);
+ this.disabled = this.select.get("disabled");
+ },
+
+ _setValueAttr: function(value, priorityChange){
+ // summary:
+ // Over-ride for the default action of setting the
+ // widget value, maps the input to known values
+ // value: Object|String
+ // The value to set in the select.
+ // priorityChange:
+ // Optional parameter used to tell the select whether or not to fire
+ // onChange event.
+
+ //if the value is not a permitted value, just set empty string to prevent showing the warning icon
+ priorityChange = priorityChange !== false?true:false;
+ this.select.set('value', dojo.indexOf(this.values,value) < 0 ? "" : value, priorityChange);
+ if(!priorityChange){
+ // Clear the last state in case of updateState calls. Ref: #10466
+ this.select._lastValueReported=null;
+ }
+ },
+
+ _getValueAttr: function(){
+ // summary:
+ // Allow retreiving the value from the composite select on
+ // call to button.get("value");
+ return this.select.get('value');
+ },
+
+ focus: function(){
+ // summary:
+ // Over-ride for focus control of this widget. Delegates focus down to the
+ // filtering select.
+ this.select.focus();
+ },
+
+ _setDisabledAttr: function(value){
+ // summary:
+ // Over-ride for the button's 'disabled' attribute so that it can be
+ // disabled programmatically.
+
+ // Save off ths disabled state so the get retrieves it correctly
+ //without needing to have a function proxy it.
+ this.disabled = value;
+ this.select.set("disabled", value);
+ }
});
-var _1c=dojo.hitch(this,function(_1d){
-if(_1d&&_1d.length){
-_13.beginEditing();
-while(_1d.length){
-this._removeFormat(_13,_1d.pop());
-}
-_13.endEditing();
-}
+
+
+dojo.declare("dijit._editor.plugins._FontNameDropDown", dijit._editor.plugins._FontDropDown, {
+ // summary:
+ // Dropdown to select a font; goes in editor toolbar.
+
+ // generic: Boolean
+ // Use generic (web standard) font names
+ generic: false,
+
+ // command: [public] String
+ // The editor 'command' implemented by this plugin.
+ command: "fontName",
+
+ postMixInProperties: function(){
+ // summary:
+ // Over-ride for the default posr mixin control
+ if(!this.values){
+ this.values = this.generic ?
+ ["serif", "sans-serif", "monospace", "cursive", "fantasy"] : // CSS font-family generics
+ ["Arial", "Times New Roman", "Comic Sans MS", "Courier New"];
+ }
+ this.inherited(arguments);
+ },
+
+ getLabel: function(value, name){
+ // summary:
+ // Function used to generate the labels of the format dropdown
+ // will return a formatted, or plain label based on the value
+ // of the plainText option.
+ // value: String
+ // The 'insert value' associated with a name
+ // name: String
+ // The text name of the value
+ if(this.plainText){
+ return name;
+ }else{
+ return "<div style='font-family: "+value+"'>" + name + "</div>";
+ }
+ },
+
+ _setValueAttr: function(value, priorityChange){
+ // summary:
+ // Over-ride for the default action of setting the
+ // widget value, maps the input to known values
+
+ priorityChange = priorityChange !== false?true:false;
+ if(this.generic){
+ var map = {
+ "Arial": "sans-serif",
+ "Helvetica": "sans-serif",
+ "Myriad": "sans-serif",
+ "Times": "serif",
+ "Times New Roman": "serif",
+ "Comic Sans MS": "cursive",
+ "Apple Chancery": "cursive",
+ "Courier": "monospace",
+ "Courier New": "monospace",
+ "Papyrus": "fantasy"
+// ,"????": "fantasy" TODO: IE doesn't map fantasy font-family?
+ };
+ value = map[value] || value;
+ }
+ this.inherited(arguments, [value, priorityChange]);
+ }
});
-var _1e=[];
-if(_16==end){
-var _1f;
-_18=_16;
-while(_18&&_18!==_13.editNode&&_18!==_13.document.body){
-if(_18.nodeType==1){
-tag=_18.tagName?_18.tagName.toLowerCase():"";
-if(dojo.indexOf(this.values,tag)!==-1){
-_1f=_18;
-break;
-}
-}
-_18=_18.parentNode;
-}
-_19(_16,_1e);
-if(_1f){
-_1e=[_1f].concat(_1e);
-}
-_1c(_1e);
-}else{
-_18=_16;
-while(dojo.withGlobal(_13.window,"inSelection",dijit._editor.selection,[_18])){
-if(_18.nodeType==1){
-tag=_18.tagName?_18.tagName.toLowerCase():"";
-if(dojo.indexOf(this.values,tag)!==-1){
-_1e.push(_18);
-}
-_19(_18,_1e);
-}
-_18=_18.nextSibling;
-}
-_1c(_1e);
-}
-_13.onDisplayChanged();
-}
-}
-}else{
-_13.execCommand(_14,_15);
-}
-},_removeFormat:function(_20,_21){
-if(_20.customUndo){
-while(_21.firstChild){
-dojo.place(_21.firstChild,_21,"before");
-}
-_21.parentNode.removeChild(_21);
-}else{
-dojo.withGlobal(_20.window,"selectElementChildren",dijit._editor.selection,[_21]);
-var _22=dojo.withGlobal(_20.window,"getSelectedHtml",dijit._editor.selection,[null]);
-dojo.withGlobal(_20.window,"selectElement",dijit._editor.selection,[_21]);
-_20.execCommand("inserthtml",_22||"");
-}
-}});
-dojo.declare("dijit._editor.plugins.FontChoice",dijit._editor._Plugin,{useDefaultCommand:false,_initButton:function(){
-var _23={fontName:dijit._editor.plugins._FontNameDropDown,fontSize:dijit._editor.plugins._FontSizeDropDown,formatBlock:dijit._editor.plugins._FormatBlockDropDown}[this.command],_24=this.params;
-if(this.params.custom){
-_24.values=this.params.custom;
-}
-var _25=this.editor;
-this.button=new _23(dojo.delegate({dir:_25.dir,lang:_25.lang},_24));
-this.connect(this.button.select,"onChange",function(_26){
-this.editor.focus();
-if(this.command=="fontName"&&_26.indexOf(" ")!=-1){
-_26="'"+_26+"'";
-}
-if(this.button._execCommand){
-this.button._execCommand(this.editor,this.command,_26);
-}else{
-this.editor.execCommand(this.command,_26);
-}
-this.editor.customUndo=this.editor.customUndo||dojo.isWebKit;
+
+dojo.declare("dijit._editor.plugins._FontSizeDropDown", dijit._editor.plugins._FontDropDown, {
+ // summary:
+ // Dropdown to select a font size; goes in editor toolbar.
+
+ // command: [public] String
+ // The editor 'command' implemented by this plugin.
+ command: "fontSize",
+
+ // values: [public] Number[]
+ // The HTML font size values supported by this plugin
+ values: [1,2,3,4,5,6,7], // sizes according to the old HTML FONT SIZE
+
+ getLabel: function(value, name){
+ // summary:
+ // Function used to generate the labels of the format dropdown
+ // will return a formatted, or plain label based on the value
+ // of the plainText option.
+ // We're stuck using the deprecated FONT tag to correspond
+ // with the size measurements used by the editor
+ // value: String
+ // The 'insert value' associated with a name
+ // name: String
+ // The text name of the value
+ if(this.plainText){
+ return name;
+ }else{
+ return "<font size=" + value + "'>" + name + "</font>";
+ }
+ },
+
+ _setValueAttr: function(value, priorityChange){
+ // summary:
+ // Over-ride for the default action of setting the
+ // widget value, maps the input to known values
+ priorityChange = priorityChange !== false?true:false;
+ if(value.indexOf && value.indexOf("px") != -1){
+ var pixels = parseInt(value, 10);
+ value = {10:1, 13:2, 16:3, 18:4, 24:5, 32:6, 48:7}[pixels] || value;
+ }
+
+ this.inherited(arguments, [value, priorityChange]);
+ }
});
-},updateState:function(){
-var _27=this.editor;
-var _28=this.command;
-if(!_27||!_27.isLoaded||!_28.length){
-return;
-}
-if(this.button){
-var _29;
-try{
-_29=_27.queryCommandValue(_28)||"";
-}
-catch(e){
-_29="";
-}
-var _2a=dojo.isString(_29)&&_29.match(/'([^']*)'/);
-if(_2a){
-_29=_2a[1];
-}
-if(_28==="formatBlock"){
-if(!_29||_29=="p"){
-_29=null;
-var _2b;
-var sel=dijit.range.getSelection(this.editor.window);
-if(sel&&sel.rangeCount>0){
-var _2c=sel.getRangeAt(0);
-if(_2c){
-_2b=_2c.endContainer;
-}
-}
-while(_2b&&_2b!==_27.editNode&&_2b!==_27.document){
-var tg=_2b.tagName?_2b.tagName.toLowerCase():"";
-if(tg&&dojo.indexOf(this.button.values,tg)>-1){
-_29=tg;
-break;
-}
-_2b=_2b.parentNode;
-}
-if(!_29){
-_29="noFormat";
-}
-}else{
-if(dojo.indexOf(this.button.values,_29)<0){
-_29="noFormat";
-}
-}
-}
-if(_29!==this.button.get("value")){
-this.button.set("value",_29,false);
-}
-}
-}});
-dojo.subscribe(dijit._scopeName+".Editor.getPlugin",null,function(o){
-if(o.plugin){
-return;
-}
-switch(o.args.name){
-case "fontName":
-case "fontSize":
-case "formatBlock":
-o.plugin=new dijit._editor.plugins.FontChoice({command:o.args.name,plainText:o.args.plainText?o.args.plainText:false});
-}
+
+
+dojo.declare("dijit._editor.plugins._FormatBlockDropDown", dijit._editor.plugins._FontDropDown, {
+ // summary:
+ // Dropdown to select a format (like paragraph or heading); goes in editor toolbar.
+
+ // command: [public] String
+ // The editor 'command' implemented by this plugin.
+ command: "formatBlock",
+
+ // values: [public] Array
+ // The HTML format tags supported by this plugin
+ values: ["noFormat", "p", "h1", "h2", "h3", "pre"],
+
+ postCreate: function(){
+ // Init and set the default value to no formatting. Update state will adjust it
+ // as needed.
+ this.inherited(arguments);
+ this.set("value", "noFormat", false);
+ },
+
+ getLabel: function(value, name){
+ // summary:
+ // Function used to generate the labels of the format dropdown
+ // will return a formatted, or plain label based on the value
+ // of the plainText option.
+ // value: String
+ // The 'insert value' associated with a name
+ // name: String
+ // The text name of the value
+ if(this.plainText || value == "noFormat"){
+ return name;
+ }else{
+ return "<" + value + ">" + name + "</" + value + ">";
+ }
+ },
+
+ _execCommand: function(editor, command, choice){
+ // summary:
+ // Over-ride for default exec-command label.
+ // Allows us to treat 'none' as special.
+ if(choice === "noFormat"){
+ var start;
+ var end;
+ var sel = dijit.range.getSelection(editor.window);
+ if(sel && sel.rangeCount > 0){
+ var range = sel.getRangeAt(0);
+ var node, tag;
+ if(range){
+ start = range.startContainer;
+ end = range.endContainer;
+
+ // find containing nodes of start/end.
+ while(start && start !== editor.editNode &&
+ start !== editor.document.body &&
+ start.nodeType !== 1){
+ start = start.parentNode;
+ }
+
+ while(end && end !== editor.editNode &&
+ end !== editor.document.body &&
+ end.nodeType !== 1){
+ end = end.parentNode;
+ }
+
+ var processChildren = dojo.hitch(this, function(node, array){
+ if(node.childNodes && node.childNodes.length){
+ var i;
+ for(i = 0; i < node.childNodes.length; i++){
+ var c = node.childNodes[i];
+ if(c.nodeType == 1){
+ if(dojo.withGlobal(editor.window, "inSelection", dijit._editor.selection, [c])){
+ var tag = c.tagName? c.tagName.toLowerCase(): "";
+ if(dojo.indexOf(this.values, tag) !== -1){
+ array.push(c);
+ }
+ processChildren(c,array);
+ }
+ }
+ }
+ }
+ });
+
+ var unformatNodes = dojo.hitch(this, function(nodes){
+ // summary:
+ // Internal function to clear format nodes.
+ // nodes:
+ // The array of nodes to strip formatting from.
+ if(nodes && nodes.length){
+ editor.beginEditing();
+ while(nodes.length){
+ this._removeFormat(editor, nodes.pop());
+ }
+ editor.endEditing();
+ }
+ });
+
+ var clearNodes = [];
+ if(start == end){
+ //Contained within the same block, may be collapsed, but who cares, see if we
+ // have a block element to remove.
+ var block;
+ node = start;
+ while(node && node !== editor.editNode && node !== editor.document.body){
+ if(node.nodeType == 1){
+ tag = node.tagName? node.tagName.toLowerCase(): "";
+ if(dojo.indexOf(this.values, tag) !== -1){
+ block = node;
+ break;
+ }
+ }
+ node = node.parentNode;
+ }
+
+ //Also look for all child nodes in the selection that may need to be
+ //cleared of formatting
+ processChildren(start, clearNodes);
+ if(block) { clearNodes = [block].concat(clearNodes); }
+ unformatNodes(clearNodes);
+ }else{
+ // Probably a multi select, so we have to process it. Whee.
+ node = start;
+ while(dojo.withGlobal(editor.window, "inSelection", dijit._editor.selection, [node])){
+ if(node.nodeType == 1){
+ tag = node.tagName? node.tagName.toLowerCase(): "";
+ if(dojo.indexOf(this.values, tag) !== -1){
+ clearNodes.push(node);
+ }
+ processChildren(node,clearNodes);
+ }
+ node = node.nextSibling;
+ }
+ unformatNodes(clearNodes);
+ }
+ editor.onDisplayChanged();
+ }
+ }
+ }else{
+ editor.execCommand(command, choice);
+ }
+ },
+
+ _removeFormat: function(editor, node){
+ // summary:
+ // function to remove the block format node.
+ // node:
+ // The block format node to remove (and leave the contents behind)
+ if(editor.customUndo){
+ // So of course IE doesn't work right with paste-overs.
+ // We have to do this manually, which is okay since IE already uses
+ // customUndo and we turned it on for WebKit. WebKit pasted funny,
+ // so couldn't use the execCommand approach
+ while(node.firstChild){
+ dojo.place(node.firstChild, node, "before");
+ }
+ node.parentNode.removeChild(node);
+ }else{
+ // Everyone else works fine this way, a paste-over and is native
+ // undo friendly.
+ dojo.withGlobal(editor.window,
+ "selectElementChildren", dijit._editor.selection, [node]);
+ var html = dojo.withGlobal(editor.window,
+ "getSelectedHtml", dijit._editor.selection, [null]);
+ dojo.withGlobal(editor.window,
+ "selectElement", dijit._editor.selection, [node]);
+ editor.execCommand("inserthtml", html||"");
+ }
+ }
+});
+
+// TODO: for 2.0, split into FontChoice plugin into three separate classes,
+// one for each command (and change registry below)
+dojo.declare("dijit._editor.plugins.FontChoice", dijit._editor._Plugin,{
+ // summary:
+ // This plugin provides three drop downs for setting style in the editor
+ // (font, font size, and format block), as controlled by command.
+ //
+ // description:
+ // The commands provided by this plugin are:
+ //
+ // * fontName
+ // | Provides a drop down to select from a list of font names
+ // * fontSize
+ // | Provides a drop down to select from a list of font sizes
+ // * formatBlock
+ // | Provides a drop down to select from a list of block styles
+ // |
+ //
+ // which can easily be added to an editor by including one or more of the above commands
+ // in the `plugins` attribute as follows:
+ //
+ // | plugins="['fontName','fontSize',...]"
+ //
+ // It is possible to override the default dropdown list by providing an Array for the `custom` property when
+ // instantiating this plugin, e.g.
+ //
+ // | plugins="[{name:'dijit._editor.plugins.FontChoice', command:'fontName', custom:['Verdana','Myriad','Garamond']},...]"
+ //
+ // Alternatively, for `fontName` only, `generic:true` may be specified to provide a dropdown with
+ // [CSS generic font families](http://www.w3.org/TR/REC-CSS2/fonts.html#generic-font-families)
+ //
+ // Note that the editor is often unable to properly handle font styling information defined outside
+ // the context of the current editor instance, such as pre-populated HTML.
+
+ // useDefaultCommand: [protected] booleam
+ // Override _Plugin.useDefaultCommand...
+ // processing is handled by this plugin, not by dijit.Editor.
+ useDefaultCommand: false,
+
+ _initButton: function(){
+ // summary:
+ // Overrides _Plugin._initButton(), to initialize the FilteringSelect+label in toolbar,
+ // rather than a simple button.
+ // tags:
+ // protected
+
+ // Create the widget to go into the toolbar (the so-called "button")
+ var clazz = {
+ fontName: dijit._editor.plugins._FontNameDropDown,
+ fontSize: dijit._editor.plugins._FontSizeDropDown,
+ formatBlock: dijit._editor.plugins._FormatBlockDropDown
+ }[this.command],
+ params = this.params;
+
+ // For back-compat reasons support setting custom values via "custom" parameter
+ // rather than "values" parameter
+ if(this.params.custom){
+ params.values = this.params.custom;
+ }
+
+ var editor = this.editor;
+ this.button = new clazz(dojo.delegate({dir: editor.dir, lang: editor.lang}, params));
+
+ // Reflect changes to the drop down in the editor
+ this.connect(this.button.select, "onChange", function(choice){
+ // User invoked change, since all internal updates set priorityChange to false and will
+ // not trigger an onChange event.
+ this.editor.focus();
+
+ if(this.command == "fontName" && choice.indexOf(" ") != -1){ choice = "'" + choice + "'"; }
+
+ // Invoke, the editor already normalizes commands called through its
+ // execCommand.
+ if(this.button._execCommand){
+ this.button._execCommand(this.editor, this.command, choice);
+ }else{
+ this.editor.execCommand(this.command, choice);
+ }
+ });
+ },
+
+ updateState: function(){
+ // summary:
+ // Overrides _Plugin.updateState(). This controls updating the menu
+ // options to the right values on state changes in the document (that trigger a
+ // test of the actions.)
+ // It set value of drop down in toolbar to reflect font/font size/format block
+ // of text at current caret position.
+ // tags:
+ // protected
+ var _e = this.editor;
+ var _c = this.command;
+ if(!_e || !_e.isLoaded || !_c.length){ return; }
+
+ if(this.button){
+ var disabled = this.get("disabled");
+ this.button.set("disabled", disabled);
+ if(disabled){ return; }
+ var value;
+ try{
+ value = _e.queryCommandValue(_c) || "";
+ }catch(e){
+ //Firefox may throw error above if the editor is just loaded, ignore it
+ value = "";
+ }
+
+ // strip off single quotes, if any
+ var quoted = dojo.isString(value) && value.match(/'([^']*)'/);
+ if(quoted){ value = quoted[1]; }
+
+ if(_c === "formatBlock"){
+ if(!value || value == "p"){
+ // Some browsers (WebKit) doesn't actually get the tag info right.
+ // and IE returns paragraph when in a DIV!, so incorrect a lot,
+ // so we have double-check it.
+ value = null;
+ var elem;
+ // Try to find the current element where the caret is.
+ var sel = dijit.range.getSelection(this.editor.window);
+ if(sel && sel.rangeCount > 0){
+ var range = sel.getRangeAt(0);
+ if(range){
+ elem = range.endContainer;
+ }
+ }
+
+ // Okay, now see if we can find one of the formatting types we're in.
+ while(elem && elem !== _e.editNode && elem !== _e.document){
+ var tg = elem.tagName?elem.tagName.toLowerCase():"";
+ if(tg && dojo.indexOf(this.button.values, tg) > -1){
+ value = tg;
+ break;
+ }
+ elem = elem.parentNode;
+ }
+ if(!value){
+ // Still no value, so lets select 'none'.
+ value = "noFormat";
+ }
+ }else{
+ // Check that the block format is one allowed, if not,
+ // null it so that it gets set to empty.
+ if(dojo.indexOf(this.button.values, value) < 0){
+ value = "noFormat";
+ }
+ }
+ }
+ if(value !== this.button.get("value")){
+ // Set the value, but denote it is not a priority change, so no
+ // onchange fires.
+ this.button.set('value', value, false);
+ }
+ }
+ }
});
+
+// Register this plugin.
+dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
+ if(o.plugin){ return; }
+ switch(o.args.name){
+ case "fontName": case "fontSize": case "formatBlock":
+ o.plugin = new dijit._editor.plugins.FontChoice({
+ command: o.args.name,
+ plainText: o.args.plainText?o.args.plainText:false
+ });
+ }
+});
+
}
diff --git a/lib/dijit/_editor/plugins/FullScreen.js b/lib/dijit/_editor/plugins/FullScreen.js
index 7a6dac55d..6978252c8 100644
--- a/lib/dijit/_editor/plugins/FullScreen.js
+++ b/lib/dijit/_editor/plugins/FullScreen.js
@@ -1,232 +1,441 @@
/*
- Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
-if(!dojo._hasResource["dijit._editor.plugins.FullScreen"]){
-dojo._hasResource["dijit._editor.plugins.FullScreen"]=true;
+if(!dojo._hasResource["dijit._editor.plugins.FullScreen"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._editor.plugins.FullScreen"] = true;
dojo.provide("dijit._editor.plugins.FullScreen");
dojo.require("dojo.window");
dojo.require("dojo.i18n");
dojo.require("dijit._editor._Plugin");
dojo.require("dijit.form.Button");
-dojo.requireLocalization("dijit._editor","commands",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw");
-dojo.declare("dijit._editor.plugins.FullScreen",dijit._editor._Plugin,{zIndex:500,_origState:null,_origiFrameState:null,_resizeHandle:null,isFullscreen:false,toggle:function(){
-this.button.set("checked",!this.button.get("checked"));
-},_initButton:function(){
-var _1=dojo.i18n.getLocalization("dijit._editor","commands"),_2=this.editor;
-this.button=new dijit.form.ToggleButton({label:_1["fullScreen"],dir:_2.dir,lang:_2.lang,showLabel:false,iconClass:this.iconClassPrefix+" "+this.iconClassPrefix+"FullScreen",tabIndex:"-1",onChange:dojo.hitch(this,"_setFullScreen")});
-},setEditor:function(_3){
-this.editor=_3;
-this._initButton();
-this.editor.addKeyHandler(dojo.keys.F11,true,true,dojo.hitch(this,function(e){
-this.toggle();
-dojo.stopEvent(e);
-setTimeout(dojo.hitch(this,function(){
-this.editor.focus();
-}),250);
-return true;
-}));
-this.connect(this.editor.domNode,"onkeydown","_containFocus");
-},_containFocus:function(e){
-if(this.isFullscreen){
-var ed=this.editor;
-if(!ed.isTabIndent&&ed._fullscreen_oldOnKeyDown&&e.keyCode===dojo.keys.TAB){
-var f=dijit.getFocus();
-var _4=this._getAltViewNode();
-if(f.node==ed.iframe||(_4&&f.node===_4)){
-setTimeout(dojo.hitch(this,function(){
-ed.toolbar.focus();
-}),10);
-}else{
-if(_4&&dojo.style(ed.iframe,"display")==="none"){
-setTimeout(dojo.hitch(this,function(){
-dijit.focus(_4);
-}),10);
-}else{
-setTimeout(dojo.hitch(this,function(){
-ed.focus();
-}),10);
-}
-}
-dojo.stopEvent(e);
-}else{
-if(ed._fullscreen_oldOnKeyDown){
-ed._fullscreen_oldOnKeyDown(e);
-}
-}
-}
-},_resizeEditor:function(){
-var vp=dojo.window.getBox();
-dojo.marginBox(this.editor.domNode,{w:vp.w,h:vp.h});
-var _5=this.editor.getHeaderHeight();
-var _6=this.editor.getFooterHeight();
-var _7=dojo._getPadBorderExtents(this.editor.domNode);
-var _8=dojo._getPadBorderExtents(this.editor.iframe.parentNode);
-var _9=dojo._getMarginExtents(this.editor.iframe.parentNode);
-var _a=vp.h-(_5+_7.h+_6);
-dojo.marginBox(this.editor.iframe.parentNode,{h:_a,w:vp.w});
-dojo.marginBox(this.editor.iframe,{h:_a-(_8.h+_9.h)});
-},_getAltViewNode:function(){
-},_setFullScreen:function(_b){
-var vp=dojo.window.getBox();
-var ed=this.editor;
-var _c=dojo.body();
-var _d=ed.domNode.parentNode;
-this.isFullscreen=_b;
-if(_b){
-while(_d&&_d!==dojo.body()){
-dojo.addClass(_d,"dijitForceStatic");
-_d=_d.parentNode;
-}
-this._editorResizeHolder=this.editor.resize;
-ed.resize=function(){
-};
-ed._fullscreen_oldOnKeyDown=ed.onKeyDown;
-ed.onKeyDown=dojo.hitch(this,this._containFocus);
-this._origState={};
-this._origiFrameState={};
-var _e=ed.domNode,_f=_e&&_e.style||{};
-this._origState={width:_f.width||"",height:_f.height||"",top:dojo.style(_e,"top")||"",left:dojo.style(_e,"left")||"",position:dojo.style(_e,"position")||"static",marginBox:dojo.marginBox(ed.domNode)};
-var _10=ed.iframe,_11=_10&&_10.style||{};
-var bc=dojo.style(ed.iframe,"backgroundColor");
-this._origiFrameState={backgroundColor:bc||"transparent",width:_11.width||"auto",height:_11.height||"auto",zIndex:_11.zIndex||""};
-dojo.style(ed.domNode,{position:"absolute",top:"0px",left:"0px",zIndex:this.zIndex,width:vp.w+"px",height:vp.h+"px"});
-dojo.style(ed.iframe,{height:"100%",width:"100%",zIndex:this.zIndex,backgroundColor:bc!=="transparent"&&bc!=="rgba(0, 0, 0, 0)"?bc:"white"});
-dojo.style(ed.iframe.parentNode,{height:"95%",width:"100%"});
-if(_c.style&&_c.style.overflow){
-this._oldOverflow=dojo.style(_c,"overflow");
-}else{
-this._oldOverflow="";
-}
-if(dojo.isIE&&!dojo.isQuirks){
-if(_c.parentNode&&_c.parentNode.style&&_c.parentNode.style.overflow){
-this._oldBodyParentOverflow=_c.parentNode.style.overflow;
-}else{
-try{
-this._oldBodyParentOverflow=dojo.style(_c.parentNode,"overflow");
-}
-catch(e){
-this._oldBodyParentOverflow="scroll";
-}
-}
-dojo.style(_c.parentNode,"overflow","hidden");
-}
-dojo.style(_c,"overflow","hidden");
-var _12=function(){
-var vp=dojo.window.getBox();
-if("_prevW" in this&&"_prevH" in this){
-if(vp.w===this._prevW&&vp.h===this._prevH){
-return;
-}
-}else{
-this._prevW=vp.w;
-this._prevH=vp.h;
-}
-if(this._resizer){
-clearTimeout(this._resizer);
-delete this._resizer;
-}
-this._resizer=setTimeout(dojo.hitch(this,function(){
-delete this._resizer;
-this._resizeEditor();
-}),10);
-};
-this._resizeHandle=dojo.connect(window,"onresize",this,_12);
-this._resizeHandle2=dojo.connect(ed,"resize",dojo.hitch(this,function(){
-if(this._resizer){
-clearTimeout(this._resizer);
-delete this._resizer;
-}
-this._resizer=setTimeout(dojo.hitch(this,function(){
-delete this._resizer;
-this._resizeEditor();
-}),10);
-}));
-this._resizeEditor();
-var dn=this.editor.toolbar.domNode;
-setTimeout(function(){
-dojo.window.scrollIntoView(dn);
-},250);
-}else{
-if(this._resizeHandle){
-dojo.disconnect(this._resizeHandle);
-this._resizeHandle=null;
-}
-if(this._resizeHandle2){
-dojo.disconnect(this._resizeHandle2);
-this._resizeHandle2=null;
-}
-if(this._rst){
-clearTimeout(this._rst);
-this._rst=null;
-}
-while(_d&&_d!==dojo.body()){
-dojo.removeClass(_d,"dijitForceStatic");
-_d=_d.parentNode;
-}
-if(this._editorResizeHolder){
-this.editor.resize=this._editorResizeHolder;
-}
-if(!this._origState&&!this._origiFrameState){
-return;
-}
-if(ed._fullscreen_oldOnKeyDown){
-ed.onKeyDown=ed._fullscreen_oldOnKeyDown;
-delete ed._fullscreen_oldOnKeyDown;
-}
-var _13=this;
-setTimeout(function(){
-var mb=_13._origState.marginBox;
-var oh=_13._origState.height;
-if(dojo.isIE&&!dojo.isQuirks){
-_c.parentNode.style.overflow=_13._oldBodyParentOverflow;
-delete _13._oldBodyParentOverflow;
-}
-dojo.style(_c,"overflow",_13._oldOverflow);
-delete _13._oldOverflow;
-dojo.style(ed.domNode,_13._origState);
-dojo.style(ed.iframe.parentNode,{height:"",width:""});
-dojo.style(ed.iframe,_13._origiFrameState);
-delete _13._origState;
-delete _13._origiFrameState;
-var _14=dijit.getEnclosingWidget(ed.domNode.parentNode);
-if(_14&&_14.resize){
-_14.resize();
-}else{
-if(!oh||oh.indexOf("%")<0){
-setTimeout(dojo.hitch(this,function(){
-ed.resize({h:mb.h});
-}),0);
-}
-}
-dojo.window.scrollIntoView(_13.editor.toolbar.domNode);
-},100);
-}
-},destroy:function(){
-if(this._resizeHandle){
-dojo.disconnect(this._resizeHandle);
-this._resizeHandle=null;
-}
-if(this._resizeHandle2){
-dojo.disconnect(this._resizeHandle2);
-this._resizeHandle2=null;
-}
-if(this._resizer){
-clearTimeout(this._resizer);
-this._resizer=null;
-}
-this.inherited(arguments);
-}});
-dojo.subscribe(dijit._scopeName+".Editor.getPlugin",null,function(o){
-if(o.plugin){
-return;
-}
-var _15=o.args.name.toLowerCase();
-if(_15==="fullscreen"){
-o.plugin=new dijit._editor.plugins.FullScreen({zIndex:("zIndex" in o.args)?o.args.zIndex:500});
-}
+dojo.requireLocalization("dijit._editor", "commands", null, "ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,kk,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw");
+
+
+dojo.declare("dijit._editor.plugins.FullScreen",dijit._editor._Plugin,{
+ // summary:
+ // This plugin provides FullScreen cabability to the editor. When
+ // toggled on, it will render the editor into the full window and
+ // overlay everything. It also binds to the hotkey: CTRL-SHIFT-F11
+ // for toggling fullscreen mode.
+
+ // zIndex: [public] Number
+ // zIndex value used for overlaying the full page.
+ // default is 500.
+ zIndex: 500,
+
+ // _origState: [private] Object
+ // The original view state of the editor.
+ _origState: null,
+
+ // _origiFrameState: [private] Object
+ // The original view state of the iframe of the editor.
+ _origiFrameState: null,
+
+ // _resizeHandle: [private] Object
+ // Connection point used for handling resize when window resizes.
+ _resizeHandle: null,
+
+ // isFullscreen: [const] boolean
+ // Read-Only variable used to denote of the editor is in fullscreen mode or not.
+ isFullscreen: false,
+
+ toggle: function(){
+ // summary:
+ // Function to allow programmatic toggling of the view.
+ this.button.set("checked", !this.button.get("checked"));
+ },
+
+ _initButton: function(){
+ // summary:
+ // Over-ride for creation of the resize button.
+ var strings = dojo.i18n.getLocalization("dijit._editor", "commands"),
+ editor = this.editor;
+ this.button = new dijit.form.ToggleButton({
+ label: strings["fullScreen"],
+ dir: editor.dir,
+ lang: editor.lang,
+ showLabel: false,
+ iconClass: this.iconClassPrefix + " " + this.iconClassPrefix + "FullScreen",
+ tabIndex: "-1",
+ onChange: dojo.hitch(this, "_setFullScreen")
+ });
+ },
+
+ setEditor: function(editor){
+ // summary:
+ // Over-ride for the setting of the editor.
+ // editor: Object
+ // The editor to configure for this plugin to use.
+ this.editor = editor;
+ this._initButton();
+
+ this.editor.addKeyHandler(dojo.keys.F11, true, true, dojo.hitch(this, function(e){
+ // Enable the CTRL-SHIFT-F11 hotkey for fullscreen mode.
+ this.toggle();
+ dojo.stopEvent(e);
+ setTimeout(dojo.hitch(this, function(){this.editor.focus();}), 250);
+ return true;
+ }));
+ this.connect(this.editor.domNode, "onkeydown", "_containFocus");
+ },
+
+ _containFocus: function(e){
+ // summary:
+ // When in Full Screen mode, it's good to try and retain focus in the editor
+ // so this function is intended to try and constrain the TAB key.
+ // e: Event
+ // The key event.
+ // tags:
+ // private
+ if(this.isFullscreen){
+ var ed = this.editor;
+ if(!ed.isTabIndent &&
+ ed._fullscreen_oldOnKeyDown &&
+ e.keyCode === dojo.keys.TAB){
+ // If we're in fullscreen mode, we want to take over how tab moves focus a bit.
+ // to keep it within the editor since it's hiding the rest of the page.
+ // IE hates changing focus IN the event handler, so need to put calls
+ // in a timeout. Gotta love IE.
+ // Also need to check for alternate view nodes if present and active.
+ var f = dijit.getFocus();
+ var avn = this._getAltViewNode();
+ if(f.node == ed.iframe ||
+ (avn && f.node === avn)){
+ setTimeout(dojo.hitch(this, function(){
+ ed.toolbar.focus();
+ }), 10);
+ }else{
+ if(avn && dojo.style(ed.iframe, "display") === "none"){
+ setTimeout(dojo.hitch(this, function(){
+ dijit.focus(avn);
+ }), 10);
+ }else{
+ setTimeout(dojo.hitch(this, function(){
+ ed.focus();
+ }), 10);
+ }
+ }
+ dojo.stopEvent(e);
+ }else if(ed._fullscreen_oldOnKeyDown){
+ // Only call up when it's a different function. Traps corner case event issue
+ // on IE which caused stack overflow on handler cleanup.
+ ed._fullscreen_oldOnKeyDown(e);
+ }
+ }
+ },
+
+ _resizeEditor: function(){
+ // summary:
+ // Function to handle resizing the editor as the viewport
+ // resizes (window scaled)
+ // tags:
+ // private
+ var vp = dojo.window.getBox();
+ dojo.marginBox(this.editor.domNode, {
+ w: vp.w,
+ h: vp.h
+ });
+
+ //Adjust the inernal heights too, as they can be a bit off.
+ var hHeight = this.editor.getHeaderHeight();
+ var fHeight = this.editor.getFooterHeight();
+ var extents = dojo._getPadBorderExtents(this.editor.domNode);
+ var fcpExtents = dojo._getPadBorderExtents(this.editor.iframe.parentNode);
+ var fcmExtents = dojo._getMarginExtents(this.editor.iframe.parentNode);
+
+ var cHeight = vp.h - (hHeight + extents.h + fHeight);
+ dojo.marginBox(this.editor.iframe.parentNode, {
+ h: cHeight,
+ w: vp.w
+ });
+ dojo.marginBox(this.editor.iframe, {
+ h: cHeight - (fcpExtents.h + fcmExtents.h)
+ });
+ },
+
+ _getAltViewNode: function(){
+ // summary:
+ // This function is intended as a hook point for setting an
+ // alternate view node for when in full screen mode and the
+ // editable iframe is hidden.
+ // tags:
+ // protected.
+ },
+
+ _setFullScreen: function(full){
+ // summary:
+ // Function to handle toggling between full screen and
+ // regular view.
+ // tags:
+ // private
+ var vp = dojo.window.getBox();
+
+ //Alias this for shorter code.
+ var ed = this.editor;
+ var body = dojo.body();
+ var editorParent = ed.domNode.parentNode;
+
+ this.isFullscreen = full;
+
+ if(full){
+ //Parent classes can royally screw up this plugin, so we
+ //have to set eveything to position static.
+ while(editorParent && editorParent !== dojo.body()){
+ dojo.addClass(editorParent, "dijitForceStatic");
+ editorParent = editorParent.parentNode;
+ }
+
+ // Save off the resize function. We want to kill its behavior.
+ this._editorResizeHolder = this.editor.resize;
+ ed.resize = function() {} ;
+
+ // Try to constrain focus control.
+ ed._fullscreen_oldOnKeyDown = ed.onKeyDown;
+ ed.onKeyDown = dojo.hitch(this, this._containFocus);
+
+ this._origState = {};
+ this._origiFrameState = {};
+
+ // Store the basic editor state we have to restore later.
+ // Not using dojo.style here, had problems, didn't
+ // give me stuff like 100%, gave me pixel calculated values.
+ // Need the exact original values.
+ var domNode = ed.domNode,
+ domStyle = domNode && domNode.style || {};
+ this._origState = {
+ width: domStyle.width || "",
+ height: domStyle.height || "",
+ top: dojo.style(domNode, "top") || "",
+ left: dojo.style(domNode, "left") || "",
+ position: dojo.style(domNode, "position") || "static",
+ marginBox: dojo.marginBox(ed.domNode)
+ };
+
+ // Store the iframe state we have to restore later.
+ // Not using dojo.style here, had problems, didn't
+ // give me stuff like 100%, gave me pixel calculated values.
+ // Need the exact original values.
+ var iframe = ed.iframe,
+ iframeStyle = iframe && iframe.style || {};
+
+ var bc = dojo.style(ed.iframe, "backgroundColor");
+ this._origiFrameState = {
+ backgroundColor: bc || "transparent",
+ width: iframeStyle.width || "auto",
+ height: iframeStyle.height || "auto",
+ zIndex: iframeStyle.zIndex || ""
+ };
+
+ // Okay, size everything.
+ dojo.style(ed.domNode, {
+ position: "absolute",
+ top: "0px",
+ left: "0px",
+ zIndex: this.zIndex,
+ width: vp.w + "px",
+ height: vp.h + "px"
+ });
+
+ dojo.style(ed.iframe, {
+ height: "100%",
+ width: "100%",
+ zIndex: this.zIndex,
+ backgroundColor: bc !== "transparent" &&
+ bc !== "rgba(0, 0, 0, 0)"?bc:"white"
+ });
+
+ dojo.style(ed.iframe.parentNode, {
+ height: "95%",
+ width: "100%"
+ });
+
+ // Store the overflow state we have to restore later.
+ // IE had issues, so have to check that it's defined. Ugh.
+ if(body.style && body.style.overflow){
+ this._oldOverflow = dojo.style(body, "overflow");
+ }else{
+ this._oldOverflow = "";
+ }
+
+ if(dojo.isIE && !dojo.isQuirks){
+ // IE will put scrollbars in anyway, html (parent of body)
+ // also controls them in standards mode, so we have to
+ // remove them, argh.
+ if(body.parentNode &&
+ body.parentNode.style &&
+ body.parentNode.style.overflow){
+ this._oldBodyParentOverflow = body.parentNode.style.overflow;
+ }else{
+ try{
+ this._oldBodyParentOverflow = dojo.style(body.parentNode, "overflow");
+ }catch(e){
+ this._oldBodyParentOverflow = "scroll";
+ }
+ }
+ dojo.style(body.parentNode, "overflow", "hidden");
+ }
+ dojo.style(body, "overflow", "hidden");
+
+ var resizer = function(){
+ // function to handle resize events.
+ // Will check current VP and only resize if
+ // different.
+ var vp = dojo.window.getBox();
+ if("_prevW" in this && "_prevH" in this){
+ // No actual size change, ignore.
+ if(vp.w === this._prevW && vp.h === this._prevH){
+ return;
+ }
+ }else{
+ this._prevW = vp.w;
+ this._prevH = vp.h;
+ }
+ if(this._resizer){
+ clearTimeout(this._resizer);
+ delete this._resizer;
+ }
+ // Timeout it to help avoid spamming resize on IE.
+ // Works for all browsers.
+ this._resizer = setTimeout(dojo.hitch(this, function(){
+ delete this._resizer;
+ this._resizeEditor();
+ }), 10);
+ };
+ this._resizeHandle = dojo.connect(window, "onresize", this, resizer);
+
+ // Also monitor for direct calls to resize and adapt editor.
+ this._resizeHandle2 = dojo.connect(ed, "resize", dojo.hitch(this, function(){
+ if(this._resizer){
+ clearTimeout(this._resizer);
+ delete this._resizer;
+ }
+ this._resizer = setTimeout(dojo.hitch(this, function(){
+ delete this._resizer;
+ this._resizeEditor();
+ }), 10);
+ }));
+
+ // Call it once to work around IE glitchiness. Safe for other browsers too.
+ this._resizeEditor();
+ var dn = this.editor.toolbar.domNode;
+ setTimeout(function(){dojo.window.scrollIntoView(dn);}, 250);
+ }else{
+ if(this._resizeHandle){
+ // Cleanup resizing listeners
+ dojo.disconnect(this._resizeHandle);
+ this._resizeHandle = null;
+ }
+ if(this._resizeHandle2){
+ // Cleanup resizing listeners
+ dojo.disconnect(this._resizeHandle2);
+ this._resizeHandle2 = null;
+ }
+ if(this._rst){
+ clearTimeout(this._rst);
+ this._rst = null;
+ }
+
+ //Remove all position static class assigns.
+ while(editorParent && editorParent !== dojo.body()){
+ dojo.removeClass(editorParent, "dijitForceStatic");
+ editorParent = editorParent.parentNode;
+ }
+
+ // Restore resize function
+ if(this._editorResizeHolder){
+ this.editor.resize = this._editorResizeHolder;
+ }
+
+ if(!this._origState && !this._origiFrameState){
+ // If we actually didn't toggle, then don't do anything.
+ return;
+ }
+ if(ed._fullscreen_oldOnKeyDown){
+ ed.onKeyDown = ed._fullscreen_oldOnKeyDown;
+ delete ed._fullscreen_oldOnKeyDown;
+ }
+
+ // Add a timeout to make sure we don't have a resize firing in the
+ // background at the time of minimize.
+ var self = this;
+ setTimeout(function(){
+ // Restore all the editor state.
+ var mb = self._origState.marginBox;
+ var oh = self._origState.height;
+ if(dojo.isIE && !dojo.isQuirks){
+ body.parentNode.style.overflow = self._oldBodyParentOverflow;
+ delete self._oldBodyParentOverflow;
+ }
+ dojo.style(body, "overflow", self._oldOverflow);
+ delete self._oldOverflow;
+
+ dojo.style(ed.domNode, self._origState);
+ dojo.style(ed.iframe.parentNode, {
+ height: "",
+ width: ""
+ });
+ dojo.style(ed.iframe, self._origiFrameState);
+ delete self._origState;
+ delete self._origiFrameState;
+ // In case it is contained in a layout and the layout changed size,
+ // go ahead and call resize.
+ var pWidget = dijit.getEnclosingWidget(ed.domNode.parentNode);
+ if(pWidget && pWidget.resize){
+ pWidget.resize();
+ }else{
+ if(!oh || oh.indexOf("%") < 0){
+ // Resize if the original size wasn't set
+ // or wasn't in percent. Timeout is to avoid
+ // an IE crash in unit testing.
+ setTimeout(dojo.hitch(this, function(){ed.resize({h: mb.h});}), 0);
+ }
+ }
+ dojo.window.scrollIntoView(self.editor.toolbar.domNode);
+ }, 100);
+ }
+ },
+
+ updateState: function(){
+ // summary:
+ // Over-ride for button state control for disabled to work.
+ this.button.set("disabled", this.get("disabled"));
+ },
+
+ destroy: function(){
+ // summary:
+ // Over-ride to ensure the resize handle gets cleaned up.
+ if(this._resizeHandle){
+ // Cleanup resizing listeners
+ dojo.disconnect(this._resizeHandle);
+ this._resizeHandle = null;
+ }
+ if(this._resizeHandle2){
+ // Cleanup resizing listeners
+ dojo.disconnect(this._resizeHandle2);
+ this._resizeHandle2 = null;
+ }
+ if(this._resizer){
+ clearTimeout(this._resizer);
+ this._resizer = null;
+ }
+ this.inherited(arguments);
+ }
});
+
+
+// Register this plugin.
+dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
+ if(o.plugin){ return; }
+ var name = o.args.name.toLowerCase();
+ if(name === "fullscreen"){
+ o.plugin = new dijit._editor.plugins.FullScreen({
+ zIndex: ("zIndex" in o.args)?o.args.zIndex:500
+ });
+ }
+});
+
}
diff --git a/lib/dijit/_editor/plugins/LinkDialog.js b/lib/dijit/_editor/plugins/LinkDialog.js
index 71de3ad8f..feb5cf9ec 100644
--- a/lib/dijit/_editor/plugins/LinkDialog.js
+++ b/lib/dijit/_editor/plugins/LinkDialog.js
@@ -1,236 +1,516 @@
/*
- Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
-if(!dojo._hasResource["dijit._editor.plugins.LinkDialog"]){
-dojo._hasResource["dijit._editor.plugins.LinkDialog"]=true;
+if(!dojo._hasResource["dijit._editor.plugins.LinkDialog"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._editor.plugins.LinkDialog"] = true;
dojo.provide("dijit._editor.plugins.LinkDialog");
dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
dojo.require("dijit._editor._Plugin");
dojo.require("dijit.TooltipDialog");
-dojo.require("dijit.form.Button");
+dojo.require("dijit.form.DropDownButton");
dojo.require("dijit.form.ValidationTextBox");
dojo.require("dijit.form.Select");
dojo.require("dijit._editor.range");
dojo.require("dojo.i18n");
dojo.require("dojo.string");
-dojo.requireLocalization("dijit","common",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw");
-dojo.requireLocalization("dijit._editor","LinkDialog",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw");
-dojo.declare("dijit._editor.plugins.LinkDialog",dijit._editor._Plugin,{buttonClass:dijit.form.DropDownButton,useDefaultCommand:false,urlRegExp:"((https?|ftps?|file)\\://|./|/|)(/[a-zA-Z]{1,1}:/|)(((?:(?:[\\da-zA-Z](?:[-\\da-zA-Z]{0,61}[\\da-zA-Z])?)\\.)*(?:[a-zA-Z](?:[-\\da-zA-Z]{0,80}[\\da-zA-Z])?)\\.?)|(((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])|(0[xX]0*[\\da-fA-F]?[\\da-fA-F]\\.){3}0[xX]0*[\\da-fA-F]?[\\da-fA-F]|(0+[0-3][0-7][0-7]\\.){3}0+[0-3][0-7][0-7]|(0|[1-9]\\d{0,8}|[1-3]\\d{9}|4[01]\\d{8}|42[0-8]\\d{7}|429[0-3]\\d{6}|4294[0-8]\\d{5}|42949[0-5]\\d{4}|429496[0-6]\\d{3}|4294967[01]\\d{2}|42949672[0-8]\\d|429496729[0-5])|0[xX]0*[\\da-fA-F]{1,8}|([\\da-fA-F]{1,4}\\:){7}[\\da-fA-F]{1,4}|([\\da-fA-F]{1,4}\\:){6}((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])))(\\:\\d+)?(/(?:[^?#\\s/]+/)*(?:[^?#\\s/]+(?:\\?[^?#\\s/]*)?(?:#.*)?)?)?",emailRegExp:"<?(mailto\\:)([!#-'*+\\-\\/-9=?A-Z^-~]+[.])*[!#-'*+\\-\\/-9=?A-Z^-~]+"+"@"+"((?:(?:[\\da-zA-Z](?:[-\\da-zA-Z]{0,61}[\\da-zA-Z])?)\\.)+(?:[a-zA-Z](?:[-\\da-zA-Z]{0,6}[\\da-zA-Z])?)\\.?)|localhost|^[^-][a-zA-Z0-9_-]*>?",htmlTemplate:"<a href=\"${urlInput}\" _djrealurl=\"${urlInput}\""+" target=\"${targetSelect}\""+">${textInput}</a>",tag:"a",_hostRxp:new RegExp("^((([^\\[:]+):)?([^@]+)@)?(\\[([^\\]]+)\\]|([^\\[:]*))(:([0-9]+))?$"),_userAtRxp:new RegExp("^([!#-'*+\\-\\/-9=?A-Z^-~]+[.])*[!#-'*+\\-\\/-9=?A-Z^-~]+@","i"),linkDialogTemplate:["<table><tr><td>","<label for='${id}_urlInput'>${url}</label>","</td><td>","<input dojoType='dijit.form.ValidationTextBox' required='true' "+"id='${id}_urlInput' name='urlInput' intermediateChanges='true'>","</td></tr><tr><td>","<label for='${id}_textInput'>${text}</label>","</td><td>","<input dojoType='dijit.form.ValidationTextBox' required='true' id='${id}_textInput' "+"name='textInput' intermediateChanges='true'>","</td></tr><tr><td>","<label for='${id}_targetSelect'>${target}</label>","</td><td>","<select id='${id}_targetSelect' name='targetSelect' dojoType='dijit.form.Select'>","<option selected='selected' value='_self'>${currentWindow}</option>","<option value='_blank'>${newWindow}</option>","<option value='_top'>${topWindow}</option>","<option value='_parent'>${parentWindow}</option>","</select>","</td></tr><tr><td colspan='2'>","<button dojoType='dijit.form.Button' type='submit' id='${id}_setButton'>${set}</button>","<button dojoType='dijit.form.Button' type='button' id='${id}_cancelButton'>${buttonCancel}</button>","</td></tr></table>"].join(""),_initButton:function(){
-var _1=this;
-this.tag=this.command=="insertImage"?"img":"a";
-var _2=dojo.mixin(dojo.i18n.getLocalization("dijit","common",this.lang),dojo.i18n.getLocalization("dijit._editor","LinkDialog",this.lang));
-var _3=(this.dropDown=new dijit.TooltipDialog({title:_2[this.command+"Title"],execute:dojo.hitch(this,"setValue"),onOpen:function(){
-_1._onOpenDialog();
-dijit.TooltipDialog.prototype.onOpen.apply(this,arguments);
-},onCancel:function(){
-setTimeout(dojo.hitch(_1,"_onCloseDialog"),0);
-}}));
-_2.urlRegExp=this.urlRegExp;
-_2.id=dijit.getUniqueId(this.editor.id);
-this._uniqueId=_2.id;
-this._setContent(_3.title+"<div style='border-bottom: 1px black solid;padding-bottom:2pt;margin-bottom:4pt'></div>"+dojo.string.substitute(this.linkDialogTemplate,_2));
-_3.startup();
-this._urlInput=dijit.byId(this._uniqueId+"_urlInput");
-this._textInput=dijit.byId(this._uniqueId+"_textInput");
-this._setButton=dijit.byId(this._uniqueId+"_setButton");
-this.connect(dijit.byId(this._uniqueId+"_cancelButton"),"onClick",function(){
-this.dropDown.onCancel();
+dojo.requireLocalization("dijit", "common", null, "ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,kk,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw");
+dojo.requireLocalization("dijit._editor", "LinkDialog", null, "ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,kk,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw");
+
+
+dojo.declare("dijit._editor.plugins.LinkDialog", dijit._editor._Plugin, {
+ // summary:
+ // This plugin provides the basis for an 'anchor' (link) dialog and an extension of it
+ // provides the image link dialog.
+ //
+ // description:
+ // The command provided by this plugin is:
+ // * createLink
+
+ // Override _Plugin.buttonClass. This plugin is controlled by a DropDownButton
+ // (which triggers a TooltipDialog).
+ buttonClass: dijit.form.DropDownButton,
+
+ // Override _Plugin.useDefaultCommand... processing is handled by this plugin, not by dijit.Editor.
+ useDefaultCommand: false,
+
+ // urlRegExp: [protected] String
+ // Used for validating input as correct URL. While file:// urls are not terribly
+ // useful, they are technically valid.
+ urlRegExp: "((https?|ftps?|file)\\://|\./|/|)(/[a-zA-Z]{1,1}:/|)(((?:(?:[\\da-zA-Z](?:[-\\da-zA-Z]{0,61}[\\da-zA-Z])?)\\.)*(?:[a-zA-Z](?:[-\\da-zA-Z]{0,80}[\\da-zA-Z])?)\\.?)|(((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])|(0[xX]0*[\\da-fA-F]?[\\da-fA-F]\\.){3}0[xX]0*[\\da-fA-F]?[\\da-fA-F]|(0+[0-3][0-7][0-7]\\.){3}0+[0-3][0-7][0-7]|(0|[1-9]\\d{0,8}|[1-3]\\d{9}|4[01]\\d{8}|42[0-8]\\d{7}|429[0-3]\\d{6}|4294[0-8]\\d{5}|42949[0-5]\\d{4}|429496[0-6]\\d{3}|4294967[01]\\d{2}|42949672[0-8]\\d|429496729[0-5])|0[xX]0*[\\da-fA-F]{1,8}|([\\da-fA-F]{1,4}\\:){7}[\\da-fA-F]{1,4}|([\\da-fA-F]{1,4}\\:){6}((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])))(\\:\\d+)?(/(?:[^?#\\s/]+/)*(?:[^?#\\s/]{0,}(?:\\?[^?#\\s/]*)?(?:#.*)?)?)?",
+
+ // emailRegExp: [protected] String
+ // Used for validating input as correct email address. Taken from dojox.validate
+ emailRegExp: "<?(mailto\\:)([!#-'*+\\-\\/-9=?A-Z^-~]+[.])*[!#-'*+\\-\\/-9=?A-Z^-~]+" /*username*/ + "@" +
+ "((?:(?:[\\da-zA-Z](?:[-\\da-zA-Z]{0,61}[\\da-zA-Z])?)\\.)+(?:[a-zA-Z](?:[-\\da-zA-Z]{0,6}[\\da-zA-Z])?)\\.?)|localhost|^[^-][a-zA-Z0-9_-]*>?", // host.
+
+ // htmlTemplate: [protected] String
+ // String used for templating the HTML to insert at the desired point.
+ htmlTemplate: "<a href=\"${urlInput}\" _djrealurl=\"${urlInput}\"" +
+ " target=\"${targetSelect}\"" +
+ ">${textInput}</a>",
+
+ // tag: [protected] String
+ // Tag used for the link type.
+ tag: "a",
+
+ // _hostRxp [private] RegExp
+ // Regular expression used to validate url fragments (ip address, hostname, etc)
+ _hostRxp: new RegExp("^((([^\\[:]+):)?([^@]+)@)?(\\[([^\\]]+)\\]|([^\\[:]*))(:([0-9]+))?$"),
+
+ // _userAtRxp [private] RegExp
+ // Regular expression used to validate e-mail address fragment.
+ _userAtRxp: new RegExp("^([!#-'*+\\-\\/-9=?A-Z^-~]+[.])*[!#-'*+\\-\\/-9=?A-Z^-~]+@", "i"),
+
+ // linkDialogTemplate: [protected] String
+ // Template for contents of TooltipDialog to pick URL
+ linkDialogTemplate: [
+ "<table><tr><td>",
+ "<label for='${id}_urlInput'>${url}</label>",
+ "</td><td>",
+ "<input dojoType='dijit.form.ValidationTextBox' required='true' " +
+ "id='${id}_urlInput' name='urlInput' intermediateChanges='true'/>",
+ "</td></tr><tr><td>",
+ "<label for='${id}_textInput'>${text}</label>",
+ "</td><td>",
+ "<input dojoType='dijit.form.ValidationTextBox' required='true' id='${id}_textInput' " +
+ "name='textInput' intermediateChanges='true'/>",
+ "</td></tr><tr><td>",
+ "<label for='${id}_targetSelect'>${target}</label>",
+ "</td><td>",
+ "<select id='${id}_targetSelect' name='targetSelect' dojoType='dijit.form.Select'>",
+ "<option selected='selected' value='_self'>${currentWindow}</option>",
+ "<option value='_blank'>${newWindow}</option>",
+ "<option value='_top'>${topWindow}</option>",
+ "<option value='_parent'>${parentWindow}</option>",
+ "</select>",
+ "</td></tr><tr><td colspan='2'>",
+ "<button dojoType='dijit.form.Button' type='submit' id='${id}_setButton'>${set}</button>",
+ "<button dojoType='dijit.form.Button' type='button' id='${id}_cancelButton'>${buttonCancel}</button>",
+ "</td></tr></table>"
+ ].join(""),
+
+ _initButton: function(){
+ // Override _Plugin._initButton() to initialize DropDownButton and TooltipDialog.
+ var _this = this;
+ this.tag = this.command == 'insertImage' ? 'img' : 'a';
+ var messages = dojo.mixin(dojo.i18n.getLocalization("dijit", "common", this.lang),
+ dojo.i18n.getLocalization("dijit._editor", "LinkDialog", this.lang));
+ var dropDown = (this.dropDown = new dijit.TooltipDialog({
+ title: messages[this.command + "Title"],
+ execute: dojo.hitch(this, "setValue"),
+ onOpen: function(){
+ _this._onOpenDialog();
+ dijit.TooltipDialog.prototype.onOpen.apply(this, arguments);
+ },
+ onCancel: function(){
+ setTimeout(dojo.hitch(_this, "_onCloseDialog"),0);
+ }
+ }));
+ messages.urlRegExp = this.urlRegExp;
+ messages.id = dijit.getUniqueId(this.editor.id);
+ this._uniqueId = messages.id;
+ this._setContent(dropDown.title +
+ "<div style='border-bottom: 1px black solid;padding-bottom:2pt;margin-bottom:4pt'></div>" +
+ dojo.string.substitute(this.linkDialogTemplate, messages));
+ dropDown.startup();
+ this._urlInput = dijit.byId(this._uniqueId + "_urlInput");
+ this._textInput = dijit.byId(this._uniqueId + "_textInput");
+ this._setButton = dijit.byId(this._uniqueId + "_setButton");
+ this.connect(dijit.byId(this._uniqueId + "_cancelButton"), "onClick", function(){
+ this.dropDown.onCancel();
+ });
+ if(this._urlInput){
+ this.connect(this._urlInput, "onChange", "_checkAndFixInput");
+ }
+ if(this._textInput){
+ this.connect(this._textInput, "onChange", "_checkAndFixInput");
+ }
+
+ // Build up the dual check for http/https/file:, and mailto formats.
+ this._urlRegExp = new RegExp("^" + this.urlRegExp + "$", "i");
+ this._emailRegExp = new RegExp("^" + this.emailRegExp + "$", "i");
+ this._urlInput.isValid = dojo.hitch(this, function(){
+ // Function over-ride of isValid to test if the input matches a url or a mailto style link.
+ var value = this._urlInput.get("value");
+ return this._urlRegExp.test(value) || this._emailRegExp.test(value);
+ });
+
+ this._connectTagEvents();
+ this.inherited(arguments);
+ },
+
+ _checkAndFixInput: function(){
+ // summary:
+ // A function to listen for onChange events and test the input contents
+ // for valid information, such as valid urls with http/https/ftp and if
+ // not present, try and guess if the input url is relative or not, and if
+ // not, append http:// to it. Also validates other fields as determined by
+ // the internal _isValid function.
+ var self = this;
+ var url = this._urlInput.get("value");
+ var fixupUrl = function(url){
+ var appendHttp = false;
+ var appendMailto = false;
+ if(url && url.length > 1){
+ url = dojo.trim(url);
+ if(url.indexOf("mailto:") !== 0){
+ if(url.indexOf("/") > 0){
+ if(url.indexOf("://") === -1){
+ // Check that it doesn't start with / or ./, which would
+ // imply 'target server relativeness'
+ if(url.charAt(0) !== '/' && url.indexOf("./") !== 0){
+ if(self._hostRxp.test(url)){
+ appendHttp = true;
+ }
+ }
+ }
+ }else if(self._userAtRxp.test(url)){
+ // If it looks like a foo@, append a mailto.
+ appendMailto = true;
+ }
+ }
+ }
+ if(appendHttp){
+ self._urlInput.set("value", "http://" + url);
+ }
+ if(appendMailto){
+ self._urlInput.set("value", "mailto:" + url);
+ }
+ self._setButton.set("disabled", !self._isValid());
+ };
+ if(this._delayedCheck){
+ clearTimeout(this._delayedCheck);
+ this._delayedCheck = null;
+ }
+ this._delayedCheck = setTimeout(function(){
+ fixupUrl(url);
+ }, 250);
+ },
+
+ _connectTagEvents: function(){
+ // summary:
+ // Over-ridable function that connects tag specific events.
+ this.editor.onLoadDeferred.addCallback(dojo.hitch(this, function(){
+ this.connect(this.editor.editNode, "ondblclick", this._onDblClick);
+ }));
+ },
+
+ _isValid: function(){
+ // summary:
+ // Internal function to allow validating of the inputs
+ // for a link to determine if set should be disabled or not
+ // tags:
+ // protected
+ return this._urlInput.isValid() && this._textInput.isValid();
+ },
+
+ _setContent: function(staticPanel){
+ // summary:
+ // Helper for _initButton above. Not sure why it's a separate method.
+ this.dropDown.set({
+ parserScope: "dojo", // make parser search for dojoType/data-dojo-type even if page is multi-version
+ content: staticPanel
+ });
+ },
+
+ _checkValues: function(args){
+ // summary:
+ // Function to check the values in args and 'fix' them up as needed.
+ // args: Object
+ // Content being set.
+ // tags:
+ // protected
+ if(args && args.urlInput){
+ args.urlInput = args.urlInput.replace(/"/g, "&quot;");
+ }
+ return args;
+ },
+
+ setValue: function(args){
+ // summary:
+ // Callback from the dialog when user presses "set" button.
+ // tags:
+ // private
+ //TODO: prevent closing popup if the text is empty
+ this._onCloseDialog();
+ if(dojo.isIE < 9){ //see #4151
+ var sel = dijit.range.getSelection(this.editor.window);
+ var range = sel.getRangeAt(0);
+ var a = range.endContainer;
+ if(a.nodeType === 3){
+ // Text node, may be the link contents, so check parent.
+ // This plugin doesn't really support nested HTML elements
+ // in the link, it assumes all link content is text.
+ a = a.parentNode;
+ }
+ if(a && (a.nodeName && a.nodeName.toLowerCase() !== this.tag)){
+ // Stll nothing, one last thing to try on IE, as it might be 'img'
+ // and thus considered a control.
+ a = dojo.withGlobal(this.editor.window,
+ "getSelectedElement", dijit._editor.selection, [this.tag]);
+ }
+ if(a && (a.nodeName && a.nodeName.toLowerCase() === this.tag)){
+ // Okay, we do have a match. IE, for some reason, sometimes pastes before
+ // instead of removing the targetted paste-over element, so we unlink the
+ // old one first. If we do not the <a> tag remains, but it has no content,
+ // so isn't readily visible (but is wrong for the action).
+ if(this.editor.queryCommandEnabled("unlink")){
+ // Select all the link childent, then unlink. The following insert will
+ // then replace the selected text.
+ dojo.withGlobal(this.editor.window,
+ "selectElementChildren", dijit._editor.selection, [a]);
+ this.editor.execCommand("unlink");
+ }
+ }
+ }
+ // make sure values are properly escaped, etc.
+ args = this._checkValues(args);
+ this.editor.execCommand('inserthtml',
+ dojo.string.substitute(this.htmlTemplate, args));
+ },
+
+ _onCloseDialog: function(){
+ // summary:
+ // Handler for close event on the dialog
+ this.editor.focus();
+ },
+
+ _getCurrentValues: function(a){
+ // summary:
+ // Over-ride for getting the values to set in the dropdown.
+ // a:
+ // The anchor/link to process for data for the dropdown.
+ // tags:
+ // protected
+ var url, text, target;
+ if(a && a.tagName.toLowerCase() === this.tag){
+ url = a.getAttribute('_djrealurl') || a.getAttribute('href');
+ target = a.getAttribute('target') || "_self";
+ text = a.textContent || a.innerText;
+ dojo.withGlobal(this.editor.window, "selectElement", dijit._editor.selection, [a, true]);
+ }else{
+ text = dojo.withGlobal(this.editor.window, dijit._editor.selection.getSelectedText);
+ }
+ return {urlInput: url || '', textInput: text || '', targetSelect: target || ''}; //Object;
+ },
+
+ _onOpenDialog: function(){
+ // summary:
+ // Handler for when the dialog is opened.
+ // If the caret is currently in a URL then populate the URL's info into the dialog.
+ var a;
+ if(dojo.isIE < 9){
+ // IE is difficult to select the element in, using the range unified
+ // API seems to work reasonably well.
+ var sel = dijit.range.getSelection(this.editor.window);
+ var range = sel.getRangeAt(0);
+ a = range.endContainer;
+ if(a.nodeType === 3){
+ // Text node, may be the link contents, so check parent.
+ // This plugin doesn't really support nested HTML elements
+ // in the link, it assumes all link content is text.
+ a = a.parentNode;
+ }
+ if(a && (a.nodeName && a.nodeName.toLowerCase() !== this.tag)){
+ // Stll nothing, one last thing to try on IE, as it might be 'img'
+ // and thus considered a control.
+ a = dojo.withGlobal(this.editor.window,
+ "getSelectedElement", dijit._editor.selection, [this.tag]);
+ }
+ }else{
+ a = dojo.withGlobal(this.editor.window,
+ "getAncestorElement", dijit._editor.selection, [this.tag]);
+ }
+ this.dropDown.reset();
+ this._setButton.set("disabled", true);
+ this.dropDown.set("value", this._getCurrentValues(a));
+ },
+
+ _onDblClick: function(e){
+ // summary:
+ // Function to define a behavior on double clicks on the element
+ // type this dialog edits to select it and pop up the editor
+ // dialog.
+ // e: Object
+ // The double-click event.
+ // tags:
+ // protected.
+ if(e && e.target){
+ var t = e.target;
+ var tg = t.tagName? t.tagName.toLowerCase() : "";
+ if(tg === this.tag && dojo.attr(t,"href")){
+ dojo.withGlobal(this.editor.window,
+ "selectElement",
+ dijit._editor.selection, [t]);
+ this.editor.onDisplayChanged();
+
+ setTimeout(dojo.hitch(this, function(){
+ // Focus shift outside the event handler.
+ // IE doesn't like focus changes in event handles.
+ this.button.set("disabled", false);
+ this.button.openDropDown();
+ }), 10);
+ }
+ }
+ }
});
-if(this._urlInput){
-this.connect(this._urlInput,"onChange","_checkAndFixInput");
-}
-if(this._textInput){
-this.connect(this._textInput,"onChange","_checkAndFixInput");
-}
-this._urlRegExp=new RegExp("^"+this.urlRegExp+"$","i");
-this._emailRegExp=new RegExp("^"+this.emailRegExp+"$","i");
-this._urlInput.isValid=dojo.hitch(this,function(){
-var _4=this._urlInput.get("value");
-return this._urlRegExp.test(_4)||this._emailRegExp.test(_4);
+
+dojo.declare("dijit._editor.plugins.ImgLinkDialog", [dijit._editor.plugins.LinkDialog], {
+ // summary:
+ // This plugin extends LinkDialog and adds in a plugin for handling image links.
+ // provides the image link dialog.
+ //
+ // description:
+ // The command provided by this plugin is:
+ // * insertImage
+
+ // linkDialogTemplate: [protected] String
+ // Over-ride for template since img dialog doesn't need target that anchor tags may.
+ linkDialogTemplate: [
+ "<table><tr><td>",
+ "<label for='${id}_urlInput'>${url}</label>",
+ "</td><td>",
+ "<input dojoType='dijit.form.ValidationTextBox' regExp='${urlRegExp}' " +
+ "required='true' id='${id}_urlInput' name='urlInput' intermediateChanges='true'/>",
+ "</td></tr><tr><td>",
+ "<label for='${id}_textInput'>${text}</label>",
+ "</td><td>",
+ "<input dojoType='dijit.form.ValidationTextBox' required='false' id='${id}_textInput' " +
+ "name='textInput' intermediateChanges='true'/>",
+ "</td></tr><tr><td>",
+ "</td><td>",
+ "</td></tr><tr><td colspan='2'>",
+ "<button dojoType='dijit.form.Button' type='submit' id='${id}_setButton'>${set}</button>",
+ "<button dojoType='dijit.form.Button' type='button' id='${id}_cancelButton'>${buttonCancel}</button>",
+ "</td></tr></table>"
+ ].join(""),
+
+ // htmlTemplate: [protected] String
+ // String used for templating the <img> HTML to insert at the desired point.
+ htmlTemplate: "<img src=\"${urlInput}\" _djrealurl=\"${urlInput}\" alt=\"${textInput}\" />",
+
+ // tag: [protected] String
+ // Tag used for the link type (img).
+ tag: "img",
+
+ _getCurrentValues: function(img){
+ // summary:
+ // Over-ride for getting the values to set in the dropdown.
+ // a:
+ // The anchor/link to process for data for the dropdown.
+ // tags:
+ // protected
+ var url, text;
+ if(img && img.tagName.toLowerCase() === this.tag){
+ url = img.getAttribute('_djrealurl') || img.getAttribute('src');
+ text = img.getAttribute('alt');
+ dojo.withGlobal(this.editor.window,
+ "selectElement", dijit._editor.selection, [img, true]);
+ }else{
+ text = dojo.withGlobal(this.editor.window, dijit._editor.selection.getSelectedText);
+ }
+ return {urlInput: url || '', textInput: text || ''}; //Object;
+ },
+
+ _isValid: function(){
+ // summary:
+ // Over-ride for images. You can have alt text of blank, it is valid.
+ // tags:
+ // protected
+ return this._urlInput.isValid();
+ },
+
+ _connectTagEvents: function(){
+ // summary:
+ // Over-ridable function that connects tag specific events.
+ this.inherited(arguments);
+ this.editor.onLoadDeferred.addCallback(dojo.hitch(this, function(){
+ // Use onmousedown instead of onclick. Seems that IE eats the first onclick
+ // to wrap it in a selector box, then the second one acts as onclick. See #10420
+ this.connect(this.editor.editNode, "onmousedown", this._selectTag);
+ }));
+ },
+
+ _selectTag: function(e){
+ // summary:
+ // A simple event handler that lets me select an image if it is clicked on.
+ // makes it easier to select images in a standard way across browsers. Otherwise
+ // selecting an image for edit becomes difficult.
+ // e: Event
+ // The mousedown event.
+ // tags:
+ // private
+ if(e && e.target){
+ var t = e.target;
+ var tg = t.tagName? t.tagName.toLowerCase() : "";
+ if(tg === this.tag){
+ dojo.withGlobal(this.editor.window,
+ "selectElement",
+ dijit._editor.selection, [t]);
+ }
+ }
+ },
+
+ _checkValues: function(args){
+ // summary:
+ // Function to check the values in args and 'fix' them up as needed
+ // (special characters in the url or alt text)
+ // args: Object
+ // Content being set.
+ // tags:
+ // protected
+ if(args && args.urlInput){
+ args.urlInput = args.urlInput.replace(/"/g, "&quot;");
+ }
+ if(args && args.textInput){
+ args.textInput = args.textInput.replace(/"/g, "&quot;");
+ }
+ return args;
+ },
+
+ _onDblClick: function(e){
+ // summary:
+ // Function to define a behavior on double clicks on the element
+ // type this dialog edits to select it and pop up the editor
+ // dialog.
+ // e: Object
+ // The double-click event.
+ // tags:
+ // protected.
+ if(e && e.target){
+ var t = e.target;
+ var tg = t.tagName? t.tagName.toLowerCase() : "";
+ if(tg === this.tag && dojo.attr(t,"src")){
+ dojo.withGlobal(this.editor.window,
+ "selectElement",
+ dijit._editor.selection, [t]);
+ this.editor.onDisplayChanged();
+ setTimeout(dojo.hitch(this, function(){
+ // Focus shift outside the event handler.
+ // IE doesn't like focus changes in event handles.
+ this.button.set("disabled", false);
+ this.button.openDropDown();
+ }), 10);
+ }
+ }
+ }
});
-this._connectTagEvents();
-this.inherited(arguments);
-},_checkAndFixInput:function(){
-var _5=this;
-var _6=this._urlInput.get("value");
-var _7=function(_8){
-var _9=false;
-var _a=false;
-if(_8&&_8.length>1){
-_8=dojo.trim(_8);
-if(_8.indexOf("mailto:")!==0){
-if(_8.indexOf("/")>0){
-if(_8.indexOf("://")===-1){
-if(_8.charAt(0)!=="/"&&_8.indexOf("./")!==0){
-if(_5._hostRxp.test(_8)){
-_9=true;
-}
-}
-}
-}else{
-if(_5._userAtRxp.test(_8)){
-_a=true;
-}
-}
-}
-}
-if(_9){
-_5._urlInput.set("value","http://"+_8);
-}
-if(_a){
-_5._urlInput.set("value","mailto:"+_8);
-}
-_5._setButton.set("disabled",!_5._isValid());
-};
-if(this._delayedCheck){
-clearTimeout(this._delayedCheck);
-this._delayedCheck=null;
-}
-this._delayedCheck=setTimeout(function(){
-_7(_6);
-},250);
-},_connectTagEvents:function(){
-this.editor.onLoadDeferred.addCallback(dojo.hitch(this,function(){
-this.connect(this.editor.editNode,"ondblclick",this._onDblClick);
-}));
-},_isValid:function(){
-return this._urlInput.isValid()&&this._textInput.isValid();
-},_setContent:function(_b){
-this.dropDown.set("content",_b);
-},_checkValues:function(_c){
-if(_c&&_c.urlInput){
-_c.urlInput=_c.urlInput.replace(/"/g,"&quot;");
-}
-return _c;
-},setValue:function(_d){
-this._onCloseDialog();
-if(dojo.isIE){
-var _e=dijit.range.getSelection(this.editor.window);
-var _f=_e.getRangeAt(0);
-var a=_f.endContainer;
-if(a.nodeType===3){
-a=a.parentNode;
-}
-if(a&&(a.nodeName&&a.nodeName.toLowerCase()!==this.tag)){
-a=dojo.withGlobal(this.editor.window,"getSelectedElement",dijit._editor.selection,[this.tag]);
-}
-if(a&&(a.nodeName&&a.nodeName.toLowerCase()===this.tag)){
-if(this.editor.queryCommandEnabled("unlink")){
-dojo.withGlobal(this.editor.window,"selectElementChildren",dijit._editor.selection,[a]);
-this.editor.execCommand("unlink");
-}
-}
-}
-_d=this._checkValues(_d);
-this.editor.execCommand("inserthtml",dojo.string.substitute(this.htmlTemplate,_d));
-},_onCloseDialog:function(){
-this.editor.focus();
-},_getCurrentValues:function(a){
-var url,_10,_11;
-if(a&&a.tagName.toLowerCase()===this.tag){
-url=a.getAttribute("_djrealurl")||a.getAttribute("href");
-_11=a.getAttribute("target")||"_self";
-_10=a.textContent||a.innerText;
-dojo.withGlobal(this.editor.window,"selectElement",dijit._editor.selection,[a,true]);
-}else{
-_10=dojo.withGlobal(this.editor.window,dijit._editor.selection.getSelectedText);
-}
-return {urlInput:url||"",textInput:_10||"",targetSelect:_11||""};
-},_onOpenDialog:function(){
-var a;
-if(dojo.isIE){
-var sel=dijit.range.getSelection(this.editor.window);
-var _12=sel.getRangeAt(0);
-a=_12.endContainer;
-if(a.nodeType===3){
-a=a.parentNode;
-}
-if(a&&(a.nodeName&&a.nodeName.toLowerCase()!==this.tag)){
-a=dojo.withGlobal(this.editor.window,"getSelectedElement",dijit._editor.selection,[this.tag]);
-}
-}else{
-a=dojo.withGlobal(this.editor.window,"getAncestorElement",dijit._editor.selection,[this.tag]);
-}
-this.dropDown.reset();
-this._setButton.set("disabled",true);
-this.dropDown.set("value",this._getCurrentValues(a));
-},_onDblClick:function(e){
-if(e&&e.target){
-var t=e.target;
-var tg=t.tagName?t.tagName.toLowerCase():"";
-if(tg===this.tag&&dojo.attr(t,"href")){
-dojo.withGlobal(this.editor.window,"selectElement",dijit._editor.selection,[t]);
-this.editor.onDisplayChanged();
-setTimeout(dojo.hitch(this,function(){
-this.button.set("disabled",false);
-this.button.openDropDown();
-}),10);
-}
-}
-}});
-dojo.declare("dijit._editor.plugins.ImgLinkDialog",[dijit._editor.plugins.LinkDialog],{linkDialogTemplate:["<table><tr><td>","<label for='${id}_urlInput'>${url}</label>","</td><td>","<input dojoType='dijit.form.ValidationTextBox' regExp='${urlRegExp}' "+"required='true' id='${id}_urlInput' name='urlInput' intermediateChanges='true'>","</td></tr><tr><td>","<label for='${id}_textInput'>${text}</label>","</td><td>","<input dojoType='dijit.form.ValidationTextBox' required='false' id='${id}_textInput' "+"name='textInput' intermediateChanges='true'>","</td></tr><tr><td>","</td><td>","</td></tr><tr><td colspan='2'>","<button dojoType='dijit.form.Button' type='submit' id='${id}_setButton'>${set}</button>","<button dojoType='dijit.form.Button' type='button' id='${id}_cancelButton'>${buttonCancel}</button>","</td></tr></table>"].join(""),htmlTemplate:"<img src=\"${urlInput}\" _djrealurl=\"${urlInput}\" alt=\"${textInput}\" />",tag:"img",_getCurrentValues:function(img){
-var url,_13;
-if(img&&img.tagName.toLowerCase()===this.tag){
-url=img.getAttribute("_djrealurl")||img.getAttribute("src");
-_13=img.getAttribute("alt");
-dojo.withGlobal(this.editor.window,"selectElement",dijit._editor.selection,[img,true]);
-}else{
-_13=dojo.withGlobal(this.editor.window,dijit._editor.selection.getSelectedText);
-}
-return {urlInput:url||"",textInput:_13||""};
-},_isValid:function(){
-return this._urlInput.isValid();
-},_connectTagEvents:function(){
-this.inherited(arguments);
-this.editor.onLoadDeferred.addCallback(dojo.hitch(this,function(){
-this.connect(this.editor.editNode,"onmousedown",this._selectTag);
-}));
-},_selectTag:function(e){
-if(e&&e.target){
-var t=e.target;
-var tg=t.tagName?t.tagName.toLowerCase():"";
-if(tg===this.tag){
-dojo.withGlobal(this.editor.window,"selectElement",dijit._editor.selection,[t]);
-}
-}
-},_checkValues:function(_14){
-if(_14&&_14.urlInput){
-_14.urlInput=_14.urlInput.replace(/"/g,"&quot;");
-}
-if(_14&&_14.textInput){
-_14.textInput=_14.textInput.replace(/"/g,"&quot;");
-}
-return _14;
-},_onDblClick:function(e){
-if(e&&e.target){
-var t=e.target;
-var tg=t.tagName?t.tagName.toLowerCase():"";
-if(tg===this.tag&&dojo.attr(t,"src")){
-dojo.withGlobal(this.editor.window,"selectElement",dijit._editor.selection,[t]);
-this.editor.onDisplayChanged();
-setTimeout(dojo.hitch(this,function(){
-this.button.set("disabled",false);
-this.button.openDropDown();
-}),10);
-}
-}
-}});
-dojo.subscribe(dijit._scopeName+".Editor.getPlugin",null,function(o){
-if(o.plugin){
-return;
-}
-switch(o.args.name){
-case "createLink":
-o.plugin=new dijit._editor.plugins.LinkDialog({command:o.args.name});
-break;
-case "insertImage":
-o.plugin=new dijit._editor.plugins.ImgLinkDialog({command:o.args.name});
-break;
-}
+
+// Register this plugin.
+dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
+ if(o.plugin){ return; }
+ switch(o.args.name){
+ case "createLink":
+ o.plugin = new dijit._editor.plugins.LinkDialog({command: o.args.name});
+ break;
+ case "insertImage":
+ o.plugin = new dijit._editor.plugins.ImgLinkDialog({command: o.args.name});
+ break;
+ }
});
+
}
diff --git a/lib/dijit/_editor/plugins/NewPage.js b/lib/dijit/_editor/plugins/NewPage.js
index 14c2cfa62..7e628d364 100644
--- a/lib/dijit/_editor/plugins/NewPage.js
+++ b/lib/dijit/_editor/plugins/NewPage.js
@@ -1,36 +1,81 @@
/*
- Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
-if(!dojo._hasResource["dijit._editor.plugins.NewPage"]){
-dojo._hasResource["dijit._editor.plugins.NewPage"]=true;
+if(!dojo._hasResource["dijit._editor.plugins.NewPage"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._editor.plugins.NewPage"] = true;
dojo.provide("dijit._editor.plugins.NewPage");
dojo.require("dijit._editor._Plugin");
dojo.require("dijit.form.Button");
dojo.require("dojo.i18n");
-dojo.requireLocalization("dijit._editor","commands",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw");
-dojo.declare("dijit._editor.plugins.NewPage",dijit._editor._Plugin,{content:"<br>",_initButton:function(){
-var _1=dojo.i18n.getLocalization("dijit._editor","commands"),_2=this.editor;
-this.button=new dijit.form.Button({label:_1["newPage"],dir:_2.dir,lang:_2.lang,showLabel:false,iconClass:this.iconClassPrefix+" "+this.iconClassPrefix+"NewPage",tabIndex:"-1",onClick:dojo.hitch(this,"_newPage")});
-},setEditor:function(_3){
-this.editor=_3;
-this._initButton();
-},_newPage:function(){
-this.editor.beginEditing();
-this.editor.set("value",this.content);
-this.editor.endEditing();
-this.editor.focus();
-}});
-dojo.subscribe(dijit._scopeName+".Editor.getPlugin",null,function(o){
-if(o.plugin){
-return;
-}
-var _4=o.args.name.toLowerCase();
-if(_4==="newpage"){
-o.plugin=new dijit._editor.plugins.NewPage({content:("content" in o.args)?o.args.content:"<br>"});
-}
+dojo.requireLocalization("dijit._editor", "commands", null, "ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,kk,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw");
+
+
+dojo.declare("dijit._editor.plugins.NewPage",dijit._editor._Plugin,{
+ // summary:
+ // This plugin provides a simple 'new page' calability. In other
+ // words, set content to some default user defined string.
+
+ // content: [public] String
+ // The default content to insert into the editor as the new page.
+ // The default is the <br> tag, a single blank line.
+ content: "<br>",
+
+ _initButton: function(){
+ // summary:
+ // Over-ride for creation of the Print button.
+ var strings = dojo.i18n.getLocalization("dijit._editor", "commands"),
+ editor = this.editor;
+ this.button = new dijit.form.Button({
+ label: strings["newPage"],
+ dir: editor.dir,
+ lang: editor.lang,
+ showLabel: false,
+ iconClass: this.iconClassPrefix + " " + this.iconClassPrefix + "NewPage",
+ tabIndex: "-1",
+ onClick: dojo.hitch(this, "_newPage")
+ });
+ },
+
+ setEditor: function(/*dijit.Editor*/ editor){
+ // summary:
+ // Tell the plugin which Editor it is associated with.
+ // editor: Object
+ // The editor object to attach the newPage capability to.
+ this.editor = editor;
+ this._initButton();
+ },
+
+ updateState: function(){
+ // summary:
+ // Over-ride for button state control for disabled to work.
+ this.button.set("disabled", this.get("disabled"));
+ },
+
+ _newPage: function(){
+ // summary:
+ // Function to set the content to blank.
+ // tags:
+ // private
+ this.editor.beginEditing();
+ this.editor.set("value", this.content);
+ this.editor.endEditing();
+ this.editor.focus();
+ }
});
+
+// Register this plugin.
+dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
+ if(o.plugin){ return; }
+ var name = o.args.name.toLowerCase();
+ if(name === "newpage"){
+ o.plugin = new dijit._editor.plugins.NewPage({
+ content: ("content" in o.args)?o.args.content:"<br>"
+ });
+ }
+});
+
}
diff --git a/lib/dijit/_editor/plugins/Print.js b/lib/dijit/_editor/plugins/Print.js
index b2e739aee..83cf0ddc7 100644
--- a/lib/dijit/_editor/plugins/Print.js
+++ b/lib/dijit/_editor/plugins/Print.js
@@ -1,65 +1,125 @@
/*
- Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
-if(!dojo._hasResource["dijit._editor.plugins.Print"]){
-dojo._hasResource["dijit._editor.plugins.Print"]=true;
+if(!dojo._hasResource["dijit._editor.plugins.Print"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._editor.plugins.Print"] = true;
dojo.provide("dijit._editor.plugins.Print");
dojo.require("dijit._editor._Plugin");
dojo.require("dijit.form.Button");
dojo.require("dojo.i18n");
-dojo.requireLocalization("dijit._editor","commands",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw");
-dojo.declare("dijit._editor.plugins.Print",dijit._editor._Plugin,{_initButton:function(){
-var _1=dojo.i18n.getLocalization("dijit._editor","commands"),_2=this.editor;
-this.button=new dijit.form.Button({label:_1["print"],dir:_2.dir,lang:_2.lang,showLabel:false,iconClass:this.iconClassPrefix+" "+this.iconClassPrefix+"Print",tabIndex:"-1",onClick:dojo.hitch(this,"_print")});
-},setEditor:function(_3){
-this.editor=_3;
-this._initButton();
-this.editor.onLoadDeferred.addCallback(dojo.hitch(this,function(){
-if(!this.editor.iframe.contentWindow["print"]){
-this.button.set("disabled",true);
-}
-}));
-},_print:function(){
-var _4=this.editor.iframe;
-if(_4.contentWindow["print"]){
-if(!dojo.isOpera&&!dojo.isChrome){
-dijit.focus(_4);
-_4.contentWindow.print();
-}else{
-var _5=this.editor.document;
-var _6=this.editor.get("value");
-_6="<html><head><meta http-equiv='Content-Type' "+"content='text/html; charset='UTF-8'></head><body>"+_6+"</body></html>";
-var _7=window.open("javascript: ''","","status=0,menubar=0,location=0,toolbar=0,"+"width=1,height=1,resizable=0,scrollbars=0");
-_7.document.open();
-_7.document.write(_6);
-_7.document.close();
-var _8=[];
-var _9=_5.getElementsByTagName("style");
-if(_9){
-var i;
-for(i=0;i<_9.length;i++){
-var _a=_9[i].innerHTML;
-var _b=_7.document.createElement("style");
-_b.appendChild(_7.document.createTextNode(_a));
-_7.document.getElementsByTagName("head")[0].appendChild(_b);
-}
-}
-_7.print();
-_7.close();
-}
-}
-}});
-dojo.subscribe(dijit._scopeName+".Editor.getPlugin",null,function(o){
-if(o.plugin){
-return;
-}
-var _c=o.args.name.toLowerCase();
-if(_c==="print"){
-o.plugin=new dijit._editor.plugins.Print({command:"print"});
-}
+dojo.requireLocalization("dijit._editor", "commands", null, "ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,kk,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw");
+
+
+dojo.declare("dijit._editor.plugins.Print",dijit._editor._Plugin,{
+ // summary:
+ // This plugin provides Print cabability to the editor. When
+ // clicked, the document in the editor frame will be printed.
+
+ _initButton: function(){
+ // summary:
+ // Over-ride for creation of the Print button.
+ var strings = dojo.i18n.getLocalization("dijit._editor", "commands"),
+ editor = this.editor;
+ this.button = new dijit.form.Button({
+ label: strings["print"],
+ dir: editor.dir,
+ lang: editor.lang,
+ showLabel: false,
+ iconClass: this.iconClassPrefix + " " + this.iconClassPrefix + "Print",
+ tabIndex: "-1",
+ onClick: dojo.hitch(this, "_print")
+ });
+ },
+
+ setEditor: function(/*dijit.Editor*/ editor){
+ // summary:
+ // Tell the plugin which Editor it is associated with.
+ // editor: Object
+ // The editor object to attach the print capability to.
+ this.editor = editor;
+ this._initButton();
+
+ // Set up a check that we have a print function
+ // and disable button if we do not.
+ this.editor.onLoadDeferred.addCallback(
+ dojo.hitch(this, function(){
+ if(!this.editor.iframe.contentWindow["print"]){
+ this.button.set("disabled", true);
+ }
+ })
+ );
+ },
+
+ updateState: function(){
+ // summary:
+ // Over-ride for button state control for disabled to work.
+ var disabled = this.get("disabled");
+ if(!this.editor.iframe.contentWindow["print"]){
+ disabled = true;
+ }
+ this.button.set("disabled", disabled);
+ },
+
+ _print: function(){
+ // summary:
+ // Function to trigger printing of the editor document
+ // tags:
+ // private
+ var edFrame = this.editor.iframe;
+ if(edFrame.contentWindow["print"]){
+ // IE requires the frame to be focused for
+ // print to work, but since this is okay for all
+ // no special casing.
+ if(!dojo.isOpera && !dojo.isChrome){
+ dijit.focus(edFrame);
+ edFrame.contentWindow.print();
+ }else{
+ // Neither Opera nor Chrome 3 et you print single frames.
+ // So, open a new 'window', print it, and close it.
+ // Also, can't use size 0x0, have to use 1x1
+ var edDoc = this.editor.document;
+ var content = this.editor.get("value");
+ content = "<html><head><meta http-equiv='Content-Type' " +
+ "content='text/html; charset='UTF-8'></head><body>" +
+ content + "</body></html>";
+ var win = window.open("javascript: ''",
+ "",
+ "status=0,menubar=0,location=0,toolbar=0," +
+ "width=1,height=1,resizable=0,scrollbars=0");
+ win.document.open();
+ win.document.write(content);
+ win.document.close();
+ var styles = [];
+ var styleNodes = edDoc.getElementsByTagName("style");
+ if(styleNodes){
+ // Clone over any editor view styles, since we can't print the iframe
+ // directly.
+ var i;
+ for(i = 0; i < styleNodes.length; i++){
+ var style = styleNodes[i].innerHTML;
+ var sNode = win.document.createElement("style");
+ sNode.appendChild(win.document.createTextNode(style));
+ win.document.getElementsByTagName("head")[0].appendChild(sNode);
+ }
+ }
+ win.print();
+ win.close();
+ }
+ }
+ }
+});
+
+// Register this plugin.
+dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
+ if(o.plugin){ return; }
+ var name = o.args.name.toLowerCase();
+ if(name === "print"){
+ o.plugin = new dijit._editor.plugins.Print({command: "print"});
+ }
});
+
}
diff --git a/lib/dijit/_editor/plugins/TabIndent.js b/lib/dijit/_editor/plugins/TabIndent.js
index 74cda400f..eb27f69dd 100644
--- a/lib/dijit/_editor/plugins/TabIndent.js
+++ b/lib/dijit/_editor/plugins/TabIndent.js
@@ -1,33 +1,69 @@
/*
- Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
-if(!dojo._hasResource["dijit._editor.plugins.TabIndent"]){
-dojo._hasResource["dijit._editor.plugins.TabIndent"]=true;
+if(!dojo._hasResource["dijit._editor.plugins.TabIndent"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._editor.plugins.TabIndent"] = true;
dojo.provide("dijit._editor.plugins.TabIndent");
-dojo.experimental("dijit._editor.plugins.TabIndent");
dojo.require("dijit._editor._Plugin");
dojo.require("dijit.form.ToggleButton");
-dojo.declare("dijit._editor.plugins.TabIndent",dijit._editor._Plugin,{useDefaultCommand:false,buttonClass:dijit.form.ToggleButton,command:"tabIndent",_initButton:function(){
-this.inherited(arguments);
-var e=this.editor;
-this.connect(this.button,"onChange",function(_1){
-e.set("isTabIndent",_1);
-});
-this.updateState();
-},updateState:function(){
-this.button.set("checked",this.editor.isTabIndent,false);
-}});
-dojo.subscribe(dijit._scopeName+".Editor.getPlugin",null,function(o){
-if(o.plugin){
-return;
-}
-switch(o.args.name){
-case "tabIndent":
-o.plugin=new dijit._editor.plugins.TabIndent({command:o.args.name});
-}
+
+
+dojo.experimental("dijit._editor.plugins.TabIndent");
+
+
+dojo.declare("dijit._editor.plugins.TabIndent",
+ dijit._editor._Plugin,
+ {
+ // summary:
+ // This plugin is used to allow the use of the tab and shift-tab keys
+ // to indent/outdent list items. This overrides the default behavior
+ // of moving focus from/to the toolbar
+
+ // Override _Plugin.useDefaultCommand... processing is handled by this plugin, not by dijit.Editor.
+ useDefaultCommand: false,
+
+ // Override _Plugin.buttonClass to use a ToggleButton for this plugin rather than a vanilla Button
+ buttonClass: dijit.form.ToggleButton,
+
+ command: "tabIndent",
+
+ _initButton: function(){
+ // Override _Plugin._initButton() to setup listener on button click
+ this.inherited(arguments);
+
+ var e = this.editor;
+ this.connect(this.button, "onChange", function(val){
+ e.set("isTabIndent", val);
+ });
+
+ // Set initial checked state of button based on Editor.isTabIndent
+ this.updateState();
+ },
+
+ updateState: function(){
+ // Overrides _Plugin.updateState().
+ // Ctrl-m in the editor will switch tabIndent mode on/off, so we need to react to that.
+ var disabled = this.get("disabled");
+ this.button.set("disabled", disabled);
+ if(disabled){
+ return;
+ }
+ this.button.set('checked', this.editor.isTabIndent, false);
+ }
+ }
+);
+
+// Register this plugin.
+dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
+ if(o.plugin){ return; }
+ switch(o.args.name){
+ case "tabIndent":
+ o.plugin = new dijit._editor.plugins.TabIndent({command: o.args.name});
+ }
});
+
}
diff --git a/lib/dijit/_editor/plugins/TextColor.js b/lib/dijit/_editor/plugins/TextColor.js
index da7bbc9a6..2f24d0424 100644
--- a/lib/dijit/_editor/plugins/TextColor.js
+++ b/lib/dijit/_editor/plugins/TextColor.js
@@ -1,62 +1,105 @@
/*
- Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
-if(!dojo._hasResource["dijit._editor.plugins.TextColor"]){
-dojo._hasResource["dijit._editor.plugins.TextColor"]=true;
+if(!dojo._hasResource["dijit._editor.plugins.TextColor"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._editor.plugins.TextColor"] = true;
dojo.provide("dijit._editor.plugins.TextColor");
dojo.require("dijit._editor._Plugin");
dojo.require("dijit.ColorPalette");
-dojo.declare("dijit._editor.plugins.TextColor",dijit._editor._Plugin,{buttonClass:dijit.form.DropDownButton,useDefaultCommand:false,constructor:function(){
-this.dropDown=new dijit.ColorPalette();
-this.connect(this.dropDown,"onChange",function(_1){
-this.editor.execCommand(this.command,_1);
+
+
+dojo.declare("dijit._editor.plugins.TextColor", dijit._editor._Plugin, {
+ // summary:
+ // This plugin provides dropdown color pickers for setting text color and background color
+ //
+ // description:
+ // The commands provided by this plugin are:
+ // * foreColor - sets the text color
+ // * hiliteColor - sets the background color
+
+ // Override _Plugin.buttonClass to use DropDownButton (with ColorPalette) to control this plugin
+ buttonClass: dijit.form.DropDownButton,
+
+ // useDefaultCommand: Boolean
+ // False as we do not use the default editor command/click behavior.
+ useDefaultCommand: false,
+
+ constructor: function(){
+ this.dropDown = new dijit.ColorPalette();
+ this.connect(this.dropDown, "onChange", function(color){
+ this.editor.execCommand(this.command, color);
+
+ });
+ },
+
+ updateState: function(){
+ // summary:
+ // Overrides _Plugin.updateState(). This updates the ColorPalette
+ // to show the color of the currently selected text.
+ // tags:
+ // protected
+
+ var _e = this.editor;
+ var _c = this.command;
+ if(!_e || !_e.isLoaded || !_c.length){
+ return;
+ }
+
+ if(this.button){
+ var disabled = this.get("disabled");
+ this.button.set("disabled", disabled);
+ if(disabled){ return; }
+
+ var value;
+ try{
+ value = _e.queryCommandValue(_c)|| "";
+ }catch(e){
+ //Firefox may throw error above if the editor is just loaded, ignore it
+ value = "";
+ }
+ }
+
+ if(value == ""){
+ value = "#000000";
+ }
+ if(value == "transparent"){
+ value = "#ffffff";
+ }
+
+ if(typeof value == "string"){
+ //if RGB value, convert to hex value
+ if(value.indexOf("rgb")> -1){
+ value = dojo.colorFromRgb(value).toHex();
+ }
+ }else{ //it's an integer(IE returns an MS access #)
+ value =((value & 0x0000ff)<< 16)|(value & 0x00ff00)|((value & 0xff0000)>>> 16);
+ value = value.toString(16);
+ value = "#000000".slice(0, 7 - value.length)+ value;
+
+ }
+
+ if(value !== this.dropDown.get('value')){
+ this.dropDown.set('value', value, false);
+ }
+ }
});
-},updateState:function(){
-var _2=this.editor;
-var _3=this.command;
-if(!_2||!_2.isLoaded||!_3.length){
-return;
-}
-if(this.button){
-var _4;
-try{
-_4=_2.queryCommandValue(_3)||"";
-}
-catch(e){
-_4="";
-}
-}
-if(_4==""){
-_4="#000000";
-}
-if(_4=="transparent"){
-_4="#ffffff";
-}
-if(typeof _4=="string"){
-if(_4.indexOf("rgb")>-1){
-_4=dojo.colorFromRgb(_4).toHex();
-}
-}else{
-_4=((_4&255)<<16)|(_4&65280)|((_4&16711680)>>>16);
-_4=_4.toString(16);
-_4="#000000".slice(0,7-_4.length)+_4;
-}
-if(_4!==this.dropDown.get("value")){
-this.dropDown.set("value",_4,false);
-}
-}});
-dojo.subscribe(dijit._scopeName+".Editor.getPlugin",null,function(o){
-if(o.plugin){
-return;
-}
-switch(o.args.name){
-case "foreColor":
-case "hiliteColor":
-o.plugin=new dijit._editor.plugins.TextColor({command:o.args.name});
-}
+
+// Register this plugin.
+dojo.subscribe(dijit._scopeName + ".Editor.getPlugin", null, function(o){
+ if(o.plugin){
+ return;
+ }
+ switch(o.args.name){
+ case "foreColor":
+ case "hiliteColor":
+ o.plugin = new dijit._editor.plugins.TextColor({
+ command: o.args.name
+ });
+ }
});
+
}
diff --git a/lib/dijit/_editor/plugins/ToggleDir.js b/lib/dijit/_editor/plugins/ToggleDir.js
index f5ecb7909..92e3d91c8 100644
--- a/lib/dijit/_editor/plugins/ToggleDir.js
+++ b/lib/dijit/_editor/plugins/ToggleDir.js
@@ -1,42 +1,80 @@
/*
- Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
-if(!dojo._hasResource["dijit._editor.plugins.ToggleDir"]){
-dojo._hasResource["dijit._editor.plugins.ToggleDir"]=true;
+if(!dojo._hasResource["dijit._editor.plugins.ToggleDir"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._editor.plugins.ToggleDir"] = true;
dojo.provide("dijit._editor.plugins.ToggleDir");
+dojo.require("dijit._editor._Plugin");
+dojo.require("dijit.form.ToggleButton");
+
+
dojo.experimental("dijit._editor.plugins.ToggleDir");
+
dojo.require("dijit._editor._Plugin");
dojo.require("dijit.form.ToggleButton");
-dojo.declare("dijit._editor.plugins.ToggleDir",dijit._editor._Plugin,{useDefaultCommand:false,command:"toggleDir",buttonClass:dijit.form.ToggleButton,_initButton:function(){
-this.inherited(arguments);
-this.editor.onLoadDeferred.addCallback(dojo.hitch(this,function(){
-var _1=this.editor.editorObject.contentWindow.document.documentElement;
-_1=_1.getElementsByTagName("body")[0];
-var _2=dojo.getComputedStyle(_1).direction=="ltr";
-this.button.set("checked",!_2);
-this.connect(this.button,"onChange","_setRtl");
-}));
-},updateState:function(){
-},_setRtl:function(_3){
-var _4="ltr";
-if(_3){
-_4="rtl";
-}
-var _5=this.editor.editorObject.contentWindow.document.documentElement;
-_5=_5.getElementsByTagName("body")[0];
-_5.dir=_4;
-}});
-dojo.subscribe(dijit._scopeName+".Editor.getPlugin",null,function(o){
-if(o.plugin){
-return;
-}
-switch(o.args.name){
-case "toggleDir":
-o.plugin=new dijit._editor.plugins.ToggleDir({command:o.args.name});
-}
+
+dojo.declare("dijit._editor.plugins.ToggleDir",
+ dijit._editor._Plugin,
+ {
+ // summary:
+ // This plugin is used to toggle direction of the edited document,
+ // independent of what direction the whole page is.
+
+ // Override _Plugin.useDefaultCommand: processing is done in this plugin
+ // rather than by sending commands to the Editor
+ useDefaultCommand: false,
+
+ command: "toggleDir",
+
+ // Override _Plugin.buttonClass to use a ToggleButton for this plugin rather than a vanilla Button
+ buttonClass: dijit.form.ToggleButton,
+
+ _initButton: function(){
+ // Override _Plugin._initButton() to setup handler for button click events.
+ this.inherited(arguments);
+ this.editor.onLoadDeferred.addCallback(dojo.hitch(this, function(){
+ var editDoc = this.editor.editorObject.contentWindow.document.documentElement;
+ //IE direction has to toggle on the body, not document itself.
+ //If you toggle just the document, things get very strange in the
+ //view. But, the nice thing is this works for all supported browsers.
+ editDoc = editDoc.getElementsByTagName("body")[0];
+ var isLtr = dojo.getComputedStyle(editDoc).direction == "ltr";
+ this.button.set("checked", !isLtr);
+ this.connect(this.button, "onChange", "_setRtl");
+ }));
+ },
+
+ updateState: function(){
+ // summary:
+ // Over-ride for button state control for disabled to work.
+ this.button.set("disabled", this.get("disabled"));
+ },
+
+ _setRtl: function(rtl){
+ // summary:
+ // Handler for button click events, to switch the text direction of the editor
+ var dir = "ltr";
+ if(rtl){
+ dir = "rtl";
+ }
+ var editDoc = this.editor.editorObject.contentWindow.document.documentElement;
+ editDoc = editDoc.getElementsByTagName("body")[0];
+ editDoc.dir/*html node*/ = dir;
+ }
+ }
+);
+
+// Register this plugin.
+dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
+ if(o.plugin){ return; }
+ switch(o.args.name){
+ case "toggleDir":
+ o.plugin = new dijit._editor.plugins.ToggleDir({command: o.args.name});
+ }
});
+
}
diff --git a/lib/dijit/_editor/plugins/ViewSource.js b/lib/dijit/_editor/plugins/ViewSource.js
index 41ea2970f..e655ad21d 100644
--- a/lib/dijit/_editor/plugins/ViewSource.js
+++ b/lib/dijit/_editor/plugins/ViewSource.js
@@ -1,317 +1,555 @@
/*
- Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
-if(!dojo._hasResource["dijit._editor.plugins.ViewSource"]){
-dojo._hasResource["dijit._editor.plugins.ViewSource"]=true;
+if(!dojo._hasResource["dijit._editor.plugins.ViewSource"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._editor.plugins.ViewSource"] = true;
dojo.provide("dijit._editor.plugins.ViewSource");
dojo.require("dojo.window");
dojo.require("dojo.i18n");
dojo.require("dijit._editor._Plugin");
dojo.require("dijit.form.Button");
-dojo.requireLocalization("dijit._editor","commands",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw");
-dojo.declare("dijit._editor.plugins.ViewSource",dijit._editor._Plugin,{stripScripts:true,stripComments:true,stripIFrames:true,readOnly:false,_fsPlugin:null,toggle:function(){
-if(dojo.isWebKit){
-this._vsFocused=true;
-}
-this.button.set("checked",!this.button.get("checked"));
-},_initButton:function(){
-var _1=dojo.i18n.getLocalization("dijit._editor","commands"),_2=this.editor;
-this.button=new dijit.form.ToggleButton({label:_1["viewSource"],dir:_2.dir,lang:_2.lang,showLabel:false,iconClass:this.iconClassPrefix+" "+this.iconClassPrefix+"ViewSource",tabIndex:"-1",onChange:dojo.hitch(this,"_showSource")});
-if(dojo.isIE==7){
-this._ieFixNode=dojo.create("div",{style:{opacity:"0",zIndex:"-1000",position:"absolute",top:"-1000px"}},dojo.body());
-}
-this.button.set("readOnly",false);
-},setEditor:function(_3){
-this.editor=_3;
-this._initButton();
-this.editor.addKeyHandler(dojo.keys.F12,true,true,dojo.hitch(this,function(e){
-this.button.focus();
-this.toggle();
-dojo.stopEvent(e);
-setTimeout(dojo.hitch(this,function(){
-this.editor.focus();
-}),100);
-}));
-},_showSource:function(_4){
-var ed=this.editor;
-var _5=ed._plugins;
-var _6;
-this._sourceShown=_4;
-var _7=this;
-try{
-if(!this.sourceArea){
-this._createSourceView();
-}
-if(_4){
-ed._sourceQueryCommandEnabled=ed.queryCommandEnabled;
-ed.queryCommandEnabled=function(_8){
-var _9=_8.toLowerCase();
-if(_9==="viewsource"){
-return true;
-}else{
-return false;
-}
-};
-this.editor.onDisplayChanged();
-_6=ed.get("value");
-_6=this._filter(_6);
-ed.set("value",_6);
-this._pluginList=[];
-this._disabledPlugins=dojo.filter(_5,function(p){
-if(p&&p.button&&!p.button.get("disabled")&&!(p instanceof dijit._editor.plugins.ViewSource)){
-p._vs_updateState=p.updateState;
-p.updateState=function(){
-return false;
-};
-p.button.set("disabled",true);
-if(p.command){
-switch(p.command){
-case "bold":
-case "italic":
-case "underline":
-case "strikethrough":
-case "superscript":
-case "subscript":
-p.button.set("checked",false);
-break;
-default:
-break;
-}
-}
-return true;
-}
-});
-if(this._fsPlugin){
-this._fsPlugin._getAltViewNode=function(){
-return _7.sourceArea;
-};
-}
-this.sourceArea.value=_6;
-var is=dojo.marginBox(ed.iframe.parentNode);
-dojo.marginBox(this.sourceArea,{w:is.w,h:is.h});
-dojo.style(ed.iframe,"display","none");
-dojo.style(this.sourceArea,{display:"block"});
-var _a=function(){
-var vp=dojo.window.getBox();
-if("_prevW" in this&&"_prevH" in this){
-if(vp.w===this._prevW&&vp.h===this._prevH){
-return;
-}else{
-this._prevW=vp.w;
-this._prevH=vp.h;
-}
-}else{
-this._prevW=vp.w;
-this._prevH=vp.h;
-}
-if(this._resizer){
-clearTimeout(this._resizer);
-delete this._resizer;
-}
-this._resizer=setTimeout(dojo.hitch(this,function(){
-delete this._resizer;
-this._resize();
-}),10);
-};
-this._resizeHandle=dojo.connect(window,"onresize",this,_a);
-setTimeout(dojo.hitch(this,this._resize),100);
-this.editor.onNormalizedDisplayChanged();
-}else{
-if(!ed._sourceQueryCommandEnabled){
-return;
-}
-dojo.disconnect(this._resizeHandle);
-delete this._resizeHandle;
-ed.queryCommandEnabled=ed._sourceQueryCommandEnabled;
-if(!this._readOnly){
-_6=this.sourceArea.value;
-_6=this._filter(_6);
-ed.beginEditing();
-ed.set("value",_6);
-ed.endEditing();
-}
-dojo.forEach(this._disabledPlugins,function(p){
-p.button.set("disabled",false);
-if(p._vs_updateState){
-p.updateState=p._vs_updateState;
-}
+dojo.requireLocalization("dijit._editor", "commands", null, "ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,kk,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw");
+
+
+dojo.declare("dijit._editor.plugins.ViewSource",dijit._editor._Plugin,{
+ // summary:
+ // This plugin provides a simple view source capability. When view
+ // source mode is enabled, it disables all other buttons/plugins on the RTE.
+ // It also binds to the hotkey: CTRL-SHIFT-F11 for toggling ViewSource mode.
+
+ // stripScripts: [public] Boolean
+ // Boolean flag used to indicate if script tags should be stripped from the document.
+ // Defaults to true.
+ stripScripts: true,
+
+ // stripComments: [public] Boolean
+ // Boolean flag used to indicate if comment tags should be stripped from the document.
+ // Defaults to true.
+ stripComments: true,
+
+ // stripComments: [public] Boolean
+ // Boolean flag used to indicate if iframe tags should be stripped from the document.
+ // Defaults to true.
+ stripIFrames: true,
+
+ // readOnly: [const] Boolean
+ // Boolean flag used to indicate if the source view should be readonly or not.
+ // Cannot be changed after initialization of the plugin.
+ // Defaults to false.
+ readOnly: false,
+
+ // _fsPlugin: [private] Object
+ // Reference to a registered fullscreen plugin so that viewSource knows
+ // how to scale.
+ _fsPlugin: null,
+
+ toggle: function(){
+ // summary:
+ // Function to allow programmatic toggling of the view.
+
+ // For Webkit, we have to focus a very particular way.
+ // when swapping views, otherwise focus doesn't shift right
+ // but can't focus this way all the time, only for VS changes.
+ // If we did it all the time, buttons like bold, italic, etc
+ // break.
+ if(dojo.isWebKit){this._vsFocused = true;}
+ this.button.set("checked", !this.button.get("checked"));
+
+ },
+
+ _initButton: function(){
+ // summary:
+ // Over-ride for creation of the resize button.
+ var strings = dojo.i18n.getLocalization("dijit._editor", "commands"),
+ editor = this.editor;
+ this.button = new dijit.form.ToggleButton({
+ label: strings["viewSource"],
+ dir: editor.dir,
+ lang: editor.lang,
+ showLabel: false,
+ iconClass: this.iconClassPrefix + " " + this.iconClassPrefix + "ViewSource",
+ tabIndex: "-1",
+ onChange: dojo.hitch(this, "_showSource")
+ });
+
+ // IE 7 has a horrible bug with zoom, so we have to create this node
+ // to cross-check later. Sigh.
+ if(dojo.isIE == 7){
+ this._ieFixNode = dojo.create("div", {
+ style: {
+ opacity: "0",
+ zIndex: "-1000",
+ position: "absolute",
+ top: "-1000px"
+ }
+ }, dojo.body());
+ }
+ // Make sure readonly mode doesn't make the wrong cursor appear over the button.
+ this.button.set("readOnly", false);
+ },
+
+
+ setEditor: function(/*dijit.Editor*/ editor){
+ // summary:
+ // Tell the plugin which Editor it is associated with.
+ // editor: Object
+ // The editor object to attach the print capability to.
+ this.editor = editor;
+ this._initButton();
+
+ this.editor.addKeyHandler(dojo.keys.F12, true, true, dojo.hitch(this, function(e){
+ // Move the focus before switching
+ // It'll focus back. Hiding a focused
+ // node causes issues.
+ this.button.focus();
+ this.toggle();
+ dojo.stopEvent(e);
+
+ // Call the focus shift outside of the handler.
+ setTimeout(dojo.hitch(this, function(){
+ // We over-ride focus, so we just need to call.
+ this.editor.focus();
+ }), 100);
+ }));
+ },
+
+ _showSource: function(source){
+ // summary:
+ // Function to toggle between the source and RTE views.
+ // source: boolean
+ // Boolean value indicating if it should be in source mode or not.
+ // tags:
+ // private
+ var ed = this.editor;
+ var edPlugins = ed._plugins;
+ var html;
+ this._sourceShown = source;
+ var self = this;
+ try{
+ if(!this.sourceArea){
+ this._createSourceView();
+ }
+ if(source){
+ // Update the QueryCommandEnabled function to disable everything but
+ // the source view mode. Have to over-ride a function, then kick all
+ // plugins to check their state.
+ ed._sourceQueryCommandEnabled = ed.queryCommandEnabled;
+ ed.queryCommandEnabled = function(cmd){
+ var lcmd = cmd.toLowerCase();
+ if(lcmd === "viewsource"){
+ return true;
+ }else{
+ return false;
+ }
+ };
+ this.editor.onDisplayChanged();
+ html = ed.get("value");
+ html = this._filter(html);
+ ed.set("value", html);
+ this._pluginList = [];
+ dojo.forEach(edPlugins, function(p){
+ // Turn off any plugins not controlled by queryCommandenabled.
+ if(!(p instanceof dijit._editor.plugins.ViewSource)){
+ p.set("disabled", true)
+ }
+ });
+
+ // We actually do need to trap this plugin and adjust how we
+ // display the textarea.
+ if(this._fsPlugin){
+ this._fsPlugin._getAltViewNode = function(){
+ return self.sourceArea;
+ };
+ }
+
+ this.sourceArea.value = html;
+ var is = dojo._getMarginSize(ed.iframe.parentNode);
+
+ dojo.marginBox(this.sourceArea, {
+ w: is.w,
+ h: is.h
+ });
+
+ dojo.style(ed.iframe, "display", "none");
+ dojo.style(this.sourceArea, {
+ display: "block"
+ });
+
+ var resizer = function(){
+ // function to handle resize events.
+ // Will check current VP and only resize if
+ // different.
+ var vp = dojo.window.getBox();
+
+ if("_prevW" in this && "_prevH" in this){
+ // No actual size change, ignore.
+ if(vp.w === this._prevW && vp.h === this._prevH){
+ return;
+ }else{
+ this._prevW = vp.w;
+ this._prevH = vp.h;
+ }
+ }else{
+ this._prevW = vp.w;
+ this._prevH = vp.h;
+ }
+ if(this._resizer){
+ clearTimeout(this._resizer);
+ delete this._resizer;
+ }
+ // Timeout it to help avoid spamming resize on IE.
+ // Works for all browsers.
+ this._resizer = setTimeout(dojo.hitch(this, function(){
+ delete this._resizer;
+ this._resize();
+ }), 10);
+ };
+ this._resizeHandle = dojo.connect(window, "onresize", this, resizer);
+
+ //Call this on a delay once to deal with IE glitchiness on initial size.
+ setTimeout(dojo.hitch(this, this._resize), 100);
+
+ //Trigger a check for command enablement/disablement.
+ this.editor.onNormalizedDisplayChanged();
+
+ this.editor.__oldGetValue = this.editor.getValue;
+ this.editor.getValue = dojo.hitch(this, function() {
+ var txt = this.sourceArea.value;
+ txt = this._filter(txt);
+ return txt;
+ });
+ }else{
+ // First check that we were in source view before doing anything.
+ // corner case for being called with a value of false and we hadn't
+ // actually been in source display mode.
+ if(!ed._sourceQueryCommandEnabled){
+ return;
+ }
+ dojo.disconnect(this._resizeHandle);
+ delete this._resizeHandle;
+
+ if(this.editor.__oldGetValue){
+ this.editor.getValue = this.editor.__oldGetValue;
+ delete this.editor.__oldGetValue;
+ }
+
+ // Restore all the plugin buttons state.
+ ed.queryCommandEnabled = ed._sourceQueryCommandEnabled;
+ if(!this._readOnly){
+ html = this.sourceArea.value;
+ html = this._filter(html);
+ ed.beginEditing();
+ ed.set("value", html);
+ ed.endEditing();
+ }
+
+ dojo.forEach(edPlugins, function(p){
+ // Turn back on any plugins we turned off.
+ p.set("disabled", false);
+ });
+
+ dojo.style(this.sourceArea, "display", "none");
+ dojo.style(ed.iframe, "display", "block");
+ delete ed._sourceQueryCommandEnabled;
+
+ //Trigger a check for command enablement/disablement.
+ this.editor.onDisplayChanged();
+ }
+ // Call a delayed resize to wait for some things to display in header/footer.
+ setTimeout(dojo.hitch(this, function(){
+ // Make resize calls.
+ var parent = ed.domNode.parentNode;
+ if(parent){
+ var container = dijit.getEnclosingWidget(parent);
+ if(container && container.resize){
+ container.resize();
+ }
+ }
+ ed.resize();
+ }), 300);
+ }catch(e){
+ console.log(e);
+ }
+ },
+
+ updateState: function(){
+ // summary:
+ // Over-ride for button state control for disabled to work.
+ this.button.set("disabled", this.get("disabled"));
+ },
+
+ _resize: function(){
+ // summary:
+ // Internal function to resize the source view
+ // tags:
+ // private
+ var ed = this.editor;
+ var tbH = ed.getHeaderHeight();
+ var fH = ed.getFooterHeight();
+ var eb = dojo.position(ed.domNode);
+
+ // Styles are now applied to the internal source container, so we have
+ // to subtract them off.
+ var containerPadding = dojo._getPadBorderExtents(ed.iframe.parentNode);
+ var containerMargin = dojo._getMarginExtents(ed.iframe.parentNode);
+
+ var extents = dojo._getPadBorderExtents(ed.domNode);
+ var mExtents = dojo._getMarginExtents(ed.domNode);
+ var edb = {
+ w: eb.w - (extents.w + mExtents.w),
+ h: eb.h - (tbH + extents.h + mExtents.h + fH)
+ };
+
+ // Fullscreen gets odd, so we need to check for the FS plugin and
+ // adapt.
+ if(this._fsPlugin && this._fsPlugin.isFullscreen){
+ //Okay, probably in FS, adjust.
+ var vp = dojo.window.getBox();
+ edb.w = (vp.w - extents.w);
+ edb.h = (vp.h - (tbH + extents.h + fH));
+ }
+
+ if(dojo.isIE){
+ // IE is always off by 2px, so we have to adjust here
+ // Note that IE ZOOM is broken here. I can't get
+ //it to scale right.
+ edb.h -= 2;
+ }
+
+ // IE has a horrible zoom bug. So, we have to try and account for
+ // it and fix up the scaling.
+ if(this._ieFixNode){
+ var _ie7zoom = -this._ieFixNode.offsetTop / 1000;
+ edb.w = Math.floor((edb.w + 0.9) / _ie7zoom);
+ edb.h = Math.floor((edb.h + 0.9) / _ie7zoom);
+ }
+
+ dojo.marginBox(this.sourceArea, {
+ w: edb.w - (containerPadding.w + containerMargin.w),
+ h: edb.h - (containerPadding.h + containerMargin.h)
+ });
+
+ // Scale the parent container too in this case.
+ dojo.marginBox(ed.iframe.parentNode, {
+ h: edb.h
+ });
+ },
+
+ _createSourceView: function(){
+ // summary:
+ // Internal function for creating the source view area.
+ // tags:
+ // private
+ var ed = this.editor;
+ var edPlugins = ed._plugins;
+ this.sourceArea = dojo.create("textarea");
+ if(this.readOnly){
+ dojo.attr(this.sourceArea, "readOnly", true);
+ this._readOnly = true;
+ }
+ dojo.style(this.sourceArea, {
+ padding: "0px",
+ margin: "0px",
+ borderWidth: "0px",
+ borderStyle: "none"
+ });
+ dojo.place(this.sourceArea, ed.iframe, "before");
+
+ if(dojo.isIE && ed.iframe.parentNode.lastChild !== ed.iframe){
+ // There's some weirdo div in IE used for focus control
+ // But is messed up scaling the textarea if we don't config
+ // it some so it doesn't have a varying height.
+ dojo.style(ed.iframe.parentNode.lastChild,{
+ width: "0px",
+ height: "0px",
+ padding: "0px",
+ margin: "0px",
+ borderWidth: "0px",
+ borderStyle: "none"
+ });
+ }
+
+ // We also need to take over editor focus a bit here, so that focus calls to
+ // focus the editor will focus to the right node when VS is active.
+ ed._viewsource_oldFocus = ed.focus;
+ var self = this;
+ ed.focus = function(){
+ if(self._sourceShown){
+ self.setSourceAreaCaret();
+ }else{
+ try{
+ if(this._vsFocused){
+ delete this._vsFocused;
+ // Must focus edit node in this case (webkit only) or
+ // focus doesn't shift right, but in normal
+ // cases we focus with the regular function.
+ dijit.focus(ed.editNode);
+ }else{
+ ed._viewsource_oldFocus();
+ }
+ }catch(e){
+ console.log(e);
+ }
+ }
+ };
+
+ var i, p;
+ for(i = 0; i < edPlugins.length; i++){
+ // We actually do need to trap this plugin and adjust how we
+ // display the textarea.
+ p = edPlugins[i];
+ if(p && (p.declaredClass === "dijit._editor.plugins.FullScreen" ||
+ p.declaredClass === (dijit._scopeName +
+ "._editor.plugins.FullScreen"))){
+ this._fsPlugin = p;
+ break;
+ }
+ }
+ if(this._fsPlugin){
+ // Found, we need to over-ride the alt-view node function
+ // on FullScreen with our own, chain up to parent call when appropriate.
+ this._fsPlugin._viewsource_getAltViewNode = this._fsPlugin._getAltViewNode;
+ this._fsPlugin._getAltViewNode = function(){
+ return self._sourceShown?self.sourceArea:this._viewsource_getAltViewNode();
+ };
+ }
+
+ // Listen to the source area for key events as well, as we need to be able to hotkey toggle
+ // it from there too.
+ this.connect(this.sourceArea, "onkeydown", dojo.hitch(this, function(e){
+ if(this._sourceShown && e.keyCode == dojo.keys.F12 && e.ctrlKey && e.shiftKey){
+ this.button.focus();
+ this.button.set("checked", false);
+ setTimeout(dojo.hitch(this, function(){ed.focus();}), 100);
+ dojo.stopEvent(e);
+ }
+ }));
+ },
+
+ _stripScripts: function(html){
+ // summary:
+ // Strips out script tags from the HTML used in editor.
+ // html: String
+ // The HTML to filter
+ // tags:
+ // private
+ if(html){
+ // Look for closed and unclosed (malformed) script attacks.
+ html = html.replace(/<\s*script[^>]*>((.|\s)*?)<\\?\/\s*script\s*>/ig, "");
+ html = html.replace(/<\s*script\b([^<>]|\s)*>?/ig, "");
+ html = html.replace(/<[^>]*=(\s|)*[("|')]javascript:[^$1][(\s|.)]*[$1][^>]*>/ig, "");
+ }
+ return html;
+ },
+
+ _stripComments: function(html){
+ // summary:
+ // Strips out comments from the HTML used in editor.
+ // html: String
+ // The HTML to filter
+ // tags:
+ // private
+ if(html){
+ html = html.replace(/<!--(.|\s){1,}?-->/g, "");
+ }
+ return html;
+ },
+
+ _stripIFrames: function(html){
+ // summary:
+ // Strips out iframe tags from the content, to avoid iframe script
+ // style injection attacks.
+ // html: String
+ // The HTML to filter
+ // tags:
+ // private
+ if(html){
+ html = html.replace(/<\s*iframe[^>]*>((.|\s)*?)<\\?\/\s*iframe\s*>/ig, "");
+ }
+ return html;
+ },
+
+ _filter: function(html){
+ // summary:
+ // Internal function to perform some filtering on the HTML.
+ // html: String
+ // The HTML to filter
+ // tags:
+ // private
+ if(html){
+ if(this.stripScripts){
+ html = this._stripScripts(html);
+ }
+ if(this.stripComments){
+ html = this._stripComments(html);
+ }
+ if(this.stripIFrames){
+ html = this._stripIFrames(html);
+ }
+ }
+ return html;
+ },
+
+ setSourceAreaCaret: function(){
+ // summary:
+ // Internal function to set the caret in the sourceArea
+ // to 0x0
+ var win = dojo.global;
+ var elem = this.sourceArea;
+ dijit.focus(elem);
+ if(this._sourceShown && !this.readOnly){
+ if(dojo.isIE){
+ if(this.sourceArea.createTextRange){
+ var range = elem.createTextRange();
+ range.collapse(true);
+ range.moveStart("character", -99999); // move to 0
+ range.moveStart("character", 0); // delta from 0 is the correct position
+ range.moveEnd("character", 0);
+ range.select();
+ }
+ }else if(win.getSelection){
+ if(elem.setSelectionRange){
+ elem.setSelectionRange(0,0);
+ }
+ }
+ }
+ },
+
+ destroy: function(){
+ // summary:
+ // Over-ride to remove the node used to correct for IE's
+ // zoom bug.
+ if(this._ieFixNode){
+ dojo.body().removeChild(this._ieFixNode);
+ }
+ if(this._resizer){
+ clearTimeout(this._resizer);
+ delete this._resizer;
+ }
+ if(this._resizeHandle){
+ dojo.disconnect(this._resizeHandle);
+ delete this._resizeHandle;
+ }
+ this.inherited(arguments);
+ }
});
-this._disabledPlugins=null;
-dojo.style(this.sourceArea,"display","none");
-dojo.style(ed.iframe,"display","block");
-delete ed._sourceQueryCommandEnabled;
-this.editor.onDisplayChanged();
-}
-setTimeout(dojo.hitch(this,function(){
-var _b=ed.domNode.parentNode;
-if(_b){
-var _c=dijit.getEnclosingWidget(_b);
-if(_c&&_c.resize){
-_c.resize();
-}
-}
-ed.resize();
-}),300);
-}
-catch(e){
-}
-},_resize:function(){
-var ed=this.editor;
-var _d=ed.getHeaderHeight();
-var fH=ed.getFooterHeight();
-var eb=dojo.position(ed.domNode);
-var _e=dojo._getPadBorderExtents(ed.iframe.parentNode);
-var _f=dojo._getMarginExtents(ed.iframe.parentNode);
-var _10=dojo._getPadBorderExtents(ed.domNode);
-var _11=dojo._getMarginExtents(ed.domNode);
-var edb={w:eb.w-(_10.w+_11.w),h:eb.h-(_d+_10.h+_11.h+fH)};
-if(this._fsPlugin&&this._fsPlugin.isFullscreen){
-var vp=dojo.window.getBox();
-edb.w=(vp.w-_10.w);
-edb.h=(vp.h-(_d+_10.h+fH));
-}
-if(dojo.isIE){
-edb.h-=2;
-}
-if(this._ieFixNode){
-var _12=-this._ieFixNode.offsetTop/1000;
-edb.w=Math.floor((edb.w+0.9)/_12);
-edb.h=Math.floor((edb.h+0.9)/_12);
-}
-dojo.marginBox(this.sourceArea,{w:edb.w-(_e.w+_f.w),h:edb.h-(_e.h+_f.h)});
-dojo.marginBox(ed.iframe.parentNode,{h:edb.h});
-},_createSourceView:function(){
-var ed=this.editor;
-var _13=ed._plugins;
-this.sourceArea=dojo.create("textarea");
-if(this.readOnly){
-dojo.attr(this.sourceArea,"readOnly",true);
-this._readOnly=true;
-}
-dojo.style(this.sourceArea,{padding:"0px",margin:"0px",borderWidth:"0px",borderStyle:"none"});
-dojo.place(this.sourceArea,ed.iframe,"before");
-if(dojo.isIE&&ed.iframe.parentNode.lastChild!==ed.iframe){
-dojo.style(ed.iframe.parentNode.lastChild,{width:"0px",height:"0px",padding:"0px",margin:"0px",borderWidth:"0px",borderStyle:"none"});
-}
-ed._viewsource_oldFocus=ed.focus;
-var _14=this;
-ed.focus=function(){
-if(_14._sourceShown){
-_14.setSourceAreaCaret();
-}else{
-try{
-if(this._vsFocused){
-delete this._vsFocused;
-dijit.focus(ed.editNode);
-}else{
-ed._viewsource_oldFocus();
-}
-}
-catch(e){
-}
-}
-};
-var i,p;
-for(i=0;i<_13.length;i++){
-p=_13[i];
-if(p&&(p.declaredClass==="dijit._editor.plugins.FullScreen"||p.declaredClass===(dijit._scopeName+"._editor.plugins.FullScreen"))){
-this._fsPlugin=p;
-break;
-}
-}
-if(this._fsPlugin){
-this._fsPlugin._viewsource_getAltViewNode=this._fsPlugin._getAltViewNode;
-this._fsPlugin._getAltViewNode=function(){
-return _14._sourceShown?_14.sourceArea:this._viewsource_getAltViewNode();
-};
-}
-this.connect(this.sourceArea,"onkeydown",dojo.hitch(this,function(e){
-if(this._sourceShown&&e.keyCode==dojo.keys.F12&&e.ctrlKey&&e.shiftKey){
-this.button.focus();
-this.button.set("checked",false);
-setTimeout(dojo.hitch(this,function(){
-ed.focus();
-}),100);
-dojo.stopEvent(e);
-}
-}));
-},_stripScripts:function(_15){
-if(_15){
-_15=_15.replace(/<\s*script[^>]*>((.|\s)*?)<\\?\/\s*script\s*>/ig,"");
-_15=_15.replace(/<\s*script\b([^<>]|\s)*>?/ig,"");
-_15=_15.replace(/<[^>]*=(\s|)*[("|')]javascript:[^$1][(\s|.)]*[$1][^>]*>/ig,"");
-}
-return _15;
-},_stripComments:function(_16){
-if(_16){
-_16=_16.replace(/<!--(.|\s){1,}?-->/g,"");
-}
-return _16;
-},_stripIFrames:function(_17){
-if(_17){
-_17=_17.replace(/<\s*iframe[^>]*>((.|\s)*?)<\\?\/\s*iframe\s*>/ig,"");
-}
-return _17;
-},_filter:function(_18){
-if(_18){
-if(this.stripScripts){
-_18=this._stripScripts(_18);
-}
-if(this.stripComments){
-_18=this._stripComments(_18);
-}
-if(this.stripIFrames){
-_18=this._stripIFrames(_18);
-}
-}
-return _18;
-},setSourceAreaCaret:function(){
-var win=dojo.global;
-var _19=this.sourceArea;
-dijit.focus(_19);
-if(this._sourceShown&&!this.readOnly){
-if(dojo.isIE){
-if(this.sourceArea.createTextRange){
-var _1a=_19.createTextRange();
-_1a.collapse(true);
-_1a.moveStart("character",-99999);
-_1a.moveStart("character",0);
-_1a.moveEnd("character",0);
-_1a.select();
-}
-}else{
-if(win.getSelection){
-if(_19.setSelectionRange){
-_19.setSelectionRange(0,0);
-}
-}
-}
-}
-},destroy:function(){
-if(this._ieFixNode){
-dojo.body().removeChild(this._ieFixNode);
-}
-if(this._resizer){
-clearTimeout(this._resizer);
-delete this._resizer;
-}
-if(this._resizeHandle){
-dojo.disconnect(this._resizeHandle);
-delete this._resizeHandle;
-}
-this.inherited(arguments);
-}});
-dojo.subscribe(dijit._scopeName+".Editor.getPlugin",null,function(o){
-if(o.plugin){
-return;
-}
-var _1b=o.args.name.toLowerCase();
-if(_1b==="viewsource"){
-o.plugin=new dijit._editor.plugins.ViewSource({readOnly:("readOnly" in o.args)?o.args.readOnly:false,stripComments:("stripComments" in o.args)?o.args.stripComments:true,stripScripts:("stripScripts" in o.args)?o.args.stripScripts:true,stripIFrames:("stripIFrames" in o.args)?o.args.stripIFrames:true});
-}
+
+// Register this plugin.
+dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
+ if(o.plugin){ return; }
+ var name = o.args.name.toLowerCase();
+ if(name === "viewsource"){
+ o.plugin = new dijit._editor.plugins.ViewSource({
+ readOnly: ("readOnly" in o.args)?o.args.readOnly:false,
+ stripComments: ("stripComments" in o.args)?o.args.stripComments:true,
+ stripScripts: ("stripScripts" in o.args)?o.args.stripScripts:true,
+ stripIFrames: ("stripIFrames" in o.args)?o.args.stripIFrames:true
+ });
+ }
});
+
}