[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/yuilib/3.17.2/dom-core/ -> dom-core.js (source)

   1  /*
   2  YUI 3.17.2 (build 9c3c78e)
   3  Copyright 2014 Yahoo! Inc. All rights reserved.
   4  Licensed under the BSD License.
   5  http://yuilibrary.com/license/
   6  */
   7  
   8  YUI.add('dom-core', function (Y, NAME) {
   9  
  10  var NODE_TYPE = 'nodeType',
  11      OWNER_DOCUMENT = 'ownerDocument',
  12      DOCUMENT_ELEMENT = 'documentElement',
  13      DEFAULT_VIEW = 'defaultView',
  14      PARENT_WINDOW = 'parentWindow',
  15      TAG_NAME = 'tagName',
  16      PARENT_NODE = 'parentNode',
  17      PREVIOUS_SIBLING = 'previousSibling',
  18      NEXT_SIBLING = 'nextSibling',
  19      CONTAINS = 'contains',
  20      COMPARE_DOCUMENT_POSITION = 'compareDocumentPosition',
  21      EMPTY_ARRAY = [],
  22  
  23      // IE < 8 throws on node.contains(textNode)
  24      supportsContainsTextNode = (function() {
  25          var node = Y.config.doc.createElement('div'),
  26              textNode = node.appendChild(Y.config.doc.createTextNode('')),
  27              result = false;
  28  
  29          try {
  30              result = node.contains(textNode);
  31          } catch(e) {}
  32  
  33          return result;
  34      })(),
  35  
  36  /**
  37   * The DOM utility provides a cross-browser abtraction layer
  38   * normalizing DOM tasks, and adds extra helper functionality
  39   * for other common tasks.
  40   * @module dom
  41   * @main dom
  42   * @submodule dom-base
  43   * @for DOM
  44   *
  45   */
  46  
  47  /**
  48   * Provides DOM helper methods.
  49   * @class DOM
  50   *
  51   */
  52  
  53  Y_DOM = {
  54      /**
  55       * Returns the HTMLElement with the given ID (Wrapper for document.getElementById).
  56       * @method byId
  57       * @param {String} id the id attribute
  58       * @param {Object} doc optional The document to search. Defaults to current document
  59       * @return {HTMLElement | null} The HTMLElement with the id, or null if none found.
  60       */
  61      byId: function(id, doc) {
  62          // handle dupe IDs and IE name collision
  63          return Y_DOM.allById(id, doc)[0] || null;
  64      },
  65  
  66      getId: function(node) {
  67          var id;
  68          // HTMLElement returned from FORM when INPUT name === "id"
  69          // IE < 8: HTMLCollection returned when INPUT id === "id"
  70          // via both getAttribute and form.id
  71          if (node.id && !node.id.tagName && !node.id.item) {
  72              id = node.id;
  73          } else if (node.attributes && node.attributes.id) {
  74              id = node.attributes.id.value;
  75          }
  76  
  77          return id;
  78      },
  79  
  80      setId: function(node, id) {
  81          if (node.setAttribute) {
  82              node.setAttribute('id', id);
  83          } else {
  84              node.id = id;
  85          }
  86      },
  87  
  88      /*
  89       * Finds the ancestor of the element.
  90       * @method ancestor
  91       * @param {HTMLElement} element The html element.
  92       * @param {Function} fn optional An optional boolean test to apply.
  93       * The optional function is passed the current DOM node being tested as its only argument.
  94       * If no function is given, the parentNode is returned.
  95       * @param {Boolean} testSelf optional Whether or not to include the element in the scan
  96       * @return {HTMLElement | null} The matching DOM node or null if none found.
  97       */
  98      ancestor: function(element, fn, testSelf, stopFn) {
  99          var ret = null;
 100          if (testSelf) {
 101              ret = (!fn || fn(element)) ? element : null;
 102  
 103          }
 104          return ret || Y_DOM.elementByAxis(element, PARENT_NODE, fn, null, stopFn);
 105      },
 106  
 107      /*
 108       * Finds the ancestors of the element.
 109       * @method ancestors
 110       * @param {HTMLElement} element The html element.
 111       * @param {Function} fn optional An optional boolean test to apply.
 112       * The optional function is passed the current DOM node being tested as its only argument.
 113       * If no function is given, all ancestors are returned.
 114       * @param {Boolean} testSelf optional Whether or not to include the element in the scan
 115       * @return {Array} An array containing all matching DOM nodes.
 116       */
 117      ancestors: function(element, fn, testSelf, stopFn) {
 118          var ancestor = element,
 119              ret = [];
 120  
 121          while ((ancestor = Y_DOM.ancestor(ancestor, fn, testSelf, stopFn))) {
 122              testSelf = false;
 123              if (ancestor) {
 124                  ret.unshift(ancestor);
 125  
 126                  if (stopFn && stopFn(ancestor)) {
 127                      return ret;
 128                  }
 129              }
 130          }
 131  
 132          return ret;
 133      },
 134  
 135      /**
 136       * Searches the element by the given axis for the first matching element.
 137       * @method elementByAxis
 138       * @param {HTMLElement} element The html element.
 139       * @param {String} axis The axis to search (parentNode, nextSibling, previousSibling).
 140       * @param {Function} [fn] An optional boolean test to apply.
 141       * @param {Boolean} [all] Whether text nodes as well as element nodes should be returned, or
 142       * just element nodes will be returned(default)
 143       * The optional function is passed the current HTMLElement being tested as its only argument.
 144       * If no function is given, the first element is returned.
 145       * @return {HTMLElement | null} The matching element or null if none found.
 146       */
 147      elementByAxis: function(element, axis, fn, all, stopAt) {
 148          while (element && (element = element[axis])) { // NOTE: assignment
 149                  if ( (all || element[TAG_NAME]) && (!fn || fn(element)) ) {
 150                      return element;
 151                  }
 152  
 153                  if (stopAt && stopAt(element)) {
 154                      return null;
 155                  }
 156          }
 157          return null;
 158      },
 159  
 160      /**
 161       * Determines whether or not one HTMLElement is or contains another HTMLElement.
 162       * @method contains
 163       * @param {HTMLElement} element The containing html element.
 164       * @param {HTMLElement} needle The html element that may be contained.
 165       * @return {Boolean} Whether or not the element is or contains the needle.
 166       */
 167      contains: function(element, needle) {
 168          var ret = false;
 169  
 170          if ( !needle || !element || !needle[NODE_TYPE] || !element[NODE_TYPE]) {
 171              ret = false;
 172          } else if (element[CONTAINS] &&
 173                  // IE < 8 throws on node.contains(textNode) so fall back to brute.
 174                  // Falling back for other nodeTypes as well.
 175                  (needle[NODE_TYPE] === 1 || supportsContainsTextNode)) {
 176                  ret = element[CONTAINS](needle);
 177          } else if (element[COMPARE_DOCUMENT_POSITION]) {
 178              // Match contains behavior (node.contains(node) === true).
 179              // Needed for Firefox < 4.
 180              if (element === needle || !!(element[COMPARE_DOCUMENT_POSITION](needle) & 16)) {
 181                  ret = true;
 182              }
 183          } else {
 184              ret = Y_DOM._bruteContains(element, needle);
 185          }
 186  
 187          return ret;
 188      },
 189  
 190      /**
 191       * Determines whether or not the HTMLElement is part of the document.
 192       * @method inDoc
 193       * @param {HTMLElement} element The containing html element.
 194       * @param {HTMLElement} doc optional The document to check.
 195       * @return {Boolean} Whether or not the element is attached to the document.
 196       */
 197      inDoc: function(element, doc) {
 198          var ret = false,
 199              rootNode;
 200  
 201          if (element && element.nodeType) {
 202              (doc) || (doc = element[OWNER_DOCUMENT]);
 203  
 204              rootNode = doc[DOCUMENT_ELEMENT];
 205  
 206              // contains only works with HTML_ELEMENT
 207              if (rootNode && rootNode.contains && element.tagName) {
 208                  ret = rootNode.contains(element);
 209              } else {
 210                  ret = Y_DOM.contains(rootNode, element);
 211              }
 212          }
 213  
 214          return ret;
 215  
 216      },
 217  
 218     allById: function(id, root) {
 219          root = root || Y.config.doc;
 220          var nodes = [],
 221              ret = [],
 222              i,
 223              node;
 224  
 225          if (root.querySelectorAll) {
 226              ret = root.querySelectorAll('[id="' + id + '"]');
 227          } else if (root.all) {
 228              nodes = root.all(id);
 229  
 230              if (nodes) {
 231                  // root.all may return HTMLElement or HTMLCollection.
 232                  // some elements are also HTMLCollection (FORM, SELECT).
 233                  if (nodes.nodeName) {
 234                      if (nodes.id === id) { // avoid false positive on name
 235                          ret.push(nodes);
 236                          nodes = EMPTY_ARRAY; // done, no need to filter
 237                      } else { //  prep for filtering
 238                          nodes = [nodes];
 239                      }
 240                  }
 241  
 242                  if (nodes.length) {
 243                      // filter out matches on node.name
 244                      // and element.id as reference to element with id === 'id'
 245                      for (i = 0; node = nodes[i++];) {
 246                          if (node.id === id  ||
 247                                  (node.attributes && node.attributes.id &&
 248                                  node.attributes.id.value === id)) {
 249                              ret.push(node);
 250                          }
 251                      }
 252                  }
 253              }
 254          } else {
 255              ret = [Y_DOM._getDoc(root).getElementById(id)];
 256          }
 257  
 258          return ret;
 259     },
 260  
 261  
 262      isWindow: function(obj) {
 263          return !!(obj && obj.scrollTo && obj.document);
 264      },
 265  
 266      _removeChildNodes: function(node) {
 267          while (node.firstChild) {
 268              node.removeChild(node.firstChild);
 269          }
 270      },
 271  
 272      siblings: function(node, fn) {
 273          var nodes = [],
 274              sibling = node;
 275  
 276          while ((sibling = sibling[PREVIOUS_SIBLING])) {
 277              if (sibling[TAG_NAME] && (!fn || fn(sibling))) {
 278                  nodes.unshift(sibling);
 279              }
 280          }
 281  
 282          sibling = node;
 283          while ((sibling = sibling[NEXT_SIBLING])) {
 284              if (sibling[TAG_NAME] && (!fn || fn(sibling))) {
 285                  nodes.push(sibling);
 286              }
 287          }
 288  
 289          return nodes;
 290      },
 291  
 292      /**
 293       * Brute force version of contains.
 294       * Used for browsers without contains support for non-HTMLElement Nodes (textNodes, etc).
 295       * @method _bruteContains
 296       * @private
 297       * @param {HTMLElement} element The containing html element.
 298       * @param {HTMLElement} needle The html element that may be contained.
 299       * @return {Boolean} Whether or not the element is or contains the needle.
 300       */
 301      _bruteContains: function(element, needle) {
 302          while (needle) {
 303              if (element === needle) {
 304                  return true;
 305              }
 306              needle = needle.parentNode;
 307          }
 308          return false;
 309      },
 310  
 311  // TODO: move to Lang?
 312      /**
 313       * Memoizes dynamic regular expressions to boost runtime performance.
 314       * @method _getRegExp
 315       * @private
 316       * @param {String} str The string to convert to a regular expression.
 317       * @param {String} flags optional An optinal string of flags.
 318       * @return {RegExp} An instance of RegExp
 319       */
 320      _getRegExp: function(str, flags) {
 321          flags = flags || '';
 322          Y_DOM._regexCache = Y_DOM._regexCache || {};
 323          if (!Y_DOM._regexCache[str + flags]) {
 324              Y_DOM._regexCache[str + flags] = new RegExp(str, flags);
 325          }
 326          return Y_DOM._regexCache[str + flags];
 327      },
 328  
 329  // TODO: make getDoc/Win true privates?
 330      /**
 331       * returns the appropriate document.
 332       * @method _getDoc
 333       * @private
 334       * @param {HTMLElement} element optional Target element.
 335       * @return {Object} The document for the given element or the default document.
 336       */
 337      _getDoc: function(element) {
 338          var doc = Y.config.doc;
 339          if (element) {
 340              doc = (element[NODE_TYPE] === 9) ? element : // element === document
 341                  element[OWNER_DOCUMENT] || // element === DOM node
 342                  element.document || // element === window
 343                  Y.config.doc; // default
 344          }
 345  
 346          return doc;
 347      },
 348  
 349      /**
 350       * returns the appropriate window.
 351       * @method _getWin
 352       * @private
 353       * @param {HTMLElement} element optional Target element.
 354       * @return {Object} The window for the given element or the default window.
 355       */
 356      _getWin: function(element) {
 357          var doc = Y_DOM._getDoc(element);
 358          return doc[DEFAULT_VIEW] || doc[PARENT_WINDOW] || Y.config.win;
 359      },
 360  
 361      _batch: function(nodes, fn, arg1, arg2, arg3, etc) {
 362          fn = (typeof fn === 'string') ? Y_DOM[fn] : fn;
 363          var result,
 364              i = 0,
 365              node,
 366              ret;
 367  
 368          if (fn && nodes) {
 369              while ((node = nodes[i++])) {
 370                  result = result = fn.call(Y_DOM, node, arg1, arg2, arg3, etc);
 371                  if (typeof result !== 'undefined') {
 372                      (ret) || (ret = []);
 373                      ret.push(result);
 374                  }
 375              }
 376          }
 377  
 378          return (typeof ret !== 'undefined') ? ret : nodes;
 379      },
 380  
 381      generateID: function(el) {
 382          var id = el.id;
 383  
 384          if (!id) {
 385              id = Y.stamp(el);
 386              el.id = id;
 387          }
 388  
 389          return id;
 390      }
 391  };
 392  
 393  
 394  Y.DOM = Y_DOM;
 395  
 396  
 397  }, '3.17.2', {"requires": ["oop", "features"]});


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1