upgrade Dojo to 1.6.1

This commit is contained in:
Andrew Dolgov
2011-11-08 20:40:44 +04:00
parent 870a70e109
commit 81bea17aef
680 changed files with 51915 additions and 74107 deletions

View File

@@ -1,119 +1,190 @@
/*
Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
if(!dojo._hasResource["dijit._editor.plugins.AlwaysShowToolbar"]){
dojo._hasResource["dijit._editor.plugins.AlwaysShowToolbar"]=true;
if(!dojo._hasResource["dijit._editor.plugins.AlwaysShowToolbar"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit._editor.plugins.AlwaysShowToolbar"] = true;
dojo.provide("dijit._editor.plugins.AlwaysShowToolbar");
dojo.declare("dijit._editor.plugins.AlwaysShowToolbar",dijit._editor._Plugin,{_handleScroll:true,setEditor:function(e){
if(!e.iframe){
return;
}
this.editor=e;
e.onLoadDeferred.addCallback(dojo.hitch(this,this.enable));
},enable:function(d){
this._updateHeight();
this.connect(window,"onscroll","globalOnScrollHandler");
this.connect(this.editor,"onNormalizedDisplayChanged","_updateHeight");
return d;
},_updateHeight:function(){
var e=this.editor;
if(!e.isLoaded){
return;
}
if(e.height){
return;
}
var _1=dojo.marginBox(e.editNode).h;
if(dojo.isOpera){
_1=e.editNode.scrollHeight;
}
if(!_1){
_1=dojo.marginBox(e.document.body).h;
}
if(_1==0){
return;
}
if(dojo.isIE<=7&&this.editor.minHeight){
var _2=parseInt(this.editor.minHeight);
if(_1<_2){
_1=_2;
}
}
if(_1!=this._lastHeight){
this._lastHeight=_1;
dojo.marginBox(e.iframe,{h:this._lastHeight});
}
},_lastHeight:0,globalOnScrollHandler:function(){
var _3=dojo.isIE<7;
if(!this._handleScroll){
return;
}
var _4=this.editor.header;
var db=dojo.body;
if(!this._scrollSetUp){
this._scrollSetUp=true;
this._scrollThreshold=dojo.position(_4,true).y;
}
var _5=dojo._docScroll().y;
var s=_4.style;
if(_5>this._scrollThreshold&&_5<this._scrollThreshold+this._lastHeight){
if(!this._fixEnabled){
var _6=dojo.marginBox(_4);
this.editor.iframe.style.marginTop=_6.h+"px";
if(_3){
s.left=dojo.position(_4).x;
if(_4.previousSibling){
this._IEOriginalPos=["after",_4.previousSibling];
}else{
if(_4.nextSibling){
this._IEOriginalPos=["before",_4.nextSibling];
}else{
this._IEOriginalPos=["last",_4.parentNode];
}
}
dojo.body().appendChild(_4);
dojo.addClass(_4,"dijitIEFixedToolbar");
}else{
s.position="fixed";
s.top="0px";
}
dojo.marginBox(_4,{w:_6.w});
s.zIndex=2000;
this._fixEnabled=true;
}
var _7=(this.height)?parseInt(this.editor.height):this.editor._lastHeight;
s.display=(_5>this._scrollThreshold+_7)?"none":"";
}else{
if(this._fixEnabled){
this.editor.iframe.style.marginTop="";
s.position="";
s.top="";
s.zIndex="";
s.display="";
if(_3){
s.left="";
dojo.removeClass(_4,"dijitIEFixedToolbar");
if(this._IEOriginalPos){
dojo.place(_4,this._IEOriginalPos[1],this._IEOriginalPos[0]);
this._IEOriginalPos=null;
}else{
dojo.place(_4,this.editor.iframe,"before");
}
}
s.width="";
this._fixEnabled=false;
}
}
},destroy:function(){
this._IEOriginalPos=null;
this._handleScroll=false;
dojo.forEach(this._connects,dojo.disconnect);
if(dojo.isIE<7){
dojo.removeClass(this.editor.header,"dijitIEFixedToolbar");
}
}});
dojo.require("dijit._editor._Plugin");
dojo.declare("dijit._editor.plugins.AlwaysShowToolbar", dijit._editor._Plugin,
{
// summary:
// This plugin is required for Editors in auto-expand mode.
// It handles the auto-expansion as the user adds/deletes text,
// and keeps the editor's toolbar visible even when the top of the editor
// has scrolled off the top of the viewport (usually when editing a long
// document).
// description:
// Specify this in extraPlugins (or plugins) parameter and also set
// height to "".
// example:
// | <div dojoType="dijit.Editor" height=""
// | extraPlugins="['dijit._editor.plugins.AlwaysShowToolbar']">
// _handleScroll: Boolean
// Enables/disables the handler for scroll events
_handleScroll: true,
setEditor: function(e){
// Overrides _Plugin.setEditor().
if(!e.iframe){
console.log('Port AlwaysShowToolbar plugin to work with Editor without iframe');
return;
}
this.editor = e;
e.onLoadDeferred.addCallback(dojo.hitch(this, this.enable));
},
enable: function(d){
// summary:
// Enable plugin. Called when Editor has finished initializing.
// tags:
// private
this._updateHeight();
this.connect(window, 'onscroll', "globalOnScrollHandler");
this.connect(this.editor, 'onNormalizedDisplayChanged', "_updateHeight");
return d;
},
_updateHeight: function(){
// summary:
// Updates the height of the editor area to fit the contents.
var e = this.editor;
if(!e.isLoaded){ return; }
if(e.height){ return; }
var height = dojo._getMarginSize(e.editNode).h;
if(dojo.isOpera){
height = e.editNode.scrollHeight;
}
// console.debug('height',height);
// alert(this.editNode);
//height maybe zero in some cases even though the content is not empty,
//we try the height of body instead
if(!height){
height = dojo._getMarginSize(e.document.body).h;
}
if(height == 0){
console.debug("Can not figure out the height of the editing area!");
return; //prevent setting height to 0
}
if(dojo.isIE <= 7 && this.editor.minHeight){
var min = parseInt(this.editor.minHeight);
if(height < min){ height = min; }
}
if(height != this._lastHeight){
this._lastHeight = height;
// this.editorObject.style.height = this._lastHeight + "px";
dojo.marginBox(e.iframe, { h: this._lastHeight });
}
},
// _lastHeight: Integer
// Height in px of the editor at the last time we did sizing
_lastHeight: 0,
globalOnScrollHandler: function(){
// summary:
// Handler for scroll events that bubbled up to <html>
// tags:
// private
var isIE6 = dojo.isIE < 7;
if(!this._handleScroll){ return; }
var tdn = this.editor.header;
var db = dojo.body;
if(!this._scrollSetUp){
this._scrollSetUp = true;
this._scrollThreshold = dojo.position(tdn, true).y;
// console.log("threshold:", this._scrollThreshold);
//what's this for?? comment out for now
// if((isIE6)&&(db)&&(dojo.style(db, "backgroundIimage")=="none")){
// db.style.backgroundImage = "url(" + dojo.uri.moduleUri("dijit", "templates/blank.gif") + ")";
// db.style.backgroundAttachment = "fixed";
// }
}
var scrollPos = dojo._docScroll().y;
var s = tdn.style;
if(scrollPos > this._scrollThreshold && scrollPos < this._scrollThreshold+this._lastHeight){
// dojo.debug(scrollPos);
if(!this._fixEnabled){
var tdnbox = dojo._getMarginSize(tdn);
this.editor.iframe.style.marginTop = tdnbox.h+"px";
if(isIE6){
s.left = dojo.position(tdn).x;
if(tdn.previousSibling){
this._IEOriginalPos = ['after',tdn.previousSibling];
}else if(tdn.nextSibling){
this._IEOriginalPos = ['before',tdn.nextSibling];
}else{
this._IEOriginalPos = ['last',tdn.parentNode];
}
dojo.body().appendChild(tdn);
dojo.addClass(tdn,'dijitIEFixedToolbar');
}else{
s.position = "fixed";
s.top = "0px";
}
dojo.marginBox(tdn, { w: tdnbox.w });
s.zIndex = 2000;
this._fixEnabled = true;
}
// if we're showing the floating toolbar, make sure that if
// we've scrolled past the bottom of the editor that we hide
// the toolbar for this instance of the editor.
// TODO: when we get multiple editor toolbar support working
// correctly, ensure that we check this against the scroll
// position of the bottom-most editor instance.
var eHeight = (this.height) ? parseInt(this.editor.height) : this.editor._lastHeight;
s.display = (scrollPos > this._scrollThreshold+eHeight) ? "none" : "";
}else if(this._fixEnabled){
this.editor.iframe.style.marginTop = '';
s.position = "";
s.top = "";
s.zIndex = "";
s.display = "";
if(isIE6){
s.left = "";
dojo.removeClass(tdn,'dijitIEFixedToolbar');
if(this._IEOriginalPos){
dojo.place(tdn, this._IEOriginalPos[1], this._IEOriginalPos[0]);
this._IEOriginalPos = null;
}else{
dojo.place(tdn, this.editor.iframe, 'before');
}
}
s.width = "";
this._fixEnabled = false;
}
},
destroy: function(){
// Overrides _Plugin.destroy(). TODO: call this.inherited() rather than repeating code.
this._IEOriginalPos = null;
this._handleScroll = false;
dojo.forEach(this._connects, dojo.disconnect);
// clearInterval(this.scrollInterval);
if(dojo.isIE < 7){
dojo.removeClass(this.editor.header, 'dijitIEFixedToolbar');
}
}
});
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +1,12 @@
/*
Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
if(!dojo._hasResource["dijit._editor.plugins.FontChoice"]){
dojo._hasResource["dijit._editor.plugins.FontChoice"]=true;
if(!dojo._hasResource["dijit._editor.plugins.FontChoice"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit._editor.plugins.FontChoice"] = true;
dojo.provide("dijit._editor.plugins.FontChoice");
dojo.require("dijit._editor._Plugin");
dojo.require("dijit._editor.range");
@@ -14,252 +14,570 @@ dojo.require("dijit._editor.selection");
dojo.require("dijit.form.FilteringSelect");
dojo.require("dojo.data.ItemFileReadStore");
dojo.require("dojo.i18n");
dojo.requireLocalization("dijit._editor","FontChoice",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw");
dojo.declare("dijit._editor.plugins._FontDropDown",[dijit._Widget,dijit._Templated],{label:"",widgetsInTemplate:true,plainText:false,templateString:"<span style='white-space: nowrap' class='dijit dijitReset dijitInline'>"+"<label class='dijitLeft dijitInline' for='${selectId}'>${label}</label>"+"<input dojoType='dijit.form.FilteringSelect' required=false labelType=html labelAttr=label searchAttr=name "+"tabIndex='-1' id='${selectId}' dojoAttachPoint='select' value=''/>"+"</span>",postMixInProperties:function(){
this.inherited(arguments);
this.strings=dojo.i18n.getLocalization("dijit._editor","FontChoice");
this.label=this.strings[this.command];
this.id=dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
this.selectId=this.id+"_select";
this.inherited(arguments);
},postCreate:function(){
var _1=dojo.map(this.values,function(_2){
var _3=this.strings[_2]||_2;
return {label:this.getLabel(_2,_3),name:_3,value:_2};
},this);
this.select.store=new dojo.data.ItemFileReadStore({data:{identifier:"value",items:_1}});
this.select.set("value","",false);
this.disabled=this.select.get("disabled");
},_setValueAttr:function(_4,_5){
_5=_5!==false?true:false;
this.select.set("value",dojo.indexOf(this.values,_4)<0?"":_4,_5);
if(!_5){
this.select._lastValueReported=null;
}
},_getValueAttr:function(){
return this.select.get("value");
},focus:function(){
this.select.focus();
},_setDisabledAttr:function(_6){
this.disabled=_6;
this.select.set("disabled",_6);
}});
dojo.declare("dijit._editor.plugins._FontNameDropDown",dijit._editor.plugins._FontDropDown,{generic:false,command:"fontName",postMixInProperties:function(){
if(!this.values){
this.values=this.generic?["serif","sans-serif","monospace","cursive","fantasy"]:["Arial","Times New Roman","Comic Sans MS","Courier New"];
}
this.inherited(arguments);
},getLabel:function(_7,_8){
if(this.plainText){
return _8;
}else{
return "<div style='font-family: "+_7+"'>"+_8+"</div>";
}
},_setValueAttr:function(_9,_a){
_a=_a!==false?true:false;
if(this.generic){
var _b={"Arial":"sans-serif","Helvetica":"sans-serif","Myriad":"sans-serif","Times":"serif","Times New Roman":"serif","Comic Sans MS":"cursive","Apple Chancery":"cursive","Courier":"monospace","Courier New":"monospace","Papyrus":"fantasy"};
_9=_b[_9]||_9;
}
this.inherited(arguments,[_9,_a]);
}});
dojo.declare("dijit._editor.plugins._FontSizeDropDown",dijit._editor.plugins._FontDropDown,{command:"fontSize",values:[1,2,3,4,5,6,7],getLabel:function(_c,_d){
if(this.plainText){
return _d;
}else{
return "<font size="+_c+"'>"+_d+"</font>";
}
},_setValueAttr:function(_e,_f){
_f=_f!==false?true:false;
if(_e.indexOf&&_e.indexOf("px")!=-1){
var _10=parseInt(_e,10);
_e={10:1,13:2,16:3,18:4,24:5,32:6,48:7}[_10]||_e;
}
this.inherited(arguments,[_e,_f]);
}});
dojo.declare("dijit._editor.plugins._FormatBlockDropDown",dijit._editor.plugins._FontDropDown,{command:"formatBlock",values:["noFormat","p","h1","h2","h3","pre"],postCreate:function(){
this.inherited(arguments);
this.set("value","noFormat",false);
},getLabel:function(_11,_12){
if(this.plainText){
return _12;
}else{
return "<"+_11+">"+_12+"</"+_11+">";
}
},_execCommand:function(_13,_14,_15){
if(_15==="noFormat"){
var _16;
var end;
var sel=dijit.range.getSelection(_13.window);
if(sel&&sel.rangeCount>0){
var _17=sel.getRangeAt(0);
var _18,tag;
if(_17){
_16=_17.startContainer;
end=_17.endContainer;
while(_16&&_16!==_13.editNode&&_16!==_13.document.body&&_16.nodeType!==1){
_16=_16.parentNode;
}
while(end&&end!==_13.editNode&&end!==_13.document.body&&end.nodeType!==1){
end=end.parentNode;
}
var _19=dojo.hitch(this,function(_1a,_1b){
if(_1a.childNodes&&_1a.childNodes.length){
var i;
for(i=0;i<_1a.childNodes.length;i++){
var c=_1a.childNodes[i];
if(c.nodeType==1){
if(dojo.withGlobal(_13.window,"inSelection",dijit._editor.selection,[c])){
var tag=c.tagName?c.tagName.toLowerCase():"";
if(dojo.indexOf(this.values,tag)!==-1){
_1b.push(c);
}
_19(c,_1b);
}
}
}
}
dojo.requireLocalization("dijit._editor", "FontChoice", null, "ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,kk,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw");
dojo.declare("dijit._editor.plugins._FontDropDown",
[dijit._Widget, dijit._Templated],{
// summary:
// Base class for widgets that contains a label (like "Font:")
// and a FilteringSelect drop down to pick a value.
// Used as Toolbar entry.
// label: [public] String
// The label to apply to this particular FontDropDown.
label: "",
// widgetsInTemplate: [public] boolean
// Over-ride denoting the template has widgets to parse.
widgetsInTemplate: true,
// plainText: [public] boolean
// Flag to indicate that the returned label should be plain text
// instead of an example.
plainText: false,
// templateString: [public] String
// The template used to construct the labeled dropdown.
templateString:
"<span style='white-space: nowrap' class='dijit dijitReset dijitInline'>" +
"<label class='dijitLeft dijitInline' for='${selectId}'>${label}</label>" +
"<input dojoType='dijit.form.FilteringSelect' required='false' labelType='html' labelAttr='label' searchAttr='name' " +
"tabIndex='-1' id='${selectId}' dojoAttachPoint='select' value=''/>" +
"</span>",
postMixInProperties: function(){
// summary:
// Over-ride to set specific properties.
this.inherited(arguments);
this.strings = dojo.i18n.getLocalization("dijit._editor", "FontChoice");
// Set some substitution variables used in the template
this.label = this.strings[this.command];
this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
this.selectId = this.id + "_select";
this.inherited(arguments);
},
postCreate: function(){
// summary:
// Over-ride for the default postCreate action
// This establishes the filtering selects and the like.
// Initialize the list of items in the drop down by creating data store with items like:
// {value: 1, name: "xx-small", label: "<font size=1>xx-small</font-size>" }
var items = dojo.map(this.values, function(value){
var name = this.strings[value] || value;
return {
label: this.getLabel(value, name),
name: name,
value: value
};
}, this);
this.select.store = new dojo.data.ItemFileReadStore({
data: {
identifier: "value",
items: items
}
});
this.select.set("value", "", false);
this.disabled = this.select.get("disabled");
},
_setValueAttr: function(value, priorityChange){
// summary:
// Over-ride for the default action of setting the
// widget value, maps the input to known values
// value: Object|String
// The value to set in the select.
// priorityChange:
// Optional parameter used to tell the select whether or not to fire
// onChange event.
//if the value is not a permitted value, just set empty string to prevent showing the warning icon
priorityChange = priorityChange !== false?true:false;
this.select.set('value', dojo.indexOf(this.values,value) < 0 ? "" : value, priorityChange);
if(!priorityChange){
// Clear the last state in case of updateState calls. Ref: #10466
this.select._lastValueReported=null;
}
},
_getValueAttr: function(){
// summary:
// Allow retreiving the value from the composite select on
// call to button.get("value");
return this.select.get('value');
},
focus: function(){
// summary:
// Over-ride for focus control of this widget. Delegates focus down to the
// filtering select.
this.select.focus();
},
_setDisabledAttr: function(value){
// summary:
// Over-ride for the button's 'disabled' attribute so that it can be
// disabled programmatically.
// Save off ths disabled state so the get retrieves it correctly
//without needing to have a function proxy it.
this.disabled = value;
this.select.set("disabled", value);
}
});
var _1c=dojo.hitch(this,function(_1d){
if(_1d&&_1d.length){
_13.beginEditing();
while(_1d.length){
this._removeFormat(_13,_1d.pop());
}
_13.endEditing();
}
dojo.declare("dijit._editor.plugins._FontNameDropDown", dijit._editor.plugins._FontDropDown, {
// summary:
// Dropdown to select a font; goes in editor toolbar.
// generic: Boolean
// Use generic (web standard) font names
generic: false,
// command: [public] String
// The editor 'command' implemented by this plugin.
command: "fontName",
postMixInProperties: function(){
// summary:
// Over-ride for the default posr mixin control
if(!this.values){
this.values = this.generic ?
["serif", "sans-serif", "monospace", "cursive", "fantasy"] : // CSS font-family generics
["Arial", "Times New Roman", "Comic Sans MS", "Courier New"];
}
this.inherited(arguments);
},
getLabel: function(value, name){
// summary:
// Function used to generate the labels of the format dropdown
// will return a formatted, or plain label based on the value
// of the plainText option.
// value: String
// The 'insert value' associated with a name
// name: String
// The text name of the value
if(this.plainText){
return name;
}else{
return "<div style='font-family: "+value+"'>" + name + "</div>";
}
},
_setValueAttr: function(value, priorityChange){
// summary:
// Over-ride for the default action of setting the
// widget value, maps the input to known values
priorityChange = priorityChange !== false?true:false;
if(this.generic){
var map = {
"Arial": "sans-serif",
"Helvetica": "sans-serif",
"Myriad": "sans-serif",
"Times": "serif",
"Times New Roman": "serif",
"Comic Sans MS": "cursive",
"Apple Chancery": "cursive",
"Courier": "monospace",
"Courier New": "monospace",
"Papyrus": "fantasy"
// ,"????": "fantasy" TODO: IE doesn't map fantasy font-family?
};
value = map[value] || value;
}
this.inherited(arguments, [value, priorityChange]);
}
});
var _1e=[];
if(_16==end){
var _1f;
_18=_16;
while(_18&&_18!==_13.editNode&&_18!==_13.document.body){
if(_18.nodeType==1){
tag=_18.tagName?_18.tagName.toLowerCase():"";
if(dojo.indexOf(this.values,tag)!==-1){
_1f=_18;
break;
}
}
_18=_18.parentNode;
}
_19(_16,_1e);
if(_1f){
_1e=[_1f].concat(_1e);
}
_1c(_1e);
}else{
_18=_16;
while(dojo.withGlobal(_13.window,"inSelection",dijit._editor.selection,[_18])){
if(_18.nodeType==1){
tag=_18.tagName?_18.tagName.toLowerCase():"";
if(dojo.indexOf(this.values,tag)!==-1){
_1e.push(_18);
}
_19(_18,_1e);
}
_18=_18.nextSibling;
}
_1c(_1e);
}
_13.onDisplayChanged();
}
}
}else{
_13.execCommand(_14,_15);
}
},_removeFormat:function(_20,_21){
if(_20.customUndo){
while(_21.firstChild){
dojo.place(_21.firstChild,_21,"before");
}
_21.parentNode.removeChild(_21);
}else{
dojo.withGlobal(_20.window,"selectElementChildren",dijit._editor.selection,[_21]);
var _22=dojo.withGlobal(_20.window,"getSelectedHtml",dijit._editor.selection,[null]);
dojo.withGlobal(_20.window,"selectElement",dijit._editor.selection,[_21]);
_20.execCommand("inserthtml",_22||"");
}
}});
dojo.declare("dijit._editor.plugins.FontChoice",dijit._editor._Plugin,{useDefaultCommand:false,_initButton:function(){
var _23={fontName:dijit._editor.plugins._FontNameDropDown,fontSize:dijit._editor.plugins._FontSizeDropDown,formatBlock:dijit._editor.plugins._FormatBlockDropDown}[this.command],_24=this.params;
if(this.params.custom){
_24.values=this.params.custom;
}
var _25=this.editor;
this.button=new _23(dojo.delegate({dir:_25.dir,lang:_25.lang},_24));
this.connect(this.button.select,"onChange",function(_26){
this.editor.focus();
if(this.command=="fontName"&&_26.indexOf(" ")!=-1){
_26="'"+_26+"'";
}
if(this.button._execCommand){
this.button._execCommand(this.editor,this.command,_26);
}else{
this.editor.execCommand(this.command,_26);
}
this.editor.customUndo=this.editor.customUndo||dojo.isWebKit;
dojo.declare("dijit._editor.plugins._FontSizeDropDown", dijit._editor.plugins._FontDropDown, {
// summary:
// Dropdown to select a font size; goes in editor toolbar.
// command: [public] String
// The editor 'command' implemented by this plugin.
command: "fontSize",
// values: [public] Number[]
// The HTML font size values supported by this plugin
values: [1,2,3,4,5,6,7], // sizes according to the old HTML FONT SIZE
getLabel: function(value, name){
// summary:
// Function used to generate the labels of the format dropdown
// will return a formatted, or plain label based on the value
// of the plainText option.
// We're stuck using the deprecated FONT tag to correspond
// with the size measurements used by the editor
// value: String
// The 'insert value' associated with a name
// name: String
// The text name of the value
if(this.plainText){
return name;
}else{
return "<font size=" + value + "'>" + name + "</font>";
}
},
_setValueAttr: function(value, priorityChange){
// summary:
// Over-ride for the default action of setting the
// widget value, maps the input to known values
priorityChange = priorityChange !== false?true:false;
if(value.indexOf && value.indexOf("px") != -1){
var pixels = parseInt(value, 10);
value = {10:1, 13:2, 16:3, 18:4, 24:5, 32:6, 48:7}[pixels] || value;
}
this.inherited(arguments, [value, priorityChange]);
}
});
},updateState:function(){
var _27=this.editor;
var _28=this.command;
if(!_27||!_27.isLoaded||!_28.length){
return;
}
if(this.button){
var _29;
try{
_29=_27.queryCommandValue(_28)||"";
}
catch(e){
_29="";
}
var _2a=dojo.isString(_29)&&_29.match(/'([^']*)'/);
if(_2a){
_29=_2a[1];
}
if(_28==="formatBlock"){
if(!_29||_29=="p"){
_29=null;
var _2b;
var sel=dijit.range.getSelection(this.editor.window);
if(sel&&sel.rangeCount>0){
var _2c=sel.getRangeAt(0);
if(_2c){
_2b=_2c.endContainer;
}
}
while(_2b&&_2b!==_27.editNode&&_2b!==_27.document){
var tg=_2b.tagName?_2b.tagName.toLowerCase():"";
if(tg&&dojo.indexOf(this.button.values,tg)>-1){
_29=tg;
break;
}
_2b=_2b.parentNode;
}
if(!_29){
_29="noFormat";
}
}else{
if(dojo.indexOf(this.button.values,_29)<0){
_29="noFormat";
}
}
}
if(_29!==this.button.get("value")){
this.button.set("value",_29,false);
}
}
}});
dojo.subscribe(dijit._scopeName+".Editor.getPlugin",null,function(o){
if(o.plugin){
return;
}
switch(o.args.name){
case "fontName":
case "fontSize":
case "formatBlock":
o.plugin=new dijit._editor.plugins.FontChoice({command:o.args.name,plainText:o.args.plainText?o.args.plainText:false});
}
dojo.declare("dijit._editor.plugins._FormatBlockDropDown", dijit._editor.plugins._FontDropDown, {
// summary:
// Dropdown to select a format (like paragraph or heading); goes in editor toolbar.
// command: [public] String
// The editor 'command' implemented by this plugin.
command: "formatBlock",
// values: [public] Array
// The HTML format tags supported by this plugin
values: ["noFormat", "p", "h1", "h2", "h3", "pre"],
postCreate: function(){
// Init and set the default value to no formatting. Update state will adjust it
// as needed.
this.inherited(arguments);
this.set("value", "noFormat", false);
},
getLabel: function(value, name){
// summary:
// Function used to generate the labels of the format dropdown
// will return a formatted, or plain label based on the value
// of the plainText option.
// value: String
// The 'insert value' associated with a name
// name: String
// The text name of the value
if(this.plainText || value == "noFormat"){
return name;
}else{
return "<" + value + ">" + name + "</" + value + ">";
}
},
_execCommand: function(editor, command, choice){
// summary:
// Over-ride for default exec-command label.
// Allows us to treat 'none' as special.
if(choice === "noFormat"){
var start;
var end;
var sel = dijit.range.getSelection(editor.window);
if(sel && sel.rangeCount > 0){
var range = sel.getRangeAt(0);
var node, tag;
if(range){
start = range.startContainer;
end = range.endContainer;
// find containing nodes of start/end.
while(start && start !== editor.editNode &&
start !== editor.document.body &&
start.nodeType !== 1){
start = start.parentNode;
}
while(end && end !== editor.editNode &&
end !== editor.document.body &&
end.nodeType !== 1){
end = end.parentNode;
}
var processChildren = dojo.hitch(this, function(node, array){
if(node.childNodes && node.childNodes.length){
var i;
for(i = 0; i < node.childNodes.length; i++){
var c = node.childNodes[i];
if(c.nodeType == 1){
if(dojo.withGlobal(editor.window, "inSelection", dijit._editor.selection, [c])){
var tag = c.tagName? c.tagName.toLowerCase(): "";
if(dojo.indexOf(this.values, tag) !== -1){
array.push(c);
}
processChildren(c,array);
}
}
}
}
});
var unformatNodes = dojo.hitch(this, function(nodes){
// summary:
// Internal function to clear format nodes.
// nodes:
// The array of nodes to strip formatting from.
if(nodes && nodes.length){
editor.beginEditing();
while(nodes.length){
this._removeFormat(editor, nodes.pop());
}
editor.endEditing();
}
});
var clearNodes = [];
if(start == end){
//Contained within the same block, may be collapsed, but who cares, see if we
// have a block element to remove.
var block;
node = start;
while(node && node !== editor.editNode && node !== editor.document.body){
if(node.nodeType == 1){
tag = node.tagName? node.tagName.toLowerCase(): "";
if(dojo.indexOf(this.values, tag) !== -1){
block = node;
break;
}
}
node = node.parentNode;
}
//Also look for all child nodes in the selection that may need to be
//cleared of formatting
processChildren(start, clearNodes);
if(block) { clearNodes = [block].concat(clearNodes); }
unformatNodes(clearNodes);
}else{
// Probably a multi select, so we have to process it. Whee.
node = start;
while(dojo.withGlobal(editor.window, "inSelection", dijit._editor.selection, [node])){
if(node.nodeType == 1){
tag = node.tagName? node.tagName.toLowerCase(): "";
if(dojo.indexOf(this.values, tag) !== -1){
clearNodes.push(node);
}
processChildren(node,clearNodes);
}
node = node.nextSibling;
}
unformatNodes(clearNodes);
}
editor.onDisplayChanged();
}
}
}else{
editor.execCommand(command, choice);
}
},
_removeFormat: function(editor, node){
// summary:
// function to remove the block format node.
// node:
// The block format node to remove (and leave the contents behind)
if(editor.customUndo){
// So of course IE doesn't work right with paste-overs.
// We have to do this manually, which is okay since IE already uses
// customUndo and we turned it on for WebKit. WebKit pasted funny,
// so couldn't use the execCommand approach
while(node.firstChild){
dojo.place(node.firstChild, node, "before");
}
node.parentNode.removeChild(node);
}else{
// Everyone else works fine this way, a paste-over and is native
// undo friendly.
dojo.withGlobal(editor.window,
"selectElementChildren", dijit._editor.selection, [node]);
var html = dojo.withGlobal(editor.window,
"getSelectedHtml", dijit._editor.selection, [null]);
dojo.withGlobal(editor.window,
"selectElement", dijit._editor.selection, [node]);
editor.execCommand("inserthtml", html||"");
}
}
});
// TODO: for 2.0, split into FontChoice plugin into three separate classes,
// one for each command (and change registry below)
dojo.declare("dijit._editor.plugins.FontChoice", dijit._editor._Plugin,{
// summary:
// This plugin provides three drop downs for setting style in the editor
// (font, font size, and format block), as controlled by command.
//
// description:
// The commands provided by this plugin are:
//
// * fontName
// | Provides a drop down to select from a list of font names
// * fontSize
// | Provides a drop down to select from a list of font sizes
// * formatBlock
// | Provides a drop down to select from a list of block styles
// |
//
// which can easily be added to an editor by including one or more of the above commands
// in the `plugins` attribute as follows:
//
// | plugins="['fontName','fontSize',...]"
//
// It is possible to override the default dropdown list by providing an Array for the `custom` property when
// instantiating this plugin, e.g.
//
// | plugins="[{name:'dijit._editor.plugins.FontChoice', command:'fontName', custom:['Verdana','Myriad','Garamond']},...]"
//
// Alternatively, for `fontName` only, `generic:true` may be specified to provide a dropdown with
// [CSS generic font families](http://www.w3.org/TR/REC-CSS2/fonts.html#generic-font-families)
//
// Note that the editor is often unable to properly handle font styling information defined outside
// the context of the current editor instance, such as pre-populated HTML.
// useDefaultCommand: [protected] booleam
// Override _Plugin.useDefaultCommand...
// processing is handled by this plugin, not by dijit.Editor.
useDefaultCommand: false,
_initButton: function(){
// summary:
// Overrides _Plugin._initButton(), to initialize the FilteringSelect+label in toolbar,
// rather than a simple button.
// tags:
// protected
// Create the widget to go into the toolbar (the so-called "button")
var clazz = {
fontName: dijit._editor.plugins._FontNameDropDown,
fontSize: dijit._editor.plugins._FontSizeDropDown,
formatBlock: dijit._editor.plugins._FormatBlockDropDown
}[this.command],
params = this.params;
// For back-compat reasons support setting custom values via "custom" parameter
// rather than "values" parameter
if(this.params.custom){
params.values = this.params.custom;
}
var editor = this.editor;
this.button = new clazz(dojo.delegate({dir: editor.dir, lang: editor.lang}, params));
// Reflect changes to the drop down in the editor
this.connect(this.button.select, "onChange", function(choice){
// User invoked change, since all internal updates set priorityChange to false and will
// not trigger an onChange event.
this.editor.focus();
if(this.command == "fontName" && choice.indexOf(" ") != -1){ choice = "'" + choice + "'"; }
// Invoke, the editor already normalizes commands called through its
// execCommand.
if(this.button._execCommand){
this.button._execCommand(this.editor, this.command, choice);
}else{
this.editor.execCommand(this.command, choice);
}
});
},
updateState: function(){
// summary:
// Overrides _Plugin.updateState(). This controls updating the menu
// options to the right values on state changes in the document (that trigger a
// test of the actions.)
// It set value of drop down in toolbar to reflect font/font size/format block
// of text at current caret position.
// tags:
// protected
var _e = this.editor;
var _c = this.command;
if(!_e || !_e.isLoaded || !_c.length){ return; }
if(this.button){
var disabled = this.get("disabled");
this.button.set("disabled", disabled);
if(disabled){ return; }
var value;
try{
value = _e.queryCommandValue(_c) || "";
}catch(e){
//Firefox may throw error above if the editor is just loaded, ignore it
value = "";
}
// strip off single quotes, if any
var quoted = dojo.isString(value) && value.match(/'([^']*)'/);
if(quoted){ value = quoted[1]; }
if(_c === "formatBlock"){
if(!value || value == "p"){
// Some browsers (WebKit) doesn't actually get the tag info right.
// and IE returns paragraph when in a DIV!, so incorrect a lot,
// so we have double-check it.
value = null;
var elem;
// Try to find the current element where the caret is.
var sel = dijit.range.getSelection(this.editor.window);
if(sel && sel.rangeCount > 0){
var range = sel.getRangeAt(0);
if(range){
elem = range.endContainer;
}
}
// Okay, now see if we can find one of the formatting types we're in.
while(elem && elem !== _e.editNode && elem !== _e.document){
var tg = elem.tagName?elem.tagName.toLowerCase():"";
if(tg && dojo.indexOf(this.button.values, tg) > -1){
value = tg;
break;
}
elem = elem.parentNode;
}
if(!value){
// Still no value, so lets select 'none'.
value = "noFormat";
}
}else{
// Check that the block format is one allowed, if not,
// null it so that it gets set to empty.
if(dojo.indexOf(this.button.values, value) < 0){
value = "noFormat";
}
}
}
if(value !== this.button.get("value")){
// Set the value, but denote it is not a priority change, so no
// onchange fires.
this.button.set('value', value, false);
}
}
}
});
// Register this plugin.
dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
if(o.plugin){ return; }
switch(o.args.name){
case "fontName": case "fontSize": case "formatBlock":
o.plugin = new dijit._editor.plugins.FontChoice({
command: o.args.name,
plainText: o.args.plainText?o.args.plainText:false
});
}
});
}

View File

@@ -1,232 +1,441 @@
/*
Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
if(!dojo._hasResource["dijit._editor.plugins.FullScreen"]){
dojo._hasResource["dijit._editor.plugins.FullScreen"]=true;
if(!dojo._hasResource["dijit._editor.plugins.FullScreen"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit._editor.plugins.FullScreen"] = true;
dojo.provide("dijit._editor.plugins.FullScreen");
dojo.require("dojo.window");
dojo.require("dojo.i18n");
dojo.require("dijit._editor._Plugin");
dojo.require("dijit.form.Button");
dojo.requireLocalization("dijit._editor","commands",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw");
dojo.declare("dijit._editor.plugins.FullScreen",dijit._editor._Plugin,{zIndex:500,_origState:null,_origiFrameState:null,_resizeHandle:null,isFullscreen:false,toggle:function(){
this.button.set("checked",!this.button.get("checked"));
},_initButton:function(){
var _1=dojo.i18n.getLocalization("dijit._editor","commands"),_2=this.editor;
this.button=new dijit.form.ToggleButton({label:_1["fullScreen"],dir:_2.dir,lang:_2.lang,showLabel:false,iconClass:this.iconClassPrefix+" "+this.iconClassPrefix+"FullScreen",tabIndex:"-1",onChange:dojo.hitch(this,"_setFullScreen")});
},setEditor:function(_3){
this.editor=_3;
this._initButton();
this.editor.addKeyHandler(dojo.keys.F11,true,true,dojo.hitch(this,function(e){
this.toggle();
dojo.stopEvent(e);
setTimeout(dojo.hitch(this,function(){
this.editor.focus();
}),250);
return true;
}));
this.connect(this.editor.domNode,"onkeydown","_containFocus");
},_containFocus:function(e){
if(this.isFullscreen){
var ed=this.editor;
if(!ed.isTabIndent&&ed._fullscreen_oldOnKeyDown&&e.keyCode===dojo.keys.TAB){
var f=dijit.getFocus();
var _4=this._getAltViewNode();
if(f.node==ed.iframe||(_4&&f.node===_4)){
setTimeout(dojo.hitch(this,function(){
ed.toolbar.focus();
}),10);
}else{
if(_4&&dojo.style(ed.iframe,"display")==="none"){
setTimeout(dojo.hitch(this,function(){
dijit.focus(_4);
}),10);
}else{
setTimeout(dojo.hitch(this,function(){
ed.focus();
}),10);
}
}
dojo.stopEvent(e);
}else{
if(ed._fullscreen_oldOnKeyDown){
ed._fullscreen_oldOnKeyDown(e);
}
}
}
},_resizeEditor:function(){
var vp=dojo.window.getBox();
dojo.marginBox(this.editor.domNode,{w:vp.w,h:vp.h});
var _5=this.editor.getHeaderHeight();
var _6=this.editor.getFooterHeight();
var _7=dojo._getPadBorderExtents(this.editor.domNode);
var _8=dojo._getPadBorderExtents(this.editor.iframe.parentNode);
var _9=dojo._getMarginExtents(this.editor.iframe.parentNode);
var _a=vp.h-(_5+_7.h+_6);
dojo.marginBox(this.editor.iframe.parentNode,{h:_a,w:vp.w});
dojo.marginBox(this.editor.iframe,{h:_a-(_8.h+_9.h)});
},_getAltViewNode:function(){
},_setFullScreen:function(_b){
var vp=dojo.window.getBox();
var ed=this.editor;
var _c=dojo.body();
var _d=ed.domNode.parentNode;
this.isFullscreen=_b;
if(_b){
while(_d&&_d!==dojo.body()){
dojo.addClass(_d,"dijitForceStatic");
_d=_d.parentNode;
}
this._editorResizeHolder=this.editor.resize;
ed.resize=function(){
};
ed._fullscreen_oldOnKeyDown=ed.onKeyDown;
ed.onKeyDown=dojo.hitch(this,this._containFocus);
this._origState={};
this._origiFrameState={};
var _e=ed.domNode,_f=_e&&_e.style||{};
this._origState={width:_f.width||"",height:_f.height||"",top:dojo.style(_e,"top")||"",left:dojo.style(_e,"left")||"",position:dojo.style(_e,"position")||"static",marginBox:dojo.marginBox(ed.domNode)};
var _10=ed.iframe,_11=_10&&_10.style||{};
var bc=dojo.style(ed.iframe,"backgroundColor");
this._origiFrameState={backgroundColor:bc||"transparent",width:_11.width||"auto",height:_11.height||"auto",zIndex:_11.zIndex||""};
dojo.style(ed.domNode,{position:"absolute",top:"0px",left:"0px",zIndex:this.zIndex,width:vp.w+"px",height:vp.h+"px"});
dojo.style(ed.iframe,{height:"100%",width:"100%",zIndex:this.zIndex,backgroundColor:bc!=="transparent"&&bc!=="rgba(0, 0, 0, 0)"?bc:"white"});
dojo.style(ed.iframe.parentNode,{height:"95%",width:"100%"});
if(_c.style&&_c.style.overflow){
this._oldOverflow=dojo.style(_c,"overflow");
}else{
this._oldOverflow="";
}
if(dojo.isIE&&!dojo.isQuirks){
if(_c.parentNode&&_c.parentNode.style&&_c.parentNode.style.overflow){
this._oldBodyParentOverflow=_c.parentNode.style.overflow;
}else{
try{
this._oldBodyParentOverflow=dojo.style(_c.parentNode,"overflow");
}
catch(e){
this._oldBodyParentOverflow="scroll";
}
}
dojo.style(_c.parentNode,"overflow","hidden");
}
dojo.style(_c,"overflow","hidden");
var _12=function(){
var vp=dojo.window.getBox();
if("_prevW" in this&&"_prevH" in this){
if(vp.w===this._prevW&&vp.h===this._prevH){
return;
}
}else{
this._prevW=vp.w;
this._prevH=vp.h;
}
if(this._resizer){
clearTimeout(this._resizer);
delete this._resizer;
}
this._resizer=setTimeout(dojo.hitch(this,function(){
delete this._resizer;
this._resizeEditor();
}),10);
};
this._resizeHandle=dojo.connect(window,"onresize",this,_12);
this._resizeHandle2=dojo.connect(ed,"resize",dojo.hitch(this,function(){
if(this._resizer){
clearTimeout(this._resizer);
delete this._resizer;
}
this._resizer=setTimeout(dojo.hitch(this,function(){
delete this._resizer;
this._resizeEditor();
}),10);
}));
this._resizeEditor();
var dn=this.editor.toolbar.domNode;
setTimeout(function(){
dojo.window.scrollIntoView(dn);
},250);
}else{
if(this._resizeHandle){
dojo.disconnect(this._resizeHandle);
this._resizeHandle=null;
}
if(this._resizeHandle2){
dojo.disconnect(this._resizeHandle2);
this._resizeHandle2=null;
}
if(this._rst){
clearTimeout(this._rst);
this._rst=null;
}
while(_d&&_d!==dojo.body()){
dojo.removeClass(_d,"dijitForceStatic");
_d=_d.parentNode;
}
if(this._editorResizeHolder){
this.editor.resize=this._editorResizeHolder;
}
if(!this._origState&&!this._origiFrameState){
return;
}
if(ed._fullscreen_oldOnKeyDown){
ed.onKeyDown=ed._fullscreen_oldOnKeyDown;
delete ed._fullscreen_oldOnKeyDown;
}
var _13=this;
setTimeout(function(){
var mb=_13._origState.marginBox;
var oh=_13._origState.height;
if(dojo.isIE&&!dojo.isQuirks){
_c.parentNode.style.overflow=_13._oldBodyParentOverflow;
delete _13._oldBodyParentOverflow;
}
dojo.style(_c,"overflow",_13._oldOverflow);
delete _13._oldOverflow;
dojo.style(ed.domNode,_13._origState);
dojo.style(ed.iframe.parentNode,{height:"",width:""});
dojo.style(ed.iframe,_13._origiFrameState);
delete _13._origState;
delete _13._origiFrameState;
var _14=dijit.getEnclosingWidget(ed.domNode.parentNode);
if(_14&&_14.resize){
_14.resize();
}else{
if(!oh||oh.indexOf("%")<0){
setTimeout(dojo.hitch(this,function(){
ed.resize({h:mb.h});
}),0);
}
}
dojo.window.scrollIntoView(_13.editor.toolbar.domNode);
},100);
}
},destroy:function(){
if(this._resizeHandle){
dojo.disconnect(this._resizeHandle);
this._resizeHandle=null;
}
if(this._resizeHandle2){
dojo.disconnect(this._resizeHandle2);
this._resizeHandle2=null;
}
if(this._resizer){
clearTimeout(this._resizer);
this._resizer=null;
}
this.inherited(arguments);
}});
dojo.subscribe(dijit._scopeName+".Editor.getPlugin",null,function(o){
if(o.plugin){
return;
}
var _15=o.args.name.toLowerCase();
if(_15==="fullscreen"){
o.plugin=new dijit._editor.plugins.FullScreen({zIndex:("zIndex" in o.args)?o.args.zIndex:500});
}
dojo.requireLocalization("dijit._editor", "commands", null, "ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,kk,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw");
dojo.declare("dijit._editor.plugins.FullScreen",dijit._editor._Plugin,{
// summary:
// This plugin provides FullScreen cabability to the editor. When
// toggled on, it will render the editor into the full window and
// overlay everything. It also binds to the hotkey: CTRL-SHIFT-F11
// for toggling fullscreen mode.
// zIndex: [public] Number
// zIndex value used for overlaying the full page.
// default is 500.
zIndex: 500,
// _origState: [private] Object
// The original view state of the editor.
_origState: null,
// _origiFrameState: [private] Object
// The original view state of the iframe of the editor.
_origiFrameState: null,
// _resizeHandle: [private] Object
// Connection point used for handling resize when window resizes.
_resizeHandle: null,
// isFullscreen: [const] boolean
// Read-Only variable used to denote of the editor is in fullscreen mode or not.
isFullscreen: false,
toggle: function(){
// summary:
// Function to allow programmatic toggling of the view.
this.button.set("checked", !this.button.get("checked"));
},
_initButton: function(){
// summary:
// Over-ride for creation of the resize button.
var strings = dojo.i18n.getLocalization("dijit._editor", "commands"),
editor = this.editor;
this.button = new dijit.form.ToggleButton({
label: strings["fullScreen"],
dir: editor.dir,
lang: editor.lang,
showLabel: false,
iconClass: this.iconClassPrefix + " " + this.iconClassPrefix + "FullScreen",
tabIndex: "-1",
onChange: dojo.hitch(this, "_setFullScreen")
});
},
setEditor: function(editor){
// summary:
// Over-ride for the setting of the editor.
// editor: Object
// The editor to configure for this plugin to use.
this.editor = editor;
this._initButton();
this.editor.addKeyHandler(dojo.keys.F11, true, true, dojo.hitch(this, function(e){
// Enable the CTRL-SHIFT-F11 hotkey for fullscreen mode.
this.toggle();
dojo.stopEvent(e);
setTimeout(dojo.hitch(this, function(){this.editor.focus();}), 250);
return true;
}));
this.connect(this.editor.domNode, "onkeydown", "_containFocus");
},
_containFocus: function(e){
// summary:
// When in Full Screen mode, it's good to try and retain focus in the editor
// so this function is intended to try and constrain the TAB key.
// e: Event
// The key event.
// tags:
// private
if(this.isFullscreen){
var ed = this.editor;
if(!ed.isTabIndent &&
ed._fullscreen_oldOnKeyDown &&
e.keyCode === dojo.keys.TAB){
// If we're in fullscreen mode, we want to take over how tab moves focus a bit.
// to keep it within the editor since it's hiding the rest of the page.
// IE hates changing focus IN the event handler, so need to put calls
// in a timeout. Gotta love IE.
// Also need to check for alternate view nodes if present and active.
var f = dijit.getFocus();
var avn = this._getAltViewNode();
if(f.node == ed.iframe ||
(avn && f.node === avn)){
setTimeout(dojo.hitch(this, function(){
ed.toolbar.focus();
}), 10);
}else{
if(avn && dojo.style(ed.iframe, "display") === "none"){
setTimeout(dojo.hitch(this, function(){
dijit.focus(avn);
}), 10);
}else{
setTimeout(dojo.hitch(this, function(){
ed.focus();
}), 10);
}
}
dojo.stopEvent(e);
}else if(ed._fullscreen_oldOnKeyDown){
// Only call up when it's a different function. Traps corner case event issue
// on IE which caused stack overflow on handler cleanup.
ed._fullscreen_oldOnKeyDown(e);
}
}
},
_resizeEditor: function(){
// summary:
// Function to handle resizing the editor as the viewport
// resizes (window scaled)
// tags:
// private
var vp = dojo.window.getBox();
dojo.marginBox(this.editor.domNode, {
w: vp.w,
h: vp.h
});
//Adjust the inernal heights too, as they can be a bit off.
var hHeight = this.editor.getHeaderHeight();
var fHeight = this.editor.getFooterHeight();
var extents = dojo._getPadBorderExtents(this.editor.domNode);
var fcpExtents = dojo._getPadBorderExtents(this.editor.iframe.parentNode);
var fcmExtents = dojo._getMarginExtents(this.editor.iframe.parentNode);
var cHeight = vp.h - (hHeight + extents.h + fHeight);
dojo.marginBox(this.editor.iframe.parentNode, {
h: cHeight,
w: vp.w
});
dojo.marginBox(this.editor.iframe, {
h: cHeight - (fcpExtents.h + fcmExtents.h)
});
},
_getAltViewNode: function(){
// summary:
// This function is intended as a hook point for setting an
// alternate view node for when in full screen mode and the
// editable iframe is hidden.
// tags:
// protected.
},
_setFullScreen: function(full){
// summary:
// Function to handle toggling between full screen and
// regular view.
// tags:
// private
var vp = dojo.window.getBox();
//Alias this for shorter code.
var ed = this.editor;
var body = dojo.body();
var editorParent = ed.domNode.parentNode;
this.isFullscreen = full;
if(full){
//Parent classes can royally screw up this plugin, so we
//have to set eveything to position static.
while(editorParent && editorParent !== dojo.body()){
dojo.addClass(editorParent, "dijitForceStatic");
editorParent = editorParent.parentNode;
}
// Save off the resize function. We want to kill its behavior.
this._editorResizeHolder = this.editor.resize;
ed.resize = function() {} ;
// Try to constrain focus control.
ed._fullscreen_oldOnKeyDown = ed.onKeyDown;
ed.onKeyDown = dojo.hitch(this, this._containFocus);
this._origState = {};
this._origiFrameState = {};
// Store the basic editor state we have to restore later.
// Not using dojo.style here, had problems, didn't
// give me stuff like 100%, gave me pixel calculated values.
// Need the exact original values.
var domNode = ed.domNode,
domStyle = domNode && domNode.style || {};
this._origState = {
width: domStyle.width || "",
height: domStyle.height || "",
top: dojo.style(domNode, "top") || "",
left: dojo.style(domNode, "left") || "",
position: dojo.style(domNode, "position") || "static",
marginBox: dojo.marginBox(ed.domNode)
};
// Store the iframe state we have to restore later.
// Not using dojo.style here, had problems, didn't
// give me stuff like 100%, gave me pixel calculated values.
// Need the exact original values.
var iframe = ed.iframe,
iframeStyle = iframe && iframe.style || {};
var bc = dojo.style(ed.iframe, "backgroundColor");
this._origiFrameState = {
backgroundColor: bc || "transparent",
width: iframeStyle.width || "auto",
height: iframeStyle.height || "auto",
zIndex: iframeStyle.zIndex || ""
};
// Okay, size everything.
dojo.style(ed.domNode, {
position: "absolute",
top: "0px",
left: "0px",
zIndex: this.zIndex,
width: vp.w + "px",
height: vp.h + "px"
});
dojo.style(ed.iframe, {
height: "100%",
width: "100%",
zIndex: this.zIndex,
backgroundColor: bc !== "transparent" &&
bc !== "rgba(0, 0, 0, 0)"?bc:"white"
});
dojo.style(ed.iframe.parentNode, {
height: "95%",
width: "100%"
});
// Store the overflow state we have to restore later.
// IE had issues, so have to check that it's defined. Ugh.
if(body.style && body.style.overflow){
this._oldOverflow = dojo.style(body, "overflow");
}else{
this._oldOverflow = "";
}
if(dojo.isIE && !dojo.isQuirks){
// IE will put scrollbars in anyway, html (parent of body)
// also controls them in standards mode, so we have to
// remove them, argh.
if(body.parentNode &&
body.parentNode.style &&
body.parentNode.style.overflow){
this._oldBodyParentOverflow = body.parentNode.style.overflow;
}else{
try{
this._oldBodyParentOverflow = dojo.style(body.parentNode, "overflow");
}catch(e){
this._oldBodyParentOverflow = "scroll";
}
}
dojo.style(body.parentNode, "overflow", "hidden");
}
dojo.style(body, "overflow", "hidden");
var resizer = function(){
// function to handle resize events.
// Will check current VP and only resize if
// different.
var vp = dojo.window.getBox();
if("_prevW" in this && "_prevH" in this){
// No actual size change, ignore.
if(vp.w === this._prevW && vp.h === this._prevH){
return;
}
}else{
this._prevW = vp.w;
this._prevH = vp.h;
}
if(this._resizer){
clearTimeout(this._resizer);
delete this._resizer;
}
// Timeout it to help avoid spamming resize on IE.
// Works for all browsers.
this._resizer = setTimeout(dojo.hitch(this, function(){
delete this._resizer;
this._resizeEditor();
}), 10);
};
this._resizeHandle = dojo.connect(window, "onresize", this, resizer);
// Also monitor for direct calls to resize and adapt editor.
this._resizeHandle2 = dojo.connect(ed, "resize", dojo.hitch(this, function(){
if(this._resizer){
clearTimeout(this._resizer);
delete this._resizer;
}
this._resizer = setTimeout(dojo.hitch(this, function(){
delete this._resizer;
this._resizeEditor();
}), 10);
}));
// Call it once to work around IE glitchiness. Safe for other browsers too.
this._resizeEditor();
var dn = this.editor.toolbar.domNode;
setTimeout(function(){dojo.window.scrollIntoView(dn);}, 250);
}else{
if(this._resizeHandle){
// Cleanup resizing listeners
dojo.disconnect(this._resizeHandle);
this._resizeHandle = null;
}
if(this._resizeHandle2){
// Cleanup resizing listeners
dojo.disconnect(this._resizeHandle2);
this._resizeHandle2 = null;
}
if(this._rst){
clearTimeout(this._rst);
this._rst = null;
}
//Remove all position static class assigns.
while(editorParent && editorParent !== dojo.body()){
dojo.removeClass(editorParent, "dijitForceStatic");
editorParent = editorParent.parentNode;
}
// Restore resize function
if(this._editorResizeHolder){
this.editor.resize = this._editorResizeHolder;
}
if(!this._origState && !this._origiFrameState){
// If we actually didn't toggle, then don't do anything.
return;
}
if(ed._fullscreen_oldOnKeyDown){
ed.onKeyDown = ed._fullscreen_oldOnKeyDown;
delete ed._fullscreen_oldOnKeyDown;
}
// Add a timeout to make sure we don't have a resize firing in the
// background at the time of minimize.
var self = this;
setTimeout(function(){
// Restore all the editor state.
var mb = self._origState.marginBox;
var oh = self._origState.height;
if(dojo.isIE && !dojo.isQuirks){
body.parentNode.style.overflow = self._oldBodyParentOverflow;
delete self._oldBodyParentOverflow;
}
dojo.style(body, "overflow", self._oldOverflow);
delete self._oldOverflow;
dojo.style(ed.domNode, self._origState);
dojo.style(ed.iframe.parentNode, {
height: "",
width: ""
});
dojo.style(ed.iframe, self._origiFrameState);
delete self._origState;
delete self._origiFrameState;
// In case it is contained in a layout and the layout changed size,
// go ahead and call resize.
var pWidget = dijit.getEnclosingWidget(ed.domNode.parentNode);
if(pWidget && pWidget.resize){
pWidget.resize();
}else{
if(!oh || oh.indexOf("%") < 0){
// Resize if the original size wasn't set
// or wasn't in percent. Timeout is to avoid
// an IE crash in unit testing.
setTimeout(dojo.hitch(this, function(){ed.resize({h: mb.h});}), 0);
}
}
dojo.window.scrollIntoView(self.editor.toolbar.domNode);
}, 100);
}
},
updateState: function(){
// summary:
// Over-ride for button state control for disabled to work.
this.button.set("disabled", this.get("disabled"));
},
destroy: function(){
// summary:
// Over-ride to ensure the resize handle gets cleaned up.
if(this._resizeHandle){
// Cleanup resizing listeners
dojo.disconnect(this._resizeHandle);
this._resizeHandle = null;
}
if(this._resizeHandle2){
// Cleanup resizing listeners
dojo.disconnect(this._resizeHandle2);
this._resizeHandle2 = null;
}
if(this._resizer){
clearTimeout(this._resizer);
this._resizer = null;
}
this.inherited(arguments);
}
});
// Register this plugin.
dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
if(o.plugin){ return; }
var name = o.args.name.toLowerCase();
if(name === "fullscreen"){
o.plugin = new dijit._editor.plugins.FullScreen({
zIndex: ("zIndex" in o.args)?o.args.zIndex:500
});
}
});
}

View File

@@ -1,236 +1,516 @@
/*
Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
if(!dojo._hasResource["dijit._editor.plugins.LinkDialog"]){
dojo._hasResource["dijit._editor.plugins.LinkDialog"]=true;
if(!dojo._hasResource["dijit._editor.plugins.LinkDialog"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit._editor.plugins.LinkDialog"] = true;
dojo.provide("dijit._editor.plugins.LinkDialog");
dojo.require("dijit._Widget");
dojo.require("dijit._Templated");
dojo.require("dijit._editor._Plugin");
dojo.require("dijit.TooltipDialog");
dojo.require("dijit.form.Button");
dojo.require("dijit.form.DropDownButton");
dojo.require("dijit.form.ValidationTextBox");
dojo.require("dijit.form.Select");
dojo.require("dijit._editor.range");
dojo.require("dojo.i18n");
dojo.require("dojo.string");
dojo.requireLocalization("dijit","common",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw");
dojo.requireLocalization("dijit._editor","LinkDialog",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw");
dojo.declare("dijit._editor.plugins.LinkDialog",dijit._editor._Plugin,{buttonClass:dijit.form.DropDownButton,useDefaultCommand:false,urlRegExp:"((https?|ftps?|file)\\://|./|/|)(/[a-zA-Z]{1,1}:/|)(((?:(?:[\\da-zA-Z](?:[-\\da-zA-Z]{0,61}[\\da-zA-Z])?)\\.)*(?:[a-zA-Z](?:[-\\da-zA-Z]{0,80}[\\da-zA-Z])?)\\.?)|(((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])|(0[xX]0*[\\da-fA-F]?[\\da-fA-F]\\.){3}0[xX]0*[\\da-fA-F]?[\\da-fA-F]|(0+[0-3][0-7][0-7]\\.){3}0+[0-3][0-7][0-7]|(0|[1-9]\\d{0,8}|[1-3]\\d{9}|4[01]\\d{8}|42[0-8]\\d{7}|429[0-3]\\d{6}|4294[0-8]\\d{5}|42949[0-5]\\d{4}|429496[0-6]\\d{3}|4294967[01]\\d{2}|42949672[0-8]\\d|429496729[0-5])|0[xX]0*[\\da-fA-F]{1,8}|([\\da-fA-F]{1,4}\\:){7}[\\da-fA-F]{1,4}|([\\da-fA-F]{1,4}\\:){6}((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])))(\\:\\d+)?(/(?:[^?#\\s/]+/)*(?:[^?#\\s/]+(?:\\?[^?#\\s/]*)?(?:#.*)?)?)?",emailRegExp:"<?(mailto\\:)([!#-'*+\\-\\/-9=?A-Z^-~]+[.])*[!#-'*+\\-\\/-9=?A-Z^-~]+"+"@"+"((?:(?:[\\da-zA-Z](?:[-\\da-zA-Z]{0,61}[\\da-zA-Z])?)\\.)+(?:[a-zA-Z](?:[-\\da-zA-Z]{0,6}[\\da-zA-Z])?)\\.?)|localhost|^[^-][a-zA-Z0-9_-]*>?",htmlTemplate:"<a href=\"${urlInput}\" _djrealurl=\"${urlInput}\""+" target=\"${targetSelect}\""+">${textInput}</a>",tag:"a",_hostRxp:new RegExp("^((([^\\[:]+):)?([^@]+)@)?(\\[([^\\]]+)\\]|([^\\[:]*))(:([0-9]+))?$"),_userAtRxp:new RegExp("^([!#-'*+\\-\\/-9=?A-Z^-~]+[.])*[!#-'*+\\-\\/-9=?A-Z^-~]+@","i"),linkDialogTemplate:["<table><tr><td>","<label for='${id}_urlInput'>${url}</label>","</td><td>","<input dojoType='dijit.form.ValidationTextBox' required='true' "+"id='${id}_urlInput' name='urlInput' intermediateChanges='true'>","</td></tr><tr><td>","<label for='${id}_textInput'>${text}</label>","</td><td>","<input dojoType='dijit.form.ValidationTextBox' required='true' id='${id}_textInput' "+"name='textInput' intermediateChanges='true'>","</td></tr><tr><td>","<label for='${id}_targetSelect'>${target}</label>","</td><td>","<select id='${id}_targetSelect' name='targetSelect' dojoType='dijit.form.Select'>","<option selected='selected' value='_self'>${currentWindow}</option>","<option value='_blank'>${newWindow}</option>","<option value='_top'>${topWindow}</option>","<option value='_parent'>${parentWindow}</option>","</select>","</td></tr><tr><td colspan='2'>","<button dojoType='dijit.form.Button' type='submit' id='${id}_setButton'>${set}</button>","<button dojoType='dijit.form.Button' type='button' id='${id}_cancelButton'>${buttonCancel}</button>","</td></tr></table>"].join(""),_initButton:function(){
var _1=this;
this.tag=this.command=="insertImage"?"img":"a";
var _2=dojo.mixin(dojo.i18n.getLocalization("dijit","common",this.lang),dojo.i18n.getLocalization("dijit._editor","LinkDialog",this.lang));
var _3=(this.dropDown=new dijit.TooltipDialog({title:_2[this.command+"Title"],execute:dojo.hitch(this,"setValue"),onOpen:function(){
_1._onOpenDialog();
dijit.TooltipDialog.prototype.onOpen.apply(this,arguments);
},onCancel:function(){
setTimeout(dojo.hitch(_1,"_onCloseDialog"),0);
}}));
_2.urlRegExp=this.urlRegExp;
_2.id=dijit.getUniqueId(this.editor.id);
this._uniqueId=_2.id;
this._setContent(_3.title+"<div style='border-bottom: 1px black solid;padding-bottom:2pt;margin-bottom:4pt'></div>"+dojo.string.substitute(this.linkDialogTemplate,_2));
_3.startup();
this._urlInput=dijit.byId(this._uniqueId+"_urlInput");
this._textInput=dijit.byId(this._uniqueId+"_textInput");
this._setButton=dijit.byId(this._uniqueId+"_setButton");
this.connect(dijit.byId(this._uniqueId+"_cancelButton"),"onClick",function(){
this.dropDown.onCancel();
dojo.requireLocalization("dijit", "common", null, "ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,kk,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw");
dojo.requireLocalization("dijit._editor", "LinkDialog", null, "ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,kk,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw");
dojo.declare("dijit._editor.plugins.LinkDialog", dijit._editor._Plugin, {
// summary:
// This plugin provides the basis for an 'anchor' (link) dialog and an extension of it
// provides the image link dialog.
//
// description:
// The command provided by this plugin is:
// * createLink
// Override _Plugin.buttonClass. This plugin is controlled by a DropDownButton
// (which triggers a TooltipDialog).
buttonClass: dijit.form.DropDownButton,
// Override _Plugin.useDefaultCommand... processing is handled by this plugin, not by dijit.Editor.
useDefaultCommand: false,
// urlRegExp: [protected] String
// Used for validating input as correct URL. While file:// urls are not terribly
// useful, they are technically valid.
urlRegExp: "((https?|ftps?|file)\\://|\./|/|)(/[a-zA-Z]{1,1}:/|)(((?:(?:[\\da-zA-Z](?:[-\\da-zA-Z]{0,61}[\\da-zA-Z])?)\\.)*(?:[a-zA-Z](?:[-\\da-zA-Z]{0,80}[\\da-zA-Z])?)\\.?)|(((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])|(0[xX]0*[\\da-fA-F]?[\\da-fA-F]\\.){3}0[xX]0*[\\da-fA-F]?[\\da-fA-F]|(0+[0-3][0-7][0-7]\\.){3}0+[0-3][0-7][0-7]|(0|[1-9]\\d{0,8}|[1-3]\\d{9}|4[01]\\d{8}|42[0-8]\\d{7}|429[0-3]\\d{6}|4294[0-8]\\d{5}|42949[0-5]\\d{4}|429496[0-6]\\d{3}|4294967[01]\\d{2}|42949672[0-8]\\d|429496729[0-5])|0[xX]0*[\\da-fA-F]{1,8}|([\\da-fA-F]{1,4}\\:){7}[\\da-fA-F]{1,4}|([\\da-fA-F]{1,4}\\:){6}((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])))(\\:\\d+)?(/(?:[^?#\\s/]+/)*(?:[^?#\\s/]{0,}(?:\\?[^?#\\s/]*)?(?:#.*)?)?)?",
// emailRegExp: [protected] String
// Used for validating input as correct email address. Taken from dojox.validate
emailRegExp: "<?(mailto\\:)([!#-'*+\\-\\/-9=?A-Z^-~]+[.])*[!#-'*+\\-\\/-9=?A-Z^-~]+" /*username*/ + "@" +
"((?:(?:[\\da-zA-Z](?:[-\\da-zA-Z]{0,61}[\\da-zA-Z])?)\\.)+(?:[a-zA-Z](?:[-\\da-zA-Z]{0,6}[\\da-zA-Z])?)\\.?)|localhost|^[^-][a-zA-Z0-9_-]*>?", // host.
// htmlTemplate: [protected] String
// String used for templating the HTML to insert at the desired point.
htmlTemplate: "<a href=\"${urlInput}\" _djrealurl=\"${urlInput}\"" +
" target=\"${targetSelect}\"" +
">${textInput}</a>",
// tag: [protected] String
// Tag used for the link type.
tag: "a",
// _hostRxp [private] RegExp
// Regular expression used to validate url fragments (ip address, hostname, etc)
_hostRxp: new RegExp("^((([^\\[:]+):)?([^@]+)@)?(\\[([^\\]]+)\\]|([^\\[:]*))(:([0-9]+))?$"),
// _userAtRxp [private] RegExp
// Regular expression used to validate e-mail address fragment.
_userAtRxp: new RegExp("^([!#-'*+\\-\\/-9=?A-Z^-~]+[.])*[!#-'*+\\-\\/-9=?A-Z^-~]+@", "i"),
// linkDialogTemplate: [protected] String
// Template for contents of TooltipDialog to pick URL
linkDialogTemplate: [
"<table><tr><td>",
"<label for='${id}_urlInput'>${url}</label>",
"</td><td>",
"<input dojoType='dijit.form.ValidationTextBox' required='true' " +
"id='${id}_urlInput' name='urlInput' intermediateChanges='true'/>",
"</td></tr><tr><td>",
"<label for='${id}_textInput'>${text}</label>",
"</td><td>",
"<input dojoType='dijit.form.ValidationTextBox' required='true' id='${id}_textInput' " +
"name='textInput' intermediateChanges='true'/>",
"</td></tr><tr><td>",
"<label for='${id}_targetSelect'>${target}</label>",
"</td><td>",
"<select id='${id}_targetSelect' name='targetSelect' dojoType='dijit.form.Select'>",
"<option selected='selected' value='_self'>${currentWindow}</option>",
"<option value='_blank'>${newWindow}</option>",
"<option value='_top'>${topWindow}</option>",
"<option value='_parent'>${parentWindow}</option>",
"</select>",
"</td></tr><tr><td colspan='2'>",
"<button dojoType='dijit.form.Button' type='submit' id='${id}_setButton'>${set}</button>",
"<button dojoType='dijit.form.Button' type='button' id='${id}_cancelButton'>${buttonCancel}</button>",
"</td></tr></table>"
].join(""),
_initButton: function(){
// Override _Plugin._initButton() to initialize DropDownButton and TooltipDialog.
var _this = this;
this.tag = this.command == 'insertImage' ? 'img' : 'a';
var messages = dojo.mixin(dojo.i18n.getLocalization("dijit", "common", this.lang),
dojo.i18n.getLocalization("dijit._editor", "LinkDialog", this.lang));
var dropDown = (this.dropDown = new dijit.TooltipDialog({
title: messages[this.command + "Title"],
execute: dojo.hitch(this, "setValue"),
onOpen: function(){
_this._onOpenDialog();
dijit.TooltipDialog.prototype.onOpen.apply(this, arguments);
},
onCancel: function(){
setTimeout(dojo.hitch(_this, "_onCloseDialog"),0);
}
}));
messages.urlRegExp = this.urlRegExp;
messages.id = dijit.getUniqueId(this.editor.id);
this._uniqueId = messages.id;
this._setContent(dropDown.title +
"<div style='border-bottom: 1px black solid;padding-bottom:2pt;margin-bottom:4pt'></div>" +
dojo.string.substitute(this.linkDialogTemplate, messages));
dropDown.startup();
this._urlInput = dijit.byId(this._uniqueId + "_urlInput");
this._textInput = dijit.byId(this._uniqueId + "_textInput");
this._setButton = dijit.byId(this._uniqueId + "_setButton");
this.connect(dijit.byId(this._uniqueId + "_cancelButton"), "onClick", function(){
this.dropDown.onCancel();
});
if(this._urlInput){
this.connect(this._urlInput, "onChange", "_checkAndFixInput");
}
if(this._textInput){
this.connect(this._textInput, "onChange", "_checkAndFixInput");
}
// Build up the dual check for http/https/file:, and mailto formats.
this._urlRegExp = new RegExp("^" + this.urlRegExp + "$", "i");
this._emailRegExp = new RegExp("^" + this.emailRegExp + "$", "i");
this._urlInput.isValid = dojo.hitch(this, function(){
// Function over-ride of isValid to test if the input matches a url or a mailto style link.
var value = this._urlInput.get("value");
return this._urlRegExp.test(value) || this._emailRegExp.test(value);
});
this._connectTagEvents();
this.inherited(arguments);
},
_checkAndFixInput: function(){
// summary:
// A function to listen for onChange events and test the input contents
// for valid information, such as valid urls with http/https/ftp and if
// not present, try and guess if the input url is relative or not, and if
// not, append http:// to it. Also validates other fields as determined by
// the internal _isValid function.
var self = this;
var url = this._urlInput.get("value");
var fixupUrl = function(url){
var appendHttp = false;
var appendMailto = false;
if(url && url.length > 1){
url = dojo.trim(url);
if(url.indexOf("mailto:") !== 0){
if(url.indexOf("/") > 0){
if(url.indexOf("://") === -1){
// Check that it doesn't start with / or ./, which would
// imply 'target server relativeness'
if(url.charAt(0) !== '/' && url.indexOf("./") !== 0){
if(self._hostRxp.test(url)){
appendHttp = true;
}
}
}
}else if(self._userAtRxp.test(url)){
// If it looks like a foo@, append a mailto.
appendMailto = true;
}
}
}
if(appendHttp){
self._urlInput.set("value", "http://" + url);
}
if(appendMailto){
self._urlInput.set("value", "mailto:" + url);
}
self._setButton.set("disabled", !self._isValid());
};
if(this._delayedCheck){
clearTimeout(this._delayedCheck);
this._delayedCheck = null;
}
this._delayedCheck = setTimeout(function(){
fixupUrl(url);
}, 250);
},
_connectTagEvents: function(){
// summary:
// Over-ridable function that connects tag specific events.
this.editor.onLoadDeferred.addCallback(dojo.hitch(this, function(){
this.connect(this.editor.editNode, "ondblclick", this._onDblClick);
}));
},
_isValid: function(){
// summary:
// Internal function to allow validating of the inputs
// for a link to determine if set should be disabled or not
// tags:
// protected
return this._urlInput.isValid() && this._textInput.isValid();
},
_setContent: function(staticPanel){
// summary:
// Helper for _initButton above. Not sure why it's a separate method.
this.dropDown.set({
parserScope: "dojo", // make parser search for dojoType/data-dojo-type even if page is multi-version
content: staticPanel
});
},
_checkValues: function(args){
// summary:
// Function to check the values in args and 'fix' them up as needed.
// args: Object
// Content being set.
// tags:
// protected
if(args && args.urlInput){
args.urlInput = args.urlInput.replace(/"/g, "&quot;");
}
return args;
},
setValue: function(args){
// summary:
// Callback from the dialog when user presses "set" button.
// tags:
// private
//TODO: prevent closing popup if the text is empty
this._onCloseDialog();
if(dojo.isIE < 9){ //see #4151
var sel = dijit.range.getSelection(this.editor.window);
var range = sel.getRangeAt(0);
var a = range.endContainer;
if(a.nodeType === 3){
// Text node, may be the link contents, so check parent.
// This plugin doesn't really support nested HTML elements
// in the link, it assumes all link content is text.
a = a.parentNode;
}
if(a && (a.nodeName && a.nodeName.toLowerCase() !== this.tag)){
// Stll nothing, one last thing to try on IE, as it might be 'img'
// and thus considered a control.
a = dojo.withGlobal(this.editor.window,
"getSelectedElement", dijit._editor.selection, [this.tag]);
}
if(a && (a.nodeName && a.nodeName.toLowerCase() === this.tag)){
// Okay, we do have a match. IE, for some reason, sometimes pastes before
// instead of removing the targetted paste-over element, so we unlink the
// old one first. If we do not the <a> tag remains, but it has no content,
// so isn't readily visible (but is wrong for the action).
if(this.editor.queryCommandEnabled("unlink")){
// Select all the link childent, then unlink. The following insert will
// then replace the selected text.
dojo.withGlobal(this.editor.window,
"selectElementChildren", dijit._editor.selection, [a]);
this.editor.execCommand("unlink");
}
}
}
// make sure values are properly escaped, etc.
args = this._checkValues(args);
this.editor.execCommand('inserthtml',
dojo.string.substitute(this.htmlTemplate, args));
},
_onCloseDialog: function(){
// summary:
// Handler for close event on the dialog
this.editor.focus();
},
_getCurrentValues: function(a){
// summary:
// Over-ride for getting the values to set in the dropdown.
// a:
// The anchor/link to process for data for the dropdown.
// tags:
// protected
var url, text, target;
if(a && a.tagName.toLowerCase() === this.tag){
url = a.getAttribute('_djrealurl') || a.getAttribute('href');
target = a.getAttribute('target') || "_self";
text = a.textContent || a.innerText;
dojo.withGlobal(this.editor.window, "selectElement", dijit._editor.selection, [a, true]);
}else{
text = dojo.withGlobal(this.editor.window, dijit._editor.selection.getSelectedText);
}
return {urlInput: url || '', textInput: text || '', targetSelect: target || ''}; //Object;
},
_onOpenDialog: function(){
// summary:
// Handler for when the dialog is opened.
// If the caret is currently in a URL then populate the URL's info into the dialog.
var a;
if(dojo.isIE < 9){
// IE is difficult to select the element in, using the range unified
// API seems to work reasonably well.
var sel = dijit.range.getSelection(this.editor.window);
var range = sel.getRangeAt(0);
a = range.endContainer;
if(a.nodeType === 3){
// Text node, may be the link contents, so check parent.
// This plugin doesn't really support nested HTML elements
// in the link, it assumes all link content is text.
a = a.parentNode;
}
if(a && (a.nodeName && a.nodeName.toLowerCase() !== this.tag)){
// Stll nothing, one last thing to try on IE, as it might be 'img'
// and thus considered a control.
a = dojo.withGlobal(this.editor.window,
"getSelectedElement", dijit._editor.selection, [this.tag]);
}
}else{
a = dojo.withGlobal(this.editor.window,
"getAncestorElement", dijit._editor.selection, [this.tag]);
}
this.dropDown.reset();
this._setButton.set("disabled", true);
this.dropDown.set("value", this._getCurrentValues(a));
},
_onDblClick: function(e){
// summary:
// Function to define a behavior on double clicks on the element
// type this dialog edits to select it and pop up the editor
// dialog.
// e: Object
// The double-click event.
// tags:
// protected.
if(e && e.target){
var t = e.target;
var tg = t.tagName? t.tagName.toLowerCase() : "";
if(tg === this.tag && dojo.attr(t,"href")){
dojo.withGlobal(this.editor.window,
"selectElement",
dijit._editor.selection, [t]);
this.editor.onDisplayChanged();
setTimeout(dojo.hitch(this, function(){
// Focus shift outside the event handler.
// IE doesn't like focus changes in event handles.
this.button.set("disabled", false);
this.button.openDropDown();
}), 10);
}
}
}
});
if(this._urlInput){
this.connect(this._urlInput,"onChange","_checkAndFixInput");
}
if(this._textInput){
this.connect(this._textInput,"onChange","_checkAndFixInput");
}
this._urlRegExp=new RegExp("^"+this.urlRegExp+"$","i");
this._emailRegExp=new RegExp("^"+this.emailRegExp+"$","i");
this._urlInput.isValid=dojo.hitch(this,function(){
var _4=this._urlInput.get("value");
return this._urlRegExp.test(_4)||this._emailRegExp.test(_4);
dojo.declare("dijit._editor.plugins.ImgLinkDialog", [dijit._editor.plugins.LinkDialog], {
// summary:
// This plugin extends LinkDialog and adds in a plugin for handling image links.
// provides the image link dialog.
//
// description:
// The command provided by this plugin is:
// * insertImage
// linkDialogTemplate: [protected] String
// Over-ride for template since img dialog doesn't need target that anchor tags may.
linkDialogTemplate: [
"<table><tr><td>",
"<label for='${id}_urlInput'>${url}</label>",
"</td><td>",
"<input dojoType='dijit.form.ValidationTextBox' regExp='${urlRegExp}' " +
"required='true' id='${id}_urlInput' name='urlInput' intermediateChanges='true'/>",
"</td></tr><tr><td>",
"<label for='${id}_textInput'>${text}</label>",
"</td><td>",
"<input dojoType='dijit.form.ValidationTextBox' required='false' id='${id}_textInput' " +
"name='textInput' intermediateChanges='true'/>",
"</td></tr><tr><td>",
"</td><td>",
"</td></tr><tr><td colspan='2'>",
"<button dojoType='dijit.form.Button' type='submit' id='${id}_setButton'>${set}</button>",
"<button dojoType='dijit.form.Button' type='button' id='${id}_cancelButton'>${buttonCancel}</button>",
"</td></tr></table>"
].join(""),
// htmlTemplate: [protected] String
// String used for templating the <img> HTML to insert at the desired point.
htmlTemplate: "<img src=\"${urlInput}\" _djrealurl=\"${urlInput}\" alt=\"${textInput}\" />",
// tag: [protected] String
// Tag used for the link type (img).
tag: "img",
_getCurrentValues: function(img){
// summary:
// Over-ride for getting the values to set in the dropdown.
// a:
// The anchor/link to process for data for the dropdown.
// tags:
// protected
var url, text;
if(img && img.tagName.toLowerCase() === this.tag){
url = img.getAttribute('_djrealurl') || img.getAttribute('src');
text = img.getAttribute('alt');
dojo.withGlobal(this.editor.window,
"selectElement", dijit._editor.selection, [img, true]);
}else{
text = dojo.withGlobal(this.editor.window, dijit._editor.selection.getSelectedText);
}
return {urlInput: url || '', textInput: text || ''}; //Object;
},
_isValid: function(){
// summary:
// Over-ride for images. You can have alt text of blank, it is valid.
// tags:
// protected
return this._urlInput.isValid();
},
_connectTagEvents: function(){
// summary:
// Over-ridable function that connects tag specific events.
this.inherited(arguments);
this.editor.onLoadDeferred.addCallback(dojo.hitch(this, function(){
// Use onmousedown instead of onclick. Seems that IE eats the first onclick
// to wrap it in a selector box, then the second one acts as onclick. See #10420
this.connect(this.editor.editNode, "onmousedown", this._selectTag);
}));
},
_selectTag: function(e){
// summary:
// A simple event handler that lets me select an image if it is clicked on.
// makes it easier to select images in a standard way across browsers. Otherwise
// selecting an image for edit becomes difficult.
// e: Event
// The mousedown event.
// tags:
// private
if(e && e.target){
var t = e.target;
var tg = t.tagName? t.tagName.toLowerCase() : "";
if(tg === this.tag){
dojo.withGlobal(this.editor.window,
"selectElement",
dijit._editor.selection, [t]);
}
}
},
_checkValues: function(args){
// summary:
// Function to check the values in args and 'fix' them up as needed
// (special characters in the url or alt text)
// args: Object
// Content being set.
// tags:
// protected
if(args && args.urlInput){
args.urlInput = args.urlInput.replace(/"/g, "&quot;");
}
if(args && args.textInput){
args.textInput = args.textInput.replace(/"/g, "&quot;");
}
return args;
},
_onDblClick: function(e){
// summary:
// Function to define a behavior on double clicks on the element
// type this dialog edits to select it and pop up the editor
// dialog.
// e: Object
// The double-click event.
// tags:
// protected.
if(e && e.target){
var t = e.target;
var tg = t.tagName? t.tagName.toLowerCase() : "";
if(tg === this.tag && dojo.attr(t,"src")){
dojo.withGlobal(this.editor.window,
"selectElement",
dijit._editor.selection, [t]);
this.editor.onDisplayChanged();
setTimeout(dojo.hitch(this, function(){
// Focus shift outside the event handler.
// IE doesn't like focus changes in event handles.
this.button.set("disabled", false);
this.button.openDropDown();
}), 10);
}
}
}
});
this._connectTagEvents();
this.inherited(arguments);
},_checkAndFixInput:function(){
var _5=this;
var _6=this._urlInput.get("value");
var _7=function(_8){
var _9=false;
var _a=false;
if(_8&&_8.length>1){
_8=dojo.trim(_8);
if(_8.indexOf("mailto:")!==0){
if(_8.indexOf("/")>0){
if(_8.indexOf("://")===-1){
if(_8.charAt(0)!=="/"&&_8.indexOf("./")!==0){
if(_5._hostRxp.test(_8)){
_9=true;
}
}
}
}else{
if(_5._userAtRxp.test(_8)){
_a=true;
}
}
}
}
if(_9){
_5._urlInput.set("value","http://"+_8);
}
if(_a){
_5._urlInput.set("value","mailto:"+_8);
}
_5._setButton.set("disabled",!_5._isValid());
};
if(this._delayedCheck){
clearTimeout(this._delayedCheck);
this._delayedCheck=null;
}
this._delayedCheck=setTimeout(function(){
_7(_6);
},250);
},_connectTagEvents:function(){
this.editor.onLoadDeferred.addCallback(dojo.hitch(this,function(){
this.connect(this.editor.editNode,"ondblclick",this._onDblClick);
}));
},_isValid:function(){
return this._urlInput.isValid()&&this._textInput.isValid();
},_setContent:function(_b){
this.dropDown.set("content",_b);
},_checkValues:function(_c){
if(_c&&_c.urlInput){
_c.urlInput=_c.urlInput.replace(/"/g,"&quot;");
}
return _c;
},setValue:function(_d){
this._onCloseDialog();
if(dojo.isIE){
var _e=dijit.range.getSelection(this.editor.window);
var _f=_e.getRangeAt(0);
var a=_f.endContainer;
if(a.nodeType===3){
a=a.parentNode;
}
if(a&&(a.nodeName&&a.nodeName.toLowerCase()!==this.tag)){
a=dojo.withGlobal(this.editor.window,"getSelectedElement",dijit._editor.selection,[this.tag]);
}
if(a&&(a.nodeName&&a.nodeName.toLowerCase()===this.tag)){
if(this.editor.queryCommandEnabled("unlink")){
dojo.withGlobal(this.editor.window,"selectElementChildren",dijit._editor.selection,[a]);
this.editor.execCommand("unlink");
}
}
}
_d=this._checkValues(_d);
this.editor.execCommand("inserthtml",dojo.string.substitute(this.htmlTemplate,_d));
},_onCloseDialog:function(){
this.editor.focus();
},_getCurrentValues:function(a){
var url,_10,_11;
if(a&&a.tagName.toLowerCase()===this.tag){
url=a.getAttribute("_djrealurl")||a.getAttribute("href");
_11=a.getAttribute("target")||"_self";
_10=a.textContent||a.innerText;
dojo.withGlobal(this.editor.window,"selectElement",dijit._editor.selection,[a,true]);
}else{
_10=dojo.withGlobal(this.editor.window,dijit._editor.selection.getSelectedText);
}
return {urlInput:url||"",textInput:_10||"",targetSelect:_11||""};
},_onOpenDialog:function(){
var a;
if(dojo.isIE){
var sel=dijit.range.getSelection(this.editor.window);
var _12=sel.getRangeAt(0);
a=_12.endContainer;
if(a.nodeType===3){
a=a.parentNode;
}
if(a&&(a.nodeName&&a.nodeName.toLowerCase()!==this.tag)){
a=dojo.withGlobal(this.editor.window,"getSelectedElement",dijit._editor.selection,[this.tag]);
}
}else{
a=dojo.withGlobal(this.editor.window,"getAncestorElement",dijit._editor.selection,[this.tag]);
}
this.dropDown.reset();
this._setButton.set("disabled",true);
this.dropDown.set("value",this._getCurrentValues(a));
},_onDblClick:function(e){
if(e&&e.target){
var t=e.target;
var tg=t.tagName?t.tagName.toLowerCase():"";
if(tg===this.tag&&dojo.attr(t,"href")){
dojo.withGlobal(this.editor.window,"selectElement",dijit._editor.selection,[t]);
this.editor.onDisplayChanged();
setTimeout(dojo.hitch(this,function(){
this.button.set("disabled",false);
this.button.openDropDown();
}),10);
}
}
}});
dojo.declare("dijit._editor.plugins.ImgLinkDialog",[dijit._editor.plugins.LinkDialog],{linkDialogTemplate:["<table><tr><td>","<label for='${id}_urlInput'>${url}</label>","</td><td>","<input dojoType='dijit.form.ValidationTextBox' regExp='${urlRegExp}' "+"required='true' id='${id}_urlInput' name='urlInput' intermediateChanges='true'>","</td></tr><tr><td>","<label for='${id}_textInput'>${text}</label>","</td><td>","<input dojoType='dijit.form.ValidationTextBox' required='false' id='${id}_textInput' "+"name='textInput' intermediateChanges='true'>","</td></tr><tr><td>","</td><td>","</td></tr><tr><td colspan='2'>","<button dojoType='dijit.form.Button' type='submit' id='${id}_setButton'>${set}</button>","<button dojoType='dijit.form.Button' type='button' id='${id}_cancelButton'>${buttonCancel}</button>","</td></tr></table>"].join(""),htmlTemplate:"<img src=\"${urlInput}\" _djrealurl=\"${urlInput}\" alt=\"${textInput}\" />",tag:"img",_getCurrentValues:function(img){
var url,_13;
if(img&&img.tagName.toLowerCase()===this.tag){
url=img.getAttribute("_djrealurl")||img.getAttribute("src");
_13=img.getAttribute("alt");
dojo.withGlobal(this.editor.window,"selectElement",dijit._editor.selection,[img,true]);
}else{
_13=dojo.withGlobal(this.editor.window,dijit._editor.selection.getSelectedText);
}
return {urlInput:url||"",textInput:_13||""};
},_isValid:function(){
return this._urlInput.isValid();
},_connectTagEvents:function(){
this.inherited(arguments);
this.editor.onLoadDeferred.addCallback(dojo.hitch(this,function(){
this.connect(this.editor.editNode,"onmousedown",this._selectTag);
}));
},_selectTag:function(e){
if(e&&e.target){
var t=e.target;
var tg=t.tagName?t.tagName.toLowerCase():"";
if(tg===this.tag){
dojo.withGlobal(this.editor.window,"selectElement",dijit._editor.selection,[t]);
}
}
},_checkValues:function(_14){
if(_14&&_14.urlInput){
_14.urlInput=_14.urlInput.replace(/"/g,"&quot;");
}
if(_14&&_14.textInput){
_14.textInput=_14.textInput.replace(/"/g,"&quot;");
}
return _14;
},_onDblClick:function(e){
if(e&&e.target){
var t=e.target;
var tg=t.tagName?t.tagName.toLowerCase():"";
if(tg===this.tag&&dojo.attr(t,"src")){
dojo.withGlobal(this.editor.window,"selectElement",dijit._editor.selection,[t]);
this.editor.onDisplayChanged();
setTimeout(dojo.hitch(this,function(){
this.button.set("disabled",false);
this.button.openDropDown();
}),10);
}
}
}});
dojo.subscribe(dijit._scopeName+".Editor.getPlugin",null,function(o){
if(o.plugin){
return;
}
switch(o.args.name){
case "createLink":
o.plugin=new dijit._editor.plugins.LinkDialog({command:o.args.name});
break;
case "insertImage":
o.plugin=new dijit._editor.plugins.ImgLinkDialog({command:o.args.name});
break;
}
// Register this plugin.
dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
if(o.plugin){ return; }
switch(o.args.name){
case "createLink":
o.plugin = new dijit._editor.plugins.LinkDialog({command: o.args.name});
break;
case "insertImage":
o.plugin = new dijit._editor.plugins.ImgLinkDialog({command: o.args.name});
break;
}
});
}

View File

@@ -1,36 +1,81 @@
/*
Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
if(!dojo._hasResource["dijit._editor.plugins.NewPage"]){
dojo._hasResource["dijit._editor.plugins.NewPage"]=true;
if(!dojo._hasResource["dijit._editor.plugins.NewPage"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit._editor.plugins.NewPage"] = true;
dojo.provide("dijit._editor.plugins.NewPage");
dojo.require("dijit._editor._Plugin");
dojo.require("dijit.form.Button");
dojo.require("dojo.i18n");
dojo.requireLocalization("dijit._editor","commands",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw");
dojo.declare("dijit._editor.plugins.NewPage",dijit._editor._Plugin,{content:"<br>",_initButton:function(){
var _1=dojo.i18n.getLocalization("dijit._editor","commands"),_2=this.editor;
this.button=new dijit.form.Button({label:_1["newPage"],dir:_2.dir,lang:_2.lang,showLabel:false,iconClass:this.iconClassPrefix+" "+this.iconClassPrefix+"NewPage",tabIndex:"-1",onClick:dojo.hitch(this,"_newPage")});
},setEditor:function(_3){
this.editor=_3;
this._initButton();
},_newPage:function(){
this.editor.beginEditing();
this.editor.set("value",this.content);
this.editor.endEditing();
this.editor.focus();
}});
dojo.subscribe(dijit._scopeName+".Editor.getPlugin",null,function(o){
if(o.plugin){
return;
}
var _4=o.args.name.toLowerCase();
if(_4==="newpage"){
o.plugin=new dijit._editor.plugins.NewPage({content:("content" in o.args)?o.args.content:"<br>"});
}
dojo.requireLocalization("dijit._editor", "commands", null, "ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,kk,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw");
dojo.declare("dijit._editor.plugins.NewPage",dijit._editor._Plugin,{
// summary:
// This plugin provides a simple 'new page' calability. In other
// words, set content to some default user defined string.
// content: [public] String
// The default content to insert into the editor as the new page.
// The default is the <br> tag, a single blank line.
content: "<br>",
_initButton: function(){
// summary:
// Over-ride for creation of the Print button.
var strings = dojo.i18n.getLocalization("dijit._editor", "commands"),
editor = this.editor;
this.button = new dijit.form.Button({
label: strings["newPage"],
dir: editor.dir,
lang: editor.lang,
showLabel: false,
iconClass: this.iconClassPrefix + " " + this.iconClassPrefix + "NewPage",
tabIndex: "-1",
onClick: dojo.hitch(this, "_newPage")
});
},
setEditor: function(/*dijit.Editor*/ editor){
// summary:
// Tell the plugin which Editor it is associated with.
// editor: Object
// The editor object to attach the newPage capability to.
this.editor = editor;
this._initButton();
},
updateState: function(){
// summary:
// Over-ride for button state control for disabled to work.
this.button.set("disabled", this.get("disabled"));
},
_newPage: function(){
// summary:
// Function to set the content to blank.
// tags:
// private
this.editor.beginEditing();
this.editor.set("value", this.content);
this.editor.endEditing();
this.editor.focus();
}
});
// Register this plugin.
dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
if(o.plugin){ return; }
var name = o.args.name.toLowerCase();
if(name === "newpage"){
o.plugin = new dijit._editor.plugins.NewPage({
content: ("content" in o.args)?o.args.content:"<br>"
});
}
});
}

