diff options
Diffstat (limited to 'js/dojo-1.6/dojox/editor/plugins/NormalizeIndentOutdent.xd.js')
| -rw-r--r-- | js/dojo-1.6/dojox/editor/plugins/NormalizeIndentOutdent.xd.js | 889 |
1 files changed, 889 insertions, 0 deletions
diff --git a/js/dojo-1.6/dojox/editor/plugins/NormalizeIndentOutdent.xd.js b/js/dojo-1.6/dojox/editor/plugins/NormalizeIndentOutdent.xd.js new file mode 100644 index 0000000..a8fa2f7 --- /dev/null +++ b/js/dojo-1.6/dojox/editor/plugins/NormalizeIndentOutdent.xd.js @@ -0,0 +1,889 @@ +/*
+ 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
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.editor.plugins.NormalizeIndentOutdent"],
+["require", "dijit._editor.selection"],
+["require", "dijit._editor._Plugin"]],
+defineResource: function(dojo, dijit, dojox){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"
+ });
+ }
+});
+
+}
+
+}};});
|
