From 4364221ecb0394788a42eab21e098d982bd21bd8 Mon Sep 17 00:00:00 2001 From: Glenn Vandeuren Date: Mon, 13 Mar 2017 00:25:19 +0100 Subject: [PATCH] :trollface: Version: 0.1.0-alpha.1 --- dist/backed-es.js | 173 ++++++++++++++++++++++++---------------- dist/backed-es.js.map | 2 +- dist/backed-node.js | 173 ++++++++++++++++++++++++---------------- dist/backed-node.js.map | 2 +- dist/backed.js | 159 +++++++++++++++++++++++------------- dist/backed.js.map | 2 +- package.json | 2 +- 7 files changed, 313 insertions(+), 200 deletions(-) diff --git a/dist/backed-es.js b/dist/backed-es.js index 435cfea..41cad32 100644 --- a/dist/backed-es.js +++ b/dist/backed-es.js @@ -1,20 +1,29 @@ -// import Bind from './bind.js'; - const handleProperties = (target, properties) => { if (properties) { for (let property of Object.keys(properties)) { const observer = properties[property].observer; const strict = properties[property].strict; - handlePropertyObserver(target, property, strict, observer); + const isGlobal = properties[property].global; + handlePropertyObserver(target, property, observer, { + strict: strict || false, + global: isGlobal || false + }); // Bind(superclass, superclass.properties) } } }; -const handlePropertyObserver = (obj, property, strict, observer) => { +const handlePropertyObserver = (obj, property, observer, opts={ + strict: false, global:false +}) => { + if (observer && _needsObserverSetup(obj, property)) { obj.observedProperties.push(property); - setupObserver(obj, property, strict, observer); + + if (opts.global) { + PubSub.subscribe(`global.${property}`, obj[observer]); + } + setupObserver(obj, property, observer, opts); } }; @@ -32,6 +41,22 @@ const _needsObserverSetup = (obj, property) => { } }; +const forObservers = (target, observers, isGlobal=false) => { + for (let observe of observers) { + let parts = observe.split(/\(|\)/g); + let fn = parts[0]; + parts = parts.slice(1); + for (let property of parts) { + if (property.length) { + handlePropertyObserver(target, property, fn, { + strict: false, + global: isGlobal + }); + } + } + } +}; + /** * Runs a method on target whenever given property changes * @@ -46,7 +71,9 @@ const _needsObserverSetup = (obj, property) => { * @arg {boolean} strict * @arg {method} fn The method to run on change */ -const setupObserver = (obj, property, strict=false, fn) => { +const setupObserver = (obj, property, fn, opts={ + strict: false, global: false +}) => { Object.defineProperty(obj, property, { set(value) { this[`_${property}`] = value; @@ -54,58 +81,39 @@ const setupObserver = (obj, property, strict=false, fn) => { property: property, value: value }; - this[fn](data); - PubSub.publish(fn, data); + if (opts.global) { + data.instance = this; + PubSub.publish(`global.${property}`, data); + } else { + this[fn](data); + } }, get() { return this[`_${property}`]; }, - configurable: strict ? false : true + configurable: opts.strict }); }; -const handleObservers = (obj, observers) => { - if (!observers) { +const handleObservers = (target, observers=[], globalObservers=[]) => { + if (!observers && !globalObservers) { return; } - for (let observe of observers) { - let parts = observe.split(/\(|\)/g); - let fn = parts[0]; - parts = parts.slice(1); - for (let property of parts) { - if (property.length) { - handlePropertyObserver(obj, property, false, fn); - } - } - } + forObservers(target, observers); }; -var Utils = { +var base = { handleProperties: handleProperties.bind(undefined), handlePropertyObserver: handlePropertyObserver.bind(undefined), handleObservers: handleObservers.bind(undefined), setupObserver: setupObserver.bind(undefined) }; -/** - * @mixin backed - * @param {string} type Name of the event - * @param {HTMLElement} target Name of the event - * @param {string|boolean|number|object|array} detail - */ var fireEvent = (type=String, detail=null, target=document) => { target.dispatchEvent(new CustomEvent(type, {detail: detail})); }; -/** - * @mixin Backed - * - * some-prop -> someProp - * - * @arg {string} string The content to convert - * @return {string} string - */ var toJsProp = string => { let parts = string.split('-'); if (parts.length > 1) { @@ -152,36 +160,41 @@ var Pubsub = class { /** * @param {String} event - * @param {String|Number|Boolean|Object|Array} value + * @param {String|Number|Boolean|Object|Array} change */ - publish(event, value) { + publish(event, change) { for (let i = 0; i < this.handlers.length; i++) { if (this.handlers[i].event === event) { - this.handlers[i].handler(event, value, this.handlers[i].oldValue); - this.handlers[i].oldValue = value; + let oldValue = this.handlers[i].oldValue || {}; + // dirty checking value, ensures that we don't create a loop + if (oldValue.value !== change.value) { + this.handlers[i].handler(change, this.handlers[i].oldValue); + this.handlers[i].oldValue = change; + } } } } }; -var PubSubLoader = isNode => { - if (isNode) { - global.PubSub = global.PubSub || new Pubsub(); - } else { +var PubSubLoader = isWindow => { + if (isWindow) { window.PubSub = window.PubSub || new Pubsub(); + } else { + global.PubSub = global.PubSub || new Pubsub(); } }; -const isNode = () => { +const supportsCustomElementsV1 = 'customElements' in window; +const supportsCustomElementsV0 = 'registerElement' in document; + +const isWindow = () => { try { - return global; - }catch(e){ + return window; + } catch(e) { return false; } }; -PubSubLoader(isNode()); - /** * * @module backed @@ -192,30 +205,50 @@ var backed = _class => { return string.replace(/([A-Z])/g, "-$1").toLowerCase().replace('-', ''); }; - const construct = (name, _class) => { - if (isNode()) { - return _class; - } else { - customElements.define(name, _class); - } - }; - - // get the tagName or try to make one with class.name let name = _class.is || upperToHyphen(_class.name); - // Setup properties & mixins - // define/register custom-element - return construct(name, class extends _class { - constructor() { - super(); - this.fireEvent = fireEvent.bind(this); - this.toJsProp = toJsProp.bind(this); - this.loadScript = loadScript.bind(this); - - Utils.handleProperties(this, _class.properties); - Utils.handleObservers(this, _class.observers); + // Setup properties & observers + + if (isWindow()) { + if (supportsCustomElementsV1) { + let klass = class extends _class { + constructor() { + super(); + this.created(); + } + created() { + PubSubLoader(isWindow()); + this.fireEvent = fireEvent.bind(this); + this.toJsProp = toJsProp.bind(this); + this.loadScript = loadScript.bind(this); + + base.handleProperties(this, _class.properties); + base.handleObservers(this, _class.observers, _class.globalObservers); + } + }; + customElements.define(name, klass); + } else if (supportsCustomElementsV0) { + let klass = class extends _class { + createdCallback() { + this.created(); + } + created() { + PubSubLoader(isWindow()); + this.fireEvent = fireEvent.bind(this); + this.toJsProp = toJsProp.bind(this); + this.loadScript = loadScript.bind(this); + + base.handleProperties(this, _class.properties); + base.handleObservers(this, _class.observers, _class.globalObservers); + } + }; + document.registerElement(name, klass); + } else { + console.warn('classes::unsupported'); + } + } else { + return _class; } - }); }; export default backed; diff --git a/dist/backed-es.js.map b/dist/backed-es.js.map index fdc91be..4387d6a 100644 --- a/dist/backed-es.js.map +++ b/dist/backed-es.js.map @@ -1 +1 @@ -{"version":3,"file":"backed-es.js","sources":["../src/utils.js","../src/internals/fire-event.js","../src/internals/to-js-prop.js","../src/internals/load-script.js","../src/internals/pub-sub.js","../src/internals/pub-sub-loader.js","../src/backed.js"],"sourcesContent":["'use strict';\r\n// import Bind from './bind.js';\r\n\r\nconst handleProperties = (target, properties) => {\r\n if (properties) {\r\n for (let property of Object.keys(properties)) {\r\n const observer = properties[property].observer;\r\n const strict = properties[property].strict;\r\n handlePropertyObserver(target, property, strict, observer);\r\n // Bind(superclass, superclass.properties)\r\n }\r\n }\r\n}\r\n\r\nconst handlePropertyObserver = (obj, property, strict, observer) => {\r\n if (observer && _needsObserverSetup(obj, property)) {\r\n obj.observedProperties.push(property);\r\n setupObserver(obj, property, strict, observer)\r\n }\r\n}\r\n\r\nconst _needsObserverSetup = (obj, property) => {\r\n if (!obj.observedProperties) {\r\n obj.observedProperties = [];\r\n }\r\n if (obj.observedProperties[property]) {\r\n console.warn(\r\n 'observer::ignoring duplicate property observer ' + property\r\n );\r\n return false;\r\n } else {\r\n return true;\r\n }\r\n}\r\n\r\n/**\r\n * Runs a method on target whenever given property changes\r\n *\r\n * example:\r\n * change(change) {\r\n * change.property // name of the property\r\n * change.value // value of the property\r\n * }\r\n *\r\n * @arg {object} obj target\r\n * @arg {string} property name\r\n * @arg {boolean} strict\r\n * @arg {method} fn The method to run on change\r\n */\r\nconst setupObserver = (obj, property, strict=false, fn) => {\r\n Object.defineProperty(obj, property, {\r\n set(value) {\r\n this[`_${property}`] = value;\r\n let data = {\r\n property: property,\r\n value: value\r\n };\r\n this[fn](data);\r\n PubSub.publish(fn, data);\r\n },\r\n get() {\r\n return this[`_${property}`];\r\n },\r\n configurable: strict ? false : true\r\n });\r\n}\r\n\r\n\r\nconst handleObservers = (obj, observers) => {\r\n if (!observers) {\r\n return;\r\n }\r\n for (let observe of observers) {\r\n let parts = observe.split(/\\(|\\)/g);\r\n let fn = parts[0];\r\n parts = parts.slice(1);\r\n for (let property of parts) {\r\n if (property.length) {\r\n handlePropertyObserver(obj, property, false, fn);\r\n }\r\n }\r\n }\r\n}\r\n\r\nexport default {\r\n handleProperties: handleProperties.bind(this),\r\n handlePropertyObserver: handlePropertyObserver.bind(this),\r\n handleObservers: handleObservers.bind(this),\r\n setupObserver: setupObserver.bind(this)\r\n}\r\n","'use strict';\r\n/**\r\n * @mixin backed\r\n * @param {string} type Name of the event\r\n * @param {HTMLElement} target Name of the event\r\n * @param {string|boolean|number|object|array} detail\r\n */\r\nexport default (type=String, detail=null, target=document) => {\r\n target.dispatchEvent(new CustomEvent(type, {detail: detail}));\r\n};\r\n","'use strict';\r\n/**\r\n * @mixin Backed\r\n *\r\n * some-prop -> someProp\r\n *\r\n * @arg {string} string The content to convert\r\n * @return {string} string\r\n */\r\nexport default string => {\r\n let parts = string.split('-');\r\n if (parts.length > 1) {\r\n var upper = parts[1].charAt(0).toUpperCase();\r\n string = parts[0] + upper + parts[1].slice(1).toLowerCase();\r\n }\r\n return string;\r\n};\r\n","'use strict';\nconst loadScript = src => {\n return new Promise((resolve, reject) => {\n let script = document.createElement('script');\n script.src = src;\n script.onload = result => {\n resolve(result);\n }\n script.onerror = error => {\n reject(error);\n }\n document.body.appendChild(script);\n });\n}\nexport default loadScript;\n","'use strict';\r\nexport default class {\r\n\r\n /**\r\n * Creates handlers\r\n */\r\n constructor() {\r\n this.handlers = [];\r\n }\r\n\r\n /**\r\n * @param {String} event\r\n * @param {Method} handler\r\n * @param {HTMLElement} context\r\n */\r\n subscribe(event, handler, context) {\r\n if (typeof context === 'undefined') {\r\n context = handler;\r\n }\r\n this.handlers.push({event: event, handler: handler.bind(context)});\r\n }\r\n\r\n /**\r\n * @param {String} event\r\n * @param {String|Number|Boolean|Object|Array} value\r\n */\r\n publish(event, value) {\r\n for (let i = 0; i < this.handlers.length; i++) {\r\n if (this.handlers[i].event === event) {\r\n this.handlers[i].handler(event, value, this.handlers[i].oldValue);\r\n this.handlers[i].oldValue = value;\r\n }\r\n }\r\n }\r\n}\r\n","'use strict';\r\nimport Pubsub from './pub-sub.js';\nexport default isNode => {\n if (isNode) {\n global.PubSub = global.PubSub || new Pubsub();\n } else {\n window.PubSub = window.PubSub || new Pubsub();\n }\n}\r\n","'use strict';\r\nimport Utils from './utils';\r\nimport fireEvent from './internals/fire-event.js';\r\nimport toJsProp from './internals/to-js-prop.js';\r\nimport loadScript from './internals/load-script.js';\r\nimport PubSubLoader from './internals/pub-sub-loader.js';\n\nconst isNode = () => {\n try {\n return global;\n }catch(e){\n return false;\n }\n};\n\nPubSubLoader(isNode());\n\r\n/**\r\n *\r\n * @module backed\r\n * @param {class} _class\r\n */\r\nexport default _class => {\r\n const upperToHyphen = string => {\r\n return string.replace(/([A-Z])/g, \"-$1\").toLowerCase().replace('-', '');\r\n };\n\r\n const construct = (name, _class) => {\r\n if (isNode()) {\r\n return _class;\r\n } else {\r\n customElements.define(name, _class);\r\n }\r\n }\r\n\r\n\r\n // get the tagName or try to make one with class.name\r\n let name = _class.is || upperToHyphen(_class.name);\r\n // Setup properties & mixins\r\n // define/register custom-element\r\n return construct(name, class extends _class {\r\n constructor() {\r\n super();\r\n this.fireEvent = fireEvent.bind(this);\r\n this.toJsProp = toJsProp.bind(this);\r\n this.loadScript = loadScript.bind(this);\r\n\r\n Utils.handleProperties(this, _class.properties);\r\n Utils.handleObservers(this, _class.observers);\r\n }\r\n });\r\n};\r\n"],"names":["this"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"backed-es.js","sources":["../src/base.js","../src/internals/fire-event.js","../src/internals/to-js-prop.js","../src/internals/load-script.js","../src/internals/pub-sub.js","../src/internals/pub-sub-loader.js","../src/backed.js"],"sourcesContent":["'use strict';\n\r\nconst handleProperties = (target, properties) => {\r\n if (properties) {\r\n for (let property of Object.keys(properties)) {\r\n const observer = properties[property].observer;\r\n const strict = properties[property].strict;\n const isGlobal = properties[property].global;\n handlePropertyObserver(target, property, observer, {\n strict: strict || false,\n global: isGlobal || false\n });\n // Bind(superclass, superclass.properties)\r\n }\r\n }\r\n}\r\n\r\nconst handlePropertyObserver = (obj, property, observer, opts={\n strict: false, global:false\n}) => {\n\n if (observer && _needsObserverSetup(obj, property)) {\n obj.observedProperties.push(property);\n\n if (opts.global) {\n PubSub.subscribe(`global.${property}`, obj[observer]);\n }\n setupObserver(obj, property, observer, opts)\n }\r\n}\r\n\r\nconst _needsObserverSetup = (obj, property) => {\r\n if (!obj.observedProperties) {\r\n obj.observedProperties = [];\r\n }\r\n if (obj.observedProperties[property]) {\r\n console.warn(\r\n 'observer::ignoring duplicate property observer ' + property\r\n );\r\n return false;\r\n } else {\r\n return true;\r\n }\r\n}\n\nconst forObservers = (target, observers, isGlobal=false) => {\n for (let observe of observers) {\n let parts = observe.split(/\\(|\\)/g);\n let fn = parts[0];\n parts = parts.slice(1);\n for (let property of parts) {\n if (property.length) {\n handlePropertyObserver(target, property, fn, {\n strict: false,\n global: isGlobal\n });\n }\n }\n }\n}\n\r\n/**\r\n * Runs a method on target whenever given property changes\r\n *\r\n * example:\r\n * change(change) {\r\n * change.property // name of the property\r\n * change.value // value of the property\r\n * }\r\n *\r\n * @arg {object} obj target\r\n * @arg {string} property name\r\n * @arg {boolean} strict\r\n * @arg {method} fn The method to run on change\r\n */\r\nconst setupObserver = (obj, property, fn, opts={\n strict: false, global: false\n}) => {\n Object.defineProperty(obj, property, {\r\n set(value) {\n this[`_${property}`] = value;\n let data = {\r\n property: property,\r\n value: value\r\n };\n if (opts.global) {\n data.instance = this;\n PubSub.publish(`global.${property}`, data);\n } else {\n this[fn](data);\n }\n },\n get() {\n return this[`_${property}`];\n },\n configurable: opts.strict\n });\n}\r\n\r\n\r\nconst handleObservers = (target, observers=[], globalObservers=[]) => {\n if (!observers && !globalObservers) {\n return;\r\n }\n forObservers(target, observers);\n}\r\n\r\nexport default {\r\n handleProperties: handleProperties.bind(this),\r\n handlePropertyObserver: handlePropertyObserver.bind(this),\r\n handleObservers: handleObservers.bind(this),\r\n setupObserver: setupObserver.bind(this)\r\n}\r\n","'use strict';\r\n/**\r\n * @mixin backed\r\n * @param {string} type Name of the event\r\n * @param {HTMLElement} target Name of the event\r\n * @param {string|boolean|number|object|array} detail\r\n */\r\nexport default (type=String, detail=null, target=document) => {\r\n target.dispatchEvent(new CustomEvent(type, {detail: detail}));\r\n};\r\n","'use strict';\r\n/**\r\n * @mixin Backed\r\n *\r\n * some-prop -> someProp\r\n *\r\n * @arg {string} string The content to convert\r\n * @return {string} string\r\n */\r\nexport default string => {\r\n let parts = string.split('-');\r\n if (parts.length > 1) {\r\n var upper = parts[1].charAt(0).toUpperCase();\r\n string = parts[0] + upper + parts[1].slice(1).toLowerCase();\r\n }\r\n return string;\r\n};\r\n","'use strict';\nconst loadScript = src => {\n return new Promise((resolve, reject) => {\n let script = document.createElement('script');\n script.src = src;\n script.onload = result => {\n resolve(result);\n }\n script.onerror = error => {\n reject(error);\n }\n document.body.appendChild(script);\n });\n}\nexport default loadScript;\n","'use strict';\r\nexport default class {\r\n\r\n /**\r\n * Creates handlers\r\n */\r\n constructor() {\r\n this.handlers = [];\r\n }\r\n\r\n /**\r\n * @param {String} event\r\n * @param {Method} handler\r\n * @param {HTMLElement} context\r\n */\r\n subscribe(event, handler, context) {\r\n if (typeof context === 'undefined') {\r\n context = handler;\r\n }\r\n this.handlers.push({event: event, handler: handler.bind(context)});\r\n }\r\n\r\n /**\r\n * @param {String} event\r\n * @param {String|Number|Boolean|Object|Array} change\n */\r\n publish(event, change) {\n for (let i = 0; i < this.handlers.length; i++) {\r\n if (this.handlers[i].event === event) {\n let oldValue = this.handlers[i].oldValue || {};\n // dirty checking value, ensures that we don't create a loop\n if (oldValue.value !== change.value) {\n this.handlers[i].handler(change, this.handlers[i].oldValue);\n this.handlers[i].oldValue = change;\n }\n }\r\n }\r\n }\r\n}\r\n","'use strict';\r\nimport Pubsub from './pub-sub.js';\nexport default isWindow => {\n if (isWindow) {\n window.PubSub = window.PubSub || new Pubsub();\n } else {\n global.PubSub = global.PubSub || new Pubsub();\n }\n}\r\n","'use strict';\r\nimport base from './base.js';\nimport fireEvent from './internals/fire-event.js';\r\nimport toJsProp from './internals/to-js-prop.js';\r\nimport loadScript from './internals/load-script.js';\r\nimport PubSubLoader from './internals/pub-sub-loader.js';\r\nconst supportsCustomElementsV1 = 'customElements' in window;\nconst supportsCustomElementsV0 = 'registerElement' in document;\n\nconst isWindow = () => {\n try {\r\n return window;\n } catch(e) {\n return false;\r\n }\r\n};\n\r\n/**\r\n *\r\n * @module backed\r\n * @param {class} _class\r\n */\r\nexport default _class => {\r\n const upperToHyphen = string => {\r\n return string.replace(/([A-Z])/g, \"-$1\").toLowerCase().replace('-', '');\r\n };\n\r\n // get the tagName or try to make one with class.name\r\n let name = _class.is || upperToHyphen(_class.name);\r\n // Setup properties & observers\n\n if (isWindow()) {\n if (supportsCustomElementsV1) {\n let klass = class extends _class {\n constructor() {\n super();\n this.created();\n }\n created() {\n PubSubLoader(isWindow());\n this.fireEvent = fireEvent.bind(this);\n this.toJsProp = toJsProp.bind(this);\n this.loadScript = loadScript.bind(this);\n\n base.handleProperties(this, _class.properties);\n base.handleObservers(this, _class.observers, _class.globalObservers);\n }\n }\n customElements.define(name, klass);\n } else if (supportsCustomElementsV0) {\n let klass = class extends _class {\n createdCallback() {\n this.created();\n }\n created() {\n PubSubLoader(isWindow());\n this.fireEvent = fireEvent.bind(this);\n this.toJsProp = toJsProp.bind(this);\n this.loadScript = loadScript.bind(this);\n\n base.handleProperties(this, _class.properties);\n base.handleObservers(this, _class.observers, _class.globalObservers);\n }\n }\n document.registerElement(name, klass)\n } else {\n console.warn('classes::unsupported');\n }\n } else {\n return _class;\n }\n};\r\n"],"names":["this"],"mappings":"AAEA,MAAM,gBAAgB,GAAG,CAAC,MAAM,EAAE,UAAU,KAAK;EAC/C,IAAI,UAAU,EAAE;IACd,KAAK,IAAI,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE;MAC5C,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC;MAC/C,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC;MAC3C,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC;MAC7C,sBAAsB,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE;QACjD,MAAM,EAAE,MAAM,IAAI,KAAK;QACvB,MAAM,EAAE,QAAQ,IAAI,KAAK;OAC1B,CAAC,CAAC;;KAEJ;GACF;CACF,CAAA;;AAED,MAAM,sBAAsB,GAAG,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC;EAC5D,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK;CAC5B,KAAK;;EAEJ,IAAI,QAAQ,IAAI,mBAAmB,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE;IAClD,GAAG,CAAC,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;;IAEtC,IAAI,IAAI,CAAC,MAAM,EAAE;MACf,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;KACvD;IACD,aAAa,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAA;GAC7C;CACF,CAAA;;AAED,MAAM,mBAAmB,GAAG,CAAC,GAAG,EAAE,QAAQ,KAAK;EAC7C,IAAI,CAAC,GAAG,CAAC,kBAAkB,EAAE;IAC3B,GAAG,CAAC,kBAAkB,GAAG,EAAE,CAAC;GAC7B;EACD,IAAI,GAAG,CAAC,kBAAkB,CAAC,QAAQ,CAAC,EAAE;IACpC,OAAO,CAAC,IAAI;MACV,iDAAiD,GAAG,QAAQ;KAC7D,CAAC;IACF,OAAO,KAAK,CAAC;GACd,MAAM;IACL,OAAO,IAAI,CAAC;GACb;CACF,CAAA;;AAED,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC,KAAK,KAAK;EAC1D,KAAK,IAAI,OAAO,IAAI,SAAS,EAAE;IAC7B,IAAI,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACpC,IAAI,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAClB,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACvB,KAAK,IAAI,QAAQ,IAAI,KAAK,EAAE;MAC1B,IAAI,QAAQ,CAAC,MAAM,EAAE;QACnB,sBAAsB,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE;UAC3C,MAAM,EAAE,KAAK;UACb,MAAM,EAAE,QAAQ;SACjB,CAAC,CAAC;OACJ;KACF;GACF;CACF,CAAA;;;;;;;;;;;;;;;;AAgBD,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,CAAC;EAC7C,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK;CAC7B,KAAK;EACJ,MAAM,CAAC,cAAc,CAAC,GAAG,EAAE,QAAQ,EAAE;IACnC,GAAG,CAAC,KAAK,EAAE;MACT,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;MAC7B,IAAI,IAAI,GAAG;QACT,QAAQ,EAAE,QAAQ;QAClB,KAAK,EAAE,KAAK;OACb,CAAC;MACF,IAAI,IAAI,CAAC,MAAM,EAAE;QACf,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;OAC5C,MAAM;QACL,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;OAChB;KACF;IACD,GAAG,GAAG;MACJ,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;KAC7B;IACD,YAAY,EAAE,IAAI,CAAC,MAAM;GAC1B,CAAC,CAAC;CACJ,CAAA;;;AAGD,MAAM,eAAe,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,EAAE,eAAe,CAAC,EAAE,KAAK;EACpE,IAAI,CAAC,SAAS,IAAI,CAAC,eAAe,EAAE;IAClC,OAAO;GACR;EACD,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;CACjC,CAAA;;AAED,WAAe;EACb,gBAAgB,EAAE,gBAAgB,CAAC,IAAI,CAACA,SAAI,CAAC;EAC7C,sBAAsB,EAAE,sBAAsB,CAAC,IAAI,CAACA,SAAI,CAAC;EACzD,eAAe,EAAE,eAAe,CAAC,IAAI,CAACA,SAAI,CAAC;EAC3C,aAAa,EAAE,aAAa,CAAC,IAAI,CAACA,SAAI,CAAC;CACxC,CAAA;;ACzGD,gBAAe,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,QAAQ,KAAK;EAC5D,MAAM,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;CAC/D,CAAC;;ACAF,eAAe,MAAM,IAAI;EACvB,IAAI,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;EAC9B,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE;IACpB,IAAI,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAC7C,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;GAC7D;EACD,OAAO,MAAM,CAAC;CACf,CAAC;;ACfF,MAAM,UAAU,GAAG,GAAG,IAAI;EACxB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK;IACtC,IAAI,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IAC9C,MAAM,CAAC,GAAG,GAAG,GAAG,CAAC;IACjB,MAAM,CAAC,MAAM,GAAG,MAAM,IAAI;MACxB,OAAO,CAAC,MAAM,CAAC,CAAC;KACjB,CAAA;IACD,MAAM,CAAC,OAAO,GAAG,KAAK,IAAI;MACxB,MAAM,CAAC,KAAK,CAAC,CAAC;KACf,CAAA;IACD,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;GACnC,CAAC,CAAC;CACJ,CAAA,AACD,AAA0B;;ACb1B,aAAe,MAAM;;;;;EAKnB,WAAW,GAAG;IACZ,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;GACpB;;;;;;;EAOD,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE;IACjC,IAAI,OAAO,OAAO,KAAK,WAAW,EAAE;MAClC,OAAO,GAAG,OAAO,CAAC;KACnB;IACD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;GACpE;;;;;;EAMD,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE;IACrB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;MAC7C,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,EAAE;QACpC,IAAI,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC;;QAE/C,IAAI,QAAQ,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,EAAE;UACnC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;UAC5D,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,MAAM,CAAC;SACpC;OACF;KACF;GACF;CACF,CAAA;;ACpCD,mBAAe,QAAQ,IAAI;EACzB,IAAI,QAAQ,EAAE;IACZ,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;GAC/C,MAAM;IACL,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;GAC/C;CACF,CAAA;;ACFD,MAAM,wBAAwB,GAAG,gBAAgB,IAAI,MAAM,CAAC;AAC5D,MAAM,wBAAwB,GAAG,iBAAiB,IAAI,QAAQ,CAAC;;AAE/D,MAAM,QAAQ,GAAG,MAAM;EACrB,IAAI;IACF,OAAO,MAAM,CAAC;GACf,CAAC,MAAM,CAAC,EAAE;IACT,OAAO,KAAK,CAAC;GACd;CACF,CAAC;;;;;;;AAOF,aAAe,MAAM,IAAI;EACvB,MAAM,aAAa,GAAG,MAAM,IAAI;IAC9B,OAAO,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;GACzE,CAAC;;;EAGF,IAAI,IAAI,GAAG,MAAM,CAAC,EAAE,IAAI,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;;;IAGjD,IAAI,QAAQ,EAAE,EAAE;MACd,IAAI,wBAAwB,EAAE;QAC5B,IAAI,KAAK,GAAG,cAAc,MAAM,CAAC;UAC/B,WAAW,GAAG;YACZ,KAAK,EAAE,CAAC;YACR,IAAI,CAAC,OAAO,EAAE,CAAC;WAChB;UACD,OAAO,GAAG;YACR,YAAY,CAAC,QAAQ,EAAE,CAAC,CAAC;YACzB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;;YAExC,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;YAC/C,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC;WACtE;SACF,CAAA;QACD,cAAc,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;OACpC,MAAM,IAAI,wBAAwB,EAAE;QACnC,IAAI,KAAK,GAAG,cAAc,MAAM,CAAC;UAC/B,eAAe,GAAG;YAChB,IAAI,CAAC,OAAO,EAAE,CAAC;WAChB;UACD,OAAO,GAAG;YACR,YAAY,CAAC,QAAQ,EAAE,CAAC,CAAC;YACzB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;;YAExC,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;YAC/C,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC;WACtE;SACF,CAAA;QACD,QAAQ,CAAC,eAAe,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;OACtC,MAAM;QACL,OAAO,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;OACtC;KACF,MAAM;MACL,OAAO,MAAM,CAAC;KACf;CACJ,CAAC,;;"} \ No newline at end of file diff --git a/dist/backed-node.js b/dist/backed-node.js index 1db4219..162e667 100644 --- a/dist/backed-node.js +++ b/dist/backed-node.js @@ -1,22 +1,31 @@ 'use strict'; -// import Bind from './bind.js'; - const handleProperties = (target, properties) => { if (properties) { for (let property of Object.keys(properties)) { const observer = properties[property].observer; const strict = properties[property].strict; - handlePropertyObserver(target, property, strict, observer); + const isGlobal = properties[property].global; + handlePropertyObserver(target, property, observer, { + strict: strict || false, + global: isGlobal || false + }); // Bind(superclass, superclass.properties) } } }; -const handlePropertyObserver = (obj, property, strict, observer) => { +const handlePropertyObserver = (obj, property, observer, opts={ + strict: false, global:false +}) => { + if (observer && _needsObserverSetup(obj, property)) { obj.observedProperties.push(property); - setupObserver(obj, property, strict, observer); + + if (opts.global) { + PubSub.subscribe(`global.${property}`, obj[observer]); + } + setupObserver(obj, property, observer, opts); } }; @@ -34,6 +43,22 @@ const _needsObserverSetup = (obj, property) => { } }; +const forObservers = (target, observers, isGlobal=false) => { + for (let observe of observers) { + let parts = observe.split(/\(|\)/g); + let fn = parts[0]; + parts = parts.slice(1); + for (let property of parts) { + if (property.length) { + handlePropertyObserver(target, property, fn, { + strict: false, + global: isGlobal + }); + } + } + } +}; + /** * Runs a method on target whenever given property changes * @@ -48,7 +73,9 @@ const _needsObserverSetup = (obj, property) => { * @arg {boolean} strict * @arg {method} fn The method to run on change */ -const setupObserver = (obj, property, strict=false, fn) => { +const setupObserver = (obj, property, fn, opts={ + strict: false, global: false +}) => { Object.defineProperty(obj, property, { set(value) { this[`_${property}`] = value; @@ -56,58 +83,39 @@ const setupObserver = (obj, property, strict=false, fn) => { property: property, value: value }; - this[fn](data); - PubSub.publish(fn, data); + if (opts.global) { + data.instance = this; + PubSub.publish(`global.${property}`, data); + } else { + this[fn](data); + } }, get() { return this[`_${property}`]; }, - configurable: strict ? false : true + configurable: opts.strict }); }; -const handleObservers = (obj, observers) => { - if (!observers) { +const handleObservers = (target, observers=[], globalObservers=[]) => { + if (!observers && !globalObservers) { return; } - for (let observe of observers) { - let parts = observe.split(/\(|\)/g); - let fn = parts[0]; - parts = parts.slice(1); - for (let property of parts) { - if (property.length) { - handlePropertyObserver(obj, property, false, fn); - } - } - } + forObservers(target, observers); }; -var Utils = { +var base = { handleProperties: handleProperties.bind(undefined), handlePropertyObserver: handlePropertyObserver.bind(undefined), handleObservers: handleObservers.bind(undefined), setupObserver: setupObserver.bind(undefined) }; -/** - * @mixin backed - * @param {string} type Name of the event - * @param {HTMLElement} target Name of the event - * @param {string|boolean|number|object|array} detail - */ var fireEvent = (type=String, detail=null, target=document) => { target.dispatchEvent(new CustomEvent(type, {detail: detail})); }; -/** - * @mixin Backed - * - * some-prop -> someProp - * - * @arg {string} string The content to convert - * @return {string} string - */ var toJsProp = string => { let parts = string.split('-'); if (parts.length > 1) { @@ -154,36 +162,41 @@ var Pubsub = class { /** * @param {String} event - * @param {String|Number|Boolean|Object|Array} value + * @param {String|Number|Boolean|Object|Array} change */ - publish(event, value) { + publish(event, change) { for (let i = 0; i < this.handlers.length; i++) { if (this.handlers[i].event === event) { - this.handlers[i].handler(event, value, this.handlers[i].oldValue); - this.handlers[i].oldValue = value; + let oldValue = this.handlers[i].oldValue || {}; + // dirty checking value, ensures that we don't create a loop + if (oldValue.value !== change.value) { + this.handlers[i].handler(change, this.handlers[i].oldValue); + this.handlers[i].oldValue = change; + } } } } }; -var PubSubLoader = isNode => { - if (isNode) { - global.PubSub = global.PubSub || new Pubsub(); - } else { +var PubSubLoader = isWindow => { + if (isWindow) { window.PubSub = window.PubSub || new Pubsub(); + } else { + global.PubSub = global.PubSub || new Pubsub(); } }; -const isNode = () => { +const supportsCustomElementsV1 = 'customElements' in window; +const supportsCustomElementsV0 = 'registerElement' in document; + +const isWindow = () => { try { - return global; - }catch(e){ + return window; + } catch(e) { return false; } }; -PubSubLoader(isNode()); - /** * * @module backed @@ -194,30 +207,50 @@ var backed = _class => { return string.replace(/([A-Z])/g, "-$1").toLowerCase().replace('-', ''); }; - const construct = (name, _class) => { - if (isNode()) { - return _class; - } else { - customElements.define(name, _class); - } - }; - - // get the tagName or try to make one with class.name let name = _class.is || upperToHyphen(_class.name); - // Setup properties & mixins - // define/register custom-element - return construct(name, class extends _class { - constructor() { - super(); - this.fireEvent = fireEvent.bind(this); - this.toJsProp = toJsProp.bind(this); - this.loadScript = loadScript.bind(this); - - Utils.handleProperties(this, _class.properties); - Utils.handleObservers(this, _class.observers); + // Setup properties & observers + + if (isWindow()) { + if (supportsCustomElementsV1) { + let klass = class extends _class { + constructor() { + super(); + this.created(); + } + created() { + PubSubLoader(isWindow()); + this.fireEvent = fireEvent.bind(this); + this.toJsProp = toJsProp.bind(this); + this.loadScript = loadScript.bind(this); + + base.handleProperties(this, _class.properties); + base.handleObservers(this, _class.observers, _class.globalObservers); + } + }; + customElements.define(name, klass); + } else if (supportsCustomElementsV0) { + let klass = class extends _class { + createdCallback() { + this.created(); + } + created() { + PubSubLoader(isWindow()); + this.fireEvent = fireEvent.bind(this); + this.toJsProp = toJsProp.bind(this); + this.loadScript = loadScript.bind(this); + + base.handleProperties(this, _class.properties); + base.handleObservers(this, _class.observers, _class.globalObservers); + } + }; + document.registerElement(name, klass); + } else { + console.warn('classes::unsupported'); + } + } else { + return _class; } - }); }; module.exports = backed; diff --git a/dist/backed-node.js.map b/dist/backed-node.js.map index d934d62..f9fec86 100644 --- a/dist/backed-node.js.map +++ b/dist/backed-node.js.map @@ -1 +1 @@ -{"version":3,"file":"backed-node.js","sources":["../src/utils.js","../src/internals/fire-event.js","../src/internals/to-js-prop.js","../src/internals/load-script.js","../src/internals/pub-sub.js","../src/internals/pub-sub-loader.js","../src/backed.js"],"sourcesContent":["'use strict';\r\n// import Bind from './bind.js';\r\n\r\nconst handleProperties = (target, properties) => {\r\n if (properties) {\r\n for (let property of Object.keys(properties)) {\r\n const observer = properties[property].observer;\r\n const strict = properties[property].strict;\r\n handlePropertyObserver(target, property, strict, observer);\r\n // Bind(superclass, superclass.properties)\r\n }\r\n }\r\n}\r\n\r\nconst handlePropertyObserver = (obj, property, strict, observer) => {\r\n if (observer && _needsObserverSetup(obj, property)) {\r\n obj.observedProperties.push(property);\r\n setupObserver(obj, property, strict, observer)\r\n }\r\n}\r\n\r\nconst _needsObserverSetup = (obj, property) => {\r\n if (!obj.observedProperties) {\r\n obj.observedProperties = [];\r\n }\r\n if (obj.observedProperties[property]) {\r\n console.warn(\r\n 'observer::ignoring duplicate property observer ' + property\r\n );\r\n return false;\r\n } else {\r\n return true;\r\n }\r\n}\r\n\r\n/**\r\n * Runs a method on target whenever given property changes\r\n *\r\n * example:\r\n * change(change) {\r\n * change.property // name of the property\r\n * change.value // value of the property\r\n * }\r\n *\r\n * @arg {object} obj target\r\n * @arg {string} property name\r\n * @arg {boolean} strict\r\n * @arg {method} fn The method to run on change\r\n */\r\nconst setupObserver = (obj, property, strict=false, fn) => {\r\n Object.defineProperty(obj, property, {\r\n set(value) {\r\n this[`_${property}`] = value;\r\n let data = {\r\n property: property,\r\n value: value\r\n };\r\n this[fn](data);\r\n PubSub.publish(fn, data);\r\n },\r\n get() {\r\n return this[`_${property}`];\r\n },\r\n configurable: strict ? false : true\r\n });\r\n}\r\n\r\n\r\nconst handleObservers = (obj, observers) => {\r\n if (!observers) {\r\n return;\r\n }\r\n for (let observe of observers) {\r\n let parts = observe.split(/\\(|\\)/g);\r\n let fn = parts[0];\r\n parts = parts.slice(1);\r\n for (let property of parts) {\r\n if (property.length) {\r\n handlePropertyObserver(obj, property, false, fn);\r\n }\r\n }\r\n }\r\n}\r\n\r\nexport default {\r\n handleProperties: handleProperties.bind(this),\r\n handlePropertyObserver: handlePropertyObserver.bind(this),\r\n handleObservers: handleObservers.bind(this),\r\n setupObserver: setupObserver.bind(this)\r\n}\r\n","'use strict';\r\n/**\r\n * @mixin backed\r\n * @param {string} type Name of the event\r\n * @param {HTMLElement} target Name of the event\r\n * @param {string|boolean|number|object|array} detail\r\n */\r\nexport default (type=String, detail=null, target=document) => {\r\n target.dispatchEvent(new CustomEvent(type, {detail: detail}));\r\n};\r\n","'use strict';\r\n/**\r\n * @mixin Backed\r\n *\r\n * some-prop -> someProp\r\n *\r\n * @arg {string} string The content to convert\r\n * @return {string} string\r\n */\r\nexport default string => {\r\n let parts = string.split('-');\r\n if (parts.length > 1) {\r\n var upper = parts[1].charAt(0).toUpperCase();\r\n string = parts[0] + upper + parts[1].slice(1).toLowerCase();\r\n }\r\n return string;\r\n};\r\n","'use strict';\nconst loadScript = src => {\n return new Promise((resolve, reject) => {\n let script = document.createElement('script');\n script.src = src;\n script.onload = result => {\n resolve(result);\n }\n script.onerror = error => {\n reject(error);\n }\n document.body.appendChild(script);\n });\n}\nexport default loadScript;\n","'use strict';\r\nexport default class {\r\n\r\n /**\r\n * Creates handlers\r\n */\r\n constructor() {\r\n this.handlers = [];\r\n }\r\n\r\n /**\r\n * @param {String} event\r\n * @param {Method} handler\r\n * @param {HTMLElement} context\r\n */\r\n subscribe(event, handler, context) {\r\n if (typeof context === 'undefined') {\r\n context = handler;\r\n }\r\n this.handlers.push({event: event, handler: handler.bind(context)});\r\n }\r\n\r\n /**\r\n * @param {String} event\r\n * @param {String|Number|Boolean|Object|Array} value\r\n */\r\n publish(event, value) {\r\n for (let i = 0; i < this.handlers.length; i++) {\r\n if (this.handlers[i].event === event) {\r\n this.handlers[i].handler(event, value, this.handlers[i].oldValue);\r\n this.handlers[i].oldValue = value;\r\n }\r\n }\r\n }\r\n}\r\n","'use strict';\r\nimport Pubsub from './pub-sub.js';\nexport default isNode => {\n if (isNode) {\n global.PubSub = global.PubSub || new Pubsub();\n } else {\n window.PubSub = window.PubSub || new Pubsub();\n }\n}\r\n","'use strict';\r\nimport Utils from './utils';\r\nimport fireEvent from './internals/fire-event.js';\r\nimport toJsProp from './internals/to-js-prop.js';\r\nimport loadScript from './internals/load-script.js';\r\nimport PubSubLoader from './internals/pub-sub-loader.js';\n\nconst isNode = () => {\n try {\n return global;\n }catch(e){\n return false;\n }\n};\n\nPubSubLoader(isNode());\n\r\n/**\r\n *\r\n * @module backed\r\n * @param {class} _class\r\n */\r\nexport default _class => {\r\n const upperToHyphen = string => {\r\n return string.replace(/([A-Z])/g, \"-$1\").toLowerCase().replace('-', '');\r\n };\n\r\n const construct = (name, _class) => {\r\n if (isNode()) {\r\n return _class;\r\n } else {\r\n customElements.define(name, _class);\r\n }\r\n }\r\n\r\n\r\n // get the tagName or try to make one with class.name\r\n let name = _class.is || upperToHyphen(_class.name);\r\n // Setup properties & mixins\r\n // define/register custom-element\r\n return construct(name, class extends _class {\r\n constructor() {\r\n super();\r\n this.fireEvent = fireEvent.bind(this);\r\n this.toJsProp = toJsProp.bind(this);\r\n this.loadScript = loadScript.bind(this);\r\n\r\n Utils.handleProperties(this, _class.properties);\r\n Utils.handleObservers(this, _class.observers);\r\n }\r\n });\r\n};\r\n"],"names":["this"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"backed-node.js","sources":["../src/base.js","../src/internals/fire-event.js","../src/internals/to-js-prop.js","../src/internals/load-script.js","../src/internals/pub-sub.js","../src/internals/pub-sub-loader.js","../src/backed.js"],"sourcesContent":["'use strict';\n\r\nconst handleProperties = (target, properties) => {\r\n if (properties) {\r\n for (let property of Object.keys(properties)) {\r\n const observer = properties[property].observer;\r\n const strict = properties[property].strict;\n const isGlobal = properties[property].global;\n handlePropertyObserver(target, property, observer, {\n strict: strict || false,\n global: isGlobal || false\n });\n // Bind(superclass, superclass.properties)\r\n }\r\n }\r\n}\r\n\r\nconst handlePropertyObserver = (obj, property, observer, opts={\n strict: false, global:false\n}) => {\n\n if (observer && _needsObserverSetup(obj, property)) {\n obj.observedProperties.push(property);\n\n if (opts.global) {\n PubSub.subscribe(`global.${property}`, obj[observer]);\n }\n setupObserver(obj, property, observer, opts)\n }\r\n}\r\n\r\nconst _needsObserverSetup = (obj, property) => {\r\n if (!obj.observedProperties) {\r\n obj.observedProperties = [];\r\n }\r\n if (obj.observedProperties[property]) {\r\n console.warn(\r\n 'observer::ignoring duplicate property observer ' + property\r\n );\r\n return false;\r\n } else {\r\n return true;\r\n }\r\n}\n\nconst forObservers = (target, observers, isGlobal=false) => {\n for (let observe of observers) {\n let parts = observe.split(/\\(|\\)/g);\n let fn = parts[0];\n parts = parts.slice(1);\n for (let property of parts) {\n if (property.length) {\n handlePropertyObserver(target, property, fn, {\n strict: false,\n global: isGlobal\n });\n }\n }\n }\n}\n\r\n/**\r\n * Runs a method on target whenever given property changes\r\n *\r\n * example:\r\n * change(change) {\r\n * change.property // name of the property\r\n * change.value // value of the property\r\n * }\r\n *\r\n * @arg {object} obj target\r\n * @arg {string} property name\r\n * @arg {boolean} strict\r\n * @arg {method} fn The method to run on change\r\n */\r\nconst setupObserver = (obj, property, fn, opts={\n strict: false, global: false\n}) => {\n Object.defineProperty(obj, property, {\r\n set(value) {\n this[`_${property}`] = value;\n let data = {\r\n property: property,\r\n value: value\r\n };\n if (opts.global) {\n data.instance = this;\n PubSub.publish(`global.${property}`, data);\n } else {\n this[fn](data);\n }\n },\n get() {\n return this[`_${property}`];\n },\n configurable: opts.strict\n });\n}\r\n\r\n\r\nconst handleObservers = (target, observers=[], globalObservers=[]) => {\n if (!observers && !globalObservers) {\n return;\r\n }\n forObservers(target, observers);\n}\r\n\r\nexport default {\r\n handleProperties: handleProperties.bind(this),\r\n handlePropertyObserver: handlePropertyObserver.bind(this),\r\n handleObservers: handleObservers.bind(this),\r\n setupObserver: setupObserver.bind(this)\r\n}\r\n","'use strict';\r\n/**\r\n * @mixin backed\r\n * @param {string} type Name of the event\r\n * @param {HTMLElement} target Name of the event\r\n * @param {string|boolean|number|object|array} detail\r\n */\r\nexport default (type=String, detail=null, target=document) => {\r\n target.dispatchEvent(new CustomEvent(type, {detail: detail}));\r\n};\r\n","'use strict';\r\n/**\r\n * @mixin Backed\r\n *\r\n * some-prop -> someProp\r\n *\r\n * @arg {string} string The content to convert\r\n * @return {string} string\r\n */\r\nexport default string => {\r\n let parts = string.split('-');\r\n if (parts.length > 1) {\r\n var upper = parts[1].charAt(0).toUpperCase();\r\n string = parts[0] + upper + parts[1].slice(1).toLowerCase();\r\n }\r\n return string;\r\n};\r\n","'use strict';\nconst loadScript = src => {\n return new Promise((resolve, reject) => {\n let script = document.createElement('script');\n script.src = src;\n script.onload = result => {\n resolve(result);\n }\n script.onerror = error => {\n reject(error);\n }\n document.body.appendChild(script);\n });\n}\nexport default loadScript;\n","'use strict';\r\nexport default class {\r\n\r\n /**\r\n * Creates handlers\r\n */\r\n constructor() {\r\n this.handlers = [];\r\n }\r\n\r\n /**\r\n * @param {String} event\r\n * @param {Method} handler\r\n * @param {HTMLElement} context\r\n */\r\n subscribe(event, handler, context) {\r\n if (typeof context === 'undefined') {\r\n context = handler;\r\n }\r\n this.handlers.push({event: event, handler: handler.bind(context)});\r\n }\r\n\r\n /**\r\n * @param {String} event\r\n * @param {String|Number|Boolean|Object|Array} change\n */\r\n publish(event, change) {\n for (let i = 0; i < this.handlers.length; i++) {\r\n if (this.handlers[i].event === event) {\n let oldValue = this.handlers[i].oldValue || {};\n // dirty checking value, ensures that we don't create a loop\n if (oldValue.value !== change.value) {\n this.handlers[i].handler(change, this.handlers[i].oldValue);\n this.handlers[i].oldValue = change;\n }\n }\r\n }\r\n }\r\n}\r\n","'use strict';\r\nimport Pubsub from './pub-sub.js';\nexport default isWindow => {\n if (isWindow) {\n window.PubSub = window.PubSub || new Pubsub();\n } else {\n global.PubSub = global.PubSub || new Pubsub();\n }\n}\r\n","'use strict';\r\nimport base from './base.js';\nimport fireEvent from './internals/fire-event.js';\r\nimport toJsProp from './internals/to-js-prop.js';\r\nimport loadScript from './internals/load-script.js';\r\nimport PubSubLoader from './internals/pub-sub-loader.js';\r\nconst supportsCustomElementsV1 = 'customElements' in window;\nconst supportsCustomElementsV0 = 'registerElement' in document;\n\nconst isWindow = () => {\n try {\r\n return window;\n } catch(e) {\n return false;\r\n }\r\n};\n\r\n/**\r\n *\r\n * @module backed\r\n * @param {class} _class\r\n */\r\nexport default _class => {\r\n const upperToHyphen = string => {\r\n return string.replace(/([A-Z])/g, \"-$1\").toLowerCase().replace('-', '');\r\n };\n\r\n // get the tagName or try to make one with class.name\r\n let name = _class.is || upperToHyphen(_class.name);\r\n // Setup properties & observers\n\n if (isWindow()) {\n if (supportsCustomElementsV1) {\n let klass = class extends _class {\n constructor() {\n super();\n this.created();\n }\n created() {\n PubSubLoader(isWindow());\n this.fireEvent = fireEvent.bind(this);\n this.toJsProp = toJsProp.bind(this);\n this.loadScript = loadScript.bind(this);\n\n base.handleProperties(this, _class.properties);\n base.handleObservers(this, _class.observers, _class.globalObservers);\n }\n }\n customElements.define(name, klass);\n } else if (supportsCustomElementsV0) {\n let klass = class extends _class {\n createdCallback() {\n this.created();\n }\n created() {\n PubSubLoader(isWindow());\n this.fireEvent = fireEvent.bind(this);\n this.toJsProp = toJsProp.bind(this);\n this.loadScript = loadScript.bind(this);\n\n base.handleProperties(this, _class.properties);\n base.handleObservers(this, _class.observers, _class.globalObservers);\n }\n }\n document.registerElement(name, klass)\n } else {\n console.warn('classes::unsupported');\n }\n } else {\n return _class;\n }\n};\r\n"],"names":["this"],"mappings":"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"} \ No newline at end of file diff --git a/dist/backed.js b/dist/backed.js index f862d78..c50617a 100644 --- a/dist/backed.js +++ b/dist/backed.js @@ -1,23 +1,32 @@ var Backed = (function () { 'use strict'; -// import Bind from './bind.js'; - const handleProperties = (target, properties) => { if (properties) { for (let property of Object.keys(properties)) { const observer = properties[property].observer; const strict = properties[property].strict; - handlePropertyObserver(target, property, strict, observer); + const isGlobal = properties[property].global; + handlePropertyObserver(target, property, observer, { + strict: strict || false, + global: isGlobal || false + }); // Bind(superclass, superclass.properties) } } }; -const handlePropertyObserver = (obj, property, strict, observer) => { +const handlePropertyObserver = (obj, property, observer, opts={ + strict: false, global:false +}) => { + if (observer && _needsObserverSetup(obj, property)) { obj.observedProperties.push(property); - setupObserver(obj, property, strict, observer); + + if (opts.global) { + PubSub.subscribe(`global.${property}`, obj[observer]); + } + setupObserver(obj, property, observer, opts); } }; @@ -35,6 +44,22 @@ const _needsObserverSetup = (obj, property) => { } }; +const forObservers = (target, observers, isGlobal=false) => { + for (let observe of observers) { + let parts = observe.split(/\(|\)/g); + let fn = parts[0]; + parts = parts.slice(1); + for (let property of parts) { + if (property.length) { + handlePropertyObserver(target, property, fn, { + strict: false, + global: isGlobal + }); + } + } + } +}; + /** * Runs a method on target whenever given property changes * @@ -49,7 +74,9 @@ const _needsObserverSetup = (obj, property) => { * @arg {boolean} strict * @arg {method} fn The method to run on change */ -const setupObserver = (obj, property, strict=false, fn) => { +const setupObserver = (obj, property, fn, opts={ + strict: false, global: false +}) => { Object.defineProperty(obj, property, { set(value) { this[`_${property}`] = value; @@ -57,34 +84,29 @@ const setupObserver = (obj, property, strict=false, fn) => { property: property, value: value }; - this[fn](data); - PubSub.publish(fn, data); + if (opts.global) { + data.instance = this; + PubSub.publish(`global.${property}`, data); + } else { + this[fn](data); + } }, get() { return this[`_${property}`]; }, - configurable: strict ? false : true + configurable: opts.strict }); }; -const handleObservers = (obj, observers) => { - if (!observers) { +const handleObservers = (target, observers=[], globalObservers=[]) => { + if (!observers && !globalObservers) { return; } - for (let observe of observers) { - let parts = observe.split(/\(|\)/g); - let fn = parts[0]; - parts = parts.slice(1); - for (let property of parts) { - if (property.length) { - handlePropertyObserver(obj, property, false, fn); - } - } - } + forObservers(target, observers); }; -var Utils = { +var base = { handleProperties: handleProperties.bind(undefined), handlePropertyObserver: handlePropertyObserver.bind(undefined), handleObservers: handleObservers.bind(undefined), @@ -155,36 +177,41 @@ var Pubsub = class { /** * @param {String} event - * @param {String|Number|Boolean|Object|Array} value + * @param {String|Number|Boolean|Object|Array} change */ - publish(event, value) { + publish(event, change) { for (let i = 0; i < this.handlers.length; i++) { if (this.handlers[i].event === event) { - this.handlers[i].handler(event, value, this.handlers[i].oldValue); - this.handlers[i].oldValue = value; + let oldValue = this.handlers[i].oldValue || {}; + // dirty checking value, ensures that we don't create a loop + if (oldValue.value !== change.value) { + this.handlers[i].handler(change, this.handlers[i].oldValue); + this.handlers[i].oldValue = change; + } } } } }; -var PubSubLoader = isNode => { - if (isNode) { - global.PubSub = global.PubSub || new Pubsub(); - } else { +var PubSubLoader = isWindow => { + if (isWindow) { window.PubSub = window.PubSub || new Pubsub(); + } else { + global.PubSub = global.PubSub || new Pubsub(); } }; -const isNode = () => { +const supportsCustomElementsV1 = 'customElements' in window; +const supportsCustomElementsV0 = 'registerElement' in document; + +const isWindow = () => { try { - return global; - }catch(e){ + return window; + } catch(e) { return false; } }; -PubSubLoader(isNode()); - /** * * @module backed @@ -195,30 +222,50 @@ var backed = _class => { return string.replace(/([A-Z])/g, "-$1").toLowerCase().replace('-', ''); }; - const construct = (name, _class) => { - if (isNode()) { - return _class; - } else { - customElements.define(name, _class); - } - }; - - // get the tagName or try to make one with class.name let name = _class.is || upperToHyphen(_class.name); - // Setup properties & mixins - // define/register custom-element - return construct(name, class extends _class { - constructor() { - super(); - this.fireEvent = fireEvent.bind(this); - this.toJsProp = toJsProp.bind(this); - this.loadScript = loadScript.bind(this); - - Utils.handleProperties(this, _class.properties); - Utils.handleObservers(this, _class.observers); + // Setup properties & observers + + if (isWindow()) { + if (supportsCustomElementsV1) { + let klass = class extends _class { + constructor() { + super(); + this.created(); + } + created() { + PubSubLoader(isWindow()); + this.fireEvent = fireEvent.bind(this); + this.toJsProp = toJsProp.bind(this); + this.loadScript = loadScript.bind(this); + + base.handleProperties(this, _class.properties); + base.handleObservers(this, _class.observers, _class.globalObservers); + } + }; + customElements.define(name, klass); + } else if (supportsCustomElementsV0) { + let klass = class extends _class { + createdCallback() { + this.created(); + } + created() { + PubSubLoader(isWindow()); + this.fireEvent = fireEvent.bind(this); + this.toJsProp = toJsProp.bind(this); + this.loadScript = loadScript.bind(this); + + base.handleProperties(this, _class.properties); + base.handleObservers(this, _class.observers, _class.globalObservers); + } + }; + document.registerElement(name, klass); + } else { + console.warn('classes::unsupported'); + } + } else { + return _class; } - }); }; return backed; diff --git a/dist/backed.js.map b/dist/backed.js.map index 94cc230..d32efe2 100644 --- a/dist/backed.js.map +++ b/dist/backed.js.map @@ -1 +1 @@ -{"version":3,"file":"backed.js","sources":["../src/utils.js","../src/internals/fire-event.js","../src/internals/to-js-prop.js","../src/internals/load-script.js","../src/internals/pub-sub.js","../src/internals/pub-sub-loader.js","../src/backed.js"],"sourcesContent":["'use strict';\r\n// import Bind from './bind.js';\r\n\r\nconst handleProperties = (target, properties) => {\r\n if (properties) {\r\n for (let property of Object.keys(properties)) {\r\n const observer = properties[property].observer;\r\n const strict = properties[property].strict;\r\n handlePropertyObserver(target, property, strict, observer);\r\n // Bind(superclass, superclass.properties)\r\n }\r\n }\r\n}\r\n\r\nconst handlePropertyObserver = (obj, property, strict, observer) => {\r\n if (observer && _needsObserverSetup(obj, property)) {\r\n obj.observedProperties.push(property);\r\n setupObserver(obj, property, strict, observer)\r\n }\r\n}\r\n\r\nconst _needsObserverSetup = (obj, property) => {\r\n if (!obj.observedProperties) {\r\n obj.observedProperties = [];\r\n }\r\n if (obj.observedProperties[property]) {\r\n console.warn(\r\n 'observer::ignoring duplicate property observer ' + property\r\n );\r\n return false;\r\n } else {\r\n return true;\r\n }\r\n}\r\n\r\n/**\r\n * Runs a method on target whenever given property changes\r\n *\r\n * example:\r\n * change(change) {\r\n * change.property // name of the property\r\n * change.value // value of the property\r\n * }\r\n *\r\n * @arg {object} obj target\r\n * @arg {string} property name\r\n * @arg {boolean} strict\r\n * @arg {method} fn The method to run on change\r\n */\r\nconst setupObserver = (obj, property, strict=false, fn) => {\r\n Object.defineProperty(obj, property, {\r\n set(value) {\r\n this[`_${property}`] = value;\r\n let data = {\r\n property: property,\r\n value: value\r\n };\r\n this[fn](data);\r\n PubSub.publish(fn, data);\r\n },\r\n get() {\r\n return this[`_${property}`];\r\n },\r\n configurable: strict ? false : true\r\n });\r\n}\r\n\r\n\r\nconst handleObservers = (obj, observers) => {\r\n if (!observers) {\r\n return;\r\n }\r\n for (let observe of observers) {\r\n let parts = observe.split(/\\(|\\)/g);\r\n let fn = parts[0];\r\n parts = parts.slice(1);\r\n for (let property of parts) {\r\n if (property.length) {\r\n handlePropertyObserver(obj, property, false, fn);\r\n }\r\n }\r\n }\r\n}\r\n\r\nexport default {\r\n handleProperties: handleProperties.bind(this),\r\n handlePropertyObserver: handlePropertyObserver.bind(this),\r\n handleObservers: handleObservers.bind(this),\r\n setupObserver: setupObserver.bind(this)\r\n}\r\n","'use strict';\r\n/**\r\n * @mixin backed\r\n * @param {string} type Name of the event\r\n * @param {HTMLElement} target Name of the event\r\n * @param {string|boolean|number|object|array} detail\r\n */\r\nexport default (type=String, detail=null, target=document) => {\r\n target.dispatchEvent(new CustomEvent(type, {detail: detail}));\r\n};\r\n","'use strict';\r\n/**\r\n * @mixin Backed\r\n *\r\n * some-prop -> someProp\r\n *\r\n * @arg {string} string The content to convert\r\n * @return {string} string\r\n */\r\nexport default string => {\r\n let parts = string.split('-');\r\n if (parts.length > 1) {\r\n var upper = parts[1].charAt(0).toUpperCase();\r\n string = parts[0] + upper + parts[1].slice(1).toLowerCase();\r\n }\r\n return string;\r\n};\r\n","'use strict';\nconst loadScript = src => {\n return new Promise((resolve, reject) => {\n let script = document.createElement('script');\n script.src = src;\n script.onload = result => {\n resolve(result);\n }\n script.onerror = error => {\n reject(error);\n }\n document.body.appendChild(script);\n });\n}\nexport default loadScript;\n","'use strict';\r\nexport default class {\r\n\r\n /**\r\n * Creates handlers\r\n */\r\n constructor() {\r\n this.handlers = [];\r\n }\r\n\r\n /**\r\n * @param {String} event\r\n * @param {Method} handler\r\n * @param {HTMLElement} context\r\n */\r\n subscribe(event, handler, context) {\r\n if (typeof context === 'undefined') {\r\n context = handler;\r\n }\r\n this.handlers.push({event: event, handler: handler.bind(context)});\r\n }\r\n\r\n /**\r\n * @param {String} event\r\n * @param {String|Number|Boolean|Object|Array} value\r\n */\r\n publish(event, value) {\r\n for (let i = 0; i < this.handlers.length; i++) {\r\n if (this.handlers[i].event === event) {\r\n this.handlers[i].handler(event, value, this.handlers[i].oldValue);\r\n this.handlers[i].oldValue = value;\r\n }\r\n }\r\n }\r\n}\r\n","'use strict';\r\nimport Pubsub from './pub-sub.js';\nexport default isNode => {\n if (isNode) {\n global.PubSub = global.PubSub || new Pubsub();\n } else {\n window.PubSub = window.PubSub || new Pubsub();\n }\n}\r\n","'use strict';\r\nimport Utils from './utils';\r\nimport fireEvent from './internals/fire-event.js';\r\nimport toJsProp from './internals/to-js-prop.js';\r\nimport loadScript from './internals/load-script.js';\r\nimport PubSubLoader from './internals/pub-sub-loader.js';\n\nconst isNode = () => {\n try {\n return global;\n }catch(e){\n return false;\n }\n};\n\nPubSubLoader(isNode());\n\r\n/**\r\n *\r\n * @module backed\r\n * @param {class} _class\r\n */\r\nexport default _class => {\r\n const upperToHyphen = string => {\r\n return string.replace(/([A-Z])/g, \"-$1\").toLowerCase().replace('-', '');\r\n };\n\r\n const construct = (name, _class) => {\r\n if (isNode()) {\r\n return _class;\r\n } else {\r\n customElements.define(name, _class);\r\n }\r\n }\r\n\r\n\r\n // get the tagName or try to make one with class.name\r\n let name = _class.is || upperToHyphen(_class.name);\r\n // Setup properties & mixins\r\n // define/register custom-element\r\n return construct(name, class extends _class {\r\n constructor() {\r\n super();\r\n this.fireEvent = fireEvent.bind(this);\r\n this.toJsProp = toJsProp.bind(this);\r\n this.loadScript = loadScript.bind(this);\r\n\r\n Utils.handleProperties(this, _class.properties);\r\n Utils.handleObservers(this, _class.observers);\r\n }\r\n });\r\n};\r\n"],"names":["this"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"backed.js","sources":["../src/base.js","../src/internals/fire-event.js","../src/internals/to-js-prop.js","../src/internals/load-script.js","../src/internals/pub-sub.js","../src/internals/pub-sub-loader.js","../src/backed.js"],"sourcesContent":["'use strict';\n\r\nconst handleProperties = (target, properties) => {\r\n if (properties) {\r\n for (let property of Object.keys(properties)) {\r\n const observer = properties[property].observer;\r\n const strict = properties[property].strict;\n const isGlobal = properties[property].global;\n handlePropertyObserver(target, property, observer, {\n strict: strict || false,\n global: isGlobal || false\n });\n // Bind(superclass, superclass.properties)\r\n }\r\n }\r\n}\r\n\r\nconst handlePropertyObserver = (obj, property, observer, opts={\n strict: false, global:false\n}) => {\n\n if (observer && _needsObserverSetup(obj, property)) {\n obj.observedProperties.push(property);\n\n if (opts.global) {\n PubSub.subscribe(`global.${property}`, obj[observer]);\n }\n setupObserver(obj, property, observer, opts)\n }\r\n}\r\n\r\nconst _needsObserverSetup = (obj, property) => {\r\n if (!obj.observedProperties) {\r\n obj.observedProperties = [];\r\n }\r\n if (obj.observedProperties[property]) {\r\n console.warn(\r\n 'observer::ignoring duplicate property observer ' + property\r\n );\r\n return false;\r\n } else {\r\n return true;\r\n }\r\n}\n\nconst forObservers = (target, observers, isGlobal=false) => {\n for (let observe of observers) {\n let parts = observe.split(/\\(|\\)/g);\n let fn = parts[0];\n parts = parts.slice(1);\n for (let property of parts) {\n if (property.length) {\n handlePropertyObserver(target, property, fn, {\n strict: false,\n global: isGlobal\n });\n }\n }\n }\n}\n\r\n/**\r\n * Runs a method on target whenever given property changes\r\n *\r\n * example:\r\n * change(change) {\r\n * change.property // name of the property\r\n * change.value // value of the property\r\n * }\r\n *\r\n * @arg {object} obj target\r\n * @arg {string} property name\r\n * @arg {boolean} strict\r\n * @arg {method} fn The method to run on change\r\n */\r\nconst setupObserver = (obj, property, fn, opts={\n strict: false, global: false\n}) => {\n Object.defineProperty(obj, property, {\r\n set(value) {\n this[`_${property}`] = value;\n let data = {\r\n property: property,\r\n value: value\r\n };\n if (opts.global) {\n data.instance = this;\n PubSub.publish(`global.${property}`, data);\n } else {\n this[fn](data);\n }\n },\n get() {\n return this[`_${property}`];\n },\n configurable: opts.strict\n });\n}\r\n\r\n\r\nconst handleObservers = (target, observers=[], globalObservers=[]) => {\n if (!observers && !globalObservers) {\n return;\r\n }\n forObservers(target, observers);\n}\r\n\r\nexport default {\r\n handleProperties: handleProperties.bind(this),\r\n handlePropertyObserver: handlePropertyObserver.bind(this),\r\n handleObservers: handleObservers.bind(this),\r\n setupObserver: setupObserver.bind(this)\r\n}\r\n","'use strict';\r\n/**\r\n * @mixin backed\r\n * @param {string} type Name of the event\r\n * @param {HTMLElement} target Name of the event\r\n * @param {string|boolean|number|object|array} detail\r\n */\r\nexport default (type=String, detail=null, target=document) => {\r\n target.dispatchEvent(new CustomEvent(type, {detail: detail}));\r\n};\r\n","'use strict';\r\n/**\r\n * @mixin Backed\r\n *\r\n * some-prop -> someProp\r\n *\r\n * @arg {string} string The content to convert\r\n * @return {string} string\r\n */\r\nexport default string => {\r\n let parts = string.split('-');\r\n if (parts.length > 1) {\r\n var upper = parts[1].charAt(0).toUpperCase();\r\n string = parts[0] + upper + parts[1].slice(1).toLowerCase();\r\n }\r\n return string;\r\n};\r\n","'use strict';\nconst loadScript = src => {\n return new Promise((resolve, reject) => {\n let script = document.createElement('script');\n script.src = src;\n script.onload = result => {\n resolve(result);\n }\n script.onerror = error => {\n reject(error);\n }\n document.body.appendChild(script);\n });\n}\nexport default loadScript;\n","'use strict';\r\nexport default class {\r\n\r\n /**\r\n * Creates handlers\r\n */\r\n constructor() {\r\n this.handlers = [];\r\n }\r\n\r\n /**\r\n * @param {String} event\r\n * @param {Method} handler\r\n * @param {HTMLElement} context\r\n */\r\n subscribe(event, handler, context) {\r\n if (typeof context === 'undefined') {\r\n context = handler;\r\n }\r\n this.handlers.push({event: event, handler: handler.bind(context)});\r\n }\r\n\r\n /**\r\n * @param {String} event\r\n * @param {String|Number|Boolean|Object|Array} change\n */\r\n publish(event, change) {\n for (let i = 0; i < this.handlers.length; i++) {\r\n if (this.handlers[i].event === event) {\n let oldValue = this.handlers[i].oldValue || {};\n // dirty checking value, ensures that we don't create a loop\n if (oldValue.value !== change.value) {\n this.handlers[i].handler(change, this.handlers[i].oldValue);\n this.handlers[i].oldValue = change;\n }\n }\r\n }\r\n }\r\n}\r\n","'use strict';\r\nimport Pubsub from './pub-sub.js';\nexport default isWindow => {\n if (isWindow) {\n window.PubSub = window.PubSub || new Pubsub();\n } else {\n global.PubSub = global.PubSub || new Pubsub();\n }\n}\r\n","'use strict';\r\nimport base from './base.js';\nimport fireEvent from './internals/fire-event.js';\r\nimport toJsProp from './internals/to-js-prop.js';\r\nimport loadScript from './internals/load-script.js';\r\nimport PubSubLoader from './internals/pub-sub-loader.js';\r\nconst supportsCustomElementsV1 = 'customElements' in window;\nconst supportsCustomElementsV0 = 'registerElement' in document;\n\nconst isWindow = () => {\n try {\r\n return window;\n } catch(e) {\n return false;\r\n }\r\n};\n\r\n/**\r\n *\r\n * @module backed\r\n * @param {class} _class\r\n */\r\nexport default _class => {\r\n const upperToHyphen = string => {\r\n return string.replace(/([A-Z])/g, \"-$1\").toLowerCase().replace('-', '');\r\n };\n\r\n // get the tagName or try to make one with class.name\r\n let name = _class.is || upperToHyphen(_class.name);\r\n // Setup properties & observers\n\n if (isWindow()) {\n if (supportsCustomElementsV1) {\n let klass = class extends _class {\n constructor() {\n super();\n this.created();\n }\n created() {\n PubSubLoader(isWindow());\n this.fireEvent = fireEvent.bind(this);\n this.toJsProp = toJsProp.bind(this);\n this.loadScript = loadScript.bind(this);\n\n base.handleProperties(this, _class.properties);\n base.handleObservers(this, _class.observers, _class.globalObservers);\n }\n }\n customElements.define(name, klass);\n } else if (supportsCustomElementsV0) {\n let klass = class extends _class {\n createdCallback() {\n this.created();\n }\n created() {\n PubSubLoader(isWindow());\n this.fireEvent = fireEvent.bind(this);\n this.toJsProp = toJsProp.bind(this);\n this.loadScript = loadScript.bind(this);\n\n base.handleProperties(this, _class.properties);\n base.handleObservers(this, _class.observers, _class.globalObservers);\n }\n }\n document.registerElement(name, klass)\n } else {\n console.warn('classes::unsupported');\n }\n } else {\n return _class;\n }\n};\r\n"],"names":["this"],"mappings":"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"} \ No newline at end of file diff --git a/package.json b/package.json index 95078e7..153a08a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "backed", - "version": "0.0.2", + "version": "0.1.0-alpha.1", "description": "Small web framework for quick app & component development", "main": "dist/backed-node.js", "scripts": {