{"version":3,"file":"ceb.min.js","sources":["../src/ceb.js"],"names":["g","factory","exports","module","define","amd","ceb","this","emptyFn","listValues","o","Object","keys","map","propName","fromCamelCaseToHyphenCase","value","split","part","charAt","toLowerCase","slice","join","compareLevels","a","b","level","applyAttributeValue","el","attName","isBoolean","hasAttribute","setAttribute","removeAttribute","undefined","getAttribute","accessorFactory","wrappers","wrapped","stack","sort","reduce","previous","current","bind","apply","arguments","attributeAccessorSetFactory","setter","attValue","call","attributeAccessorGetFactory","getter","methodFactory","args","Array","prototype","length","sanitizeStructure","struct","create","HTMLElement","features","interceptors","listeners","properties","methods","assign","createdCallback","attachedCallback","detachedCallback","attributeChangedCallback","setupFeatures","builder","tagName","registered","forEach","feature","fn","setup","options","createAttributesHash","filter","property","createDefinedPropertiesHash","definedProperty","configurable","enumerable","attribute","set","get","hasOwnProperty","writable","setStack","getStack","createMethodsHash","methName","build","attributes","definedProperties","defineProperties","wrappedMethods","document","registerElement","delegableSetAccessorInterceptor","next","target","querySelector","delegate","targetPropName","targetAttName","delegableGetAccessorInterceptor","result","eventListener","evt","baseStructFactory","builtInFeature","sanitizeProperty","name","params","api","wrap","isNaN","push","intercept","setFn","getFn","anExtend","aProto","someProperties","sanitizedProperties","givenValue","currentValue","someMethods","listen","queries","trim","query","parts","event","listener","register","defineProperty","source","key","valueFactory","Number","MAX_VALUE","__eventHandlers","callback","addEventListener","handler","removeEventListener","oldVal","newVal"],"mappings":"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","sourcesContent":["(function (g, factory) {\n 'use strict';\n\n // Export the **ceb** function according the detected loader.\n\n /* istanbul ignore next */\n if(typeof exports === 'object') {\n module.exports = factory();\n } else if(typeof define === 'function' && define.amd) {\n define('ceb', [], factory);\n } else {\n g.ceb = factory();\n }\n\n}(this, function () {\n 'use strict';\n\n // ## Polyfill\n\n /* istanbul ignore next */\n if(!('assign' in Object)) {\n /* https://github.com/paulmillr/es6-shim/blob/master/es6-shim.js */\n Object.defineProperty(Object, 'assign', {\n configurable: true,\n enumerable: false,\n writable: true,\n value: function polyfillAssign() {\n return Array.prototype.reduce.call(arguments, function (target, source) {\n return Object.keys(Object(source)).reduce(function (target, key) {\n target[key] = source[key];\n return target;\n }, target);\n });\n }\n });\n }\n\n // ## Tools\n\n // Return a new empty function.\n function emptyFn() {\n return function () {};\n }\n\n // List the values of an object.\n function listValues(o) {\n return Object.keys(o).map(function (propName) {\n return o[propName];\n });\n }\n\n // Transform property notation to attribute notation.\n function fromCamelCaseToHyphenCase(value) {\n return value.split(/(?=[A-Z])/).map(function (part) {\n return part.charAt(0).toLowerCase() + part.slice(1);\n }).join('-');\n }\n\n // Compare object according to their levels.\n function compareLevels(a, b) {\n return a.level - b.level;\n }\n\n // Apply an attribute value to an element.\n function applyAttributeValue(el, attName, value, isBoolean) {\n if(isBoolean) {\n // Handle boolean value\n if(value && !el.hasAttribute(attName)) {\n // Set attribute only if the attribute is not preset\n el.setAttribute(attName, '');\n } else if(!value && el.hasAttribute(attName)) {\n // The value is false so the attribute must be removed\n el.removeAttribute(attName);\n }\n } else {\n // Handle none boolean value\n if((value === null || value === undefined) && el.hasAttribute(attName)) {\n // There is no value, so the attribute must be removed\n el.removeAttribute(attName);\n } else if((value !== null && value !== undefined) && el.getAttribute(attName) !== value) {\n // Sync the attribute value with value\n el.setAttribute(attName, value);\n }\n }\n }\n\n // Create an accessor function in order to wrap the original accessor with its accessors.\n function accessorFactory(wrappers, wrapped, propName) {\n // Order the stack of wrappers\n var stack = wrappers.sort(compareLevels);\n return function accessor() {\n var el = this;\n // The first function of the stack is called,\n // calling the next function when its argument function next is called.\n // The original accessor is the last call.\n return stack.reduce(function (previous, current) {\n return current.bind(el, previous, el, propName);\n }, wrapped.bind(el, el, propName)).apply(el, arguments);\n };\n }\n\n // Create the accessor set for a property linked to an attribute\n function attributeAccessorSetFactory(attName, setter, isBoolean) {\n return function attributeAccessorSet(el, propName, value) {\n // By default, the attribute value is the set value.\n var attValue = value;\n if(setter) {\n // The default value can be overridden by a given setter.\n attValue = setter.call(el, el, propName, value);\n }\n // Finally apply the attribute to the linked attribute.\n applyAttributeValue(el, attName, attValue, isBoolean);\n };\n }\n\n // Create the accessor get for a property linked to an attribute\n function attributeAccessorGetFactory(attName, getter, isBoolean) {\n return function attributeAccessorGet(el, propName) {\n // By default, the returned value is the attribute value.\n var value = isBoolean ? el.hasAttribute(attName) : el.getAttribute(attName);\n if(getter) {\n // The returned value can be overridden by a given getter.\n value = getter.call(el, el, propName, value);\n }\n // Finally the value is returned\n return value;\n };\n }\n\n // Create an element's method\n function methodFactory(wrappers, wrapped) {\n // Order the stack of wrappers\n var stack = wrappers.sort(compareLevels);\n return function () {\n var el = this;\n // The first function of the stack is called, calling the next function when its argument function next is called.\n // The original method is the last call.\n return stack.reduce(function (previous, current) {\n return current.bind(el, function next(args) {\n return previous.apply(el, Array.prototype.slice.call(args).slice(2, args.length));\n }, el);\n }, wrapped.bind(el, el)).apply(el, arguments);\n };\n }\n\n // ## Life cycle\n\n // Sanitize a structure to avoid the errors `?? not defined`\n function sanitizeStructure(struct) {\n struct.prototype = struct.prototype || Object.create(HTMLElement.prototype);\n struct.features = struct.features || [];\n struct.interceptors = struct.interceptors || [];\n struct.wrappers = struct.wrappers || [];\n struct.listeners = struct.listeners || [];\n struct.properties = struct.properties || {};\n struct.methods = Object.assign({\n createdCallback: emptyFn(),\n attachedCallback: emptyFn(),\n detachedCallback: emptyFn(),\n attributeChangedCallback: emptyFn()\n }, struct.methods);\n return struct;\n }\n\n // Call the setup's method of features.\n function setupFeatures(struct) {\n // Create a builder from the current structure.\n var b = builder(struct.tagName, {\n struct: struct,\n registered: true\n });\n // Call setup functions according their features's levels.\n struct.features.sort(compareLevels).forEach(function (feature) {\n if(feature.fn && feature.fn.setup) {\n feature.fn.setup(struct, b, feature.options);\n }\n });\n }\n\n // Create an hash of attributes from the structure's properties.\n // The hash of attributes is used to keep in sync properties' values and attributes' values.\n function createAttributesHash(struct) {\n return listValues(struct.properties).filter(function (property) {\n return property.attName;\n }).reduce(function (previous, current) {\n previous[current.attName] = current;\n return previous;\n }, {});\n }\n\n // Create an hash of defined properties from the structure's properties.\n // The defined properties are the input of Object.defineProperties().\n function createDefinedPropertiesHash(struct) {\n return listValues(struct.properties).map(function (property) {\n // By default properties should not be configurable but enumerable.\n var definedProperty = {\n configurable: false,\n enumerable: true\n };\n\n if(property.attribute) {\n // Create attribute accessors.\n property.set = attributeAccessorSetFactory(property.attName, property.setter, !!property.attribute.boolean);\n property.get = attributeAccessorGetFactory(property.attName, property.getter, !!property.attribute.boolean);\n } else if(property.hasOwnProperty('value') && property.hasOwnProperty('writable') && !property.writable) {\n // A constant has a value which is not writable.\n definedProperty.value = property.value;\n definedProperty.writable = false;\n if(property.hasOwnProperty('enumerable')) {\n definedProperty.enumerable = property.enumerable;\n }\n } else if(!property.set && !property.get) {\n // A none constant property without accessor must be writable.\n definedProperty.writable = true;\n }\n\n if(!definedProperty.hasOwnProperty('writable')) {\n // Create the property's function set and get according to their interceptors.\n var interceptors = struct.interceptors[property.propName] || {};\n if(property.set) {\n var setStack = interceptors.set || [];\n definedProperty.set = accessorFactory(setStack, property.set, property.propName);\n }\n if(property.get) {\n var getStack = interceptors.get || [];\n definedProperty.get = accessorFactory(getStack, property.get, property.propName);\n }\n }\n\n // Finally add the defined property to the current property.\n return Object.assign(property, {\n definedProperty: definedProperty\n });\n }).reduce(function (previous, current) {\n previous[current.propName] = current.definedProperty;\n return previous;\n }, {});\n }\n\n // Create an hash of methods from the structure's methods.\n function createMethodsHash(struct) {\n // Iterate over methods in order to wrap them with their wrappers.\n return Object.keys(struct.methods).map(function (methName) {\n var stack = struct.wrappers[methName] || [];\n var fn = struct.methods[methName];\n return {\n methName: methName,\n fn: methodFactory(stack, fn)\n };\n }).reduce(function (previous, current) {\n previous[current.methName] = current.fn;\n return previous;\n }, {});\n }\n\n // ## Build\n\n // Work with the structure in order to register the corresponding custom element.\n function build(struct) {\n // Clean the structure to avoid potential errors.\n sanitizeStructure(struct);\n\n // Let's feature enhanced the structure.\n setupFeatures(struct);\n\n // Build an hash of attribute for sync attributes' and properties' values.\n struct.attributes = createAttributesHash(struct);\n\n // Create the public properties definition of the custom element.\n var definedProperties = createDefinedPropertiesHash(struct);\n // Apply the public properties definition to the custom element prototype.\n Object.defineProperties(struct.prototype, definedProperties);\n\n // Override the originals methods to create the wrapped ones.\n var wrappedMethods = createMethodsHash(struct);\n\n // Apply the wrapped methods to the custom element prototype.\n Object.assign(struct.prototype, wrappedMethods);\n\n // Register the custom element according to its structure.\n return document.registerElement(struct.tagName, struct);\n }\n\n // ## Built-in feature\n\n // **ceb** defines an internal feature in order to add runtime functionalities:\n // - initialize properties' values\n // - add and remove event listeners\n // - sync properties' values when theirs linked attributes change\n // - handle delegation of property access to a child element\n\n // ### Interceptors\n\n // Intercept write accesses of delegable properties.\n function delegableSetAccessorInterceptor(property, next, el, propName, value) {\n next(value);\n // Logic should be done after the effective write.\n var target = el.querySelector(property.delegate.target);\n /* istanbul ignore else */\n if(target) {\n // Resolve the eventual targeted property's name or attribute's name.\n var targetPropName = property.delegate.property;\n var targetAttName = property.delegate.attribute;\n if(!targetPropName && !targetAttName) {\n targetPropName = property.propName;\n targetAttName = property.attName;\n }\n // Check the boolean nature of the value.\n var isBoolean = property.attribute && !!property.attribute.boolean;\n if(property.delegate.hasOwnProperty('boolean')) {\n isBoolean = property.delegate.boolean;\n }\n // Apply change to the child.\n if(targetAttName) {\n // Update the child's attribute value.\n applyAttributeValue(target, targetAttName, value, isBoolean);\n } else {\n // Update the child's property value.\n target[targetPropName] = value;\n }\n }\n }\n\n // Intercept read accesses of delegable properties.\n function delegableGetAccessorInterceptor(property, next, el, propName, value) {\n var result = next(value);\n // Logic should be done after the effective write.\n var target = el.querySelector(property.delegate.target);\n /* istanbul ignore else */\n if(target) {\n // Resolve the eventual targeted property's name or attribute's name.\n var targetPropName = property.delegate.property;\n var targetAttName = property.delegate.attribute;\n if(!targetPropName && !targetAttName) {\n targetPropName = property.propName;\n targetAttName = property.attName;\n }\n // Check the boolean nature of the value.\n var isBoolean = property.attribute && !!property.attribute.boolean;\n if(property.delegate.hasOwnProperty('boolean')) {\n isBoolean = property.delegate.boolean;\n }\n // Get value from the child.\n if(targetAttName) {\n // Get the child's attribute value.\n result = isBoolean ? target.hasAttribute(targetAttName) : target.getAttribute(targetAttName);\n } else {\n // Get the child's property value.\n result = target[targetPropName];\n }\n }\n return result;\n }\n\n // ### Listeners\n\n // DOM event listener calling the structure's event listener.\n function eventListener(el, fn, evt) {\n fn(el, evt);\n }\n\n // ### Feature's functions\n\n // Initialize the builtInFeature;\n var builtInFeature = emptyFn();\n // The setup function of the built-in feature\n builtInFeature.setup = function (struct, builder) {\n // Iterate over structure's properties in order to detect delegable properties.\n listValues(struct.properties).filter(function (property) {\n return property.delegate;\n }).forEach(function (property) {\n if(!property.attName) {\n // Force the existence of getter and setter to handle interception.\n property.set = property.set || emptyFn();\n property.get = property.get || emptyFn();\n }\n // Create interceptor for the delegable property.\n builder.intercept(\n property.propName,\n delegableSetAccessorInterceptor.bind(this, property),\n delegableGetAccessorInterceptor.bind(this, property)\n );\n });\n // Apply initial values to properties.\n builder.wrap('createdCallback', function (next, el) {\n next(arguments);\n listValues(struct.properties).filter(function (property) {\n // Skip only properties having an attribute's value set.\n return !el.hasAttribute(property.attName);\n }).forEach(function (property) {\n if(property.hasOwnProperty('value') && property.writable) {\n el[property.propName] = property.value;\n } else if(property.valueFactory) {\n el[property.propName] = property.valueFactory(el);\n }\n });\n });\n // Apply attributes' values to properties.\n builder.wrap('createdCallback', function (next, el) {\n next(arguments);\n // Initialize the attributes' value after the call of the createdCallback method.\n listValues(struct.properties).filter(function (property) {\n // Keep only properties having an attribute's value set.\n return el.hasAttribute(property.attName);\n }).forEach(function (property) {\n el[property.propName] = property.attribute.boolean ? true : el.getAttribute(property.attName);\n });\n }, Number.MAX_VALUE);\n // Wrap the method attachedCallback.\n builder.wrap('attachedCallback', function (next, el) {\n next(arguments);\n // Add the event listeners after the call of the attachedCallback method.\n el.__eventHandlers = struct.listeners.map(function (listener) {\n var target = listener.target ? el.querySelector(listener.target) : el;\n var callback = eventListener.bind(el, el, listener.fn);\n target.addEventListener(listener.event, callback, true);\n return {\n event: listener.event,\n target: target,\n callback: callback\n };\n });\n });\n // Wrap the method detachedCallback.\n builder.wrap('detachedCallback', function (next, el) {\n // Remove the event listeners before the call of the detachedCallback method.\n el.__eventHandlers.forEach(function (handler) {\n handler.target.removeEventListener(handler.event, handler.callback, true);\n });\n el.__eventHandlers = null;\n next(arguments);\n });\n // Wrap the method attributeChangedCallback.\n builder.wrap('attributeChangedCallback', function (next, el, attName, oldVal, newVal) {\n // Synchronize the attributes' values with their properties\n var property = struct.attributes[attName];\n if(property) {\n var value = newVal;\n if(property.attribute.boolean) {\n value = typeof newVal === 'string' ? true : false;\n }\n if(el[property.propName] !== value) {\n el[property.propName] = value;\n }\n }\n next(arguments);\n });\n };\n\n // ## ceb\n\n // Create a base and valid structure;\n function baseStructFactory() {\n return {\n properties: {},\n methods: {},\n wrappers: [],\n interceptors: [],\n listeners: [],\n features: [{\n fn: builtInFeature\n }]\n };\n }\n\n // Sanitize the properties on the fly\n function sanitizeProperty(property) {\n if(property.attribute) {\n // A property linked to an attribute must have a valid attribute name\n property.attName = fromCamelCaseToHyphenCase(property.attribute.name || property.propName);\n }\n // By default a property is writable\n property.writable = property.hasOwnProperty('writable') ? property.writable : true;\n return property;\n }\n\n // Provides the sugar API of **ceb**.\n function builder(tagName, params) {\n // The structure of the builder can be given from the parameters.\n var struct = params && params.struct ? sanitizeStructure(params.struct) : baseStructFactory();\n // A structure must have a tag name.\n struct.tagName = tagName;\n // A strucuture which is already registered will not register the custom element twice.\n var registered = params && params.hasOwnProperty('registered') ? params.registered : false;\n var api = {};\n // Add a wrapper to the structure.\n api.wrap = function (methName, fn, level) {\n if(!struct.wrappers[methName]) {\n struct.wrappers[methName] = [];\n }\n fn.level = isNaN(level) ? 0 : level;\n struct.wrappers[methName].push(fn);\n return api;\n };\n // Add an interceptor to the structure.\n api.intercept = function (propName, setFn, getFn, level) {\n if(!struct.interceptors[propName]) {\n struct.interceptors[propName] = {\n set: [],\n get: []\n };\n }\n if(setFn) {\n setFn.level = isNaN(level) ? 0 : level;\n struct.interceptors[propName].set.push(setFn);\n }\n if(getFn) {\n getFn.level = isNaN(level) ? 0 : level;\n struct.interceptors[propName].get.push(getFn);\n }\n return api;\n };\n // Set the extends value\n api['extends'] = function (anExtend) {\n struct['extends'] = anExtend;\n return api;\n };\n // Set the herited prototype\n api.prototype = function (aProto) {\n struct.prototype = aProto;\n return api;\n };\n // Add properties to the structure.\n api.properties = function (someProperties) {\n var sanitizedProperties = Object.keys(someProperties).map(function (propName) {\n var givenValue = someProperties[propName];\n var currentValue = struct.properties[propName];\n return Object.assign({\n propName: propName\n }, givenValue, currentValue || {});\n }).map(sanitizeProperty).reduce(function (previous, current) {\n previous[current.propName] = current;\n return previous;\n }, {});\n Object.assign(struct.properties, sanitizedProperties);\n return api;\n };\n // Add methods to the structure.\n api.methods = function (someMethods) {\n Object.assign(struct.methods, someMethods);\n return api;\n };\n // Add a listener to the structure.\n api.listen = function (queries, fn) {\n queries.trim().split(',').map(function (query) {\n var parts = query.trim().split(' ');\n return {\n event: parts[0].trim(),\n target: (parts[1] || '').trim(),\n fn: fn\n };\n }).forEach(function (listener) {\n struct.listeners.push(listener);\n });\n return api;\n };\n // Add a feature to the structure.\n api.feature = function (fn, options, level) {\n struct.features.push({\n fn: fn,\n options: options || {},\n level: isNaN(level) ? 0 : level\n });\n return api;\n };\n // Register the custom element if not already done.\n api.register = function () {\n if(!registered) {\n registered = true;\n return build(struct);\n }\n };\n // Get the current structure.\n api.get = function () {\n return struct;\n };\n return api;\n }\n\n // The `ced()` function.\n function ceb(params) {\n var api = {};\n // A builder is given when a name is known.\n api.name = function (tagName) {\n return builder(tagName, params);\n };\n return api;\n }\n\n return ceb;\n}));\n"]}