View File

@@ -1,65 +1,125 @@
/*
Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
if(!dojo._hasResource["dijit._editor.plugins.Print"]){
dojo._hasResource["dijit._editor.plugins.Print"]=true;
if(!dojo._hasResource["dijit._editor.plugins.Print"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit._editor.plugins.Print"] = true;
dojo.provide("dijit._editor.plugins.Print");
dojo.require("dijit._editor._Plugin");
dojo.require("dijit.form.Button");
dojo.require("dojo.i18n");
dojo.requireLocalization("dijit._editor","commands",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw");
dojo.declare("dijit._editor.plugins.Print",dijit._editor._Plugin,{_initButton:function(){
var _1=dojo.i18n.getLocalization("dijit._editor","commands"),_2=this.editor;
this.button=new dijit.form.Button({label:_1["print"],dir:_2.dir,lang:_2.lang,showLabel:false,iconClass:this.iconClassPrefix+" "+this.iconClassPrefix+"Print",tabIndex:"-1",onClick:dojo.hitch(this,"_print")});
},setEditor:function(_3){
this.editor=_3;
this._initButton();
this.editor.onLoadDeferred.addCallback(dojo.hitch(this,function(){
if(!this.editor.iframe.contentWindow["print"]){
this.button.set("disabled",true);
}
}));
},_print:function(){
var _4=this.editor.iframe;
if(_4.contentWindow["print"]){
if(!dojo.isOpera&&!dojo.isChrome){
dijit.focus(_4);
_4.contentWindow.print();
}else{
var _5=this.editor.document;
var _6=this.editor.get("value");
_6="<html><head><meta http-equiv='Content-Type' "+"content='text/html; charset='UTF-8'></head><body>"+_6+"</body></html>";
var _7=window.open("javascript: ''","","status=0,menubar=0,location=0,toolbar=0,"+"width=1,height=1,resizable=0,scrollbars=0");
_7.document.open();
_7.document.write(_6);
_7.document.close();
var _8=[];
var _9=_5.getElementsByTagName("style");
if(_9){
var i;
for(i=0;i<_9.length;i++){
var _a=_9[i].innerHTML;
var _b=_7.document.createElement("style");
_b.appendChild(_7.document.createTextNode(_a));
_7.document.getElementsByTagName("head")[0].appendChild(_b);
}
}
_7.print();
_7.close();
}
}
}});
dojo.subscribe(dijit._scopeName+".Editor.getPlugin",null,function(o){
if(o.plugin){
return;
}
var _c=o.args.name.toLowerCase();
if(_c==="print"){
o.plugin=new dijit._editor.plugins.Print({command:"print"});
}
dojo.requireLocalization("dijit._editor", "commands", null, "ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,kk,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw");
dojo.declare("dijit._editor.plugins.Print",dijit._editor._Plugin,{
// summary:
// This plugin provides Print cabability to the editor. When
// clicked, the document in the editor frame will be printed.
_initButton: function(){
// summary:
// Over-ride for creation of the Print button.
var strings = dojo.i18n.getLocalization("dijit._editor", "commands"),
editor = this.editor;
this.button = new dijit.form.Button({
label: strings["print"],
dir: editor.dir,
lang: editor.lang,
showLabel: false,
iconClass: this.iconClassPrefix + " " + this.iconClassPrefix + "Print",
tabIndex: "-1",
onClick: dojo.hitch(this, "_print")
});
},
setEditor: function(/*dijit.Editor*/ editor){
// summary:
// Tell the plugin which Editor it is associated with.
// editor: Object
// The editor object to attach the print capability to.
this.editor = editor;
this._initButton();
// Set up a check that we have a print function
// and disable button if we do not.
this.editor.onLoadDeferred.addCallback(
dojo.hitch(this, function(){
if(!this.editor.iframe.contentWindow["print"]){
this.button.set("disabled", true);
}
})
);
},
updateState: function(){
// summary:
// Over-ride for button state control for disabled to work.
var disabled = this.get("disabled");
if(!this.editor.iframe.contentWindow["print"]){
disabled = true;
}
this.button.set("disabled", disabled);
},
_print: function(){
// summary:
// Function to trigger printing of the editor document
// tags:
// private
var edFrame = this.editor.iframe;
if(edFrame.contentWindow["print"]){
// IE requires the frame to be focused for
// print to work, but since this is okay for all
// no special casing.
if(!dojo.isOpera && !dojo.isChrome){
dijit.focus(edFrame);
edFrame.contentWindow.print();
}else{
// Neither Opera nor Chrome 3 et you print single frames.
// So, open a new 'window', print it, and close it.
// Also, can't use size 0x0, have to use 1x1
var edDoc = this.editor.document;
var content = this.editor.get("value");
content = "<html><head><meta http-equiv='Content-Type' " +
"content='text/html; charset='UTF-8'></head><body>" +
content + "</body></html>";
var win = window.open("javascript: ''",
"",
"status=0,menubar=0,location=0,toolbar=0," +
"width=1,height=1,resizable=0,scrollbars=0");
win.document.open();
win.document.write(content);
win.document.close();
var styles = [];
var styleNodes = edDoc.getElementsByTagName("style");
if(styleNodes){
// Clone over any editor view styles, since we can't print the iframe
// directly.
var i;
for(i = 0; i < styleNodes.length; i++){
var style = styleNodes[i].innerHTML;
var sNode = win.document.createElement("style");
sNode.appendChild(win.document.createTextNode(style));
win.document.getElementsByTagName("head")[0].appendChild(sNode);
}
}
win.print();
win.close();
}
}
}
});
// Register this plugin.
dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
if(o.plugin){ return; }
var name = o.args.name.toLowerCase();
if(name === "print"){
o.plugin = new dijit._editor.plugins.Print({command: "print"});
}
});
}

