[ Index ]
 

Code source de PRADO 3.0.6

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

title

Body

[fermer]

/tests/test_tools/selenium/core/xpath/ -> dom.js (source)

   1  // Copyright 2005 Google Inc.
   2  // All Rights Reserved
   3  //
   4  // An XML parse and a minimal DOM implementation that just supportes
   5  // the subset of the W3C DOM that is used in the XSLT implementation.
   6  //
   7  // References: 
   8  //
   9  // [DOM] W3C DOM Level 3 Core Specification
  10  //       <http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/>.
  11  //
  12  // 
  13  // Author: Steffen Meschkat <mesch@google.com>
  14  
  15  // NOTE: The split() method in IE omits empty result strings. This is
  16  // utterly annoying. So we don't use it here.
  17  
  18  // Resolve entities in XML text fragments. According to the DOM
  19  // specification, the DOM is supposed to resolve entity references at
  20  // the API level. I.e. no entity references are passed through the
  21  // API. See "Entities and the DOM core", p.12, DOM 2 Core
  22  // Spec. However, different browsers actually pass very different
  23  // values at the API.
  24  //
  25  function xmlResolveEntities(s) {
  26  
  27    var parts = stringSplit(s, '&');
  28  
  29    var ret = parts[0];
  30    for (var i = 1; i < parts.length; ++i) {
  31      var rp = stringSplit(parts[i], ';');
  32      if (rp.length == 1) {
  33        // no entity reference: just a & but no ;
  34        ret += parts[i];
  35        continue;
  36      }
  37      
  38      var ch;
  39      switch (rp[0]) {
  40        case 'lt': 
  41          ch = '<';
  42          break;
  43        case 'gt': 
  44          ch = '>';
  45          break;
  46        case 'amp': 
  47          ch = '&';
  48          break;
  49        case 'quot': 
  50          ch = '"';
  51          break;
  52        case 'apos': 
  53          ch = '\'';
  54          break;
  55        case 'nbsp': 
  56          ch = String.fromCharCode(160);
  57          break;
  58        default:
  59          // Cool trick: let the DOM do the entity decoding. We assign
  60          // the entity text through non-W3C DOM properties and read it
  61          // through the W3C DOM. W3C DOM access is specified to resolve
  62          // entities. 
  63          var span = window.document.createElement('span');
  64          span.innerHTML = '&' + rp[0] + '; ';
  65          ch = span.childNodes[0].nodeValue.charAt(0);
  66      }
  67      ret += ch + rp[1];
  68    }
  69  
  70    return ret;
  71  }
  72  
  73  
  74  // Parses the given XML string with our custom, JavaScript XML parser. Written
  75  // by Steffen Meschkat (mesch@google.com).
  76  function xmlParse(xml) {
  77    Timer.start('xmlparse');
  78    var regex_empty = /\/$/;
  79  
  80    // See also <http://www.w3.org/TR/REC-xml/#sec-common-syn> for
  81    // allowed chars in a tag and attribute name. TODO(mesch): the
  82    // following is still not completely correct.
  83  
  84    var regex_tagname = /^([\w:-]*)/;
  85    var regex_attribute = /([\w:-]+)\s?=\s?('([^\']*)'|"([^\"]*)")/g;
  86  
  87    var xmldoc = new XDocument();
  88    var root = xmldoc;
  89  
  90    // For the record: in Safari, we would create native DOM nodes, but
  91    // in Opera that is not possible, because the DOM only allows HTML
  92    // element nodes to be created, so we have to do our own DOM nodes.
  93  
  94    // xmldoc = document.implementation.createDocument('','',null);
  95    // root = xmldoc; // .createDocumentFragment();
  96    // NOTE(mesch): using the DocumentFragment instead of the Document
  97    // crashes my Safari 1.2.4 (v125.12).
  98    var stack = [];
  99  
 100    var parent = root;
 101    stack.push(parent);
 102  
 103    var x = stringSplit(xml, '<');
 104    for (var i = 1; i < x.length; ++i) {
 105      var xx = stringSplit(x[i], '>');
 106      var tag = xx[0];
 107      var text = xmlResolveEntities(xx[1] || '');
 108  
 109      if (tag.charAt(0) == '/') {
 110        stack.pop();
 111        parent = stack[stack.length-1];
 112  
 113      } else if (tag.charAt(0) == '?') {
 114        // Ignore XML declaration and processing instructions
 115      } else if (tag.charAt(0) == '!') {
 116        // Ignore notation and comments
 117      } else {
 118        var empty = tag.match(regex_empty);
 119        var tagname = regex_tagname.exec(tag)[1];
 120        var node = xmldoc.createElement(tagname);
 121  
 122        var att;
 123        while (att = regex_attribute.exec(tag)) {
 124          var val = xmlResolveEntities(att[3] || att[4] || '');
 125          node.setAttribute(att[1], val);
 126        }
 127        
 128        if (empty) {
 129          parent.appendChild(node);
 130        } else {
 131          parent.appendChild(node);
 132          parent = node;
 133          stack.push(node);
 134        }
 135      }
 136  
 137      if (text && parent != root) {
 138        parent.appendChild(xmldoc.createTextNode(text));
 139      }
 140    }
 141  
 142    Timer.end('xmlparse');
 143    return root;
 144  }
 145  
 146  
 147  // Our W3C DOM Node implementation. Note we call it XNode because we
 148  // can't define the identifier Node. We do this mostly for Opera,
 149  // where we can't reuse the HTML DOM for parsing our own XML, and for
 150  // Safari, where it is too expensive to have the template processor
 151  // operate on native DOM nodes.
 152  function XNode(type, name, value, owner) {
 153    this.attributes = [];
 154    this.childNodes = [];
 155  
 156    XNode.init.call(this, type, name, value, owner);
 157  }
 158  
 159  // Don't call as method, use apply() or call().
 160  XNode.init = function(type, name, value, owner) {
 161    this.nodeType = type - 0;
 162    this.nodeName = '' + name;
 163    this.nodeValue = '' + value;
 164    this.ownerDocument = owner;
 165  
 166    this.firstChild = null;
 167    this.lastChild = null;
 168    this.nextSibling = null;
 169    this.previousSibling = null;
 170    this.parentNode = null;
 171  }
 172  
 173  XNode.unused_ = [];
 174  
 175  XNode.recycle = function(node) {
 176    if (!node) {
 177      return;
 178    }
 179  
 180    if (node.constructor == XDocument) {
 181      XNode.recycle(node.documentElement);
 182      return;
 183    }
 184  
 185    if (node.constructor != this) {
 186      return;
 187    }
 188  
 189    XNode.unused_.push(node);
 190    for (var a = 0; a < node.attributes.length; ++a) {
 191      XNode.recycle(node.attributes[a]);
 192    }
 193    for (var c = 0; c < node.childNodes.length; ++c) {
 194      XNode.recycle(node.childNodes[c]);
 195    }
 196    node.attributes.length = 0;
 197    node.childNodes.length = 0;
 198    XNode.init.call(node, 0, '', '', null);
 199  }
 200  
 201  XNode.create = function(type, name, value, owner) {
 202    if (XNode.unused_.length > 0) {
 203      var node = XNode.unused_.pop();
 204      XNode.init.call(node, type, name, value, owner);
 205      return node;
 206    } else {
 207      return new XNode(type, name, value, owner);
 208    }
 209  }
 210  
 211  XNode.prototype.appendChild = function(node) {
 212    // firstChild
 213    if (this.childNodes.length == 0) {
 214      this.firstChild = node;
 215    }
 216  
 217    // previousSibling
 218    node.previousSibling = this.lastChild;
 219  
 220    // nextSibling
 221    node.nextSibling = null;
 222    if (this.lastChild) {
 223      this.lastChild.nextSibling = node;
 224    }
 225  
 226    // parentNode
 227    node.parentNode = this;
 228  
 229    // lastChild
 230    this.lastChild = node;
 231  
 232    // childNodes
 233    this.childNodes.push(node);
 234  }
 235  
 236  
 237  XNode.prototype.replaceChild = function(newNode, oldNode) {
 238    if (oldNode == newNode) {
 239      return;
 240    }
 241  
 242    for (var i = 0; i < this.childNodes.length; ++i) {
 243      if (this.childNodes[i] == oldNode) {
 244        this.childNodes[i] = newNode;
 245        
 246        var p = oldNode.parentNode;
 247        oldNode.parentNode = null;
 248        newNode.parentNode = p;
 249        
 250        p = oldNode.previousSibling;
 251        oldNode.previousSibling = null;
 252        newNode.previousSibling = p;
 253        if (newNode.previousSibling) {
 254          newNode.previousSibling.nextSibling = newNode;
 255        }
 256        
 257        p = oldNode.nextSibling;
 258        oldNode.nextSibling = null;
 259        newNode.nextSibling = p;
 260        if (newNode.nextSibling) {
 261          newNode.nextSibling.previousSibling = newNode;
 262        }
 263  
 264        if (this.firstChild == oldNode) {
 265          this.firstChild = newNode;
 266        }
 267  
 268        if (this.lastChild == oldNode) {
 269          this.lastChild = newNode;
 270        }
 271  
 272        break;
 273      }
 274    }
 275  }
 276  
 277  XNode.prototype.insertBefore = function(newNode, oldNode) {
 278    if (oldNode == newNode) {
 279      return;
 280    }
 281  
 282    if (oldNode.parentNode != this) {
 283      return;
 284    }
 285  
 286    if (newNode.parentNode) {
 287      newNode.parentNode.removeChild(newNode);
 288    }
 289  
 290    var newChildren = [];
 291    for (var i = 0; i < this.childNodes.length; ++i) {
 292      var c = this.childNodes[i];
 293      if (c == oldNode) {
 294        newChildren.push(newNode);
 295  
 296        newNode.parentNode = this;
 297  
 298        newNode.previousSibling = oldNode.previousSibling;
 299        oldNode.previousSibling = newNode;
 300        if (newNode.previousSibling) {
 301          newNode.previousSibling.nextSibling = newNode;
 302        }
 303        
 304        newNode.nextSibling = oldNode;
 305  
 306        if (this.firstChild == oldNode) {
 307          this.firstChild = newNode;
 308        }
 309      }
 310      newChildren.push(c);
 311    }
 312    this.childNodes = newChildren;
 313  }
 314  
 315  XNode.prototype.removeChild = function(node) {
 316    var newChildren = [];
 317    for (var i = 0; i < this.childNodes.length; ++i) {
 318      var c = this.childNodes[i];
 319      if (c != node) {
 320        newChildren.push(c);
 321      } else {
 322        if (c.previousSibling) {
 323          c.previousSibling.nextSibling = c.nextSibling;
 324        }
 325        if (c.nextSibling) {
 326          c.nextSibling.previousSibling = c.previousSibling;
 327        }
 328        if (this.firstChild == c) {
 329          this.firstChild = c.nextSibling;
 330        }
 331        if (this.lastChild == c) {
 332          this.lastChild = c.previousSibling;
 333        }
 334      }
 335    }
 336    this.childNodes = newChildren;
 337  }
 338  
 339  
 340  XNode.prototype.hasAttributes = function() {
 341    return this.attributes.length > 0;
 342  }
 343  
 344  
 345  XNode.prototype.setAttribute = function(name, value) {
 346    for (var i = 0; i < this.attributes.length; ++i) {
 347      if (this.attributes[i].nodeName == name) {
 348        this.attributes[i].nodeValue = '' + value;
 349        return;
 350      }
 351    }
 352    this.attributes.push(new XNode(DOM_ATTRIBUTE_NODE, name, value));
 353  }
 354  
 355  
 356  XNode.prototype.getAttribute = function(name) {
 357    for (var i = 0; i < this.attributes.length; ++i) {
 358      if (this.attributes[i].nodeName == name) {
 359        return this.attributes[i].nodeValue;
 360      }
 361    }
 362    return null;
 363  }
 364  
 365  XNode.prototype.removeAttribute = function(name) {
 366    var a = [];
 367    for (var i = 0; i < this.attributes.length; ++i) {
 368      if (this.attributes[i].nodeName != name) {
 369        a.push(this.attributes[i]);
 370      }
 371    }
 372    this.attributes = a;
 373  }
 374  
 375  
 376  function XDocument() {
 377    XNode.call(this, DOM_DOCUMENT_NODE, '#document', null, this);
 378    this.documentElement = null;
 379  }
 380  
 381  XDocument.prototype = new XNode(DOM_DOCUMENT_NODE, '#document');
 382  
 383  XDocument.prototype.clear = function() {
 384    XNode.recycle(this.documentElement);
 385    this.documentElement = null;
 386  }
 387  
 388  XDocument.prototype.appendChild = function(node) {
 389    XNode.prototype.appendChild.call(this, node);
 390    this.documentElement = this.childNodes[0];
 391  }
 392  
 393  XDocument.prototype.createElement = function(name) {
 394    return XNode.create(DOM_ELEMENT_NODE, name, null, this);
 395  }
 396  
 397  XDocument.prototype.createDocumentFragment = function() {
 398    return XNode.create(DOM_DOCUMENT_FRAGMENT_NODE, '#document-fragment',
 399                      null, this);
 400  }
 401  
 402  XDocument.prototype.createTextNode = function(value) {
 403    return XNode.create(DOM_TEXT_NODE, '#text', value, this);
 404  }
 405  
 406  XDocument.prototype.createAttribute = function(name) {
 407    return XNode.create(DOM_ATTRIBUTE_NODE, name, null, this);
 408  }
 409  
 410  XDocument.prototype.createComment = function(data) {
 411    return XNode.create(DOM_COMMENT_NODE, '#comment', data, this);
 412  }
 413  
 414  XNode.prototype.getElementsByTagName = function(name, list) {
 415    if (!list) {
 416      list = [];
 417    }
 418  
 419    if (this.nodeName == name) {
 420      list.push(this);
 421    }
 422  
 423    for (var i = 0; i < this.childNodes.length; ++i) {
 424      this.childNodes[i].getElementsByTagName(name, list);
 425    }
 426  
 427    return list;
 428  }


Généré le : Sun Feb 25 21:07:04 2007 par Balluche grâce à PHPXref 0.7