dijit/_editor/range.js

  • Provides:

    • dijit._editor.range
  • dijit.range.W3CRange

    • type
      Function
    • source: [view]
        if(arguments.length>0){
         this.setStart(arguments[0][0],arguments[0][1]);
         this.setEnd(arguments[0][2],arguments[0][3]);
        }else{
         this.commonAncestorContainer = null;
         this.startContainer = null;
         this.startOffset = 0;
         this.endContainer = null;
         this.endOffset = 0;
         this.collapsed = true;
        }
    • summary
  • dijit.range.W3CRange._updateInternal

    • type
      Function
    • source: [view]
        if(this.startContainer !== this.endContainer){
         this.commonAncestorContainer = dijit.range.getCommonAncestor(this.startContainer, this.endContainer);
        }else{
         this.commonAncestorContainer = this.startContainer;
        }
        this.collapsed = (this.startContainer === this.endContainer) && (this.startOffset == this.endOffset);
    • summary
  • dijit.range.W3CRange.setStart

    • type
      Function
    • parameters:
      • node: (typeof )
      • offset: (typeof )
    • source: [view]
        offset=parseInt(offset);
        if(this.startContainer === node && this.startOffset == offset){
         return;
        }
        delete this._cachedBookmark;


        this.startContainer = node;
        this.startOffset = offset;
        if(!this.endContainer){
         this.setEnd(node, offset);
        }else{
         this._updateInternal();
        }
    • summary
  • dijit.range.W3CRange.setEnd

    • type
      Function
    • parameters:
      • node: (typeof )
      • offset: (typeof )
    • source: [view]
        offset=parseInt(offset);
        if(this.endContainer === node && this.endOffset == offset){
         return;
        }
        delete this._cachedBookmark;


        this.endContainer = node;
        this.endOffset = offset;
        if(!this.startContainer){
         this.setStart(node, offset);
        }else{
         this._updateInternal();
        }
    • summary
  • dijit.range.W3CRange.setStartAfter

    • type
      Function
    • parameters:
      • node: (typeof )
      • offset: (typeof )
    • source: [view]
        this._setPoint('setStart', node, offset, 1);
    • summary
  • dijit.range.W3CRange.setStartBefore

    • type
      Function
    • parameters:
      • node: (typeof )
      • offset: (typeof )
    • source: [view]
        this._setPoint('setStart', node, offset, 0);
    • summary
  • dijit.range.W3CRange.setEndAfter

    • type
      Function
    • parameters:
      • node: (typeof )
      • offset: (typeof )
    • source: [view]
        this._setPoint('setEnd', node, offset, 1);
    • summary
  • dijit.range.W3CRange.setEndBefore

    • type
      Function
    • parameters:
      • node: (typeof )
      • offset: (typeof )
    • source: [view]
        this._setPoint('setEnd', node, offset, 0);
    • summary
  • dijit.range.W3CRange._setPoint

    • type
      Function
    • parameters:
      • what: (typeof )
      • node: (typeof )
      • offset: (typeof )
      • ext: (typeof )
    • source: [view]
        var index = dijit.range.getIndex(node, node.parentNode).o;
        this[what](node.parentNode, index.pop()+ext);
    • summary
  • dijit.range.W3CRange._getIERange

    • type
      Function
    • source: [view]
        var r = (this._body || this.endContainer.ownerDocument.body).createTextRange();
        dijit.range.ie.setRange(r, this.startContainer, this.startOffset, this.endContainer, this.endOffset, this.collapsed);
        return r;
    • summary
  • dijit.range.W3CRange.getBookmark

    • type
      Function
    • parameters:
      • body: (typeof )
    • source: [view]
        this._getIERange();
        return this._cachedBookmark;
    • summary
  • dijit.range.W3CRange._select

    • type
      Function
    • source: [view]
        var r = this._getIERange();
        r.select();
    • summary
  • dijit.range.W3CRange.deleteContents

    • type
      Function
    • source: [view]
        var r = this._getIERange();
        r.pasteHTML('');
        this.endContainer = this.startContainer;
        this.endOffset = this.startOffset;
        this.collapsed = true;
    • summary
  • dijit.range.W3CRange.cloneRange

    • type
      Function
    • source: [view]
        var r = new dijit.range.W3CRange([this.startContainer,this.startOffset,
         this.endContainer,this.endOffset]);
        r._body = this._body;
        return r;
    • summary
  • dijit.range.W3CRange.detach

    • type
      Function
    • source: [view]
        this._body = null;
        this.commonAncestorContainer = null;
        this.startContainer = null;
        this.startOffset = 0;
        this.endContainer = null;
        this.endOffset = 0;
        this.collapsed = true;
    • summary
  • dijit.range.W3CRange.commonAncestorContainer

    • summary
  • dijit.range.W3CRange.collapsed

    • summary
  • dijit.range.W3CRange.startContainer

    • summary
  • dijit.range.W3CRange.startOffset

    • summary
  • dijit.range.W3CRange.endContainer

    • summary
  • dijit.range.W3CRange.endOffset

    • summary
  • dijit.range.W3CRange._body

    • summary
  • dijit.range

    • type
      Object
    • summary
  • dijit.range.ie

    • type
      Object
    • summary
  • dijit.range.ie.cachedSelection

    • type
      Object
    • summary
  • dijit.range.ie.selection

    • type
      Function
    • parameters:
      • win: (typeof )
    • source: [view]
         this._ranges = [];
         this.addRange = function(r, /*boolean*/internal){
          this._ranges.push(r);
          if(!internal){
           r._select();
          }
          this.rangeCount = this._ranges.length;
         };
         this.removeAllRanges = function(){
          //don't detach, the range may be used later
      //    for(var i=0;i//     this._ranges[i].detach();
      //    }
          this._ranges = [];
          this.rangeCount = 0;
         };
         var _initCurrentRange = function(){
          var r = win.document.selection.createRange();
          var type=win.document.selection.type.toUpperCase();
          if(type == "CONTROL"){
           //TODO: multiple range selection(?)
           return new dijit.range.W3CRange(dijit.range.ie.decomposeControlRange(r));
          }else{
           return new dijit.range.W3CRange(dijit.range.ie.decomposeTextRange(r));
          }
         };
         this.getRangeAt = function(i){
          return this._ranges[i];
         };
         this._getCurrentSelection = function(){
          this.removeAllRanges();
          var r=_initCurrentRange();
          if(r){
           this.addRange(r, true);
          }
         };
    • summary
  • dijit.range.ie.selection._ranges

    • summary
  • dijit.range.ie.selection.addRange

    • type
      Function
    • parameters:
      • r: (typeof )
      • internal: (typeof boolean)
    • source: [view]
          this._ranges.push(r);
          if(!internal){
           r._select();
          }
          this.rangeCount = this._ranges.length;
    • summary
  • dijit.range.ie.selection.rangeCount

    • summary
  • dijit.range.ie.selection.removeAllRanges

    • type
      Function
    • source: [view]
      define("dijit/_editor/range", ["dojo", "dijit"], function(dojo, dijit) {


      dijit.range={};


      dijit.range.getIndex=function(/*DomNode*/node, /*DomNode*/parent){
      // dojo.profile.start("dijit.range.getIndex");
       var ret=[], retR=[];
       var stop = parent;
       var onode = node;


       var pnode, n;
       while(node != stop){
        var i = 0;
        pnode = node.parentNode;
        while((n=pnode.childNodes[i++])){
         if(n === node){
          --i;
          break;
         }
        }
        //if(i>=pnode.childNodes.length){
         //dojo.debug("Error finding index of a node in dijit.range.getIndex");
        //}
        ret.unshift(i);
        retR.unshift(i-pnode.childNodes.length);
        node = pnode;
       }


       //normalized() can not be called so often to prevent
       //invalidating selection/range, so we have to detect
       //here that any text nodes in a row
       if(ret.length > 0 && onode.nodeType == 3){
        n = onode.previousSibling;
        while(n && n.nodeType == 3){
         ret[ret.length-1]--;
         n = n.previousSibling;
        }
        n = onode.nextSibling;
        while(n && n.nodeType == 3){
         retR[retR.length-1]++;
         n = n.nextSibling;
        }
       }
      // dojo.profile.end("dijit.range.getIndex");
       return {o: ret, r:retR};
      }


      dijit.range.getNode = function(/*Array*/index, /*DomNode*/parent){
       if(!dojo.isArray(index) || index.length == 0){
        return parent;
       }
       var node = parent;
      // if(!node)debugger
       dojo.every(index, function(i){
        if(i >= 0 && i < node.childNodes.length){
         node = node.childNodes[i];
        }else{
         node = null;
         //console.debug('Error: can not find node with index',index,'under parent node',parent );
         return false; //terminate dojo.every
        }
        return true; //carry on the every loop
       });


       return node;
      }


      dijit.range.getCommonAncestor = function(n1,n2,root){
       root = root||n1.ownerDocument.body;
       var getAncestors = function(n){
        var as=[];
        while(n){
         as.unshift(n);
         if(n !== root){
          n = n.parentNode;
         }else{
          break;
         }
        }
        return as;
       };
       var n1as = getAncestors(n1);
       var n2as = getAncestors(n2);


       var m = Math.min(n1as.length,n2as.length);
       var com = n1as[0]; //at least, one element should be in the array: the root (BODY by default)
       for(var i=1;i  if(n1as[i] === n2as[i]){
         com = n1as[i]
        }else{
         break;
        }
       }
       return com;
      }


      dijit.range.getAncestor = function(/*DomNode*/node, /*RegEx?*/regex, /*DomNode?*/root){
       root = root || node.ownerDocument.body;
       while(node && node !== root){
        var name = node.nodeName.toUpperCase() ;
        if(regex.test(name)){
         return node;
        }


        node = node.parentNode;
       }
       return null;
      }


      dijit.range.BlockTagNames = /^(?:P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|DT|DE)$/;
      dijit.range.getBlockAncestor = function(/*DomNode*/node, /*RegEx?*/regex, /*DomNode?*/root){
       root = root || node.ownerDocument.body;
       regex = regex || dijit.range.BlockTagNames;
       var block=null, blockContainer;
       while(node && node !== root){
        var name = node.nodeName.toUpperCase() ;
        if(!block && regex.test(name)){
         block = node;
        }
        if(!blockContainer && (/^(?:BODY|TD|TH|CAPTION)$/).test(name)){
         blockContainer = node;
        }


        node = node.parentNode;
       }
       return {blockNode:block, blockContainer:blockContainer || node.ownerDocument.body};
      }


      dijit.range.atBeginningOfContainer = function(/*DomNode*/container, /*DomNode*/node, /*Int*/offset){
       var atBeginning = false;
       var offsetAtBeginning = (offset == 0);
       if(!offsetAtBeginning && node.nodeType == 3){ //if this is a text node, check whether the left part is all space
        if(/^[\s\xA0]+$/.test(node.nodeValue.substr(0,offset))){
         offsetAtBeginning = true;
        }
       }
       if(offsetAtBeginning){
        var cnode = node;
        atBeginning = true;
        while(cnode && cnode !== container){
         if(cnode.previousSibling){
          atBeginning = false;
          break;
         }
         cnode = cnode.parentNode;
        }
       }
       return atBeginning;
      }


      dijit.range.atEndOfContainer = function(/*DomNode*/container, /*DomNode*/node, /*Int*/offset){
       var atEnd = false;
       var offsetAtEnd = (offset == (node.length || node.childNodes.length));
       if(!offsetAtEnd && node.nodeType == 3){ //if this is a text node, check whether the right part is all space
        if(/^[\s\xA0]+$/.test(node.nodeValue.substr(offset))){
         offsetAtEnd = true;
        }
       }
       if(offsetAtEnd){
        var cnode = node;
        atEnd = true;
        while(cnode && cnode !== container){
         if(cnode.nextSibling){
          atEnd = false;
          break;
         }
         cnode = cnode.parentNode;
        }
       }
       return atEnd;
      }


      dijit.range.adjacentNoneTextNode=function(startnode, next){
       var node = startnode;
       var len = (0-startnode.length) || 0;
       var prop = next?'nextSibling':'previousSibling';
       while(node){
        if(node.nodeType!=3){
         break;
        }
        len += node.length
        node = node[prop];
       }
       return [node,len];
      }


      dijit.range._w3c = Boolean(window['getSelection']);
      dijit.range.create = function(/*Window?*/win){
       if(dijit.range._w3c){
        return (win || dojo.global).document.createRange();
       }else{//IE
        return new dijit.range.W3CRange;
       }
      }


      dijit.range.getSelection = function(/*Window*/win, /*Boolean?*/ignoreUpdate){
       if(dijit.range._w3c){
        return win.getSelection();
       }else{//IE
        var s = new dijit.range.ie.selection(win);
        if(!ignoreUpdate){
         s._getCurrentSelection();
        }
        return s;
       }
      }


      if(!dijit.range._w3c){
       dijit.range.ie={
        cachedSelection: {},
        selection: function(win){
         this._ranges = [];
         this.addRange = function(r, /*boolean*/internal){
          this._ranges.push(r);
          if(!internal){
           r._select();
          }
          this.rangeCount = this._ranges.length;
         };
         this.removeAllRanges = function(){
          //don't detach, the range may be used later
      //    for(var i=0;i//     this._ranges[i].detach();
      //    }
          this._ranges = [];
          this.rangeCount = 0;
    • returns
      terminate dojo.every|carry on the every loop
    • summary
  • dijit.range.ie.selection.getRangeAt

    • type
      Function
    • parameters:
      • i: (typeof )
    • source: [view]
          return this._ranges[i];
    • summary
  • dijit.range.ie.selection._getCurrentSelection

    • type
      Function
    • source: [view]
          this.removeAllRanges();
          var r=_initCurrentRange();
          if(r){
           this.addRange(r, true);
          }
    • summary
  • dijit.range.ie.decomposeControlRange

    • type
      Function
    • parameters:
      • range: (typeof )
    • source: [view]
         var firstnode = range.item(0), lastnode = range.item(range.length-1);
         var startContainer = firstnode.parentNode, endContainer = lastnode.parentNode;
         var startOffset = dijit.range.getIndex(firstnode, startContainer).o;
         var endOffset = dijit.range.getIndex(lastnode, endContainer).o+1;
         return [startContainer, startOffset,endContainer, endOffset];
    • summary
  • dijit.range.ie.getEndPoint

    • type
      Function
    • parameters:
      • range: (typeof )
      • end: (typeof )
    • source: [view]
         var atmrange = range.duplicate();
         atmrange.collapse(!end);
         var cmpstr = 'EndTo' + (end?'End':'Start');
         var parentNode = atmrange.parentElement();


         var startnode, startOffset, lastNode;
         if(parentNode.childNodes.length>0){
          dojo.every(parentNode.childNodes, function(node,i){
           var calOffset;
           if(node.nodeType != 3){
            atmrange.moveToElementText(node);


            if(atmrange.compareEndPoints(cmpstr,range) > 0){
             //startnode = node.previousSibling;
             if(lastNode && lastNode.nodeType == 3){
              //where shall we put the start? in the text node or after?
              startnode = lastNode;
              calOffset = true;
             }else{
              startnode = parentNode;
              startOffset = i;
              return false;
             }
            }else{
             if(i == parentNode.childNodes.length-1){
              startnode = parentNode;
              startOffset = parentNode.childNodes.length;
              return false;
             }
            }
           }else{
            if(i == parentNode.childNodes.length-1){//at the end of this node
             startnode = node;
             calOffset = true;
            }
           }
        //   try{
            if(calOffset && startnode){
             var prevnode = dijit.range.adjacentNoneTextNode(startnode)[0];
             if(prevnode){
              startnode = prevnode.nextSibling;
             }else{
              startnode = parentNode.firstChild; //firstChild must be a text node
             }
             var prevnodeobj = dijit.range.adjacentNoneTextNode(startnode);
             prevnode = prevnodeobj[0];
             var lenoffset = prevnodeobj[1];
             if(prevnode){
              atmrange.moveToElementText(prevnode);
              atmrange.collapse(false);
             }else{
              atmrange.moveToElementText(parentNode);
             }
             atmrange.setEndPoint(cmpstr, range);
             startOffset = atmrange.text.length-lenoffset;


             return false;
            }
        //   }catch(e){ debugger }
           lastNode = node;
           return true;
          });
         }else{
          startnode = parentNode;
          startOffset = 0;
         }


         //if at the end of startnode and we are dealing with start container, then
         //move the startnode to nextSibling if it is a text node
         //TODO: do this for end container?
         if(!end && startnode.nodeType == 1 && startOffset == startnode.childNodes.length){
          var nextnode=startnode.nextSibling;
          if(nextnode && nextnode.nodeType == 3){
           startnode = nextnode;
           startOffset = 0;
          }
         }
         return [startnode, startOffset];
    • summary
  • dijit.range.ie.setEndPoint

    • type
      Function
    • parameters:
      • range: (typeof )
      • container: (typeof )
      • offset: (typeof )
    • source: [view]
      define("dijit/_editor/range", ["dojo", "dijit"], function(dojo, dijit) {


      dijit.range={};


      dijit.range.getIndex=function(/*DomNode*/node, /*DomNode*/parent){
      // dojo.profile.start("dijit.range.getIndex");
       var ret=[], retR=[];
       var stop = parent;
       var onode = node;


       var pnode, n;
       while(node != stop){
        var i = 0;
        pnode = node.parentNode;
        while((n=pnode.childNodes[i++])){
         if(n === node){
          --i;
          break;
         }
        }
        //if(i>=pnode.childNodes.length){
         //dojo.debug("Error finding index of a node in dijit.range.getIndex");
        //}
        ret.unshift(i);
        retR.unshift(i-pnode.childNodes.length);
        node = pnode;
       }


       //normalized() can not be called so often to prevent
       //invalidating selection/range, so we have to detect
       //here that any text nodes in a row
       if(ret.length > 0 && onode.nodeType == 3){
        n = onode.previousSibling;
        while(n && n.nodeType == 3){
         ret[ret.length-1]--;
         n = n.previousSibling;
        }
        n = onode.nextSibling;
        while(n && n.nodeType == 3){
         retR[retR.length-1]++;
         n = n.nextSibling;
        }
       }
      // dojo.profile.end("dijit.range.getIndex");
       return {o: ret, r:retR};
      }


      dijit.range.getNode = function(/*Array*/index, /*DomNode*/parent){
       if(!dojo.isArray(index) || index.length == 0){
        return parent;
       }
       var node = parent;
      // if(!node)debugger
       dojo.every(index, function(i){
        if(i >= 0 && i < node.childNodes.length){
         node = node.childNodes[i];
        }else{
         node = null;
         //console.debug('Error: can not find node with index',index,'under parent node',parent );
         return false; //terminate dojo.every
        }
        return true; //carry on the every loop
       });


       return node;
      }


      dijit.range.getCommonAncestor = function(n1,n2,root){
       root = root||n1.ownerDocument.body;
       var getAncestors = function(n){
        var as=[];
        while(n){
         as.unshift(n);
         if(n !== root){
          n = n.parentNode;
         }else{
          break;
         }
        }
        return as;
       };
       var n1as = getAncestors(n1);
       var n2as = getAncestors(n2);


       var m = Math.min(n1as.length,n2as.length);
       var com = n1as[0]; //at least, one element should be in the array: the root (BODY by default)
       for(var i=1;i  if(n1as[i] === n2as[i]){
         com = n1as[i]
        }else{
         break;
        }
       }
       return com;
      }


      dijit.range.getAncestor = function(/*DomNode*/node, /*RegEx?*/regex, /*DomNode?*/root){
       root = root || node.ownerDocument.body;
       while(node && node !== root){
        var name = node.nodeName.toUpperCase() ;
        if(regex.test(name)){
         return node;
        }


        node = node.parentNode;
       }
       return null;
      }


      dijit.range.BlockTagNames = /^(?:P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|DT|DE)$/;
      dijit.range.getBlockAncestor = function(/*DomNode*/node, /*RegEx?*/regex, /*DomNode?*/root){
       root = root || node.ownerDocument.body;
       regex = regex || dijit.range.BlockTagNames;
       var block=null, blockContainer;
       while(node && node !== root){
        var name = node.nodeName.toUpperCase() ;
        if(!block && regex.test(name)){
         block = node;
        }
        if(!blockContainer && (/^(?:BODY|TD|TH|CAPTION)$/).test(name)){
         blockContainer = node;
        }


        node = node.parentNode;
       }
       return {blockNode:block, blockContainer:blockContainer || node.ownerDocument.body};
      }


      dijit.range.atBeginningOfContainer = function(/*DomNode*/container, /*DomNode*/node, /*Int*/offset){
       var atBeginning = false;
       var offsetAtBeginning = (offset == 0);
       if(!offsetAtBeginning && node.nodeType == 3){ //if this is a text node, check whether the left part is all space
        if(/^[\s\xA0]+$/.test(node.nodeValue.substr(0,offset))){
         offsetAtBeginning = true;
        }
       }
       if(offsetAtBeginning){
        var cnode = node;
        atBeginning = true;
        while(cnode && cnode !== container){
         if(cnode.previousSibling){
          atBeginning = false;
          break;
         }
         cnode = cnode.parentNode;
        }
       }
       return atBeginning;
      }


      dijit.range.atEndOfContainer = function(/*DomNode*/container, /*DomNode*/node, /*Int*/offset){
       var atEnd = false;
       var offsetAtEnd = (offset == (node.length || node.childNodes.length));
       if(!offsetAtEnd && node.nodeType == 3){ //if this is a text node, check whether the right part is all space
        if(/^[\s\xA0]+$/.test(node.nodeValue.substr(offset))){
         offsetAtEnd = true;
        }
       }
       if(offsetAtEnd){
        var cnode = node;
        atEnd = true;
        while(cnode && cnode !== container){
         if(cnode.nextSibling){
          atEnd = false;
          break;
         }
         cnode = cnode.parentNode;
        }
       }
       return atEnd;
      }


      dijit.range.adjacentNoneTextNode=function(startnode, next){
       var node = startnode;
       var len = (0-startnode.length) || 0;
       var prop = next?'nextSibling':'previousSibling';
       while(node){
        if(node.nodeType!=3){
         break;
        }
        len += node.length
        node = node[prop];
       }
       return [node,len];
      }


      dijit.range._w3c = Boolean(window['getSelection']);
      dijit.range.create = function(/*Window?*/win){
       if(dijit.range._w3c){
        return (win || dojo.global).document.createRange();
       }else{//IE
        return new dijit.range.W3CRange;
       }
      }


      dijit.range.getSelection = function(/*Window*/win, /*Boolean?*/ignoreUpdate){
       if(dijit.range._w3c){
        return win.getSelection();
       }else{//IE
        var s = new dijit.range.ie.selection(win);
        if(!ignoreUpdate){
         s._getCurrentSelection();
        }
        return s;
       }
      }


      if(!dijit.range._w3c){
       dijit.range.ie={
        cachedSelection: {},
        selection: function(win){
         this._ranges = [];
         this.addRange = function(r, /*boolean*/internal){
          this._ranges.push(r);
          if(!internal){
           r._select();
          }
          this.rangeCount = this._ranges.length;
         };
         this.removeAllRanges = function(){
          //don't detach, the range may be used later
      //    for(var i=0;i//     this._ranges[i].detach();
      //    }
          this._ranges = [];
          this.rangeCount = 0;
         };
         var _initCurrentRange = function(){
          var r = win.document.selection.createRange();
          var type=win.document.selection.type.toUpperCase();
          if(type == "CONTROL"){
           //TODO: multiple range selection(?)
           return new dijit.range.W3CRange(dijit.range.ie.decomposeControlRange(r));
          }else{
           return new dijit.range.W3CRange(dijit.range.ie.decomposeTextRange(r));
          }
         };
         this.getRangeAt = function(i){
          return this._ranges[i];
         };
         this._getCurrentSelection = function(){
          this.removeAllRanges();
          var r=_initCurrentRange();
          if(r){
           this.addRange(r, true);
          }
         };
        },
        decomposeControlRange: function(range){
         var firstnode = range.item(0), lastnode = range.item(range.length-1);
         var startContainer = firstnode.parentNode, endContainer = lastnode.parentNode;
         var startOffset = dijit.range.getIndex(firstnode, startContainer).o;
         var endOffset = dijit.range.getIndex(lastnode, endContainer).o+1;
         return [startContainer, startOffset,endContainer, endOffset];
        },
        getEndPoint: function(range, end){
         var atmrange = range.duplicate();
         atmrange.collapse(!end);
         var cmpstr = 'EndTo' + (end?'End':'Start');
         var parentNode = atmrange.parentElement();


         var startnode, startOffset, lastNode;
         if(parentNode.childNodes.length>0){
          dojo.every(parentNode.childNodes, function(node,i){
           var calOffset;
           if(node.nodeType != 3){
            atmrange.moveToElementText(node);


            if(atmrange.compareEndPoints(cmpstr,range) > 0){
             //startnode = node.previousSibling;
             if(lastNode && lastNode.nodeType == 3){
              //where shall we put the start? in the text node or after?
              startnode = lastNode;
              calOffset = true;
             }else{
              startnode = parentNode;
              startOffset = i;
              return false;
             }
            }else{
             if(i == parentNode.childNodes.length-1){
              startnode = parentNode;
              startOffset = parentNode.childNodes.length;
              return false;
             }
            }
           }else{
            if(i == parentNode.childNodes.length-1){//at the end of this node
             startnode = node;
             calOffset = true;
            }
           }
        //   try{
            if(calOffset && startnode){
             var prevnode = dijit.range.adjacentNoneTextNode(startnode)[0];
             if(prevnode){
              startnode = prevnode.nextSibling;
             }else{
              startnode = parentNode.firstChild; //firstChild must be a text node
             }
             var prevnodeobj = dijit.range.adjacentNoneTextNode(startnode);
             prevnode = prevnodeobj[0];
             var lenoffset = prevnodeobj[1];
             if(prevnode){
              atmrange.moveToElementText(prevnode);
              atmrange.collapse(false);
             }else{
              atmrange.moveToElementText(parentNode);
             }
             atmrange.setEndPoint(cmpstr, range);
             startOffset = atmrange.text.length-lenoffset;


             return false;
            }
        //   }catch(e){ debugger }
           lastNode = node;
           return true;
          });
         }else{
          startnode = parentNode;
          startOffset = 0;
         }


         //if at the end of startnode and we are dealing with start container, then
         //move the startnode to nextSibling if it is a text node
         //TODO: do this for end container?
         if(!end && startnode.nodeType == 1 && startOffset == startnode.childNodes.length){
          var nextnode=startnode.nextSibling;
          if(nextnode && nextnode.nodeType == 3){
           startnode = nextnode;
           startOffset = 0;
          }
         }
         return [startnode, startOffset];
        },
        setEndPoint: function(range, container, offset){
         //text node
         var atmrange = range.duplicate(), node, len;
         if(container.nodeType!=3){ //normal node
          if(offset > 0){
           node = container.childNodes[offset-1];
           if(node){
            if(node.nodeType == 3){
             container = node;
             offset = node.length;
             //pass through
            }else{
             if(node.nextSibling && node.nextSibling.nodeType == 3){
              container=node.nextSibling;
              offset=0;
              //pass through
             }else{
              atmrange.moveToElementText(node.nextSibling?node:container);
              var parent = node.parentNode;
              var tempNode = parent.insertBefore(node.ownerDocument.createTextNode(' '), node.nextSibling);
              atmrange.collapse(false);
              parent.removeChild(tempNode);
             }
            }
           }
          }else{
           atmrange.moveToElementText(container);
           atmrange.collapse(true);
          }
         }
         if(container.nodeType == 3){
          var prevnodeobj = dijit.range.adjacentNoneTextNode(container);
          var prevnode = prevnodeobj[0];
          len = prevnodeobj[1];
          if(prevnode){
           atmrange.moveToElementText(prevnode);
           atmrange.collapse(false);
           //if contentEditable is not inherit, the above collapse won't make the end point
           //in the correctly position: it always has a -1 offset, so compensate it
           if(prevnode.contentEditable!='inherit'){
            len++;
           }
          }else{
           atmrange.moveToElementText(container.parentNode);
           atmrange.collapse(true);
          }


          offset += len;
          if(offset>0){
           if(atmrange.move('character',offset) != offset){
            console.error('Error when moving!');
           }
          }
         }


         return atmrange;
    • returns
      terminate dojo.every|carry on the every loop
    • summary
  • dijit.range.ie.decomposeTextRange

    • type
      Function
    • parameters:
      • range: (typeof )
    • source: [view]
         var tmpary = dijit.range.ie.getEndPoint(range);
         var startContainer = tmpary[0], startOffset = tmpary[1];
         var endContainer = tmpary[0], endOffset = tmpary[1];


         if(range.htmlText.length){
          if(range.htmlText == range.text){ //in the same text node
           endOffset = startOffset+range.text.length;
          }else{
           tmpary = dijit.range.ie.getEndPoint(range,true);
           endContainer = tmpary[0], endOffset = tmpary[1];
      //     if(startContainer.tagName == "BODY"){
      //      startContainer = startContainer.firstChild;
      //     }
          }
         }
         return [startContainer, startOffset, endContainer, endOffset];
    • summary
  • dijit.range.ie.setRange

    • type
      Function
    • parameters:
      • range: (typeof )
      • startContainer: (typeof )
      • startOffset: (typeof )
      • endContainer: (typeof )
      • endOffset: (typeof )
      • collapsed: (typeof )
    • source: [view]
         var start=dijit.range.ie.setEndPoint(range, startContainer, startOffset);


         range.setEndPoint('StartToStart',start);
         if(!collapsed){
          var end=dijit.range.ie.setEndPoint(range, endContainer, endOffset);
         }
         range.setEndPoint('EndToEnd',end || start);


         return range;
    • summary
  • dijit.range.getIndex

    • type
      Function
    • parameters:
      • node: (typeof DomNode)
      • parent: (typeof DomNode)
    • source: [view]
      define("dijit/_editor/range", ["dojo", "dijit"], function(dojo, dijit) {


      dijit.range={};


      dijit.range.getIndex=function(/*DomNode*/node, /*DomNode*/parent){
      // dojo.profile.start("dijit.range.getIndex");
       var ret=[], retR=[];
       var stop = parent;
       var onode = node;


       var pnode, n;
       while(node != stop){
        var i = 0;
        pnode = node.parentNode;
        while((n=pnode.childNodes[i++])){
         if(n === node){
          --i;
          break;
         }
        }
        //if(i>=pnode.childNodes.length){
         //dojo.debug("Error finding index of a node in dijit.range.getIndex");
        //}
        ret.unshift(i);
        retR.unshift(i-pnode.childNodes.length);
        node = pnode;
       }


       //normalized() can not be called so often to prevent
       //invalidating selection/range, so we have to detect
       //here that any text nodes in a row
       if(ret.length > 0 && onode.nodeType == 3){
        n = onode.previousSibling;
        while(n && n.nodeType == 3){
         ret[ret.length-1]--;
         n = n.previousSibling;
        }
        n = onode.nextSibling;
        while(n && n.nodeType == 3){
         retR[retR.length-1]++;
         n = n.nextSibling;
        }
       }
      // dojo.profile.end("dijit.range.getIndex");
       return {o: ret, r:retR};
    • summary
  • dijit.range.getNode

    • type
      Function
    • parameters:
      • index: (typeof Array)
      • parent: (typeof DomNode)
    • source: [view]
       if(!dojo.isArray(index) || index.length == 0){
        return parent;
       }
       var node = parent;
      // if(!node)debugger
       dojo.every(index, function(i){
        if(i >= 0 && i < node.childNodes.length){
         node = node.childNodes[i];
        }else{
         node = null;
         //console.debug('Error: can not find node with index',index,'under parent node',parent );
         return false; //terminate dojo.every
        }
        return true; //carry on the every loop
       });


       return node;
    • returns
      terminate dojo.every|carry on the every loop
    • summary
  • dijit.range.getCommonAncestor

    • type
      Function
    • parameters:
      • n1: (typeof )
      • n2: (typeof )
      • root: (typeof )
    • source: [view]
       root = root||n1.ownerDocument.body;
       var getAncestors = function(n){
        var as=[];
        while(n){
         as.unshift(n);
         if(n !== root){
          n = n.parentNode;
         }else{
          break;
         }
        }
        return as;
       };
       var n1as = getAncestors(n1);
       var n2as = getAncestors(n2);


       var m = Math.min(n1as.length,n2as.length);
       var com = n1as[0]; //at least, one element should be in the array: the root (BODY by default)
       for(var i=1;i  if(n1as[i] === n2as[i]){
         com = n1as[i]
        }else{
         break;
        }
       }
       return com;
    • summary
  • dijit.range.getAncestor

    • type
      Function
    • parameters:
      • node: (typeof DomNode)
      • regex: (typeof RegEx)
      • root: (typeof DomNode)
    • source: [view]
       root = root || node.ownerDocument.body;
       while(node && node !== root){
        var name = node.nodeName.toUpperCase() ;
        if(regex.test(name)){
         return node;
        }


        node = node.parentNode;
       }
       return null;
    • summary
  • dijit.range.getBlockAncestor

    • type
      Function
    • parameters:
      • node: (typeof DomNode)
      • regex: (typeof RegEx)
      • root: (typeof DomNode)
    • source: [view]
       root = root || node.ownerDocument.body;
       regex = regex || dijit.range.BlockTagNames;
       var block=null, blockContainer;
       while(node && node !== root){
        var name = node.nodeName.toUpperCase() ;
        if(!block && regex.test(name)){
         block = node;
        }
        if(!blockContainer && (/^(?:BODY|TD|TH|CAPTION)$/).test(name)){
         blockContainer = node;
        }


        node = node.parentNode;
       }
       return {blockNode:block, blockContainer:blockContainer || node.ownerDocument.body};
    • summary
  • dijit.range.atBeginningOfContainer

    • type
      Function
    • parameters:
      • container: (typeof DomNode)
      • node: (typeof DomNode)
      • offset: (typeof Int)
    • source: [view]
       var atBeginning = false;
       var offsetAtBeginning = (offset == 0);
       if(!offsetAtBeginning && node.nodeType == 3){ //if this is a text node, check whether the left part is all space
        if(/^[\s\xA0]+$/.test(node.nodeValue.substr(0,offset))){
         offsetAtBeginning = true;
        }
       }
       if(offsetAtBeginning){
        var cnode = node;
        atBeginning = true;
        while(cnode && cnode !== container){
         if(cnode.previousSibling){
          atBeginning = false;
          break;
         }
         cnode = cnode.parentNode;
        }
       }
       return atBeginning;
    • summary
  • dijit.range.atEndOfContainer

    • type
      Function
    • parameters:
      • container: (typeof DomNode)
      • node: (typeof DomNode)
      • offset: (typeof Int)
    • source: [view]
       var atEnd = false;
       var offsetAtEnd = (offset == (node.length || node.childNodes.length));
       if(!offsetAtEnd && node.nodeType == 3){ //if this is a text node, check whether the right part is all space
        if(/^[\s\xA0]+$/.test(node.nodeValue.substr(offset))){
         offsetAtEnd = true;
        }
       }
       if(offsetAtEnd){
        var cnode = node;
        atEnd = true;
        while(cnode && cnode !== container){
         if(cnode.nextSibling){
          atEnd = false;
          break;
         }
         cnode = cnode.parentNode;
        }
       }
       return atEnd;
    • summary
  • dijit.range.adjacentNoneTextNode

    • type
      Function
    • parameters:
      • startnode: (typeof )
      • next: (typeof )
    • source: [view]
       var node = startnode;
       var len = (0-startnode.length) || 0;
       var prop = next?'nextSibling':'previousSibling';
       while(node){
        if(node.nodeType!=3){
         break;
        }
        len += node.length
        node = node[prop];
       }
       return [node,len];
    • summary
  • dijit.range.create

    • type
      Function
    • parameters:
      • win: (typeof Window)
    • source: [view]
       if(dijit.range._w3c){
        return (win || dojo.global).document.createRange();
       }else{//IE
        return new dijit.range.W3CRange;
       }
    • summary
  • dijit.range.getSelection

    • type
      Function
    • parameters:
      • win: (typeof Window)
      • ignoreUpdate: (typeof Boolean)
    • source: [view]
       if(dijit.range._w3c){
        return win.getSelection();
       }else{//IE
        var s = new dijit.range.ie.selection(win);
        if(!ignoreUpdate){
         s._getCurrentSelection();
        }
        return s;
       }
    • summary
  • dijit.range.BlockTagNames

    • summary
  • dijit.range._w3c

    • summary
  • dijit._editor.range

    • type
      Object
    • summary
  • dijit._editor

    • type
      Object
    • summary
  • dijit

    • type
      Object
    • summary