/trunk/api/js/dojo1.0/dijit/_editor/plugins/LinkDialog.js |
---|
New file |
0,0 → 1,150 |
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.Dialog"); |
dojo.require("dijit.form.Button"); |
dojo.require("dijit.form.ValidationTextBox"); |
dojo.require("dojo.i18n"); |
dojo.require("dojo.string"); |
dojo.requireLocalization("dijit._editor", "LinkDialog", null, "ko,zh,ja,zh-tw,ru,it,ROOT,hu,fr,pt,pl,es,de,cs"); |
dojo.declare("dijit._editor.plugins.DualStateDropDownButton", |
dijit.form.DropDownButton, |
{ |
// summary: a DropDownButton but button can be displayed in two states (checked or unchecked) |
setChecked: dijit.form.ToggleButton.prototype.setChecked |
} |
); |
dojo.declare("dijit._editor.plugins.UrlTextBox", |
dijit.form.ValidationTextBox, |
{ |
// summary: the URL input box we use in our dialog |
// regular expression for URLs, generated from dojo.regexp.url() |
regExp: "((https?|ftps?)\\://|)(([0-9a-zA-Z]([-0-9a-zA-Z]{0,61}[0-9a-zA-Z])?\\.)+(arpa|aero|biz|com|coop|edu|gov|info|int|mil|museum|name|net|org|pro|travel|xxx|jobs|mobi|post|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|er|eu|es|et|fi|fj|fk|fm|fo|fr|ga|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sk|sl|sm|sn|sr|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tm|tn|to|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)|(((\\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])))(\\:(0|[1-9]\\d*))?(/([^?#\\s/]+/)*)?([^?#\\s/]+(\\?[^?#\\s/]*)?(#[A-Za-z][\\w.:-]*)?)?", |
required: true, |
postMixInProperties: function(){ |
this.inherited("postMixInProperties", arguments); |
this.invalidMessage = dojo.i18n.getLocalization("dijit._editor", "LinkDialog", this.lang).urlInvalidMessage; |
}, |
getValue: function(){ |
if(!/^(https?|ftps?)/.test(this.textbox.value)){ |
this.textbox.value="http://"+this.textbox.value; |
} |
return this.textbox.value; |
} |
} |
); |
dojo.declare("dijit._editor.plugins.LinkDialog", |
dijit._editor._Plugin, |
{ |
buttonClass: dijit._editor.plugins.DualStateDropDownButton, |
useDefaultCommand: false, |
command: "createLink", |
linkDialogTemplate: [ |
"<label for='urlInput'>${url} </label>", |
"<input dojoType=dijit._editor.plugins.UrlTextBox name='urlInput'><br>", |
"<label for='textInput'>${text} </label>", |
"<input dojoType=dijit.form.TextBox name='textInput'>", |
"<br>", |
"<button dojoType=dijit.form.Button type='submit'>${set}</button>" |
].join(""), |
constructor: function(){ |
var _this = this; |
var messages = dojo.i18n.getLocalization("dijit._editor", "LinkDialog", this.lang); |
this.dropDown = new dijit.TooltipDialog({ |
title: messages.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); |
}, |
onClose: dojo.hitch(this, "_onCloseDialog") |
}); |
this.dropDown.setContent(dojo.string.substitute(this.linkDialogTemplate, messages)); |
this.dropDown.startup(); |
}, |
setValue: function(args){ |
// summary: callback from the dialog when user hits "set" button |
//TODO: prevent closing popup if the text is empty |
this._onCloseDialog(); |
if(dojo.isIE){ //see #4151 |
var a = dojo.withGlobal(this.editor.window, "getAncestorElement",dijit._editor.selection, ['a']); |
if(a){ |
dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [a]); |
} |
} |
var attstr='href="'+args.urlInput+'" _djrealurl="'+args.urlInput+'"'; |
// console.log(args,this.editor,'<a '+attstr+'>'+args.textInput+'</a>'); |
this.editor.execCommand('inserthtml', '<a '+attstr+'>'+args.textInput+'</a>'); |
// this.editor.execCommand(this.command, args.urlInput); |
}, |
// _savedSelection: null, |
_onCloseDialog: function(){ |
// FIXME: IE is really messed up here!! |
if(dojo.isIE){ |
if(this._savedSelection){ |
var b=this._savedSelection; |
this._savedSelection=null; |
this.editor.focus(); |
var range = this.editor.document.selection.createRange(); |
range.moveToBookmark(b); |
range.select(); |
} |
}else{this.editor.focus(); |
} |
}, |
_onOpenDialog: function(){ |
var a = dojo.withGlobal(this.editor.window, "getAncestorElement",dijit._editor.selection, ['a']); |
var url='',text=''; |
if(a){ |
url=a.getAttribute('_djrealurl'); |
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); |
} |
// FIXME: IE is *really* b0rken |
if(dojo.isIE){ |
var range = this.editor.document.selection.createRange(); |
this._savedSelection = range.getBookmark(); |
} |
this.dropDown.setValues({'urlInput':url,'textInput':text}); |
//dijit.focus(this.urlInput); |
}, |
updateState: function(){ |
// summary: change shading on button if we are over a link (or not) |
var _e = this.editor; |
if(!_e){ return; } |
if(!_e.isLoaded){ return; } |
if(this.button){ |
try{ |
// display button differently if there is an existing link associated with the current selection |
var hasA = dojo.withGlobal(this.editor.window, "hasAncestorElement",dijit._editor.selection, ['a']); |
this.button.setChecked(hasA); |
}catch(e){ |
console.debug(e); //FIXME: probably shouldn't squelch an exception here |
} |
} |
} |
} |
); |
} |
/trunk/api/js/dojo1.0/dijit/_editor/plugins/FontChoice.js |
---|
New file |
0,0 → 1,66 |
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.form.FilteringSelect"); |
dojo.require("dojo.data.ItemFileReadStore"); |
dojo.require("dojo.i18n"); |
dojo.requireLocalization("dijit._editor", "FontChoice", null, "ROOT"); |
dojo.declare("dijit._editor.plugins.FontChoice", |
dijit._editor._Plugin, |
{ |
_uniqueId: 0, |
buttonClass: dijit.form.FilteringSelect, |
_initButton: function(){ |
this.inherited("_initButton", arguments); |
//TODO: do we need nls for font names? provide css font lists? or otherwise make this more configurable? |
var names = { |
fontName: ["serif", "sans-serif", "monospaced", "cursive", "fantasy"], |
fontSize: [1,2,3,4,5,6,7], |
formatBlock: ["p", "h1", "h2", "h3", "pre"] }[this.command]; |
var strings = dojo.i18n.getLocalization("dijit._editor", "FontChoice"); |
var items = dojo.map(names, function(x){ return { name: strings[x], value: x }; }); |
items.push({name:"", value:""}); // FilteringSelect doesn't like unmatched blank strings |
this.button.store = new dojo.data.ItemFileReadStore( |
{ data: { identifier: "value", |
items: items } |
}); |
this.button.setValue(""); |
dojo.connect(this.button, "onChange", this, function(choice){ |
this.editor.execCommand(this.command, choice); |
}); |
}, |
updateState: function(){ |
this.inherited("updateState", arguments); |
var _e = this.editor; |
var _c = this.command; |
if(!_e || !_e.isLoaded || !_c.length){ return; } |
if(this.button){ |
var value = _e.queryCommandValue(_c); |
this.button.setValue(value); |
} |
}, |
setToolbar: function(){ |
this.inherited("setToolbar", arguments); |
var forRef = this.button; |
if(!forRef.id){ forRef.id = "dijitEditorButton-"+this.command+(this._uniqueId++); } //TODO: is this necessary? FilteringSelects always seem to have an id? |
var label = dojo.doc.createElement("label"); |
label.setAttribute("for", forRef.id); |
var strings = dojo.i18n.getLocalization("dijit._editor", "FontChoice"); |
label.appendChild(dojo.doc.createTextNode(strings[this.command])); |
dojo.place(label, this.button.domNode, "before"); |
} |
} |
); |
} |
/trunk/api/js/dojo1.0/dijit/_editor/plugins/TextColor.js |
---|
New file |
0,0 → 1,24 |
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, |
//TODO: set initial focus/selection state? |
constructor: function(){ |
this.dropDown = new dijit.ColorPalette(); |
dojo.connect(this.dropDown, "onChange", this, function(color){ |
this.editor.execCommand(this.command, color); |
}); |
} |
} |
); |
} |
/trunk/api/js/dojo1.0/dijit/_editor/plugins/AlwaysShowToolbar.js |
---|
New file |
0,0 → 1,147 |
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", null, |
{ |
_handleScroll: true, |
setEditor: function(e){ |
this.editor=e; |
// setTimeout(dojo.hitch(this,this.enable),10000); |
e.onLoadDeferred.addCallback(dojo.hitch(this,this.enable)); |
// this.scrollInterval = setInterval(dojo.hitch(this, "globalOnScrollHandler"), 100); |
}, |
enable: function(d){ |
this._updateHeight(); |
this._connects=[dojo.connect(window,'onscroll',this,"globalOnScrollHandler"), |
dojo.connect(this.editor,'onNormalizedDisplayChanged',this,"_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.marginBox(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.marginBox(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(height != this._lastHeight){ |
this._lastHeight = height; |
// this.editorObject.style.height = this._lastHeight + "px"; |
dojo.marginBox(e.iframe, { h: this._lastHeight }); |
// this.iframe.height=this._lastHeight+10+'px'; |
// this.iframe.style.height=this._lastHeight+'px'; |
} |
}, |
_lastHeight: 0, |
globalOnScrollHandler: function(){ |
var isIE = dojo.isIE && dojo.isIE<7; |
if(!this._handleScroll){ return; } |
var tdn = this.editor.toolbar.domNode; |
var db = dojo.body; |
if(!this._scrollSetUp){ |
this._scrollSetUp = true; |
this._scrollThreshold = dojo._abs(tdn, true).y; |
// console.log("threshold:", this._scrollThreshold); |
//what's this for?? comment out for now |
// if((isIE)&&(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; |
if(scrollPos > this._scrollThreshold && scrollPos < this._scrollThreshold+this._lastHeight){ |
// dojo.debug(scrollPos); |
if(!this._fixEnabled){ |
var tdnbox = dojo.marginBox(tdn); |
this.editor.iframe.style.marginTop = tdnbox.h+"px"; |
if(isIE){ |
tdn.style.left = dojo._abs(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,'IEFixedToolbar'); |
}else{ |
with(tdn.style){ |
position = "fixed"; |
top = "0px"; |
} |
} |
dojo.marginBox(tdn, { w: tdnbox.w }); |
tdn.style.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; |
if(scrollPos > (this._scrollThreshold+eHeight)){ |
tdn.style.display = "none"; |
}else{ |
tdn.style.display = ""; |
} |
}else if(this._fixEnabled){ |
this.editor.iframe.style.marginTop = ''; |
with(tdn.style){ |
position = ""; |
top = ""; |
zIndex = ""; |
display = ""; |
} |
if(isIE){ |
tdn.style.left = ""; |
dojo.removeClass(tdn,'IEFixedToolbar'); |
if(this._IEOriginalPos){ |
dojo.place(tdn, this._IEOriginalPos[1], this._IEOriginalPos[0]); |
this._IEOriginalPos = null; |
}else{ |
dojo.place(tdn, this.editor.iframe,'before'); |
} |
} |
tdn.style.width = ""; |
this._fixEnabled = false; |
} |
}, |
destroy: function(){ |
this._IEOriginalPos = null; |
this._handleScroll = false; |
dojo.forEach(this._connects,dojo.disconnect); |
// clearInterval(this.scrollInterval); |
if(dojo.isIE && dojo.isIE<7){ |
dojo.removeClass(this.editor.toolbar.domNode,'IEFixedToolbar'); |
} |
} |
}); |
} |
/trunk/api/js/dojo1.0/dijit/_editor/plugins/EnterKeyHandling.js |
---|
New file |
0,0 → 1,422 |
if(!dojo._hasResource["dijit._editor.plugins.EnterKeyHandling"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. |
dojo._hasResource["dijit._editor.plugins.EnterKeyHandling"] = true; |
dojo.provide("dijit._editor.plugins.EnterKeyHandling"); |
dojo.declare("dijit._editor.plugins.EnterKeyHandling",null,{ |
// blockNodeForEnter: String |
// this property decides the behavior of Enter key. It can be either P, |
// DIV, BR, or empty (which means disable this feature). Anything else |
// will trigger errors. |
blockNodeForEnter: 'P', |
constructor: function(args){ |
if(args){ |
dojo.mixin(this,args); |
} |
}, |
setEditor: function(editor){ |
this.editor=editor; |
if(this.blockNodeForEnter=='BR'){ |
if(dojo.isIE){ |
editor.contentDomPreFilters.push(dojo.hitch(this, "regularPsToSingleLinePs")); |
editor.contentDomPostFilters.push(dojo.hitch(this, "singleLinePsToRegularPs")); |
editor.onLoadDeferred.addCallback(dojo.hitch(this, "_fixNewLineBehaviorForIE")); |
}else{ |
editor.onLoadDeferred.addCallback(dojo.hitch(this,function(d){ |
try{ |
this.editor.document.execCommand("insertBrOnReturn", false, true); |
}catch(e){}; |
return d; |
})); |
} |
}else if(this.blockNodeForEnter){ |
//add enter key handler |
// FIXME: need to port to the new event code!! |
dojo['require']('dijit._editor.range'); |
var h=dojo.hitch(this,this.handleEnterKey); |
editor.addKeyHandler(13, 0, h); //enter |
editor.addKeyHandler(13, 2, h); //shift+enter |
this.connect(this.editor,'onKeyPressed','onKeyPressed'); |
} |
}, |
connect: function(o,f,tf){ |
if(!this._connects){ |
this._connects=[]; |
} |
this._connects.push(dojo.connect(o,f,this,tf)); |
}, |
destroy: function(){ |
dojo.forEach(this._connects,dojo.disconnect); |
this._connects=[]; |
}, |
onKeyPressed: function(e){ |
if(this._checkListLater){ |
if(dojo.withGlobal(this.editor.window, 'isCollapsed', dijit._editor.selection)){ |
if(!dojo.withGlobal(this.editor.window, 'hasAncestorElement', dijit._editor.selection, ['LI'])){ |
//circulate the undo detection code by calling RichText::execCommand directly |
dijit._editor.RichText.prototype.execCommand.apply(this.editor, ['formatblock',this.blockNodeForEnter]); |
//set the innerHTML of the new block node |
var block = dojo.withGlobal(this.editor.window, 'getAncestorElement', dijit._editor.selection, [this.blockNodeForEnter]) |
if(block){ |
block.innerHTML=this.bogusHtmlContent; |
if(dojo.isIE){ |
//the following won't work, it will move the caret to the last list item in the previous list |
// var newrange = dijit.range.create(); |
// newrange.setStart(block.firstChild,0); |
// var selection = dijit.range.getSelection(this.editor.window) |
// selection.removeAllRanges(); |
// selection.addRange(newrange); |
//move to the start by move backward one char |
var r = this.editor.document.selection.createRange(); |
r.move('character',-1); |
r.select(); |
} |
}else{ |
alert('onKeyPressed: Can not find the new block node'); |
} |
} |
} |
this._checkListLater = false; |
}else if(this._pressedEnterInBlock){ |
//the new created is the original current P, so we have previousSibling below |
this.removeTrailingBr(this._pressedEnterInBlock.previousSibling); |
delete this._pressedEnterInBlock; |
} |
}, |
bogusHtmlContent: ' ', |
blockNodes: /^(?:H1|H2|H3|H4|H5|H6|LI)$/, |
handleEnterKey: function(e){ |
// summary: manually handle enter key event to make the behavior consistant across |
// all supported browsers. See property blockNodeForEnter for available options |
if(!this.blockNodeForEnter){ return true; } //let browser handle this |
if(e.shiftKey //shift+enter always generates <br> |
|| this.blockNodeForEnter=='BR'){ |
var parent = dojo.withGlobal(this.editor.window, "getParentElement", dijit._editor.selection); |
var header = dijit.range.getAncestor(parent,this.editor.blockNodes); |
if(header){ |
if(header.tagName=='LI'){ |
return true; //let brower handle |
} |
var selection = dijit.range.getSelection(this.editor.window); |
var range = selection.getRangeAt(0); |
if(!range.collapsed){ |
range.deleteContents(); |
} |
if(dijit.range.atBeginningOfContainer(header, range.startContainer, range.startOffset)){ |
dojo.place(this.editor.document.createElement('br'), header, "before"); |
}else if(dijit.range.atEndOfContainer(header, range.startContainer, range.startOffset)){ |
dojo.place(this.editor.document.createElement('br'), header, "after"); |
var newrange = dijit.range.create(); |
newrange.setStartAfter(header); |
selection.removeAllRanges(); |
selection.addRange(newrange); |
}else{ |
return true; //let brower handle |
} |
}else{ |
//don't change this: do not call this.execCommand, as that may have other logic in subclass |
// FIXME |
dijit._editor.RichText.prototype.execCommand.call(this.editor, 'inserthtml', '<br>'); |
} |
return false; |
} |
var _letBrowserHandle = true; |
//blockNodeForEnter is either P or DIV |
//first remove selection |
var selection = dijit.range.getSelection(this.editor.window); |
var range = selection.getRangeAt(0); |
if(!range.collapsed){ |
range.deleteContents(); |
} |
var block = dijit.range.getBlockAncestor(range.endContainer, null, this.editor.editNode); |
if(block.blockNode && block.blockNode.tagName == 'LI'){ |
this._checkListLater = true; |
return true; |
}else{ |
this._checkListLater = false; |
} |
//text node directly under body, let's wrap them in a node |
if(!block.blockNode){ |
this.editor.document.execCommand('formatblock',false, this.blockNodeForEnter); |
//get the newly created block node |
// FIXME |
block = {blockNode:dojo.withGlobal(this.editor.window, "getAncestorElement", dijit._editor.selection, [this.blockNodeForEnter]), |
blockContainer: this.editor.editNode}; |
if(block.blockNode){ |
if((block.blockNode.textContent||block.blockNode.innerHTML).replace(/^\s+|\s+$/g, "").length==0){ |
this.removeTrailingBr(block.blockNode); |
return false; |
} |
}else{ |
block.blockNode = this.editor.editNode; |
} |
selection = dijit.range.getSelection(this.editor.window); |
range = selection.getRangeAt(0); |
} |
var newblock = this.editor.document.createElement(this.blockNodeForEnter); |
newblock.innerHTML=this.bogusHtmlContent; |
this.removeTrailingBr(block.blockNode); |
if(dijit.range.atEndOfContainer(block.blockNode, range.endContainer, range.endOffset)){ |
if(block.blockNode === block.blockContainer){ |
block.blockNode.appendChild(newblock); |
}else{ |
dojo.place(newblock, block.blockNode, "after"); |
} |
_letBrowserHandle = false; |
//lets move caret to the newly created block |
var newrange = dijit.range.create(); |
newrange.setStart(newblock,0); |
selection.removeAllRanges(); |
selection.addRange(newrange); |
if(this.editor.height){ |
newblock.scrollIntoView(false); |
} |
}else if(dijit.range.atBeginningOfContainer(block.blockNode, |
range.startContainer, range.startOffset)){ |
if(block.blockNode === block.blockContainer){ |
dojo.place(newblock, block.blockNode, "first"); |
}else{ |
dojo.place(newblock, block.blockNode, "before"); |
} |
if(this.editor.height){ |
//browser does not scroll the caret position into view, do it manually |
newblock.scrollIntoView(false); |
} |
_letBrowserHandle = false; |
}else{ //press enter in the middle of P |
if(dojo.isMoz){ |
//press enter in middle of P may leave a trailing <br/>, let's remove it later |
this._pressedEnterInBlock = block.blockNode; |
} |
} |
return _letBrowserHandle; |
}, |
removeTrailingBr: function(container){ |
if(/P|DIV|LI/i .test(container.tagName)){ |
var para = container; |
}else{ |
var para = dijit._editor.selection.getParentOfType(container,['P','DIV','LI']); |
} |
if(!para){ return; } |
if(para.lastChild){ |
if(para.childNodes.length>1 && para.lastChild.nodeType==3 && /^[\s\xAD]*$/ .test(para.lastChild.nodeValue)){ |
dojo._destroyElement(para.lastChild); |
} |
if(para.lastChild && para.lastChild.tagName=='BR'){ |
dojo._destroyElement(para.lastChild); |
} |
} |
if(para.childNodes.length==0){ |
para.innerHTML=this.bogusHtmlContent; |
} |
}, |
_fixNewLineBehaviorForIE: function(d){ |
if(typeof this.editor.document.__INSERTED_EDITIOR_NEWLINE_CSS == "undefined"){ |
var lineFixingStyles = "p{margin:0 !important;}"; |
var insertCssText = function( |
/*String*/ cssStr, |
/*Document*/ doc, |
/*String*/ URI) |
{ |
// summary: |
// Attempt to insert CSS rules into the document through inserting a |
// style element |
// DomNode Style = insertCssText(String ".dojoMenu {color: green;}"[, DomDoc document, dojo.uri.Uri Url ]) |
if(!cssStr){ |
return; // HTMLStyleElement |
} |
if(!doc){ doc = document; } |
// if(URI){// fix paths in cssStr |
// cssStr = dojo.html.fixPathsInCssText(cssStr, URI); |
// } |
var style = doc.createElement("style"); |
style.setAttribute("type", "text/css"); |
// IE is b0rken enough to require that we add the element to the doc |
// before changing it's properties |
var head = doc.getElementsByTagName("head")[0]; |
if(!head){ // must have a head tag |
console.debug("No head tag in document, aborting styles"); |
return; // HTMLStyleElement |
}else{ |
head.appendChild(style); |
} |
if(style.styleSheet){// IE |
var setFunc = function(){ |
try{ |
style.styleSheet.cssText = cssStr; |
}catch(e){ dojo.debug(e); } |
}; |
if(style.styleSheet.disabled){ |
setTimeout(setFunc, 10); |
}else{ |
setFunc(); |
} |
}else{ // w3c |
var cssText = doc.createTextNode(cssStr); |
style.appendChild(cssText); |
} |
return style; // HTMLStyleElement |
} |
insertCssText(lineFixingStyles, this.editor.document); |
this.editor.document.__INSERTED_EDITIOR_NEWLINE_CSS = true; |
// this.regularPsToSingleLinePs(this.editNode); |
return d; |
} |
}, |
regularPsToSingleLinePs: function(element, noWhiteSpaceInEmptyP){ |
function wrapLinesInPs(el){ |
// move "lines" of top-level text nodes into ps |
function wrapNodes(nodes){ |
// nodes are assumed to all be siblings |
var newP = nodes[0].ownerDocument.createElement('p'); // FIXME: not very idiomatic |
nodes[0].parentNode.insertBefore(newP, nodes[0]); |
for(var i=0; i<nodes.length; i++){ |
newP.appendChild(nodes[i]); |
} |
} |
var currentNodeIndex = 0; |
var nodesInLine = []; |
var currentNode; |
while(currentNodeIndex < el.childNodes.length){ |
currentNode = el.childNodes[currentNodeIndex]; |
if( (currentNode.nodeName!='BR') && |
(currentNode.nodeType==1) && |
(dojo.style(currentNode, "display")!="block") |
){ |
nodesInLine.push(currentNode); |
}else{ |
// hit line delimiter; process nodesInLine if there are any |
var nextCurrentNode = currentNode.nextSibling; |
if(nodesInLine.length){ |
wrapNodes(nodesInLine); |
currentNodeIndex = (currentNodeIndex+1)-nodesInLine.length; |
if(currentNode.nodeName=="BR"){ |
dojo._destroyElement(currentNode); |
} |
} |
nodesInLine = []; |
} |
currentNodeIndex++; |
} |
if(nodesInLine.length){ wrapNodes(nodesInLine); } |
} |
function splitP(el){ |
// split a paragraph into seperate paragraphs at BRs |
var currentNode = null; |
var trailingNodes = []; |
var lastNodeIndex = el.childNodes.length-1; |
for(var i=lastNodeIndex; i>=0; i--){ |
currentNode = el.childNodes[i]; |
if(currentNode.nodeName=="BR"){ |
var newP = currentNode.ownerDocument.createElement('p'); |
dojo.place(newP, el, "after"); |
if (trailingNodes.length==0 && i != lastNodeIndex) { |
newP.innerHTML = " " |
} |
dojo.forEach(trailingNodes, function(node){ |
newP.appendChild(node); |
}); |
dojo._destroyElement(currentNode); |
trailingNodes = []; |
}else{ |
trailingNodes.unshift(currentNode); |
} |
} |
} |
var pList = []; |
var ps = element.getElementsByTagName('p'); |
dojo.forEach(ps, function(p){ pList.push(p); }); |
dojo.forEach(pList, function(p){ |
if( (p.previousSibling) && |
(p.previousSibling.nodeName == 'P' || dojo.style(p.previousSibling, 'display') != 'block') |
){ |
var newP = p.parentNode.insertBefore(this.document.createElement('p'), p); |
// this is essential to prevent IE from losing the P. |
// if it's going to be innerHTML'd later we need |
// to add the to _really_ force the issue |
newP.innerHTML = noWhiteSpaceInEmptyP ? "" : " "; |
} |
splitP(p); |
},this.editor); |
wrapLinesInPs(element); |
return element; |
}, |
singleLinePsToRegularPs: function(element){ |
function getParagraphParents(node){ |
var ps = node.getElementsByTagName('p'); |
var parents = []; |
for(var i=0; i<ps.length; i++){ |
var p = ps[i]; |
var knownParent = false; |
for(var k=0; k < parents.length; k++){ |
if(parents[k] === p.parentNode){ |
knownParent = true; |
break; |
} |
} |
if(!knownParent){ |
parents.push(p.parentNode); |
} |
} |
return parents; |
} |
function isParagraphDelimiter(node){ |
if(node.nodeType != 1 || node.tagName != 'P'){ |
return (dojo.style(node, 'display') == 'block'); |
}else{ |
if(!node.childNodes.length || node.innerHTML==" "){ return true } |
//return node.innerHTML.match(/^(<br\ ?\/?>| |\ \;)$/i); |
} |
} |
var paragraphContainers = getParagraphParents(element); |
for(var i=0; i<paragraphContainers.length; i++){ |
var container = paragraphContainers[i]; |
var firstPInBlock = null; |
var node = container.firstChild; |
var deleteNode = null; |
while(node){ |
if(node.nodeType != "1" || node.tagName != 'P'){ |
firstPInBlock = null; |
}else if (isParagraphDelimiter(node)){ |
deleteNode = node; |
firstPInBlock = null; |
}else{ |
if(firstPInBlock == null){ |
firstPInBlock = node; |
}else{ |
if( (!firstPInBlock.lastChild || firstPInBlock.lastChild.nodeName != 'BR') && |
(node.firstChild) && |
(node.firstChild.nodeName != 'BR') |
){ |
firstPInBlock.appendChild(this.editor.document.createElement('br')); |
} |
while(node.firstChild){ |
firstPInBlock.appendChild(node.firstChild); |
} |
deleteNode = node; |
} |
} |
node = node.nextSibling; |
if(deleteNode){ |
dojo._destroyElement(deleteNode); |
deleteNode = null; |
} |
} |
} |
return element; |
} |
}); |
} |