UNPKG

skylark-utils

Version:

An Elegant HTML5 JavaScript Library.

412 lines (341 loc) 10.5 kB
define([ "./skylark", "./langx", "./styler" ], function(skylark, langx, styler) { var isIE = !!navigator.userAgent.match(/Trident/g) || !!navigator.userAgent.match(/MSIE/g), fragmentRE = /^\s*<(\w+|!)[^>]*>/, singleTagRE = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, div = document.createElement("div"), table = document.createElement('table'), tableBody = document.createElement('tbody'), tableRow = document.createElement('tr'), containers = { 'tr': tableBody, 'tbody': table, 'thead': table, 'tfoot': table, 'td': tableRow, 'th': tableRow, '*': div }, rootNodeRE = /^(?:body|html)$/i, map = Array.prototype.map, slice = Array.prototype.slice; function ensureNodes(nodes, copyByClone) { if (!langx.isArrayLike(nodes)) { nodes = [nodes]; } if (copyByClone) { nodes = map.call(nodes, function(node) { return node.cloneNode(true); }); } return langx.flatten(nodes); } function nodeName(elm, chkName) { var name = elm.nodeName && elm.nodeName.toLowerCase(); if (chkName !== undefined) { return name === chkName.toLowerCase(); } return name; }; function contents(elm) { if (nodeName(elm, "iframe")) { return elm.contentDocument; } return elm.childNodes; } function html(node, html) { if (html === undefined) { return node.innerHTML; } else { this.empty(node); html = html || ""; if (langx.isString(html) || langx.isNumber(html)) { node.innerHTML = html; } else if (langx.isArrayLike(html)) { for (var i = 0; i < html.length; i++) { node.appendChild(html[i]); } } else { node.appendChild(html); } } } function clone(node, deep) { var self = this, clone; // TODO: Add feature detection here in the future if (!isIE || node.nodeType !== 1 || deep) { return node.cloneNode(deep); } // Make a HTML5 safe shallow copy if (!deep) { clone = document.createElement(node.nodeName); // Copy attribs each(self.getAttribs(node), function(attr) { self.setAttrib(clone, attr.nodeName, self.getAttrib(node, attr.nodeName)); }); return clone; } } function createElement(tag, props) { var node = document.createElement(tag); if (props) { langx.mixin(node, props); } return node; } function createFragment(html) { // A special case optimization for a single tag if (singleTagRE.test(html)) { return [createElement(RegExp.$1)]; } var name = fragmentRE.test(html) && RegExp.$1 if (!(name in containers)) { name = "*" } var container = containers[name]; container.innerHTML = "" + html; dom = slice.call(container.childNodes); dom.forEach(function(node) { container.removeChild(node); }) return dom; } function contains(node, child) { return isChildOf(child, node); } function createTextNode(text) { return document.createTextNode(text); } function doc() { return document; } function empty(node) { while (node.hasChildNodes()) { var child = node.firstChild; node.removeChild(child); } return this; } function isChildOf(node, parent) { if (document.documentElement.contains) { return parent.contains(node); } while (node) { if (parent === node) { return true; } node = node.parentNode; } return false; } function isDoc(node) { return node != null && node.nodeType == node.DOCUMENT_NODE } function ownerDoc(elm) { if (!elm) { return document; } if (elm.nodeType == 9) { return elm; } return elm.ownerDocument; } function ownerWindow(elm) { var doc = ownerDoc(elm); return doc.defaultView || doc.parentWindow; } function after(node, placing, copyByClone) { var refNode = node, parent = refNode.parentNode; if (parent) { var nodes = ensureNodes(placing, copyByClone), refNode = refNode.nextSibling; for (var i = 0; i < nodes.length; i++) { if (refNode) { parent.insertBefore(nodes[i], refNode); } else { parent.appendChild(nodes[i]); } } } return this; } function before(node, placing, copyByClone) { var refNode = node, parent = refNode.parentNode; if (parent) { var nodes = ensureNodes(placing, copyByClone); for (var i = 0; i < nodes.length; i++) { parent.insertBefore(nodes[i], refNode); } } return this; } function prepend(node, placing, copyByClone) { var parentNode = node, refNode = parentNode.firstChild, nodes = ensureNodes(placing, copyByClone); for (var i = 0; i < nodes.length; i++) { if (refNode) { parentNode.insertBefore(nodes[i], refNode); } else { parentNode.appendChild(nodes[i]); } } return this; } function append(node, placing, copyByClone) { var parentNode = node, nodes = ensureNodes(placing, copyByClone); for (var i = 0; i < nodes.length; i++) { parentNode.appendChild(nodes[i]); } return this; } function overlay(elm, params) { var overlayDiv = createElement("div", params); styler.css(overlayDiv, { position: "absolute", top: 0, left: 0, width: "100%", height: "100%", zIndex: 0x7FFFFFFF, opacity: 0.7 }); elm.appendChild(overlayDiv); return overlayDiv; } function remove(node) { if (node && node.parentNode) { node.parentNode.removeChild(node); } return this; } function replace(node, oldNode) { oldNode.parentNode.replaceChild(node, oldNode); return this; } function throb(elm, params) { params = params || {}; var self = this, text = params.text, style = params.style, time = params.time, callback = params.callback, timer, throbber = this.createElement("div", { className: params.className || "throbber", style: style }), _overlay = overlay(throbber, { className: 'overlay fade' }), throb = this.createElement("div", { className: "throb" }), textNode = this.createTextNode(text || ""), remove = function() { if (timer) { clearTimeout(timer); timer = null; } if (throbber) { self.remove(throbber); throbber = null; } }, update = function(params) { if (params && params.text && throbber) { textNode.nodeValue = params.text; } }; throb.appendChild(textNode); throbber.appendChild(throb); elm.appendChild(throbber); var end = function() { remove(); if (callback) callback(); }; if (time) { timer = setTimeout(end, time); } return { remove: remove, update: update }; } function traverse(node, fn) { fn(node) for (var i = 0, len = node.childNodes.length; i < len; i++) { traverse(node.childNodes[i], fn); } return this; } function reverse(node) { var firstChild = node.firstChild; for (var i = node.children.length - 1; i > 0; i--) { if (i > 0) { var child = node.children[i]; node.insertBefore(child, firstChild); } } } function wrapper(node, wrapperNode) { if (langx.isString(wrapperNode)) { wrapperNode = this.createFragment(wrapperNode).firstChild; } node.parentNode.insertBefore(wrapperNode, node); wrapperNode.appendChild(node); } function wrapperInner(node, wrapperNode) { var childNodes = slice.call(node.childNodes); node.appendChild(wrapperNode); for (var i = 0; i < childNodes.length; i++) { wrapperNode.appendChild(childNodes[i]); } return this; } function unwrap(node) { var child, parent = node.parentNode; if (parent) { if (this.isDoc(parent.parentNode)) return; parent.parentNode.insertBefore(node, parent); } } function noder() { return noder; } langx.mixin(noder, { clone: clone, contents: contents, createElement: createElement, createFragment: createFragment, contains: contains, createTextNode: createTextNode, doc: doc, empty: empty, html: html, isChildOf: isChildOf, isDoc: isDoc, ownerDoc: ownerDoc, ownerWindow : ownerWindow, after: after, before: before, prepend: prepend, append: append, remove: remove, replace: replace, throb: throb, traverse: traverse, reverse: reverse, wrapper: wrapper, wrapperInner: wrapperInner, unwrap: unwrap }); return skylark.noder = noder; });