diff --git a/ajax/libs/document-register-element/0.1.2/document-register-element.js b/ajax/libs/document-register-element/0.1.2/document-register-element.js new file mode 100644 index 000000000..bf2eaf34f --- /dev/null +++ b/ajax/libs/document-register-element/0.1.2/document-register-element.js @@ -0,0 +1,2 @@ +/*! (C) WebReflection Mit Style License */ +(function(e,t,n,r){"use strict";function q(e,t){for(var n=0,r=e.length;n>0),s="extends",o="DOMAttrModified",u="DOMSubtreeModified",a=/^[A-Z][A-Z0-9]*(?:-[A-Z0-9]+)+$/,f=["ANNOTATION-XML","COLOR-PROFILE","FONT-FACE","FONT-FACE-SRC","FONT-FACE-URI","FONT-FACE-FORMAT","FONT-FACE-NAME","MISSING-GLYPH"],l=[],c=[],h="",p=t.documentElement,d=l.indexOf||function(e){for(var t=this.length;t--&&this[t]!==e;);return t},v=n.prototype,m=v.hasOwnProperty,g=v.isPrototypeOf,y=n.defineProperty,b=n.getOwnPropertyDescriptor,w=n.getOwnPropertyNames,E=n.getPrototypeOf,S=n.setPrototypeOf,x=!!n.__proto__,T=n.create||function K(e){return e?(K.prototype=e,new K):this},N=S||(x?function(e,t){return e.__proto__=t,e}:w&&b?function(){function e(e,t){for(var n,r=w(t),i=0,s=r.length;i> 0), + + // shortcuts and costants + EXTENDS = 'extends', + DOM_ATTR_MODIFIED = 'DOMAttrModified', + DOM_SUBTREE_MODIFIED = 'DOMSubtreeModified', + + // valid and invalid node names + validName = /^[A-Z][A-Z0-9]*(?:-[A-Z0-9]+)+$/, + invalidNames = [ + 'ANNOTATION-XML', + 'COLOR-PROFILE', + 'FONT-FACE', + 'FONT-FACE-SRC', + 'FONT-FACE-URI', + 'FONT-FACE-FORMAT', + 'FONT-FACE-NAME', + 'MISSING-GLYPH' + ], + + // registered types and their prototypes + types = [], + protos = [], + + // to query subnodes + query = '', + + // html shortcut used to feature detect + documentElement = document.documentElement, + + // ES5 inline helpers || basic patches + indexOf = types.indexOf || function (v) { + for(var i = this.length; i-- && this[i] !== v;){} + return i; + }, + + // other helpers / shortcuts + OP = Object.prototype, + hOP = OP.hasOwnProperty, + iPO = OP.isPrototypeOf, + + defineProperty = Object.defineProperty, + gOPD = Object.getOwnPropertyDescriptor, + gOPN = Object.getOwnPropertyNames, + gPO = Object.getPrototypeOf, + sPO = Object.setPrototypeOf, + + hasProto = !!Object.__proto__, + + // used to create unique instances + create = Object.create || function Bridge(proto) { + // silly broken polyfill probably ever used but short enough to work + return proto ? ((Bridge.prototype = proto), new Bridge) : this; + }, + + // will set the prototype if possible + // or copy over all properties + setPrototype = sPO || ( + hasProto ? + function (o, p) { + o.__proto__ = p; + return o; + } : ( + (gOPN && gOPD) ? + (function(){ + function setProperties(o, p) { + for (var + key, + names = gOPN(p), + i = 0, length = names.length; + i < length; i++ + ) { + key = names[i]; + if (!hOP.call(o, key)) { + defineProperty(o, key, gOPD(p, key)); + } + } + } + return function (o, p) { + do { + setProperties(o, p); + } while (p = gPO(p)); + return o; + }; + }()) : + function (o, p) { + for (var key in p) { + o[key] = p[key]; + } + return o; + } + )), + + // based on setting prototype capability + // will check proto or the expando attribute + // in order to setup the node once + patchIfNotAlready = sPO || hasProto ? + function (node, proto) { + if (!iPO.call(proto, node)) { + setupNode(node, proto); + } + } : + function (node, proto) { + if (!node[EXPANDO_UID]) { + node[EXPANDO_UID] = Object(true); + setupNode(node, proto); + } + } + , + + // DOM shortcuts and helpers, if any + + MutationObserver = window.MutationObserver || + window.WebKitMutationObserver, + + HTMLElementPrototype = ( + window.HTMLElement || + window.Element || + window.Node + ).prototype, + + cloneNode = HTMLElementPrototype.cloneNode, + setAttribute = HTMLElementPrototype.setAttribute, + + // replaced later on + createElement = document.createElement, + + // shared observer for all attributes + attributesObserver = MutationObserver && { + attributes: true, + characterData: true, + attributeOldValue: true + }, + + // useful to detect only if there's no MutationObserver + DOMAttrModified = MutationObserver || function(e) { + doesNotSupportDOMAttrModified = false; + documentElement.removeEventListener( + DOM_ATTR_MODIFIED, + DOMAttrModified + ); + }, + + // internal flags + setListener = false, + doesNotSupportDOMAttrModified = true, + + // optionally defined later on + onSubtreeModified, + callDOMAttrModified, + getAttributesMirror, + observer +; + +if (!MutationObserver) { + documentElement.addEventListener(DOM_ATTR_MODIFIED, DOMAttrModified); + documentElement.setAttribute(EXPANDO_UID, 1); + documentElement.removeAttribute(EXPANDO_UID); + if (doesNotSupportDOMAttrModified) { + onSubtreeModified = function (e) { + var + node = this, + oldAttributes, + newAttributes, + key + ; + if (node === e.target) { + oldAttributes = node[EXPANDO_UID]; + node[EXPANDO_UID] = (newAttributes = getAttributesMirror(node)); + for (key in newAttributes) { + if (!(key in oldAttributes)) { + // attribute was added + return callDOMAttrModified( + 0, + node, + key, + oldAttributes[key], + newAttributes[key], + 'ADDITION' + ); + } else if (newAttributes[key] !== oldAttributes[key]) { + // attribute was changed + return callDOMAttrModified( + 1, + node, + key, + oldAttributes[key], + newAttributes[key], + 'MODIFICATION' + ); + } + } + // checking if it has been removed + for (key in oldAttributes) { + if (!(key in newAttributes)) { + // attribute removed + return callDOMAttrModified( + 2, + node, + key, + oldAttributes[key], + newAttributes[key], + 'REMOVAL' + ); + } + } + } + }; + callDOMAttrModified = function ( + attrChange, + currentTarget, + attrName, + prevValue, + newValue, + action + ) { + var e = { + attrChange: attrChange, + currentTarget: currentTarget, + attrName: attrName, + prevValue: prevValue, + newValue: newValue + }; + e[action] = attrChange; + onDOMAttrModified(e); + }; + getAttributesMirror = function (node) { + for (var + attr, name, + result = {}, + attributes = node.attributes, + i = 0, length = attributes.length; + i < length; i++ + ) { + attr = attributes[i]; + name = attr.name; + if (name !== 'setAttribute') { + result[name] = attr.value; + } + } + return result; + }; + } +} + +function loopAndVerify(list, action) { + for (var i = 0, length = list.length; i < length; i++) { + verifyAndSetupAndAction(list[i], action); + } +} + +function loopAndSetup(list) { + for (var i = 0, length = list.length, node; i < length; i++) { + node = list[i]; + setupNode(node, protos[getTypeIndex(node)]); + } +} + +function executeAction(action) { + return function (node) { + if (iPO.call(HTMLElementPrototype, node)) { + verifyAndSetupAndAction(node, action); + loopAndVerify( + node.querySelectorAll(query), + action + ); + } + }; +} + +function getTypeIndex(target) { + var is = target.getAttribute('is'); + return indexOf.call( + types, + is ? + is.toUpperCase() : + target.nodeName + ); +} + +function onDOMAttrModified(e) { + var + node = e.currentTarget, + attrChange = e.attrChange, + prevValue = e.prevValue, + newValue = e.newValue + ; + if (node.attributeChangedCallback && + e.attrName !== 'style') { + node.attributeChangedCallback( + e.attrName, + attrChange === e.ADDITION ? null : prevValue, + attrChange === e.REMOVAL ? null : newValue + ); + } +} + +function onDOMNode(action) { + var executor = executeAction(action); + return function (e) { + executor(e.target); + }; +} + +function patchedSetAttribute(name, value) { + var self = this; + setAttribute.call(self, name, value); + onSubtreeModified.call(self, {target: self}); +} + +function setupNode(node, proto) { + setPrototype(node, proto); + if (observer) { + observer.observe(node, attributesObserver); + } else { + if (doesNotSupportDOMAttrModified) { + node.setAttribute = patchedSetAttribute; + node[EXPANDO_UID] = getAttributesMirror(node); + node.addEventListener(DOM_SUBTREE_MODIFIED, onSubtreeModified); + } + node.addEventListener(DOM_ATTR_MODIFIED, onDOMAttrModified); + } + if (node.createdCallback) { + node.created = true; + node.createdCallback(); + node.created = false; + } +} + +function verifyAndSetupAndAction(node, action) { + var + fn, + i = getTypeIndex(node), + attached = 'attached', + detached = 'detached' + ; + if (-1 < i) { + patchIfNotAlready(node, protos[i]); + i = 0; + if (action === attached && !node[attached]) { + node[detached] = false; + node[attached] = true; + i = 1; + } else if (action === detached && !node[detached]) { + node[attached] = false; + node[detached] = true; + i = 1; + } + if (i && (fn = node[action + 'Callback'])) fn.call(node); + } +} + +// set as enumerable, writable and configurable +document[REGISTER_ELEMENT] = function registerElement(type, options) { + upperType = type.toUpperCase(); + if (!setListener) { + // only first time document.registerElement is used + // we need to set this listener + // setting it by default might slow down for no reason + setListener = true; + if (MutationObserver) { + observer = (function(attached, detached){ + function checkEmAll(list, callback) { + for (var i = 0, length = list.length; i < length; callback(list[i++])){} + } + return new MutationObserver(function (records) { + for (var + current, node, + i = 0, length = records.length; i < length; i++ + ) { + current = records[i]; + if (current.type === 'childList') { + checkEmAll(current.addedNodes, attached); + checkEmAll(current.removedNodes, detached); + } else { + node = current.target; + if (node.attributeChangedCallback && + current.attributeName !== 'style') { + node.attributeChangedCallback( + current.attributeName, + current.oldValue, + node.getAttribute(current.attributeName) + ); + } + } + } + }); + }(executeAction('attached'), executeAction('detached'))); + observer.observe( + document, + { + childList: true, + subtree: true + } + ); + } else { + document.addEventListener('DOMNodeInserted', onDOMNode('attached')); + document.addEventListener('DOMNodeRemoved', onDOMNode('detached')); + } + + document.addEventListener('readystatechange', function (e) { + loopAndVerify( + document.querySelectorAll(query), + 'attached' + ); + }); + + document.createElement = function (localName, typeExtension) { + var i, node = createElement.apply(document, arguments); + if (typeExtension) { + node.setAttribute('is', localName = typeExtension.toLowerCase()); + } + i = indexOf.call(types, localName.toUpperCase()); + if (-1 < i) setupNode(node, protos[i]); + return node; + }; + + HTMLElementPrototype.cloneNode = function (deep) { + var + node = cloneNode.call(this, !!deep), + i = getTypeIndex(node) + ; + if (-1 < i) setupNode(node, protos[i]); + if (deep) loopAndSetup(node.querySelectorAll(query)); + return node; + }; + } + + if (-1 < indexOf.call(types, upperType)) { + throw new Error('A ' + type + ' type is already registered'); + } + + if (!validName.test(upperType) || -1 < indexOf.call(invalidNames, upperType)) { + throw new Error('The type ' + type + ' is invalid'); + } + + var + constructor = function () { + return document.createElement(nodeName, extending && upperType); + }, + opt = options || OP, + extending = hOP.call(opt, EXTENDS), + nodeName = extending ? options[EXTENDS] : upperType, + i = types.push(upperType) - 1, + upperType + ; + + query = query.concat( + query.length ? ',' : '', + extending ? nodeName + '[is="' + type.toLowerCase() + '"]' : nodeName + ); + + constructor.prototype = ( + protos[i] = hOP.call(opt, 'prototype') ? + opt.prototype : + create(HTMLElementPrototype) + ); + + loopAndVerify( + document.querySelectorAll(query), + 'attached' + ); + + return constructor; +}; + + +}(window, document, Object, 'registerElement')); \ No newline at end of file diff --git a/ajax/libs/document-register-element/package.json b/ajax/libs/document-register-element/package.json new file mode 100644 index 000000000..195c220f9 --- /dev/null +++ b/ajax/libs/document-register-element/package.json @@ -0,0 +1,35 @@ +{ + "name": "document-register-element", + "version": "0.1.2", + "description": "A stand-alone working lightweight version of the W3C Custom Elements specification", + "homepage": "https://github.com/WebReflection/document-register-element", + "keywords": [ + "Web", + "Components", + "Custom", + "Element", + "Elements", + "DOM", + "W3C", + "Polymer", + "polyfill", + "alternative" + ], + "author": { + "name": "Andrea Giammarchi", + "web": "http://webreflection.blogspot.com/" + }, + "repository": { + "type": "git", + "url": "git://github.com/WebReflection/document-register-element.git" + }, + "filename": "document-register-element.js", + "npmName": "document-register-element", + "npmFileMap": [{ + "basePath": "/build/", + "files": [ + "document-register-element.js", + "document-register-element.max.js" + ] + }] +} \ No newline at end of file