!function () { /* * The MIT License (MIT) * Copyright (c) 2014, John Friend */ (function (funcName, baseObj) { "use strict"; // The public function name defaults to window.docReady // but you can modify the last line of this function to pass in a different object or method name // if you want to put them in a different namespace and those will be used instead of // window.docReady(...) funcName = funcName || "docReady"; baseObj = baseObj || window; var readyList = []; var readyFired = false; var readyEventHandlersInstalled = false; // call this when the document is ready // this function protects itself against being called more than once function ready() { if (!readyFired) { // this must be set to true before we start calling callbacks readyFired = true; for (var i = 0; i < readyList.length; i++) { // if a callback here happens to add new ready handlers, // the docReady() function will see that it already fired // and will schedule the callback to run right after // this event loop finishes so all handlers will still execute // in order and no new ones will be added to the readyList // while we are processing the list readyList[i].fn.call(window, readyList[i].ctx); } // allow any closures held by these functions to free readyList = []; } } function readyStateChange() { if (document.readyState === "complete") { ready(); } } // This is the one public interface // docReady(fn, context); // the context argument is optional - if present, it will be passed // as an argument to the callback baseObj[funcName] = function (callback, context) { if (typeof callback !== "function") { throw new TypeError("callback for docReady(fn) must be a function"); } // if ready has already fired, then just schedule the callback // to fire asynchronously, but right away if (readyFired) { setTimeout(function () { callback(context); }, 1); return; } else { // add the function and context to the list readyList.push({fn: callback, ctx: context}); } // if document already ready to go, schedule the ready function to run // IE only safe when readyState is "complete", others safe when readyState is "interactive" if (document.readyState === "complete" || (!document.attachEvent && document.readyState === "interactive")) { setTimeout(ready, 1); } else if (!readyEventHandlersInstalled) { // otherwise if we don't have event handlers installed, install them if (document.addEventListener) { // first choice is DOMContentLoaded event document.addEventListener("DOMContentLoaded", ready, false); // backup is window load event window.addEventListener("load", ready, false); } else { // must be IE document.attachEvent("onreadystatechange", readyStateChange); window.attachEvent("onload", ready); } readyEventHandlersInstalled = true; } } })("docReady", window); docReady(function () { if (!!window.Widgenta) return; window.Widgenta = new (function () { var registry = []; var assets = []; var Future = function () { var value = null, callbacks = []; this.get = function (fn) { if (value) fn(value); else callbacks.push(fn); } this.set = function (v) { value = v; for (var i = 0; i < callbacks.length; ++i) { callbacks[i](value); } callbacks = []; } } var Context = function (arg) { this.element = arg.element; this.type = arg.type; this.key = arg.key; this.data = arg.data; this.endpoint = function () { return this.type.endpoint; } this.inlineCSS = function (css, opt) { var o = !!opt || {}; inlineCSS(css, o.target); } this.loadCSS = function (href, opt) { var o = opt || {}; loadCSS(this.type.endpoint + href + "?ts=" + this.type.ts, o.target, o.onload); } this.loadJS = function (src, opt) { var o = opt || {}; loadJS(this.type.endpoint + src + "?ts=" + this.type.ts, o.target, o.onload); } this.loadJSs = function (src, opt) { var o = opt || {}, arr = []; for (var i = 0; i < src.length; ++i) { arr.push(this.type.endpoint + src[i] + "?ts=" + this.type.ts); } loadJSs(arr, o.target, o.onload); } } var WidgetType = function (code) { var type = new Future(); var entry = new Future(); this.setEntry = function (e) { entry.set(e); }; this.init = function (e, key) { type.get(function (type) { entry.get(function (entry) { request(type.endpoint + "/w/" + key, function (data) { try { entry(new Context({element: e, type: type, key: key, data: data})); } catch (e) { console.error(e); } }); }) }) }; /* init */ request("https://bs.widgenta.com/type/" + code, function (t) { type.set(t); // load entry var entry = t.endpoint + t.entry + "?ts=" + t.ts; var node = document.createElement("script"); node.type = "text/javascript"; node.src = entry; node.defer = true; node.onload = function () { console.log(" * loaded [" + t.code + "] " + entry) }; document.head.appendChild(node); }); } var request = function (url, cb) { var xhr = new XMLHttpRequest(); xhr.open("GET", url, true); xhr.onreadystatechange = function () { if (xhr.readyState !== 4) return; if (xhr.status === 200) { cb(JSON.parse(xhr.responseText)); } } xhr.send(); } var inlineCSS = function (css, target) { var e = target || document.querySelector("head"); if (!!e) { var node = document.createElement("style"); node.type = "text/css"; node.innerHTML = css; e.appendChild(node); } } var loadCSS = function (href, target, onload) { if (assets.hasOwnProperty(href)) { assets[href].get(function () { onload(); }); return; } var e = target || document.querySelector("head"); if (!!e) { var f = new Future(); f.get(function () { onload(); }); assets[href] = f; var node = document.createElement("link"); node.rel = "stylesheet"; node.type = "text/css"; node.href = href; node.onload = function () { f.set(true); }; e.appendChild(node); } } var loadJS = function (src, target, onload) { if (assets.hasOwnProperty(src)) { assets[src].get(function () { onload(); }); return; } var e = target || document.querySelector("head"); if (!!e) { var f = new Future(); f.get(function () { onload(); }); assets[src] = f; var node = document.createElement("script"); node.type = "text/javascript"; node.src = src; node.defer = true; node.onload = function () { f.set(true); }; e.appendChild(node); } } var loadJSs = function (src, target, onload) { var c = src.length for (var i = 0; i < src.length; ++i) { loadJS(src[i], target, function () { if (!(--c)) onload(); }); } } /* public */ this.register = function (type, entry) { if (!registry.hasOwnProperty(type)) { // warning return; } var r = registry[type]; r.setEntry(entry); } /* init */ var el = document.querySelectorAll('div[class^="nbwidget-"]'); for (var n = 0; n < el.length; ++n) { var e = el[n], cl = e.className.split(" "); var key, type, c, p; for (var i = 0; i < cl.length; ++i) { c = cl[i]; if (!c.startsWith("nbwidget-")) continue; p = c.indexOf("."); if (p !== -1) { key = c.substring(p + 1); type = c.substring(("nbwidget-").length, p); break; } } if (type && key) { var r; if (registry.hasOwnProperty(type)) r = registry[type]; else { r = new WidgetType(type); registry[type] = r; } r.init(e, key); } } }); }); }();