Version 3.18.1

APIs

  • Begin typing in the search box above to see results.
Show:

File: dom/js/dom-create.js

 var re_tag = /<([a-z]+)/i,
 
 Y_DOM = Y.DOM,
 
 addFeature = Y.Features.add,
 testFeature = Y.Features.test,
 
 creators = {},
 
 createFromDIV = function(html, tag) {
 var div = Y.config.doc.createElement('div'),
 ret = true;
 
 div.innerHTML = html;
 if (!div.firstChild || div.firstChild.tagName !== tag.toUpperCase()) {
 ret = false;
 }
 
 return ret;
 },
 
 re_tbody = /(?:\/(?:thead|tfoot|tbody|caption|col|colgroup)>)+\s*<tbody/,
 
 TABLE_OPEN = '<table>',
 TABLE_CLOSE = '</table>',
 
 selectedIndex;
 
 Y.mix(Y.DOM, {
 _fragClones: {},
 
 _create: function(html, doc, tag) {
 tag = tag || 'div';
 
 var frag = Y_DOM._fragClones[tag];
 if (frag) {
 frag = frag.cloneNode(false);
 } else {
 frag = Y_DOM._fragClones[tag] = doc.createElement(tag);
 }
 frag.innerHTML = html;
 return frag;
 },
 
 _children: function(node, tag) {
 var i = 0,
 children = node.children,
 childNodes,
 hasComments,
 child;
 
 if (children && children.tags) { // use tags filter when possible
 if (tag) {
 children = node.children.tags(tag);
 } else { // IE leaks comments into children
 hasComments = children.tags('!').length;
 }
 }
 
 if (!children || (!children.tags && tag) || hasComments) {
 childNodes = children || node.childNodes;
 children = [];
 while ((child = childNodes[i++])) {
 if (child.nodeType === 1) {
 if (!tag || tag === child.tagName) {
 children.push(child);
 }
 }
 }
 }
 
 return children || [];
 },
 
 /**
 * Creates a new dom node using the provided markup string.
 * @method create
 * @param {String} html The markup used to create the element
 * @param {HTMLDocument} doc An optional document context
 * @return {HTMLElement|DocumentFragment} returns a single HTMLElement
 * when creating one node, and a documentFragment when creating
 * multiple nodes.
 */
 create: function(html, doc) {
 if (typeof html === 'string') {
 html = Y.Lang.trim(html); // match IE which trims whitespace from innerHTML
 
 }
 
 doc = doc || Y.config.doc;
 var m = re_tag.exec(html),
 create = Y_DOM._create,
 custom = creators,
 ret = null,
 creator, tag, node, nodes;
 
 if (html != undefined) { // not undefined or null
 if (m && m[1]) {
 creator = custom[m[1].toLowerCase()];
 if (typeof creator === 'function') {
 create = creator;
 } else {
 tag = creator;
 }
 }
 
 node = create(html, doc, tag);
 nodes = node.childNodes;
 
 if (nodes.length === 1) { // return single node, breaking parentNode ref from "fragment"
 ret = node.removeChild(nodes[0]);
 } else if (nodes[0] && nodes[0].className === 'yui3-big-dummy') { // using dummy node to preserve some attributes (e.g. OPTION not selected)
 selectedIndex = node.selectedIndex;
 
 if (nodes.length === 2) {
 ret = nodes[0].nextSibling;
 } else {
 node.removeChild(nodes[0]);
 ret = Y_DOM._nl2frag(nodes, doc);
 }
 } else { // return multiple nodes as a fragment
 ret = Y_DOM._nl2frag(nodes, doc);
 }
 
 }
 
 return ret;
 },
 
 _nl2frag: function(nodes, doc) {
 var ret = null,
 i, len;
 
 if (nodes && (nodes.push || nodes.item) && nodes[0]) {
 doc = doc || nodes[0].ownerDocument;
 ret = doc.createDocumentFragment();
 
 if (nodes.item) { // convert live list to static array
 nodes = Y.Array(nodes, 0, true);
 }
 
 for (i = 0, len = nodes.length; i < len; i++) {
 ret.appendChild(nodes[i]);
 }
 } // else inline with log for minification
 return ret;
 },
 
 /**
 * Inserts content in a node at the given location
 * @method addHTML
 * @param {HTMLElement} node The node to insert into
 * @param {HTMLElement | Array | HTMLCollection} content The content to be inserted
 * @param {HTMLElement} where Where to insert the content
 * If no "where" is given, content is appended to the node
 * Possible values for "where"
 * <dl>
 * <dt>HTMLElement</dt>
 * <dd>The element to insert before</dd>
 * <dt>"replace"</dt>
 * <dd>Replaces the existing HTML</dd>
 * <dt>"before"</dt>
 * <dd>Inserts before the existing HTML</dd>
 * <dt>"before"</dt>
 * <dd>Inserts content before the node</dd>
 * <dt>"after"</dt>
 * <dd>Inserts content after the node</dd>
 * </dl>
 */
 addHTML: function(node, content, where) {
 var nodeParent = node.parentNode,
 i = 0,
 item,
 ret = content,
 newNode;
 
 
 if (content != undefined) { // not null or undefined (maybe 0)
 if (content.nodeType) { // DOM node, just add it
 newNode = content;
 } else if (typeof content == 'string' || typeof content == 'number') {
 ret = newNode = Y_DOM.create(content);
 } else if (content[0] && content[0].nodeType) { // array or collection
 newNode = Y.config.doc.createDocumentFragment();
 while ((item = content[i++])) {
 newNode.appendChild(item); // append to fragment for insertion
 }
 }
 }
 
 if (where) {
 if (newNode && where.parentNode) { // insert regardless of relationship to node
 where.parentNode.insertBefore(newNode, where);
 } else {
 switch (where) {
 case 'replace':
 while (node.firstChild) {
 node.removeChild(node.firstChild);
 }
 if (newNode) { // allow empty content to clear node
 node.appendChild(newNode);
 }
 break;
 case 'before':
 if (newNode) {
 nodeParent.insertBefore(newNode, node);
 }
 break;
 case 'after':
 if (newNode) {
 if (node.nextSibling) { // IE errors if refNode is null
 nodeParent.insertBefore(newNode, node.nextSibling);
 } else {
 nodeParent.appendChild(newNode);
 }
 }
 break;
 default:
 if (newNode) {
 node.appendChild(newNode);
 }
 }
 }
 } else if (newNode) {
 node.appendChild(newNode);
 }
 
 // `select` elements are the only elements with `selectedIndex`.
 // Don't grab the dummy `option` element's `selectedIndex`.
 if (node.nodeName == "SELECT" && selectedIndex > 0) {
 node.selectedIndex = selectedIndex - 1;
 }
 
 return ret;
 },
 
 wrap: function(node, html) {
 var parent = (html && html.nodeType) ? html : Y.DOM.create(html),
 nodes = parent.getElementsByTagName('*');
 
 if (nodes.length) {
 parent = nodes[nodes.length - 1];
 }
 
 if (node.parentNode) {
 node.parentNode.replaceChild(parent, node);
 }
 parent.appendChild(node);
 },
 
 unwrap: function(node) {
 var parent = node.parentNode,
 lastChild = parent.lastChild,
 next = node,
 grandparent;
 
 if (parent) {
 grandparent = parent.parentNode;
 if (grandparent) {
 node = parent.firstChild;
 while (node !== lastChild) {
 next = node.nextSibling;
 grandparent.insertBefore(node, parent);
 node = next;
 }
 grandparent.replaceChild(lastChild, parent);
 } else {
 parent.removeChild(node);
 }
 }
 }
 });
 
 addFeature('innerhtml', 'table', {
 test: function() {
 var node = Y.config.doc.createElement('table');
 try {
 node.innerHTML = '<tbody></tbody>';
 } catch(e) {
 return false;
 }
 return (node.firstChild && node.firstChild.nodeName === 'TBODY');
 }
 });
 
 addFeature('innerhtml-div', 'tr', {
 test: function() {
 return createFromDIV('<tr></tr>', 'tr');
 }
 });
 
 addFeature('innerhtml-div', 'script', {
 test: function() {
 return createFromDIV('<script></script>', 'script');
 }
 });
 
 if (!testFeature('innerhtml', 'table')) {
 // TODO: thead/tfoot with nested tbody
 // IE adds TBODY when creating TABLE elements (which may share this impl)
 creators.tbody = function(html, doc) {
 var frag = Y_DOM.create(TABLE_OPEN + html + TABLE_CLOSE, doc),
 tb = Y.DOM._children(frag, 'tbody')[0];
 
 if (frag.children.length > 1 && tb && !re_tbody.test(html)) {
 tb.parentNode.removeChild(tb); // strip extraneous tbody
 }
 return frag;
 };
 }
 
 if (!testFeature('innerhtml-div', 'script')) {
 creators.script = function(html, doc) {
 var frag = doc.createElement('div');
 
 frag.innerHTML = '-' + html;
 frag.removeChild(frag.firstChild);
 return frag;
 };
 
 creators.link = creators.style = creators.script;
 }
 
 if (!testFeature('innerhtml-div', 'tr')) {
 Y.mix(creators, {
 option: function(html, doc) {
 return Y_DOM.create('<select><option class="yui3-big-dummy" selected></option>' + html + '</select>', doc);
 },
 
 tr: function(html, doc) {
 return Y_DOM.create('<tbody>' + html + '</tbody>', doc);
 },
 
 td: function(html, doc) {
 return Y_DOM.create('<tr>' + html + '</tr>', doc);
 },
 
 col: function(html, doc) {
 return Y_DOM.create('<colgroup>' + html + '</colgroup>', doc);
 },
 
 tbody: 'table'
 });
 
 Y.mix(creators, {
 legend: 'fieldset',
 th: creators.td,
 thead: creators.tbody,
 tfoot: creators.tbody,
 caption: creators.tbody,
 colgroup: creators.tbody,
 optgroup: creators.option
 });
 }
 
 Y_DOM.creators = creators;
 
 

AltStyle によって変換されたページ (->オリジナル) /