Blame | Last modification | View Log | RSS feed
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); //entereditor.addKeyHandler(13, 2, h); //shift+enterthis.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 directlydijit._editor.RichText.prototype.execCommand.apply(this.editor, ['formatblock',this.blockNodeForEnter]);//set the innerHTML of the new block nodevar 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 charvar 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 belowthis.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 optionsif(!this.blockNodeForEnter){ return true; } //let browser handle thisif(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// FIXMEdijit._editor.RichText.prototype.execCommand.call(this.editor, 'inserthtml', '<br>');}return false;}var _letBrowserHandle = true;//blockNodeForEnter is either P or DIV//first remove selectionvar 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 nodeif(!block.blockNode){this.editor.document.execCommand('formatblock',false, this.blockNodeForEnter);//get the newly created block node// FIXMEblock = {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 blockvar 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 manuallynewblock.scrollIntoView(false);}_letBrowserHandle = false;}else{ //press enter in the middle of Pif(dojo.isMoz){//press enter in middle of P may leave a trailing <br/>, let's remove it laterthis._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 propertiesvar head = doc.getElementsByTagName("head")[0];if(!head){ // must have a head tagconsole.debug("No head tag in document, aborting styles");return; // HTMLStyleElement}else{head.appendChild(style);}if(style.styleSheet){// IEvar setFunc = function(){try{style.styleSheet.cssText = cssStr;}catch(e){ dojo.debug(e); }};if(style.styleSheet.disabled){setTimeout(setFunc, 10);}else{setFunc();}}else{ // w3cvar 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 psfunction wrapNodes(nodes){// nodes are assumed to all be siblingsvar newP = nodes[0].ownerDocument.createElement('p'); // FIXME: not very idiomaticnodes[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 anyvar 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 BRsvar 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 issuenewP.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;}});}