[ Index ]

PHP Cross Reference of phpBB-3.2.11-deutsch

title

Body

[close]

/vendor/s9e/text-formatter/src/ -> render.js (source)

   1  var MSXML = (typeof DOMParser === 'undefined' || typeof XSLTProcessor === 'undefined');
   2  var xslt = {
   3      /**
   4      * @param {!string} xsl
   5      */
   6      init: function(xsl)
   7      {
   8          var stylesheet = xslt.loadXML(xsl, 'MSXML2.FreeThreadedDOMDocument.6.0');
   9          if (MSXML)
  10          {
  11              var generator = new ActiveXObject('MSXML2.XSLTemplate.6.0');
  12              generator['stylesheet'] = stylesheet;
  13              xslt.proc = generator['createProcessor']();
  14          }
  15          else
  16          {
  17              xslt.proc = new XSLTProcessor;
  18              xslt.proc['importStylesheet'](stylesheet);
  19          }
  20      },
  21  
  22      /**
  23      * @param {!string} xml
  24      * @param {string} type
  25      */
  26      loadXML: function(xml, type)
  27      {
  28          if (MSXML)
  29          {
  30              var dom = new ActiveXObject(type);
  31              dom['async'] = false;
  32              dom['validateOnParse'] = false;
  33              dom['loadXML'](xml);
  34  
  35              return dom;
  36          }
  37  
  38          return (new DOMParser).parseFromString(xml, 'text/xml');
  39      },
  40  
  41      /**
  42      * @param {!string} paramName  Parameter name
  43      * @param {!string} paramValue Parameter's value
  44      */
  45      setParameter: function(paramName, paramValue)
  46      {
  47          if (MSXML)
  48          {
  49              xslt.proc['addParameter'](paramName, paramValue, '');
  50          }
  51          else
  52          {
  53              xslt.proc['setParameter'](null, paramName, paramValue);
  54          }
  55      },
  56  
  57      /**
  58      * @param {!string} xml
  59      * @param {!HTMLDocument} targetDoc
  60      */
  61      transformToFragment: function(xml, targetDoc)
  62      {
  63          if (MSXML)
  64          {
  65              var div = targetDoc.createElement('div'),
  66                  fragment = targetDoc.createDocumentFragment();
  67  
  68              xslt.proc['input'] = xslt.loadXML(xml, 'MSXML2.DOMDocument.6.0');
  69              xslt.proc['transform']();
  70              div.innerHTML = xslt.proc['output'];
  71              while (div.firstChild)
  72              {
  73                  fragment.appendChild(div.firstChild);
  74              }
  75  
  76              return fragment;
  77          }
  78  
  79          // NOTE: importNode() is used because of https://code.google.com/p/chromium/issues/detail?id=266305
  80          return targetDoc.importNode(xslt.proc['transformToFragment'](xslt.loadXML(xml), targetDoc), true);
  81      }
  82  }
  83  xslt.init(xsl);
  84  
  85  var postProcessFunctions = {};
  86  
  87  /**
  88  * Parse a given text and render it into given HTML element
  89  *
  90  * @param  {!string} text
  91  * @param  {!HTMLElement} target
  92  * @return {!Node}
  93  */
  94  function preview(text, target)
  95  {
  96      var targetDoc      = target.ownerDocument,
  97          resultFragment = xslt.transformToFragment(parse(text).replace(/<[eis]>.*?<\/[eis]>/g, ''), targetDoc),
  98          lastUpdated    = target;
  99  
 100      // Apply post-processing
 101      if (HINT.postProcessing)
 102      {
 103          var nodes = resultFragment['querySelectorAll']('[data-s9e-livepreview-postprocess]'),
 104              i     = nodes.length;
 105          while (--i >= 0)
 106          {
 107              /** @type {!string} */
 108              var code = nodes[i]['getAttribute']('data-s9e-livepreview-postprocess');
 109              if (!postProcessFunctions[code])
 110              {
 111                  postProcessFunctions[code] = new Function(code);
 112              }
 113  
 114              postProcessFunctions[code]['call'](nodes[i]);
 115          }
 116      }
 117  
 118      /**
 119      * Update the content of given element oldEl to match element newEl
 120      *
 121      * @param {!HTMLElement} oldEl
 122      * @param {!HTMLElement} newEl
 123      */
 124  	function refreshElementContent(oldEl, newEl)
 125      {
 126          var oldNodes = oldEl.childNodes,
 127              newNodes = newEl.childNodes,
 128              oldCnt   = oldNodes.length,
 129              newCnt   = newNodes.length,
 130              oldNode,
 131              newNode,
 132              left     = 0,
 133              right    = 0;
 134  
 135          // Skip the leftmost matching nodes
 136          while (left < oldCnt && left < newCnt)
 137          {
 138              oldNode = oldNodes[left];
 139              newNode = newNodes[left];
 140              if (!refreshNode(oldNode, newNode))
 141              {
 142                  break;
 143              }
 144  
 145              ++left;
 146          }
 147  
 148          // Skip the rightmost matching nodes
 149          var maxRight = Math.min(oldCnt - left, newCnt - left);
 150          while (right < maxRight)
 151          {
 152              oldNode = oldNodes[oldCnt - (right + 1)];
 153              newNode = newNodes[newCnt - (right + 1)];
 154              if (!refreshNode(oldNode, newNode))
 155              {
 156                  break;
 157              }
 158  
 159              ++right;
 160          }
 161  
 162          // Remove the old dirty nodes in the middle of the tree
 163          var i = oldCnt - right;
 164          while (--i >= left)
 165          {
 166              oldEl.removeChild(oldNodes[i]);
 167              lastUpdated = oldEl;
 168          }
 169  
 170          // Test whether there are any nodes in the new tree between the matching nodes at the left
 171          // and the matching nodes at the right
 172          var rightBoundary = newCnt - right;
 173          if (left >= rightBoundary)
 174          {
 175              return;
 176          }
 177  
 178          // Clone the new nodes
 179          var newNodesFragment = targetDoc.createDocumentFragment();
 180          i = left;
 181          do
 182          {
 183              lastUpdated = newNodesFragment.appendChild(newNodes[i]);
 184          }
 185          while (i < --rightBoundary);
 186  
 187          // If we haven't skipped any nodes to the right, we can just append the fragment
 188          if (!right)
 189          {
 190              oldEl.appendChild(newNodesFragment);
 191          }
 192          else
 193          {
 194              oldEl.insertBefore(newNodesFragment, oldEl.childNodes[left]);
 195          }
 196      }
 197  
 198      /**
 199      * Update given node oldNode to make it match newNode
 200      *
 201      * @param {!HTMLElement} oldNode
 202      * @param {!HTMLElement} newNode
 203      * @return boolean Whether the node can be skipped
 204      */
 205  	function refreshNode(oldNode, newNode)
 206      {
 207          if (oldNode.nodeName !== newNode.nodeName
 208           || oldNode.nodeType !== newNode.nodeType)
 209          {
 210              return false;
 211          }
 212  
 213          // Node.TEXT_NODE || Node.COMMENT_NODE
 214          if (oldNode.nodeType === 3 || oldNode.nodeType === 8)
 215          {
 216              if (oldNode.nodeValue !== newNode.nodeValue)
 217              {
 218                  oldNode.nodeValue = newNode.nodeValue;
 219                  lastUpdated = oldNode;
 220              }
 221  
 222              return true;
 223          }
 224  
 225          if (!oldNode.isEqualNode || !oldNode.isEqualNode(newNode))
 226          {
 227              syncElementAttributes(oldNode, newNode);
 228              refreshElementContent(oldNode, newNode);
 229          }
 230  
 231          return true;
 232      }
 233  
 234      /**
 235      * Make the set of attributes of given element oldEl match newEl's
 236      *
 237      * @param {!HTMLElement} oldEl
 238      * @param {!HTMLElement} newEl
 239      */
 240  	function syncElementAttributes(oldEl, newEl)
 241      {
 242          var oldAttributes = oldEl['attributes'],
 243              newAttributes = newEl['attributes'],
 244              oldCnt        = oldAttributes.length,
 245              newCnt        = newAttributes.length,
 246              i             = oldCnt,
 247              ignoreAttrs   = ' ' + oldAttributes['data-s9e-livepreview-ignore-attrs'] + ' ';
 248  
 249          while (--i >= 0)
 250          {
 251              var oldAttr      = oldAttributes[i],
 252                  namespaceURI = oldAttr['namespaceURI'],
 253                  attrName     = oldAttr['name'];
 254  
 255              if (HINT.ignoreAttrs && ignoreAttrs.indexOf(' ' + attrName + ' ') > -1)
 256              {
 257                  continue;
 258              }
 259              if (!newEl.hasAttributeNS(namespaceURI, attrName))
 260              {
 261                  oldEl.removeAttributeNS(namespaceURI, attrName);
 262                  lastUpdated = oldEl;
 263              }
 264          }
 265  
 266          i = newCnt;
 267          while (--i >= 0)
 268          {
 269              var newAttr      = newAttributes[i],
 270                  namespaceURI = newAttr['namespaceURI'],
 271                  attrName     = newAttr['name'],
 272                  attrValue    = newAttr['value'];
 273  
 274              if (HINT.ignoreAttrs && ignoreAttrs.indexOf(' ' + attrName + ' ') > -1)
 275              {
 276                  continue;
 277              }
 278              if (attrValue !== oldEl.getAttributeNS(namespaceURI, attrName))
 279              {
 280                  oldEl.setAttributeNS(namespaceURI, attrName, attrValue);
 281                  lastUpdated = oldEl;
 282              }
 283          }
 284      }
 285  
 286      refreshElementContent(target, resultFragment);
 287  
 288      return lastUpdated;
 289  }
 290  
 291  /**
 292  * Set the value of a stylesheet parameter
 293  *
 294  * @param {!string} paramName  Parameter name
 295  * @param {!string} paramValue Parameter's value
 296  */
 297  function setParameter(paramName, paramValue)
 298  {
 299      xslt.setParameter(paramName, paramValue);
 300  }


Generated: Wed Nov 11 20:33:01 2020 Cross-referenced by PHPXref 0.7.1