summaryrefslogtreecommitdiff
path: root/lib/dijit/_editor/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dijit/_editor/plugins')
-rw-r--r--lib/dijit/_editor/plugins/AlwaysShowToolbar.js2
-rw-r--r--lib/dijit/_editor/plugins/AlwaysShowToolbar.js.uncompressed.js191
-rw-r--r--lib/dijit/_editor/plugins/EnterKeyHandling.js2
-rw-r--r--lib/dijit/_editor/plugins/EnterKeyHandling.js.uncompressed.js622
-rw-r--r--lib/dijit/_editor/plugins/FontChoice.js2
-rw-r--r--lib/dijit/_editor/plugins/FontChoice.js.uncompressed.js583
-rw-r--r--lib/dijit/_editor/plugins/FullScreen.js2
-rw-r--r--lib/dijit/_editor/plugins/FullScreen.js.uncompressed.js450
-rw-r--r--lib/dijit/_editor/plugins/LinkDialog.js2
-rw-r--r--lib/dijit/_editor/plugins/LinkDialog.js.uncompressed.js609
-rw-r--r--lib/dijit/_editor/plugins/NewPage.js2
-rw-r--r--lib/dijit/_editor/plugins/NewPage.js.uncompressed.js77
-rw-r--r--lib/dijit/_editor/plugins/Print.js2
-rw-r--r--lib/dijit/_editor/plugins/Print.js.uncompressed.js123
-rw-r--r--lib/dijit/_editor/plugins/TabIndent.js.uncompressed.js60
-rw-r--r--lib/dijit/_editor/plugins/TextColor.js2
-rw-r--r--lib/dijit/_editor/plugins/TextColor.js.uncompressed.js115
-rw-r--r--lib/dijit/_editor/plugins/ToggleDir.js2
-rw-r--r--lib/dijit/_editor/plugins/ToggleDir.js.uncompressed.js69
-rw-r--r--lib/dijit/_editor/plugins/ViewSource.js2
-rw-r--r--lib/dijit/_editor/plugins/ViewSource.js.uncompressed.js577
21 files changed, 3486 insertions, 10 deletions
diff --git a/lib/dijit/_editor/plugins/AlwaysShowToolbar.js b/lib/dijit/_editor/plugins/AlwaysShowToolbar.js
index 665b4bb7d..20a56fcfa 100644
--- a/lib/dijit/_editor/plugins/AlwaysShowToolbar.js
+++ b/lib/dijit/_editor/plugins/AlwaysShowToolbar.js
@@ -1,2 +1,2 @@
//>>built
-define("dijit/_editor/plugins/AlwaysShowToolbar",["dojo/_base/declare","dojo/dom-class","dojo/dom-construct","dojo/dom-geometry","dojo/_base/lang","dojo/_base/sniff","dojo/_base/window","../_Plugin"],function(_1,_2,_3,_4,_5,_6,_7,_8){return _1("dijit._editor.plugins.AlwaysShowToolbar",_8,{_handleScroll:true,setEditor:function(e){if(!e.iframe){return;}this.editor=e;e.onLoadDeferred.addCallback(_5.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 _9=_4.getMarginSize(e.editNode).h;if(_6("opera")){_9=e.editNode.scrollHeight;}if(!_9){_9=_4.getMarginSize(e.document.body).h;}if(_9==0){return;}if(_6("ie")<=7&&this.editor.minHeight){var _a=parseInt(this.editor.minHeight);if(_9<_a){_9=_a;}}if(_9!=this._lastHeight){this._lastHeight=_9;_4.setMarginBox(e.iframe,{h:this._lastHeight});}},_lastHeight:0,globalOnScrollHandler:function(){var _b=_6("ie")<7;if(!this._handleScroll){return;}var _c=this.editor.header;if(!this._scrollSetUp){this._scrollSetUp=true;this._scrollThreshold=_4.position(_c,true).y;}var _d=_4.docScroll().y;var s=_c.style;if(_d>this._scrollThreshold&&_d<this._scrollThreshold+this._lastHeight){if(!this._fixEnabled){var _e=_4.getMarginSize(_c);this.editor.iframe.style.marginTop=_e.h+"px";if(_b){s.left=_4.position(_c).x;if(_c.previousSibling){this._IEOriginalPos=["after",_c.previousSibling];}else{if(_c.nextSibling){this._IEOriginalPos=["before",_c.nextSibling];}else{this._IEOriginalPos=["last",_c.parentNode];}}_7.body().appendChild(_c);_2.add(_c,"dijitIEFixedToolbar");}else{s.position="fixed";s.top="0px";}_4.setMarginBox(_c,{w:_e.w});s.zIndex=2000;this._fixEnabled=true;}var _f=(this.height)?parseInt(this.editor.height):this.editor._lastHeight;s.display=(_d>this._scrollThreshold+_f)?"none":"";}else{if(this._fixEnabled){this.editor.iframe.style.marginTop="";s.position="";s.top="";s.zIndex="";s.display="";if(_b){s.left="";_2.remove(_c,"dijitIEFixedToolbar");if(this._IEOriginalPos){_3.place(_c,this._IEOriginalPos[1],this._IEOriginalPos[0]);this._IEOriginalPos=null;}else{_3.place(_c,this.editor.iframe,"before");}}s.width="";this._fixEnabled=false;}}},destroy:function(){this._IEOriginalPos=null;this._handleScroll=false;this.inherited(arguments);if(_6("ie")<7){_2.remove(this.editor.header,"dijitIEFixedToolbar");}}});}); \ No newline at end of file
+define("dijit/_editor/plugins/AlwaysShowToolbar",["dojo/_base/declare","dojo/dom-class","dojo/dom-construct","dojo/dom-geometry","dojo/_base/lang","dojo/sniff","dojo/_base/window","../_Plugin"],function(_1,_2,_3,_4,_5,_6,_7,_8){return _1("dijit._editor.plugins.AlwaysShowToolbar",_8,{_handleScroll:true,setEditor:function(e){if(!e.iframe){return;}this.editor=e;e.onLoadDeferred.then(_5.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 _9=_4.getMarginSize(e.editNode).h;if(_6("opera")){_9=e.editNode.scrollHeight;}if(!_9){_9=_4.getMarginSize(e.document.body).h;}if(_9==0){return;}if(_6("ie")<=7&&this.editor.minHeight){var _a=parseInt(this.editor.minHeight);if(_9<_a){_9=_a;}}if(_9!=this._lastHeight){this._lastHeight=_9;_4.setMarginBox(e.iframe,{h:this._lastHeight});}},_lastHeight:0,globalOnScrollHandler:function(){var _b=_6("ie")<7;if(!this._handleScroll){return;}var _c=this.editor.header;if(!this._scrollSetUp){this._scrollSetUp=true;this._scrollThreshold=_4.position(_c,true).y;}var _d=_4.docScroll(this.editor.ownerDocument).y;var s=_c.style;if(_d>this._scrollThreshold&&_d<this._scrollThreshold+this._lastHeight){if(!this._fixEnabled){var _e=_4.getMarginSize(_c);this.editor.iframe.style.marginTop=_e.h+"px";if(_b){s.left=_4.position(_c).x;if(_c.previousSibling){this._IEOriginalPos=["after",_c.previousSibling];}else{if(_c.nextSibling){this._IEOriginalPos=["before",_c.nextSibling];}else{this._IEOriginalPos=["last",_c.parentNode];}}this.editor.ownerDocumentBody.appendChild(_c);_2.add(_c,"dijitIEFixedToolbar");}else{s.position="fixed";s.top="0px";}_4.setMarginBox(_c,{w:_e.w});s.zIndex=2000;this._fixEnabled=true;}var _f=(this.height)?parseInt(this.editor.height):this.editor._lastHeight;s.display=(_d>this._scrollThreshold+_f)?"none":"";}else{if(this._fixEnabled){this.editor.iframe.style.marginTop="";s.position="";s.top="";s.zIndex="";s.display="";if(_b){s.left="";_2.remove(_c,"dijitIEFixedToolbar");if(this._IEOriginalPos){_3.place(_c,this._IEOriginalPos[1],this._IEOriginalPos[0]);this._IEOriginalPos=null;}else{_3.place(_c,this.editor.iframe,"before");}}s.width="";this._fixEnabled=false;}}},destroy:function(){this._IEOriginalPos=null;this._handleScroll=false;this.inherited(arguments);if(_6("ie")<7){_2.remove(this.editor.header,"dijitIEFixedToolbar");}}});}); \ No newline at end of file
diff --git a/lib/dijit/_editor/plugins/AlwaysShowToolbar.js.uncompressed.js b/lib/dijit/_editor/plugins/AlwaysShowToolbar.js.uncompressed.js
new file mode 100644
index 000000000..1f2b7a4e2
--- /dev/null
+++ b/lib/dijit/_editor/plugins/AlwaysShowToolbar.js.uncompressed.js
@@ -0,0 +1,191 @@
+define("dijit/_editor/plugins/AlwaysShowToolbar", [
+ "dojo/_base/declare", // declare
+ "dojo/dom-class", // domClass.add domClass.remove
+ "dojo/dom-construct", // domConstruct.place
+ "dojo/dom-geometry",
+ "dojo/_base/lang", // lang.hitch
+ "dojo/sniff", // has("ie") has("opera")
+ "dojo/_base/window", // win.body
+ "../_Plugin"
+], function(declare, domClass, domConstruct, domGeometry, lang, has, win, _Plugin){
+
+// module:
+// dijit/_editor/plugins/AlwaysShowToolbar
+
+return declare("dijit._editor.plugins.AlwaysShowToolbar", _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:
+ // | <script type="dojo/require">
+ // | AlwaysShowToolbar: "dijit/_editor/plugins/AlwaysShowToolbar"
+ // | </script>
+ // | <div data-dojo-type="dijit/Editor" height=""
+ // | data-dojo-props="extraPlugins: [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.then(lang.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 = domGeometry.getMarginSize(e.editNode).h;
+ if(has("opera")){
+ 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 = domGeometry.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(has("ie") <= 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";
+ domGeometry.setMarginBox(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 = has("ie") < 7;
+ if(!this._handleScroll){ return; }
+ var tdn = this.editor.header;
+ if(!this._scrollSetUp){
+ this._scrollSetUp = true;
+ this._scrollThreshold = domGeometry.position(tdn, true).y;
+// var db = win.body;
+// console.log("threshold:", this._scrollThreshold);
+ //what's this for?? comment out for now
+// if((isIE6)&&(db)&&(domStyle.set or get TODO(db, "backgroundIimage")=="none")){
+// db.style.backgroundImage = "url(" + dojo.uri.moduleUri("dijit", "templates/blank.gif") + ")";
+// db.style.backgroundAttachment = "fixed";
+// }
+ }
+
+ var scrollPos = domGeometry.docScroll(this.editor.ownerDocument).y;
+ var s = tdn.style;
+
+ if(scrollPos > this._scrollThreshold && scrollPos < this._scrollThreshold+this._lastHeight){
+ // dojo.debug(scrollPos);
+ if(!this._fixEnabled){
+ var tdnbox = domGeometry.getMarginSize(tdn);
+ this.editor.iframe.style.marginTop = tdnbox.h+"px";
+
+ if(isIE6){
+ s.left = domGeometry.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];
+ }
+ this.editor.ownerDocumentBody.appendChild(tdn);
+ domClass.add(tdn,'dijitIEFixedToolbar');
+ }else{
+ s.position = "fixed";
+ s.top = "0px";
+ }
+
+ domGeometry.setMarginBox(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 = "";
+ domClass.remove(tdn,'dijitIEFixedToolbar');
+ if(this._IEOriginalPos){
+ domConstruct.place(tdn, this._IEOriginalPos[1], this._IEOriginalPos[0]);
+ this._IEOriginalPos = null;
+ }else{
+ domConstruct.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;
+ this.inherited(arguments);
+
+ if(has("ie") < 7){
+ domClass.remove(this.editor.header, 'dijitIEFixedToolbar');
+ }
+ }
+});
+
+});
diff --git a/lib/dijit/_editor/plugins/EnterKeyHandling.js b/lib/dijit/_editor/plugins/EnterKeyHandling.js
index 60b3baa8a..6d226232c 100644
--- a/lib/dijit/_editor/plugins/EnterKeyHandling.js
+++ b/lib/dijit/_editor/plugins/EnterKeyHandling.js
@@ -1,2 +1,2 @@
//>>built
-define("dijit/_editor/plugins/EnterKeyHandling",["dojo/_base/declare","dojo/dom-construct","dojo/_base/event","dojo/keys","dojo/_base/lang","dojo/_base/sniff","dojo/_base/window","dojo/window","../_Plugin","../RichText","../range","../selection"],function(_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c){return _1("dijit._editor.plugins.EnterKeyHandling",_9,{blockNodeForEnter:"BR",constructor:function(_d){if(_d){if("blockNodeForEnter" in _d){_d.blockNodeForEnter=_d.blockNodeForEnter.toUpperCase();}_5.mixin(this,_d);}},setEditor:function(_e){if(this.editor===_e){return;}this.editor=_e;if(this.blockNodeForEnter=="BR"){this.editor.customUndo=true;_e.onLoadDeferred.then(_5.hitch(this,function(d){this.connect(_e.document,"onkeypress",function(e){if(e.charOrCode==_4.ENTER){var ne=_5.mixin({},e);ne.shiftKey=true;if(!this.handleEnterKey(ne)){_3.stop(e);}}});if(_6("ie")==9){this.connect(_e.document,"onpaste",function(e){setTimeout(dojo.hitch(this,function(){var r=this.editor.document.selection.createRange();r.move("character",-1);r.select();r.move("character",1);r.select();}),0);});}return d;}));}else{if(this.blockNodeForEnter){var h=_5.hitch(this,this.handleEnterKey);_e.addKeyHandler(13,0,0,h);_e.addKeyHandler(13,0,1,h);this.connect(this.editor,"onKeyPressed","onKeyPressed");}}},onKeyPressed:function(){if(this._checkListLater){if(_7.withGlobal(this.editor.window,"isCollapsed",dijit)){var _f=_7.withGlobal(this.editor.window,"getAncestorElement",_c,["LI"]);if(!_f){_a.prototype.execCommand.call(this.editor,"formatblock",this.blockNodeForEnter);var _10=_7.withGlobal(this.editor.window,"getAncestorElement",_c,[this.blockNodeForEnter]);if(_10){_10.innerHTML=this.bogusHtmlContent;if(_6("ie")){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(_6("mozilla")){if(_f.parentNode.parentNode.nodeName=="LI"){_f=_f.parentNode.parentNode;}}var fc=_f.firstChild;if(fc&&fc.nodeType==1&&(fc.nodeName=="UL"||fc.nodeName=="OL")){_f.insertBefore(fc.ownerDocument.createTextNode(" "),fc);var _11=_b.create(this.editor.window);_11.setStart(_f.firstChild,0);var _12=_b.getSelection(this.editor.window,true);_12.removeAllRanges();_12.addRange(_11);}}}this._checkListLater=false;}if(this._pressedEnterInBlock){if(this._pressedEnterInBlock.previousSibling){this.removeTrailingBr(this._pressedEnterInBlock.previousSibling);}delete this._pressedEnterInBlock;}},bogusHtmlContent:"&#160;",blockNodes:/^(?:P|H1|H2|H3|H4|H5|H6|LI)$/,handleEnterKey:function(e){var _13,_14,_15,_16,_17,_18,doc=this.editor.document,br,rs,txt;if(e.shiftKey){var _19=_7.withGlobal(this.editor.window,"getParentElement",_c);var _1a=_b.getAncestor(_19,this.blockNodes);if(_1a){if(_1a.tagName=="LI"){return true;}_13=_b.getSelection(this.editor.window);_14=_13.getRangeAt(0);if(!_14.collapsed){_14.deleteContents();_13=_b.getSelection(this.editor.window);_14=_13.getRangeAt(0);}if(_b.atBeginningOfContainer(_1a,_14.startContainer,_14.startOffset)){br=doc.createElement("br");_15=_b.create(this.editor.window);_1a.insertBefore(br,_1a.firstChild);_15.setStartAfter(br);_13.removeAllRanges();_13.addRange(_15);}else{if(_b.atEndOfContainer(_1a,_14.startContainer,_14.startOffset)){_15=_b.create(this.editor.window);br=doc.createElement("br");_1a.appendChild(br);_1a.appendChild(doc.createTextNode(" "));_15.setStart(_1a.lastChild,0);_13.removeAllRanges();_13.addRange(_15);}else{rs=_14.startContainer;if(rs&&rs.nodeType==3){txt=rs.nodeValue;_7.withGlobal(this.editor.window,function(){_16=doc.createTextNode(txt.substring(0,_14.startOffset));_17=doc.createTextNode(txt.substring(_14.startOffset));_18=doc.createElement("br");if(_17.nodeValue==""&&_6("webkit")){_17=doc.createTextNode(" ");}_2.place(_16,rs,"after");_2.place(_18,_16,"after");_2.place(_17,_18,"after");_2.destroy(rs);_15=_b.create();_15.setStart(_17,0);_13.removeAllRanges();_13.addRange(_15);});return false;}return true;}}}else{_13=_b.getSelection(this.editor.window);if(_13.rangeCount){_14=_13.getRangeAt(0);if(_14&&_14.startContainer){if(!_14.collapsed){_14.deleteContents();_13=_b.getSelection(this.editor.window);_14=_13.getRangeAt(0);}rs=_14.startContainer;if(rs&&rs.nodeType==3){_7.withGlobal(this.editor.window,_5.hitch(this,function(){var _1b=false;var _1c=_14.startOffset;if(rs.length<_1c){ret=this._adjustNodeAndOffset(rs,_1c);rs=ret.node;_1c=ret.offset;}txt=rs.nodeValue;_16=doc.createTextNode(txt.substring(0,_1c));_17=doc.createTextNode(txt.substring(_1c));_18=doc.createElement("br");if(!_17.length){_17=doc.createTextNode(" ");_1b=true;}if(_16.length){_2.place(_16,rs,"after");}else{_16=rs;}_2.place(_18,_16,"after");_2.place(_17,_18,"after");_2.destroy(rs);_15=_b.create();_15.setStart(_17,0);_15.setEnd(_17,_17.length);_13.removeAllRanges();_13.addRange(_15);if(_1b&&!_6("webkit")){_c.remove();}else{_c.collapse(true);}}));}else{var _1d;if(_14.startOffset>=0){_1d=rs.childNodes[_14.startOffset];}_7.withGlobal(this.editor.window,_5.hitch(this,function(){var _1e=doc.createElement("br");var _1f=doc.createTextNode(" ");if(!_1d){rs.appendChild(_1e);rs.appendChild(_1f);}else{_2.place(_1e,_1d,"before");_2.place(_1f,_1e,"after");}_15=_b.create(_7.global);_15.setStart(_1f,0);_15.setEnd(_1f,_1f.length);_13.removeAllRanges();_13.addRange(_15);_c.collapse(true);}));}}}else{_a.prototype.execCommand.call(this.editor,"inserthtml","<br>");}}return false;}var _20=true;_13=_b.getSelection(this.editor.window);_14=_13.getRangeAt(0);if(!_14.collapsed){_14.deleteContents();_13=_b.getSelection(this.editor.window);_14=_13.getRangeAt(0);}var _21=_b.getBlockAncestor(_14.endContainer,null,this.editor.editNode);var _22=_21.blockNode;if((this._checkListLater=(_22&&(_22.nodeName=="LI"||_22.parentNode.nodeName=="LI")))){if(_6("mozilla")){this._pressedEnterInBlock=_22;}if(/^(\s|&nbsp;|&#160;|\xA0|<span\b[^>]*\bclass=['"]Apple-style-span['"][^>]*>(\s|&nbsp;|&#160;|\xA0)<\/span>)?(<br>)?$/.test(_22.innerHTML)){_22.innerHTML="";if(_6("webkit")){_15=_b.create(this.editor.window);_15.setStart(_22,0);_13.removeAllRanges();_13.addRange(_15);}this._checkListLater=false;}return true;}if(!_21.blockNode||_21.blockNode===this.editor.editNode){try{_a.prototype.execCommand.call(this.editor,"formatblock",this.blockNodeForEnter);}catch(e2){}_21={blockNode:_7.withGlobal(this.editor.window,"getAncestorElement",_c,[this.blockNodeForEnter]),blockContainer:this.editor.editNode};if(_21.blockNode){if(_21.blockNode!=this.editor.editNode&&(!(_21.blockNode.textContent||_21.blockNode.innerHTML).replace(/^\s+|\s+$/g,"").length)){this.removeTrailingBr(_21.blockNode);return false;}}else{_21.blockNode=this.editor.editNode;}_13=_b.getSelection(this.editor.window);_14=_13.getRangeAt(0);}var _23=doc.createElement(this.blockNodeForEnter);_23.innerHTML=this.bogusHtmlContent;this.removeTrailingBr(_21.blockNode);var _24=_14.endOffset;var _25=_14.endContainer;if(_25.length<_24){var ret=this._adjustNodeAndOffset(_25,_24);_25=ret.node;_24=ret.offset;}if(_b.atEndOfContainer(_21.blockNode,_25,_24)){if(_21.blockNode===_21.blockContainer){_21.blockNode.appendChild(_23);}else{_2.place(_23,_21.blockNode,"after");}_20=false;_15=_b.create(this.editor.window);_15.setStart(_23,0);_13.removeAllRanges();_13.addRange(_15);if(this.editor.height){_8.scrollIntoView(_23);}}else{if(_b.atBeginningOfContainer(_21.blockNode,_14.startContainer,_14.startOffset)){_2.place(_23,_21.blockNode,_21.blockNode===_21.blockContainer?"first":"before");if(_23.nextSibling&&this.editor.height){_15=_b.create(this.editor.window);_15.setStart(_23.nextSibling,0);_13.removeAllRanges();_13.addRange(_15);_8.scrollIntoView(_23.nextSibling);}_20=false;}else{if(_21.blockNode===_21.blockContainer){_21.blockNode.appendChild(_23);}else{_2.place(_23,_21.blockNode,"after");}_20=false;if(_21.blockNode.style){if(_23.style){if(_21.blockNode.style.cssText){_23.style.cssText=_21.blockNode.style.cssText;}}}rs=_14.startContainer;var _26;if(rs&&rs.nodeType==3){var _27,_28;_24=_14.endOffset;if(rs.length<_24){ret=this._adjustNodeAndOffset(rs,_24);rs=ret.node;_24=ret.offset;}txt=rs.nodeValue;_16=doc.createTextNode(txt.substring(0,_24));_17=doc.createTextNode(txt.substring(_24,txt.length));_2.place(_16,rs,"before");_2.place(_17,rs,"after");_2.destroy(rs);var _29=_16.parentNode;while(_29!==_21.blockNode){var tg=_29.tagName;var _2a=doc.createElement(tg);if(_29.style){if(_2a.style){if(_29.style.cssText){_2a.style.cssText=_29.style.cssText;}}}if(_29.tagName==="FONT"){if(_29.color){_2a.color=_29.color;}if(_29.face){_2a.face=_29.face;}if(_29.size){_2a.size=_29.size;}}_27=_17;while(_27){_28=_27.nextSibling;_2a.appendChild(_27);_27=_28;}_2.place(_2a,_29,"after");_16=_29;_17=_2a;_29=_29.parentNode;}_27=_17;if(_27.nodeType==1||(_27.nodeType==3&&_27.nodeValue)){_23.innerHTML="";}_26=_27;while(_27){_28=_27.nextSibling;_23.appendChild(_27);_27=_28;}}_15=_b.create(this.editor.window);var _2b;var _2c=_26;if(this.blockNodeForEnter!=="BR"){while(_2c){_2b=_2c;_28=_2c.firstChild;_2c=_28;}if(_2b&&_2b.parentNode){_23=_2b.parentNode;_15.setStart(_23,0);_13.removeAllRanges();_13.addRange(_15);if(this.editor.height){_8.scrollIntoView(_23);}if(_6("mozilla")){this._pressedEnterInBlock=_21.blockNode;}}else{_20=true;}}else{_15.setStart(_23,0);_13.removeAllRanges();_13.addRange(_15);if(this.editor.height){_8.scrollIntoView(_23);}if(_6("mozilla")){this._pressedEnterInBlock=_21.blockNode;}}}}return _20;},_adjustNodeAndOffset:function(_2d,_2e){while(_2d.length<_2e&&_2d.nextSibling&&_2d.nextSibling.nodeType==3){_2e=_2e-_2d.length;_2d=_2d.nextSibling;}return {"node":_2d,"offset":_2e};},removeTrailingBr:function(_2f){var _30=/P|DIV|LI/i.test(_2f.tagName)?_2f:_c.getParentOfType(_2f,["P","DIV","LI"]);if(!_30){return;}if(_30.lastChild){if((_30.childNodes.length>1&&_30.lastChild.nodeType==3&&/^[\s\xAD]*$/.test(_30.lastChild.nodeValue))||_30.lastChild.tagName=="BR"){_2.destroy(_30.lastChild);}}if(!_30.childNodes.length){_30.innerHTML=this.bogusHtmlContent;}}});}); \ No newline at end of file
+define("dijit/_editor/plugins/EnterKeyHandling",["dojo/_base/declare","dojo/dom-construct","dojo/_base/event","dojo/keys","dojo/_base/lang","dojo/sniff","dojo/_base/window","dojo/window","../_Plugin","../RichText","../range","../../_base/focus"],function(_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c){return _1("dijit._editor.plugins.EnterKeyHandling",_9,{blockNodeForEnter:"BR",constructor:function(_d){if(_d){if("blockNodeForEnter" in _d){_d.blockNodeForEnter=_d.blockNodeForEnter.toUpperCase();}_5.mixin(this,_d);}},setEditor:function(_e){if(this.editor===_e){return;}this.editor=_e;if(this.blockNodeForEnter=="BR"){this.editor.customUndo=true;_e.onLoadDeferred.then(_5.hitch(this,function(d){this.connect(_e.document,"onkeypress",function(e){if(e.charOrCode==_4.ENTER){var ne=_5.mixin({},e);ne.shiftKey=true;if(!this.handleEnterKey(ne)){_3.stop(e);}}});if(_6("ie")>=9){this.connect(_e.document,"onpaste",function(e){setTimeout(dojo.hitch(this,function(){var r=this.editor.document.selection.createRange();r.move("character",-1);r.select();r.move("character",1);r.select();}),0);});}return d;}));}else{if(this.blockNodeForEnter){var h=_5.hitch(this,this.handleEnterKey);_e.addKeyHandler(13,0,0,h);_e.addKeyHandler(13,0,1,h);this.connect(this.editor,"onKeyPressed","onKeyPressed");}}},onKeyPressed:function(){if(this._checkListLater){if(_7.withGlobal(this.editor.window,"isCollapsed",_c)){var _f=this.editor._sCall("getAncestorElement",["LI"]);if(!_f){_a.prototype.execCommand.call(this.editor,"formatblock",this.blockNodeForEnter);var _10=this.editor._sCall("getAncestorElement",[this.blockNodeForEnter]);if(_10){_10.innerHTML=this.bogusHtmlContent;if(_6("ie")<=9){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(_6("mozilla")){if(_f.parentNode.parentNode.nodeName=="LI"){_f=_f.parentNode.parentNode;}}var fc=_f.firstChild;if(fc&&fc.nodeType==1&&(fc.nodeName=="UL"||fc.nodeName=="OL")){_f.insertBefore(fc.ownerDocument.createTextNode(" "),fc);var _11=_b.create(this.editor.window);_11.setStart(_f.firstChild,0);var _12=_b.getSelection(this.editor.window,true);_12.removeAllRanges();_12.addRange(_11);}}}this._checkListLater=false;}if(this._pressedEnterInBlock){if(this._pressedEnterInBlock.previousSibling){this.removeTrailingBr(this._pressedEnterInBlock.previousSibling);}delete this._pressedEnterInBlock;}},bogusHtmlContent:"&#160;",blockNodes:/^(?:P|H1|H2|H3|H4|H5|H6|LI)$/,handleEnterKey:function(e){var _13,_14,_15,_16,_17,_18,doc=this.editor.document,br,rs,txt;if(e.shiftKey){var _19=this.editor._sCall("getParentElement",[]);var _1a=_b.getAncestor(_19,this.blockNodes);if(_1a){if(_1a.tagName=="LI"){return true;}_13=_b.getSelection(this.editor.window);_14=_13.getRangeAt(0);if(!_14.collapsed){_14.deleteContents();_13=_b.getSelection(this.editor.window);_14=_13.getRangeAt(0);}if(_b.atBeginningOfContainer(_1a,_14.startContainer,_14.startOffset)){br=doc.createElement("br");_15=_b.create(this.editor.window);_1a.insertBefore(br,_1a.firstChild);_15.setStartAfter(br);_13.removeAllRanges();_13.addRange(_15);}else{if(_b.atEndOfContainer(_1a,_14.startContainer,_14.startOffset)){_15=_b.create(this.editor.window);br=doc.createElement("br");_1a.appendChild(br);_1a.appendChild(doc.createTextNode(" "));_15.setStart(_1a.lastChild,0);_13.removeAllRanges();_13.addRange(_15);}else{rs=_14.startContainer;if(rs&&rs.nodeType==3){txt=rs.nodeValue;_16=doc.createTextNode(txt.substring(0,_14.startOffset));_17=doc.createTextNode(txt.substring(_14.startOffset));_18=doc.createElement("br");if(_17.nodeValue==""&&_6("webkit")){_17=doc.createTextNode(" ");}_2.place(_16,rs,"after");_2.place(_18,_16,"after");_2.place(_17,_18,"after");_2.destroy(rs);_15=_b.create(this.editor.window);_15.setStart(_17,0);_13.removeAllRanges();_13.addRange(_15);return false;}return true;}}}else{_13=_b.getSelection(this.editor.window);if(_13.rangeCount){_14=_13.getRangeAt(0);if(_14&&_14.startContainer){if(!_14.collapsed){_14.deleteContents();_13=_b.getSelection(this.editor.window);_14=_13.getRangeAt(0);}rs=_14.startContainer;if(rs&&rs.nodeType==3){var _1b=false;var _1c=_14.startOffset;if(rs.length<_1c){ret=this._adjustNodeAndOffset(rs,_1c);rs=ret.node;_1c=ret.offset;}txt=rs.nodeValue;_16=doc.createTextNode(txt.substring(0,_1c));_17=doc.createTextNode(txt.substring(_1c));_18=doc.createElement("br");if(!_17.length){_17=doc.createTextNode(" ");_1b=true;}if(_16.length){_2.place(_16,rs,"after");}else{_16=rs;}_2.place(_18,_16,"after");_2.place(_17,_18,"after");_2.destroy(rs);_15=_b.create(this.editor.window);_15.setStart(_17,0);_15.setEnd(_17,_17.length);_13.removeAllRanges();_13.addRange(_15);if(_1b&&!_6("webkit")){this.editor._sCall("remove",[]);}else{this.editor._sCall("collapse",[true]);}}else{var _1d;if(_14.startOffset>=0){_1d=rs.childNodes[_14.startOffset];}var _18=doc.createElement("br");var _17=doc.createTextNode(" ");if(!_1d){rs.appendChild(_18);rs.appendChild(_17);}else{_2.place(_18,_1d,"before");_2.place(_17,_18,"after");}_15=_b.create(this.editor.window);_15.setStart(_17,0);_15.setEnd(_17,_17.length);_13.removeAllRanges();_13.addRange(_15);this.editor._sCall("collapse",[true]);}}}else{_a.prototype.execCommand.call(this.editor,"inserthtml","<br>");}}return false;}var _1e=true;_13=_b.getSelection(this.editor.window);_14=_13.getRangeAt(0);if(!_14.collapsed){_14.deleteContents();_13=_b.getSelection(this.editor.window);_14=_13.getRangeAt(0);}var _1f=_b.getBlockAncestor(_14.endContainer,null,this.editor.editNode);var _20=_1f.blockNode;if((this._checkListLater=(_20&&(_20.nodeName=="LI"||_20.parentNode.nodeName=="LI")))){if(_6("mozilla")){this._pressedEnterInBlock=_20;}if(/^(\s|&nbsp;|&#160;|\xA0|<span\b[^>]*\bclass=['"]Apple-style-span['"][^>]*>(\s|&nbsp;|&#160;|\xA0)<\/span>)?(<br>)?$/.test(_20.innerHTML)){_20.innerHTML="";if(_6("webkit")){_15=_b.create(this.editor.window);_15.setStart(_20,0);_13.removeAllRanges();_13.addRange(_15);}this._checkListLater=false;}return true;}if(!_1f.blockNode||_1f.blockNode===this.editor.editNode){try{_a.prototype.execCommand.call(this.editor,"formatblock",this.blockNodeForEnter);}catch(e2){}_1f={blockNode:this.editor._sCall("getAncestorElement",[this.blockNodeForEnter]),blockContainer:this.editor.editNode};if(_1f.blockNode){if(_1f.blockNode!=this.editor.editNode&&(!(_1f.blockNode.textContent||_1f.blockNode.innerHTML).replace(/^\s+|\s+$/g,"").length)){this.removeTrailingBr(_1f.blockNode);return false;}}else{_1f.blockNode=this.editor.editNode;}_13=_b.getSelection(this.editor.window);_14=_13.getRangeAt(0);}var _21=doc.createElement(this.blockNodeForEnter);_21.innerHTML=this.bogusHtmlContent;this.removeTrailingBr(_1f.blockNode);var _22=_14.endOffset;var _23=_14.endContainer;if(_23.length<_22){var ret=this._adjustNodeAndOffset(_23,_22);_23=ret.node;_22=ret.offset;}if(_b.atEndOfContainer(_1f.blockNode,_23,_22)){if(_1f.blockNode===_1f.blockContainer){_1f.blockNode.appendChild(_21);}else{_2.place(_21,_1f.blockNode,"after");}_1e=false;_15=_b.create(this.editor.window);_15.setStart(_21,0);_13.removeAllRanges();_13.addRange(_15);if(this.editor.height){_8.scrollIntoView(_21);}}else{if(_b.atBeginningOfContainer(_1f.blockNode,_14.startContainer,_14.startOffset)){_2.place(_21,_1f.blockNode,_1f.blockNode===_1f.blockContainer?"first":"before");if(_21.nextSibling&&this.editor.height){_15=_b.create(this.editor.window);_15.setStart(_21.nextSibling,0);_13.removeAllRanges();_13.addRange(_15);_8.scrollIntoView(_21.nextSibling);}_1e=false;}else{if(_1f.blockNode===_1f.blockContainer){_1f.blockNode.appendChild(_21);}else{_2.place(_21,_1f.blockNode,"after");}_1e=false;if(_1f.blockNode.style){if(_21.style){if(_1f.blockNode.style.cssText){_21.style.cssText=_1f.blockNode.style.cssText;}}}rs=_14.startContainer;var _24;if(rs&&rs.nodeType==3){var _25,_26;_22=_14.endOffset;if(rs.length<_22){ret=this._adjustNodeAndOffset(rs,_22);rs=ret.node;_22=ret.offset;}txt=rs.nodeValue;_16=doc.createTextNode(txt.substring(0,_22));_17=doc.createTextNode(txt.substring(_22,txt.length));_2.place(_16,rs,"before");_2.place(_17,rs,"after");_2.destroy(rs);var _27=_16.parentNode;while(_27!==_1f.blockNode){var tg=_27.tagName;var _28=doc.createElement(tg);if(_27.style){if(_28.style){if(_27.style.cssText){_28.style.cssText=_27.style.cssText;}}}if(_27.tagName==="FONT"){if(_27.color){_28.color=_27.color;}if(_27.face){_28.face=_27.face;}if(_27.size){_28.size=_27.size;}}_25=_17;while(_25){_26=_25.nextSibling;_28.appendChild(_25);_25=_26;}_2.place(_28,_27,"after");_16=_27;_17=_28;_27=_27.parentNode;}_25=_17;if(_25.nodeType==1||(_25.nodeType==3&&_25.nodeValue)){_21.innerHTML="";}_24=_25;while(_25){_26=_25.nextSibling;_21.appendChild(_25);_25=_26;}}_15=_b.create(this.editor.window);var _29;var _2a=_24;if(this.blockNodeForEnter!=="BR"){while(_2a){_29=_2a;_26=_2a.firstChild;_2a=_26;}if(_29&&_29.parentNode){_21=_29.parentNode;_15.setStart(_21,0);_13.removeAllRanges();_13.addRange(_15);if(this.editor.height){_8.scrollIntoView(_21);}if(_6("mozilla")){this._pressedEnterInBlock=_1f.blockNode;}}else{_1e=true;}}else{_15.setStart(_21,0);_13.removeAllRanges();_13.addRange(_15);if(this.editor.height){_8.scrollIntoView(_21);}if(_6("mozilla")){this._pressedEnterInBlock=_1f.blockNode;}}}}return _1e;},_adjustNodeAndOffset:function(_2b,_2c){while(_2b.length<_2c&&_2b.nextSibling&&_2b.nextSibling.nodeType==3){_2c=_2c-_2b.length;_2b=_2b.nextSibling;}return {"node":_2b,"offset":_2c};},removeTrailingBr:function(_2d){var _2e=/P|DIV|LI/i.test(_2d.tagName)?_2d:this.editor._sCall("getParentOfType",[_2d,["P","DIV","LI"]]);if(!_2e){return;}if(_2e.lastChild){if((_2e.childNodes.length>1&&_2e.lastChild.nodeType==3&&/^[\s\xAD]*$/.test(_2e.lastChild.nodeValue))||_2e.lastChild.tagName=="BR"){_2.destroy(_2e.lastChild);}}if(!_2e.childNodes.length){_2e.innerHTML=this.bogusHtmlContent;}}});}); \ No newline at end of file
diff --git a/lib/dijit/_editor/plugins/EnterKeyHandling.js.uncompressed.js b/lib/dijit/_editor/plugins/EnterKeyHandling.js.uncompressed.js
new file mode 100644
index 000000000..e5c7b7466
--- /dev/null
+++ b/lib/dijit/_editor/plugins/EnterKeyHandling.js.uncompressed.js
@@ -0,0 +1,622 @@
+define("dijit/_editor/plugins/EnterKeyHandling", [
+ "dojo/_base/declare", // declare
+ "dojo/dom-construct", // domConstruct.destroy domConstruct.place
+ "dojo/_base/event", // event.stop
+ "dojo/keys", // keys.ENTER
+ "dojo/_base/lang",
+ "dojo/sniff", // has("ie") has("mozilla") has("webkit")
+ "dojo/_base/window", // win.withGlobal
+ "dojo/window", // winUtils.scrollIntoView
+ "../_Plugin",
+ "../RichText",
+ "../range",
+ "../../_base/focus"
+], function(declare, domConstruct, event, keys, lang, has, win, winUtils, _Plugin, RichText, rangeapi, baseFocus){
+
+// module:
+// dijit/_editor/plugins/EnterKeyHandling
+
+return declare("dijit._editor.plugins.EnterKeyHandling", _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:
+ //
+ // - blockNodeForEnter=BR
+ // - blockNodeForEnter=DIV
+ // - blockNodeForEnter=P
+ //
+ // In blockNodeForEnter=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();
+ }
+ lang.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.then(lang.hitch(this,function(d){
+ this.connect(editor.document, "onkeypress", function(e){
+ if(e.charOrCode == keys.ENTER){
+ // Just do it manually. The handleEnterKey has a shift mode that
+ // Always acts like <br>, so just use it.
+ var ne = lang.mixin({},e);
+ ne.shiftKey = true;
+ if(!this.handleEnterKey(ne)){
+ event.stop(e);
+ }
+ }
+ });
+ if(has("ie") >= 9){
+ this.connect(editor.document, "onpaste", function(e){
+ setTimeout(dojo.hitch(this, function(){
+ // Use the old range/selection code to kick IE 9 into updating
+ // its range by moving it back, then forward, one 'character'.
+ var r = this.editor.document.selection.createRange();
+ r.move('character',-1);
+ r.select();
+ r.move('character',1);
+ r.select();
+ }),0);
+ });
+ }
+ return d;
+ }));
+ }else if(this.blockNodeForEnter){
+ // add enter key handler
+ // FIXME: need to port to the new event code!!
+ var h = lang.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(){
+ // summary:
+ // Handler for keypress events.
+ // tags:
+ // private
+ if(this._checkListLater){
+ if(win.withGlobal(this.editor.window, 'isCollapsed', baseFocus)){
+ var liparent = this.editor._sCall('getAncestorElement', ['LI']);
+ if(!liparent){
+ // circulate the undo detection code by calling RichText::execCommand directly
+ RichText.prototype.execCommand.call(this.editor, 'formatblock',this.blockNodeForEnter);
+ // set the innerHTML of the new block node
+ var block = this.editor._sCall('getAncestorElement', [this.blockNodeForEnter]);
+ if(block){
+ block.innerHTML=this.bogusHtmlContent;
+ if(has("ie") <= 9){
+ // 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(has("mozilla")){
+ 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 = rangeapi.create(this.editor.window);
+ newrange.setStart(liparent.firstChild,0);
+ var selection = rangeapi.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: '&#160;', // &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 blockNodeForEnter 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 = this.editor._sCall('getParentElement', []);
+ var header = rangeapi.getAncestor(parent,this.blockNodes);
+ if(header){
+ if(header.tagName == 'LI'){
+ return true; // let browser handle
+ }
+ selection = rangeapi.getSelection(this.editor.window);
+ range = selection.getRangeAt(0);
+ if(!range.collapsed){
+ range.deleteContents();
+ selection = rangeapi.getSelection(this.editor.window);
+ range = selection.getRangeAt(0);
+ }
+ if(rangeapi.atBeginningOfContainer(header, range.startContainer, range.startOffset)){
+ br=doc.createElement('br');
+ newrange = rangeapi.create(this.editor.window);
+ header.insertBefore(br,header.firstChild);
+ newrange.setStartAfter(br);
+ selection.removeAllRanges();
+ selection.addRange(newrange);
+ }else if(rangeapi.atEndOfContainer(header, range.startContainer, range.startOffset)){
+ newrange = rangeapi.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;
+ startNode = doc.createTextNode(txt.substring(0, range.startOffset));
+ endNode = doc.createTextNode(txt.substring(range.startOffset));
+ brNode = doc.createElement("br");
+
+ if(endNode.nodeValue == "" && has("webkit")){
+ endNode = doc.createTextNode('\xA0')
+ }
+ domConstruct.place(startNode, rs, "after");
+ domConstruct.place(brNode, startNode, "after");
+ domConstruct.place(endNode, brNode, "after");
+ domConstruct.destroy(rs);
+ newrange = rangeapi.create(this.editor.window);
+ newrange.setStart(endNode,0);
+ selection.removeAllRanges();
+ selection.addRange(newrange);
+ return false;
+ }
+ return true; // let browser handle
+ }
+ }else{
+ selection = rangeapi.getSelection(this.editor.window);
+ if(selection.rangeCount){
+ range = selection.getRangeAt(0);
+ if(range && range.startContainer){
+ if(!range.collapsed){
+ range.deleteContents();
+ selection = rangeapi.getSelection(this.editor.window);
+ range = selection.getRangeAt(0);
+ }
+ rs = range.startContainer;
+ if(rs && rs.nodeType == 3){
+ // Text node, we have to split it.
+ 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){
+ domConstruct.place(startNode, rs, "after");
+ }else{
+ startNode = rs;
+ }
+ domConstruct.place(brNode, startNode, "after");
+ domConstruct.place(endNode, brNode, "after");
+ domConstruct.destroy(rs);
+ newrange = rangeapi.create(this.editor.window);
+ newrange.setStart(endNode,0);
+ newrange.setEnd(endNode, endNode.length);
+ selection.removeAllRanges();
+ selection.addRange(newrange);
+ if(endEmpty && !has("webkit")){
+ this.editor._sCall("remove", []);
+ }else{
+ this.editor._sCall("collapse", [true]);
+ }
+ }else{
+ var targetNode;
+ if(range.startOffset >= 0){
+ targetNode = rs.childNodes[range.startOffset];
+ }
+ var brNode = doc.createElement("br");
+ var endNode = doc.createTextNode('\xA0');
+ if(!targetNode){
+ rs.appendChild(brNode);
+ rs.appendChild(endNode);
+ }else{
+ domConstruct.place(brNode, targetNode, "before");
+ domConstruct.place(endNode, brNode, "after");
+ }
+ newrange = rangeapi.create(this.editor.window);
+ newrange.setStart(endNode,0);
+ newrange.setEnd(endNode, endNode.length);
+ selection.removeAllRanges();
+ selection.addRange(newrange);
+ this.editor._sCall("collapse", [true]);
+ }
+ }
+ }else{
+ // don't change this: do not call this.execCommand, as that may have other logic in subclass
+ RichText.prototype.execCommand.call(this.editor, 'inserthtml', '<br>');
+ }
+ }
+ return false;
+ }
+ var _letBrowserHandle = true;
+
+ // first remove selection
+ selection = rangeapi.getSelection(this.editor.window);
+ range = selection.getRangeAt(0);
+ if(!range.collapsed){
+ range.deleteContents();
+ selection = rangeapi.getSelection(this.editor.window);
+ range = selection.getRangeAt(0);
+ }
+
+ var block = rangeapi.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(has("mozilla")){
+ // 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;|&#160;|\xA0|<span\b[^>]*\bclass=['"]Apple-style-span['"][^>]*>(\s|&nbsp;|&#160;|\xA0)<\/span>)?(<br>)?$/.test(blockNode.innerHTML)){
+ // empty LI node
+ blockNode.innerHTML = '';
+ if(has("webkit")){ // WebKit tosses the range when innerHTML is reset
+ newrange = rangeapi.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{
+ 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: this.editor._sCall('getAncestorElement', [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 = rangeapi.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(rangeapi.atEndOfContainer(block.blockNode, node, endOffset)){
+ if(block.blockNode === block.blockContainer){
+ block.blockNode.appendChild(newblock);
+ }else{
+ domConstruct.place(newblock, block.blockNode, "after");
+ }
+ _letBrowserHandle = false;
+ // lets move caret to the newly created block
+ newrange = rangeapi.create(this.editor.window);
+ newrange.setStart(newblock, 0);
+ selection.removeAllRanges();
+ selection.addRange(newrange);
+ if(this.editor.height){
+ winUtils.scrollIntoView(newblock);
+ }
+ }else if(rangeapi.atBeginningOfContainer(block.blockNode,
+ range.startContainer, range.startOffset)){
+ domConstruct.place(newblock, block.blockNode, block.blockNode === block.blockContainer ? "first" : "before");
+ if(newblock.nextSibling && this.editor.height){
+ // position input caret - mostly WebKit needs this
+ newrange = rangeapi.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
+ winUtils.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{
+ domConstruct.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.
+ domConstruct.place(startNode, rs, "before");
+ domConstruct.place(endNode, rs, "after");
+ domConstruct.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;
+ }
+ domConstruct.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 = rangeapi.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){
+ winUtils.scrollIntoView(newblock);
+ }
+ if(has("mozilla")){
+ // 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){
+ winUtils.scrollIntoView(newblock);
+ }
+ if(has("mozilla")){
+ // 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;
+ }
+ return {"node": node, "offset": offset};
+ },
+
+ 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 : this.editor._sCall("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'){
+
+ domConstruct.destroy(para.lastChild);
+ }
+ }
+ if(!para.childNodes.length){
+ para.innerHTML=this.bogusHtmlContent;
+ }
+ }
+});
+
+});
diff --git a/lib/dijit/_editor/plugins/FontChoice.js b/lib/dijit/_editor/plugins/FontChoice.js
index 7e12ac008..f96894ad7 100644
--- a/lib/dijit/_editor/plugins/FontChoice.js
+++ b/lib/dijit/_editor/plugins/FontChoice.js
@@ -1,2 +1,2 @@
//>>built
-define("dijit/_editor/plugins/FontChoice",["dojo/_base/array","dojo/_base/declare","dojo/dom-construct","dojo/i18n","dojo/_base/lang","dojo/store/Memory","dojo/_base/window","../../registry","../../_Widget","../../_TemplatedMixin","../../_WidgetsInTemplateMixin","../../form/FilteringSelect","../_Plugin","../range","../selection","dojo/i18n!../nls/FontChoice"],function(_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c,_d,_e,_f){var _10=_2("dijit._editor.plugins._FontDropDown",[_9,_a,_b],{label:"",plainText:false,templateString:"<span style='white-space: nowrap' class='dijit dijitReset dijitInline'>"+"<label class='dijitLeft dijitInline' for='${selectId}'>${label}</label>"+"<input data-dojo-type='dijit.form.FilteringSelect' required='false' "+"data-dojo-props='labelType:\"html\", labelAttr:\"label\", searchAttr:\"name\"' "+"tabIndex='-1' id='${selectId}' data-dojo-attach-point='select' value=''/>"+"</span>",postMixInProperties:function(){this.inherited(arguments);this.strings=_4.getLocalization("dijit._editor","FontChoice");this.label=this.strings[this.command];this.id=_8.getUniqueId(this.declaredClass.replace(/\./g,"_"));this.selectId=this.id+"_select";this.inherited(arguments);},postCreate:function(){this.select.set("store",new _6({idProperty:"value",data:_1.map(this.values,function(_11){var _12=this.strings[_11]||_11;return {label:this.getLabel(_11,_12),name:_12,value:_11};},this)}));this.select.set("value","",false);this.disabled=this.select.get("disabled");},_setValueAttr:function(_13,_14){_14=_14!==false;this.select.set("value",_1.indexOf(this.values,_13)<0?"":_13,_14);if(!_14){this.select._lastValueReported=null;}},_getValueAttr:function(){return this.select.get("value");},focus:function(){this.select.focus();},_setDisabledAttr:function(_15){this.disabled=_15;this.select.set("disabled",_15);}});var _16=_2("dijit._editor.plugins._FontNameDropDown",_10,{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(_17,_18){if(this.plainText){return _18;}else{return "<div style='font-family: "+_17+"'>"+_18+"</div>";}},_setValueAttr:function(_19,_1a){_1a=_1a!==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","Estrangelo Edessa":"cursive","Gabriola":"fantasy"};_19=map[_19]||_19;}this.inherited(arguments,[_19,_1a]);}});var _1b=_2("dijit._editor.plugins._FontSizeDropDown",_10,{command:"fontSize",values:[1,2,3,4,5,6,7],getLabel:function(_1c,_1d){if(this.plainText){return _1d;}else{return "<font size="+_1c+"'>"+_1d+"</font>";}},_setValueAttr:function(_1e,_1f){_1f=_1f!==false;if(_1e.indexOf&&_1e.indexOf("px")!=-1){var _20=parseInt(_1e,10);_1e={10:1,13:2,16:3,18:4,24:5,32:6,48:7}[_20]||_1e;}this.inherited(arguments,[_1e,_1f]);}});var _21=_2("dijit._editor.plugins._FormatBlockDropDown",_10,{command:"formatBlock",values:["noFormat","p","h1","h2","h3","pre"],postCreate:function(){this.inherited(arguments);this.set("value","noFormat",false);},getLabel:function(_22,_23){if(this.plainText||_22=="noFormat"){return _23;}else{return "<"+_22+">"+_23+"</"+_22+">";}},_execCommand:function(_24,_25,_26){if(_26==="noFormat"){var _27;var end;var sel=_e.getSelection(_24.window);if(sel&&sel.rangeCount>0){var _28=sel.getRangeAt(0);var _29,tag;if(_28){_27=_28.startContainer;end=_28.endContainer;while(_27&&_27!==_24.editNode&&_27!==_24.document.body&&_27.nodeType!==1){_27=_27.parentNode;}while(end&&end!==_24.editNode&&end!==_24.document.body&&end.nodeType!==1){end=end.parentNode;}var _2a=_5.hitch(this,function(_2b,ary){if(_2b.childNodes&&_2b.childNodes.length){var i;for(i=0;i<_2b.childNodes.length;i++){var c=_2b.childNodes[i];if(c.nodeType==1){if(_7.withGlobal(_24.window,"inSelection",_f,[c])){var tag=c.tagName?c.tagName.toLowerCase():"";if(_1.indexOf(this.values,tag)!==-1){ary.push(c);}_2a(c,ary);}}}}});var _2c=_5.hitch(this,function(_2d){if(_2d&&_2d.length){_24.beginEditing();while(_2d.length){this._removeFormat(_24,_2d.pop());}_24.endEditing();}});var _2e=[];if(_27==end){var _2f;_29=_27;while(_29&&_29!==_24.editNode&&_29!==_24.document.body){if(_29.nodeType==1){tag=_29.tagName?_29.tagName.toLowerCase():"";if(_1.indexOf(this.values,tag)!==-1){_2f=_29;break;}}_29=_29.parentNode;}_2a(_27,_2e);if(_2f){_2e=[_2f].concat(_2e);}_2c(_2e);}else{_29=_27;while(_7.withGlobal(_24.window,"inSelection",_f,[_29])){if(_29.nodeType==1){tag=_29.tagName?_29.tagName.toLowerCase():"";if(_1.indexOf(this.values,tag)!==-1){_2e.push(_29);}_2a(_29,_2e);}_29=_29.nextSibling;}_2c(_2e);}_24.onDisplayChanged();}}}else{_24.execCommand(_25,_26);}},_removeFormat:function(_30,_31){if(_30.customUndo){while(_31.firstChild){_3.place(_31.firstChild,_31,"before");}_31.parentNode.removeChild(_31);}else{_7.withGlobal(_30.window,"selectElementChildren",_f,[_31]);var _32=_7.withGlobal(_30.window,"getSelectedHtml",_f,[null]);_7.withGlobal(_30.window,"selectElement",_f,[_31]);_30.execCommand("inserthtml",_32||"");}}});var _33=_2("dijit._editor.plugins.FontChoice",_d,{useDefaultCommand:false,_initButton:function(){var _34={fontName:_16,fontSize:_1b,formatBlock:_21}[this.command],_35=this.params;if(this.params.custom){_35.values=this.params.custom;}var _36=this.editor;this.button=new _34(_5.delegate({dir:_36.dir,lang:_36.lang},_35));this.connect(this.button.select,"onChange",function(_37){this.editor.focus();if(this.command=="fontName"&&_37.indexOf(" ")!=-1){_37="'"+_37+"'";}if(this.button._execCommand){this.button._execCommand(this.editor,this.command,_37);}else{this.editor.execCommand(this.command,_37);}});},updateState:function(){var _38=this.editor;var _39=this.command;if(!_38||!_38.isLoaded||!_39.length){return;}if(this.button){var _3a=this.get("disabled");this.button.set("disabled",_3a);if(_3a){return;}var _3b;try{_3b=_38.queryCommandValue(_39)||"";}catch(e){_3b="";}var _3c=_5.isString(_3b)&&_3b.match(/'([^']*)'/);if(_3c){_3b=_3c[1];}if(_39==="formatBlock"){if(!_3b||_3b=="p"){_3b=null;var _3d;var sel=_e.getSelection(this.editor.window);if(sel&&sel.rangeCount>0){var _3e=sel.getRangeAt(0);if(_3e){_3d=_3e.endContainer;}}while(_3d&&_3d!==_38.editNode&&_3d!==_38.document){var tg=_3d.tagName?_3d.tagName.toLowerCase():"";if(tg&&_1.indexOf(this.button.values,tg)>-1){_3b=tg;break;}_3d=_3d.parentNode;}if(!_3b){_3b="noFormat";}}else{if(_1.indexOf(this.button.values,_3b)<0){_3b="noFormat";}}}if(_3b!==this.button.get("value")){this.button.set("value",_3b,false);}}}});_1.forEach(["fontName","fontSize","formatBlock"],function(_3f){_d.registry[_3f]=function(_40){return new _33({command:_3f,plainText:_40.plainText});};});}); \ No newline at end of file
+define("dijit/_editor/plugins/FontChoice",["dojo/_base/array","dojo/_base/declare","dojo/dom-construct","dojo/i18n","dojo/_base/lang","dojo/store/Memory","../../registry","../../_Widget","../../_TemplatedMixin","../../_WidgetsInTemplateMixin","../../form/FilteringSelect","../_Plugin","../range","dojo/i18n!../nls/FontChoice"],function(_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c,_d){var _e=_2("dijit._editor.plugins._FontDropDown",[_8,_9,_a],{label:"",plainText:false,templateString:"<span style='white-space: nowrap' class='dijit dijitReset dijitInline'>"+"<label class='dijitLeft dijitInline' for='${selectId}'>${label}</label>"+"<input data-dojo-type='dijit.form.FilteringSelect' required='false' "+"data-dojo-props='labelType:\"html\", labelAttr:\"label\", searchAttr:\"name\"' "+"tabIndex='-1' id='${selectId}' data-dojo-attach-point='select' value=''/>"+"</span>",postMixInProperties:function(){this.inherited(arguments);this.strings=_4.getLocalization("dijit._editor","FontChoice");this.label=this.strings[this.command];this.id=_7.getUniqueId(this.declaredClass.replace(/\./g,"_"));this.selectId=this.id+"_select";this.inherited(arguments);},postCreate:function(){this.select.set("store",new _6({idProperty:"value",data:_1.map(this.values,function(_f){var _10=this.strings[_f]||_f;return {label:this.getLabel(_f,_10),name:_10,value:_f};},this)}));this.select.set("value","",false);this.disabled=this.select.get("disabled");},_setValueAttr:function(_11,_12){_12=_12!==false;this.select.set("value",_1.indexOf(this.values,_11)<0?"":_11,_12);if(!_12){this.select._lastValueReported=null;}},_getValueAttr:function(){return this.select.get("value");},focus:function(){this.select.focus();},_setDisabledAttr:function(_13){this.disabled=_13;this.select.set("disabled",_13);}});var _14=_2("dijit._editor.plugins._FontNameDropDown",_e,{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(_15,_16){if(this.plainText){return _16;}else{return "<div style='font-family: "+_15+"'>"+_16+"</div>";}},_setValueAttr:function(_17,_18){_18=_18!==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","Estrangelo Edessa":"cursive","Gabriola":"fantasy"};_17=map[_17]||_17;}this.inherited(arguments,[_17,_18]);}});var _19=_2("dijit._editor.plugins._FontSizeDropDown",_e,{command:"fontSize",values:[1,2,3,4,5,6,7],getLabel:function(_1a,_1b){if(this.plainText){return _1b;}else{return "<font size="+_1a+"'>"+_1b+"</font>";}},_setValueAttr:function(_1c,_1d){_1d=_1d!==false;if(_1c.indexOf&&_1c.indexOf("px")!=-1){var _1e=parseInt(_1c,10);_1c={10:1,13:2,16:3,18:4,24:5,32:6,48:7}[_1e]||_1c;}this.inherited(arguments,[_1c,_1d]);}});var _1f=_2("dijit._editor.plugins._FormatBlockDropDown",_e,{command:"formatBlock",values:["noFormat","p","h1","h2","h3","pre"],postCreate:function(){this.inherited(arguments);this.set("value","noFormat",false);},getLabel:function(_20,_21){if(this.plainText||_20=="noFormat"){return _21;}else{return "<"+_20+">"+_21+"</"+_20+">";}},_execCommand:function(_22,_23,_24){if(_24==="noFormat"){var _25;var end;var sel=_d.getSelection(_22.window);if(sel&&sel.rangeCount>0){var _26=sel.getRangeAt(0);var _27,tag;if(_26){_25=_26.startContainer;end=_26.endContainer;while(_25&&_25!==_22.editNode&&_25!==_22.document.body&&_25.nodeType!==1){_25=_25.parentNode;}while(end&&end!==_22.editNode&&end!==_22.document.body&&end.nodeType!==1){end=end.parentNode;}var _28=_5.hitch(this,function(_29,ary){if(_29.childNodes&&_29.childNodes.length){var i;for(i=0;i<_29.childNodes.length;i++){var c=_29.childNodes[i];if(c.nodeType==1){if(_22._sCall("inSelection",[c])){var tag=c.tagName?c.tagName.toLowerCase():"";if(_1.indexOf(this.values,tag)!==-1){ary.push(c);}_28(c,ary);}}}}});var _2a=_5.hitch(this,function(_2b){if(_2b&&_2b.length){_22.beginEditing();while(_2b.length){this._removeFormat(_22,_2b.pop());}_22.endEditing();}});var _2c=[];if(_25==end){var _2d;_27=_25;while(_27&&_27!==_22.editNode&&_27!==_22.document.body){if(_27.nodeType==1){tag=_27.tagName?_27.tagName.toLowerCase():"";if(_1.indexOf(this.values,tag)!==-1){_2d=_27;break;}}_27=_27.parentNode;}_28(_25,_2c);if(_2d){_2c=[_2d].concat(_2c);}_2a(_2c);}else{_27=_25;while(_22._sCall("inSelection",[_27])){if(_27.nodeType==1){tag=_27.tagName?_27.tagName.toLowerCase():"";if(_1.indexOf(this.values,tag)!==-1){_2c.push(_27);}_28(_27,_2c);}_27=_27.nextSibling;}_2a(_2c);}_22.onDisplayChanged();}}}else{_22.execCommand(_23,_24);}},_removeFormat:function(_2e,_2f){if(_2e.customUndo){while(_2f.firstChild){_3.place(_2f.firstChild,_2f,"before");}_2f.parentNode.removeChild(_2f);}else{_2e._sCall("selectElementChildren",[_2f]);var _30=_2e._sCall("getSelectedHtml",[]);_2e._sCall("selectElement",[_2f]);_2e.execCommand("inserthtml",_30||"");}}});var _31=_2("dijit._editor.plugins.FontChoice",_c,{useDefaultCommand:false,_initButton:function(){var _32={fontName:_14,fontSize:_19,formatBlock:_1f}[this.command],_33=this.params;if(this.params.custom){_33.values=this.params.custom;}var _34=this.editor;this.button=new _32(_5.delegate({dir:_34.dir,lang:_34.lang},_33));this.connect(this.button.select,"onChange",function(_35){this.editor.focus();if(this.command=="fontName"&&_35.indexOf(" ")!=-1){_35="'"+_35+"'";}if(this.button._execCommand){this.button._execCommand(this.editor,this.command,_35);}else{this.editor.execCommand(this.command,_35);}});},updateState:function(){var _36=this.editor;var _37=this.command;if(!_36||!_36.isLoaded||!_37.length){return;}if(this.button){var _38=this.get("disabled");this.button.set("disabled",_38);if(_38){return;}var _39;try{_39=_36.queryCommandValue(_37)||"";}catch(e){_39="";}var _3a=_5.isString(_39)&&_39.match(/'([^']*)'/);if(_3a){_39=_3a[1];}if(_37==="formatBlock"){if(!_39||_39=="p"){_39=null;var _3b;var sel=_d.getSelection(this.editor.window);if(sel&&sel.rangeCount>0){var _3c=sel.getRangeAt(0);if(_3c){_3b=_3c.endContainer;}}while(_3b&&_3b!==_36.editNode&&_3b!==_36.document){var tg=_3b.tagName?_3b.tagName.toLowerCase():"";if(tg&&_1.indexOf(this.button.values,tg)>-1){_39=tg;break;}_3b=_3b.parentNode;}if(!_39){_39="noFormat";}}else{if(_1.indexOf(this.button.values,_39)<0){_39="noFormat";}}}if(_39!==this.button.get("value")){this.button.set("value",_39,false);}}}});_1.forEach(["fontName","fontSize","formatBlock"],function(_3d){_c.registry[_3d]=function(_3e){return new _31({command:_3d,plainText:_3e.plainText});};});_31._FontDropDown=_e;_31._FontNameDropDown=_14;_31._FontSizeDropDown=_19;_31._FormatBlockDropDown=_1f;return _31;}); \ No newline at end of file
diff --git a/lib/dijit/_editor/plugins/FontChoice.js.uncompressed.js b/lib/dijit/_editor/plugins/FontChoice.js.uncompressed.js
new file mode 100644
index 000000000..713717351
--- /dev/null
+++ b/lib/dijit/_editor/plugins/FontChoice.js.uncompressed.js
@@ -0,0 +1,583 @@
+define("dijit/_editor/plugins/FontChoice", [
+ "dojo/_base/array", // array.indexOf array.map
+ "dojo/_base/declare", // declare
+ "dojo/dom-construct", // domConstruct.place
+ "dojo/i18n", // i18n.getLocalization
+ "dojo/_base/lang", // lang.delegate lang.hitch lang.isString
+ "dojo/store/Memory", // MemoryStore
+ "../../registry", // registry.getUniqueId
+ "../../_Widget",
+ "../../_TemplatedMixin",
+ "../../_WidgetsInTemplateMixin",
+ "../../form/FilteringSelect",
+ "../_Plugin",
+ "../range",
+ "dojo/i18n!../nls/FontChoice"
+], function(array, declare, domConstruct, i18n, lang, MemoryStore,
+ registry, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin, FilteringSelect, _Plugin, rangeapi){
+
+
+// module:
+// dijit/_editor/plugins/FontChoice
+
+
+var _FontDropDown = declare("dijit._editor.plugins._FontDropDown",
+ [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin], {
+ // 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: "",
+
+ // 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 data-dojo-type='dijit.form.FilteringSelect' required='false' " +
+ "data-dojo-props='labelType:\"html\", labelAttr:\"label\", searchAttr:\"name\"' " +
+ "tabIndex='-1' id='${selectId}' data-dojo-attach-point='select' value=''/>" +
+ "</span>",
+
+ postMixInProperties: function(){
+ // summary:
+ // Over-ride to set specific properties.
+ this.inherited(arguments);
+
+ this.strings = i18n.getLocalization("dijit._editor", "FontChoice");
+
+ // Set some substitution variables used in the template
+ this.label = this.strings[this.command];
+
+ // _WidgetBase sets the id after postMixInProperties(), but we need it now.
+ // Alternative is to have a buildRendering() method and move this.selectId setting there,
+ // or alternately get rid of selectId variable and just access ${id} in template?
+ this.id = registry.getUniqueId(this.declaredClass.replace(/\./g,"_"));
+
+ this.selectId = this.id + "_select"; // used in template
+
+ 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>" }
+ this.select.set("store", new MemoryStore({
+ idProperty: "value",
+ data: array.map(this.values, function(value){
+ var name = this.strings[value] || value;
+ return {
+ label: this.getLabel(value, name),
+ name: name,
+ value: value
+ };
+ }, this)
+ }));
+
+ 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;
+ this.select.set('value', array.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 retrieving 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 _FontNameDropDown = declare("dijit._editor.plugins._FontNameDropDown", _FontDropDown, {
+ // summary:
+ // Dropdown to select a font; goes in editor toolbar.
+
+ // generic: [const] 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;
+ 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",
+ "Estrangelo Edessa": "cursive", // Windows 7
+ "Gabriola": "fantasy" // Windows 7
+ };
+ value = map[value] || value;
+ }
+ this.inherited(arguments, [value, priorityChange]);
+ }
+});
+
+var _FontSizeDropDown = declare("dijit._editor.plugins._FontSizeDropDown", _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;
+ 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]);
+ }
+});
+
+
+var _FormatBlockDropDown = declare("dijit._editor.plugins._FormatBlockDropDown", _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 = rangeapi.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 = lang.hitch(this, function(node, ary){
+ 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(editor._sCall("inSelection", [c])){
+ var tag = c.tagName? c.tagName.toLowerCase(): "";
+ if(array.indexOf(this.values, tag) !== -1){
+ ary.push(c);
+ }
+ processChildren(c, ary);
+ }
+ }
+ }
+ }
+ });
+
+ var unformatNodes = lang.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(array.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(editor._sCall("inSelection", [node])){
+ if(node.nodeType == 1){
+ tag = node.tagName? node.tagName.toLowerCase(): "";
+ if(array.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){
+ domConstruct.place(node.firstChild, node, "before");
+ }
+ node.parentNode.removeChild(node);
+ }else{
+ // Everyone else works fine this way, a paste-over and is native
+ // undo friendly.
+ editor._sCall("selectElementChildren", [node])
+ var html = editor._sCall("getSelectedHtml", [])
+ editor._sCall("selectElement", [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)
+var FontChoice = declare("dijit._editor.plugins.FontChoice", _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', values:['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] Boolean
+ // 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: _FontNameDropDown,
+ fontSize: _FontSizeDropDown,
+ formatBlock: _FormatBlockDropDown
+ }[this.command],
+ params = this.params;
+
+ // For back-compat reasons support setting custom values via "custom" parameter
+ // rather than "values" parameter. Remove in 2.0.
+ if(this.params.custom){
+ params.values = this.params.custom;
+ }
+
+ var editor = this.editor;
+ this.button = new clazz(lang.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 = lang.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 = rangeapi.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 && array.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(array.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 these plugins
+array.forEach(["fontName", "fontSize", "formatBlock"], function(name){
+ _Plugin.registry[name] = function(args){
+ return new FontChoice({
+ command: name,
+ plainText: args.plainText
+ });
+ };
+});
+
+// Make all classes available through AMD, and return main class
+FontChoice._FontDropDown = _FontDropDown;
+FontChoice._FontNameDropDown = _FontNameDropDown;
+FontChoice._FontSizeDropDown = _FontSizeDropDown;
+FontChoice._FormatBlockDropDown = _FormatBlockDropDown;
+return FontChoice;
+
+});
diff --git a/lib/dijit/_editor/plugins/FullScreen.js b/lib/dijit/_editor/plugins/FullScreen.js
index 139f630dc..458dbf8b7 100644
--- a/lib/dijit/_editor/plugins/FullScreen.js
+++ b/lib/dijit/_editor/plugins/FullScreen.js
@@ -1,2 +1,2 @@
//>>built
-define("dijit/_editor/plugins/FullScreen",["dojo/aspect","dojo/_base/declare","dojo/dom-class","dojo/dom-geometry","dojo/dom-style","dojo/_base/event","dojo/i18n","dojo/keys","dojo/_base/lang","dojo/on","dojo/_base/sniff","dojo/_base/window","dojo/window","../../focus","../_Plugin","../../form/ToggleButton","../../registry","dojo/i18n!../nls/commands"],function(_1,_2,_3,_4,_5,_6,_7,_8,_9,on,_a,_b,_c,_d,_e,_f,_10){var _11=_2("dijit._editor.plugins.FullScreen",_e,{zIndex:500,_origState:null,_origiFrameState:null,_resizeHandle:null,isFullscreen:false,toggle:function(){this.button.set("checked",!this.button.get("checked"));},_initButton:function(){var _12=_7.getLocalization("dijit._editor","commands"),_13=this.editor;this.button=new _f({label:_12["fullScreen"],dir:_13.dir,lang:_13.lang,showLabel:false,iconClass:this.iconClassPrefix+" "+this.iconClassPrefix+"FullScreen",tabIndex:"-1",onChange:_9.hitch(this,"_setFullScreen")});},setEditor:function(_14){this.editor=_14;this._initButton();this.editor.addKeyHandler(_8.F11,true,true,_9.hitch(this,function(e){this.toggle();_6.stop(e);setTimeout(_9.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===_8.TAB){var f=_d.curNode;var avn=this._getAltViewNode();if(f==ed.iframe||(avn&&f===avn)){setTimeout(_9.hitch(this,function(){ed.toolbar.focus();}),10);}else{if(avn&&_5.get(ed.iframe,"display")==="none"){setTimeout(_9.hitch(this,function(){_d.focus(avn);}),10);}else{setTimeout(_9.hitch(this,function(){ed.focus();}),10);}}_6.stop(e);}else{if(ed._fullscreen_oldOnKeyDown){ed._fullscreen_oldOnKeyDown(e);}}}},_resizeEditor:function(){var vp=_c.getBox();_4.setMarginBox(this.editor.domNode,{w:vp.w,h:vp.h});var _15=this.editor.getHeaderHeight();var _16=this.editor.getFooterHeight();var _17=_4.getPadBorderExtents(this.editor.domNode);var _18=_4.getPadBorderExtents(this.editor.iframe.parentNode);var _19=_4.getMarginExtents(this.editor.iframe.parentNode);var _1a=vp.h-(_15+_17.h+_16);_4.setMarginBox(this.editor.iframe.parentNode,{h:_1a,w:vp.w});_4.setMarginBox(this.editor.iframe,{h:_1a-(_18.h+_19.h)});},_getAltViewNode:function(){},_setFullScreen:function(_1b){var vp=_c.getBox();var ed=this.editor;var _1c=_b.body();var _1d=ed.domNode.parentNode;this.isFullscreen=_1b;if(_1b){while(_1d&&_1d!==_b.body()){_3.add(_1d,"dijitForceStatic");_1d=_1d.parentNode;}this._editorResizeHolder=this.editor.resize;ed.resize=function(){};ed._fullscreen_oldOnKeyDown=ed.onKeyDown;ed.onKeyDown=_9.hitch(this,this._containFocus);this._origState={};this._origiFrameState={};var _1e=ed.domNode,_1f=_1e&&_1e.style||{};this._origState={width:_1f.width||"",height:_1f.height||"",top:_5.get(_1e,"top")||"",left:_5.get(_1e,"left")||"",position:_5.get(_1e,"position")||"static",marginBox:_4.getMarginBox(ed.domNode)};var _20=ed.iframe,_21=_20&&_20.style||{};var bc=_5.get(ed.iframe,"backgroundColor");this._origiFrameState={backgroundColor:bc||"transparent",width:_21.width||"auto",height:_21.height||"auto",zIndex:_21.zIndex||""};_5.set(ed.domNode,{position:"absolute",top:"0px",left:"0px",zIndex:this.zIndex,width:vp.w+"px",height:vp.h+"px"});_5.set(ed.iframe,{height:"100%",width:"100%",zIndex:this.zIndex,backgroundColor:bc!=="transparent"&&bc!=="rgba(0, 0, 0, 0)"?bc:"white"});_5.set(ed.iframe.parentNode,{height:"95%",width:"100%"});if(_1c.style&&_1c.style.overflow){this._oldOverflow=_5.get(_1c,"overflow");}else{this._oldOverflow="";}if(_a("ie")&&!_a("quirks")){if(_1c.parentNode&&_1c.parentNode.style&&_1c.parentNode.style.overflow){this._oldBodyParentOverflow=_1c.parentNode.style.overflow;}else{try{this._oldBodyParentOverflow=_5.get(_1c.parentNode,"overflow");}catch(e){this._oldBodyParentOverflow="scroll";}}_5.set(_1c.parentNode,"overflow","hidden");}_5.set(_1c,"overflow","hidden");var _22=function(){var vp=_c.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(_9.hitch(this,function(){delete this._resizer;this._resizeEditor();}),10);};this._resizeHandle=on(window,"resize",_9.hitch(this,_22));this._resizeHandle2=_1.after(ed,"onResize",_9.hitch(this,function(){if(this._resizer){clearTimeout(this._resizer);delete this._resizer;}this._resizer=setTimeout(_9.hitch(this,function(){delete this._resizer;this._resizeEditor();}),10);}));this._resizeEditor();var dn=this.editor.toolbar.domNode;setTimeout(function(){_c.scrollIntoView(dn);},250);}else{if(this._resizeHandle){this._resizeHandle.remove();this._resizeHandle=null;}if(this._resizeHandle2){this._resizeHandle2.remove();this._resizeHandle2=null;}if(this._rst){clearTimeout(this._rst);this._rst=null;}while(_1d&&_1d!==_b.body()){_3.remove(_1d,"dijitForceStatic");_1d=_1d.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 _23=this;setTimeout(function(){var mb=_23._origState.marginBox;var oh=_23._origState.height;if(_a("ie")&&!_a("quirks")){_1c.parentNode.style.overflow=_23._oldBodyParentOverflow;delete _23._oldBodyParentOverflow;}_5.set(_1c,"overflow",_23._oldOverflow);delete _23._oldOverflow;_5.set(ed.domNode,_23._origState);_5.set(ed.iframe.parentNode,{height:"",width:""});_5.set(ed.iframe,_23._origiFrameState);delete _23._origState;delete _23._origiFrameState;var _24=_10.getEnclosingWidget(ed.domNode.parentNode);if(_24&&_24.resize){_24.resize();}else{if(!oh||oh.indexOf("%")<0){setTimeout(_9.hitch(this,function(){ed.resize({h:mb.h});}),0);}}_c.scrollIntoView(_23.editor.toolbar.domNode);},100);}},updateState:function(){this.button.set("disabled",this.get("disabled"));},destroy:function(){if(this._resizeHandle){this._resizeHandle.remove();this._resizeHandle=null;}if(this._resizeHandle2){this._resizeHandle2.remove();this._resizeHandle2=null;}if(this._resizer){clearTimeout(this._resizer);this._resizer=null;}this.inherited(arguments);}});_e.registry["fullScreen"]=_e.registry["fullscreen"]=function(_25){return new _11({zIndex:("zIndex" in _25)?_25.zIndex:500});};return _11;}); \ No newline at end of file
+define("dijit/_editor/plugins/FullScreen",["dojo/aspect","dojo/_base/declare","dojo/dom-class","dojo/dom-geometry","dojo/dom-style","dojo/_base/event","dojo/i18n","dojo/keys","dojo/_base/lang","dojo/on","dojo/sniff","dojo/_base/window","dojo/window","../../focus","../_Plugin","../../form/ToggleButton","../../registry","dojo/i18n!../nls/commands"],function(_1,_2,_3,_4,_5,_6,_7,_8,_9,on,_a,_b,_c,_d,_e,_f,_10){var _11=_2("dijit._editor.plugins.FullScreen",_e,{zIndex:500,_origState:null,_origiFrameState:null,_resizeHandle:null,isFullscreen:false,toggle:function(){this.button.set("checked",!this.button.get("checked"));},_initButton:function(){var _12=_7.getLocalization("dijit._editor","commands"),_13=this.editor;this.button=new _f({label:_12["fullScreen"],ownerDocument:_13.ownerDocument,dir:_13.dir,lang:_13.lang,showLabel:false,iconClass:this.iconClassPrefix+" "+this.iconClassPrefix+"FullScreen",tabIndex:"-1",onChange:_9.hitch(this,"_setFullScreen")});},setEditor:function(_14){this.editor=_14;this._initButton();this.editor.addKeyHandler(_8.F11,true,true,_9.hitch(this,function(e){this.toggle();_6.stop(e);setTimeout(_9.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===_8.TAB){var f=_d.curNode;var avn=this._getAltViewNode();if(f==ed.iframe||(avn&&f===avn)){setTimeout(_9.hitch(this,function(){ed.toolbar.focus();}),10);}else{if(avn&&_5.get(ed.iframe,"display")==="none"){setTimeout(_9.hitch(this,function(){_d.focus(avn);}),10);}else{setTimeout(_9.hitch(this,function(){ed.focus();}),10);}}_6.stop(e);}else{if(ed._fullscreen_oldOnKeyDown){ed._fullscreen_oldOnKeyDown(e);}}}},_resizeEditor:function(){var vp=_c.getBox(this.editor.ownerDocument);_4.setMarginBox(this.editor.domNode,{w:vp.w,h:vp.h});var _15=this.editor.getHeaderHeight();var _16=this.editor.getFooterHeight();var _17=_4.getPadBorderExtents(this.editor.domNode);var _18=_4.getPadBorderExtents(this.editor.iframe.parentNode);var _19=_4.getMarginExtents(this.editor.iframe.parentNode);var _1a=vp.h-(_15+_17.h+_16);_4.setMarginBox(this.editor.iframe.parentNode,{h:_1a,w:vp.w});_4.setMarginBox(this.editor.iframe,{h:_1a-(_18.h+_19.h)});},_getAltViewNode:function(){},_setFullScreen:function(_1b){var ed=this.editor;var _1c=ed.ownerDocumentBody;var _1d=ed.domNode.parentNode;var vp=_c.getBox(ed.ownerDocument);this.isFullscreen=_1b;if(_1b){while(_1d&&_1d!==_1c){_3.add(_1d,"dijitForceStatic");_1d=_1d.parentNode;}this._editorResizeHolder=this.editor.resize;ed.resize=function(){};ed._fullscreen_oldOnKeyDown=ed.onKeyDown;ed.onKeyDown=_9.hitch(this,this._containFocus);this._origState={};this._origiFrameState={};var _1e=ed.domNode,_1f=_1e&&_1e.style||{};this._origState={width:_1f.width||"",height:_1f.height||"",top:_5.get(_1e,"top")||"",left:_5.get(_1e,"left")||"",position:_5.get(_1e,"position")||"static",marginBox:_4.getMarginBox(ed.domNode)};var _20=ed.iframe,_21=_20&&_20.style||{};var bc=_5.get(ed.iframe,"backgroundColor");this._origiFrameState={backgroundColor:bc||"transparent",width:_21.width||"auto",height:_21.height||"auto",zIndex:_21.zIndex||""};_5.set(ed.domNode,{position:"absolute",top:"0px",left:"0px",zIndex:this.zIndex,width:vp.w+"px",height:vp.h+"px"});_5.set(ed.iframe,{height:"100%",width:"100%",zIndex:this.zIndex,backgroundColor:bc!=="transparent"&&bc!=="rgba(0, 0, 0, 0)"?bc:"white"});_5.set(ed.iframe.parentNode,{height:"95%",width:"100%"});if(_1c.style&&_1c.style.overflow){this._oldOverflow=_5.get(_1c,"overflow");}else{this._oldOverflow="";}if(_a("ie")&&!_a("quirks")){if(_1c.parentNode&&_1c.parentNode.style&&_1c.parentNode.style.overflow){this._oldBodyParentOverflow=_1c.parentNode.style.overflow;}else{try{this._oldBodyParentOverflow=_5.get(_1c.parentNode,"overflow");}catch(e){this._oldBodyParentOverflow="scroll";}}_5.set(_1c.parentNode,"overflow","hidden");}_5.set(_1c,"overflow","hidden");var _22=function(){var vp=_c.getBox(ed.ownerDocument);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(_9.hitch(this,function(){delete this._resizer;this._resizeEditor();}),10);};this._resizeHandle=on(window,"resize",_9.hitch(this,_22));this._resizeHandle2=_1.after(ed,"onResize",_9.hitch(this,function(){if(this._resizer){clearTimeout(this._resizer);delete this._resizer;}this._resizer=setTimeout(_9.hitch(this,function(){delete this._resizer;this._resizeEditor();}),10);}));this._resizeEditor();var dn=this.editor.toolbar.domNode;setTimeout(function(){_c.scrollIntoView(dn);},250);}else{if(this._resizeHandle){this._resizeHandle.remove();this._resizeHandle=null;}if(this._resizeHandle2){this._resizeHandle2.remove();this._resizeHandle2=null;}if(this._rst){clearTimeout(this._rst);this._rst=null;}while(_1d&&_1d!==_1c){_3.remove(_1d,"dijitForceStatic");_1d=_1d.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 _23=this;setTimeout(function(){var mb=_23._origState.marginBox;var oh=_23._origState.height;if(_a("ie")&&!_a("quirks")){_1c.parentNode.style.overflow=_23._oldBodyParentOverflow;delete _23._oldBodyParentOverflow;}_5.set(_1c,"overflow",_23._oldOverflow);delete _23._oldOverflow;_5.set(ed.domNode,_23._origState);_5.set(ed.iframe.parentNode,{height:"",width:""});_5.set(ed.iframe,_23._origiFrameState);delete _23._origState;delete _23._origiFrameState;var _24=_10.getEnclosingWidget(ed.domNode.parentNode);if(_24&&_24.resize){_24.resize();}else{if(!oh||oh.indexOf("%")<0){setTimeout(_9.hitch(this,function(){ed.resize({h:mb.h});}),0);}}_c.scrollIntoView(_23.editor.toolbar.domNode);},100);}},updateState:function(){this.button.set("disabled",this.get("disabled"));},destroy:function(){if(this._resizeHandle){this._resizeHandle.remove();this._resizeHandle=null;}if(this._resizeHandle2){this._resizeHandle2.remove();this._resizeHandle2=null;}if(this._resizer){clearTimeout(this._resizer);this._resizer=null;}this.inherited(arguments);}});_e.registry["fullScreen"]=_e.registry["fullscreen"]=function(_25){return new _11({zIndex:("zIndex" in _25)?_25.zIndex:500});};return _11;}); \ No newline at end of file
diff --git a/lib/dijit/_editor/plugins/FullScreen.js.uncompressed.js b/lib/dijit/_editor/plugins/FullScreen.js.uncompressed.js
new file mode 100644
index 000000000..68f27954b
--- /dev/null
+++ b/lib/dijit/_editor/plugins/FullScreen.js.uncompressed.js
@@ -0,0 +1,450 @@
+define("dijit/_editor/plugins/FullScreen", [
+ "dojo/aspect",
+ "dojo/_base/declare", // declare
+ "dojo/dom-class", // domClass.add domClass.remove
+ "dojo/dom-geometry",
+ "dojo/dom-style",
+ "dojo/_base/event", // event.stop
+ "dojo/i18n", // i18n.getLocalization
+ "dojo/keys", // keys.F11 keys.TAB
+ "dojo/_base/lang", // lang.hitch
+ "dojo/on", // on()
+ "dojo/sniff", // has("ie"), has("quirks")
+ "dojo/_base/window", // win.body
+ "dojo/window", // winUtils.getBox winUtils.scrollIntoView
+ "../../focus", // focus.focus(), focus.curNode
+ "../_Plugin",
+ "../../form/ToggleButton",
+ "../../registry", // registry.getEnclosingWidget()
+ "dojo/i18n!../nls/commands"
+], function(aspect, declare, domClass, domGeometry, domStyle, event, i18n, keys, lang, on, has, win, winUtils,
+ focus, _Plugin, ToggleButton, registry){
+
+
+// module:
+// dijit/_editor/plugins/FullScreen
+
+
+var FullScreen = declare("dijit._editor.plugins.FullScreen",_Plugin,{
+ // summary:
+ // This plugin provides FullScreen capability 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 = i18n.getLocalization("dijit._editor", "commands"),
+ editor = this.editor;
+ this.button = new ToggleButton({
+ label: strings["fullScreen"],
+ ownerDocument: editor.ownerDocument,
+ dir: editor.dir,
+ lang: editor.lang,
+ showLabel: false,
+ iconClass: this.iconClassPrefix + " " + this.iconClassPrefix + "FullScreen",
+ tabIndex: "-1",
+ onChange: lang.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(keys.F11, true, true, lang.hitch(this, function(e){
+ // Enable the CTRL-SHIFT-F11 hotkey for fullscreen mode.
+ this.toggle();
+ event.stop(e);
+ setTimeout(lang.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 === 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 = focus.curNode;
+ var avn = this._getAltViewNode();
+ if(f == ed.iframe ||
+ (avn && f === avn)){
+ setTimeout(lang.hitch(this, function(){
+ ed.toolbar.focus();
+ }), 10);
+ }else{
+ if(avn && domStyle.get(ed.iframe, "display") === "none"){
+ setTimeout(lang.hitch(this, function(){
+ focus.focus(avn);
+ }), 10);
+ }else{
+ setTimeout(lang.hitch(this, function(){
+ ed.focus();
+ }), 10);
+ }
+ }
+ event.stop(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 = winUtils.getBox(this.editor.ownerDocument);
+ domGeometry.setMarginBox(this.editor.domNode, {
+ w: vp.w,
+ h: vp.h
+ });
+
+ //Adjust the internal heights too, as they can be a bit off.
+ var hHeight = this.editor.getHeaderHeight();
+ var fHeight = this.editor.getFooterHeight();
+ var extents = domGeometry.getPadBorderExtents(this.editor.domNode);
+ var fcpExtents = domGeometry.getPadBorderExtents(this.editor.iframe.parentNode);
+ var fcmExtents = domGeometry.getMarginExtents(this.editor.iframe.parentNode);
+
+ var cHeight = vp.h - (hHeight + extents.h + fHeight);
+ domGeometry.setMarginBox(this.editor.iframe.parentNode, {
+ h: cHeight,
+ w: vp.w
+ });
+ domGeometry.setMarginBox(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
+
+ //Alias this for shorter code.
+ var ed = this.editor;
+ var body = ed.ownerDocumentBody;
+ var editorParent = ed.domNode.parentNode;
+
+ var vp = winUtils.getBox(ed.ownerDocument);
+
+ this.isFullscreen = full;
+
+ if(full){
+ //Parent classes can royally screw up this plugin, so we
+ //have to set everything to position static.
+ while(editorParent && editorParent !== body){
+ domClass.add(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 = lang.hitch(this, this._containFocus);
+
+ this._origState = {};
+ this._origiFrameState = {};
+
+ // Store the basic editor state we have to restore later.
+ // Not using domStyle.get here, had problems, didn't
+ // give me stuff like 100%, gave me pixel calculated values.
+ // Need the exact original values.
+ var domNode = ed.domNode,
+ rawStyle = domNode && domNode.style || {};
+ this._origState = {
+ width: rawStyle.width || "",
+ height: rawStyle.height || "",
+ top: domStyle.get(domNode, "top") || "",
+ left: domStyle.get(domNode, "left") || "",
+ position: domStyle.get(domNode, "position") || "static",
+ marginBox: domGeometry.getMarginBox(ed.domNode)
+ };
+
+ // Store the iframe state we have to restore later.
+ // Not using domStyle.get 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 = domStyle.get(ed.iframe, "backgroundColor");
+ this._origiFrameState = {
+ backgroundColor: bc || "transparent",
+ width: iframeStyle.width || "auto",
+ height: iframeStyle.height || "auto",
+ zIndex: iframeStyle.zIndex || ""
+ };
+
+ // Okay, size everything.
+ domStyle.set(ed.domNode, {
+ position: "absolute",
+ top: "0px",
+ left: "0px",
+ zIndex: this.zIndex,
+ width: vp.w + "px",
+ height: vp.h + "px"
+ });
+
+ domStyle.set(ed.iframe, {
+ height: "100%",
+ width: "100%",
+ zIndex: this.zIndex,
+ backgroundColor: bc !== "transparent" &&
+ bc !== "rgba(0, 0, 0, 0)"?bc:"white"
+ });
+
+ domStyle.set(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 = domStyle.get(body, "overflow");
+ }else{
+ this._oldOverflow = "";
+ }
+
+ if(has("ie") && !has("quirks")){
+ // 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 = domStyle.get(body.parentNode, "overflow");
+ }catch(e){
+ this._oldBodyParentOverflow = "scroll";
+ }
+ }
+ domStyle.set(body.parentNode, "overflow", "hidden");
+ }
+ domStyle.set(body, "overflow", "hidden");
+
+ var resizer = function(){
+ // function to handle resize events.
+ // Will check current VP and only resize if
+ // different.
+ var vp = winUtils.getBox(ed.ownerDocument);
+ 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(lang.hitch(this, function(){
+ delete this._resizer;
+ this._resizeEditor();
+ }), 10);
+ };
+ this._resizeHandle = on(window, "resize", lang.hitch(this, resizer));
+
+ // Also monitor for direct calls to resize and adapt editor.
+ this._resizeHandle2 = aspect.after(ed, "onResize", lang.hitch(this, function(){
+ if(this._resizer){
+ clearTimeout(this._resizer);
+ delete this._resizer;
+ }
+ this._resizer = setTimeout(lang.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(){winUtils.scrollIntoView(dn);}, 250);
+ }else{
+ if(this._resizeHandle){
+ // Cleanup resizing listeners
+ this._resizeHandle.remove();
+ this._resizeHandle = null;
+ }
+ if(this._resizeHandle2){
+ // Cleanup resizing listeners
+ this._resizeHandle2.remove();
+ this._resizeHandle2 = null;
+ }
+ if(this._rst){
+ clearTimeout(this._rst);
+ this._rst = null;
+ }
+
+ //Remove all position static class assigns.
+ while(editorParent && editorParent !== body){
+ domClass.remove(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(has("ie") && !has("quirks")){
+ body.parentNode.style.overflow = self._oldBodyParentOverflow;
+ delete self._oldBodyParentOverflow;
+ }
+ domStyle.set(body, "overflow", self._oldOverflow);
+ delete self._oldOverflow;
+
+ domStyle.set(ed.domNode, self._origState);
+ domStyle.set(ed.iframe.parentNode, {
+ height: "",
+ width: ""
+ });
+ domStyle.set(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 = registry.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(lang.hitch(this, function(){ed.resize({h: mb.h});}), 0);
+ }
+ }
+ winUtils.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
+ this._resizeHandle.remove();
+ this._resizeHandle = null;
+ }
+ if(this._resizeHandle2){
+ // Cleanup resizing listeners
+ this._resizeHandle2.remove();
+ this._resizeHandle2 = null;
+ }
+ if(this._resizer){
+ clearTimeout(this._resizer);
+ this._resizer = null;
+ }
+ this.inherited(arguments);
+ }
+});
+
+// Register this plugin.
+// For back-compat accept "fullscreen" (all lowercase) too, remove in 2.0
+_Plugin.registry["fullScreen"] = _Plugin.registry["fullscreen"] = function(args){
+ return new FullScreen({
+ zIndex: ("zIndex" in args)?args.zIndex:500
+ });
+};
+
+return FullScreen;
+});
diff --git a/lib/dijit/_editor/plugins/LinkDialog.js b/lib/dijit/_editor/plugins/LinkDialog.js
index a70a9683c..f4fb0b56d 100644
--- a/lib/dijit/_editor/plugins/LinkDialog.js
+++ b/lib/dijit/_editor/plugins/LinkDialog.js
@@ -1,2 +1,2 @@
//>>built
-define("dijit/_editor/plugins/LinkDialog",["require","dojo/_base/declare","dojo/dom-attr","dojo/keys","dojo/_base/lang","dojo/_base/sniff","dojo/string","dojo/_base/window","../../_Widget","../_Plugin","../../form/DropDownButton","../range","../selection"],function(_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c,_d){var _e=_2("dijit._editor.plugins.LinkDialog",_a,{buttonClass:_b,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/]{0,}(?:\\?[^?#\\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:/^((([^\[:]+):)?([^@]+)@)?(\[([^\]]+)\]|([^\[:]*))(:([0-9]+))?$/,_userAtRxp:/^([!#-'*+\-\/-9=?A-Z^-~]+[.])*[!#-'*+\-\/-9=?A-Z^-~]+@/i,linkDialogTemplate:["<table><tr><td>","<label for='${id}_urlInput'>${url}</label>","</td><td>","<input data-dojo-type='dijit.form.ValidationTextBox' required='true' "+"id='${id}_urlInput' name='urlInput' data-dojo-props='intermediateChanges:true'/>","</td></tr><tr><td>","<label for='${id}_textInput'>${text}</label>","</td><td>","<input data-dojo-type='dijit.form.ValidationTextBox' required='true' id='${id}_textInput' "+"name='textInput' data-dojo-props='intermediateChanges:true'/>","</td></tr><tr><td>","<label for='${id}_targetSelect'>${target}</label>","</td><td>","<select id='${id}_targetSelect' name='targetSelect' data-dojo-type='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 data-dojo-type='dijit.form.Button' type='submit' id='${id}_setButton'>${set}</button>","<button data-dojo-type='dijit.form.Button' type='button' id='${id}_cancelButton'>${buttonCancel}</button>","</td></tr></table>"].join(""),_initButton:function(){this.inherited(arguments);this.button.loadDropDown=_5.hitch(this,"_loadDropDown");this._connectTagEvents();},_loadDropDown:function(_f){_1(["dojo/i18n","../../TooltipDialog","../../registry","../../form/Button","../../form/Select","../../form/ValidationTextBox","dojo/i18n!../../nls/common","dojo/i18n!../nls/LinkDialog"],_5.hitch(this,function(_10,_11,_12){var _13=this;this.tag=this.command=="insertImage"?"img":"a";var _14=_5.delegate(_10.getLocalization("dijit","common",this.lang),_10.getLocalization("dijit._editor","LinkDialog",this.lang));var _15=(this.dropDown=this.button.dropDown=new _11({title:_14[this.command+"Title"],execute:_5.hitch(this,"setValue"),onOpen:function(){_13._onOpenDialog();_11.prototype.onOpen.apply(this,arguments);},onCancel:function(){setTimeout(_5.hitch(_13,"_onCloseDialog"),0);}}));_14.urlRegExp=this.urlRegExp;_14.id=_12.getUniqueId(this.editor.id);this._uniqueId=_14.id;this._setContent(_15.title+"<div style='border-bottom: 1px black solid;padding-bottom:2pt;margin-bottom:4pt'></div>"+_7.substitute(this.linkDialogTemplate,_14));_15.startup();this._urlInput=_12.byId(this._uniqueId+"_urlInput");this._textInput=_12.byId(this._uniqueId+"_textInput");this._setButton=_12.byId(this._uniqueId+"_setButton");this.connect(_12.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");}this._urlRegExp=new RegExp("^"+this.urlRegExp+"$","i");this._emailRegExp=new RegExp("^"+this.emailRegExp+"$","i");this._urlInput.isValid=_5.hitch(this,function(){var _16=this._urlInput.get("value");return this._urlRegExp.test(_16)||this._emailRegExp.test(_16);});this.connect(_15.domNode,"onkeypress",function(e){if(e&&e.charOrCode==_4.ENTER&&!e.shiftKey&&!e.metaKey&&!e.ctrlKey&&!e.altKey){if(!this._setButton.get("disabled")){_15.onExecute();_15.execute(_15.get("value"));}}});_f();}));},_checkAndFixInput:function(){var _17=this;var url=this._urlInput.get("value");var _18=function(url){var _19=false;var _1a=false;if(url&&url.length>1){url=_5.trim(url);if(url.indexOf("mailto:")!==0){if(url.indexOf("/")>0){if(url.indexOf("://")===-1){if(url.charAt(0)!=="/"&&url.indexOf("./")!==0){if(_17._hostRxp.test(url)){_19=true;}}}}else{if(_17._userAtRxp.test(url)){_1a=true;}}}}if(_19){_17._urlInput.set("value","http://"+url);}if(_1a){_17._urlInput.set("value","mailto:"+url);}_17._setButton.set("disabled",!_17._isValid());};if(this._delayedCheck){clearTimeout(this._delayedCheck);this._delayedCheck=null;}this._delayedCheck=setTimeout(function(){_18(url);},250);},_connectTagEvents:function(){this.editor.onLoadDeferred.addCallback(_5.hitch(this,function(){this.connect(this.editor.editNode,"ondblclick",this._onDblClick);}));},_isValid:function(){return this._urlInput.isValid()&&this._textInput.isValid();},_setContent:function(_1b){this.dropDown.set({parserScope:"dojo",content:_1b});},_checkValues:function(_1c){if(_1c&&_1c.urlInput){_1c.urlInput=_1c.urlInput.replace(/"/g,"&quot;");}return _1c;},setValue:function(_1d){this._onCloseDialog();if(_6("ie")<9){var sel=_c.getSelection(this.editor.window);var _1e=sel.getRangeAt(0);var a=_1e.endContainer;if(a.nodeType===3){a=a.parentNode;}if(a&&(a.nodeName&&a.nodeName.toLowerCase()!==this.tag)){a=_8.withGlobal(this.editor.window,"getSelectedElement",_d,[this.tag]);}if(a&&(a.nodeName&&a.nodeName.toLowerCase()===this.tag)){if(this.editor.queryCommandEnabled("unlink")){_8.withGlobal(this.editor.window,"selectElementChildren",_d,[a]);this.editor.execCommand("unlink");}}}_1d=this._checkValues(_1d);this.editor.execCommand("inserthtml",_7.substitute(this.htmlTemplate,_1d));},_onCloseDialog:function(){this.editor.focus();},_getCurrentValues:function(a){var url,_1f,_20;if(a&&a.tagName.toLowerCase()===this.tag){url=a.getAttribute("_djrealurl")||a.getAttribute("href");_20=a.getAttribute("target")||"_self";_1f=a.textContent||a.innerText;_8.withGlobal(this.editor.window,"selectElement",_d,[a,true]);}else{_1f=_8.withGlobal(this.editor.window,_d.getSelectedText);}return {urlInput:url||"",textInput:_1f||"",targetSelect:_20||""};},_onOpenDialog:function(){var a;if(_6("ie")<9){var sel=_c.getSelection(this.editor.window);var _21=sel.getRangeAt(0);a=_21.endContainer;if(a.nodeType===3){a=a.parentNode;}if(a&&(a.nodeName&&a.nodeName.toLowerCase()!==this.tag)){a=_8.withGlobal(this.editor.window,"getSelectedElement",_d,[this.tag]);}}else{a=_8.withGlobal(this.editor.window,"getAncestorElement",_d,[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&&_3.get(t,"href")){var _22=this.editor;_8.withGlobal(_22.window,"selectElement",_d,[t]);_22.onDisplayChanged();if(_22._updateTimer){clearTimeout(_22._updateTimer);delete _22._updateTimer;}_22.onNormalizedDisplayChanged();var _23=this.button;setTimeout(function(){_23.set("disabled",false);_23.loadAndOpenDropDown().then(function(){if(_23.dropDown.focus){_23.dropDown.focus();}});},10);}}}});var _24=_2("dijit._editor.plugins.ImgLinkDialog",[_e],{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' data-dojo-props='intermediateChanges:true'/>","</td></tr><tr><td>","<label for='${id}_textInput'>${text}</label>","</td><td>","<input data-dojo-type='dijit.form.ValidationTextBox' required='false' id='${id}_textInput' "+"name='textInput' data-dojo-props='intermediateChanges:true'/>","</td></tr><tr><td>","</td><td>","</td></tr><tr><td colspan='2'>","<button data-dojo-type='dijit.form.Button' type='submit' id='${id}_setButton'>${set}</button>","<button data-dojo-type='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,_25;if(img&&img.tagName.toLowerCase()===this.tag){url=img.getAttribute("_djrealurl")||img.getAttribute("src");_25=img.getAttribute("alt");_8.withGlobal(this.editor.window,"selectElement",_d,[img,true]);}else{_25=_8.withGlobal(this.editor.window,_d.getSelectedText);}return {urlInput:url||"",textInput:_25||""};},_isValid:function(){return this._urlInput.isValid();},_connectTagEvents:function(){this.inherited(arguments);this.editor.onLoadDeferred.addCallback(_5.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){_8.withGlobal(this.editor.window,"selectElement",_d,[t]);}}},_checkValues:function(_26){if(_26&&_26.urlInput){_26.urlInput=_26.urlInput.replace(/"/g,"&quot;");}if(_26&&_26.textInput){_26.textInput=_26.textInput.replace(/"/g,"&quot;");}return _26;},_onDblClick:function(e){if(e&&e.target){var t=e.target;var tg=t.tagName?t.tagName.toLowerCase():"";if(tg===this.tag&&_3.get(t,"src")){var _27=this.editor;_8.withGlobal(_27.window,"selectElement",_d,[t]);_27.onDisplayChanged();if(_27._updateTimer){clearTimeout(_27._updateTimer);delete _27._updateTimer;}_27.onNormalizedDisplayChanged();var _28=this.button;setTimeout(function(){_28.set("disabled",false);_28.loadAndOpenDropDown().then(function(){if(_28.dropDown.focus){_28.dropDown.focus();}});},10);}}}});_a.registry["createLink"]=function(){return new _e({command:"createLink"});};_a.registry["insertImage"]=function(){return new _24({command:"insertImage"});};_e.ImgLinkDialog=_24;return _e;}); \ No newline at end of file
+define("dijit/_editor/plugins/LinkDialog",["require","dojo/_base/declare","dojo/dom-attr","dojo/keys","dojo/_base/lang","dojo/sniff","dojo/_base/query","dojo/string","../../_Widget","../_Plugin","../../form/DropDownButton","../range"],function(_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c){var _d=_2("dijit._editor.plugins.LinkDialog",_a,{buttonClass:_b,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/]{0,}(?:\\?[^?#\\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:/^((([^\[:]+):)?([^@]+)@)?(\[([^\]]+)\]|([^\[:]*))(:([0-9]+))?$/,_userAtRxp:/^([!#-'*+\-\/-9=?A-Z^-~]+[.])*[!#-'*+\-\/-9=?A-Z^-~]+@/i,linkDialogTemplate:["<table role='presentation'><tr><td>","<label for='${id}_urlInput'>${url}</label>","</td><td>","<input data-dojo-type='dijit.form.ValidationTextBox' required='true' "+"id='${id}_urlInput' name='urlInput' data-dojo-props='intermediateChanges:true'/>","</td></tr><tr><td>","<label for='${id}_textInput'>${text}</label>","</td><td>","<input data-dojo-type='dijit.form.ValidationTextBox' required='true' id='${id}_textInput' "+"name='textInput' data-dojo-props='intermediateChanges:true'/>","</td></tr><tr><td>","<label for='${id}_targetSelect'>${target}</label>","</td><td>","<select id='${id}_targetSelect' name='targetSelect' data-dojo-type='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 data-dojo-type='dijit.form.Button' type='submit' id='${id}_setButton'>${set}</button>","<button data-dojo-type='dijit.form.Button' type='button' id='${id}_cancelButton'>${buttonCancel}</button>","</td></tr></table>"].join(""),_initButton:function(){this.inherited(arguments);this.button.loadDropDown=_5.hitch(this,"_loadDropDown");this._connectTagEvents();},_loadDropDown:function(_e){_1(["dojo/i18n","../../TooltipDialog","../../registry","../../form/Button","../../form/Select","../../form/ValidationTextBox","dojo/i18n!../../nls/common","dojo/i18n!../nls/LinkDialog"],_5.hitch(this,function(_f,_10,_11){var _12=this;this.tag=this.command=="insertImage"?"img":"a";var _13=_5.delegate(_f.getLocalization("dijit","common",this.lang),_f.getLocalization("dijit._editor","LinkDialog",this.lang));var _14=(this.dropDown=this.button.dropDown=new _10({title:_13[this.command+"Title"],ownerDocument:this.editor.ownerDocument,dir:this.editor.dir,execute:_5.hitch(this,"setValue"),onOpen:function(){_12._onOpenDialog();_10.prototype.onOpen.apply(this,arguments);},onCancel:function(){setTimeout(_5.hitch(_12,"_onCloseDialog"),0);}}));_13.urlRegExp=this.urlRegExp;_13.id=_11.getUniqueId(this.editor.id);this._uniqueId=_13.id;this._setContent(_14.title+"<div style='border-bottom: 1px black solid;padding-bottom:2pt;margin-bottom:4pt'></div>"+_8.substitute(this.linkDialogTemplate,_13));_14.startup();this._urlInput=_11.byId(this._uniqueId+"_urlInput");this._textInput=_11.byId(this._uniqueId+"_textInput");this._setButton=_11.byId(this._uniqueId+"_setButton");this.connect(_11.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");}this._urlRegExp=new RegExp("^"+this.urlRegExp+"$","i");this._emailRegExp=new RegExp("^"+this.emailRegExp+"$","i");this._urlInput.isValid=_5.hitch(this,function(){var _15=this._urlInput.get("value");return this._urlRegExp.test(_15)||this._emailRegExp.test(_15);});this.connect(_14.domNode,"onkeypress",function(e){if(e&&e.charOrCode==_4.ENTER&&!e.shiftKey&&!e.metaKey&&!e.ctrlKey&&!e.altKey){if(!this._setButton.get("disabled")){_14.onExecute();_14.execute(_14.get("value"));}}});_e();}));},_checkAndFixInput:function(){var _16=this;var url=this._urlInput.get("value");var _17=function(url){var _18=false;var _19=false;if(url&&url.length>1){url=_5.trim(url);if(url.indexOf("mailto:")!==0){if(url.indexOf("/")>0){if(url.indexOf("://")===-1){if(url.charAt(0)!=="/"&&url.indexOf("./")&&url.indexOf("../")!==0){if(_16._hostRxp.test(url)){_18=true;}}}}else{if(_16._userAtRxp.test(url)){_19=true;}}}}if(_18){_16._urlInput.set("value","http://"+url);}if(_19){_16._urlInput.set("value","mailto:"+url);}_16._setButton.set("disabled",!_16._isValid());};if(this._delayedCheck){clearTimeout(this._delayedCheck);this._delayedCheck=null;}this._delayedCheck=setTimeout(function(){_17(url);},250);},_connectTagEvents:function(){this.editor.onLoadDeferred.then(_5.hitch(this,function(){this.connect(this.editor.editNode,"ondblclick",this._onDblClick);}));},_isValid:function(){return this._urlInput.isValid()&&this._textInput.isValid();},_setContent:function(_1a){this.dropDown.set({parserScope:"dojo",content:_1a});},_checkValues:function(_1b){if(_1b&&_1b.urlInput){_1b.urlInput=_1b.urlInput.replace(/"/g,"&quot;");}return _1b;},setValue:function(_1c){this._onCloseDialog();if(_6("ie")<9){var sel=_c.getSelection(this.editor.window);var _1d=sel.getRangeAt(0);var a=_1d.endContainer;if(a.nodeType===3){a=a.parentNode;}if(a&&(a.nodeName&&a.nodeName.toLowerCase()!==this.tag)){a=this.editor._sCall("getSelectedElement",[this.tag]);}if(a&&(a.nodeName&&a.nodeName.toLowerCase()===this.tag)){if(this.editor.queryCommandEnabled("unlink")){this.editor._sCall("selectElementChildren",[a]);this.editor.execCommand("unlink");}}}_1c=this._checkValues(_1c);this.editor.execCommand("inserthtml",_8.substitute(this.htmlTemplate,_1c));_7("a",this.editor.document).forEach(function(a){if(!a.innerHTML&&!_3.has(a,"name")){a.parentNode.removeChild(a);}},this);},_onCloseDialog:function(){this.editor.focus();},_getCurrentValues:function(a){var url,_1e,_1f;if(a&&a.tagName.toLowerCase()===this.tag){url=a.getAttribute("_djrealurl")||a.getAttribute("href");_1f=a.getAttribute("target")||"_self";_1e=a.textContent||a.innerText;this.editor._sCall("selectElement",[a,true]);}else{_1e=this.editor._sCall("getSelectedText");}return {urlInput:url||"",textInput:_1e||"",targetSelect:_1f||""};},_onOpenDialog:function(){var a,b,fc;if(_6("ie")){var sel=_c.getSelection(this.editor.window);if(sel.rangeCount){var _20=sel.getRangeAt(0);a=_20.endContainer;if(a.nodeType===3){a=a.parentNode;}if(a&&(a.nodeName&&a.nodeName.toLowerCase()!==this.tag)){a=this.editor._sCall("getSelectedElement",[this.tag]);}if(!a||(a.nodeName&&a.nodeName.toLowerCase()!==this.tag)){b=this.editor._sCall("getAncestorElement",[this.tag]);if(b&&(b.nodeName&&b.nodeName.toLowerCase()==this.tag)){a=b;this.editor._sCall("selectElement",[a]);}else{if(_20.startContainer===_20.endContainer){fc=_20.startContainer.firstChild;if(fc&&(fc.nodeName&&fc.nodeName.toLowerCase()==this.tag)){a=fc;this.editor._sCall("selectElement",[a]);}}}}}}else{a=this.editor._sCall("getAncestorElement",[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&&_3.get(t,"href")){var _21=this.editor;this.editor._sCall("selectElement",[t]);_21.onDisplayChanged();if(_21._updateTimer){_21._updateTimer.remove();delete _21._updateTimer;}_21.onNormalizedDisplayChanged();var _22=this.button;setTimeout(function(){_22.set("disabled",false);_22.loadAndOpenDropDown().then(function(){if(_22.dropDown.focus){_22.dropDown.focus();}});},10);}}}});var _23=_2("dijit._editor.plugins.ImgLinkDialog",[_d],{linkDialogTemplate:["<table role='presentation'><tr><td>","<label for='${id}_urlInput'>${url}</label>","</td><td>","<input dojoType='dijit.form.ValidationTextBox' regExp='${urlRegExp}' "+"required='true' id='${id}_urlInput' name='urlInput' data-dojo-props='intermediateChanges:true'/>","</td></tr><tr><td>","<label for='${id}_textInput'>${text}</label>","</td><td>","<input data-dojo-type='dijit.form.ValidationTextBox' required='false' id='${id}_textInput' "+"name='textInput' data-dojo-props='intermediateChanges:true'/>","</td></tr><tr><td>","</td><td>","</td></tr><tr><td colspan='2'>","<button data-dojo-type='dijit.form.Button' type='submit' id='${id}_setButton'>${set}</button>","<button data-dojo-type='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,_24;if(img&&img.tagName.toLowerCase()===this.tag){url=img.getAttribute("_djrealurl")||img.getAttribute("src");_24=img.getAttribute("alt");this.editor._sCall("selectElement",[img,true]);}else{_24=this.editor._sCall("getSelectedText",[]);}return {urlInput:url||"",textInput:_24||""};},_isValid:function(){return this._urlInput.isValid();},_connectTagEvents:function(){this.inherited(arguments);this.editor.onLoadDeferred.then(_5.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){this.editor._sCall("selectElement",[t]);}}},_checkValues:function(_25){if(_25&&_25.urlInput){_25.urlInput=_25.urlInput.replace(/"/g,"&quot;");}if(_25&&_25.textInput){_25.textInput=_25.textInput.replace(/"/g,"&quot;");}return _25;},_onDblClick:function(e){if(e&&e.target){var t=e.target;var tg=t.tagName?t.tagName.toLowerCase():"";if(tg===this.tag&&_3.get(t,"src")){var _26=this.editor;this.editor._sCall("selectElement",[t]);_26.onDisplayChanged();if(_26._updateTimer){_26._updateTimer.remove();delete _26._updateTimer;}_26.onNormalizedDisplayChanged();var _27=this.button;setTimeout(function(){_27.set("disabled",false);_27.loadAndOpenDropDown().then(function(){if(_27.dropDown.focus){_27.dropDown.focus();}});},10);}}}});_a.registry["createLink"]=function(){return new _d({command:"createLink"});};_a.registry["insertImage"]=function(){return new _23({command:"insertImage"});};_d.ImgLinkDialog=_23;return _d;}); \ No newline at end of file
diff --git a/lib/dijit/_editor/plugins/LinkDialog.js.uncompressed.js b/lib/dijit/_editor/plugins/LinkDialog.js.uncompressed.js
new file mode 100644
index 000000000..5ed6ce3da
--- /dev/null
+++ b/lib/dijit/_editor/plugins/LinkDialog.js.uncompressed.js
@@ -0,0 +1,609 @@
+define("dijit/_editor/plugins/LinkDialog", [
+ "require",
+ "dojo/_base/declare", // declare
+ "dojo/dom-attr", // domAttr.get
+ "dojo/keys", // keys.ENTER
+ "dojo/_base/lang", // lang.delegate lang.hitch lang.trim
+ "dojo/sniff", // has("ie")
+ "dojo/_base/query", // query
+ "dojo/string", // string.substitute
+ "../../_Widget",
+ "../_Plugin",
+ "../../form/DropDownButton",
+ "../range"
+], function(require, declare, domAttr, keys, lang, has, query, string,
+ _Widget, _Plugin, DropDownButton, rangeapi){
+
+
+// module:
+// dijit/_editor/plugins/LinkDialog
+// summary:
+// Editor plugins: LinkDialog (for inserting links) and ImgLinkDialog (for inserting images)
+
+
+var LinkDialog = declare("dijit._editor.plugins.LinkDialog", _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: 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: /^((([^\[:]+):)?([^@]+)@)?(\[([^\]]+)\]|([^\[:]*))(:([0-9]+))?$/,
+
+ // _userAtRxp [private] RegExp
+ // Regular expression used to validate e-mail address fragment.
+ _userAtRxp: /^([!#-'*+\-\/-9=?A-Z^-~]+[.])*[!#-'*+\-\/-9=?A-Z^-~]+@/i,
+
+ // linkDialogTemplate: [protected] String
+ // Template for contents of TooltipDialog to pick URL
+ linkDialogTemplate: [
+ "<table role='presentation'><tr><td>",
+ "<label for='${id}_urlInput'>${url}</label>",
+ "</td><td>",
+ "<input data-dojo-type='dijit.form.ValidationTextBox' required='true' " +
+ "id='${id}_urlInput' name='urlInput' data-dojo-props='intermediateChanges:true'/>",
+ "</td></tr><tr><td>",
+ "<label for='${id}_textInput'>${text}</label>",
+ "</td><td>",
+ "<input data-dojo-type='dijit.form.ValidationTextBox' required='true' id='${id}_textInput' " +
+ "name='textInput' data-dojo-props='intermediateChanges:true'/>",
+ "</td></tr><tr><td>",
+ "<label for='${id}_targetSelect'>${target}</label>",
+ "</td><td>",
+ "<select id='${id}_targetSelect' name='targetSelect' data-dojo-type='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 data-dojo-type='dijit.form.Button' type='submit' id='${id}_setButton'>${set}</button>",
+ "<button data-dojo-type='dijit.form.Button' type='button' id='${id}_cancelButton'>${buttonCancel}</button>",
+ "</td></tr></table>"
+ ].join(""),
+
+ _initButton: function(){
+ this.inherited(arguments);
+
+ // Setup to lazy create TooltipDialog first time the button is clicked
+ this.button.loadDropDown = lang.hitch(this, "_loadDropDown");
+
+ this._connectTagEvents();
+ },
+ _loadDropDown: function(callback){
+ // Called the first time the button is pressed. Initialize TooltipDialog.
+ require([
+ "dojo/i18n", // i18n.getLocalization
+ "../../TooltipDialog",
+ "../../registry", // registry.byId, registry.getUniqueId
+ "../../form/Button", // used by template
+ "../../form/Select", // used by template
+ "../../form/ValidationTextBox", // used by template
+ "dojo/i18n!../../nls/common",
+ "dojo/i18n!../nls/LinkDialog"
+ ], lang.hitch(this, function(i18n, TooltipDialog, registry){
+ var _this = this;
+ this.tag = this.command == 'insertImage' ? 'img' : 'a';
+ var messages = lang.delegate(i18n.getLocalization("dijit", "common", this.lang),
+ i18n.getLocalization("dijit._editor", "LinkDialog", this.lang));
+ var dropDown = (this.dropDown = this.button.dropDown = new TooltipDialog({
+ title: messages[this.command + "Title"],
+ ownerDocument: this.editor.ownerDocument,
+ dir: this.editor.dir,
+ execute: lang.hitch(this, "setValue"),
+ onOpen: function(){
+ _this._onOpenDialog();
+ TooltipDialog.prototype.onOpen.apply(this, arguments);
+ },
+ onCancel: function(){
+ setTimeout(lang.hitch(_this, "_onCloseDialog"),0);
+ }
+ }));
+ messages.urlRegExp = this.urlRegExp;
+ messages.id = registry.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>" +
+ string.substitute(this.linkDialogTemplate, messages));
+ dropDown.startup();
+ this._urlInput = registry.byId(this._uniqueId + "_urlInput");
+ this._textInput = registry.byId(this._uniqueId + "_textInput");
+ this._setButton = registry.byId(this._uniqueId + "_setButton");
+ this.connect(registry.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 = lang.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);
+ });
+
+ // Listen for enter and execute if valid.
+ this.connect(dropDown.domNode, "onkeypress", function(e){
+ if(e && e.charOrCode == keys.ENTER &&
+ !e.shiftKey && !e.metaKey && !e.ctrlKey && !e.altKey){
+ if(!this._setButton.get("disabled")){
+ dropDown.onExecute();
+ dropDown.execute(dropDown.get('value'));
+ }
+ }
+ });
+
+ callback();
+ }));
+ },
+
+ _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 = lang.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("./") && 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.then(lang.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(has("ie") < 9){ //see #4151
+ var sel = rangeapi.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)){
+ // Still nothing, one last thing to try on IE, as it might be 'img'
+ // and thus considered a control.
+ a = this.editor._sCall("getSelectedElement", [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 targeted 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 children, then unlink. The following insert will
+ // then replace the selected text.
+ this.editor._sCall("selectElementChildren", [a]);
+ this.editor.execCommand("unlink");
+ }
+ }
+ }
+ // make sure values are properly escaped, etc.
+ args = this._checkValues(args);
+ this.editor.execCommand('inserthtml',
+ string.substitute(this.htmlTemplate, args));
+
+ // IE sometimes leaves a blank link, so we need to fix it up.
+ // Go ahead and do this for everyone just to avoid blank links
+ // in the page.
+ query("a", this.editor.document).forEach(function(a){
+ if(!a.innerHTML && !domAttr.has(a, "name")){
+ // Remove empty anchors that do not have "name" set.
+ // Empty ones with a name set could be a hidden hash
+ // anchor.
+ a.parentNode.removeChild(a);
+ }
+ }, this);
+ },
+
+ _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;
+ this.editor._sCall("selectElement", [a, true]);
+ }else{
+ text = this.editor._sCall("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,b,fc;
+ if(has("ie")){
+ // IE, even IE10, is difficult to select the element in, using the range unified
+ // API seems to work reasonably well.
+ var sel = rangeapi.getSelection(this.editor.window);
+ if(sel.rangeCount){
+ 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)){
+ // Still nothing, one last thing to try on IE, as it might be 'img'
+ // and thus considered a control.
+ a = this.editor._sCall("getSelectedElement", [this.tag]);
+ }
+ if(!a || (a.nodeName && a.nodeName.toLowerCase() !== this.tag)){
+ // Try another lookup, IE's selection is just terrible.
+ b = this.editor._sCall("getAncestorElement", [this.tag]);
+ if(b && (b.nodeName && b.nodeName.toLowerCase() == this.tag)){
+ // Looks like we found an A tag, use it and make sure just it is
+ // selected.
+ a = b;
+ this.editor._sCall("selectElement", [a]);
+ }else if (range.startContainer === range.endContainer){
+ // STILL nothing. Trying one more thing. Lets look at the first child.
+ // It might be an anchor tag in a div by itself or the like. If it is,
+ // we'll use it otherwise we give up. The selection is not easily
+ // determinable to be on an existing anchor tag.
+ fc = range.startContainer.firstChild;
+ if(fc && (fc.nodeName && fc.nodeName.toLowerCase() == this.tag)){
+ a = fc;
+ this.editor._sCall("selectElement", [a]);
+ }
+ }
+ }
+ }
+ }else{
+ a = this.editor._sCall("getAncestorElement", [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 && domAttr.get(t,"href")){
+ var editor = this.editor;
+
+ this.editor._sCall("selectElement", [t]);
+ editor.onDisplayChanged();
+
+ // Call onNormalizedDisplayChange() now, rather than on timer.
+ // On IE, when focus goes to the first <input> in the TooltipDialog, the editor loses it's selection.
+ // Later if onNormalizedDisplayChange() gets called via the timer it will disable the LinkDialog button
+ // (actually, all the toolbar buttons), at which point clicking the <input> will close the dialog,
+ // since (for unknown reasons) focus.js ignores disabled controls.
+ if(editor._updateTimer){
+ editor._updateTimer.remove();
+ delete editor._updateTimer;
+ }
+ editor.onNormalizedDisplayChanged();
+
+ var button = this.button;
+ setTimeout(function(){
+ // Focus shift outside the event handler.
+ // IE doesn't like focus changes in event handles.
+ button.set("disabled", false);
+ button.loadAndOpenDropDown().then(function(){
+ if(button.dropDown.focus){
+ button.dropDown.focus();
+ }
+ });
+ }, 10);
+ }
+ }
+ }
+});
+
+var ImgLinkDialog = declare("dijit._editor.plugins.ImgLinkDialog", [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 role='presentation'><tr><td>",
+ "<label for='${id}_urlInput'>${url}</label>",
+ "</td><td>",
+ "<input dojoType='dijit.form.ValidationTextBox' regExp='${urlRegExp}' " +
+ "required='true' id='${id}_urlInput' name='urlInput' data-dojo-props='intermediateChanges:true'/>",
+ "</td></tr><tr><td>",
+ "<label for='${id}_textInput'>${text}</label>",
+ "</td><td>",
+ "<input data-dojo-type='dijit.form.ValidationTextBox' required='false' id='${id}_textInput' " +
+ "name='textInput' data-dojo-props='intermediateChanges:true'/>",
+ "</td></tr><tr><td>",
+ "</td><td>",
+ "</td></tr><tr><td colspan='2'>",
+ "<button data-dojo-type='dijit.form.Button' type='submit' id='${id}_setButton'>${set}</button>",
+ "<button data-dojo-type='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');
+ this.editor._sCall("selectElement", [img, true]);
+ }else{
+ text = this.editor._sCall("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.then(lang.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){
+ this.editor._sCall("selectElement", [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 && domAttr.get(t,"src")){
+ var editor = this.editor;
+
+ this.editor._sCall("selectElement", [t]);
+ editor.onDisplayChanged();
+
+ // Call onNormalizedDisplayChange() now, rather than on timer.
+ // On IE, when focus goes to the first <input> in the TooltipDialog, the editor loses it's selection.
+ // Later if onNormalizedDisplayChange() gets called via the timer it will disable the LinkDialog button
+ // (actually, all the toolbar buttons), at which point clicking the <input> will close the dialog,
+ // since (for unknown reasons) focus.js ignores disabled controls.
+ if(editor._updateTimer){
+ editor._updateTimer.remove();
+ delete editor._updateTimer;
+ }
+ editor.onNormalizedDisplayChanged();
+
+ var button = this.button;
+ setTimeout(function(){
+ // Focus shift outside the event handler.
+ // IE doesn't like focus changes in event handles.
+ button.set("disabled", false);
+ button.loadAndOpenDropDown().then(function(){
+ if(button.dropDown.focus){
+ button.dropDown.focus();
+ }
+ });
+ }, 10);
+ }
+ }
+ }
+});
+
+// Register these plugins
+_Plugin.registry["createLink"] = function(){
+ return new LinkDialog({command: "createLink"});
+};
+_Plugin.registry["insertImage"] = function(){
+ return new ImgLinkDialog({command: "insertImage"});
+};
+
+
+// Export both LinkDialog and ImgLinkDialog
+// TODO for 2.0: either return both classes in a hash, or split this file into two separate files.
+// Then the documentation for the module can be applied to the hash, and will show up in the API doc.
+LinkDialog.ImgLinkDialog = ImgLinkDialog;
+return LinkDialog;
+});
diff --git a/lib/dijit/_editor/plugins/NewPage.js b/lib/dijit/_editor/plugins/NewPage.js
index 911731a00..bdd07946e 100644
--- a/lib/dijit/_editor/plugins/NewPage.js
+++ b/lib/dijit/_editor/plugins/NewPage.js
@@ -1,2 +1,2 @@
//>>built
-define("dijit/_editor/plugins/NewPage",["dojo/_base/declare","dojo/i18n","dojo/_base/lang","../_Plugin","../../form/Button","dojo/i18n!../nls/commands"],function(_1,_2,_3,_4,_5){var _6=_1("dijit._editor.plugins.NewPage",_4,{content:"<br>",_initButton:function(){var _7=_2.getLocalization("dijit._editor","commands"),_8=this.editor;this.button=new _5({label:_7["newPage"],dir:_8.dir,lang:_8.lang,showLabel:false,iconClass:this.iconClassPrefix+" "+this.iconClassPrefix+"NewPage",tabIndex:"-1",onClick:_3.hitch(this,"_newPage")});},setEditor:function(_9){this.editor=_9;this._initButton();},updateState:function(){this.button.set("disabled",this.get("disabled"));},_newPage:function(){this.editor.beginEditing();this.editor.set("value",this.content);this.editor.endEditing();this.editor.focus();}});_4.registry["newPage"]=_4.registry["newpage"]=function(_a){return new _6({content:("content" in _a)?_a.content:"<br>"});};return _6;}); \ No newline at end of file
+define("dijit/_editor/plugins/NewPage",["dojo/_base/declare","dojo/i18n","dojo/_base/lang","../_Plugin","../../form/Button","dojo/i18n!../nls/commands"],function(_1,_2,_3,_4,_5){var _6=_1("dijit._editor.plugins.NewPage",_4,{content:"<br>",_initButton:function(){var _7=_2.getLocalization("dijit._editor","commands"),_8=this.editor;this.button=new _5({label:_7["newPage"],ownerDocument:_8.ownerDocument,dir:_8.dir,lang:_8.lang,showLabel:false,iconClass:this.iconClassPrefix+" "+this.iconClassPrefix+"NewPage",tabIndex:"-1",onClick:_3.hitch(this,"_newPage")});},setEditor:function(_9){this.editor=_9;this._initButton();},updateState:function(){this.button.set("disabled",this.get("disabled"));},_newPage:function(){this.editor.beginEditing();this.editor.set("value",this.content);this.editor.endEditing();this.editor.focus();}});_4.registry["newPage"]=_4.registry["newpage"]=function(_a){return new _6({content:("content" in _a)?_a.content:"<br>"});};return _6;}); \ No newline at end of file
diff --git a/lib/dijit/_editor/plugins/NewPage.js.uncompressed.js b/lib/dijit/_editor/plugins/NewPage.js.uncompressed.js
new file mode 100644
index 000000000..72b6f686a
--- /dev/null
+++ b/lib/dijit/_editor/plugins/NewPage.js.uncompressed.js
@@ -0,0 +1,77 @@
+define("dijit/_editor/plugins/NewPage", [
+ "dojo/_base/declare", // declare
+ "dojo/i18n", // i18n.getLocalization
+ "dojo/_base/lang", // lang.hitch
+ "../_Plugin",
+ "../../form/Button",
+ "dojo/i18n!../nls/commands"
+], function(declare, i18n, lang, _Plugin, Button){
+
+// module:
+// dijit/_editor/plugins/NewPage
+
+
+var NewPage = declare("dijit._editor.plugins.NewPage",_Plugin,{
+ // summary:
+ // This plugin provides a simple 'new page' capability. 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 = i18n.getLocalization("dijit._editor", "commands"),
+ editor = this.editor;
+ this.button = new Button({
+ label: strings["newPage"],
+ ownerDocument: editor.ownerDocument,
+ dir: editor.dir,
+ lang: editor.lang,
+ showLabel: false,
+ iconClass: this.iconClassPrefix + " " + this.iconClassPrefix + "NewPage",
+ tabIndex: "-1",
+ onClick: lang.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.
+// For back-compat accept "newpage" (all lowercase) too, remove in 2.0
+_Plugin.registry["newPage"] = _Plugin.registry["newpage"] = function(args){
+ return new NewPage({
+ content: ("content" in args)?args.content:"<br>"
+ });
+};
+
+return NewPage;
+});
diff --git a/lib/dijit/_editor/plugins/Print.js b/lib/dijit/_editor/plugins/Print.js
index 7de192d52..b8d83cb2b 100644
--- a/lib/dijit/_editor/plugins/Print.js
+++ b/lib/dijit/_editor/plugins/Print.js
@@ -1,2 +1,2 @@
//>>built
-define("dijit/_editor/plugins/Print",["dojo/_base/declare","dojo/i18n","dojo/_base/lang","dojo/_base/sniff","../../focus","../_Plugin","../../form/Button","dojo/i18n!../nls/commands"],function(_1,_2,_3,_4,_5,_6,_7){var _8=_1("dijit._editor.plugins.Print",_6,{_initButton:function(){var _9=_2.getLocalization("dijit._editor","commands"),_a=this.editor;this.button=new _7({label:_9["print"],dir:_a.dir,lang:_a.lang,showLabel:false,iconClass:this.iconClassPrefix+" "+this.iconClassPrefix+"Print",tabIndex:"-1",onClick:_3.hitch(this,"_print")});},setEditor:function(_b){this.editor=_b;this._initButton();this.editor.onLoadDeferred.addCallback(_3.hitch(this,function(){if(!this.editor.iframe.contentWindow["print"]){this.button.set("disabled",true);}}));},updateState:function(){var _c=this.get("disabled");if(!this.editor.iframe.contentWindow["print"]){_c=true;}this.button.set("disabled",_c);},_print:function(){var _d=this.editor.iframe;if(_d.contentWindow["print"]){if(!_4("opera")&&!_4("chrome")){_5.focus(_d);_d.contentWindow.print();}else{var _e=this.editor.document;var _f=this.editor.get("value");_f="<html><head><meta http-equiv='Content-Type' "+"content='text/html; charset='UTF-8'></head><body>"+_f+"</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(_f);win.document.close();var _10=_e.getElementsByTagName("style");if(_10){var i;for(i=0;i<_10.length;i++){var _11=_10[i].innerHTML;var _12=win.document.createElement("style");_12.appendChild(win.document.createTextNode(_11));win.document.getElementsByTagName("head")[0].appendChild(_12);}}win.print();win.close();}}}});_6.registry["print"]=function(){return new _8({command:"print"});};return _8;}); \ No newline at end of file
+define("dijit/_editor/plugins/Print",["dojo/_base/declare","dojo/i18n","dojo/_base/lang","dojo/sniff","../../focus","../_Plugin","../../form/Button","dojo/i18n!../nls/commands"],function(_1,_2,_3,_4,_5,_6,_7){var _8=_1("dijit._editor.plugins.Print",_6,{_initButton:function(){var _9=_2.getLocalization("dijit._editor","commands"),_a=this.editor;this.button=new _7({label:_9["print"],ownerDocument:_a.ownerDocument,dir:_a.dir,lang:_a.lang,showLabel:false,iconClass:this.iconClassPrefix+" "+this.iconClassPrefix+"Print",tabIndex:"-1",onClick:_3.hitch(this,"_print")});},setEditor:function(_b){this.editor=_b;this._initButton();this.editor.onLoadDeferred.then(_3.hitch(this,function(){if(!this.editor.iframe.contentWindow["print"]){this.button.set("disabled",true);}}));},updateState:function(){var _c=this.get("disabled");if(!this.editor.iframe.contentWindow["print"]){_c=true;}this.button.set("disabled",_c);},_print:function(){var _d=this.editor.iframe;if(_d.contentWindow["print"]){if(!_4("opera")&&!_4("chrome")){_5.focus(_d);_d.contentWindow.print();}else{var _e=this.editor.document;var _f=this.editor.get("value");_f="<html><head><meta http-equiv='Content-Type' "+"content='text/html; charset='UTF-8'></head><body>"+_f+"</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(_f);win.document.close();var _10=_e.getElementsByTagName("style");if(_10){var i;for(i=0;i<_10.length;i++){var _11=_10[i].innerHTML;var _12=win.document.createElement("style");_12.appendChild(win.document.createTextNode(_11));win.document.getElementsByTagName("head")[0].appendChild(_12);}}win.print();win.close();}}}});_6.registry["print"]=function(){return new _8({command:"print"});};return _8;}); \ No newline at end of file
diff --git a/lib/dijit/_editor/plugins/Print.js.uncompressed.js b/lib/dijit/_editor/plugins/Print.js.uncompressed.js
new file mode 100644
index 000000000..933633d24
--- /dev/null
+++ b/lib/dijit/_editor/plugins/Print.js.uncompressed.js
@@ -0,0 +1,123 @@
+define("dijit/_editor/plugins/Print", [
+ "dojo/_base/declare", // declare
+ "dojo/i18n", // i18n.getLocalization
+ "dojo/_base/lang", // lang.hitch
+ "dojo/sniff", // has("chrome") has("opera")
+ "../../focus", // focus.focus()
+ "../_Plugin",
+ "../../form/Button",
+ "dojo/i18n!../nls/commands"
+], function(declare, i18n, lang, has, focus, _Plugin, Button){
+
+// module:
+// dijit/_editor/plugins/Print
+
+
+var Print = declare("dijit._editor.plugins.Print",_Plugin,{
+ // summary:
+ // This plugin provides Print capability 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 = i18n.getLocalization("dijit._editor", "commands"),
+ editor = this.editor;
+ this.button = new Button({
+ label: strings["print"],
+ ownerDocument: editor.ownerDocument,
+ dir: editor.dir,
+ lang: editor.lang,
+ showLabel: false,
+ iconClass: this.iconClassPrefix + " " + this.iconClassPrefix + "Print",
+ tabIndex: "-1",
+ onClick: lang.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.then(
+ lang.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(!has("opera") && !has("chrome")){
+ focus.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 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.
+_Plugin.registry["print"] = function(){
+ return new Print({command: "print"});
+};
+
+
+return Print;
+});
diff --git a/lib/dijit/_editor/plugins/TabIndent.js.uncompressed.js b/lib/dijit/_editor/plugins/TabIndent.js.uncompressed.js
new file mode 100644
index 000000000..3cd0a136b
--- /dev/null
+++ b/lib/dijit/_editor/plugins/TabIndent.js.uncompressed.js
@@ -0,0 +1,60 @@
+define("dijit/_editor/plugins/TabIndent", [
+ "dojo/_base/declare", // declare
+ "dojo/_base/kernel", // kernel.experimental
+ "../_Plugin",
+ "../../form/ToggleButton"
+], function(declare, kernel, _Plugin, ToggleButton){
+
+ // module:
+ // dijit/_editor/plugins/TabIndent
+
+ kernel.experimental("dijit._editor.plugins.TabIndent");
+
+
+ var TabIndent = declare("dijit._editor.plugins.TabIndent", _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: 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.
+ _Plugin.registry["tabIndent"] = function(){
+ return new TabIndent({command: "tabIndent"});
+ };
+
+
+ return TabIndent;
+});
diff --git a/lib/dijit/_editor/plugins/TextColor.js b/lib/dijit/_editor/plugins/TextColor.js
index c7943d640..7aa50cd51 100644
--- a/lib/dijit/_editor/plugins/TextColor.js
+++ b/lib/dijit/_editor/plugins/TextColor.js
@@ -1,2 +1,2 @@
//>>built
-define("dijit/_editor/plugins/TextColor",["require","dojo/colors","dojo/_base/declare","dojo/_base/lang","../_Plugin","../../form/DropDownButton"],function(_1,_2,_3,_4,_5,_6){var _7=_3("dijit._editor.plugins.TextColor",_5,{buttonClass:_6,useDefaultCommand:false,_initButton:function(){this.inherited(arguments);var _8=this;this.button.loadDropDown=function(_9){_1(["../../ColorPalette"],_4.hitch(this,function(_a){this.dropDown=new _a({value:_8.value,onChange:function(_b){_8.editor.execCommand(_8.command,_b);}});_9();}));};},updateState:function(){var _c=this.editor;var _d=this.command;if(!_c||!_c.isLoaded||!_d.length){return;}if(this.button){var _e=this.get("disabled");this.button.set("disabled",_e);if(_e){return;}var _f;try{_f=_c.queryCommandValue(_d)||"";}catch(e){_f="";}}if(_f==""){_f="#000000";}if(_f=="transparent"){_f="#ffffff";}if(typeof _f=="string"){if(_f.indexOf("rgb")>-1){_f=_2.fromRgb(_f).toHex();}}else{_f=((_f&255)<<16)|(_f&65280)|((_f&16711680)>>>16);_f=_f.toString(16);_f="#000000".slice(0,7-_f.length)+_f;}this.value=_f;var _10=this.button.dropDown;if(_10&&_f!==_10.get("value")){_10.set("value",_f,false);}}});_5.registry["foreColor"]=function(){return new _7({command:"foreColor"});};_5.registry["hiliteColor"]=function(){return new _7({command:"hiliteColor"});};return _7;}); \ No newline at end of file
+define("dijit/_editor/plugins/TextColor",["require","dojo/colors","dojo/_base/declare","dojo/_base/lang","../_Plugin","../../form/DropDownButton"],function(_1,_2,_3,_4,_5,_6){var _7=_3("dijit._editor.plugins.TextColor",_5,{buttonClass:_6,useDefaultCommand:false,_initButton:function(){this.inherited(arguments);var _8=this;this.button.loadDropDown=function(_9){_1(["../../ColorPalette"],_4.hitch(this,function(_a){this.dropDown=new _a({dir:_8.editor.dir,ownerDocument:_8.editor.ownerDocument,value:_8.value,onChange:function(_b){_8.editor.execCommand(_8.command,_b);}});_9();}));};},updateState:function(){var _c=this.editor;var _d=this.command;if(!_c||!_c.isLoaded||!_d.length){return;}if(this.button){var _e=this.get("disabled");this.button.set("disabled",_e);if(_e){return;}var _f;try{_f=_c.queryCommandValue(_d)||"";}catch(e){_f="";}}if(_f==""){_f="#000000";}if(_f=="transparent"){_f="#ffffff";}if(typeof _f=="string"){if(_f.indexOf("rgb")>-1){_f=_2.fromRgb(_f).toHex();}}else{_f=((_f&255)<<16)|(_f&65280)|((_f&16711680)>>>16);_f=_f.toString(16);_f="#000000".slice(0,7-_f.length)+_f;}this.value=_f;var _10=this.button.dropDown;if(_10&&_f!==_10.get("value")){_10.set("value",_f,false);}}});_5.registry["foreColor"]=function(){return new _7({command:"foreColor"});};_5.registry["hiliteColor"]=function(){return new _7({command:"hiliteColor"});};return _7;}); \ No newline at end of file
diff --git a/lib/dijit/_editor/plugins/TextColor.js.uncompressed.js b/lib/dijit/_editor/plugins/TextColor.js.uncompressed.js
new file mode 100644
index 000000000..b8da7c4a6
--- /dev/null
+++ b/lib/dijit/_editor/plugins/TextColor.js.uncompressed.js
@@ -0,0 +1,115 @@
+define("dijit/_editor/plugins/TextColor", [
+ "require",
+ "dojo/colors", // colors.fromRgb
+ "dojo/_base/declare", // declare
+ "dojo/_base/lang",
+ "../_Plugin",
+ "../../form/DropDownButton"
+], function(require, colors, declare, lang, _Plugin, DropDownButton){
+
+// module:
+// dijit/_editor/plugins/TextColor
+
+
+var TextColor = declare("dijit._editor.plugins.TextColor", _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: DropDownButton,
+
+ // useDefaultCommand: Boolean
+ // False as we do not use the default editor command/click behavior.
+ useDefaultCommand: false,
+
+ _initButton: function(){
+ this.inherited(arguments);
+
+ // Setup to lazy load ColorPalette first time the button is clicked
+ var self = this;
+ this.button.loadDropDown = function(callback){
+ require(["../../ColorPalette"], lang.hitch(this, function(ColorPalette){
+ this.dropDown = new ColorPalette({
+ dir: self.editor.dir,
+ ownerDocument: self.editor.ownerDocument,
+ value: self.value,
+ onChange: function(color){
+ self.editor.execCommand(self.command, color);
+ }
+ });
+ callback();
+ }));
+ };
+ },
+
+ 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 = colors.fromRgb(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;
+
+ }
+
+ this.value = value;
+
+ var dropDown = this.button.dropDown;
+ if(dropDown && value !== dropDown.get('value')){
+ dropDown.set('value', value, false);
+ }
+ }
+});
+
+// Register this plugin.
+_Plugin.registry["foreColor"] = function(){
+ return new TextColor({command: "foreColor"});
+};
+_Plugin.registry["hiliteColor"] = function(){
+ return new TextColor({command: "hiliteColor"});
+};
+
+
+return TextColor;
+});
diff --git a/lib/dijit/_editor/plugins/ToggleDir.js b/lib/dijit/_editor/plugins/ToggleDir.js
index 058445a9c..bf16dce9c 100644
--- a/lib/dijit/_editor/plugins/ToggleDir.js
+++ b/lib/dijit/_editor/plugins/ToggleDir.js
@@ -1,2 +1,2 @@
//>>built
-define("dijit/_editor/plugins/ToggleDir",["dojo/_base/declare","dojo/dom-style","dojo/_base/kernel","dojo/_base/lang","../_Plugin","../../form/ToggleButton"],function(_1,_2,_3,_4,_5,_6){_3.experimental("dijit._editor.plugins.ToggleDir");var _7=_1("dijit._editor.plugins.ToggleDir",_5,{useDefaultCommand:false,command:"toggleDir",buttonClass:_6,_initButton:function(){this.inherited(arguments);this.editor.onLoadDeferred.addCallback(_4.hitch(this,function(){var _8=this.editor.editorObject.contentWindow.document.documentElement;_8=_8.getElementsByTagName("body")[0];var _9=_2.getComputedStyle(_8).direction=="ltr";this.button.set("checked",!_9);this.connect(this.button,"onChange","_setRtl");}));},updateState:function(){this.button.set("disabled",this.get("disabled"));},_setRtl:function(_a){var _b="ltr";if(_a){_b="rtl";}var _c=this.editor.editorObject.contentWindow.document.documentElement;_c=_c.getElementsByTagName("body")[0];_c.dir=_b;}});_5.registry["toggleDir"]=function(){return new _7({command:"toggleDir"});};return _7;}); \ No newline at end of file
+define("dijit/_editor/plugins/ToggleDir",["dojo/_base/declare","dojo/dom-style","dojo/_base/kernel","dojo/_base/lang","../_Plugin","../../form/ToggleButton"],function(_1,_2,_3,_4,_5,_6){_3.experimental("dijit._editor.plugins.ToggleDir");var _7=_1("dijit._editor.plugins.ToggleDir",_5,{useDefaultCommand:false,command:"toggleDir",buttonClass:_6,_initButton:function(){this.inherited(arguments);this.editor.onLoadDeferred.then(_4.hitch(this,function(){var _8=this.editor.editorObject.contentWindow.document.documentElement;_8=_8.getElementsByTagName("body")[0];var _9=_2.getComputedStyle(_8).direction=="ltr";this.button.set("checked",!_9);this.connect(this.button,"onChange","_setRtl");}));},updateState:function(){this.button.set("disabled",this.get("disabled"));},_setRtl:function(_a){var _b="ltr";if(_a){_b="rtl";}var _c=this.editor.editorObject.contentWindow.document.documentElement;_c=_c.getElementsByTagName("body")[0];_c.dir=_b;}});_5.registry["toggleDir"]=function(){return new _7({command:"toggleDir"});};return _7;}); \ No newline at end of file
diff --git a/lib/dijit/_editor/plugins/ToggleDir.js.uncompressed.js b/lib/dijit/_editor/plugins/ToggleDir.js.uncompressed.js
new file mode 100644
index 000000000..7b36a21d9
--- /dev/null
+++ b/lib/dijit/_editor/plugins/ToggleDir.js.uncompressed.js
@@ -0,0 +1,69 @@
+define("dijit/_editor/plugins/ToggleDir", [
+ "dojo/_base/declare", // declare
+ "dojo/dom-style", // domStyle.getComputedStyle
+ "dojo/_base/kernel", // kernel.experimental
+ "dojo/_base/lang", // lang.hitch
+ "../_Plugin",
+ "../../form/ToggleButton"
+], function(declare, domStyle, kernel, lang, _Plugin, ToggleButton){
+
+ // module:
+ // dijit/_editor/plugins/ToggleDir
+
+ kernel.experimental("dijit._editor.plugins.ToggleDir");
+
+ var ToggleDir = declare("dijit._editor.plugins.ToggleDir", _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: ToggleButton,
+
+ _initButton: function(){
+ // Override _Plugin._initButton() to setup handler for button click events.
+ this.inherited(arguments);
+ this.editor.onLoadDeferred.then(lang.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 = domStyle.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.
+ _Plugin.registry["toggleDir"] = function(){
+ return new ToggleDir({command: "toggleDir"});
+ };
+
+ return ToggleDir;
+});
diff --git a/lib/dijit/_editor/plugins/ViewSource.js b/lib/dijit/_editor/plugins/ViewSource.js
index c788fa048..e235ed09b 100644
--- a/lib/dijit/_editor/plugins/ViewSource.js
+++ b/lib/dijit/_editor/plugins/ViewSource.js
@@ -1,2 +1,2 @@
//>>built
-define("dijit/_editor/plugins/ViewSource",["dojo/_base/array","dojo/_base/declare","dojo/dom-attr","dojo/dom-construct","dojo/dom-geometry","dojo/dom-style","dojo/_base/event","dojo/i18n","dojo/keys","dojo/_base/lang","dojo/on","dojo/_base/sniff","dojo/_base/window","dojo/window","../../focus","../_Plugin","../../form/ToggleButton","../..","../../registry","dojo/i18n!../nls/commands"],function(_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,on,_b,_c,_d,_e,_f,_10,_11,_12){var _13=_2("dijit._editor.plugins.ViewSource",_f,{stripScripts:true,stripComments:true,stripIFrames:true,readOnly:false,_fsPlugin:null,toggle:function(){if(_b("webkit")){this._vsFocused=true;}this.button.set("checked",!this.button.get("checked"));},_initButton:function(){var _14=_8.getLocalization("dijit._editor","commands"),_15=this.editor;this.button=new _10({label:_14["viewSource"],dir:_15.dir,lang:_15.lang,showLabel:false,iconClass:this.iconClassPrefix+" "+this.iconClassPrefix+"ViewSource",tabIndex:"-1",onChange:_a.hitch(this,"_showSource")});if(_b("ie")==7){this._ieFixNode=_4.create("div",{style:{opacity:"0",zIndex:"-1000",position:"absolute",top:"-1000px"}},_c.body());}this.button.set("readOnly",false);},setEditor:function(_16){this.editor=_16;this._initButton();this.editor.addKeyHandler(_9.F12,true,true,_a.hitch(this,function(e){this.button.focus();this.toggle();_7.stop(e);setTimeout(_a.hitch(this,function(){this.editor.focus();}),100);}));},_showSource:function(_17){var ed=this.editor;var _18=ed._plugins;var _19;this._sourceShown=_17;var _1a=this;try{if(!this.sourceArea){this._createSourceView();}if(_17){ed._sourceQueryCommandEnabled=ed.queryCommandEnabled;ed.queryCommandEnabled=function(cmd){return cmd.toLowerCase()==="viewsource";};this.editor.onDisplayChanged();_19=ed.get("value");_19=this._filter(_19);ed.set("value",_19);_1.forEach(_18,function(p){if(!(p instanceof _13)){p.set("disabled",true);}});if(this._fsPlugin){this._fsPlugin._getAltViewNode=function(){return _1a.sourceArea;};}this.sourceArea.value=_19;this.sourceArea.style.height=ed.iframe.style.height;this.sourceArea.style.width=ed.iframe.style.width;_6.set(ed.iframe,"display","none");_6.set(this.sourceArea,{display:"block"});var _1b=function(){var vp=_d.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(_a.hitch(this,function(){delete this._resizer;this._resize();}),10);};this._resizeHandle=on(window,"resize",_a.hitch(this,_1b));setTimeout(_a.hitch(this,this._resize),100);this.editor.onNormalizedDisplayChanged();this.editor.__oldGetValue=this.editor.getValue;this.editor.getValue=_a.hitch(this,function(){var txt=this.sourceArea.value;txt=this._filter(txt);return txt;});}else{if(!ed._sourceQueryCommandEnabled){return;}this._resizeHandle.remove();delete this._resizeHandle;if(this.editor.__oldGetValue){this.editor.getValue=this.editor.__oldGetValue;delete this.editor.__oldGetValue;}ed.queryCommandEnabled=ed._sourceQueryCommandEnabled;if(!this._readOnly){_19=this.sourceArea.value;_19=this._filter(_19);ed.beginEditing();ed.set("value",_19);ed.endEditing();}_1.forEach(_18,function(p){p.set("disabled",false);});_6.set(this.sourceArea,"display","none");_6.set(ed.iframe,"display","block");delete ed._sourceQueryCommandEnabled;this.editor.onDisplayChanged();}setTimeout(_a.hitch(this,function(){var _1c=ed.domNode.parentNode;if(_1c){var _1d=_12.getEnclosingWidget(_1c);if(_1d&&_1d.resize){_1d.resize();}}ed.resize();}),300);}catch(e){}},updateState:function(){this.button.set("disabled",this.get("disabled"));},_resize:function(){var ed=this.editor;var tbH=ed.getHeaderHeight();var fH=ed.getFooterHeight();var eb=_5.position(ed.domNode);var _1e=_5.getPadBorderExtents(ed.iframe.parentNode);var _1f=_5.getMarginExtents(ed.iframe.parentNode);var _20=_5.getPadBorderExtents(ed.domNode);var edb={w:eb.w-_20.w,h:eb.h-(tbH+_20.h+ +fH)};if(this._fsPlugin&&this._fsPlugin.isFullscreen){var vp=_d.getBox();edb.w=(vp.w-_20.w);edb.h=(vp.h-(tbH+_20.h+fH));}if(_b("ie")){edb.h-=2;}if(this._ieFixNode){var _21=-this._ieFixNode.offsetTop/1000;edb.w=Math.floor((edb.w+0.9)/_21);edb.h=Math.floor((edb.h+0.9)/_21);}_5.setMarginBox(this.sourceArea,{w:edb.w-(_1e.w+_1f.w),h:edb.h-(_1e.h+_1f.h)});_5.setMarginBox(ed.iframe.parentNode,{h:edb.h});},_createSourceView:function(){var ed=this.editor;var _22=ed._plugins;this.sourceArea=_4.create("textarea");if(this.readOnly){_3.set(this.sourceArea,"readOnly",true);this._readOnly=true;}_6.set(this.sourceArea,{padding:"0px",margin:"0px",borderWidth:"0px",borderStyle:"none"});_4.place(this.sourceArea,ed.iframe,"before");if(_b("ie")&&ed.iframe.parentNode.lastChild!==ed.iframe){_6.set(ed.iframe.parentNode.lastChild,{width:"0px",height:"0px",padding:"0px",margin:"0px",borderWidth:"0px",borderStyle:"none"});}ed._viewsource_oldFocus=ed.focus;var _23=this;ed.focus=function(){if(_23._sourceShown){_23.setSourceAreaCaret();}else{try{if(this._vsFocused){delete this._vsFocused;_e.focus(ed.editNode);}else{ed._viewsource_oldFocus();}}catch(e){}}};var i,p;for(i=0;i<_22.length;i++){p=_22[i];if(p&&(p.declaredClass==="dijit._editor.plugins.FullScreen"||p.declaredClass===(_11._scopeName+"._editor.plugins.FullScreen"))){this._fsPlugin=p;break;}}if(this._fsPlugin){this._fsPlugin._viewsource_getAltViewNode=this._fsPlugin._getAltViewNode;this._fsPlugin._getAltViewNode=function(){return _23._sourceShown?_23.sourceArea:this._viewsource_getAltViewNode();};}this.connect(this.sourceArea,"onkeydown",_a.hitch(this,function(e){if(this._sourceShown&&e.keyCode==_9.F12&&e.ctrlKey&&e.shiftKey){this.button.focus();this.button.set("checked",false);setTimeout(_a.hitch(this,function(){ed.focus();}),100);_7.stop(e);}}));},_stripScripts:function(_24){if(_24){_24=_24.replace(/<\s*script[^>]*>((.|\s)*?)<\\?\/\s*script\s*>/ig,"");_24=_24.replace(/<\s*script\b([^<>]|\s)*>?/ig,"");_24=_24.replace(/<[^>]*=(\s|)*[("|')]javascript:[^$1][(\s|.)]*[$1][^>]*>/ig,"");}return _24;},_stripComments:function(_25){if(_25){_25=_25.replace(/<!--(.|\s){1,}?-->/g,"");}return _25;},_stripIFrames:function(_26){if(_26){_26=_26.replace(/<\s*iframe[^>]*>((.|\s)*?)<\\?\/\s*iframe\s*>/ig,"");}return _26;},_filter:function(_27){if(_27){if(this.stripScripts){_27=this._stripScripts(_27);}if(this.stripComments){_27=this._stripComments(_27);}if(this.stripIFrames){_27=this._stripIFrames(_27);}}return _27;},setSourceAreaCaret:function(){var _28=_c.global;var _29=this.sourceArea;_e.focus(_29);if(this._sourceShown&&!this.readOnly){if(_b("ie")){if(this.sourceArea.createTextRange){var _2a=_29.createTextRange();_2a.collapse(true);_2a.moveStart("character",-99999);_2a.moveStart("character",0);_2a.moveEnd("character",0);_2a.select();}}else{if(_28.getSelection){if(_29.setSelectionRange){_29.setSelectionRange(0,0);}}}}},destroy:function(){if(this._ieFixNode){_c.body().removeChild(this._ieFixNode);}if(this._resizer){clearTimeout(this._resizer);delete this._resizer;}if(this._resizeHandle){this._resizeHandle.remove();delete this._resizeHandle;}this.inherited(arguments);}});_f.registry["viewSource"]=_f.registry["viewsource"]=function(_2b){return new _13({readOnly:("readOnly" in _2b)?_2b.readOnly:false,stripComments:("stripComments" in _2b)?_2b.stripComments:true,stripScripts:("stripScripts" in _2b)?_2b.stripScripts:true,stripIFrames:("stripIFrames" in _2b)?_2b.stripIFrames:true});};return _13;}); \ No newline at end of file
+define("dijit/_editor/plugins/ViewSource",["dojo/_base/array","dojo/_base/declare","dojo/dom-attr","dojo/dom-construct","dojo/dom-geometry","dojo/dom-style","dojo/_base/event","dojo/i18n","dojo/keys","dojo/_base/lang","dojo/on","dojo/sniff","dojo/_base/window","dojo/window","../../focus","../_Plugin","../../form/ToggleButton","../..","../../registry","dojo/aspect","dojo/i18n!../nls/commands"],function(_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,on,_b,_c,_d,_e,_f,_10,_11,_12,_13){var _14=_2("dijit._editor.plugins.ViewSource",_f,{stripScripts:true,stripComments:true,stripIFrames:true,readOnly:false,_fsPlugin:null,toggle:function(){if(_b("webkit")){this._vsFocused=true;}this.button.set("checked",!this.button.get("checked"));},_initButton:function(){var _15=_8.getLocalization("dijit._editor","commands"),_16=this.editor;this.button=new _10({label:_15["viewSource"],ownerDocument:_16.ownerDocument,dir:_16.dir,lang:_16.lang,showLabel:false,iconClass:this.iconClassPrefix+" "+this.iconClassPrefix+"ViewSource",tabIndex:"-1",onChange:_a.hitch(this,"_showSource")});if(_b("ie")==7){this._ieFixNode=_4.create("div",{style:{opacity:"0",zIndex:"-1000",position:"absolute",top:"-1000px"}},_16.ownerDocumentBody);}this.button.set("readOnly",false);},setEditor:function(_17){this.editor=_17;this._initButton();this.editor.addKeyHandler(_9.F12,true,true,_a.hitch(this,function(e){this.button.focus();this.toggle();_7.stop(e);setTimeout(_a.hitch(this,function(){this.editor.focus();}),100);}));},_showSource:function(_18){var ed=this.editor;var _19=ed._plugins;var _1a;this._sourceShown=_18;var _1b=this;try{if(!this.sourceArea){this._createSourceView();}if(_18){ed._sourceQueryCommandEnabled=ed.queryCommandEnabled;ed.queryCommandEnabled=function(cmd){return cmd.toLowerCase()==="viewsource";};this.editor.onDisplayChanged();_1a=ed.get("value");_1a=this._filter(_1a);ed.set("value",_1a);_1.forEach(_19,function(p){if(p&&!(p instanceof _14)&&p.isInstanceOf(_f)){p.set("disabled",true);}});if(this._fsPlugin){this._fsPlugin._getAltViewNode=function(){return _1b.sourceArea;};}this.sourceArea.value=_1a;this.sourceArea.style.height=ed.iframe.style.height;this.sourceArea.style.width=ed.iframe.style.width;_6.set(ed.iframe,"display","none");_6.set(this.sourceArea,{display:"block"});var _1c=function(){var vp=_d.getBox(ed.ownerDocument);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(_a.hitch(this,function(){delete this._resizer;this._resize();}),10);};this._resizeHandle=on(window,"resize",_a.hitch(this,_1c));setTimeout(_a.hitch(this,this._resize),100);this.editor.onNormalizedDisplayChanged();this.editor.__oldGetValue=this.editor.getValue;this.editor.getValue=_a.hitch(this,function(){var txt=this.sourceArea.value;txt=this._filter(txt);return txt;});this._setListener=_13.after(this.editor,"setValue",_a.hitch(this,function(_1d){_1d=_1d||"";_1d=this._filter(_1d);this.sourceArea.value=_1d;}),true);}else{if(!ed._sourceQueryCommandEnabled){return;}this._setListener.remove();delete this._setListener;this._resizeHandle.remove();delete this._resizeHandle;if(this.editor.__oldGetValue){this.editor.getValue=this.editor.__oldGetValue;delete this.editor.__oldGetValue;}ed.queryCommandEnabled=ed._sourceQueryCommandEnabled;if(!this._readOnly){_1a=this.sourceArea.value;_1a=this._filter(_1a);ed.beginEditing();ed.set("value",_1a);ed.endEditing();}_1.forEach(_19,function(p){if(p&&p.isInstanceOf(_f)){p.set("disabled",false);}});_6.set(this.sourceArea,"display","none");_6.set(ed.iframe,"display","block");delete ed._sourceQueryCommandEnabled;this.editor.onDisplayChanged();}setTimeout(_a.hitch(this,function(){var _1e=ed.domNode.parentNode;if(_1e){var _1f=_12.getEnclosingWidget(_1e);if(_1f&&_1f.resize){_1f.resize();}}ed.resize();}),300);}catch(e){}},updateState:function(){this.button.set("disabled",this.get("disabled"));},_resize:function(){var ed=this.editor;var tbH=ed.getHeaderHeight();var fH=ed.getFooterHeight();var eb=_5.position(ed.domNode);var _20=_5.getPadBorderExtents(ed.iframe.parentNode);var _21=_5.getMarginExtents(ed.iframe.parentNode);var _22=_5.getPadBorderExtents(ed.domNode);var edb={w:eb.w-_22.w,h:eb.h-(tbH+_22.h+fH)};if(this._fsPlugin&&this._fsPlugin.isFullscreen){var vp=_d.getBox(ed.ownerDocument);edb.w=(vp.w-_22.w);edb.h=(vp.h-(tbH+_22.h+fH));}if(_b("ie")){edb.h-=2;}if(this._ieFixNode){var _23=-this._ieFixNode.offsetTop/1000;edb.w=Math.floor((edb.w+0.9)/_23);edb.h=Math.floor((edb.h+0.9)/_23);}_5.setMarginBox(this.sourceArea,{w:edb.w-(_20.w+_21.w),h:edb.h-(_20.h+_21.h)});_5.setMarginBox(ed.iframe.parentNode,{h:edb.h});},_createSourceView:function(){var ed=this.editor;var _24=ed._plugins;this.sourceArea=_4.create("textarea");if(this.readOnly){_3.set(this.sourceArea,"readOnly",true);this._readOnly=true;}_6.set(this.sourceArea,{padding:"0px",margin:"0px",borderWidth:"0px",borderStyle:"none"});_4.place(this.sourceArea,ed.iframe,"before");if(_b("ie")&&ed.iframe.parentNode.lastChild!==ed.iframe){_6.set(ed.iframe.parentNode.lastChild,{width:"0px",height:"0px",padding:"0px",margin:"0px",borderWidth:"0px",borderStyle:"none"});}ed._viewsource_oldFocus=ed.focus;var _25=this;ed.focus=function(){if(_25._sourceShown){_25.setSourceAreaCaret();}else{try{if(this._vsFocused){delete this._vsFocused;_e.focus(ed.editNode);}else{ed._viewsource_oldFocus();}}catch(e){}}};var i,p;for(i=0;i<_24.length;i++){p=_24[i];if(p&&(p.declaredClass==="dijit._editor.plugins.FullScreen"||p.declaredClass===(_11._scopeName+"._editor.plugins.FullScreen"))){this._fsPlugin=p;break;}}if(this._fsPlugin){this._fsPlugin._viewsource_getAltViewNode=this._fsPlugin._getAltViewNode;this._fsPlugin._getAltViewNode=function(){return _25._sourceShown?_25.sourceArea:this._viewsource_getAltViewNode();};}this.connect(this.sourceArea,"onkeydown",_a.hitch(this,function(e){if(this._sourceShown&&e.keyCode==_9.F12&&e.ctrlKey&&e.shiftKey){this.button.focus();this.button.set("checked",false);setTimeout(_a.hitch(this,function(){ed.focus();}),100);_7.stop(e);}}));},_stripScripts:function(_26){if(_26){_26=_26.replace(/<\s*script[^>]*>((.|\s)*?)<\\?\/\s*script\s*>/ig,"");_26=_26.replace(/<\s*script\b([^<>]|\s)*>?/ig,"");_26=_26.replace(/<[^>]*=(\s|)*[("|')]javascript:[^$1][(\s|.)]*[$1][^>]*>/ig,"");}return _26;},_stripComments:function(_27){if(_27){_27=_27.replace(/<!--(.|\s){1,}?-->/g,"");}return _27;},_stripIFrames:function(_28){if(_28){_28=_28.replace(/<\s*iframe[^>]*>((.|\s)*?)<\\?\/\s*iframe\s*>/ig,"");}return _28;},_filter:function(_29){if(_29){if(this.stripScripts){_29=this._stripScripts(_29);}if(this.stripComments){_29=this._stripComments(_29);}if(this.stripIFrames){_29=this._stripIFrames(_29);}}return _29;},setSourceAreaCaret:function(){var _2a=_c.global;var _2b=this.sourceArea;_e.focus(_2b);if(this._sourceShown&&!this.readOnly){if(_b("ie")){if(this.sourceArea.createTextRange){var _2c=_2b.createTextRange();_2c.collapse(true);_2c.moveStart("character",-99999);_2c.moveStart("character",0);_2c.moveEnd("character",0);_2c.select();}}else{if(_2a.getSelection){if(_2b.setSelectionRange){_2b.setSelectionRange(0,0);}}}}},destroy:function(){if(this._ieFixNode){_4.destroy(this._ieFixNode);}if(this._resizer){clearTimeout(this._resizer);delete this._resizer;}if(this._resizeHandle){this._resizeHandle.remove();delete this._resizeHandle;}if(this._setListener){this._setListener.remove();delete this._setListener;}this.inherited(arguments);}});_f.registry["viewSource"]=_f.registry["viewsource"]=function(_2d){return new _14({readOnly:("readOnly" in _2d)?_2d.readOnly:false,stripComments:("stripComments" in _2d)?_2d.stripComments:true,stripScripts:("stripScripts" in _2d)?_2d.stripScripts:true,stripIFrames:("stripIFrames" in _2d)?_2d.stripIFrames:true});};return _14;}); \ No newline at end of file
diff --git a/lib/dijit/_editor/plugins/ViewSource.js.uncompressed.js b/lib/dijit/_editor/plugins/ViewSource.js.uncompressed.js
new file mode 100644
index 000000000..e70e05c22
--- /dev/null
+++ b/lib/dijit/_editor/plugins/ViewSource.js.uncompressed.js
@@ -0,0 +1,577 @@
+define("dijit/_editor/plugins/ViewSource", [
+ "dojo/_base/array", // array.forEach
+ "dojo/_base/declare", // declare
+ "dojo/dom-attr", // domAttr.set
+ "dojo/dom-construct", // domConstruct.create domConstruct.place
+ "dojo/dom-geometry", // domGeometry.setMarginBox domGeometry.position
+ "dojo/dom-style", // domStyle.set
+ "dojo/_base/event", // event.stop
+ "dojo/i18n", // i18n.getLocalization
+ "dojo/keys", // keys.F12
+ "dojo/_base/lang", // lang.hitch
+ "dojo/on", // on()
+ "dojo/sniff", // has("ie") has("webkit")
+ "dojo/_base/window", // win.body win.global
+ "dojo/window", // winUtils.getBox
+ "../../focus", // focus.focus()
+ "../_Plugin",
+ "../../form/ToggleButton",
+ "../..", // dijit._scopeName
+ "../../registry", // registry.getEnclosingWidget()
+ "dojo/aspect", // Aspect commands for adice
+ "dojo/i18n!../nls/commands"
+], function(array, declare, domAttr, domConstruct, domGeometry, domStyle, event, i18n, keys, lang, on, has, win,
+ winUtils, focus, _Plugin, ToggleButton, dijit, registry, aspect){
+
+// module:
+// dijit/_editor/plugins/ViewSource
+
+
+var ViewSource = declare("dijit._editor.plugins.ViewSource",_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(has("webkit")){this._vsFocused = true;}
+ this.button.set("checked", !this.button.get("checked"));
+
+ },
+
+ _initButton: function(){
+ // summary:
+ // Over-ride for creation of the resize button.
+ var strings = i18n.getLocalization("dijit._editor", "commands"),
+ editor = this.editor;
+ this.button = new ToggleButton({
+ label: strings["viewSource"],
+ ownerDocument: editor.ownerDocument,
+ dir: editor.dir,
+ lang: editor.lang,
+ showLabel: false,
+ iconClass: this.iconClassPrefix + " " + this.iconClassPrefix + "ViewSource",
+ tabIndex: "-1",
+ onChange: lang.hitch(this, "_showSource")
+ });
+
+ // IE 7 has a horrible bug with zoom, so we have to create this node
+ // to cross-check later. Sigh.
+ if(has("ie") == 7){
+ this._ieFixNode = domConstruct.create("div", {
+ style: {
+ opacity: "0",
+ zIndex: "-1000",
+ position: "absolute",
+ top: "-1000px"
+ }
+ }, editor.ownerDocumentBody);
+ }
+ // 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(keys.F12, true, true, lang.hitch(this, function(e){
+ // Move the focus before switching
+ // It'll focus back. Hiding a focused
+ // node causes issues.
+ this.button.focus();
+ this.toggle();
+ event.stop(e);
+
+ // Call the focus shift outside of the handler.
+ setTimeout(lang.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){
+ return cmd.toLowerCase() === "viewsource";
+ };
+ this.editor.onDisplayChanged();
+ html = ed.get("value");
+ html = this._filter(html);
+ ed.set("value", html);
+ array.forEach(edPlugins, function(p){
+ // Turn off any plugins not controlled by queryCommandenabled.
+ if(p && !(p instanceof ViewSource) && p.isInstanceOf(_Plugin)){
+ 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;
+
+ // Since neither iframe nor textarea have margin, border, or padding,
+ // just set sizes equal
+ this.sourceArea.style.height = ed.iframe.style.height;
+ this.sourceArea.style.width = ed.iframe.style.width;
+ domStyle.set(ed.iframe, "display", "none");
+ domStyle.set(this.sourceArea, {
+ display: "block"
+ });
+
+ var resizer = function(){
+ // function to handle resize events.
+ // Will check current VP and only resize if
+ // different.
+ var vp = winUtils.getBox(ed.ownerDocument);
+
+ 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(lang.hitch(this, function(){
+ delete this._resizer;
+ this._resize();
+ }), 10);
+ };
+ this._resizeHandle = on(window, "resize", lang.hitch(this, resizer));
+
+ //Call this on a delay once to deal with IE glitchiness on initial size.
+ setTimeout(lang.hitch(this, this._resize), 100);
+
+ //Trigger a check for command enablement/disablement.
+ this.editor.onNormalizedDisplayChanged();
+
+ this.editor.__oldGetValue = this.editor.getValue;
+ this.editor.getValue = lang.hitch(this, function(){
+ var txt = this.sourceArea.value;
+ txt = this._filter(txt);
+ return txt;
+ });
+
+ this._setListener = aspect.after(this.editor, "setValue", lang.hitch(this, function(htmlTxt){
+ htmlTxt = htmlTxt || "";
+ htmlTxt = this._filter(htmlTxt);
+ this.sourceArea.value = htmlTxt;
+ }), true);
+ }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;
+ }
+
+ // Remove the set listener.
+ this._setListener.remove();
+ delete this._setListener;
+
+ this._resizeHandle.remove();
+ 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();
+ }
+
+ array.forEach(edPlugins, function(p){
+ // Turn back on any plugins we turned off.
+ if(p && p.isInstanceOf(_Plugin)){
+ p.set("disabled", false);
+ }
+ });
+
+ domStyle.set(this.sourceArea, "display", "none");
+ domStyle.set(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(lang.hitch(this, function(){
+ // Make resize calls.
+ var parent = ed.domNode.parentNode;
+ if(parent){
+ var container = registry.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 = domGeometry.position(ed.domNode);
+
+ // Styles are now applied to the internal source container, so we have
+ // to subtract them off.
+ var containerPadding = domGeometry.getPadBorderExtents(ed.iframe.parentNode);
+ var containerMargin = domGeometry.getMarginExtents(ed.iframe.parentNode);
+
+ var extents = domGeometry.getPadBorderExtents(ed.domNode);
+ var edb = {
+ w: eb.w - extents.w,
+ h: eb.h - (tbH + extents.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 = winUtils.getBox(ed.ownerDocument);
+ edb.w = (vp.w - extents.w);
+ edb.h = (vp.h - (tbH + extents.h + fH));
+ }
+
+ if(has("ie")){
+ // 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);
+ }
+
+ domGeometry.setMarginBox(this.sourceArea, {
+ w: edb.w - (containerPadding.w + containerMargin.w),
+ h: edb.h - (containerPadding.h + containerMargin.h)
+ });
+
+ // Scale the parent container too in this case.
+ domGeometry.setMarginBox(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 = domConstruct.create("textarea");
+ if(this.readOnly){
+ domAttr.set(this.sourceArea, "readOnly", true);
+ this._readOnly = true;
+ }
+ domStyle.set(this.sourceArea, {
+ padding: "0px",
+ margin: "0px",
+ borderWidth: "0px",
+ borderStyle: "none"
+ });
+ domConstruct.place(this.sourceArea, ed.iframe, "before");
+
+ if(has("ie") && 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.
+ domStyle.set(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.
+ focus.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", lang.hitch(this, function(e){
+ if(this._sourceShown && e.keyCode == keys.F12 && e.ctrlKey && e.shiftKey){
+ this.button.focus();
+ this.button.set("checked", false);
+ setTimeout(lang.hitch(this, function(){ed.focus();}), 100);
+ event.stop(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 global = win.global;
+ var elem = this.sourceArea;
+ focus.focus(elem);
+ if(this._sourceShown && !this.readOnly){
+ if(has("ie")){
+ 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(global.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){
+ domConstruct.destroy(this._ieFixNode);
+ }
+ if(this._resizer){
+ clearTimeout(this._resizer);
+ delete this._resizer;
+ }
+ if(this._resizeHandle){
+ this._resizeHandle.remove();
+ delete this._resizeHandle;
+ }
+ if(this._setListener){
+ this._setListener.remove();
+ delete this._setListener;
+ }
+ this.inherited(arguments);
+ }
+});
+
+// Register this plugin.
+// For back-compat accept "viewsource" (all lowercase) too, remove in 2.0
+_Plugin.registry["viewSource"] = _Plugin.registry["viewsource"] = function(args){
+ return new ViewSource({
+ readOnly: ("readOnly" in args)?args.readOnly:false,
+ stripComments: ("stripComments" in args)?args.stripComments:true,
+ stripScripts: ("stripScripts" in args)?args.stripScripts:true,
+ stripIFrames: ("stripIFrames" in args)?args.stripIFrames:true
+ });
+};
+
+
+
+
+return ViewSource;
+});