[ Index ]
 

Code source de eGroupWare 1.2.106-2

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/phpgwapi/js/htmlarea/plugins/EnterParagraphs/ -> enter-paragraphs.js (source)

   1  // Modification to htmlArea to insert Paragraphs instead of
   2  // linebreaks, under Gecko engines, circa January 2004
   3  // By Adam Wright, for The University of Western Australia
   4  //
   5  // Distributed under the same terms as HTMLArea itself.
   6  // This notice MUST stay intact for use (see license.txt).
   7  
   8  function EnterParagraphs(editor, params) {
   9      this.editor = editor;
  10      // activate only if we're talking to Gecko
  11      if (HTMLArea.is_gecko)
  12          this.onKeyPress = this.__onKeyPress;
  13  };
  14  
  15  EnterParagraphs._pluginInfo = {
  16      name          : "EnterParagraphs",
  17      version       : "1.0",
  18      developer     : "Adam Wright",
  19      developer_url : "http://blog.hipikat.org/",
  20      sponsor       : "The University of Western Australia",
  21      sponsor_url   : "http://www.uwa.edu.au/",
  22      license       : "htmlArea"
  23  };
  24  
  25  // An array of elements who, in html4, by default, have an inline display and can have children
  26  // we use RegExp here since it should be a bit faster, also cleaner to check
  27  EnterParagraphs.prototype._html4_inlines_re = /^(a|abbr|acronym|b|bdo|big|cite|code|dfn|em|font|i|kbd|label|q|s|samp|select|small|span|strike|strong|sub|sup|textarea|tt|u|var)$/i;
  28  
  29  // Finds the first parent element of a given node whose display is probably not inline
  30  EnterParagraphs.prototype.parentBlock = function(node) {
  31      while (node.parentNode && (node.nodeType != 1 || this._html4_inlines_re.test(node.tagName)))
  32          node = node.parentNode;
  33      return node;
  34  };
  35  
  36  // Internal function for recursively itterating over a all nodes in a fragment
  37  // If a callback function returns a non-null value, that is returned and the crawl is therefore broken
  38  EnterParagraphs.prototype.walkNodeChildren = function(me, callback) {
  39      if (me.firstChild) {
  40          var myChild = me.firstChild;
  41          var retVal;
  42          while (myChild) {
  43              if ((retVal = callback(this, myChild)) != null)
  44                  return retVal;
  45              if ((retVal = this.walkNodeChildren(myChild, callback)) != null)
  46                  return retVal;
  47              myChild = myChild.nextSibling;
  48          }
  49      }
  50  };
  51  
  52  // Callback function to be performed on each node in the hierarchy
  53  // Sets flag to true if we find actual text or an element that's not usually displayed inline
  54  EnterParagraphs.prototype._isFilling = function(self, node) {
  55      if (node.nodeType == 1 && !self._html4_inlines_re.test(node.nodeName))
  56          return true;
  57      else if (node.nodeType == 3 && node.nodeValue != '')
  58          return true;
  59      return null;
  60      //alert(node.nodeName);
  61  };
  62  
  63  // Inserts a node deeply on the left of a hierarchy of nodes
  64  EnterParagraphs.prototype.insertDeepLeftText = function(target, toInsert) {
  65      var falling = target;
  66      while (falling.firstChild && falling.firstChild.nodeType == 1)
  67          falling = falling.firstChild;
  68      //var refNode = falling.firstChild ? falling.firstChild : null;
  69      //falling.insertBefore(toInsert, refNode);
  70      falling.innerHTML = toInsert;
  71  };
  72  
  73  // Kind of like a macros, for a frequent query...
  74  EnterParagraphs.prototype.isElem = function(node, type) {
  75      return node.nodeName.toLowerCase() == type.toLowerCase();
  76  };
  77  
  78  // The onKeyPress even that does all the work - nicely breaks the line into paragraphs
  79  EnterParagraphs.prototype.__onKeyPress = function(ev) {
  80  
  81      if (ev.keyCode == 13 && !ev.shiftKey && this.editor._iframe.contentWindow.getSelection) {
  82  
  83          var editor = this.editor;
  84  
  85          // Get the selection and solid references to what we're dealing with chopping
  86          var sel = editor._iframe.contentWindow.getSelection();
  87  
  88          // Set the start and end points such that they're going /forward/ through the document
  89          var rngLeft = editor._doc.createRange();        var rngRight = editor._doc.createRange();
  90          rngLeft.setStart(sel.anchorNode, sel.anchorOffset);    rngRight.setStart(sel.focusNode, sel.focusOffset);
  91          rngLeft.collapse(true);                    rngRight.collapse(true);
  92  
  93          var direct = rngLeft.compareBoundaryPoints(rngLeft.START_TO_END, rngRight) < 0;
  94  
  95          var startNode = direct ? sel.anchorNode : sel.focusNode;
  96          var startOffset = direct ? sel.anchorOffset : sel.focusOffset;
  97          var endNode = direct ? sel.focusNode : sel.anchorNode;
  98          var endOffset = direct ? sel.focusOffset : sel.anchorOffset;
  99  
 100          // Find the parent blocks of nodes at either end, and their attributes if they're paragraphs
 101          var startBlock = this.parentBlock(startNode);        var endBlock = this.parentBlock(endNode);
 102          var attrsLeft = new Array();                var attrsRight = new Array();
 103  
 104          // If a list, let the browser take over, if we're in a paragraph, gather it's attributes
 105          if (this.isElem(startBlock, 'li') || this.isElem(endBlock, 'li'))
 106              return;
 107  
 108          if (this.isElem(startBlock, 'p')) {
 109              for (var i = 0; i < startBlock.attributes.length; i++) {
 110                  attrsLeft[startBlock.attributes[i].nodeName] = startBlock.attributes[i].nodeValue;
 111              }
 112          }
 113          if (this.isElem(endBlock, 'p')) {
 114              for (var i = 0; i < endBlock.attributes.length; i++) {
 115                  // If we start and end within one paragraph, don't duplicate the 'id'
 116                  if (endBlock != startBlock || endBlock.attributes[i].nodeName.toLowerCase() != 'id')
 117                      attrsRight[endBlock.attributes[i].nodeName] = endBlock.attributes[i].nodeValue;
 118              }
 119          }
 120  
 121          // Look for where to start and end our chopping - within surrounding paragraphs
 122          // if they exist, or at the edges of the containing block, otherwise
 123          var startChop = startNode;                var endChop = endNode;
 124  
 125          while ((startChop.previousSibling && !this.isElem(startChop.previousSibling, 'p'))
 126                 || (startChop.parentNode && startChop.parentNode != startBlock && startChop.parentNode.nodeType != 9))
 127              startChop = startChop.previousSibling ? startChop.previousSibling : startChop.parentNode;
 128  
 129          while ((endChop.nextSibling && !this.isElem(endChop.nextSibling, 'p'))
 130                 || (endChop.parentNode && endChop.parentNode != endBlock && endChop.parentNode.nodeType != 9))
 131              endChop = endChop.nextSibling ? endChop.nextSibling : endChop.parentNode;
 132  
 133          // Set up new paragraphs
 134          var pLeft = editor._doc.createElement('p');        var pRight = editor._doc.createElement('p');
 135  
 136          for (var attrName in attrsLeft) {
 137              var thisAttr = editor._doc.createAttribute(attrName);
 138              thisAttr.value = attrsLeft[attrName];
 139              pLeft.setAttributeNode(thisAttr);
 140          }
 141          for (var attrName in attrsRight) {
 142              var thisAttr = editor._doc.createAttribute(attrName);
 143              thisAttr.value = attrsRight[attrName];
 144              pRight.setAttributeNode(thisAttr);
 145          }
 146  
 147          // Get the ranges destined to be stuffed into new paragraphs
 148          rngLeft.setStartBefore(startChop);
 149          rngLeft.setEnd(startNode,startOffset);
 150          pLeft.appendChild(rngLeft.cloneContents());        // Copy into pLeft
 151  
 152          rngRight.setEndAfter(endChop);
 153          rngRight.setStart(endNode,endOffset);
 154          pRight.appendChild(rngRight.cloneContents());        // Copy into pRight
 155  
 156          // If either paragraph is empty, fill it with a nonbreakable space
 157          var foundBlock = false;
 158          foundBlock = this.walkNodeChildren(pLeft, this._isFilling);
 159          if (foundBlock != true)
 160              this.insertDeepLeftText(pLeft, '&nbsp;');
 161  
 162          foundBlock = false;
 163          foundBlock = this.walkNodeChildren(pRight, this._isFilling);
 164          if (foundBlock != true)
 165              this.insertDeepLeftText(pRight, '&nbsp;');
 166  
 167          // Get a range for everything to be replaced and replace it
 168          var rngAround = editor._doc.createRange();
 169  
 170          if (!startChop.previousSibling && this.isElem(startChop.parentNode, 'p'))
 171              rngAround.setStartBefore(startChop.parentNode);
 172          else
 173              rngAround.setStart(rngLeft.startContainer, rngLeft.startOffset);
 174  
 175          if (!endChop.nextSibling && this.isElem(endChop.parentNode, 'p'))
 176              rngAround.setEndAfter(endChop.parentNode);
 177          else
 178              rngAround.setEnd(rngRight.endContainer, rngRight.endOffset);
 179  
 180          rngAround.deleteContents();
 181          rngAround.insertNode(pRight);
 182          rngAround.insertNode(pLeft);
 183  
 184          // Set the selection to the start of the (second) new paragraph
 185          if (pRight.firstChild) {
 186              while (pRight.firstChild && this._html4_inlines_re.test(pRight.firstChild.nodeName))
 187                  pRight = pRight.firstChild;
 188              // Slip into any inline tags
 189              if (pRight.firstChild && pRight.firstChild.nodeType == 3)
 190                  pRight = pRight.firstChild;    // and text, if they've got it
 191  
 192              var rngCaret = editor._doc.createRange();
 193              rngCaret.setStart(pRight, 0);
 194              rngCaret.collapse(true);
 195  
 196              sel = editor._iframe.contentWindow.getSelection();
 197              sel.removeAllRanges();
 198              sel.addRange(rngCaret);
 199          }
 200  
 201          // Stop the bubbling
 202          HTMLArea._stopEvent(ev);
 203      }
 204  };


Généré le : Sun Feb 25 17:20:01 2007 par Balluche grâce à PHPXref 0.7