View File

@@ -1,33 +1,69 @@
/*
Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
if(!dojo._hasResource["dijit._editor.plugins.TabIndent"]){
dojo._hasResource["dijit._editor.plugins.TabIndent"]=true;
if(!dojo._hasResource["dijit._editor.plugins.TabIndent"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit._editor.plugins.TabIndent"] = true;
dojo.provide("dijit._editor.plugins.TabIndent");
dojo.experimental("dijit._editor.plugins.TabIndent");
dojo.require("dijit._editor._Plugin");
dojo.require("dijit.form.ToggleButton");
dojo.declare("dijit._editor.plugins.TabIndent",dijit._editor._Plugin,{useDefaultCommand:false,buttonClass:dijit.form.ToggleButton,command:"tabIndent",_initButton:function(){
this.inherited(arguments);
var e=this.editor;
this.connect(this.button,"onChange",function(_1){
e.set("isTabIndent",_1);
});
this.updateState();
},updateState:function(){
this.button.set("checked",this.editor.isTabIndent,false);
}});
dojo.subscribe(dijit._scopeName+".Editor.getPlugin",null,function(o){
if(o.plugin){
return;
}
switch(o.args.name){
case "tabIndent":
o.plugin=new dijit._editor.plugins.TabIndent({command:o.args.name});
}
dojo.experimental("dijit._editor.plugins.TabIndent");
dojo.declare("dijit._editor.plugins.TabIndent",
dijit._editor._Plugin,
{
// summary:
// This plugin is used to allow the use of the tab and shift-tab keys
// to indent/outdent list items. This overrides the default behavior
// of moving focus from/to the toolbar
// Override _Plugin.useDefaultCommand... processing is handled by this plugin, not by dijit.Editor.
useDefaultCommand: false,
// Override _Plugin.buttonClass to use a ToggleButton for this plugin rather than a vanilla Button
buttonClass: dijit.form.ToggleButton,
command: "tabIndent",
_initButton: function(){
// Override _Plugin._initButton() to setup listener on button click
this.inherited(arguments);
var e = this.editor;
this.connect(this.button, "onChange", function(val){
e.set("isTabIndent", val);
});
// Set initial checked state of button based on Editor.isTabIndent
this.updateState();
},
updateState: function(){
// Overrides _Plugin.updateState().
// Ctrl-m in the editor will switch tabIndent mode on/off, so we need to react to that.
var disabled = this.get("disabled");
this.button.set("disabled", disabled);
if(disabled){
return;
}
this.button.set('checked', this.editor.isTabIndent, false);
}
}
);
// Register this plugin.
dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
if(o.plugin){ return; }
switch(o.args.name){
case "tabIndent":
o.plugin = new dijit._editor.plugins.TabIndent({command: o.args.name});
}
});
}

View File

@@ -1,62 +1,105 @@
/*
Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
if(!dojo._hasResource["dijit._editor.plugins.TextColor"]){
dojo._hasResource["dijit._editor.plugins.TextColor"]=true;
if(!dojo._hasResource["dijit._editor.plugins.TextColor"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit._editor.plugins.TextColor"] = true;
dojo.provide("dijit._editor.plugins.TextColor");
dojo.require("dijit._editor._Plugin");
dojo.require("dijit.ColorPalette");
dojo.declare("dijit._editor.plugins.TextColor",dijit._editor._Plugin,{buttonClass:dijit.form.DropDownButton,useDefaultCommand:false,constructor:function(){
this.dropDown=new dijit.ColorPalette();
this.connect(this.dropDown,"onChange",function(_1){
this.editor.execCommand(this.command,_1);
dojo.declare("dijit._editor.plugins.TextColor", dijit._editor._Plugin, {
// summary:
// This plugin provides dropdown color pickers for setting text color and background color
//
// description:
// The commands provided by this plugin are:
// * foreColor - sets the text color
// * hiliteColor - sets the background color
// Override _Plugin.buttonClass to use DropDownButton (with ColorPalette) to control this plugin
buttonClass: dijit.form.DropDownButton,
// useDefaultCommand: Boolean
// False as we do not use the default editor command/click behavior.
useDefaultCommand: false,
constructor: function(){
this.dropDown = new dijit.ColorPalette();
this.connect(this.dropDown, "onChange", function(color){
this.editor.execCommand(this.command, color);
});
},
updateState: function(){
// summary:
// Overrides _Plugin.updateState(). This updates the ColorPalette
// to show the color of the currently selected text.
// tags:
// protected
var _e = this.editor;
var _c = this.command;
if(!_e || !_e.isLoaded || !_c.length){
return;
}
if(this.button){
var disabled = this.get("disabled");
this.button.set("disabled", disabled);
if(disabled){ return; }
var value;
try{
value = _e.queryCommandValue(_c)|| "";
}catch(e){
//Firefox may throw error above if the editor is just loaded, ignore it
value = "";
}
}
if(value == ""){
value = "#000000";
}
if(value == "transparent"){
value = "#ffffff";
}
if(typeof value == "string"){
//if RGB value, convert to hex value
if(value.indexOf("rgb")> -1){
value = dojo.colorFromRgb(value).toHex();
}
}else{ //it's an integer(IE returns an MS access #)
value =((value & 0x0000ff)<< 16)|(value & 0x00ff00)|((value & 0xff0000)>>> 16);
value = value.toString(16);
value = "#000000".slice(0, 7 - value.length)+ value;
}
if(value !== this.dropDown.get('value')){
this.dropDown.set('value', value, false);
}
}
});
},updateState:function(){
var _2=this.editor;
var _3=this.command;
if(!_2||!_2.isLoaded||!_3.length){
return;
}
if(this.button){
var _4;
try{
_4=_2.queryCommandValue(_3)||"";
}
catch(e){
_4="";
}
}
if(_4==""){
_4="#000000";
}
if(_4=="transparent"){
_4="#ffffff";
}
if(typeof _4=="string"){
if(_4.indexOf("rgb")>-1){
_4=dojo.colorFromRgb(_4).toHex();
}
}else{
_4=((_4&255)<<16)|(_4&65280)|((_4&16711680)>>>16);
_4=_4.toString(16);
_4="#000000".slice(0,7-_4.length)+_4;
}
if(_4!==this.dropDown.get("value")){
this.dropDown.set("value",_4,false);
}
}});
dojo.subscribe(dijit._scopeName+".Editor.getPlugin",null,function(o){
if(o.plugin){
return;
}
switch(o.args.name){
case "foreColor":
case "hiliteColor":
o.plugin=new dijit._editor.plugins.TextColor({command:o.args.name});
}
// Register this plugin.
dojo.subscribe(dijit._scopeName + ".Editor.getPlugin", null, function(o){
if(o.plugin){
return;
}
switch(o.args.name){
case "foreColor":
case "hiliteColor":
o.plugin = new dijit._editor.plugins.TextColor({
command: o.args.name
});
}
});
}

View File

@@ -1,42 +1,80 @@
/*
Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
if(!dojo._hasResource["dijit._editor.plugins.ToggleDir"]){
dojo._hasResource["dijit._editor.plugins.ToggleDir"]=true;
if(!dojo._hasResource["dijit._editor.plugins.ToggleDir"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit._editor.plugins.ToggleDir"] = true;
dojo.provide("dijit._editor.plugins.ToggleDir");
dojo.experimental("dijit._editor.plugins.ToggleDir");
dojo.require("dijit._editor._Plugin");
dojo.require("dijit.form.ToggleButton");
dojo.declare("dijit._editor.plugins.ToggleDir",dijit._editor._Plugin,{useDefaultCommand:false,command:"toggleDir",buttonClass:dijit.form.ToggleButton,_initButton:function(){
this.inherited(arguments);
this.editor.onLoadDeferred.addCallback(dojo.hitch(this,function(){
var _1=this.editor.editorObject.contentWindow.document.documentElement;
_1=_1.getElementsByTagName("body")[0];
var _2=dojo.getComputedStyle(_1).direction=="ltr";
this.button.set("checked",!_2);
this.connect(this.button,"onChange","_setRtl");
}));
},updateState:function(){
},_setRtl:function(_3){
var _4="ltr";
if(_3){
_4="rtl";
}
var _5=this.editor.editorObject.contentWindow.document.documentElement;
_5=_5.getElementsByTagName("body")[0];
_5.dir=_4;
}});
dojo.subscribe(dijit._scopeName+".Editor.getPlugin",null,function(o){
if(o.plugin){
return;
}
switch(o.args.name){
case "toggleDir":
o.plugin=new dijit._editor.plugins.ToggleDir({command:o.args.name});
}
dojo.experimental("dijit._editor.plugins.ToggleDir");
dojo.require("dijit._editor._Plugin");
dojo.require("dijit.form.ToggleButton");
dojo.declare("dijit._editor.plugins.ToggleDir",
dijit._editor._Plugin,
{
// summary:
// This plugin is used to toggle direction of the edited document,
// independent of what direction the whole page is.
// Override _Plugin.useDefaultCommand: processing is done in this plugin
// rather than by sending commands to the Editor
useDefaultCommand: false,
command: "toggleDir",
// Override _Plugin.buttonClass to use a ToggleButton for this plugin rather than a vanilla Button
buttonClass: dijit.form.ToggleButton,
_initButton: function(){
// Override _Plugin._initButton() to setup handler for button click events.
this.inherited(arguments);
this.editor.onLoadDeferred.addCallback(dojo.hitch(this, function(){
var editDoc = this.editor.editorObject.contentWindow.document.documentElement;
//IE direction has to toggle on the body, not document itself.
//If you toggle just the document, things get very strange in the
//view. But, the nice thing is this works for all supported browsers.
editDoc = editDoc.getElementsByTagName("body")[0];
var isLtr = dojo.getComputedStyle(editDoc).direction == "ltr";
this.button.set("checked", !isLtr);
this.connect(this.button, "onChange", "_setRtl");
}));
},
updateState: function(){
// summary:
// Over-ride for button state control for disabled to work.
this.button.set("disabled", this.get("disabled"));
},
_setRtl: function(rtl){
// summary:
// Handler for button click events, to switch the text direction of the editor
var dir = "ltr";
if(rtl){
dir = "rtl";
}
var editDoc = this.editor.editorObject.contentWindow.document.documentElement;
editDoc = editDoc.getElementsByTagName("body")[0];
editDoc.dir/*html node*/ = dir;
}
}
);
// Register this plugin.
dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
if(o.plugin){ return; }
switch(o.args.name){
case "toggleDir":
o.plugin = new dijit._editor.plugins.ToggleDir({command: o.args.name});
}
});
}

