123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882 |
- /*
- Copyright (c) 2004-2012, 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["dojox.editor.plugins.NormalizeIndentOutdent"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
- dojo._hasResource["dojox.editor.plugins.NormalizeIndentOutdent"] = true;
- dojo.provide("dojox.editor.plugins.NormalizeIndentOutdent");
- dojo.require("dijit._editor.selection");
- dojo.require("dijit._editor._Plugin");
- dojo.declare("dojox.editor.plugins.NormalizeIndentOutdent",dijit._editor._Plugin,{
- // summary:
- // This plugin provides improved indent and outdent handling to
- // the editor. It tries to generate valid HTML, as well as be
- // consistent about how it indents and outdents lists and blocks/elements.
- // indentBy: [public] number
- // The amount to indent by. Valid values are 1+. This is combined with
- // the indentUnits parameter to determine how much to indent or outdent
- // by for regular text. It does not affect lists.
- indentBy: 40,
-
- // indentUnits: [public] String
- // The units to apply to the indent amount. Usually 'px', but can also
- // be em.
- indentUnits: "px",
- 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;
- // Register out indent handler via the builtin over-ride mechanism.
- editor._indentImpl = dojo.hitch(this, this._indentImpl);
- editor._outdentImpl = dojo.hitch(this, this._outdentImpl);
- // Take over the query command enabled function, we want to prevent
- // indent of first items in a list, etc.
- if(!editor._indentoutdent_queryCommandEnabled){
- editor._indentoutdent_queryCommandEnabled = editor.queryCommandEnabled;
- }
- editor.queryCommandEnabled = dojo.hitch(this, this._queryCommandEnabled);
- // We need the custom undo code since we manipulate the dom
- // outside of the browser natives and only customUndo really handles
- // that. It will incur a performance hit, but should hopefully be
- // relatively small.
- editor.customUndo = true;
- },
- _queryCommandEnabled: function(command){
- // summary:
- // An over-ride for the editor's query command enabled,
- // so that we can prevent indents, etc, on bad elements
- // or positions (like first element in a list).
- // command:
- // The command passed in to check enablement.
- // tags:
- // private
- var c = command.toLowerCase();
- var ed, sel, range, node, tag, prevNode;
- var style = "marginLeft";
- if(!this._isLtr()){
- style = "marginRight";
- }
- if(c === "indent"){
- ed = this.editor;
- sel = dijit.range.getSelection(ed.window);
- if(sel && sel.rangeCount > 0){
- range = sel.getRangeAt(0);
- node = range.startContainer;
- // Check for li nodes first, we handle them a certain way.
- while(node && node !== ed.document && node !== ed.editNode){
- tag = this._getTagName(node);
- if(tag === "li"){
-
- prevNode = node.previousSibling;
- while(prevNode && prevNode.nodeType !== 1){
- prevNode = prevNode.previousSibling;
- }
- if(prevNode && this._getTagName(prevNode) === "li"){
- return true;
- }else{
- // First item, disallow
- return false;
- }
- }else if(this._isIndentableElement(tag)){
- return true;
- }
- node = node.parentNode;
- }
- if(this._isRootInline(range.startContainer)){
- return true;
- }
- }
- }else if(c === "outdent"){
- ed = this.editor;
- sel = dijit.range.getSelection(ed.window);
- if(sel && sel.rangeCount > 0){
- range = sel.getRangeAt(0);
- node = range.startContainer;
- // Check for li nodes first, we handle them a certain way.
- while(node && node !== ed.document && node !== ed.editNode){
- tag = this._getTagName(node);
- if(tag === "li"){
- // Standard list, we can ask the browser.
- return this.editor._indentoutdent_queryCommandEnabled(command);
- }else if(this._isIndentableElement(tag)){
- // Block, we need to handle the indent check.
- var cIndent = node.style?node.style[style]:"";
- if(cIndent){
- cIndent = this._convertIndent(cIndent);
- if(cIndent/this.indentBy >= 1){
- return true;
- }
- }
- return false;
- }
- node = node.parentNode;
- }
- if(this._isRootInline(range.startContainer)){
- return false;
- }
- }
- }else{
- return this.editor._indentoutdent_queryCommandEnabled(command);
- }
- return false;
- },
- _indentImpl: function(/*String*/ html) {
- // summary:
- // Improved implementation of indent, generates correct indent for
- // ul/ol
- var ed = this.editor;
- var sel = dijit.range.getSelection(ed.window);
- if(sel && sel.rangeCount > 0){
- var range = sel.getRangeAt(0);
- var node = range.startContainer;
- var tag, start, end, div;
-
- if(range.startContainer === range.endContainer){
- // No selection, just cursor point, we need to see if we're
- // in an indentable block, or similar.
- if(this._isRootInline(range.startContainer)){
- // Text at the 'root' of the document,
- // we'll try to indent it and all inline selements around it
- // as they are visually a single line.
- // First, we need to find the toplevel inline element that is rooted
- // to the document 'editNode'
- start = range.startContainer;
- while(start && start.parentNode !== ed.editNode){
- start = start.parentNode;
- }
- // Now we need to walk up its siblings and look for the first one in the rooting
- // that isn't inline or text, as we want to grab all of that for indent.
- while(start && start.previousSibling && (
- this._isTextElement(start) ||
- (start.nodeType === 1 && this._isInlineFormat(this._getTagName(start))
- ))){
- start = start.previousSibling;
- }
- if(start && start.nodeType === 1 && !this._isInlineFormat(this._getTagName(start))){
- // Adjust slightly, we're one node too far back in this case.
- start = start.nextSibling;
- }
- // Okay, we have a configured start, lets grab everything following it that's
- // inline and make it an indentable block!
- if(start){
- div = ed.document.createElement("div");
- dojo.place(div, start, "after");
- div.appendChild(start);
- end = div.nextSibling;
- while(end && (
- this._isTextElement(end) ||
- (end.nodeType === 1 &&
- this._isInlineFormat(this._getTagName(end)))
- )){
- // Add it.
- div.appendChild(end);
- end = div.nextSibling;
- }
- this._indentElement(div);
- dojo.withGlobal(ed.window,
- "selectElementChildren", dijit._editor.selection, [div]);
- dojo.withGlobal(ed.window,
- "collapse", dijit._editor.selection, [true]);
- }
- }else{
- while(node && node !== ed.document && node !== ed.editNode){
- tag = this._getTagName(node);
- if(tag === "li"){
- this._indentList(node);
- return;
- }else if(this._isIndentableElement(tag)){
- this._indentElement(node);
- return;
- }
- node = node.parentNode;
- }
- }
- }else{
- var curNode;
- // multi-node select. We need to scan over them.
- // Find the two containing nodes at start and end.
- // then move the end one node past. Then ... lets see
- // what we can indent!
- start = range.startContainer;
- end = range.endContainer;
- // Find the non-text nodes.
- while(start && this._isTextElement(start) && start.parentNode !== ed.editNode){
- start = start.parentNode;
- }
- while(end && this._isTextElement(end) && end.parentNode !== ed.editNode){
- end = end.parentNode;
- }
- if(end === ed.editNode || end === ed.document.body){
- // Okay, selection end is somewhere after start, we need to find the last node
- // that is safely in the range.
- curNode = start;
- while(curNode.nextSibling &&
- dojo.withGlobal(ed.window, "inSelection", dijit._editor.selection, [curNode])){
- curNode = curNode.nextSibling;
- }
- end = curNode;
- if(end === ed.editNode || end === ed.document.body){
- // Unable to determine real selection end, so just make it
- // a single node indent of start + all following inline styles, if
- // present, then just exit.
- tag = this._getTagName(start);
- if(tag === "li"){
- this._indentList(start);
- }else if(this._isIndentableElement(tag)){
- this._indentElement(start);
- }else if(this._isTextElement(start) ||
- this._isInlineFormat(tag)){
- // inline element or textnode, So we want to indent it somehow
- div = ed.document.createElement("div");
- dojo.place(div, start, "after");
- // Find and move all inline tags following the one we inserted also into the
- // div so we don't split up content funny.
- var next = start;
- while(next && (
- this._isTextElement(next) ||
- (next.nodeType === 1 &&
- this._isInlineFormat(this._getTagName(next))))){
- div.appendChild(next);
- next = div.nextSibling;
- }
- this._indentElement(div);
- }
- return;
- }
- }
-
- // Has a definite end somewhere, so lets try to indent up to it.
- // requires looking at the selections and in some cases, moving nodes
- // into indentable blocks.
- end = end.nextSibling;
- curNode = start;
- while(curNode && curNode !== end){
- if(curNode.nodeType === 1){
- tag = this._getTagName(curNode);
- if(dojo.isIE){
- // IE sometimes inserts blank P tags, which we want to skip
- // as they end up indented, which messes up layout.
- if(tag === "p" && this._isEmpty(curNode)){
- curNode = curNode.nextSibling;
- continue;
- }
- }
- if(tag === "li"){
- if(div){
- if(this._isEmpty(div)){
- div.parentNode.removeChild(div);
- }else{
- this._indentElement(div);
- }
- div = null;
- }
- this._indentList(curNode);
- }else if(!this._isInlineFormat(tag) && this._isIndentableElement(tag)){
- if(div){
- if(this._isEmpty(div)){
- div.parentNode.removeChild(div);
- }else{
- this._indentElement(div);
- }
- div = null;
- }
- curNode = this._indentElement(curNode);
- }else if(this._isInlineFormat(tag)){
- // inline tag.
- if(!div){
- div = ed.document.createElement("div");
- dojo.place(div, curNode, "after");
- div.appendChild(curNode);
- curNode = div;
- }else{
- div.appendChild(curNode);
- curNode = div;
- }
- }
- }else if(this._isTextElement(curNode)){
- if(!div){
- div = ed.document.createElement("div");
- dojo.place(div, curNode, "after");
- div.appendChild(curNode);
- curNode = div;
- }else{
- div.appendChild(curNode);
- curNode = div;
- }
- }
- curNode = curNode.nextSibling;
- }
- // Okay, indent everything we merged if we haven't yet..
- if(div){
- if(this._isEmpty(div)){
- div.parentNode.removeChild(div);
- }else{
- this._indentElement(div);
- }
- div = null;
- }
- }
- }
- },
- _indentElement: function(node){
- // summary:
- // Function to indent a block type tag.
- // node:
- // The node who's content to indent.
- // tags:
- // private
- var style = "marginLeft";
- if(!this._isLtr()){
- style = "marginRight";
- }
- var tag = this._getTagName(node);
- if(tag === "ul" || tag === "ol"){
- // Lists indent funny, so lets wrap them in a div
- // and indent the div instead.
- var div = this.editor.document.createElement("div");
- dojo.place(div, node, "after");
- div.appendChild(node);
- node = div;
- }
- var cIndent = node.style?node.style[style]:"";
- if(cIndent){
- cIndent = this._convertIndent(cIndent);
- cIndent = (parseInt(cIndent, 10) + this.indentBy) + this.indentUnits;
- }else{
- cIndent = this.indentBy + this.indentUnits;
- }
- dojo.style(node, style, cIndent);
- return node; //Return the node that was indented.
- },
- _outdentElement: function(node){
- // summary:
- // Function to outdent a block type tag.
- // node:
- // The node who's content to outdent.
- // tags:
- // private
- var style = "marginLeft";
- if(!this._isLtr()){
- style = "marginRight";
- }
- var cIndent = node.style?node.style[style]:"";
- if(cIndent){
- cIndent = this._convertIndent(cIndent);
- if(cIndent - this.indentBy > 0){
- cIndent = (parseInt(cIndent, 10) - this.indentBy) + this.indentUnits;
- }else{
- cIndent = "";
- }
- dojo.style(node, style, cIndent);
- }
- },
- _outdentImpl: function(/*String*/ html) {
- // summary:
- // Improved implementation of outdent, generates correct indent for
- // ul/ol and other elements.
- // tags:
- // private
- var ed = this.editor;
- var sel = dijit.range.getSelection(ed.window);
- if(sel && sel.rangeCount > 0){
- var range = sel.getRangeAt(0);
- var node = range.startContainer;
- var tag;
- if(range.startContainer === range.endContainer){
- // Check for li nodes first, we handle them a certain way.
- while(node && node !== ed.document && node !== ed.editNode){
- tag = this._getTagName(node);
- if(tag === "li"){
- return this._outdentList(node);
- }else if(this._isIndentableElement(tag)){
- return this._outdentElement(node);
- }
- node = node.parentNode;
- }
- ed.document.execCommand("outdent", false, html);
- }else{
- // multi-node select. We need to scan over them.
- // Find the two containing nodes at start and end.
- // then move the end one node past. Then ... lets see
- // what we can outdent!
- var start = range.startContainer;
- var end = range.endContainer;
- // Find the non-text nodes.
- while(start && start.nodeType === 3){
- start = start.parentNode;
- }
- while(end && end.nodeType === 3){
- end = end.parentNode;
- }
- end = end.nextSibling;
- var curNode = start;
- while(curNode && curNode !== end){
- if(curNode.nodeType === 1){
- tag = this._getTagName(curNode);
- if(tag === "li"){
- this._outdentList(curNode);
- }else if(this._isIndentableElement(tag)){
- this._outdentElement(curNode);
- }
- }
- curNode = curNode.nextSibling;
- }
- }
- }
- return null;
- },
- _indentList: function(listItem){
- // summary:
- // Internal function to handle indenting a list element.
- // listItem:
- // The list item to indent.
- // tags:
- // private
- var ed = this.editor;
- var newList, li;
- var listContainer = listItem.parentNode;
- var prevTag = listItem.previousSibling;
-
- // Ignore text, we want elements.
- while(prevTag && prevTag.nodeType !== 1){
- prevTag = prevTag.previousSibling;
- }
- var type = null;
- var tg = this._getTagName(listContainer);
-
- // Try to determine what kind of list item is here to indent.
- if(tg === "ol"){
- type = "ol";
- }else if(tg === "ul"){
- type = "ul";
- }
-
- // Only indent list items actually in a list.
- // Bail out if the list is malformed somehow.
- if(type){
- // There is a previous node in the list, so we want to append a new list
- // element after it that contains a new list of the content to indent it.
- if(prevTag && prevTag.tagName.toLowerCase() == "li"){
- // Lets see if we can merge this into another (Eg,
- // does the sibling li contain an embedded list already of
- // the same type? if so, we move into that one.
- var embList;
- if(prevTag.childNodes){
- var i;
- for(i = 0; i < prevTag.childNodes.length; i++){
- var n = prevTag.childNodes[i];
- if(n.nodeType === 3){
- if(dojo.trim(n.nodeValue)){
- if(embList){
- // Non-empty text after list, exit, can't embed.
- break;
- }
- }
- }else if(n.nodeType === 1 && !embList){
- // See if this is a list container.
- if(type === n.tagName.toLowerCase()){
- embList = n;
- }
- }else{
- // Other node present, break, can't embed.
- break;
- }
- }
- }
- if(embList){
- // We found a list to merge to, so merge.
- embList.appendChild(listItem);
- }else{
- // Nope, wasn't an embedded list container,
- // So lets just create a new one.
- newList = ed.document.createElement(type);
- dojo.style(newList, {
- paddingTop: "0px",
- paddingBottom: "0px"
- });
- li = ed.document.createElement("li");
- dojo.style(li, {
- listStyleImage: "none",
- listStyleType: "none"
- });
- prevTag.appendChild(newList);
- newList.appendChild(listItem);
- }
- // Move cursor.
- dojo.withGlobal(ed.window,
- "selectElementChildren", dijit._editor.selection, [listItem]);
- dojo.withGlobal(ed.window,
- "collapse", dijit._editor.selection, [true]);
- }
- }
- },
- _outdentList: function(listItem){
- // summary:
- // Internal function to handle outdenting a list element.
- // listItem:
- // The list item to outdent.
- // tags:
- // private
- var ed = this.editor;
- var list = listItem.parentNode;
- var type = null;
- var tg = list.tagName ? list.tagName.toLowerCase() : "";
- var li;
- // Try to determine what kind of list contains the item.
- if(tg === "ol"){
- type = "ol";
- }else if(tg === "ul"){
- type = "ul";
- }
- // Check to see if it is a nested list, as outdenting is handled differently.
- var listParent = list.parentNode;
- var lpTg = this._getTagName(listParent);
-
- // We're in a list, so we need to outdent this specially.
- // Check for welformed and malformed lists (<ul><ul></ul>U/ul> type stuff).
- if(lpTg === "li" || lpTg === "ol" || lpTg === "ul"){
- if(lpTg === "ol" || lpTg === "ul"){
- // Okay, we need to fix this up, this is invalid html,
- // So try to combine this into a previous element before
- // de do a shuffle of the nodes, to build an HTML compliant
- // list.
- var prevListLi = list.previousSibling;
- while(prevListLi && (prevListLi.nodeType !== 1 ||
- (prevListLi.nodeType === 1 &&
- this._getTagName(prevListLi) !== "li"))
- ){
- prevListLi = prevListLi.previousSibling;
- }
- if(prevListLi){
- // Move this list up into the previous li
- // to fix malformation.
- prevListLi.appendChild(list);
- listParent = prevListLi;
- }else{
- li = listItem;
- var firstItem = listItem;
- while(li.previousSibling){
- li = li.previousSibling;
- if(li.nodeType === 1 && this._getTagName(li) === "li"){
- firstItem = li;
- }
- }
- if(firstItem !== listItem){
- dojo.place(firstItem, list, "before");
- firstItem.appendChild(list);
- listParent = firstItem;
- }else{
- // No previous list item in a malformed list
- // ... so create one and move into that.
- li = ed.document.createElement("li");
- dojo.place(li, list, "before");
- li.appendChild(list);
- listParent = li;
- }
- dojo.style(list, {
- paddingTop: "0px",
- paddingBottom: "0px"
- });
- }
- }
- // find the previous node, if any,
- // non-text.
- var prevLi = listItem.previousSibling;
- while(prevLi && prevLi.nodeType !== 1){
- prevLi = prevLi.previousSibling;
- }
- var nextLi = listItem.nextSibling;
- while(nextLi && nextLi.nodeType !== 1){
- nextLi = nextLi.nextSibling;
- }
- if(!prevLi){
- // Top item in a nested list, so just move it out
- // and then shuffle the remaining indented list into it.
- dojo.place(listItem, listParent, "after");
- listItem.appendChild(list);
- }else if(!nextLi){
- // Last item in a nested list, shuffle it out after
- // the nsted list only.
- dojo.place(listItem, listParent, "after");
- }else{
- // Item is in the middle of an embedded list, so we
- // have to split it.
- // Move all the items following current list item into
- // a list after it.
- var newList = ed.document.createElement(type);
- dojo.style(newList, {
- paddingTop: "0px",
- paddingBottom: "0px"
- });
- listItem.appendChild(newList);
- while(listItem.nextSibling){
- newList.appendChild(listItem.nextSibling);
- }
- // Okay, now place the list item after the
- // current list parent (li).
- dojo.place(listItem, listParent, "after");
- }
-
- // Clean up any empty lists left behind.
- if(list && this._isEmpty(list)){
- list.parentNode.removeChild(list);
- }
- if(listParent && this._isEmpty(listParent)){
- listParent.parentNode.removeChild(listParent);
- }
-
- // Move our cursor to the list item we moved.
- dojo.withGlobal(ed.window,
- "selectElementChildren", dijit._editor.selection, [listItem]);
- dojo.withGlobal(ed.window,
- "collapse", dijit._editor.selection, [true]);
- }else{
- // Not in a nested list, so we can just defer to the
- // browser and hope it outdents right.
- ed.document.execCommand("outdent", false, null);
- }
- },
- _isEmpty: function(node){
- // summary:
- // Internal function to determine if a node is 'empty'
- // Eg, contains only blank text. Used to determine if
- // an empty list element should be removed or not.
- // node:
- // The node to check.
- // tags:
- // private
- if(node.childNodes){
- var empty = true;
- var i;
- for(i = 0; i < node.childNodes.length; i++){
- var n = node.childNodes[i];
- if(n.nodeType === 1){
- if(this._getTagName(n) === "p"){
- if(!dojo.trim(n.innerHTML)){
- continue;
- }
- }
- empty = false;
- break;
- }else if(this._isTextElement(n)){
- // Check for empty text.
- var nv = dojo.trim(n.nodeValue);
- if(nv && nv !==" " && nv !== "\u00A0"){
- empty = false;
- break;
- }
- }else{
- empty = false;
- break;
- }
- }
- return empty;
- }else{
- return true;
- }
- },
- _isIndentableElement: function(tag){
- // summary:
- // Internal function to detect what element types
- // are indent-controllable by us.
- // tag:
- // The tag to check
- // tags:
- // private
- switch(tag){
- case "p":
- case "div":
- case "h1":
- case "h2":
- case "h3":
- case "center":
- case "table":
- case "ul":
- case "ol":
- return true;
- default:
- return false;
- }
- },
- _convertIndent: function(indent){
- // summary:
- // Function to convert the current indent style to
- // the units we're using by some heuristic.
- // indent:
- // The indent amount to convert.
- // tags:
- // private
- var pxPerEm = 12;
- indent = indent + "";
- indent = indent.toLowerCase();
- var curUnit = (indent.indexOf("px") > 0) ? "px" : (indent.indexOf("em") > 0) ? "em" : "px";
- indent = indent.replace(/(px;?|em;?)/gi, "");
- if(curUnit === "px"){
- if(this.indentUnits === "em"){
- indent = Math.ceil(indent/pxPerEm);
- }
- }else{
- if(this.indentUnits === "px"){
- indent = indent * pxPerEm;
- }
- }
- return indent;
- },
- _isLtr: function(){
- // summary:
- // Function to detect if the editor body is in RTL or LTR.
- // tags:
- // private
- var editDoc = this.editor.document.body;
- return dojo.withGlobal(this.editor.window, function(){
- var cs = dojo.getComputedStyle(editDoc);
- return cs ? cs.direction == "ltr" : true;
- });
- },
- _isInlineFormat: function(tag){
- // summary:
- // Function to determine if the current tag is an inline
- // element that does formatting, as we don't want to
- // break/indent around it, as it can screw up text.
- // tag:
- // The tag to examine
- // tags:
- // private
- switch(tag){
- case "a":
- case "b":
- case "strong":
- case "s":
- case "strike":
- case "i":
- case "u":
- case "em":
- case "sup":
- case "sub":
- case "span":
- case "font":
- case "big":
- case "cite":
- case "q":
- case "img":
- case "small":
- return true;
- default:
- return false;
- }
- },
- _getTagName: function(node){
- // summary:
- // Internal function to get the tag name of an element
- // if any.
- // node:
- // The node to look at.
- // tags:
- // private
- var tag = "";
- if(node && node.nodeType === 1){
- tag = node.tagName?node.tagName.toLowerCase():"";
- }
- return tag;
- },
- _isRootInline: function(node){
- // summary:
- // This functions tests whether an indicated node is in root as inline
- // or rooted inline elements in the page.
- // node:
- // The node to start at.
- // tags:
- // private
- var ed = this.editor;
- if(this._isTextElement(node) && node.parentNode === ed.editNode){
- return true;
- }else if(node.nodeType === 1 && this._isInlineFormat(node) && node.parentNode === ed.editNode){
- return true;
- }else if(this._isTextElement(node) && this._isInlineFormat(this._getTagName(node.parentNode))){
- node = node.parentNode;
- while(node && node !== ed.editNode && this._isInlineFormat(this._getTagName(node))){
- node = node.parentNode;
- }
- if(node === ed.editNode){
- return true;
- }
- }
- return false;
- },
- _isTextElement: function(node){
- // summary:
- // Helper function to check for text nodes.
- // node:
- // The node to check.
- // tags:
- // private
- if(node && node.nodeType === 3 || node.nodeType === 4){
- return true;
- }
- return false;
- }
- });
- // Register this plugin.
- dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
- if(o.plugin){ return; }
- var name = o.args.name.toLowerCase();
- if(name === "normalizeindentoutdent"){
- o.plugin = new dojox.editor.plugins.NormalizeIndentOutdent({
- indentBy: ("indentBy" in o.args) ?
- (o.args.indentBy > 0 ? o.args.indentBy : 40) :
- 40,
- indentUnits: ("indentUnits" in o.args) ?
- (o.args.indentUnits.toLowerCase() == "em"? "em" : "px") :
- "px"
- });
- }
- });
- }
|