@endorphinjs/template-runtime
Advanced tools
Comparing version 0.1.22 to 0.1.23
@@ -229,2 +229,22 @@ 'use strict'; | ||
/** | ||
* Returns property descriptors from given object | ||
* @param {Object} obj | ||
* @return {Object} | ||
*/ | ||
const getObjectDescriptors = Object.getOwnPropertyDescriptors || function(source) { | ||
const descriptors = obj(); | ||
const props = Object.getOwnPropertyNames(source); | ||
for (let i = 0, prop, descriptor; i < props.length; i++) { | ||
prop = props[i]; | ||
descriptor = Object.getOwnPropertyDescriptor(source, prop); | ||
if (descriptor != null) { | ||
descriptors[prop] = descriptor; | ||
} | ||
} | ||
return descriptors; | ||
}; | ||
/** | ||
* Represents given attribute value in element | ||
@@ -268,2 +288,15 @@ * @param {Element} elem | ||
/** | ||
* @param {Function} fn | ||
* @param {*} [arg1] | ||
* @param {*} [arg2] | ||
*/ | ||
function safeCall(fn, arg1, arg2) { | ||
try { | ||
return fn && fn(arg1, arg2); | ||
} catch (err) { | ||
console.error(err); | ||
} | ||
} | ||
/** | ||
* Creates element with given tag name | ||
@@ -1277,19 +1310,31 @@ * @param {string} tagName | ||
/** | ||
* Invokes `fn` for each `name` hook in given definition | ||
* Walks over each definition (including given one) and runs callback on it | ||
* @param {ComponentDefinition} definition | ||
* @param {string} name | ||
* @param {function} fn | ||
* @param {(dfn: ComponentDefinition) => void} fn | ||
*/ | ||
function forEachHook(definition, name, fn) { | ||
function walkDefinitions(definition, fn) { | ||
safeCall(fn, definition); | ||
const { plugins } = definition; | ||
if (plugins) { | ||
for (let i = 0; i < plugins.length; i++) { | ||
forEachHook(plugins[i], name, fn); | ||
walkDefinitions(plugins[i], fn); | ||
} | ||
} | ||
} | ||
if (name in definition) { | ||
return fn(definition[name], definition); | ||
/** | ||
* Same as `walkDefinitions` but runs in reverse order | ||
* @param {ComponentDefinition} definition | ||
* @param {(dfn: ComponentDefinition) => void} fn | ||
*/ | ||
function reverseWalkDefinitions(definition, fn) { | ||
const { plugins } = definition; | ||
if (plugins) { | ||
let i = plugins.length; | ||
while (i--) { | ||
walkDefinitions(plugins[i], fn); | ||
} | ||
} | ||
safeCall(fn, definition); | ||
} | ||
@@ -1301,8 +1346,12 @@ | ||
* @param {string} name | ||
* @param {Array} [args] | ||
* @param {*} [arg1] | ||
* @param {*} [arg2] | ||
*/ | ||
function runHook(elem, name, args) { | ||
const hookArgs = args ? [elem].concat(args) : [elem]; | ||
return forEachHook(elem.componentModel.definition, name, hook => hook.apply(null, hookArgs)); | ||
function runHook(elem, name, arg1, arg2) { | ||
walkDefinitions(elem.componentModel.definition, dfn => { | ||
const hook = dfn[name]; | ||
if (typeof hook === 'function') { | ||
hook(elem, arg1, arg2); | ||
} | ||
}); | ||
} | ||
@@ -1362,3 +1411,3 @@ | ||
if (slotStatus[name]) { | ||
runHook(host, 'didSlotUpdate', [name, input.slots[name]]); | ||
runHook(host, 'didSlotUpdate', name, input.slots[name]); | ||
slotStatus[name] = 0; | ||
@@ -1481,5 +1530,3 @@ } | ||
function createComponent(name, definition, host) { | ||
/** @type {Component} */ | ||
// @ts-ignore | ||
const element = elem(name, host && host.componentModel && host.componentModel.definition.cssScope); | ||
const element = /** @type {Component} */ (elem(name, host && host.componentModel && host.componentModel.definition.cssScope)); | ||
@@ -1498,6 +1545,10 @@ // Add host scope marker: we can’t rely on tag name since component | ||
const defaultProps = collectData(element, definition, 'props'); | ||
// XXX Should point to Shadow Root in Web Components | ||
element.componentView = element; | ||
const { props, state, extend, methods, events } = prepare(element, definition); | ||
element.refs = {}; | ||
element.props = obj(defaultProps); | ||
element.state = collectData(element, definition, 'state'); | ||
element.props = obj(props); | ||
element.state = state; | ||
element.setProps = function setProps(value) { | ||
@@ -1533,7 +1584,6 @@ const { componentModel } = element; | ||
forEachHook(definition, 'methods', methods => assign(element, methods)); | ||
assign(element, methods); | ||
// XXX Should point to Shadow Root in Web Components | ||
if (!element.componentView) { | ||
element.componentView = element; | ||
if (extend) { | ||
Object.defineProperties(element, extend); | ||
} | ||
@@ -1563,5 +1613,5 @@ | ||
queued: null, | ||
events: attachStaticEvents(element, definition), | ||
events, | ||
dispose: null, | ||
defaultProps | ||
defaultProps: props | ||
}; | ||
@@ -1592,3 +1642,3 @@ | ||
const args = [changes || {}]; | ||
const arg = changes || {}; | ||
finalizeEvents(input); | ||
@@ -1600,21 +1650,17 @@ | ||
for (const p in input.slots) { | ||
runHook(elem$$1, 'didSlotUpdate', [p, input.slots[p]]); | ||
runHook(elem$$1, 'didSlotUpdate', p, input.slots[p]); | ||
} | ||
if (changes) { | ||
runHook(elem$$1, 'didChange', args); | ||
runHook(elem$$1, 'didChange', arg); | ||
} | ||
runHook(elem$$1, 'willMount', args); | ||
runHook(elem$$1, 'willRender', args); | ||
if (definition.default) { | ||
componentModel.update = definition.default(elem$$1, getScope(elem$$1)); | ||
} | ||
runHook(elem$$1, 'willMount', arg); | ||
runHook(elem$$1, 'willRender', arg); | ||
componentModel.update = safeCall(definition.default, elem$$1, getScope(elem$$1)); | ||
componentModel.mounted = true; | ||
componentModel.rendering = false; | ||
componentModel.finalizing = true; | ||
runHook(elem$$1, 'didRender', args); | ||
runHook(elem$$1, 'didMount', args); | ||
runHook(elem$$1, 'didRender', arg); | ||
runHook(elem$$1, 'didMount', arg); | ||
componentModel.finalizing = false; | ||
@@ -1646,3 +1692,3 @@ } | ||
const { componentModel } = elem$$1; | ||
const { slots, input, dispose } = componentModel; | ||
const { slots, input, dispose, events } = componentModel; | ||
const scope = getScope(elem$$1); | ||
@@ -1653,3 +1699,5 @@ | ||
componentModel.mounted = false; | ||
detachStaticEvents(elem$$1, componentModel.events); | ||
if (events) { | ||
detachStaticEvents(elem$$1, events); | ||
} | ||
@@ -1730,3 +1778,3 @@ if (elem$$1.store) { | ||
const { componentModel } = elem$$1; | ||
const args = [changes || {}]; | ||
const arg = changes || {}; | ||
@@ -1741,17 +1789,13 @@ if (componentModel.queued) { | ||
if (changes) { | ||
runHook(elem$$1, 'didChange', args); | ||
runHook(elem$$1, 'didChange', arg); | ||
} | ||
// TODO prepare data for hooks in `mountComponent`? | ||
runHook(elem$$1, 'willUpdate', args); | ||
runHook(elem$$1, 'willRender', args); | ||
if (componentModel.update) { | ||
componentModel.update(elem$$1, getScope(elem$$1)); | ||
} | ||
runHook(elem$$1, 'willUpdate', arg); | ||
runHook(elem$$1, 'willRender', arg); | ||
safeCall(componentModel.update, elem$$1, getScope(elem$$1)); | ||
componentModel.rendering = false; | ||
componentModel.finalizing = true; | ||
runHook(elem$$1, 'didRender', args); | ||
runHook(elem$$1, 'didUpdate', args); | ||
runHook(elem$$1, 'didRender', arg); | ||
runHook(elem$$1, 'didUpdate', arg); | ||
componentModel.finalizing = false; | ||
@@ -1761,66 +1805,10 @@ } | ||
/** | ||
* Collects data generated by `key` factory | ||
* @param {Component} host | ||
* @param {ComponentDefinition} definition | ||
* @param {string} key | ||
* @return {object} initial | ||
*/ | ||
function collectData(host, definition, key) { | ||
const data = {}; | ||
forEachHook(definition, key, hook => assign(data, hook(host))); | ||
return data; | ||
} | ||
/** | ||
* Collects and attaches static event listeners to `component` from given `definition` | ||
* @param {Component} component | ||
* @param {ComponentDefinition} definition | ||
* @return {AttachedEventsMap} Map of attached event handlers | ||
*/ | ||
function attachStaticEvents(component, definition) { | ||
/** @type {AttachedEventsMap} */ | ||
const eventMap = obj(); | ||
/** @param {Event} evt */ | ||
const handler = function (evt) { | ||
if (!component.componentModel) { | ||
// In case if component was unmounted | ||
return; | ||
} | ||
const listeners = eventMap[evt.type].listeners; | ||
for (let i = 0; i < listeners.length; i++) { | ||
listeners[i](component, evt, this); | ||
} | ||
}; | ||
forEachHook(definition, 'events', events => { | ||
if (events) { | ||
const names = Object.keys(events); | ||
for (let i = 0, name; i < names.length; i++) { | ||
name = names[i]; | ||
if (name in eventMap) { | ||
eventMap[name].listeners.push(events[name]); | ||
} else { | ||
component.addEventListener(name, handler); | ||
eventMap[name] = { | ||
handler, | ||
listeners: [events[name]] | ||
}; | ||
} | ||
} | ||
} | ||
}); | ||
return eventMap; | ||
} | ||
/** | ||
* Removes attached events from given map | ||
* @param {Component} component | ||
* @param {AttachedEventsMap} eventMap | ||
* @param {AttachedStaticEvents} eventMap | ||
*/ | ||
function detachStaticEvents(component, eventMap) { | ||
for (let p in eventMap) { | ||
component.removeEventListener(p, eventMap[p].handler); | ||
const { listeners, handler } = eventMap; | ||
for (let p in listeners) { | ||
component.removeEventListener(p, handler); | ||
} | ||
@@ -1893,2 +1881,76 @@ } | ||
/** | ||
* Prepares internal data for given component | ||
* @param {Component} component | ||
* @param {ComponentDefinition} definition | ||
*/ | ||
function prepare(component, definition) { | ||
const props = obj(); | ||
const state = obj(); | ||
const methods = obj(); | ||
/** @type {AttachedStaticEvents} */ | ||
let events; | ||
let extend; | ||
reverseWalkDefinitions(definition, dfn => { | ||
dfn.props && assign(props, dfn.props(component)); | ||
dfn.state && assign(state, dfn.state(component)); | ||
dfn.methods && assign(methods, dfn.methods); | ||
if (dfn.extend) { | ||
const descriptors = getObjectDescriptors(dfn.extend); | ||
extend = extend ? assign(extend, descriptors) : descriptors; | ||
} | ||
if (dfn.events) { | ||
if (!events) { | ||
events = createEventsMap(component); | ||
} | ||
attachEventHandlers(component, dfn.events, events); | ||
} | ||
}); | ||
return { props, state, extend, methods, events }; | ||
} | ||
/** | ||
* @param {Component} component | ||
* @returns {AttachedStaticEvents} | ||
*/ | ||
function createEventsMap(component) { | ||
/** @type {{[event: string]: ComponentEventHandler[]}} */ | ||
const listeners = obj(); | ||
/** @type {StaticEventHandler} */ | ||
const handler = function (evt) { | ||
if (component.componentModel) { | ||
const handlers = listeners[evt.type]; | ||
for (let i = 0; i < handlers.length; i++) { | ||
handlers[i](component, evt, this); | ||
} | ||
} | ||
}; | ||
return { handler, listeners }; | ||
} | ||
/** | ||
* @param {Component} component | ||
* @param {{[name: string]: ComponentEventHandler}} events | ||
* @param {AttachedStaticEvents} eventMap | ||
*/ | ||
function attachEventHandlers(component, events, eventMap) { | ||
const names = Object.keys(events); | ||
const { listeners } = eventMap; | ||
for (let i = 0, name; i < names.length; i++) { | ||
name = names[i]; | ||
if (name in listeners) { | ||
listeners[name].push(events[name]); | ||
} else { | ||
component.addEventListener(name, eventMap.handler); | ||
listeners[name] = [events[name]]; | ||
} | ||
} | ||
} | ||
/** | ||
* Renders code, returned from `get` function, as HTML | ||
@@ -1895,0 +1957,0 @@ * @param {Component} host |
@@ -225,2 +225,22 @@ /** | ||
/** | ||
* Returns property descriptors from given object | ||
* @param {Object} obj | ||
* @return {Object} | ||
*/ | ||
const getObjectDescriptors = Object.getOwnPropertyDescriptors || function(source) { | ||
const descriptors = obj(); | ||
const props = Object.getOwnPropertyNames(source); | ||
for (let i = 0, prop, descriptor; i < props.length; i++) { | ||
prop = props[i]; | ||
descriptor = Object.getOwnPropertyDescriptor(source, prop); | ||
if (descriptor != null) { | ||
descriptors[prop] = descriptor; | ||
} | ||
} | ||
return descriptors; | ||
}; | ||
/** | ||
* Represents given attribute value in element | ||
@@ -264,2 +284,15 @@ * @param {Element} elem | ||
/** | ||
* @param {Function} fn | ||
* @param {*} [arg1] | ||
* @param {*} [arg2] | ||
*/ | ||
function safeCall(fn, arg1, arg2) { | ||
try { | ||
return fn && fn(arg1, arg2); | ||
} catch (err) { | ||
console.error(err); | ||
} | ||
} | ||
/** | ||
* Creates element with given tag name | ||
@@ -1273,19 +1306,31 @@ * @param {string} tagName | ||
/** | ||
* Invokes `fn` for each `name` hook in given definition | ||
* Walks over each definition (including given one) and runs callback on it | ||
* @param {ComponentDefinition} definition | ||
* @param {string} name | ||
* @param {function} fn | ||
* @param {(dfn: ComponentDefinition) => void} fn | ||
*/ | ||
function forEachHook(definition, name, fn) { | ||
function walkDefinitions(definition, fn) { | ||
safeCall(fn, definition); | ||
const { plugins } = definition; | ||
if (plugins) { | ||
for (let i = 0; i < plugins.length; i++) { | ||
forEachHook(plugins[i], name, fn); | ||
walkDefinitions(plugins[i], fn); | ||
} | ||
} | ||
} | ||
if (name in definition) { | ||
return fn(definition[name], definition); | ||
/** | ||
* Same as `walkDefinitions` but runs in reverse order | ||
* @param {ComponentDefinition} definition | ||
* @param {(dfn: ComponentDefinition) => void} fn | ||
*/ | ||
function reverseWalkDefinitions(definition, fn) { | ||
const { plugins } = definition; | ||
if (plugins) { | ||
let i = plugins.length; | ||
while (i--) { | ||
walkDefinitions(plugins[i], fn); | ||
} | ||
} | ||
safeCall(fn, definition); | ||
} | ||
@@ -1297,8 +1342,12 @@ | ||
* @param {string} name | ||
* @param {Array} [args] | ||
* @param {*} [arg1] | ||
* @param {*} [arg2] | ||
*/ | ||
function runHook(elem, name, args) { | ||
const hookArgs = args ? [elem].concat(args) : [elem]; | ||
return forEachHook(elem.componentModel.definition, name, hook => hook.apply(null, hookArgs)); | ||
function runHook(elem, name, arg1, arg2) { | ||
walkDefinitions(elem.componentModel.definition, dfn => { | ||
const hook = dfn[name]; | ||
if (typeof hook === 'function') { | ||
hook(elem, arg1, arg2); | ||
} | ||
}); | ||
} | ||
@@ -1358,3 +1407,3 @@ | ||
if (slotStatus[name]) { | ||
runHook(host, 'didSlotUpdate', [name, input.slots[name]]); | ||
runHook(host, 'didSlotUpdate', name, input.slots[name]); | ||
slotStatus[name] = 0; | ||
@@ -1477,5 +1526,3 @@ } | ||
function createComponent(name, definition, host) { | ||
/** @type {Component} */ | ||
// @ts-ignore | ||
const element = elem(name, host && host.componentModel && host.componentModel.definition.cssScope); | ||
const element = /** @type {Component} */ (elem(name, host && host.componentModel && host.componentModel.definition.cssScope)); | ||
@@ -1494,6 +1541,10 @@ // Add host scope marker: we can’t rely on tag name since component | ||
const defaultProps = collectData(element, definition, 'props'); | ||
// XXX Should point to Shadow Root in Web Components | ||
element.componentView = element; | ||
const { props, state, extend, methods, events } = prepare(element, definition); | ||
element.refs = {}; | ||
element.props = obj(defaultProps); | ||
element.state = collectData(element, definition, 'state'); | ||
element.props = obj(props); | ||
element.state = state; | ||
element.setProps = function setProps(value) { | ||
@@ -1529,7 +1580,6 @@ const { componentModel } = element; | ||
forEachHook(definition, 'methods', methods => assign(element, methods)); | ||
assign(element, methods); | ||
// XXX Should point to Shadow Root in Web Components | ||
if (!element.componentView) { | ||
element.componentView = element; | ||
if (extend) { | ||
Object.defineProperties(element, extend); | ||
} | ||
@@ -1559,5 +1609,5 @@ | ||
queued: null, | ||
events: attachStaticEvents(element, definition), | ||
events, | ||
dispose: null, | ||
defaultProps | ||
defaultProps: props | ||
}; | ||
@@ -1588,3 +1638,3 @@ | ||
const args = [changes || {}]; | ||
const arg = changes || {}; | ||
finalizeEvents(input); | ||
@@ -1596,21 +1646,17 @@ | ||
for (const p in input.slots) { | ||
runHook(elem$$1, 'didSlotUpdate', [p, input.slots[p]]); | ||
runHook(elem$$1, 'didSlotUpdate', p, input.slots[p]); | ||
} | ||
if (changes) { | ||
runHook(elem$$1, 'didChange', args); | ||
runHook(elem$$1, 'didChange', arg); | ||
} | ||
runHook(elem$$1, 'willMount', args); | ||
runHook(elem$$1, 'willRender', args); | ||
if (definition.default) { | ||
componentModel.update = definition.default(elem$$1, getScope(elem$$1)); | ||
} | ||
runHook(elem$$1, 'willMount', arg); | ||
runHook(elem$$1, 'willRender', arg); | ||
componentModel.update = safeCall(definition.default, elem$$1, getScope(elem$$1)); | ||
componentModel.mounted = true; | ||
componentModel.rendering = false; | ||
componentModel.finalizing = true; | ||
runHook(elem$$1, 'didRender', args); | ||
runHook(elem$$1, 'didMount', args); | ||
runHook(elem$$1, 'didRender', arg); | ||
runHook(elem$$1, 'didMount', arg); | ||
componentModel.finalizing = false; | ||
@@ -1642,3 +1688,3 @@ } | ||
const { componentModel } = elem$$1; | ||
const { slots, input, dispose } = componentModel; | ||
const { slots, input, dispose, events } = componentModel; | ||
const scope = getScope(elem$$1); | ||
@@ -1649,3 +1695,5 @@ | ||
componentModel.mounted = false; | ||
detachStaticEvents(elem$$1, componentModel.events); | ||
if (events) { | ||
detachStaticEvents(elem$$1, events); | ||
} | ||
@@ -1726,3 +1774,3 @@ if (elem$$1.store) { | ||
const { componentModel } = elem$$1; | ||
const args = [changes || {}]; | ||
const arg = changes || {}; | ||
@@ -1737,17 +1785,13 @@ if (componentModel.queued) { | ||
if (changes) { | ||
runHook(elem$$1, 'didChange', args); | ||
runHook(elem$$1, 'didChange', arg); | ||
} | ||
// TODO prepare data for hooks in `mountComponent`? | ||
runHook(elem$$1, 'willUpdate', args); | ||
runHook(elem$$1, 'willRender', args); | ||
if (componentModel.update) { | ||
componentModel.update(elem$$1, getScope(elem$$1)); | ||
} | ||
runHook(elem$$1, 'willUpdate', arg); | ||
runHook(elem$$1, 'willRender', arg); | ||
safeCall(componentModel.update, elem$$1, getScope(elem$$1)); | ||
componentModel.rendering = false; | ||
componentModel.finalizing = true; | ||
runHook(elem$$1, 'didRender', args); | ||
runHook(elem$$1, 'didUpdate', args); | ||
runHook(elem$$1, 'didRender', arg); | ||
runHook(elem$$1, 'didUpdate', arg); | ||
componentModel.finalizing = false; | ||
@@ -1757,66 +1801,10 @@ } | ||
/** | ||
* Collects data generated by `key` factory | ||
* @param {Component} host | ||
* @param {ComponentDefinition} definition | ||
* @param {string} key | ||
* @return {object} initial | ||
*/ | ||
function collectData(host, definition, key) { | ||
const data = {}; | ||
forEachHook(definition, key, hook => assign(data, hook(host))); | ||
return data; | ||
} | ||
/** | ||
* Collects and attaches static event listeners to `component` from given `definition` | ||
* @param {Component} component | ||
* @param {ComponentDefinition} definition | ||
* @return {AttachedEventsMap} Map of attached event handlers | ||
*/ | ||
function attachStaticEvents(component, definition) { | ||
/** @type {AttachedEventsMap} */ | ||
const eventMap = obj(); | ||
/** @param {Event} evt */ | ||
const handler = function (evt) { | ||
if (!component.componentModel) { | ||
// In case if component was unmounted | ||
return; | ||
} | ||
const listeners = eventMap[evt.type].listeners; | ||
for (let i = 0; i < listeners.length; i++) { | ||
listeners[i](component, evt, this); | ||
} | ||
}; | ||
forEachHook(definition, 'events', events => { | ||
if (events) { | ||
const names = Object.keys(events); | ||
for (let i = 0, name; i < names.length; i++) { | ||
name = names[i]; | ||
if (name in eventMap) { | ||
eventMap[name].listeners.push(events[name]); | ||
} else { | ||
component.addEventListener(name, handler); | ||
eventMap[name] = { | ||
handler, | ||
listeners: [events[name]] | ||
}; | ||
} | ||
} | ||
} | ||
}); | ||
return eventMap; | ||
} | ||
/** | ||
* Removes attached events from given map | ||
* @param {Component} component | ||
* @param {AttachedEventsMap} eventMap | ||
* @param {AttachedStaticEvents} eventMap | ||
*/ | ||
function detachStaticEvents(component, eventMap) { | ||
for (let p in eventMap) { | ||
component.removeEventListener(p, eventMap[p].handler); | ||
const { listeners, handler } = eventMap; | ||
for (let p in listeners) { | ||
component.removeEventListener(p, handler); | ||
} | ||
@@ -1889,2 +1877,76 @@ } | ||
/** | ||
* Prepares internal data for given component | ||
* @param {Component} component | ||
* @param {ComponentDefinition} definition | ||
*/ | ||
function prepare(component, definition) { | ||
const props = obj(); | ||
const state = obj(); | ||
const methods = obj(); | ||
/** @type {AttachedStaticEvents} */ | ||
let events; | ||
let extend; | ||
reverseWalkDefinitions(definition, dfn => { | ||
dfn.props && assign(props, dfn.props(component)); | ||
dfn.state && assign(state, dfn.state(component)); | ||
dfn.methods && assign(methods, dfn.methods); | ||
if (dfn.extend) { | ||
const descriptors = getObjectDescriptors(dfn.extend); | ||
extend = extend ? assign(extend, descriptors) : descriptors; | ||
} | ||
if (dfn.events) { | ||
if (!events) { | ||
events = createEventsMap(component); | ||
} | ||
attachEventHandlers(component, dfn.events, events); | ||
} | ||
}); | ||
return { props, state, extend, methods, events }; | ||
} | ||
/** | ||
* @param {Component} component | ||
* @returns {AttachedStaticEvents} | ||
*/ | ||
function createEventsMap(component) { | ||
/** @type {{[event: string]: ComponentEventHandler[]}} */ | ||
const listeners = obj(); | ||
/** @type {StaticEventHandler} */ | ||
const handler = function (evt) { | ||
if (component.componentModel) { | ||
const handlers = listeners[evt.type]; | ||
for (let i = 0; i < handlers.length; i++) { | ||
handlers[i](component, evt, this); | ||
} | ||
} | ||
}; | ||
return { handler, listeners }; | ||
} | ||
/** | ||
* @param {Component} component | ||
* @param {{[name: string]: ComponentEventHandler}} events | ||
* @param {AttachedStaticEvents} eventMap | ||
*/ | ||
function attachEventHandlers(component, events, eventMap) { | ||
const names = Object.keys(events); | ||
const { listeners } = eventMap; | ||
for (let i = 0, name; i < names.length; i++) { | ||
name = names[i]; | ||
if (name in listeners) { | ||
listeners[name].push(events[name]); | ||
} else { | ||
component.addEventListener(name, eventMap.handler); | ||
listeners[name] = [events[name]]; | ||
} | ||
} | ||
} | ||
/** | ||
* Renders code, returned from `get` function, as HTML | ||
@@ -1891,0 +1953,0 @@ * @param {Component} host |
{ | ||
"name": "@endorphinjs/template-runtime", | ||
"version": "0.1.22", | ||
"version": "0.1.23", | ||
"description": "EndorphinJS template runtime, embedded with template bundles", | ||
@@ -5,0 +5,0 @@ "main": "./dist/runtime.cjs.js", |
@@ -6,2 +6,4 @@ import { Store } from './lib/store'; | ||
type InjectorItem = any; | ||
type ComponentEventHandler = (component: Component, event: Event, target: HTMLElement) => void; | ||
type StaticEventHandler = (evt: Event) => void; | ||
@@ -108,3 +110,3 @@ interface DisposeCallback { | ||
*/ | ||
events: AttachedEventsMap; | ||
events: AttachedStaticEvents; | ||
@@ -166,3 +168,3 @@ /** Slot output for component */ | ||
*/ | ||
props?(): object; | ||
props?(component: Component): object; | ||
@@ -172,3 +174,3 @@ /** | ||
*/ | ||
state?(): object; | ||
state?(component: Component): object; | ||
@@ -189,3 +191,3 @@ /** | ||
events?: { | ||
[type: string]: (component: Component, event: Event, target: HTMLElement) => void; | ||
[type: string]: ComponentEventHandler; | ||
}; | ||
@@ -195,2 +197,3 @@ | ||
* Public methods to attach to component element | ||
* @deprecated Use `extend` instead | ||
*/ | ||
@@ -202,2 +205,7 @@ methods?: { | ||
/** | ||
* Methods and properties to extend component with | ||
*/ | ||
extend?: object; | ||
/** | ||
* List of plugins for current component | ||
@@ -329,6 +337,6 @@ */ | ||
interface AttachedEventsMap { | ||
[event: string]: { | ||
listeners: Function[]; | ||
handler: EventListener; | ||
interface AttachedStaticEvents { | ||
handler: StaticEventHandler; | ||
listeners: { | ||
[event: string]: ComponentEventHandler[]; | ||
} | ||
@@ -335,0 +343,0 @@ } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
351338
4611