View File

@@ -1,317 +1,555 @@
/*
Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
if(!dojo._hasResource["dijit._editor.plugins.ViewSource"]){
dojo._hasResource["dijit._editor.plugins.ViewSource"]=true;
if(!dojo._hasResource["dijit._editor.plugins.ViewSource"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit._editor.plugins.ViewSource"] = true;
dojo.provide("dijit._editor.plugins.ViewSource");
dojo.require("dojo.window");
dojo.require("dojo.i18n");
dojo.require("dijit._editor._Plugin");
dojo.require("dijit.form.Button");
dojo.requireLocalization("dijit._editor","commands",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw");
dojo.declare("dijit._editor.plugins.ViewSource",dijit._editor._Plugin,{stripScripts:true,stripComments:true,stripIFrames:true,readOnly:false,_fsPlugin:null,toggle:function(){
if(dojo.isWebKit){
this._vsFocused=true;
}
this.button.set("checked",!this.button.get("checked"));
},_initButton:function(){
var _1=dojo.i18n.getLocalization("dijit._editor","commands"),_2=this.editor;
this.button=new dijit.form.ToggleButton({label:_1["viewSource"],dir:_2.dir,lang:_2.lang,showLabel:false,iconClass:this.iconClassPrefix+" "+this.iconClassPrefix+"ViewSource",tabIndex:"-1",onChange:dojo.hitch(this,"_showSource")});
if(dojo.isIE==7){
this._ieFixNode=dojo.create("div",{style:{opacity:"0",zIndex:"-1000",position:"absolute",top:"-1000px"}},dojo.body());
}
this.button.set("readOnly",false);
},setEditor:function(_3){
this.editor=_3;
this._initButton();
this.editor.addKeyHandler(dojo.keys.F12,true,true,dojo.hitch(this,function(e){
this.button.focus();
this.toggle();
dojo.stopEvent(e);
setTimeout(dojo.hitch(this,function(){
this.editor.focus();
}),100);
}));
},_showSource:function(_4){
var ed=this.editor;
var _5=ed._plugins;
var _6;
this._sourceShown=_4;
var _7=this;
try{
if(!this.sourceArea){
this._createSourceView();
}
if(_4){
ed._sourceQueryCommandEnabled=ed.queryCommandEnabled;
ed.queryCommandEnabled=function(_8){
var _9=_8.toLowerCase();
if(_9==="viewsource"){
return true;
}else{
return false;
}
};
this.editor.onDisplayChanged();
_6=ed.get("value");
_6=this._filter(_6);
ed.set("value",_6);
this._pluginList=[];
this._disabledPlugins=dojo.filter(_5,function(p){
if(p&&p.button&&!p.button.get("disabled")&&!(p instanceof dijit._editor.plugins.ViewSource)){
p._vs_updateState=p.updateState;
p.updateState=function(){
return false;
};
p.button.set("disabled",true);
if(p.command){
switch(p.command){
case "bold":
case "italic":
case "underline":
case "strikethrough":
case "superscript":
case "subscript":
p.button.set("checked",false);
break;
default:
break;
}
}
return true;
}
dojo.requireLocalization("dijit._editor", "commands", null, "ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,kk,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw");
dojo.declare("dijit._editor.plugins.ViewSource",dijit._editor._Plugin,{
// summary:
// This plugin provides a simple view source capability. When view
// source mode is enabled, it disables all other buttons/plugins on the RTE.
// It also binds to the hotkey: CTRL-SHIFT-F11 for toggling ViewSource mode.
// stripScripts: [public] Boolean
// Boolean flag used to indicate if script tags should be stripped from the document.
// Defaults to true.
stripScripts: true,
// stripComments: [public] Boolean
// Boolean flag used to indicate if comment tags should be stripped from the document.
// Defaults to true.
stripComments: true,
// stripComments: [public] Boolean
// Boolean flag used to indicate if iframe tags should be stripped from the document.
// Defaults to true.
stripIFrames: true,
// readOnly: [const] Boolean
// Boolean flag used to indicate if the source view should be readonly or not.
// Cannot be changed after initialization of the plugin.
// Defaults to false.
readOnly: false,
// _fsPlugin: [private] Object
// Reference to a registered fullscreen plugin so that viewSource knows
// how to scale.
_fsPlugin: null,
toggle: function(){
// summary:
// Function to allow programmatic toggling of the view.
// For Webkit, we have to focus a very particular way.
// when swapping views, otherwise focus doesn't shift right
// but can't focus this way all the time, only for VS changes.
// If we did it all the time, buttons like bold, italic, etc
// break.
if(dojo.isWebKit){this._vsFocused = true;}
this.button.set("checked", !this.button.get("checked"));
},
_initButton: function(){
// summary:
// Over-ride for creation of the resize button.
var strings = dojo.i18n.getLocalization("dijit._editor", "commands"),
editor = this.editor;
this.button = new dijit.form.ToggleButton({
label: strings["viewSource"],
dir: editor.dir,
lang: editor.lang,
showLabel: false,
iconClass: this.iconClassPrefix + " " + this.iconClassPrefix + "ViewSource",
tabIndex: "-1",
onChange: dojo.hitch(this, "_showSource")
});
// IE 7 has a horrible bug with zoom, so we have to create this node
// to cross-check later. Sigh.
if(dojo.isIE == 7){
this._ieFixNode = dojo.create("div", {
style: {
opacity: "0",
zIndex: "-1000",
position: "absolute",
top: "-1000px"
}
}, dojo.body());
}
// Make sure readonly mode doesn't make the wrong cursor appear over the button.
this.button.set("readOnly", false);
},
setEditor: function(/*dijit.Editor*/ editor){
// summary:
// Tell the plugin which Editor it is associated with.
// editor: Object
// The editor object to attach the print capability to.
this.editor = editor;
this._initButton();
this.editor.addKeyHandler(dojo.keys.F12, true, true, dojo.hitch(this, function(e){
// Move the focus before switching
// It'll focus back. Hiding a focused
// node causes issues.
this.button.focus();
this.toggle();
dojo.stopEvent(e);
// Call the focus shift outside of the handler.
setTimeout(dojo.hitch(this, function(){
// We over-ride focus, so we just need to call.
this.editor.focus();
}), 100);
}));
},
_showSource: function(source){
// summary:
// Function to toggle between the source and RTE views.
// source: boolean
// Boolean value indicating if it should be in source mode or not.
// tags:
// private
var ed = this.editor;
var edPlugins = ed._plugins;
var html;
this._sourceShown = source;
var self = this;
try{
if(!this.sourceArea){
this._createSourceView();
}
if(source){
// Update the QueryCommandEnabled function to disable everything but
// the source view mode. Have to over-ride a function, then kick all
// plugins to check their state.
ed._sourceQueryCommandEnabled = ed.queryCommandEnabled;
ed.queryCommandEnabled = function(cmd){
var lcmd = cmd.toLowerCase();
if(lcmd === "viewsource"){
return true;
}else{
return false;
}
};
this.editor.onDisplayChanged();
html = ed.get("value");
html = this._filter(html);
ed.set("value", html);
this._pluginList = [];
dojo.forEach(edPlugins, function(p){
// Turn off any plugins not controlled by queryCommandenabled.
if(!(p instanceof dijit._editor.plugins.ViewSource)){
p.set("disabled", true)
}
});
// We actually do need to trap this plugin and adjust how we
// display the textarea.
if(this._fsPlugin){
this._fsPlugin._getAltViewNode = function(){
return self.sourceArea;
};
}
this.sourceArea.value = html;
var is = dojo._getMarginSize(ed.iframe.parentNode);
dojo.marginBox(this.sourceArea, {
w: is.w,
h: is.h
});
dojo.style(ed.iframe, "display", "none");
dojo.style(this.sourceArea, {
display: "block"
});
var resizer = function(){
// function to handle resize events.
// Will check current VP and only resize if
// different.
var vp = dojo.window.getBox();
if("_prevW" in this && "_prevH" in this){
// No actual size change, ignore.
if(vp.w === this._prevW && vp.h === this._prevH){
return;
}else{
this._prevW = vp.w;
this._prevH = vp.h;
}
}else{
this._prevW = vp.w;
this._prevH = vp.h;
}
if(this._resizer){
clearTimeout(this._resizer);
delete this._resizer;
}
// Timeout it to help avoid spamming resize on IE.
// Works for all browsers.
this._resizer = setTimeout(dojo.hitch(this, function(){
delete this._resizer;
this._resize();
}), 10);
};
this._resizeHandle = dojo.connect(window, "onresize", this, resizer);
//Call this on a delay once to deal with IE glitchiness on initial size.
setTimeout(dojo.hitch(this, this._resize), 100);
//Trigger a check for command enablement/disablement.
this.editor.onNormalizedDisplayChanged();
this.editor.__oldGetValue = this.editor.getValue;
this.editor.getValue = dojo.hitch(this, function() {
var txt = this.sourceArea.value;
txt = this._filter(txt);
return txt;
});
}else{
// First check that we were in source view before doing anything.
// corner case for being called with a value of false and we hadn't
// actually been in source display mode.
if(!ed._sourceQueryCommandEnabled){
return;
}
dojo.disconnect(this._resizeHandle);
delete this._resizeHandle;
if(this.editor.__oldGetValue){
this.editor.getValue = this.editor.__oldGetValue;
delete this.editor.__oldGetValue;
}
// Restore all the plugin buttons state.
ed.queryCommandEnabled = ed._sourceQueryCommandEnabled;
if(!this._readOnly){
html = this.sourceArea.value;
html = this._filter(html);
ed.beginEditing();
ed.set("value", html);
ed.endEditing();
}
dojo.forEach(edPlugins, function(p){
// Turn back on any plugins we turned off.
p.set("disabled", false);
});
dojo.style(this.sourceArea, "display", "none");
dojo.style(ed.iframe, "display", "block");
delete ed._sourceQueryCommandEnabled;
//Trigger a check for command enablement/disablement.
this.editor.onDisplayChanged();
}
// Call a delayed resize to wait for some things to display in header/footer.
setTimeout(dojo.hitch(this, function(){
// Make resize calls.
var parent = ed.domNode.parentNode;
if(parent){
var container = dijit.getEnclosingWidget(parent);
if(container && container.resize){
container.resize();
}
}
ed.resize();
}), 300);
}catch(e){
console.log(e);
}
},
updateState: function(){
// summary:
// Over-ride for button state control for disabled to work.
this.button.set("disabled", this.get("disabled"));
},
_resize: function(){
// summary:
// Internal function to resize the source view
// tags:
// private
var ed = this.editor;
var tbH = ed.getHeaderHeight();
var fH = ed.getFooterHeight();
var eb = dojo.position(ed.domNode);
// Styles are now applied to the internal source container, so we have
// to subtract them off.
var containerPadding = dojo._getPadBorderExtents(ed.iframe.parentNode);
var containerMargin = dojo._getMarginExtents(ed.iframe.parentNode);
var extents = dojo._getPadBorderExtents(ed.domNode);
var mExtents = dojo._getMarginExtents(ed.domNode);
var edb = {
w: eb.w - (extents.w + mExtents.w),
h: eb.h - (tbH + extents.h + mExtents.h + fH)
};
// Fullscreen gets odd, so we need to check for the FS plugin and
// adapt.
if(this._fsPlugin && this._fsPlugin.isFullscreen){
//Okay, probably in FS, adjust.
var vp = dojo.window.getBox();
edb.w = (vp.w - extents.w);
edb.h = (vp.h - (tbH + extents.h + fH));
}
if(dojo.isIE){
// IE is always off by 2px, so we have to adjust here
// Note that IE ZOOM is broken here. I can't get
//it to scale right.
edb.h -= 2;
}
// IE has a horrible zoom bug. So, we have to try and account for
// it and fix up the scaling.
if(this._ieFixNode){
var _ie7zoom = -this._ieFixNode.offsetTop / 1000;
edb.w = Math.floor((edb.w + 0.9) / _ie7zoom);
edb.h = Math.floor((edb.h + 0.9) / _ie7zoom);
}
dojo.marginBox(this.sourceArea, {
w: edb.w - (containerPadding.w + containerMargin.w),
h: edb.h - (containerPadding.h + containerMargin.h)
});
// Scale the parent container too in this case.
dojo.marginBox(ed.iframe.parentNode, {
h: edb.h
});
},
_createSourceView: function(){
// summary:
// Internal function for creating the source view area.
// tags:
// private
var ed = this.editor;
var edPlugins = ed._plugins;
this.sourceArea = dojo.create("textarea");
if(this.readOnly){
dojo.attr(this.sourceArea, "readOnly", true);
this._readOnly = true;
}
dojo.style(this.sourceArea, {
padding: "0px",
margin: "0px",
borderWidth: "0px",
borderStyle: "none"
});
dojo.place(this.sourceArea, ed.iframe, "before");
if(dojo.isIE && ed.iframe.parentNode.lastChild !== ed.iframe){
// There's some weirdo div in IE used for focus control
// But is messed up scaling the textarea if we don't config
// it some so it doesn't have a varying height.
dojo.style(ed.iframe.parentNode.lastChild,{
width: "0px",
height: "0px",
padding: "0px",
margin: "0px",
borderWidth: "0px",
borderStyle: "none"
});
}
// We also need to take over editor focus a bit here, so that focus calls to
// focus the editor will focus to the right node when VS is active.
ed._viewsource_oldFocus = ed.focus;
var self = this;
ed.focus = function(){
if(self._sourceShown){
self.setSourceAreaCaret();
}else{
try{
if(this._vsFocused){
delete this._vsFocused;
// Must focus edit node in this case (webkit only) or
// focus doesn't shift right, but in normal
// cases we focus with the regular function.
dijit.focus(ed.editNode);
}else{
ed._viewsource_oldFocus();
}
}catch(e){
console.log(e);
}
}
};
var i, p;
for(i = 0; i < edPlugins.length; i++){
// We actually do need to trap this plugin and adjust how we
// display the textarea.
p = edPlugins[i];
if(p && (p.declaredClass === "dijit._editor.plugins.FullScreen" ||
p.declaredClass === (dijit._scopeName +
"._editor.plugins.FullScreen"))){
this._fsPlugin = p;
break;
}
}
if(this._fsPlugin){
// Found, we need to over-ride the alt-view node function
// on FullScreen with our own, chain up to parent call when appropriate.
this._fsPlugin._viewsource_getAltViewNode = this._fsPlugin._getAltViewNode;
this._fsPlugin._getAltViewNode = function(){
return self._sourceShown?self.sourceArea:this._viewsource_getAltViewNode();
};
}
// Listen to the source area for key events as well, as we need to be able to hotkey toggle
// it from there too.
this.connect(this.sourceArea, "onkeydown", dojo.hitch(this, function(e){
if(this._sourceShown && e.keyCode == dojo.keys.F12 && e.ctrlKey && e.shiftKey){
this.button.focus();
this.button.set("checked", false);
setTimeout(dojo.hitch(this, function(){ed.focus();}), 100);
dojo.stopEvent(e);
}
}));
},
_stripScripts: function(html){
// summary:
// Strips out script tags from the HTML used in editor.
// html: String
// The HTML to filter
// tags:
// private
if(html){
// Look for closed and unclosed (malformed) script attacks.
html = html.replace(/<\s*script[^>]*>((.|\s)*?)<\\?\/\s*script\s*>/ig, "");
html = html.replace(/<\s*script\b([^<>]|\s)*>?/ig, "");
html = html.replace(/<[^>]*=(\s|)*[("|')]javascript:[^$1][(\s|.)]*[$1][^>]*>/ig, "");
}
return html;
},
_stripComments: function(html){
// summary:
// Strips out comments from the HTML used in editor.
// html: String
// The HTML to filter
// tags:
// private
if(html){
html = html.replace(/<!--(.|\s){1,}?-->/g, "");
}
return html;
},
_stripIFrames: function(html){
// summary:
// Strips out iframe tags from the content, to avoid iframe script
// style injection attacks.
// html: String
// The HTML to filter
// tags:
// private
if(html){
html = html.replace(/<\s*iframe[^>]*>((.|\s)*?)<\\?\/\s*iframe\s*>/ig, "");
}
return html;
},
_filter: function(html){
// summary:
// Internal function to perform some filtering on the HTML.
// html: String
// The HTML to filter
// tags:
// private
if(html){
if(this.stripScripts){
html = this._stripScripts(html);
}
if(this.stripComments){
html = this._stripComments(html);
}
if(this.stripIFrames){
html = this._stripIFrames(html);
}
}
return html;
},
setSourceAreaCaret: function(){
// summary:
// Internal function to set the caret in the sourceArea
// to 0x0
var win = dojo.global;
var elem = this.sourceArea;
dijit.focus(elem);
if(this._sourceShown && !this.readOnly){
if(dojo.isIE){
if(this.sourceArea.createTextRange){
var range = elem.createTextRange();
range.collapse(true);
range.moveStart("character", -99999); // move to 0
range.moveStart("character", 0); // delta from 0 is the correct position
range.moveEnd("character", 0);
range.select();
}
}else if(win.getSelection){
if(elem.setSelectionRange){
elem.setSelectionRange(0,0);
}
}
}
},
destroy: function(){
// summary:
// Over-ride to remove the node used to correct for IE's
// zoom bug.
if(this._ieFixNode){
dojo.body().removeChild(this._ieFixNode);
}
if(this._resizer){
clearTimeout(this._resizer);
delete this._resizer;
}
if(this._resizeHandle){
dojo.disconnect(this._resizeHandle);
delete this._resizeHandle;
}
this.inherited(arguments);
}
});
if(this._fsPlugin){
this._fsPlugin._getAltViewNode=function(){
return _7.sourceArea;
};
}
this.sourceArea.value=_6;
var is=dojo.marginBox(ed.iframe.parentNode);
dojo.marginBox(this.sourceArea,{w:is.w,h:is.h});
dojo.style(ed.iframe,"display","none");
dojo.style(this.sourceArea,{display:"block"});
var _a=function(){
var vp=dojo.window.getBox();
if("_prevW" in this&&"_prevH" in this){
if(vp.w===this._prevW&&vp.h===this._prevH){
return;
}else{
this._prevW=vp.w;
this._prevH=vp.h;
}
}else{
this._prevW=vp.w;
this._prevH=vp.h;
}
if(this._resizer){
clearTimeout(this._resizer);
delete this._resizer;
}
this._resizer=setTimeout(dojo.hitch(this,function(){
delete this._resizer;
this._resize();
}),10);
};
this._resizeHandle=dojo.connect(window,"onresize",this,_a);
setTimeout(dojo.hitch(this,this._resize),100);
this.editor.onNormalizedDisplayChanged();
}else{
if(!ed._sourceQueryCommandEnabled){
return;
}
dojo.disconnect(this._resizeHandle);
delete this._resizeHandle;
ed.queryCommandEnabled=ed._sourceQueryCommandEnabled;
if(!this._readOnly){
_6=this.sourceArea.value;
_6=this._filter(_6);
ed.beginEditing();
ed.set("value",_6);
ed.endEditing();
}
dojo.forEach(this._disabledPlugins,function(p){
p.button.set("disabled",false);
if(p._vs_updateState){
p.updateState=p._vs_updateState;
}
});
this._disabledPlugins=null;
dojo.style(this.sourceArea,"display","none");
dojo.style(ed.iframe,"display","block");
delete ed._sourceQueryCommandEnabled;
this.editor.onDisplayChanged();
}
setTimeout(dojo.hitch(this,function(){
var _b=ed.domNode.parentNode;
if(_b){
var _c=dijit.getEnclosingWidget(_b);
if(_c&&_c.resize){
_c.resize();
}
}
ed.resize();
}),300);
}
catch(e){
}
},_resize:function(){
var ed=this.editor;
var _d=ed.getHeaderHeight();
var fH=ed.getFooterHeight();
var eb=dojo.position(ed.domNode);
var _e=dojo._getPadBorderExtents(ed.iframe.parentNode);
var _f=dojo._getMarginExtents(ed.iframe.parentNode);
var _10=dojo._getPadBorderExtents(ed.domNode);
var _11=dojo._getMarginExtents(ed.domNode);
var edb={w:eb.w-(_10.w+_11.w),h:eb.h-(_d+_10.h+_11.h+fH)};
if(this._fsPlugin&&this._fsPlugin.isFullscreen){
var vp=dojo.window.getBox();
edb.w=(vp.w-_10.w);
edb.h=(vp.h-(_d+_10.h+fH));
}
if(dojo.isIE){
edb.h-=2;
}
if(this._ieFixNode){
var _12=-this._ieFixNode.offsetTop/1000;
edb.w=Math.floor((edb.w+0.9)/_12);
edb.h=Math.floor((edb.h+0.9)/_12);
}
dojo.marginBox(this.sourceArea,{w:edb.w-(_e.w+_f.w),h:edb.h-(_e.h+_f.h)});
dojo.marginBox(ed.iframe.parentNode,{h:edb.h});
},_createSourceView:function(){
var ed=this.editor;
var _13=ed._plugins;
this.sourceArea=dojo.create("textarea");
if(this.readOnly){
dojo.attr(this.sourceArea,"readOnly",true);
this._readOnly=true;
}
dojo.style(this.sourceArea,{padding:"0px",margin:"0px",borderWidth:"0px",borderStyle:"none"});
dojo.place(this.sourceArea,ed.iframe,"before");
if(dojo.isIE&&ed.iframe.parentNode.lastChild!==ed.iframe){
dojo.style(ed.iframe.parentNode.lastChild,{width:"0px",height:"0px",padding:"0px",margin:"0px",borderWidth:"0px",borderStyle:"none"});
}
ed._viewsource_oldFocus=ed.focus;
var _14=this;
ed.focus=function(){
if(_14._sourceShown){
_14.setSourceAreaCaret();
}else{
try{
if(this._vsFocused){
delete this._vsFocused;
dijit.focus(ed.editNode);
}else{
ed._viewsource_oldFocus();
}
}
catch(e){
}
}
};
var i,p;
for(i=0;i<_13.length;i++){
p=_13[i];
if(p&&(p.declaredClass==="dijit._editor.plugins.FullScreen"||p.declaredClass===(dijit._scopeName+"._editor.plugins.FullScreen"))){
this._fsPlugin=p;
break;
}
}
if(this._fsPlugin){
this._fsPlugin._viewsource_getAltViewNode=this._fsPlugin._getAltViewNode;
this._fsPlugin._getAltViewNode=function(){
return _14._sourceShown?_14.sourceArea:this._viewsource_getAltViewNode();
};
}
this.connect(this.sourceArea,"onkeydown",dojo.hitch(this,function(e){
if(this._sourceShown&&e.keyCode==dojo.keys.F12&&e.ctrlKey&&e.shiftKey){
this.button.focus();
this.button.set("checked",false);
setTimeout(dojo.hitch(this,function(){
ed.focus();
}),100);
dojo.stopEvent(e);
}
}));
},_stripScripts:function(_15){
if(_15){
_15=_15.replace(/<\s*script[^>]*>((.|\s)*?)<\\?\/\s*script\s*>/ig,"");
_15=_15.replace(/<\s*script\b([^<>]|\s)*>?/ig,"");
_15=_15.replace(/<[^>]*=(\s|)*[("|')]javascript:[^$1][(\s|.)]*[$1][^>]*>/ig,"");
}
return _15;
},_stripComments:function(_16){
if(_16){
_16=_16.replace(/<!--(.|\s){1,}?-->/g,"");
}
return _16;
},_stripIFrames:function(_17){
if(_17){
_17=_17.replace(/<\s*iframe[^>]*>((.|\s)*?)<\\?\/\s*iframe\s*>/ig,"");
}
return _17;
},_filter:function(_18){
if(_18){
if(this.stripScripts){
_18=this._stripScripts(_18);
}
if(this.stripComments){
_18=this._stripComments(_18);
}
if(this.stripIFrames){
_18=this._stripIFrames(_18);
}
}
return _18;
},setSourceAreaCaret:function(){
var win=dojo.global;
var _19=this.sourceArea;
dijit.focus(_19);
if(this._sourceShown&&!this.readOnly){
if(dojo.isIE){
if(this.sourceArea.createTextRange){
var _1a=_19.createTextRange();
_1a.collapse(true);
_1a.moveStart("character",-99999);
_1a.moveStart("character",0);
_1a.moveEnd("character",0);
_1a.select();
}
}else{
if(win.getSelection){
if(_19.setSelectionRange){
_19.setSelectionRange(0,0);
}
}
}
}
},destroy:function(){
if(this._ieFixNode){
dojo.body().removeChild(this._ieFixNode);
}
if(this._resizer){
clearTimeout(this._resizer);
delete this._resizer;
}
if(this._resizeHandle){
dojo.disconnect(this._resizeHandle);
delete this._resizeHandle;
}
this.inherited(arguments);
}});
dojo.subscribe(dijit._scopeName+".Editor.getPlugin",null,function(o){
if(o.plugin){
return;
}
var _1b=o.args.name.toLowerCase();
if(_1b==="viewsource"){
o.plugin=new dijit._editor.plugins.ViewSource({readOnly:("readOnly" in o.args)?o.args.readOnly:false,stripComments:("stripComments" in o.args)?o.args.stripComments:true,stripScripts:("stripScripts" in o.args)?o.args.stripScripts:true,stripIFrames:("stripIFrames" in o.args)?o.args.stripIFrames:true});
}
// Register this plugin.
dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
if(o.plugin){ return; }
var name = o.args.name.toLowerCase();
if(name === "viewsource"){
o.plugin = new dijit._editor.plugins.ViewSource({
readOnly: ("readOnly" in o.args)?o.args.readOnly:false,
stripComments: ("stripComments" in o.args)?o.args.stripComments:true,
stripScripts: ("stripScripts" in o.args)?o.args.stripScripts:true,
stripIFrames: ("stripIFrames" in o.args)?o.args.stripIFrames:true
});
}
});
}