diff --git a/README.md b/README.md index 8daf8080..c77d9956 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,6 @@ BOSSv3 won't have a command line interface, to simplify things. It also allows B - [ ] Optimisations to load ordering. - [ ] Implement logging. - [ ] Add a quick header-only plugin read for use when loading the metadata editor, so that existing Bash Tags can also be displayed. -- [ ] Add checks for "Deactivate" tag compliance? - [ ] Make validity checks non-fatal. - [ ] Add a massive "RUN THE GAME LAUNCHER IF YOUR GAME IS NOT DETECTED" message somewhere. - [ ] Generalise Total Conversion support, so that any TC for any of the supported 'base' games can be used with BOSS. @@ -65,7 +64,7 @@ BOSSv3 won't have a command line interface, to simplify things. It also allows B - [ ] Write report Javascript. - [ ] Double-check ghosted file support. - [ ] Add a setting that lets users choose whether to use the viewer window or their own browser when viewing BOSS's report. -- [ ] Somehow implement filter settings memory for the BOSS report. +- [x] Somehow implement filter settings memory for the BOSS report. - [ ] Implement checking of details part of report against previous report. @@ -110,6 +109,8 @@ BOSS uses the following libraries: * wxWidgets * yaml-cpp +Also uses (polyfill.js)[https://github.com/inexorabletash/polyfill/blob/master/polyfill.js], (storage.js)[https://github.com/inexorabletash/polyfill/blob/master/storage.js] and (DOM-shim)[https://github.com/Raynos/DOM-shim/blob/master/lib/DOM-shim-ie8.js] for Internet Explorer 8 compatibility. + ## Misc diff --git a/docs/BOSS Readme.html b/docs/BOSS Readme.html index 6611bb50..a53c172c 100644 --- a/docs/BOSS Readme.html +++ b/docs/BOSS Readme.html @@ -198,10 +198,7 @@ This documentation is a work in progress, covering an application that is also s
A few Bash Tags are used by BOSS in its load order error checking: -
Deactivate tag applied (not merely suggested), an error message will be displayed for it.
- Filter tag applied and missing masters will not cause any errors to be displayed.
+ If a plugin's masters are missing, an error message will be displayed for it. Filter patches are special mods designed for use with a Bashed Patch that do not require all their masters to be present, and so any plugin with the Filter tag applied and missing masters will not cause any errors to be displayed.
diff --git a/examples/resource/DOM-shim-ie8.js b/examples/resource/DOM-shim-ie8.js
new file mode 100644
index 00000000..1ba3c34e
--- /dev/null
+++ b/examples/resource/DOM-shim-ie8.js
@@ -0,0 +1,1725 @@
+(function(){
+window.M8 = {data:{}};
+(function(){
+/**
+ * modul8 v0.13.0
+ */
+
+var config = {"namespace":"M8","domains":["app","shims","all","utils"],"arbiters":{},"logging":1}
+ , ns = window[config.namespace]
+ , domains = config.domains
+ , arbiters = []
+ , exports = {}
+ , DomReg = /^([\w]*)::/;
+
+/**
+ * Initialize the exports container with domain names + move data to it
+ */
+exports.M8 = {};
+exports.external = {};
+exports.data = ns.data;
+delete ns.data;
+
+domains.forEach(function(e){
+ exports[e] = {};
+});
+
+/**
+ * Attach arbiters to the require system then delete them from the global scope
+ */
+Object.keys(config.arbiters).forEach(function(name){
+ var arbAry = config.arbiters[name];
+ arbiters.push(name);
+ exports.M8[name] = window[arbAry[0]];
+ arbAry.forEach(function(e){
+ delete window[e];
+ });
+});
+
+/**
+ * Converts a relative path to an absolute one
+ */
+function toAbsPath(pathName, relReqStr) {
+ var folders = pathName.split('/').slice(0, -1);
+ while (relReqStr.slice(0, 3) === '../') {
+ folders = folders.slice(0, -1);
+ relReqStr = relReqStr.slice(3);
+ }
+ return folders.concat(relReqStr.split('/')).join('/');
+}
+
+/**
+ * Require Factory for ns.define
+ * Each (domain,path) gets a specialized require function from this
+ */
+function makeRequire(dom, pathName) {
+ return function(reqStr) {
+ var o, scannable, k, skipFolder;
+
+ if (config.logging >= 4) {
+ console.debug('modul8: '+dom+':'+pathName+" <- "+reqStr);
+ }
+
+ if (reqStr.slice(0, 2) === './') {
+ scannable = [dom];
+ reqStr = toAbsPath(pathName, reqStr.slice(2));
+ }
+ else if (reqStr.slice(0,3) === '../') {
+ scannable = [dom];
+ reqStr = toAbsPath(pathName, reqStr);
+ }
+ else if (DomReg.test(reqStr)) {
+ scannable = [reqStr.match(DomReg)[1]];
+ reqStr = reqStr.split('::')[1];
+ }
+ else if (arbiters.indexOf(reqStr) >= 0) {
+ scannable = ['M8'];
+ }
+ else {
+ scannable = [dom].concat(domains.filter(function(e) {return e !== dom;}));
+ }
+
+ reqStr = reqStr.split('.')[0];
+ if (reqStr.slice(-1) === '/' || reqStr === '') {
+ reqStr += 'index';
+ skipFolder = true;
+ }
+
+ if (config.logging >= 3) {
+ console.log('modul8: '+dom+':'+pathName+' <- '+reqStr);
+ }
+ if (config.logging >= 4) {
+ console.debug('modul8: scanned '+JSON.stringify(scannable));
+ }
+
+ for (k = 0; k < scannable.length; k += 1) {
+ o = scannable[k];
+ if (exports[o][reqStr]) {
+ return exports[o][reqStr];
+ }
+ if (!skipFolder && exports[o][reqStr + '/index']) {
+ return exports[o][reqStr + '/index'];
+ }
+ }
+
+ if (config.logging >= 1) {
+ console.error("modul8: Unable to resolve require for: " + reqStr);
+ }
+ };
+}
+
+ns.define = function(name, domain, fn) {
+ var module = {};
+ fn(makeRequire(domain, name), module, exports[domain][name] = {});
+ if (module.exports) {
+ delete exports[domain][name];
+ exports[domain][name] = module.exports;
+ }
+};
+
+/**
+ * Public Debug API
+ */
+
+ns.inspect = function(domain) {
+ console.log(exports[domain]);
+};
+
+ns.domains = function() {
+ return domains.concat(['external','data']);
+};
+
+ns.require = makeRequire('app', 'CONSOLE');
+
+/**
+ * Live Extension API
+ */
+
+ns.data = function(name, exported) {
+ if (exports.data[name]) {
+ delete exports.data[name];
+ }
+ if (exported) {
+ exports.data[name] = exported;
+ }
+};
+
+ns.external = function(name, exported) {
+ if (exports.external[name]) {
+ delete exports.external[name];
+ }
+ if (exported) {
+ exports.external[name] = exported;
+ }
+};
+
+})();
+
+// shared code
+
+M8.define('index','utils',function(require, module, exports){
+var hasOwnProperty = Object.prototype.hasOwnProperty;
+
+
+var HTMLNames = [
+ "HTMLDocument", "HTMLLinkElement", "HTMLElement", "HTMLHtmlElement",
+ "HTMLDivElement", "HTMLAnchorElement", "HTMLSelectElement",
+ "HTMLOptionElement", "HTMLInputElement", "HTMLHeadElement",
+ "HTMLSpanElement", "XULElement", "HTMLBodyElement", "HTMLTableElement",
+ "HTMLTableCellElement", "HTMLTextAreaElement", "HTMLScriptElement",
+ "HTMLAudioElement", "HTMLMediaElement", "HTMLParagraphElement",
+ "HTMLButtonElement", "HTMLLIElement", "HTMLUListElement",
+ "HTMLFormElement", "HTMLHeadingElement", "HTMLImageElement",
+ "HTMLStyleElement", "HTMLTableRowElement", "HTMLTableSectionElement",
+ "HTMLBRElement"
+];
+
+module.exports = {
+ addShimToInterface: addShimToInterface,
+ throwDOMException: throwDOMException,
+ clone: clone,
+ recursivelyWalk: recursivelyWalk,
+ HTMLNames: HTMLNames
+};
+
+function recursivelyWalk(nodes, cb) {
+ for (var i = 0, len = nodes.length; i < len; i++) {
+ var node = nodes[i];
+ var ret = cb(node);
+ if (ret) {
+ return ret;
+ }
+ if (node.childNodes && node.childNodes.length) {
+ var ret = recursivelyWalk(node.childNodes, cb);
+ if (ret) {
+ return ret;
+ }
+ }
+ }
+}
+
+function throwDOMException(code) {
+ var ex = Object.create(DOMException.prototype);
+ ex.code = code;
+ throw ex;
+}
+
+function addShimToInterface(shim, proto, constructor) {
+ Object.keys(shim).forEach(function _eachShimProperty(name) {
+ if (name === "constants") {
+ var constants = shim[name];
+ Object.keys(constants).forEach(function _eachConstant(name) {
+ if (!hasOwnProperty.call(constructor, name)) {
+ constructor[name] = constants[name];
+ }
+ });
+ return;
+ }
+
+ if (!hasOwnProperty.call(proto, name)) {
+ var pd = shim[name];
+ if (pd.value) {
+ pd.writable = false;
+ } else {
+
+ }
+ pd.configurable = true;
+ pd.enumerable = false;
+ Object.defineProperty(proto, name, pd);
+ }
+ });
+}
+
+function clone(node, document, deep) {
+ document = document || node.ownerDocument;
+ var copy;
+ if (node.nodeType === Node.ELEMENT_NODE) {
+ var namespace = node.nodeName;
+ if (node.prefix) {
+ namespace = node.prefix + ":" + namespace;
+ }
+ copy = document.createElementNS(node.namespaceURI, namespace);
+ for (var i = 0, len = node.attributes.length; i < len; i++) {
+ var attr = node.attributes[i];
+ copy.setAttribute(attr.name, attr.value);
+ }
+ } else if (node.nodeType === Node.DOCUMENT_NODE) {
+ copy = document.implementation.createDocument("", "", null);
+ } else if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
+ copy = document.createDocumentFragment();
+ } else if (node.nodeType === Node.DOCUMENT_TYPE_NODE) {
+ copy = document.implementation.createDocumentType(node.name, node.publicId, node.systemId);
+ } else if (node.nodeType === Node.COMMENT_NODE) {
+ copy = document.createComment(node.data);
+ } else if (node.nodeType === Node.TEXT_NODE) {
+ copy = document.createTextNode(node.data);
+ } else if (node.nodeType === Node.PROCESSING_INSTRUCTION_NODE) {
+ copy = document.createProcessingInstruction(node.target, node.data);
+ }
+ // TODO: other cloning steps from other specifications
+ if (deep) {
+ var children = node.childNodes;
+ for (var i = 0, len = children.length; i < len; i++) {
+ copy.appendChild(children[i].cloneNode(node, document, deep));
+ }
+ }
+ return copy;
+}
+});
+M8.define('interfaces/DOMTokenList','all',function(require, module, exports){
+var utils = require("utils::index");
+
+var throwDOMException = utils.throwDOMException;
+
+module.exports = {
+ constructor: DOMTokenList,
+ item: item,
+ contains: contains,
+ add: add,
+ remove: remove,
+ toggle: toggle,
+ toString: _toString
+};
+
+module.exports.constructor.prototype = module.exports;
+
+function DOMTokenList(getter, setter) {
+ this._getString = getter;
+ this._setString = setter;
+ fixIndex(this, getter().split(" "));
+}
+
+function fixIndex(clist, list) {
+ for (var i = 0, len = list.length; i < len; i++) {
+ clist[i] = list[i];
+ }
+ delete clist[len];
+}
+
+function handleErrors(token) {
+ if (token === "" || token === undefined) {
+ throwDOMException(DOMException.SYNTAX_ERR);
+ }
+ // TODO: test real space chacters
+ if (token.indexOf(" ") > -1) {
+ throwDOMException(DOMException.INVALID_CHARACTER_ERR);
+ }
+}
+
+function getList(clist) {
+ var str = clist._getString();
+ if (str === "") {
+ return [];
+ } else {
+ return str.split(" ");
+ }
+}
+
+function item(index) {
+ if (index >= this.length) {
+ return null;
+ }
+ return this._getString().split(" ")[index];
+}
+
+function contains(token) {
+ handleErrors(token);
+ var list = getList(this);
+ return list.indexOf(token) > -1;
+}
+
+function add(token) {
+ handleErrors(token);
+ var list = getList(this);
+ if (list.indexOf(token) > -1) {
+ return;
+ }
+ list.push(token);
+ this._setString(list.join(" ").trim());
+ fixIndex(this, list);
+}
+
+function remove(token) {
+ handleErrors(token);
+ var list = getList(this);
+ var index = list.indexOf(token);
+ if (index > -1) {
+ list.splice(index, 1);
+ this._setString(list.join(" ").trim());
+ }
+ fixIndex(this, list);
+}
+
+function toggle(token) {
+ if (this.contains(token)) {
+ this.remove(token);
+ return false;
+ } else {
+ this.add(token);
+ return true;
+ }
+}
+
+function _toString() {
+ return this._getString();
+}
+});
+M8.define('interfaces/Element','all',function(require, module, exports){
+var DOMTokenList = require("all::interfaces/DOMTokenList").constructor;
+
+module.exports = {
+ parentElement: {
+ get: getParentElement
+ },
+ classList: {
+ get: getClassList
+ }
+}
+
+function getParentElement() {
+ var parent = this.parentNode;
+ if (parent == null) {
+ return null;
+ }
+ if (parent.nodeType === Node.ELEMENT_NODE) {
+ return parent;
+ }
+ return null;
+}
+
+function getClassList() {
+ var el = this;
+
+ if (this._classList) {
+ return this._classList;
+ } else {
+ var dtlist = new DOMTokenList(
+ function _getClassName() {
+ return el.className || "";
+ },
+ function _setClassName(v) {
+ el.className = v;
+ }
+ );
+ this._classList = dtlist;
+ return dtlist;
+ }
+}
+});
+M8.define('pd','utils',function(require, module, exports){
+!(function (exports) {
+ "use strict";
+
+ /*
+ pd will return all the own propertydescriptors of the object
+
+ @param Object obj - object to get pds from.
+
+ @return Object - A hash of key/propertyDescriptors
+ */
+ function pd(obj) {
+ var keys = Object.getOwnPropertyNames(obj);
+ var o = {};
+ keys.forEach(function _each(key) {
+ var pd = Object.getOwnPropertyDescriptor(obj, key);
+ o[key] = pd;
+ });
+ return o;
+ }
+
+ function operateOnThis(method) {
+ return function _onThis() {
+ var args = [].slice.call(arguments);
+ return method.apply(null, [this].concat(args));
+ }
+ }
+
+ /*
+ Will extend native objects with utility methods
+
+ @param Boolean prototypes - flag to indicate whether you want to extend
+ prototypes as well
+ */
+ function extendNatives(prototypes) {
+ prototypes === true && (prototypes = ["make", "beget", "extend"]);
+
+ if (!Object.getOwnPropertyDescriptors) {
+ Object.defineProperty(Object, "getOwnPropertyDescriptors", {
+ value: pd,
+ configurable: true
+ });
+ }
+ if (!Object.extend) {
+ Object.defineProperty(Object, "extend", {
+ value: pd.extend,
+ configurable: true
+ });
+ }
+ if (!Object.make) {
+ Object.defineProperty(Object, "make", {
+ value: pd.make,
+ configurable: true
+ });
+ }
+ if (!Object.beget) {
+ Object.defineProperty(Object, "beget", {
+ value: beget,
+ configurable: true
+ })
+ }
+ if (!Object.prototype.beget && prototypes.indexOf("beget") !== -1) {
+ Object.defineProperty(Object.prototype, "beget", {
+ value: operateOnThis(beget),
+ configurable: true
+ });
+ }
+ if (!Object.prototype.make && prototypes.indexOf("make") !== -1) {
+ Object.defineProperty(Object.prototype, "make", {
+ value: operateOnThis(make),
+ configurable: true
+ });
+ }
+ if (!Object.prototype.extend && prototypes.indexOf("extend") !== -1) {
+ Object.defineProperty(Object.prototype, "extend", {
+ value: operateOnThis(extend),
+ configurable: true
+ });
+ }
+ if (!Object.Name) {
+ Object.defineProperty(Object, "Name", {
+ value: Name,
+ configurable: true
+ });
+ }
+ return pd;
+ }
+
+ /*
+ Extend will extend the firat parameter with any other parameters
+ passed in. Only the own property names will be extended into
+ the object
+
+ @param Object target - target to be extended
+ @arguments Array [target, ...] - the rest of the objects passed
+ in will extended into the target
+
+ @return Object - the target
+ */
+ function extend(target) {
+ var objs = Array.prototype.slice.call(arguments, 1);
+ objs.forEach(function (obj) {
+ var props = Object.getOwnPropertyNames(obj);
+ props.forEach(function (key) {
+ target[key] = obj[key];
+ });
+ });
+ return target;
+ }
+
+ /*
+ beget will generate a new object from the proto, any other arguments
+ will be passed to proto.constructor
+
+ @param Object proto - the prototype to use for the new object
+ @arguments Array [proto, ...] - the rest of the arguments will
+ be passed into proto.constructor
+
+ @return Object - the newly created object
+ */
+ function beget(proto) {
+ var o = Object.create(proto);
+ var args = Array.prototype.slice.call(arguments, 1);
+ proto.constructor && proto.constructor.apply(o, args);
+ return o;
+ }
+
+ /*
+ make will call Object.create with the proto and pd(props)
+
+ @param Object proto - the prototype to inherit from
+ @arguments Array [proto, ...] - the rest of the arguments will
+ be mixed into the object, i.e. the object will be extend
+ with the objects
+
+ @return Object - the new object
+ */
+ function make (proto) {
+ var o = Object.create(proto);
+ var args = [].slice.call(arguments, 1);
+ args.unshift(o);
+ extend.apply(null, args);
+ return o;
+ }
+
+ /*
+ defines a namespace object. This hides a "privates" object on object
+ under the "key" namespace
+
+ @param Object object - object to hide a privates object on
+ @param Object namespace - key to hide it under
+
+ @author Gozala : https://gist.github.com/1269991
+
+ @return Object privates
+ */
+ function defineNamespace(object, namespace) {
+ var privates = Object.create(object),
+ base = object.valueOf;
+
+ Object.defineProperty(object, 'valueOf', {
+ value: function valueOf(value) {
+ if (value !== namespace || this !== object) {
+ return base.apply(this, arguments);
+ } else {
+ return privates;
+ }
+ }
+ });
+
+ return privates;
+ }
+
+ /*
+ Constructs a Name function, when given an object it will return a
+ privates object.
+
+ @author Gozala : https://gist.github.com/1269991
+
+ @return Function name
+ */
+ function Name() {
+ var namespace = {};
+
+ return function name(object) {
+ var privates = object.valueOf(namespace);
+ if (privates !== object) {
+ return privates;
+ } else {
+ return defineNamespace(object, namespace);
+ }
+ };
+ }
+
+ var Base = {
+ extend: operateOnThis(extend),
+ make: operateOnThis(make),
+ beget: operateOnThis(beget)
+ }
+
+ extend(pd, {
+ make: make,
+ extend: extend,
+ beget: beget,
+ extendNatives: extendNatives,
+ Name: Name,
+ Base: Base
+ });
+
+ exports(pd);
+
+})(function (data) {
+ if (typeof module !== "undefined") {
+ module.exports = data;
+ } else {
+ window.pd = data;
+ }
+});
+});
+M8.define('interfaces/Node','all',function(require, module, exports){
+module.exports = {
+ contains: {
+ value: contains
+ },
+ interface: window.Element
+}
+
+function contains(other) {
+ var comparison = this.compareDocumentPosition(other);
+ if (comparison === 0 ||
+ comparison & Node.DOCUMENT_POSITION_CONTAINED_BY
+ ) {
+ return true;
+ }
+ return false;
+}
+});
+M8.define('interfaces/Event','all',function(require, module, exports){
+module.exports = {
+ constructor: constructor
+};
+
+function constructor(type, dict) {
+ var e = document.createEvent("Events");
+ dict = dict || {};
+ dict.bubbles = dict.bubbles || false;
+ dict.catchable = dict.catchable || false;
+ e.initEvent(type, dict.bubbles, dict.catchable);
+ return e;
+}
+});
+M8.define('dataManager','utils',function(require, module, exports){
+var uuid = 0,
+ domShimString = "__domShim__";
+
+var dataManager = {
+ _stores: {},
+ getStore: function _getStore(el) {
+ var id = el[domShimString ];
+ if (id === undefined) {
+ return this._createStore(el);
+ }
+ return this._stores[domShimString + id];
+ },
+ _createStore: function _createStore(el) {
+ var store = {};
+ this._stores[domShimString + uuid] = store;
+ el[domShimString ] = uuid;
+ uuid++;
+ return store;
+ }
+};
+
+module.exports = dataManager;
+
+
+});
+M8.define('interfaces/Event','shims',function(require, module, exports){
+var pd = require("utils::pd"),
+ Event = require("all::interfaces/Event");
+
+module.exports = pd.extend(Event, {
+ constants: {
+ CAPTURING_PHASE: 1,
+ AT_TARGET: 2,
+ BUBBLING_PHASE: 3
+ },
+ initEvent: {
+ value: initEvent
+ }
+});
+
+function initEvent(type, bubbles, cancelable) {
+ this.type = type;
+ this.isTrusted = false;
+ this.target = null;
+ this.bubbles = bubbles;
+ this.cancelable = cancelable;
+}
+});
+M8.define('interfaces/DOMException','shims',function(require, module, exports){
+module.exports = {
+ constants: {
+ INDEX_SIZE_ERR: 1,
+ DOMSTRING_SIZE_ERR: 2, // historical
+ HIERARCHY_REQUEST_ERR: 3,
+ WRONG_DOCUMENT_ERR: 4,
+ INVALID_CHARACTER_ERR: 5,
+ NO_DATA_ALLOWED_ERR: 6, // historical
+ NO_MODIFICATION_ALLOWED_ERR: 7,
+ NOT_FOUND_ERR: 8,
+ NOT_SUPPORTED_ERR: 9,
+ INUSE_ATTRIBUTE_ERR: 10, // historical
+ INVALID_STATE_ERR: 11,
+ SYNTAX_ERR: 12,
+ INVALID_MODIFICATION_ERR: 13,
+ NAMESPACE_ERR: 14,
+ INVALID_ACCESS_ERR: 15,
+ VALIDATION_ERR: 16, // historical
+ TYPE_MISMATCH_ERR: 17,
+ SECURITY_ERR: 18,
+ NETWORK_ERR: 19,
+ ABORT_ERR: 20,
+ URL_MISMATCH_ERR: 21,
+ QUOTA_EXCEEDED_ERR: 22,
+ TIMEOUT_ERR: 23,
+ INVALID_NODE_TYPE_ERR: 24,
+ DATA_CLONE_ERR: 25
+ },
+ interface: function () { },
+ prototype: {}
+}
+});
+M8.define('interfaces/DOMImplementation','shims',function(require, module, exports){
+module.exports = {
+ createDocumentType: {
+ value: createDocumentType
+ }
+};
+
+function createDocumentType(qualifiedName, publicId, systemId) {
+ var o = {};
+ o.name = qualifiedName;
+ o.publicId = publicId;
+ o.systemId = systemId;
+ o.ownerDocument = document;
+ o.nodeType = Node.DOCUMENT_TYPE_NODE;
+ o.nodeName = qualifiedName;
+ return o;
+}
+});
+M8.define('interfaces/Element','shims',function(require, module, exports){
+var Element = require("all::interfaces/Element"),
+ recursivelyWalk = require("utils::index").recursivelyWalk,
+ pd = require("utils::pd");
+
+module.exports = pd.extend(Element, {
+ getElementsByClassName: {
+ value: getElementsByClassName
+ },
+ childElementCount: {
+ get: getChildElementCount
+ },
+ firstElementChild: {
+ get: getFirstElementChild
+ },
+ lastElementChild: {
+ get: getLastElementChild
+ },
+ nextElementSibling: {
+ get: getNextElementSibling
+ },
+ previousElementSibling: {
+ get: getPreviousElementSibling
+ }
+});
+
+function getChildElementCount() {
+ return this.children.length;
+}
+
+function getFirstElementChild() {
+ var nodes = this.childNodes;
+ for (var i = 0, len = nodes.length; i < len; i++) {
+ var node = nodes[i];
+ if (node.nodeType === Node.ELEMENT_NODE) {
+ return node;
+ }
+ }
+ return null;
+}
+
+function getLastElementChild() {
+ var nodes = this.childNodes;
+ for (var i = nodes.length - 1; i >= 0; i--) {
+ var node = nodes[i];
+ if (node.nodeType === Node.ELEMENT_NODE) {
+ return node;
+ }
+ }
+ return null;
+}
+
+function getNextElementSibling() {
+ var el = this;
+ do {
+ var el = el.nextSibling;
+ if (el && el.nodeType === Node.ELEMENT_NODE) {
+ return el;
+ }
+ } while (el !== null);
+
+ return null;
+}
+
+function getPreviousElementSibling() {
+ var el = this;
+ do {
+ el = el.previousSibling;
+ if (el && el.nodeType === Node.ELEMENT_NODE) {
+ return el;
+ }
+ } while (el !== null);
+
+ return null;
+}
+
+
+// TODO: use real algorithm
+function getElementsByClassName(clas) {
+ var ar = [];
+ recursivelyWalk(this.childNodes, function (el) {
+ if (el.classList && el.classList.contains(clas)) {
+ ar.push(el);
+ }
+ });
+ return ar;
+};
+});
+M8.define('bugs','all',function(require, module, exports){
+var utils = require("utils::index");
+
+module.exports = run;
+
+function run() {
+
+// IE9 thinks the argument is not optional
+// FF thinks the argument is not optional
+// Opera agress that its not optional
+(function () {
+ var e = document.createElement("div");
+ try {
+ document.importNode(e);
+ } catch (e) {
+ var importNode = document.importNode;
+ delete document.importNode;
+ document.importNode = function _importNode(node, bool) {
+ if (bool === undefined) {
+ bool = true;
+ }
+ return importNode.call(this, node, bool);
+ }
+ }
+})();
+
+// Firefox fails on .cloneNode thinking argument is not optional
+// Opera agress that its not optional.
+(function () {
+ var el = document.createElement("p");
+
+ try {
+ el.cloneNode();
+ } catch (e) {
+ [
+ Node.prototype,
+ Comment.prototype,
+ Element.prototype,
+ ProcessingInstruction.prototype,
+ Document.prototype,
+ DocumentType.prototype,
+ DocumentFragment.prototype
+ ].forEach(fixNodeOnProto);
+
+ utils.HTMLNames.forEach(forAllHTMLInterfaces)
+ }
+
+ function forAllHTMLInterfaces(name) {
+ window[name] && fixNodeOnProto(window[name].prototype);
+ }
+
+ function fixNodeOnProto(proto) {
+ var cloneNode = proto.cloneNode;
+ delete proto.cloneNode;
+ proto.cloneNode = function _cloneNode(bool) {
+ if (bool === undefined) {
+ bool = true;
+ }
+ return cloneNode.call(this, bool);
+ };
+ }
+})();
+
+// Opera is funny about the "optional" parameter on addEventListener
+(function () {
+ var count = 0;
+ var handler = function () {
+ count++;
+ }
+ document.addEventListener("click", handler);
+ var ev = new Event("click");
+ document.dispatchEvent(ev);
+ if (count === 0) {
+ // fix opera
+ var oldListener = EventTarget.prototype.addEventListener;
+ EventTarget.prototype.addEventListener = function (ev, cb, optional) {
+ optional = optional || false;
+ return oldListener.call(this, ev, cb, optional);
+ };
+ // fix removeEventListener aswell
+ var oldRemover = EventTarget.prototype.removeEventListener;
+ EventTarget.prototype.removeEventListener = function (ev, cb, optional) {
+ optional = optional || false;
+ return oldRemover.call(this, ev, cb, optional);
+ };
+ // punch window.
+ window.addEventListener = EventTarget.prototype.addEventListener;
+ window.removeEventListener = EventTarget.prototype.removeEventListener;
+ }
+ document.removeEventListener("click", handler);
+})();
+
+}
+});
+M8.define('interfaces/Document','shims',function(require, module, exports){
+var throwDOMException = require("utils::index").throwDOMException,
+ recursivelyWalk = require("utils::index").recursivelyWalk,
+ clone = require("utils::index").clone;
+
+module.exports = {
+ adoptNode: {
+ value: adoptNode
+ },
+ createElementNS: {
+ value: createElementNS
+ },
+ createEvent: {
+ value: createEvent
+ },
+ doctype: {
+ get: getDocType
+ },
+ importNode: {
+ value: importNode
+ },
+ interface: function () { },
+ prototype: document
+};
+
+function createEvent(interface) {
+ if (this.createEventObject) {
+ return this.createEventObject();
+ }
+}
+
+function importNode(node, deep) {
+ if (node.nodeType === Node.DOCUMENT_NODE) {
+ throwDOMException(DOMException.NOT_SUPPORTED_ERR);
+ }
+ if (deep === undefined) {
+ deep = true;
+ }
+ return clone(node, this, deep);
+}
+
+function getDocType() {
+ var docType = this.childNodes[0];
+ // TODO: remove assumption that DOCTYPE is the first node
+ Object.defineProperty(docType, "nodeType", {
+ get: function () { return Node.DOCUMENT_TYPE_NODE; }
+ });
+ return docType;
+}
+
+function createElementNS(namespace, name) {
+ var prefix, localName;
+
+ if (namespace === "") {
+ namespace = null;
+ }
+ // TODO: check the Name production
+ // TODO: check the QName production
+ if (name.indexOf(":") > -1) {
+ var split = name.split(":");
+ prefix = split[0];
+ localName = split[1];
+ } else {
+ prefix = null;
+ localName = name;
+ }
+ if (prefix === "" || prefix === "undefined") {
+ prefix = null;
+ }
+ if ((prefix !== null && namespace === null) ||
+ (
+ prefix === "xml" &&
+ namespace !== "http://www.w3.org/XML/1998/namespace"
+ ) ||
+ (
+ (name === "xmlns" || prefix === "xmlns") &&
+ namespace !== "http://www.w3.org/2000/xmlns/"
+ ) ||
+ (
+ namespace === "http://www.w3.org/2000/xmlns/" &&
+ (name !== "xmlns" && prefix !== "xmlns")
+ )
+ ) {
+ throwDOMException(DOMException.NAMESPACE_ERR);
+ }
+ var el = this.createElement(localName);
+ el.namespaceURI = namespace;
+ el.prefix = prefix;
+ return el;
+}
+
+function adopt(node, doc) {
+ if (node.nodeType === Node.ELEMENT_NODE) {
+ // TODO: base URL change
+ }
+ if (node.parentNode !== null) {
+ node.parentNode.removeChild(node);
+ }
+ recursivelyWalk([node], function (node) {
+ node.ownerDocument = doc;
+ });
+}
+
+function adoptNode(node) {
+ if (node.nodeType === Node.DOCUMENT_NODE) {
+ throwDOMException(DOMException.NOT_SUPPORTED_ERR);
+ }
+ adopt(node, this);
+ return node;
+}
+});
+M8.define('interfaces/EventTarget','shims',function(require, module, exports){
+var dataManager = require("utils::dataManager"),
+ throwDOMException = require("utils::index").throwDOMException,
+ push = [].push;
+
+module.exports = {
+ addEventListener: {
+ value: addEventListener
+ },
+ dispatchEvent: {
+ value: dispatchEvent
+ },
+ removeEventListener: {
+ value: removeEventListener
+ },
+ interface: window.Element
+};
+
+function addEventListener(type, listener, capture) {
+ if (listener === null) return;
+
+ var that = this;
+
+ capture = capture || false;
+
+ var store = dataManager.getStore(this);
+
+ var eventsString;
+ if (capture) {
+ eventsString = "captureEvents";
+ } else {
+ eventsString = "bubbleEvents";
+ }
+
+ if (!store[eventsString]) {
+ store[eventsString] = {};
+ }
+
+ var events = store[eventsString];
+
+ if (!events[type]) {
+ events[type] = {};
+ events[type].listeners = [];
+ }
+
+ var typeObject = events[type];
+
+ var listenerArray = typeObject.listeners;
+ if (listenerArray.indexOf(listener) === -1) {
+ listenerArray.push(listener);
+ } else {
+ return;
+ }
+
+ if (this.attachEvent) {
+ try {
+ this.attachEvent("on" + type, handler);
+
+ if (!typeObject.ieHandlers) {
+ typeObject.ieHandlers = [];
+ }
+
+ var index = listenerArray.length - 1;
+
+ typeObject.ieHandlers[index] = handler;
+
+ } catch (e) {
+ /* don't care. can't attach so can't be fired */
+ }
+ }
+
+ function handler() {
+ var ev = document.createEvent("event");
+ ev.initEvent(type, true, true);
+ that.dispatchEvent(ev);
+ }
+}
+
+function removeEventListener(type, listener, capture) {
+ capture = capture || false;
+
+ var store = dataManager.getStore(this);
+
+ var eventsString;
+ if (capture) {
+ eventsString = "captureEvents";
+ } else {
+ eventsString = "bubbleEvents";
+ }
+
+ var events = store[eventsString];
+
+ if (!events) return;
+
+ var typeObject = events[type];
+
+ if (!typeObject) return;
+
+ var listenerArray = typeObject.listeners;
+
+ var index = listenerArray.indexOf(listener);
+ listenerArray.splice(index, 1);
+
+ if (this.detachEvent) {
+ try {
+ var ieHandlers = typeObject.ieHandlers;
+
+ var handler = ieHandlers[index];
+
+ this.detachEvent("on" + type, handler);
+
+ ieHandlers.splice(index, 1);
+ } catch (e) {
+ /* don't care. Can't detach what hasn't been attached */
+ }
+
+ }
+}
+
+function dispatchEvent(event) {
+ if (event._dispatch === true || event._initialized === true) {
+ throwDOMException(DOMException.INVALID_STATE_ERR);
+ }
+
+ event.isTrusted = false;
+
+ dispatch(this, event);
+}
+
+function dispatch(elem, event) {
+ var invokeListenerForEvent = invokeListeners.bind(null, event);
+
+ event._dispatch = true;
+
+ event.target = elem;
+
+ if (elem.parentNode) {
+ var eventPath = [];
+ var parent = elem.parentNode;
+ while (parent) {
+ eventPath.unshift(parent);
+ parent = parent.parentNode;
+ }
+
+ event.eventPhase = Event.CAPTURING_PHASE;
+
+ eventPath.forEach(invokeListenerForEvent);
+
+ event.eventPhase = Event.AT_TARGET;
+
+ invokeListenerForEvent(event.target);
+
+ if (event.bubbles) {
+ eventPath = eventPath.reverse();
+ event.eventPhase = Event.BUBBLING_PHASE;
+ eventPath.forEach(invokeListenerForEvent);
+ }
+ } else {
+ invokeListenerForEvent(event.target);
+ }
+
+ event._dispatch = false;
+
+ event.eventPhase = Event.AT_TARGET;
+
+ event.currentTarget = null;
+
+ return !event._canceled;
+}
+
+function invokeListeners(event, elem) {
+ var store = dataManager.getStore(elem);
+
+ event.currentTarget = elem;
+
+ var listeners = [];
+ if (event.eventPhase !== Event.CAPTURING_PHASE) {
+ var events = store["bubbleEvents"];
+ if (events) {
+ var typeObject = events[event.type];
+
+ if (typeObject) {
+ var listenerArray = typeObject.listeners
+
+ push.apply(listeners, listenerArray);
+ }
+ }
+ }
+ if (event.eventPhase !== Event.BUBBLING_PHASE) {
+ var events = store["captureEvents"];
+ if (events) {
+ var typeObject = events[event.type];
+
+ if (typeObject) {
+ var listenerArray = typeObject.listeners
+
+ push.apply(listeners, listenerArray);
+ }
+ }
+ }
+
+ listeners.some(invokeListener);
+
+ function invokeListener(listener) {
+ if (event._stopImmediatePropagation) {
+ return true;
+ }
+ // DOM4 ED says currentTarget, DOM4 WD says target
+ listener.call(event.currentTarget, event);
+ }
+}
+});
+M8.define('interfaces/CustomEvent','all',function(require, module, exports){
+module.exports = {
+ constructor: constructor,
+ interface: window.Event
+};
+
+function constructor(type, dict) {
+ var e = document.createEvent("CustomEvent");
+ dict = dict || {};
+ dict.detail = dict.detail || null;
+ dict.bubbles = dict.bubbles || false;
+ dict.catchable = dict.catchable || false;
+ if (e.initCustomEvent) {
+ e.initCustomEvent(type, dict.bubbles, dict.catchable, dict.detail);
+ } else {
+ e.initEvent(type, dict.bubbles, dict.catchable);
+ e.detail = dict.detail;
+ }
+ return e;
+}
+});
+M8.define('interfaces/Node','shims',function(require, module, exports){
+var nodeShim = require("all::interfaces/Node"),
+ recursivelyWalk = require("utils::index").recursivelyWalk,
+ pd = require("utils::pd");
+
+module.exports = pd.extend(nodeShim, {
+ constants: {
+ "ELEMENT_NODE": 1,
+ "ATTRIBUTE_NODE": 2,
+ "TEXT_NODE": 3,
+ "CDATA_SECTION_NODE": 4,
+ "ENTITY_REFERENCE_NODE": 5,
+ "ENTITY_NODE": 6,
+ "PROCESSING_INSTRUCTION_NODE": 7,
+ "COMMENT_NODE": 8,
+ "DOCUMENT_NODE": 9,
+ "DOCUMENT_TYPE_NODE": 10,
+ "DOCUMENT_FRAGMENT_NODE": 11,
+ "NOTATION_NODE": 12,
+ "DOCUMENT_POSITION_DISCONNECTED": 0x01,
+ "DOCUMENT_POSITION_PRECEDING": 0x02,
+ "DOCUMENT_POSITION_FOLLOWING": 0x04,
+ "DOCUMENT_POSITION_CONTAINS": 0x08,
+ "DOCUMENT_POSITION_CONTAINED_BY": 0x10,
+ "DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC": 0x20
+ },
+ contains: {
+ value: contains
+ },
+ compareDocumentPosition: {
+ value: compareDocumentPosition
+ },
+ isEqualNode: {
+ value: isEqualNode
+ },
+ textContent: {
+ get: getTextContent,
+ set: setTextContent
+ }
+});
+
+function contains(other) {
+ return recursivelyWalk(this.childNodes, function (node) {
+ if (node === other) return true;
+ }) || false;
+}
+
+function isEqualNode(node) {
+ if (node === null) {
+ return false;
+ }
+ if (node.nodeType !== this.nodeType) {
+ return false;
+ }
+ if (node.nodeType === Node.DOCUMENT_TYPE_NODE) {
+ if (this.name !== node.name ||
+ this.publicId !== node.publicId ||
+ this.systemId !== node.systemId
+ ) {
+ return false;
+ }
+ }
+ if (node.nodeType === Node.ELEMENT_NODE) {
+ if (this.namespaceURI != node.namespaceURI ||
+ this.prefix != node.prefix ||
+ this.localName != node.localName
+ ) {
+ return false;
+ }
+ for (var i = 0, len = this.attributes.length; i < len; i++) {
+ var attr = this.attributes[length];
+ var nodeAttr = node.getAttributeNS(attr.namespaceURI, attr.localName);
+ if (nodeAttr === null || nodeAttr.value !== attr.value) {
+ return false;
+ }
+ }
+ }
+ if (node.nodeType === Node.PROCESSING_INSTRUCTION_NODE) {
+ if (this.target !== node.target || this.data !== node.data) {
+ return false;
+ }
+ }
+ if (node.nodeType === Node.TEXT_NODE || node.nodeType === Node.COMMENT_NODE) {
+ if (this.data !== node.data) {
+ return false;
+ }
+ }
+ if (node.childNodes.length !== this.childNodes.length) {
+ return false;
+ }
+ for (var i = 0, len = node.childNodes.length; i < len; i++) {
+ var isEqual = node.childNodes[i].isEqualNode(this.childNodes[i]);
+ if (isEqual === false) {
+ return false;
+ }
+ }
+ return true;
+}
+
+function getTextContent() {
+ if ('innerText' in this) {
+ return this.innerText;
+ }
+ if ('data' in this && this.appendData) {
+ return this.data;
+ }
+}
+
+function setTextContent(value) {
+ if ('innerText' in this) {
+ this.innerText = value;
+ return;
+ }
+ if ('data' in this && this.replaceData) {
+ this.replaceData(0, this.length, value);
+ return;
+ }
+}
+
+function testNodeForComparePosition(node, other) {
+ if (node === other) {
+ return true;
+ }
+}
+
+function compareDocumentPosition(other) {
+ function identifyWhichIsFirst(node) {
+ if (node === other) {
+ return "other";
+ } else if (node === reference) {
+ return "reference";
+ }
+ }
+
+ var reference = this,
+ referenceTop = this,
+ otherTop = other;
+
+ if (this === other) {
+ return 0;
+ }
+ while (referenceTop.parentNode) {
+ referenceTop = referenceTop.parentNode;
+ }
+ while (otherTop.parentNode) {
+ otherTop = otherTop.parentNode;
+ }
+
+ if (referenceTop !== otherTop) {
+ return Node.DOCUMENT_POSITION_DISCONNECTED;
+ }
+
+ var children = reference.childNodes;
+ var ret = recursivelyWalk(
+ children,
+ testNodeForComparePosition.bind(null, other)
+ );
+ if (ret) {
+ return Node.DOCUMENT_POSITION_CONTAINED_BY +
+ Node.DOCUMENT_POSITION_FOLLOWING;
+ }
+
+ var children = other.childNodes;
+ var ret = recursivelyWalk(
+ children,
+ testNodeForComparePosition.bind(null, reference)
+ );
+ if (ret) {
+ return Node.DOCUMENT_POSITION_CONTAINS +
+ Node.DOCUMENT_POSITION_PRECEDING;
+ }
+
+ var ret = recursivelyWalk(
+ [referenceTop],
+ identifyWhichIsFirst
+ );
+ if (ret === "other") {
+ return Node.DOCUMENT_POSITION_PRECEDING;
+ } else {
+ return Node.DOCUMENT_POSITION_FOLLOWING;
+ }
+}
+});
+M8.define('interfaces/index','shims',function(require, module, exports){
+module.exports = {
+ CustomEvent: require("all::interfaces/CustomEvent"),
+ DOMException: require("shims::interfaces/DOMException"),
+ DOMImplementation: require("shims::interfaces/DOMImplementation"),
+ Element: require("shims::interfaces/Element"),
+ Event: require("shims::interfaces/Event"),
+ Document: require("shims::interfaces/Document"),
+ EventTarget: require("shims::interfaces/EventTarget"),
+ Node: require("shims::interfaces/Node")
+};
+});
+M8.define('bugs','shims',function(require, module, exports){
+var utils = require("utils::index"),
+ documentShim = require("shims::interfaces/Document"),
+ nodeShim = require("shims::interfaces/Node"),
+ elementShim = require("shims::interfaces/Element"),
+ eventTargetShim = require("shims::interfaces/EventTarget");
+
+module.exports = run;
+
+function run() {
+
+// IE8 Document does not inherit EventTarget
+(function () {
+ if (!document.addEventListener) {
+ utils.addShimToInterface(eventTargetShim, document);
+ }
+})();
+
+// IE8 window.addEventListener does not exist
+(function () {
+ if (!window.addEventListener) {
+ window.addEventListener = document.addEventListener.bind(document);
+ }
+ if (!window.removeEventListener) {
+ window.removeEventListener = document.removeEventListener.bind(document);
+ }
+ if (!window.dispatchEvent) {
+ window.dispatchEvent = document.dispatchEvent.bind(document);
+ }
+})();
+
+
+// IE8 hurr durr doctype is null
+(function () {
+ if (document.doctype === null) {
+ Object.defineProperty(document, "doctype", documentShim.doctype);
+ }
+})();
+
+// IE8 hates you and your f*ing text nodes
+// I mean text node and document fragment and document no inherit from node
+(function () {
+ if (!document.createTextNode().contains) {
+ utils.addShimToInterface(nodeShim, Text.prototype, Text);
+ }
+
+ if (!document.createDocumentFragment().contains) {
+ utils.addShimToInterface(nodeShim, HTMLDocument.prototype, HTMLDocument);
+ }
+
+ if (!document.getElementsByClassName) {
+ document.getElementsByClassName = elementShim.getElementsByClassName.value;
+ }
+})();
+
+// IE8 can't write to ownerDocument
+(function () {
+ var el = document.createElement("div");
+ try {
+ el.ownerDocument = 42;
+ } catch (e) {
+ var pd = Object.getOwnPropertyDescriptor(Element.prototype, "ownerDocument");
+ var ownerDocument = pd.get;
+ Object.defineProperty(Element.prototype, "ownerDocument", {
+ get: function () {
+ if (this._ownerDocument) {
+ return this._ownerDocument;
+ } else {
+ return ownerDocument.call(this);
+ }
+ },
+ set: function (v) {
+ this._ownerDocument = v;
+ },
+ configurable: true
+ });
+ }
+})();
+
+// IE - contains fails if argument is textnode
+(function () {
+ var txt = document.createTextNode("temp"),
+ el = document.createElement("p");
+
+ el.appendChild(txt);
+
+ try {
+ el.contains(txt);
+ } catch (e) {
+ // The contains method fails on text nodes in IE8
+ // swap the contains method for our contains method
+ Node.prototype.contains = nodeShim.contains.value;
+ }
+})();
+
+require("all::bugs")();
+
+}
+});
+
+// app code - safety wrap
+
+
+(function(){
+M8.define('utils/index','app',function(require, module, exports){
+var hasOwnProperty = Object.prototype.hasOwnProperty;
+
+
+var HTMLNames = [
+ "HTMLDocument", "HTMLLinkElement", "HTMLElement", "HTMLHtmlElement",
+ "HTMLDivElement", "HTMLAnchorElement", "HTMLSelectElement",
+ "HTMLOptionElement", "HTMLInputElement", "HTMLHeadElement",
+ "HTMLSpanElement", "XULElement", "HTMLBodyElement", "HTMLTableElement",
+ "HTMLTableCellElement", "HTMLTextAreaElement", "HTMLScriptElement",
+ "HTMLAudioElement", "HTMLMediaElement", "HTMLParagraphElement",
+ "HTMLButtonElement", "HTMLLIElement", "HTMLUListElement",
+ "HTMLFormElement", "HTMLHeadingElement", "HTMLImageElement",
+ "HTMLStyleElement", "HTMLTableRowElement", "HTMLTableSectionElement",
+ "HTMLBRElement"
+];
+
+module.exports = {
+ addShimToInterface: addShimToInterface,
+ throwDOMException: throwDOMException,
+ clone: clone,
+ recursivelyWalk: recursivelyWalk,
+ HTMLNames: HTMLNames
+};
+
+function recursivelyWalk(nodes, cb) {
+ for (var i = 0, len = nodes.length; i < len; i++) {
+ var node = nodes[i];
+ var ret = cb(node);
+ if (ret) {
+ return ret;
+ }
+ if (node.childNodes && node.childNodes.length) {
+ var ret = recursivelyWalk(node.childNodes, cb);
+ if (ret) {
+ return ret;
+ }
+ }
+ }
+}
+
+function throwDOMException(code) {
+ var ex = Object.create(DOMException.prototype);
+ ex.code = code;
+ throw ex;
+}
+
+function addShimToInterface(shim, proto, constructor) {
+ Object.keys(shim).forEach(function _eachShimProperty(name) {
+ if (name === "constants") {
+ var constants = shim[name];
+ Object.keys(constants).forEach(function _eachConstant(name) {
+ if (!hasOwnProperty.call(constructor, name)) {
+ constructor[name] = constants[name];
+ }
+ });
+ return;
+ }
+
+ if (!hasOwnProperty.call(proto, name)) {
+ var pd = shim[name];
+ if (pd.value) {
+ pd.writable = false;
+ } else {
+
+ }
+ pd.configurable = true;
+ pd.enumerable = false;
+ Object.defineProperty(proto, name, pd);
+ }
+ });
+}
+
+function clone(node, document, deep) {
+ document = document || node.ownerDocument;
+ var copy;
+ if (node.nodeType === Node.ELEMENT_NODE) {
+ var namespace = node.nodeName;
+ if (node.prefix) {
+ namespace = node.prefix + ":" + namespace;
+ }
+ copy = document.createElementNS(node.namespaceURI, namespace);
+ for (var i = 0, len = node.attributes.length; i < len; i++) {
+ var attr = node.attributes[i];
+ copy.setAttribute(attr.name, attr.value);
+ }
+ } else if (node.nodeType === Node.DOCUMENT_NODE) {
+ copy = document.implementation.createDocument("", "", null);
+ } else if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
+ copy = document.createDocumentFragment();
+ } else if (node.nodeType === Node.DOCUMENT_TYPE_NODE) {
+ copy = document.implementation.createDocumentType(node.name, node.publicId, node.systemId);
+ } else if (node.nodeType === Node.COMMENT_NODE) {
+ copy = document.createComment(node.data);
+ } else if (node.nodeType === Node.TEXT_NODE) {
+ copy = document.createTextNode(node.data);
+ } else if (node.nodeType === Node.PROCESSING_INSTRUCTION_NODE) {
+ copy = document.createProcessingInstruction(node.target, node.data);
+ }
+ // TODO: other cloning steps from other specifications
+ if (deep) {
+ var children = node.childNodes;
+ for (var i = 0, len = children.length; i < len; i++) {
+ copy.appendChild(children[i].cloneNode(node, document, deep));
+ }
+ }
+ return copy;
+}
+});
+M8.define('main','app',function(require, module, exports){
+var shims = require("shims::interfaces"),
+ utils = require("utils");
+
+Object.keys(shims).forEach(function _eachShim(name) {
+ var shim = shims[name];
+ var constructor = window[name];
+ if (!constructor) {
+ constructor = window[name] = shim.interface;
+ }
+ delete shim.interface;
+ var proto = constructor.prototype;
+ if (shim.prototype) {
+ proto = constructor.prototype = shim.prototype;
+ delete shim.prototype;
+ }
+
+ console.log("adding interface ", name);
+
+ if (shim.hasOwnProperty("constructor")) {
+ window[name] = constructor = shim.constructor;
+ shim.constructor.prototype = proto;
+ delete shim.constructor;
+ }
+
+ utils.addShimToInterface(shim, proto, constructor);
+});
+
+require("shims::bugs")();
+});
+})();
+})();
\ No newline at end of file
diff --git a/examples/resource/polyfill.js b/examples/resource/polyfill.js
new file mode 100644
index 00000000..350699dd
--- /dev/null
+++ b/examples/resource/polyfill.js
@@ -0,0 +1,1210 @@
+//----------------------------------------------------------------------
+//
+// ECMAScript 5 Polyfills
+//
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+// ES5 15.2 Object Objects
+//----------------------------------------------------------------------
+
+//
+// ES5 15.2.3 Properties of the Object Constructor
+//
+
+// ES5 15.2.3.2 Object.getPrototypeOf ( O )
+// From http://ejohn.org/blog/objectgetprototypeof/
+// NOTE: won't work for typical function T() {}; T.prototype = {}; new T; case
+// since the constructor property is destroyed.
+if (!Object.getPrototypeOf) {
+ Object.getPrototypeOf = function (o) {
+ if (o !== Object(o)) { throw new TypeError("Object.getPrototypeOf called on non-object"); }
+ return o.__proto__ || o.constructor.prototype || Object.prototype;
+ };
+}
+
+// // ES5 15.2.3.3 Object.getOwnPropertyDescriptor ( O, P )
+// if (typeof Object.getOwnPropertyDescriptor !== "function") {
+// Object.getOwnPropertyDescriptor = function (o, name) {
+// if (o !== Object(o)) { throw new TypeError(); }
+// if (o.hasOwnProperty(name)) {
+// return {
+// value: o[name],
+// enumerable: true,
+// writable: true,
+// configurable: true
+// };
+// }
+// };
+// }
+
+// ES5 15.2.3.4 Object.getOwnPropertyNames ( O )
+if (typeof Object.getOwnPropertyNames !== "function") {
+ Object.getOwnPropertyNames = function (o) {
+ if (o !== Object(o)) { throw new TypeError("Object.getOwnPropertyNames called on non-object"); }
+ var props = [], p;
+ for (p in o) {
+ if (Object.prototype.hasOwnProperty.call(o, p)) {
+ props.push(p);
+ }
+ }
+ return props;
+ };
+}
+
+// ES5 15.2.3.5 Object.create ( O [, Properties] )
+if (typeof Object.create !== "function") {
+ Object.create = function (prototype, properties) {
+ "use strict";
+ if (typeof prototype !== "object") { throw new TypeError(); }
+ /** @constructor */
+ function Ctor() {}
+ Ctor.prototype = prototype;
+ var o = new Ctor();
+ if (prototype) { o.constructor = Ctor; }
+ if (arguments.length > 1) {
+ if (properties !== Object(properties)) { throw new TypeError(); }
+ Object.defineProperties(o, properties);
+ }
+ return o;
+ };
+}
+
+// ES 15.2.3.6 Object.defineProperty ( O, P, Attributes )
+// Partial support for most common case - getters, setters, and values
+(function() {
+ if (!Object.defineProperty ||
+ !(function () { try { Object.defineProperty({}, 'x', {}); return true; } catch (e) { return false; } } ())) {
+ var orig = Object.defineProperty;
+ Object.defineProperty = function (o, prop, desc) {
+ "use strict";
+
+ // In IE8 try built-in implementation for defining properties on DOM prototypes.
+ if (orig) { try { return orig(o, prop, desc); } catch (e) {} }
+
+ if (o !== Object(o)) { throw new TypeError("Object.defineProperty called on non-object"); }
+ if (Object.prototype.__defineGetter__ && ('get' in desc)) {
+ Object.prototype.__defineGetter__.call(o, prop, desc.get);
+ }
+ if (Object.prototype.__defineSetter__ && ('set' in desc)) {
+ Object.prototype.__defineSetter__.call(o, prop, desc.set);
+ }
+ if ('value' in desc) {
+ o[prop] = desc.value;
+ }
+ return o;
+ };
+ }
+}());
+
+// ES 15.2.3.7 Object.defineProperties ( O, Properties )
+if (typeof Object.defineProperties !== "function") {
+ Object.defineProperties = function (o, properties) {
+ "use strict";
+ if (o !== Object(o)) { throw new TypeError("Object.defineProperties called on non-object"); }
+ var name;
+ for (name in properties) {
+ if (Object.prototype.hasOwnProperty.call(properties, name)) {
+ Object.defineProperty(o, name, properties[name]);
+ }
+ }
+ return o;
+ };
+}
+
+
+// ES5 15.2.3.14 Object.keys ( O )
+// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/keys
+if (!Object.keys) {
+ Object.keys = function (o) {
+ if (o !== Object(o)) { throw new TypeError('Object.keys called on non-object'); }
+ var ret = [], p;
+ for (p in o) {
+ if (Object.prototype.hasOwnProperty.call(o, p)) {
+ ret.push(p);
+ }
+ }
+ return ret;
+ };
+}
+
+//----------------------------------------------------------------------
+// ES5 15.3 Function Objects
+//----------------------------------------------------------------------
+
+//
+// ES5 15.3.4 Properties of the Function Prototype Object
+//
+
+// ES5 15.3.4.5 Function.prototype.bind ( thisArg [, arg1 [, arg2, ... ]] )
+// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
+if (!Function.prototype.bind) {
+ Function.prototype.bind = function (o) {
+ if (typeof this !== 'function') { throw new TypeError("Bind must be called on a function"); }
+ var slice = [].slice,
+ args = slice.call(arguments, 1),
+ self = this,
+ bound = function () {
+ return self.apply(this instanceof nop ? this : (o || {}),
+ args.concat(slice.call(arguments)));
+ };
+
+ /** @constructor */
+ function nop() {}
+ nop.prototype = self.prototype;
+
+ bound.prototype = new nop();
+
+ return bound;
+ };
+}
+
+
+//----------------------------------------------------------------------
+// ES5 15.4 Array Objects
+//----------------------------------------------------------------------
+
+//
+// ES5 15.4.3 Properties of the Array Constructor
+//
+
+
+// ES5 15.4.3.2 Array.isArray ( arg )
+// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray
+Array.isArray = Array.isArray || function (o) { return Boolean(o && Object.prototype.toString.call(Object(o)) === '[object Array]'); };
+
+
+//
+// ES5 15.4.4 Properties of the Array Prototype Object
+//
+
+// ES5 15.4.4.14 Array.prototype.indexOf ( searchElement [ , fromIndex ] )
+// From https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
+if (!Array.prototype.indexOf) {
+ Array.prototype.indexOf = function (searchElement /*, fromIndex */) {
+ "use strict";
+
+ if (this === void 0 || this === null) { throw new TypeError(); }
+
+ var t = Object(this);
+ var len = t.length >>> 0;
+ if (len === 0) { return -1; }
+
+ var n = 0;
+ if (arguments.length > 0) {
+ n = Number(arguments[1]);
+ if (isNaN(n)) {
+ n = 0;
+ } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) {
+ n = (n > 0 || -1) * Math.floor(Math.abs(n));
+ }
+ }
+
+ if (n >= len) { return -1; }
+
+ var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
+
+ for (; k < len; k++) {
+ if (k in t && t[k] === searchElement) {
+ return k;
+ }
+ }
+ return -1;
+ };
+}
+
+// ES5 15.4.4.15 Array.prototype.lastIndexOf ( searchElement [ , fromIndex ] )
+// From https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf
+if (!Array.prototype.lastIndexOf) {
+ Array.prototype.lastIndexOf = function (searchElement /*, fromIndex*/) {
+ "use strict";
+
+ if (this === void 0 || this === null) { throw new TypeError(); }
+
+ var t = Object(this);
+ var len = t.length >>> 0;
+ if (len === 0) { return -1; }
+
+ var n = len;
+ if (arguments.length > 1) {
+ n = Number(arguments[1]);
+ if (n !== n) {
+ n = 0;
+ } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) {
+ n = (n > 0 || -1) * Math.floor(Math.abs(n));
+ }
+ }
+
+ var k = n >= 0 ? Math.min(n, len - 1) : len - Math.abs(n);
+
+ for (; k >= 0; k--) {
+ if (k in t && t[k] === searchElement) {
+ return k;
+ }
+ }
+ return -1;
+ };
+}
+
+// ES5 15.4.4.16 Array.prototype.every ( callbackfn [ , thisArg ] )
+// From https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every
+if (!Array.prototype.every) {
+ Array.prototype.every = function (fun /*, thisp */) {
+ "use strict";
+
+ if (this === void 0 || this === null) { throw new TypeError(); }
+
+ var t = Object(this);
+ var len = t.length >>> 0;
+ if (typeof fun !== "function") { throw new TypeError(); }
+
+ var thisp = arguments[1], i;
+ for (i = 0; i < len; i++) {
+ if (i in t && !fun.call(thisp, t[i], i, t)) {
+ return false;
+ }
+ }
+
+ return true;
+ };
+}
+
+// ES5 15.4.4.17 Array.prototype.some ( callbackfn [ , thisArg ] )
+// From https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
+if (!Array.prototype.some) {
+ Array.prototype.some = function (fun /*, thisp */) {
+ "use strict";
+
+ if (this === void 0 || this === null) { throw new TypeError(); }
+
+ var t = Object(this);
+ var len = t.length >>> 0;
+ if (typeof fun !== "function") { throw new TypeError(); }
+
+ var thisp = arguments[1], i;
+ for (i = 0; i < len; i++) {
+ if (i in t && fun.call(thisp, t[i], i, t)) {
+ return true;
+ }
+ }
+
+ return false;
+ };
+}
+
+// ES5 15.4.4.18 Array.prototype.forEach ( callbackfn [ , thisArg ] )
+// From https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/forEach
+if (!Array.prototype.forEach) {
+ Array.prototype.forEach = function (fun /*, thisp */) {
+ "use strict";
+
+ if (this === void 0 || this === null) { throw new TypeError(); }
+
+ var t = Object(this);
+ var len = t.length >>> 0;
+ if (typeof fun !== "function") { throw new TypeError(); }
+
+ var thisp = arguments[1], i;
+ for (i = 0; i < len; i++) {
+ if (i in t) {
+ fun.call(thisp, t[i], i, t);
+ }
+ }
+ };
+}
+
+
+// ES5 15.4.4.19 Array.prototype.map ( callbackfn [ , thisArg ] )
+// From https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/Map
+if (!Array.prototype.map) {
+ Array.prototype.map = function (fun /*, thisp */) {
+ "use strict";
+
+ if (this === void 0 || this === null) { throw new TypeError(); }
+
+ var t = Object(this);
+ var len = t.length >>> 0;
+ if (typeof fun !== "function") { throw new TypeError(); }
+
+ var res = []; res.length = len;
+ var thisp = arguments[1], i;
+ for (i = 0; i < len; i++) {
+ if (i in t) {
+ res[i] = fun.call(thisp, t[i], i, t);
+ }
+ }
+
+ return res;
+ };
+}
+
+// ES5 15.4.4.20 Array.prototype.filter ( callbackfn [ , thisArg ] )
+// From https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/Filter
+if (!Array.prototype.filter) {
+ Array.prototype.filter = function (fun /*, thisp */) {
+ "use strict";
+
+ if (this === void 0 || this === null) { throw new TypeError(); }
+
+ var t = Object(this);
+ var len = t.length >>> 0;
+ if (typeof fun !== "function") { throw new TypeError(); }
+
+ var res = [];
+ var thisp = arguments[1], i;
+ for (i = 0; i < len; i++) {
+ if (i in t) {
+ var val = t[i]; // in case fun mutates this
+ if (fun.call(thisp, val, i, t)) {
+ res.push(val);
+ }
+ }
+ }
+
+ return res;
+ };
+}
+
+
+// ES5 15.4.4.21 Array.prototype.reduce ( callbackfn [ , initialValue ] )
+// From https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/Reduce
+if (!Array.prototype.reduce) {
+ Array.prototype.reduce = function (fun /*, initialValue */) {
+ "use strict";
+
+ if (this === void 0 || this === null) { throw new TypeError(); }
+
+ var t = Object(this);
+ var len = t.length >>> 0;
+ if (typeof fun !== "function") { throw new TypeError(); }
+
+ // no value to return if no initial value and an empty array
+ if (len === 0 && arguments.length === 1) { throw new TypeError(); }
+
+ var k = 0;
+ var accumulator;
+ if (arguments.length >= 2) {
+ accumulator = arguments[1];
+ } else {
+ do {
+ if (k in t) {
+ accumulator = t[k++];
+ break;
+ }
+
+ // if array contains no values, no initial value to return
+ if (++k >= len) { throw new TypeError(); }
+ }
+ while (true);
+ }
+
+ while (k < len) {
+ if (k in t) {
+ accumulator = fun.call(undefined, accumulator, t[k], k, t);
+ }
+ k++;
+ }
+
+ return accumulator;
+ };
+}
+
+
+// ES5 15.4.4.22 Array.prototype.reduceRight ( callbackfn [, initialValue ] )
+// From https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/ReduceRight
+if (!Array.prototype.reduceRight) {
+ Array.prototype.reduceRight = function (callbackfn /*, initialValue */) {
+ "use strict";
+
+ if (this === void 0 || this === null) { throw new TypeError(); }
+
+ var t = Object(this);
+ var len = t.length >>> 0;
+ if (typeof callbackfn !== "function") { throw new TypeError(); }
+
+ // no value to return if no initial value, empty array
+ if (len === 0 && arguments.length === 1) { throw new TypeError(); }
+
+ var k = len - 1;
+ var accumulator;
+ if (arguments.length >= 2) {
+ accumulator = arguments[1];
+ } else {
+ do {
+ if (k in this) {
+ accumulator = this[k--];
+ break;
+ }
+
+ // if array contains no values, no initial value to return
+ if (--k < 0) { throw new TypeError(); }
+ }
+ while (true);
+ }
+
+ while (k >= 0) {
+ if (k in t) {
+ accumulator = callbackfn.call(undefined, accumulator, t[k], k, t);
+ }
+ k--;
+ }
+
+ return accumulator;
+ };
+}
+
+
+//----------------------------------------------------------------------
+// ES5 15.5 String Objects
+//----------------------------------------------------------------------
+
+//
+// ES5 15.5.4 Properties of the String Prototype Object
+//
+
+
+// ES5 15.5.4.20 String.prototype.trim()
+if (!String.prototype.trim) {
+ String.prototype.trim = function () {
+ return String(this).replace(/^\s+/, '').replace(/\s+$/, '');
+ };
+}
+
+
+
+//----------------------------------------------------------------------
+// ES5 15.9 Date Objects
+//----------------------------------------------------------------------
+
+
+//
+// ES 15.9.4 Properties of the Date Constructor
+//
+
+// ES5 15.9.4.4 Date.now ( )
+// From https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Date/now
+if (!Date.now) {
+ Date.now = function now() {
+ return Number(new Date());
+ };
+}
+
+
+//
+// ES5 15.9.5 Properties of the Date Prototype Object
+//
+
+// ES5 15.9.4.43 Date.prototype.toISOString ( )
+// Inspired by http://www.json.org/json2.js
+if (!Date.prototype.toISOString) {
+ Date.prototype.toISOString = function () {
+ function pad2(n) { return ('00' + n).slice(-2); }
+ function pad3(n) { return ('000' + n).slice(-3); }
+
+ return this.getUTCFullYear() + '-' +
+ pad2(this.getUTCMonth() + 1) + '-' +
+ pad2(this.getUTCDate()) + 'T' +
+ pad2(this.getUTCHours()) + ':' +
+ pad2(this.getUTCMinutes()) + ':' +
+ pad2(this.getUTCSeconds()) + '.' +
+ pad3(this.getUTCMilliseconds()) + 'Z';
+ };
+}
+
+
+//----------------------------------------------------------------------
+//
+// Non-standard JavaScript (Mozilla) functions
+//
+//----------------------------------------------------------------------
+
+(function () {
+ // JavaScript 1.8.1
+ String.prototype.trimLeft = String.prototype.trimLeft || function () {
+ return String(this).replace(/^\s+/, '');
+ };
+
+ // JavaScript 1.8.1
+ String.prototype.trimRight = String.prototype.trimRight || function () {
+ return String(this).replace(/\s+$/, '');
+ };
+
+ // JavaScript 1.?
+ var ESCAPES = {
+ //'\x00': '\\0', Special case in FF3.6, removed by FF10
+ '\b': '\\b',
+ '\t': '\\t',
+ '\n': '\\n',
+ '\f': '\\f',
+ '\r': '\\r',
+ '"' : '\\"',
+ '\\': '\\\\'
+ };
+ String.prototype.quote = String.prototype.quote || function() {
+ return '"' + String(this).replace(/[\x00-\x1F"\\\x7F-\uFFFF]/g, function(c) {
+ if (Object.prototype.hasOwnProperty.call(ESCAPES, c)) {
+ return ESCAPES[c];
+ } else if (c.charCodeAt(0) <= 0xFF) {
+ return '\\x' + ('00' + c.charCodeAt(0).toString(16).toUpperCase()).slice(-2);
+ } else {
+ return '\\u' + ('0000' + c.charCodeAt(0).toString(16).toUpperCase()).slice(-4);
+ }
+ }) + '"';
+ };
+}());
+
+
+//----------------------------------------------------------------------
+//
+// Browser Polyfills
+//
+//----------------------------------------------------------------------
+
+if ('window' in this && 'document' in this) {
+
+ //----------------------------------------------------------------------
+ //
+ // Web Standards Polyfills
+ //
+ //----------------------------------------------------------------------
+
+ //
+ // document.head (HTML5)
+ //
+ document.head = document.head || document.getElementsByTagName('head')[0];
+
+ //
+ // XMLHttpRequest (http://www.w3.org/TR/XMLHttpRequest/)
+ //
+ window.XMLHttpRequest = window.XMLHttpRequest || function () {
+ /*global ActiveXObject*/
+ try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e1) { }
+ try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (e2) { }
+ try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e3) { }
+ throw new Error("This browser does not support XMLHttpRequest.");
+ };
+ XMLHttpRequest.UNSENT = 0;
+ XMLHttpRequest.OPENED = 1;
+ XMLHttpRequest.HEADERS_RECEIVED = 2;
+ XMLHttpRequest.LOADING = 3;
+ XMLHttpRequest.DONE = 4;
+
+ //----------------------------------------------------------------------
+ //
+ // Performance
+ //
+ //----------------------------------------------------------------------
+
+ // requestAnimationFrame
+ // http://www.w3.org/TR/animation-timing/
+ (function() {
+ var TARGET_FPS = 60,
+ requests = Object.create(null),
+ raf_handle = 1,
+ timeout_handle = -1;
+
+ function isVisible(element) {
+ return element.offsetWidth > 0 && element.offsetHeight > 0;
+ }
+
+ function onFrameTimer() {
+ var cur_requests = requests;
+
+ requests = Object.create(null);
+ timeout_handle = -1;
+
+ Object.keys(cur_requests).forEach(function(id) {
+ var request = cur_requests[id];
+ if (!request.element || isVisible(request.element)) {
+ request.callback(Date.now());
+ }
+ });
+ }
+
+ function requestAnimationFrame(callback, element) {
+ var cb_handle = raf_handle++;
+ requests[cb_handle] = {callback: callback, element: element};
+
+ if (timeout_handle === -1) {
+ timeout_handle = window.setTimeout(onFrameTimer, 1000 / TARGET_FPS);
+ }
+
+ return cb_handle;
+ }
+
+ function cancelAnimationFrame(handle) {
+ delete requests[handle];
+
+ if (Object.keys(requests).length === 0) {
+ window.clearTimeout(timeout_handle);
+ timeout_handle = -1;
+ }
+ }
+
+ window.requestAnimationFrame =
+ window.requestAnimationFrame ||
+ window.webkitRequestAnimationFrame ||
+ window.mozRequestAnimationFrame ||
+ window.oRequestAnimationFrame ||
+ window.msRequestAnimationFrame ||
+ requestAnimationFrame;
+
+ // NOTE: Older versions of the spec called this "cancelRequestAnimationFrame"
+ window.cancelAnimationFrame = window.cancelRequestAnimationFrame =
+ window.cancelAnimationFrame || window.cancelRequestAnimationFrame ||
+ window.webkitCancelAnimationFrame || window.webkitCancelRequestAnimationFrame ||
+ window.mozCancelAnimationFrame || window.mozCancelRequestAnimationFrame ||
+ window.oCancelAnimationFrame || window.oCancelRequestAnimationFrame ||
+ window.msCancelAnimationFrame || window.msCancelRequestAnimationFrame ||
+ cancelAnimationFrame;
+ }());
+
+ // setImmediate
+ // https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/setImmediate/Overview.html
+ (function () {
+ function setImmediate(callback, args) {
+ var params = [].slice.call(arguments, 1), i;
+ return window.setTimeout(function() {
+ callback.apply(null, params);
+ }, 0);
+ }
+
+ function clearImmediate(handle) {
+ window.clearTimeout(handle);
+ }
+
+ window.setImmediate =
+ window.setImmediate ||
+ window.msSetImmediate ||
+ setImmediate;
+
+ window.clearImmediate =
+ window.clearImmediate ||
+ window.msClearImmediate ||
+ clearImmediate;
+ } ());
+
+ //----------------------------------------------------------------------
+ //
+ // DOM
+ //
+ //----------------------------------------------------------------------
+
+ //
+ // Selectors API Level 1 (http://www.w3.org/TR/selectors-api/)
+ // http://ajaxian.com/archives/creating-a-queryselector-for-ie-that-runs-at-native-speed
+ //
+ if (!document.querySelectorAll) {
+ document.querySelectorAll = function (selectors) {
+ var style = document.createElement('style'), elements = [], element;
+ document.documentElement.firstChild.appendChild(style);
+ document._qsa = [];
+
+ style.styleSheet.cssText = selectors + '{x-qsa:expression(document._qsa && document._qsa.push(this))}';
+ window.scrollBy(0, 0);
+ style.parentNode.removeChild(style);
+
+ while (document._qsa.length) {
+ element = document._qsa.shift();
+ element.style.removeAttribute('x-qsa');
+ elements.push(element);
+ }
+ document._qsa = null;
+ return elements;
+ };
+ }
+
+ if (!document.querySelector) {
+ document.querySelector = function (selectors) {
+ var elements = document.querySelectorAll(selectors);
+ return (elements.length) ? elements[0] : null;
+ };
+ }
+
+ if (!document.getElementsByClassName) {
+ document.getElementsByClassName = function (classNames) {
+ classNames = String(classNames).replace(/^|\s+/g, '.');
+ return document.querySelectorAll(classNames);
+ };
+ }
+
+ //
+ // DOM Enumerations (http://www.w3.org/TR/DOM-Level-2-Core/)
+ //
+ window.Node = window.Node || function Node() { throw new TypeError("Illegal constructor"); };
+ Node.ELEMENT_NODE = 1;
+ Node.ATTRIBUTE_NODE = 2;
+ Node.TEXT_NODE = 3;
+ Node.CDATA_SECTION_NODE = 4;
+ Node.ENTITY_REFERENCE_NODE = 5;
+ Node.ENTITY_NODE = 6;
+ Node.PROCESSING_INSTRUCTION_NODE = 7;
+ Node.COMMENT_NODE = 8;
+ Node.DOCUMENT_NODE = 9;
+ Node.DOCUMENT_TYPE_NODE = 10;
+ Node.DOCUMENT_FRAGMENT_NODE = 11;
+ Node.NOTATION_NODE = 12;
+
+ window.DOMException = window.DOMException || function DOMException() { throw new TypeError("Illegal constructor"); };
+ DOMException.INDEX_SIZE_ERR = 1;
+ DOMException.DOMSTRING_SIZE_ERR = 2;
+ DOMException.HIERARCHY_REQUEST_ERR = 3;
+ DOMException.WRONG_DOCUMENT_ERR = 4;
+ DOMException.INVALID_CHARACTER_ERR = 5;
+ DOMException.NO_DATA_ALLOWED_ERR = 6;
+ DOMException.NO_MODIFICATION_ALLOWED_ERR = 7;
+ DOMException.NOT_FOUND_ERR = 8;
+ DOMException.NOT_SUPPORTED_ERR = 9;
+ DOMException.INUSE_ATTRIBUTE_ERR = 10;
+ DOMException.INVALID_STATE_ERR = 11;
+ DOMException.SYNTAX_ERR = 12;
+ DOMException.INVALID_MODIFICATION_ERR = 13;
+ DOMException.NAMESPACE_ERR = 14;
+ DOMException.INVALID_ACCESS_ERR = 15;
+
+ //
+ // Events and EventTargets
+ //
+
+ (function(){
+ if (!('Element' in window) || Element.prototype.addEventListener || !Object.defineProperty)
+ return;
+
+ // interface Event
+
+ // PhaseType (const unsigned short)
+ Event.CAPTURING_PHASE = 1;
+ Event.AT_TARGET = 2;
+ Event.BUBBLING_PHASE = 3;
+
+ Object.defineProperty(Event.prototype, 'CAPTURING_PHASE', { get: function() { return 1; } });
+ Object.defineProperty(Event.prototype, 'AT_TARGET', { get: function() { return 2; } });
+ Object.defineProperty(Event.prototype, 'BUBBLING_HASE', { get: function() { return 3; } });
+
+ Object.defineProperty(Event.prototype, 'target', {
+ get: function() {
+ return this.srcElement;
+ }
+ });
+
+ Object.defineProperty(Event.prototype, 'currentTarget', {
+ get: function() {
+ return this._currentTarget;
+ }
+ });
+
+ Object.defineProperty(Event.prototype, 'eventPhase', {
+ get: function() {
+ return (this.srcElement === this.currentTarget) ? Event.AT_TARGET : Event.BUBBLING_PHASE;
+ }
+ });
+
+ Object.defineProperty(Event.prototype, 'bubbles', {
+ get: function() {
+ switch (this.type) {
+ // Mouse
+ case 'click':
+ case 'dblclick':
+ case 'mousedown':
+ case 'mouseup':
+ case 'mouseover':
+ case 'mousemove':
+ case 'mouseout':
+ case 'mousewheel':
+ // Keyboard
+ case 'keydown':
+ case 'keypress':
+ case 'keyup':
+ // Frame/Object
+ case 'resize':
+ case 'scroll':
+ // Form
+ case 'select':
+ case 'change':
+ case 'submit':
+ case 'reset':
+ return true;
+ }
+ return false;
+ }
+ });
+
+ Object.defineProperty(Event.prototype, 'cancelable', {
+ get: function() {
+ switch (this.type) {
+ // Mouse
+ case 'click':
+ case 'dblclick':
+ case 'mousedown':
+ case 'mouseup':
+ case 'mouseover':
+ case 'mouseout':
+ case 'mousewheel':
+ // Keyboard
+ case 'keydown':
+ case 'keypress':
+ case 'keyup':
+ // Form
+ case 'submit':
+ return true;
+ }
+ return false;
+ }
+ });
+
+ Object.defineProperty(Event.prototype, 'timeStamp', {
+ get: function() {
+ return this._timeStamp;
+ }
+ });
+
+ Event.prototype.stopPropagation = function() {
+ this.cancelBubble = true;
+ };
+
+ Event.prototype.preventDefault = function() {
+ this.returnValue = false;
+ };
+
+ Object.defineProperty(Event.prototype, 'defaultPrevented', {
+ get: function() {
+ return this.returnValue === false;
+ }
+ });
+
+
+ // interface EventTarget
+
+ function addEventListener(type, listener, useCapture) {
+ var target = this;
+ var f = function(e) {
+ e._timeStamp = Number(new Date);
+ e._currentTarget = target;
+ listener.call(this, e);
+ e._currentTarget = null;
+ };
+ this['_' + type + listener] = f;
+ this.attachEvent('on' + type, f);
+ }
+
+ function removeEventListener(type, listener, useCapture) {
+ var f = this['_' + type + listener];
+ if (f) {
+ this.detachEvent('on' + type, f);
+ this['_' + type + listener] = null;
+ }
+ }
+
+ var p1 = Window.prototype, p2 = HTMLDocument.prototype, p3 = Element.prototype;
+ p1.addEventListener = p2.addEventListener = p3.addEventListener = addEventListener;
+ p1.removeEventListener = p2.removeEventListener = p3.removeEventListener = removeEventListener;
+
+ }());
+
+ // Shim for DOM Events for IE7-
+ // http://www.quirksmode.org/blog/archives/2005/10/_and_the_winner_1.html
+ // Use addEvent(object, event, handler) instead of object.addEventListener(event, handler)
+
+ window.addEvent = function (obj, type, fn) {
+ if (obj.addEventListener) {
+ obj.addEventListener(type, fn, false);
+ } else if (obj.attachEvent) {
+ obj["e" + type + fn] = fn;
+ obj[type + fn] = function () {
+ var e = window.event;
+ e.currentTarget = obj;
+ e.preventDefault = function () { e.returnValue = false; };
+ e.stopPropagation = function () { e.cancelBubble = true; };
+ e.target = e.srcElement;
+ e.timeStamp = Number(new Date);
+ obj["e" + type + fn].call(this, e);
+ };
+ obj.attachEvent("on" + type, obj[type + fn]);
+ }
+ };
+
+ window.removeEvent = function (obj, type, fn) {
+ if (obj.removeEventListener) {
+ obj.removeEventListener(type, fn, false);
+ } else if (obj.detachEvent) {
+ obj.detachEvent("on" + type, obj[type + fn]);
+ obj[type + fn] = null;
+ obj["e" + type + fn] = null;
+ }
+ };
+
+ //----------------------------------------------------------------------
+ //
+ // DOMTokenList - classList and relList shims
+ //
+ //----------------------------------------------------------------------
+
+ // Shim for http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#dom-classlist
+ // Use getClassList(elem) instead of elem.classList() if IE7- support is needed
+ // Use getRelList(elem) instead of elem.relList() if IE7- support is needed
+
+ (function () {
+
+ /** @constructor */
+ function DOMTokenListShim(o, p) {
+ function split(s) { return s.length ? s.split(/\s+/g) : []; }
+
+ // NOTE: This does not exactly match the spec.
+ function removeTokenFromString(token, string) {
+ var tokens = split(string),
+ index = tokens.indexOf(token);
+ if (index !== -1) {
+ tokens.splice(index, 1);
+ }
+ return tokens.join(' ');
+ }
+
+ Object.defineProperties(
+ this,
+ {
+ length: {
+ get: function () { return split(o[p]).length; }
+ },
+
+ item: {
+ value: function (idx) {
+ var tokens = split(o[p]);
+ return 0 <= idx && idx < tokens.length ? tokens[idx] : null;
+ }
+ },
+
+ contains: {
+ value: function (token) {
+ token = String(token);
+ if (token.length === 0) { throw new SyntaxError(); }
+ if (/\s/.test(token)) { throw new Error("InvalidCharacterError"); }
+ var tokens = split(o[p]);
+
+ return tokens.indexOf(token) !== -1;
+ }
+ },
+
+ add: {
+ value: function (tokens___) {
+ tokens = Array.prototype.slice.call(arguments).map(String);
+ if (tokens.some(function(token) { return token.length === 0; })) {
+ throw new SyntaxError();
+ }
+ if (tokens.some(function(token) { return /\s/.test(token); })) {
+ throw new Error("InvalidCharacterError");
+ }
+
+ try {
+ var underlying_string = o[p];
+ var token_list = split(underlying_string);
+ tokens = tokens.filter(function(token) { return token_list.indexOf(token) === -1; });
+ if (tokens.length === 0) {
+ return;
+ }
+ if (underlying_string.length !== 0 && !/\s$/.test(underlying_string)) {
+ underlying_string += ' ';
+ }
+ underlying_string += tokens.join(' ');
+ o[p] = underlying_string;
+ } finally {
+ var length = split(o[p]).length;
+ if (this.length !== length) { this.length = length; }
+ }
+ }
+ },
+
+ remove: {
+ value: function (tokens___) {
+ tokens = Array.prototype.slice.call(arguments).map(String);
+ if (tokens.some(function(token) { return token.length === 0; })) {
+ throw new SyntaxError();
+ }
+ if (tokens.some(function(token) { return /\s/.test(token); })) {
+ throw new Error("InvalidCharacterError");
+ }
+
+ try {
+ var underlying_string = o[p];
+ tokens.forEach(function(token) {
+ underlying_string = removeTokenFromString(token, underlying_string);
+ });
+ o[p] = underlying_string;
+ } finally {
+ var length = split(o[p]).length;
+ if (this.length !== length) { this.length = length; }
+ }
+ }
+ },
+
+ toggle: {
+ value: function (token, force) {
+ try {
+ token = String(token);
+ if (token.length === 0) { throw new SyntaxError(); }
+ if (/\s/.test(token)) { throw new Error("InvalidCharacterError"); }
+ var tokens = split(o[p]),
+ index = tokens.indexOf(token);
+
+ if (index !== -1 && (!force || force === (void 0))) {
+ o[p] = removeTokenFromString(token, o[p]);
+ return false;
+ }
+ if (index !== -1 && force) {
+ return true;
+ }
+ var underlying_string = o[p];
+ if (underlying_string.length !== 0 && !/\s$/.test(underlying_string)) {
+ underlying_string += ' ';
+ }
+ underlying_string += token;
+ o[p] = underlying_string;
+ return true;
+ } finally {
+ var length = split(o[p]).length;
+ if (this.length !== length) { this.length = length; }
+ }
+ }
+ },
+
+ toString: {
+ value: function () {
+ return o[p];
+ }
+ }
+ });
+ if (!('length' in this)) {
+ // In case getters are not supported
+ this.length = split(o[p]).length;
+ } else {
+ // If they are, shim in index getters (up to 100)
+ for (var i = 0; i < 100; ++i) {
+ Object.defineProperty(this, String(i), {
+ get: (function(n) { return function () { return this.item(n); }; }(i))
+ });
+ }
+ }
+ }
+
+ function addToElementPrototype(p, f) {
+ if ('Element' in window && Element.prototype && Object.defineProperty) {
+ Object.defineProperty(Element.prototype, p, { get: f });
+ }
+ }
+
+ if ('classList' in document.createElement('span')) {
+ window.getClassList = function (elem) { return elem.classList; };
+ } else {
+ window.getClassList = function (elem) { return new DOMTokenListShim(elem, 'className'); };
+ addToElementPrototype('classList', function() { return new DOMTokenListShim(this, 'className'); } );
+ }
+
+ if ('relList' in document.createElement('link')) {
+ window.getRelList = function (elem) { return elem.relList; };
+ } else {
+ window.getRelList = function (elem) { return new DOMTokenListShim(elem, 'rel'); };
+ addToElementPrototype('relList', function() { return new DOMTokenListShim(this, 'rel'); } );
+ }
+ }());
+
+ if (!('dataset' in document.createElement('span')) &&
+ 'Element' in window && Element.prototype && Object.defineProperty) {
+ Object.defineProperty(Element.prototype, 'dataset', { get: function() {
+ var result = Object.create(null);
+ for (var i = 0; i < this.attributes.length; ++i) {
+ var attr = this.attributes[i];
+ if (attr.specified && attr.name.substring(0, 5) === 'data-') {
+ (function(element, name) {
+ Object.defineProperty(result, name, {
+ get: function() {
+ return element.getAttribute('data-' + name);
+ },
+ set: function(value) {
+ element.setAttribute('data-' + name, value);
+ }});
+ }(this, attr.name.substring(5)));
+ }
+ }
+ return result;
+ }});
+ }
+}
+
+//
+// Base64 utility methods (HTML5)
+//
+(function (global) {
+ var B64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
+ global.atob = global.atob || function (input) {
+ input = String(input);
+ var position = 0,
+ output = [],
+ buffer = 0, bits = 0, n;
+
+ input = input.replace(/\s/g, '');
+ if ((input.length % 4) === 0) { input = input.replace(/=+$/, ''); }
+ if ((input.length % 4) === 1) { throw new Error("InvalidCharacterError"); }
+ if (/[^+/0-9A-Za-z]/.test(input)) { throw new Error("InvalidCharacterError"); }
+
+ while (position < input.length) {
+ n = B64_ALPHABET.indexOf(input.charAt(position));
+ buffer = (buffer << 6) | n;
+ bits += 6;
+
+ if (bits === 24) {
+ output.push(String.fromCharCode((buffer >> 16) & 0xFF));
+ output.push(String.fromCharCode((buffer >> 8) & 0xFF));
+ output.push(String.fromCharCode(buffer & 0xFF));
+ bits = 0;
+ buffer = 0;
+ }
+ position += 1;
+ }
+
+ if (bits === 12) {
+ buffer = buffer >> 4;
+ output.push(String.fromCharCode(buffer & 0xFF));
+ } else if (bits === 18) {
+ buffer = buffer >> 2;
+ output.push(String.fromCharCode((buffer >> 8) & 0xFF));
+ output.push(String.fromCharCode(buffer & 0xFF));
+ }
+
+ return output.join('');
+ };
+
+ global.btoa = global.btoa || function (input) {
+ input = String(input);
+ var position = 0,
+ out = [],
+ o1, o2, o3,
+ e1, e2, e3, e4;
+
+ if (/[^\x00-\xFF]/.test(input)) { throw new Error("InvalidCharacterError"); }
+
+ while (position < input.length) {
+ o1 = input.charCodeAt(position++);
+ o2 = input.charCodeAt(position++);
+ o3 = input.charCodeAt(position++);
+
+ // 111111 112222 222233 333333
+ e1 = o1 >> 2;
+ e2 = ((o1 & 0x3) << 4) | (o2 >> 4);
+ e3 = ((o2 & 0xf) << 2) | (o3 >> 6);
+ e4 = o3 & 0x3f;
+
+ if (position === input.length + 2) {
+ e3 = 64; e4 = 64;
+ }
+ else if (position === input.length + 1) {
+ e4 = 64;
+ }
+
+ out.push(B64_ALPHABET.charAt(e1),
+ B64_ALPHABET.charAt(e2),
+ B64_ALPHABET.charAt(e3),
+ B64_ALPHABET.charAt(e4));
+ }
+
+ return out.join('');
+ };
+} (this));
diff --git a/examples/script.js b/examples/resource/script.js
similarity index 83%
rename from examples/script.js
rename to examples/resource/script.js
index 58d5d057..1769cbca 100755
--- a/examples/script.js
+++ b/examples/resource/script.js
@@ -1,26 +1,34 @@
'use strict';
-// shim for older browsers:
-if (!document.getElementsByClassName) {
- document.getElementsByClassName = (function(){
- // Utility function to traverse the DOM:
- function traverse (node, callback) {
- callback(node);
- for (var i=0;i < node.childNodes.length; i++) {
- traverse(node.childNodes[i],callback);
+function isStorageSupported() {
+ try {
+ return ('localStorage' in window && window['localStorage'] !== null && window['localStorage'] !== undefined);
+ } catch (e) {
+ return false;
+ }
+}
+function saveCheckboxState(evt) {
+ if (evt.currentTarget.checked) {
+ try {
+ localStorage.setItem(evt.currentTarget.id, evt.currentTarget.checked);
+ } catch (e) {
+ if (e == QUOTA_EXCEEDED_ERR) {
+ alert('Web storage quota for this document has been exceeded. Please empty your browser\'s cache. Note that this will delete all locally stored data.');
}
}
-
- // Actual definition of getElementsByClassName
- return function (name) {
- var result = [];
- traverse(document.body,function(node){
- if (node.className && node.className.indexOf(name) != -1) {
- result.push(node);
- }
- });
- return result;
+ } else {
+ localStorage.removeItem(evt.currentTarget.id);
+ }
+}
+function loadSettings() {
+ var i = localStorage.length - 1;
+ while (i > -1) {
+ var elem = document.getElementById(localStorage.key(i));
+ if (elem != null && 'defaultChecked' in elem) {
+ elem.checked = true;
+ elem.dispatchEvent(new MouseEvent('click'));
}
- })()
+ i--;
+ }
}
function showElement(element) {
if (element != null) {
@@ -164,6 +172,14 @@ function togglePlugins(evt) {
}
function setupEventHandlers() {
var i, elemArr;
+ if (isStorageSupported()) { /*Set up filter value and CSS setting storage read/write handlers.*/
+ elemArr = document.getElementById('filters').getElementsByTagName('input');
+ i = elemArr.length - 1;
+ while (i > -1) {
+ elemArr[i].addEventListener('click', saveCheckboxState, false);
+ i--;
+ }
+ }
document.getElementById('filtersToggle').addEventListener('click', toggleFilters, false);
/*Set up handlers for section display.*/
elemArr = document.getElementById('nav').querySelectorAll('.button[data-section]');
@@ -184,6 +200,9 @@ function setupEventHandlers() {
}
function init() {
setupEventHandlers();
+ if (isStorageSupported()) {
+ loadSettings();
+ }
var elemArr = document.getElementById('filters').getElementsByTagName('input');
for (var i = 0, z = elemArr.length; i < z; i++) {
elemArr[i].disabled = true;
diff --git a/examples/resource/storage.js b/examples/resource/storage.js
new file mode 100644
index 00000000..e8d1517a
--- /dev/null
+++ b/examples/resource/storage.js
@@ -0,0 +1,121 @@
+// Storage polyfill by Remy Sharp
+// https://gist.github.com/350433
+// Needed for IE7-
+
+// Dependencies:
+// JSON (use json2.js if necessary)
+
+// Tweaks by Joshua Bell (inexorabletash@gmail.com)
+// * URI-encode item keys
+// * Use String() for stringifying
+// * added length
+
+if (!window.localStorage || !window.sessionStorage) (function() {
+
+ var Storage = function(type) {
+ function createCookie(name, value, days) {
+ var date, expires;
+
+ if (days) {
+ date = new Date();
+ date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
+ expires = "; expires=" + date.toGMTString();
+ } else {
+ expires = "";
+ }
+ document.cookie = name + "=" + value + expires + "; path=/";
+ }
+
+ function readCookie(name) {
+ var nameEQ = name + "=",
+ ca = document.cookie.split(';'),
+ i, c;
+
+ for (i = 0; i < ca.length; i++) {
+ c = ca[i];
+ while (c.charAt(0) == ' ') {
+ c = c.substring(1, c.length);
+ }
+
+ if (c.indexOf(nameEQ) == 0) {
+ return c.substring(nameEQ.length, c.length);
+ }
+ }
+ return null;
+ }
+
+ function setData(data) {
+ data = JSON.stringify(data);
+ if (type == 'session') {
+ window.name = data;
+ } else {
+ createCookie('localStorage', data, 365);
+ }
+ }
+
+ function clearData() {
+ if (type == 'session') {
+ window.name = '';
+ } else {
+ createCookie('localStorage', '', 365);
+ }
+ }
+
+ function getData() {
+ var data = type == 'session' ? window.name : readCookie('localStorage');
+ return data ? JSON.parse(data) : {};
+ }
+
+
+ // initialise if there's already data
+ var data = getData();
+
+ function numKeys() {
+ var n = 0;
+ for (var k in data) {
+ if (data.hasOwnProperty(k)) {
+ n += 1;
+ }
+ }
+ return n;
+ }
+
+ return {
+ clear: function() {
+ data = {};
+ clearData();
+ this.length = numKeys();
+ },
+ getItem: function(key) {
+ key = encodeURIComponent(key);
+ return data[key] === undefined ? null : data[key];
+ },
+ key: function(i) {
+ // not perfect, but works
+ var ctr = 0;
+ for (var k in data) {
+ if (ctr == i) return decodeURIComponent(k);
+ else ctr++;
+ }
+ return null;
+ },
+ removeItem: function(key) {
+ key = encodeURIComponent(key);
+ delete data[key];
+ setData(data);
+ this.length = numKeys();
+ },
+ setItem: function(key, value) {
+ key = encodeURIComponent(key);
+ data[key] = String(value);
+ setData(data);
+ this.length = numKeys();
+ },
+ length: 0
+ };
+ };
+
+ if (!window.localStorage) window.localStorage = new Storage('local');
+ if (!window.sessionStorage) window.sessionStorage = new Storage('session');
+
+})();
diff --git a/examples/style.css b/examples/resource/style.css
similarity index 64%
rename from examples/style.css
rename to examples/resource/style.css
index 4f2d50d9..7a1fdd6b 100755
--- a/examples/style.css
+++ b/examples/resource/style.css
@@ -122,3 +122,52 @@ li {margin:0.75em 0;}
.hidden, #summary.hidden, #plugins.hidden {
display:none;
}
+
+
+/* Old BOSS Log CSS */
+
+h1{font-size:3em;margin:0;}
+
+h2{font-size:2em;margin-top:0;}
+
+ul{list-style:none;padding-left:0;}
+
+ul li{margin-left:0;margin-bottom:1em;}
+
+li ul{margin-top:.5em;padding-left:2.5em;margin-bottom:2em;}
+
+li.error{background:#ff9090;display:table;padding:0.3em 0.5em;border-radius:0.5em;}
+
+li.warn{background:#FFDD55;display:table;padding:0.3em 0.5em;border-radius:0.5em;}
+
+li.success{background:#90ff90;display:table;padding:0.3em 0.5em;border-radius:0.5em;}
+
+.version{color:#6394F8;margin-right:1em;}
+
+.crc{color:#BC8923;margin-right:1em;}
+
+.active{color:#0A0;margin-right:1em;}
+
+.tagPrefix{color:#CD5555;}
+
+.dirty{color:#960;}
+
+.message{color:gray;}
+
+.mod{margin-right:1em;}
+
+tr.good td {background: #90ff90;}
+
+tr.warn td {background: #FFDD55;}
+
+tr.error td {background:#ff9090;}
+
+th {text-align:left; padding:1em; background:lightblue;}
+
+.message {color:#880088;}
+
+#summary li {border-radius:0.5em;padding:0.5em 1em;display:table;background:#DDD;}
+
+#summary li.error{background:#ff9090;}
+
+#summary li.warn{background:#FFDD55;}
diff --git a/src/generators.h b/src/generators.h
index e9d03f7e..36eb5fcf 100644
--- a/src/generators.h
+++ b/src/generators.h
@@ -114,7 +114,7 @@ namespace boss {
node = head.append_child();
node.set_name("link");
node.append_attribute("rel").set_value("stylesheet");
- node.append_attribute("href").set_value("../../examples/style.css");
+ node.append_attribute("href").set_value("../resource/style.css");
}
void AppendNav(pugi::xml_node& body) {
@@ -458,12 +458,22 @@ namespace boss {
node = body.append_child();
node.set_name("script");
- node.append_attribute("src").set_value("../../examples/eventShim.js");
+ node.append_attribute("src").set_value("../resource/polyfill.js");
node.text().set(" ");
node = body.append_child();
node.set_name("script");
- node.append_attribute("src").set_value("../../examples/script.js");
+ node.append_attribute("src").set_value("../resource/storage.js");
+ node.text().set(" ");
+
+ node = body.append_child();
+ node.set_name("script");
+ node.append_attribute("src").set_value("../resource/DOM-shim-ie8.js");
+ node.text().set(" ");
+
+ node = body.append_child();
+ node.set_name("script");
+ node.append_attribute("src").set_value("../resource/script.js");
node.text().set(" ");
}