@endorphinjs/template-runtime
Advanced tools
Comparing version 0.1.9 to 0.1.10
@@ -28,6 +28,6 @@ 'use strict'; | ||
* @param {*} [ctx] | ||
* @returns {boolean} Returns `true` if data was updated | ||
* @returns {number} Returns `1` if data was updated, `0` otherwise | ||
*/ | ||
function finalizeItems(items, change, ctx) { | ||
let updated = false; | ||
let updated = 0; | ||
const { cur, prev } = items; | ||
@@ -38,3 +38,3 @@ | ||
if (curValue !== prevValue) { | ||
updated = true; | ||
updated = 1; | ||
change(name, prevValue, prev[name] = curValue, ctx); | ||
@@ -238,3 +238,5 @@ } | ||
function text(value) { | ||
return document.createTextNode(textValue(value)); | ||
const node = document.createTextNode(textValue(value)); | ||
node['$value'] = value; | ||
return node; | ||
} | ||
@@ -246,12 +248,12 @@ | ||
* @param {*} value | ||
* @param {*} prevValue | ||
* @return {*} New value used in text node | ||
* @returns {number} Returns `1` if text was updated, `0` otherwise | ||
*/ | ||
function updateText(node, value, prevValue) { | ||
if (value !== prevValue) { | ||
function updateText(node, value) { | ||
if (value !== node['$value']) { | ||
node.nodeValue = textValue(value); | ||
return value; | ||
node['$value'] = value; | ||
return 1; | ||
} | ||
return prevValue; | ||
return 0; | ||
} | ||
@@ -291,3 +293,3 @@ | ||
* @param {Injector} injector | ||
* @returns {boolean} Update status | ||
* @returns {number} Update status | ||
*/ | ||
@@ -341,5 +343,8 @@ function finalizeEvents(injector) { | ||
* @param {*} value | ||
* @return {number} Update status. Always returns `0` since actual attribute value | ||
* is defined in `finalizeAttributes()` | ||
*/ | ||
function setAttribute(injector, name, value) { | ||
injector.attributes.cur[name] = value; | ||
return 0; | ||
} | ||
@@ -406,35 +411,11 @@ | ||
* @param {Injector} injector | ||
* @return {number} Update status | ||
* @return {number} | ||
*/ | ||
function finalizeAttributes(injector) { | ||
return finalizeItems(normalize(injector).attributes, changeAttribute, injector.parentNode); | ||
} | ||
/** | ||
* Applies pending attributes changes to injector’s host element as props | ||
* @param {Injector} injector | ||
* @param {Object} [data] Additional props (most likely static ones) | ||
* @return {Changes} Updated props, if any | ||
*/ | ||
function finalizeProps(injector, data) { | ||
const changes = data || obj(); | ||
const updated = finalizeItems(normalize(injector).attributes, changeProp, changes); | ||
if (data || updated) { | ||
return /** @type {Component} */ (injector.parentNode).setProps(changes); | ||
} | ||
} | ||
/** | ||
* Normalizes attributes in given injector | ||
* @param {Injector} injector | ||
*/ | ||
function normalize(injector) { | ||
const { attributes } = injector; | ||
const className = attributes.cur['class']; | ||
if (isDefined(className)) { | ||
attributes.cur['class'] = normalizeClassName(className); | ||
if (isDefined(attributes.cur['class'])) { | ||
attributes.cur['class'] = normalizeClassName(attributes.cur['class']); | ||
} | ||
return injector; | ||
return finalizeItems(attributes, changeAttribute, injector.parentNode); | ||
} | ||
@@ -478,13 +459,2 @@ | ||
/** | ||
* Callback for changing attribute value | ||
* @param {string} name | ||
* @param {*} prevValue | ||
* @param {*} newValue | ||
* @param {object} changes | ||
*/ | ||
function changeProp(name, prevValue, newValue, changes) { | ||
changes[name] = newValue; | ||
} | ||
/** | ||
* Enters new variable scope context | ||
@@ -589,3 +559,5 @@ * @param {Component} host | ||
}; | ||
host.componentModel.slots[name] = mountBlock(host, createInjector(elem), blockEntry); | ||
const { slots } = host.componentModel; | ||
slots[name] = mountBlock(host, createInjector(elem), blockEntry); | ||
} | ||
@@ -598,6 +570,13 @@ | ||
function updateSlots(host) { | ||
const { slots } = host.componentModel; | ||
const { slots, slotStatus, input } = host.componentModel; | ||
for (const name in slots) { | ||
updateBlock(slots[name]); | ||
} | ||
for (const name in slotStatus) { | ||
if (slotStatus[name]) { | ||
runHook(host, 'didSlotUpdate', [name, input.slots[name]]); | ||
slotStatus[name] = 0; | ||
} | ||
} | ||
} | ||
@@ -640,2 +619,17 @@ | ||
/** | ||
* Marks slot update status | ||
* @param {Component} component | ||
* @param {string} slotName | ||
* @param {number} status | ||
*/ | ||
function markSlotUpdate(component, slotName, status) { | ||
const { slotStatus } = component.componentModel; | ||
if (slotName in slotStatus) { | ||
slotStatus[slotName] |= status; | ||
} else { | ||
slotStatus[slotName] = status; | ||
} | ||
} | ||
/** | ||
* Creates internal lightweight Endorphin component with given definition | ||
@@ -666,5 +660,5 @@ * @param {string} name | ||
element.refs = {}; | ||
element.props = assign(obj(), defaultProps); | ||
element.props = obj(defaultProps); | ||
element.state = collectData(definition, 'state'); | ||
element.setProps = function setProps(value, silent) { | ||
element.setProps = function setProps(value) { | ||
const { componentModel } = element; | ||
@@ -674,20 +668,9 @@ | ||
// check if `componentModel` is available | ||
if (!componentModel || value == null) { | ||
return; | ||
if (value != null && componentModel && componentModel.mounted) { | ||
const changes = setPropsInternal(element, element.props, obj(value)); | ||
changes && renderNext(element, changes); | ||
} | ||
value = fillDefaults(value, defaultProps); | ||
const changes = changed(value, element.props); | ||
if (changes) { | ||
assign(element.props, value); | ||
representProps(element, value); | ||
if (!silent && componentModel.mounted) { | ||
renderNext(element, changes); | ||
} | ||
} | ||
return changes; | ||
}; | ||
element.setState = function setState(value, silent) { | ||
element.setState = function setState(value) { | ||
const { componentModel } = element; | ||
@@ -697,3 +680,3 @@ | ||
// check if `componentModel` is available | ||
if (componentModel && value != null && changed(value, element.state)) { | ||
if (value != null && componentModel && hasChanges(element.state, value)) { | ||
assign(element.state, value); | ||
@@ -706,3 +689,3 @@ | ||
// on next tick | ||
if (!silent && componentModel.mounted && !componentModel.rendering) { | ||
if (componentModel.mounted && !componentModel.rendering) { | ||
scheduleRender(element); | ||
@@ -717,3 +700,3 @@ } | ||
if (!element.componentView) { | ||
element.componentView = definition.componentView ? definition.componentView(element, host) : element; | ||
element.componentView = element; | ||
} | ||
@@ -737,2 +720,3 @@ | ||
slots: obj(), | ||
slotStatus: obj(), | ||
mounted: false, | ||
@@ -742,3 +726,4 @@ rendering: false, | ||
queued: null, | ||
events: attachStaticEvents(element, definition) | ||
events: attachStaticEvents(element, definition), | ||
defaultProps | ||
}; | ||
@@ -756,12 +741,25 @@ | ||
*/ | ||
function mountComponent(elem$$1, initialProps = obj()) { | ||
function mountComponent(elem$$1, initialProps) { | ||
const { componentModel } = elem$$1; | ||
const { input, definition } = componentModel; | ||
const { input, definition, defaultProps } = componentModel; | ||
let changes = setPropsInternal(elem$$1, obj(), assign(obj(defaultProps), initialProps)); | ||
const runtimeChanges = setPropsInternal(elem$$1, input.attributes.prev, input.attributes.cur); | ||
if (changes && runtimeChanges) { | ||
assign(changes, runtimeChanges); | ||
} else if (runtimeChanges) { | ||
changes = runtimeChanges; | ||
} | ||
const args = [changes || {}]; | ||
finalizeEvents(input); | ||
finalizeProps(input, initialProps); | ||
const changes = changed(elem$$1.props, obj()); | ||
const args = [changes || {}]; | ||
componentModel.rendering = true; | ||
// Notify slot status | ||
for (const p in input.slots) { | ||
runHook(elem$$1, 'didSlotUpdate', [p, input.slots[p]]); | ||
} | ||
if (changes) { | ||
@@ -787,8 +785,9 @@ runHook(elem$$1, 'didChange', args); | ||
function updateComponent(elem$$1) { | ||
const { componentModel } = elem$$1; | ||
const { input } = elem$$1.componentModel; | ||
const changes = setPropsInternal(elem$$1, input.attributes.prev, input.attributes.cur); | ||
finalizeEvents(input); | ||
updateSlots(elem$$1); | ||
finalizeEvents(componentModel.input); | ||
const changes = finalizeProps(componentModel.input); | ||
if (changes) { | ||
renderComponent(elem$$1, changes); | ||
renderNext(elem$$1, changes); | ||
} | ||
@@ -908,16 +907,2 @@ } | ||
/** | ||
* Represents given props as attribute values in `elem` | ||
* @param {Element} elem | ||
* @param {object} props | ||
*/ | ||
function representProps(elem$$1, props) { | ||
for (const p in props) { | ||
// Do not represent passed partials: these are internals | ||
if (!/^partial:/.test(p)) { | ||
representAttributeValue(elem$$1, p.replace(/[A-Z]/g, kebabCase), props[p]); | ||
} | ||
} | ||
} | ||
/** | ||
* Collects and attaches static event listeners to `component` from given `definition` | ||
@@ -986,23 +971,56 @@ * @param {Component} component | ||
/** | ||
* Fills any `null` or `undefined` item in `data` with value from `defaults` | ||
* @param {Object} data | ||
* @param {Object} defaults | ||
* @returns {Object} | ||
* @param {Component} component | ||
* @param {Object} prevProps | ||
* @param {Object} nextProps | ||
* @returns {Changes} | ||
*/ | ||
function fillDefaults(data, defaults) { | ||
if (data) { | ||
const result = obj(); | ||
for (const p in data) { | ||
if (data[p] == null && p in defaults) { | ||
result[p] = defaults[p]; | ||
} else if (data[p] !== result[p]) { | ||
// Skip data from prototype | ||
result[p] = data[p]; | ||
function setPropsInternal(component, prevProps, nextProps) { | ||
/** @type {Changes} */ | ||
const changes = {}; | ||
let hasChanges = false; | ||
const { props } = component; | ||
const { defaultProps } = component.componentModel; | ||
for (const p in nextProps) { | ||
const prev = prevProps[p]; | ||
let current = nextProps[p]; | ||
if (current == null) { | ||
current = defaultProps[p]; | ||
} | ||
if (p === 'class' && current != null) { | ||
current = normalizeClassName(current); | ||
} | ||
if (current !== prev) { | ||
hasChanges = true; | ||
props[p] = prevProps[p] = current; | ||
changes[p] = { current, prev }; | ||
if (!/^partial:/.test(p)) { | ||
representAttributeValue(component, p.replace(/[A-Z]/g, kebabCase), current); | ||
} | ||
} | ||
return result; | ||
nextProps[p] = null; | ||
} | ||
return hasChanges ? changes : null; | ||
} | ||
/** | ||
* Check if `next` contains value that differs from one in `prev` | ||
* @param {Object} prev | ||
* @param {Object} next | ||
* @returns {boolean} | ||
*/ | ||
function hasChanges(prev, next) { | ||
for (const p in next) { | ||
if (next[p] !== prev[p]) { | ||
return true; | ||
} | ||
} | ||
} | ||
const blockKey = '&block'; | ||
@@ -1024,3 +1042,3 @@ | ||
// Do not use any additional function argument for adding value to `slots` | ||
// to reduce runtime checks and keep function in monomorphic state | ||
// to reduce runtime checks and keep functions in monomorphic state | ||
slots: null, | ||
@@ -1291,3 +1309,4 @@ attributes: changeSet(), | ||
function mountBlock(component, injector, get) { | ||
return updateBlock({ | ||
/** @type {BlockContext} */ | ||
const ctx = { | ||
component, | ||
@@ -1298,4 +1317,6 @@ injector, | ||
fn: null, | ||
update: null, | ||
}); | ||
update: null | ||
}; | ||
updateBlock(ctx); | ||
return ctx; | ||
} | ||
@@ -1306,5 +1327,6 @@ | ||
* @param {BlockContext} ctx | ||
* @returns {BlockContext} | ||
* @returns {number} Returns `1` if block was updated, `0` otherwise | ||
*/ | ||
function updateBlock(ctx) { | ||
let updated = 0; | ||
const { component, injector, block: block$$1, update } = ctx; | ||
@@ -1315,2 +1337,3 @@ const scope = getScope(component); | ||
if (ctx.fn !== fn) { | ||
updated = 1; | ||
// Unmount previously rendered content | ||
@@ -1324,6 +1347,6 @@ ctx.fn && dispose(injector, block$$1, false); | ||
// Update rendered result | ||
run(injector, block$$1, update, component, scope); | ||
updated = run(injector, block$$1, update, component, scope) ? 1 : 0; | ||
} | ||
return ctx; | ||
return updated; | ||
} | ||
@@ -1333,9 +1356,11 @@ | ||
* Mounts iterator block | ||
* @param {Comment} host | ||
* @param {Component} host | ||
* @param {Injector} injector | ||
* @param {function} get A function that returns collection to iterate | ||
* @param {function} body A function that renders item of iterated collection | ||
* @param {Function} get A function that returns collection to iterate | ||
* @param {Function} body A function that renders item of iterated collection | ||
* @returns {IteratorContext} | ||
*/ | ||
function mountIterator(host, injector, get, body) { | ||
return updateIterator({ | ||
/** @type {IteratorContext} */ | ||
const ctx = { | ||
host, | ||
@@ -1347,4 +1372,7 @@ injector, | ||
index: 0, | ||
rendered: [] | ||
}); | ||
rendered: [], | ||
updated: 0 | ||
}; | ||
updateIterator(ctx); | ||
return ctx; | ||
} | ||
@@ -1354,11 +1382,19 @@ | ||
* Updates iterator block defined in `ctx` | ||
* @param {object} ctx | ||
* @param {IteratorContext} ctx | ||
* @returns {number} Returns `1` if iterator was updated, `0` otherwise | ||
*/ | ||
function updateIterator(ctx) { | ||
run(ctx.injector, ctx.block, iteratorHost, ctx.host, ctx); | ||
return ctx; | ||
run(ctx.injector, ctx.block, iteratorHost, ctx.host, ctx) ? 1 : 0; | ||
return ctx.updated; | ||
} | ||
/** | ||
* | ||
* @param {Component} host | ||
* @param {Injector} injector | ||
* @param {IteratorContext} ctx | ||
*/ | ||
function iteratorHost(host, injector, ctx) { | ||
ctx.index = 0; | ||
ctx.updated = 0; | ||
const collection = ctx.get(host, getScope(host)); | ||
@@ -1371,2 +1407,3 @@ if (collection && typeof collection.forEach === 'function') { | ||
while (ctx.rendered.length > ctx.index) { | ||
ctx.updated = 1; | ||
dispose(injector, ctx.rendered.pop()[0], true); | ||
@@ -1376,2 +1413,7 @@ } | ||
/** | ||
* @this {IteratorContext} | ||
* @param {*} value | ||
* @param {*} key | ||
*/ | ||
function iterator(value, key) { | ||
@@ -1385,3 +1427,5 @@ const { host, injector, rendered, index } = this; | ||
setScope(host, assign(scope, localScope)); | ||
run(injector, b, update, host, scope); | ||
if (run(injector, b, update, host, scope)) { | ||
this.updated = 1; | ||
} | ||
exitScope(host); | ||
@@ -1395,2 +1439,3 @@ } else { | ||
rendered.push([b, update, scope]); | ||
this.updated = 1; | ||
} | ||
@@ -1408,5 +1453,7 @@ | ||
* @param {Function} body | ||
* @returns {KeyIteratorContext} | ||
*/ | ||
function mountKeyIterator(host, injector, get, keyExpr, body) { | ||
return updateKeyIterator({ | ||
/** @type {KeyIteratorContext} */ | ||
const ctx = { | ||
host, | ||
@@ -1420,4 +1467,7 @@ injector, | ||
index: 0, | ||
updated: 1, | ||
used: null | ||
}); | ||
}; | ||
updateKeyIterator(ctx); | ||
return ctx; | ||
} | ||
@@ -1427,7 +1477,8 @@ | ||
* Updates iterator block defined in `ctx` | ||
* @param {object} ctx | ||
* @param {KeyIteratorContext} ctx | ||
* @returns {number} Returns `1` if iterator was updated, `0` otherwise | ||
*/ | ||
function updateKeyIterator(ctx) { | ||
run(ctx.injector, ctx.block, keyIteratorHost, ctx.host, ctx); | ||
return ctx; | ||
return ctx.updated; | ||
} | ||
@@ -1439,3 +1490,3 @@ | ||
* @param {Injector} injector | ||
* @param {object} ctx | ||
* @param {KeyIteratorContext} ctx | ||
*/ | ||
@@ -1445,2 +1496,3 @@ function keyIteratorHost(host, injector, ctx) { | ||
ctx.index = 0; | ||
ctx.updated = 1; | ||
@@ -1455,2 +1507,3 @@ const collection = ctx.get(host, getScope(host)); | ||
for (let i = 0, items = ctx.rendered[k]; i < items.length; i++) { | ||
ctx.updated = 1; | ||
dispose(injector, items[i][0], true); | ||
@@ -1463,2 +1516,7 @@ } | ||
/** | ||
* @this {KeyIteratorContext} | ||
* @param {*} value | ||
* @param {*} key | ||
*/ | ||
function iterator$1(value, key) { | ||
@@ -1475,3 +1533,5 @@ const { host, injector, index, used, rendered, keyExpr, body } = this; | ||
move(injector, b, injector.ptr); | ||
run(injector, b, update, host, scope); | ||
if (run(injector, b, update, host, scope)) { | ||
this.updated = 1; | ||
} | ||
exitScope(host); | ||
@@ -1483,2 +1543,3 @@ } else { | ||
const update = run(injector, b, body, host, scope); | ||
this.updated = 1; | ||
exitScope(host); | ||
@@ -1504,5 +1565,8 @@ entry = [b, update, scope]; | ||
* @param {HTMLElement} elem | ||
* @returns {number} Update status. Refs must be explicitly finalized, thus | ||
* we always return `0` as nothing was changed | ||
*/ | ||
function setRef(host, name, elem) { | ||
host.componentModel.refs.cur[name] = elem; | ||
return 0; | ||
} | ||
@@ -1524,3 +1588,3 @@ | ||
* @param {Component} host | ||
* @returns {boolean} Update status | ||
* @returns {number} Update status | ||
*/ | ||
@@ -1555,10 +1619,12 @@ function finalizeRefs(host) { | ||
* Renders code, returned from `get` function, as HTML | ||
* @param {Component} component | ||
* @param {Component} host | ||
* @param {Injector} injector | ||
* @param {function} get | ||
* @returns {function} | ||
* @param {Function} get | ||
* @param {string} slotName | ||
* @returns {InnerHtmlContext} | ||
*/ | ||
function mountInnerHTML(component, injector, get, slotName) { | ||
return updateInnerHTML({ | ||
component, | ||
function mountInnerHTML(host, injector, get, slotName) { | ||
/** @type {InnerHtmlContext} */ | ||
const ctx = { | ||
host, | ||
injector, | ||
@@ -1569,3 +1635,5 @@ block: block(injector), | ||
slotName | ||
}); | ||
}; | ||
updateInnerHTML(ctx); | ||
return ctx; | ||
} | ||
@@ -1575,15 +1643,18 @@ | ||
* Updates inner HTML of block, defined in `ctx` | ||
* @param {object} ctx | ||
* @param {InnerHtmlContext} ctx | ||
* @returns {number} Returns `1` if inner HTML was updated, `0` otherwise | ||
*/ | ||
function updateInnerHTML(ctx) { | ||
const { component, injector, block: block$$1 } = ctx; | ||
const code = ctx.get(component, injector); | ||
const { host, injector, block: block$$1 } = ctx; | ||
const code = ctx.get(host, injector); | ||
let updated = 0; | ||
if (code !== ctx.code) { | ||
updated = 1; | ||
ctx.code = code; | ||
dispose(injector, block$$1, false); | ||
isDefined(code) && run(injector, block$$1, renderHTML, component, ctx); | ||
isDefined(code) && run(injector, block$$1, renderHTML, host, ctx); | ||
} | ||
return ctx; | ||
return updated; | ||
} | ||
@@ -1594,3 +1665,3 @@ | ||
* @param {Injector} injector | ||
* @param {Object} ctx | ||
* @param {InnerHtmlContext} ctx | ||
*/ | ||
@@ -1629,2 +1700,3 @@ function renderHTML(host, injector, ctx) { | ||
* @param {Object} args | ||
* @return {PartialContext} | ||
*/ | ||
@@ -1634,10 +1706,13 @@ function mountPartial(host, injector, partial, args) { | ||
// across renders | ||
return updatePartial({ | ||
/** @type {PartialContext} */ | ||
const ctx = { | ||
host, | ||
injector, | ||
block: block(injector), | ||
scope: createScope(host), | ||
scope: null, | ||
update: null, | ||
partial: null | ||
}, partial, args); | ||
}; | ||
updatePartial(ctx, partial, args); | ||
return ctx; | ||
} | ||
@@ -1647,9 +1722,10 @@ | ||
* Updates mounted partial | ||
* @param {Object} ctx | ||
* @param {PartialContext} ctx | ||
* @param {Object} partial | ||
* @param {Object} args | ||
* @return {Object} | ||
* @returns {number} Returns `1` if partial was updated, `0` otherwise | ||
*/ | ||
function updatePartial(ctx, partial, args) { | ||
const { host, injector, scope, block: block$$1 } = ctx; | ||
const { host, injector, block: block$$1 } = ctx; | ||
let updated = 0; | ||
@@ -1661,14 +1737,17 @@ if (ctx.partial !== partial) { | ||
// Mount new partial | ||
setScope(host, assign(scope, partial.defaults, args)); | ||
const scope = ctx.scope = enterScope(host, assign(obj(partial.defaults), args)); | ||
ctx.update = partial ? run(injector, block$$1, partial.body, host, scope) : null; | ||
ctx.partial = partial; | ||
exitScope(host); | ||
updated = 1; | ||
} else if (ctx.update) { | ||
// Update rendered partial | ||
setScope(host, assign(scope, partial.defaults, args)); | ||
run(injector, block$$1, ctx.update, host, scope); | ||
setScope(host, assign(ctx.scope, args)); | ||
if (run(injector, block$$1, ctx.update, host, ctx.scope)) { | ||
updated = 1; | ||
} | ||
exitScope(host); | ||
} | ||
return ctx; | ||
return updated; | ||
} | ||
@@ -1871,3 +1950,3 @@ | ||
exports.finalizeAttributes = finalizeAttributes; | ||
exports.finalizeProps = finalizeProps; | ||
exports.normalizeClassName = normalizeClassName; | ||
exports.addEvent = addEvent; | ||
@@ -1879,2 +1958,3 @@ exports.addStaticEvent = addStaticEvent; | ||
exports.updateSlots = updateSlots; | ||
exports.markSlotUpdate = markSlotUpdate; | ||
exports.setRef = setRef; | ||
@@ -1881,0 +1961,0 @@ exports.setStaticRef = setStaticRef; |
@@ -24,6 +24,6 @@ /** | ||
* @param {*} [ctx] | ||
* @returns {boolean} Returns `true` if data was updated | ||
* @returns {number} Returns `1` if data was updated, `0` otherwise | ||
*/ | ||
function finalizeItems(items, change, ctx) { | ||
let updated = false; | ||
let updated = 0; | ||
const { cur, prev } = items; | ||
@@ -34,3 +34,3 @@ | ||
if (curValue !== prevValue) { | ||
updated = true; | ||
updated = 1; | ||
change(name, prevValue, prev[name] = curValue, ctx); | ||
@@ -234,3 +234,5 @@ } | ||
function text(value) { | ||
return document.createTextNode(textValue(value)); | ||
const node = document.createTextNode(textValue(value)); | ||
node['$value'] = value; | ||
return node; | ||
} | ||
@@ -242,12 +244,12 @@ | ||
* @param {*} value | ||
* @param {*} prevValue | ||
* @return {*} New value used in text node | ||
* @returns {number} Returns `1` if text was updated, `0` otherwise | ||
*/ | ||
function updateText(node, value, prevValue) { | ||
if (value !== prevValue) { | ||
function updateText(node, value) { | ||
if (value !== node['$value']) { | ||
node.nodeValue = textValue(value); | ||
return value; | ||
node['$value'] = value; | ||
return 1; | ||
} | ||
return prevValue; | ||
return 0; | ||
} | ||
@@ -287,3 +289,3 @@ | ||
* @param {Injector} injector | ||
* @returns {boolean} Update status | ||
* @returns {number} Update status | ||
*/ | ||
@@ -337,5 +339,8 @@ function finalizeEvents(injector) { | ||
* @param {*} value | ||
* @return {number} Update status. Always returns `0` since actual attribute value | ||
* is defined in `finalizeAttributes()` | ||
*/ | ||
function setAttribute(injector, name, value) { | ||
injector.attributes.cur[name] = value; | ||
return 0; | ||
} | ||
@@ -402,35 +407,11 @@ | ||
* @param {Injector} injector | ||
* @return {number} Update status | ||
* @return {number} | ||
*/ | ||
function finalizeAttributes(injector) { | ||
return finalizeItems(normalize(injector).attributes, changeAttribute, injector.parentNode); | ||
} | ||
/** | ||
* Applies pending attributes changes to injector’s host element as props | ||
* @param {Injector} injector | ||
* @param {Object} [data] Additional props (most likely static ones) | ||
* @return {Changes} Updated props, if any | ||
*/ | ||
function finalizeProps(injector, data) { | ||
const changes = data || obj(); | ||
const updated = finalizeItems(normalize(injector).attributes, changeProp, changes); | ||
if (data || updated) { | ||
return /** @type {Component} */ (injector.parentNode).setProps(changes); | ||
} | ||
} | ||
/** | ||
* Normalizes attributes in given injector | ||
* @param {Injector} injector | ||
*/ | ||
function normalize(injector) { | ||
const { attributes } = injector; | ||
const className = attributes.cur['class']; | ||
if (isDefined(className)) { | ||
attributes.cur['class'] = normalizeClassName(className); | ||
if (isDefined(attributes.cur['class'])) { | ||
attributes.cur['class'] = normalizeClassName(attributes.cur['class']); | ||
} | ||
return injector; | ||
return finalizeItems(attributes, changeAttribute, injector.parentNode); | ||
} | ||
@@ -474,13 +455,2 @@ | ||
/** | ||
* Callback for changing attribute value | ||
* @param {string} name | ||
* @param {*} prevValue | ||
* @param {*} newValue | ||
* @param {object} changes | ||
*/ | ||
function changeProp(name, prevValue, newValue, changes) { | ||
changes[name] = newValue; | ||
} | ||
/** | ||
* Enters new variable scope context | ||
@@ -585,3 +555,5 @@ * @param {Component} host | ||
}; | ||
host.componentModel.slots[name] = mountBlock(host, createInjector(elem), blockEntry); | ||
const { slots } = host.componentModel; | ||
slots[name] = mountBlock(host, createInjector(elem), blockEntry); | ||
} | ||
@@ -594,6 +566,13 @@ | ||
function updateSlots(host) { | ||
const { slots } = host.componentModel; | ||
const { slots, slotStatus, input } = host.componentModel; | ||
for (const name in slots) { | ||
updateBlock(slots[name]); | ||
} | ||
for (const name in slotStatus) { | ||
if (slotStatus[name]) { | ||
runHook(host, 'didSlotUpdate', [name, input.slots[name]]); | ||
slotStatus[name] = 0; | ||
} | ||
} | ||
} | ||
@@ -636,2 +615,17 @@ | ||
/** | ||
* Marks slot update status | ||
* @param {Component} component | ||
* @param {string} slotName | ||
* @param {number} status | ||
*/ | ||
function markSlotUpdate(component, slotName, status) { | ||
const { slotStatus } = component.componentModel; | ||
if (slotName in slotStatus) { | ||
slotStatus[slotName] |= status; | ||
} else { | ||
slotStatus[slotName] = status; | ||
} | ||
} | ||
/** | ||
* Creates internal lightweight Endorphin component with given definition | ||
@@ -662,5 +656,5 @@ * @param {string} name | ||
element.refs = {}; | ||
element.props = assign(obj(), defaultProps); | ||
element.props = obj(defaultProps); | ||
element.state = collectData(definition, 'state'); | ||
element.setProps = function setProps(value, silent) { | ||
element.setProps = function setProps(value) { | ||
const { componentModel } = element; | ||
@@ -670,20 +664,9 @@ | ||
// check if `componentModel` is available | ||
if (!componentModel || value == null) { | ||
return; | ||
if (value != null && componentModel && componentModel.mounted) { | ||
const changes = setPropsInternal(element, element.props, obj(value)); | ||
changes && renderNext(element, changes); | ||
} | ||
value = fillDefaults(value, defaultProps); | ||
const changes = changed(value, element.props); | ||
if (changes) { | ||
assign(element.props, value); | ||
representProps(element, value); | ||
if (!silent && componentModel.mounted) { | ||
renderNext(element, changes); | ||
} | ||
} | ||
return changes; | ||
}; | ||
element.setState = function setState(value, silent) { | ||
element.setState = function setState(value) { | ||
const { componentModel } = element; | ||
@@ -693,3 +676,3 @@ | ||
// check if `componentModel` is available | ||
if (componentModel && value != null && changed(value, element.state)) { | ||
if (value != null && componentModel && hasChanges(element.state, value)) { | ||
assign(element.state, value); | ||
@@ -702,3 +685,3 @@ | ||
// on next tick | ||
if (!silent && componentModel.mounted && !componentModel.rendering) { | ||
if (componentModel.mounted && !componentModel.rendering) { | ||
scheduleRender(element); | ||
@@ -713,3 +696,3 @@ } | ||
if (!element.componentView) { | ||
element.componentView = definition.componentView ? definition.componentView(element, host) : element; | ||
element.componentView = element; | ||
} | ||
@@ -733,2 +716,3 @@ | ||
slots: obj(), | ||
slotStatus: obj(), | ||
mounted: false, | ||
@@ -738,3 +722,4 @@ rendering: false, | ||
queued: null, | ||
events: attachStaticEvents(element, definition) | ||
events: attachStaticEvents(element, definition), | ||
defaultProps | ||
}; | ||
@@ -752,12 +737,25 @@ | ||
*/ | ||
function mountComponent(elem$$1, initialProps = obj()) { | ||
function mountComponent(elem$$1, initialProps) { | ||
const { componentModel } = elem$$1; | ||
const { input, definition } = componentModel; | ||
const { input, definition, defaultProps } = componentModel; | ||
let changes = setPropsInternal(elem$$1, obj(), assign(obj(defaultProps), initialProps)); | ||
const runtimeChanges = setPropsInternal(elem$$1, input.attributes.prev, input.attributes.cur); | ||
if (changes && runtimeChanges) { | ||
assign(changes, runtimeChanges); | ||
} else if (runtimeChanges) { | ||
changes = runtimeChanges; | ||
} | ||
const args = [changes || {}]; | ||
finalizeEvents(input); | ||
finalizeProps(input, initialProps); | ||
const changes = changed(elem$$1.props, obj()); | ||
const args = [changes || {}]; | ||
componentModel.rendering = true; | ||
// Notify slot status | ||
for (const p in input.slots) { | ||
runHook(elem$$1, 'didSlotUpdate', [p, input.slots[p]]); | ||
} | ||
if (changes) { | ||
@@ -783,8 +781,9 @@ runHook(elem$$1, 'didChange', args); | ||
function updateComponent(elem$$1) { | ||
const { componentModel } = elem$$1; | ||
const { input } = elem$$1.componentModel; | ||
const changes = setPropsInternal(elem$$1, input.attributes.prev, input.attributes.cur); | ||
finalizeEvents(input); | ||
updateSlots(elem$$1); | ||
finalizeEvents(componentModel.input); | ||
const changes = finalizeProps(componentModel.input); | ||
if (changes) { | ||
renderComponent(elem$$1, changes); | ||
renderNext(elem$$1, changes); | ||
} | ||
@@ -904,16 +903,2 @@ } | ||
/** | ||
* Represents given props as attribute values in `elem` | ||
* @param {Element} elem | ||
* @param {object} props | ||
*/ | ||
function representProps(elem$$1, props) { | ||
for (const p in props) { | ||
// Do not represent passed partials: these are internals | ||
if (!/^partial:/.test(p)) { | ||
representAttributeValue(elem$$1, p.replace(/[A-Z]/g, kebabCase), props[p]); | ||
} | ||
} | ||
} | ||
/** | ||
* Collects and attaches static event listeners to `component` from given `definition` | ||
@@ -982,23 +967,56 @@ * @param {Component} component | ||
/** | ||
* Fills any `null` or `undefined` item in `data` with value from `defaults` | ||
* @param {Object} data | ||
* @param {Object} defaults | ||
* @returns {Object} | ||
* @param {Component} component | ||
* @param {Object} prevProps | ||
* @param {Object} nextProps | ||
* @returns {Changes} | ||
*/ | ||
function fillDefaults(data, defaults) { | ||
if (data) { | ||
const result = obj(); | ||
for (const p in data) { | ||
if (data[p] == null && p in defaults) { | ||
result[p] = defaults[p]; | ||
} else if (data[p] !== result[p]) { | ||
// Skip data from prototype | ||
result[p] = data[p]; | ||
function setPropsInternal(component, prevProps, nextProps) { | ||
/** @type {Changes} */ | ||
const changes = {}; | ||
let hasChanges = false; | ||
const { props } = component; | ||
const { defaultProps } = component.componentModel; | ||
for (const p in nextProps) { | ||
const prev = prevProps[p]; | ||
let current = nextProps[p]; | ||
if (current == null) { | ||
current = defaultProps[p]; | ||
} | ||
if (p === 'class' && current != null) { | ||
current = normalizeClassName(current); | ||
} | ||
if (current !== prev) { | ||
hasChanges = true; | ||
props[p] = prevProps[p] = current; | ||
changes[p] = { current, prev }; | ||
if (!/^partial:/.test(p)) { | ||
representAttributeValue(component, p.replace(/[A-Z]/g, kebabCase), current); | ||
} | ||
} | ||
return result; | ||
nextProps[p] = null; | ||
} | ||
return hasChanges ? changes : null; | ||
} | ||
/** | ||
* Check if `next` contains value that differs from one in `prev` | ||
* @param {Object} prev | ||
* @param {Object} next | ||
* @returns {boolean} | ||
*/ | ||
function hasChanges(prev, next) { | ||
for (const p in next) { | ||
if (next[p] !== prev[p]) { | ||
return true; | ||
} | ||
} | ||
} | ||
const blockKey = '&block'; | ||
@@ -1020,3 +1038,3 @@ | ||
// Do not use any additional function argument for adding value to `slots` | ||
// to reduce runtime checks and keep function in monomorphic state | ||
// to reduce runtime checks and keep functions in monomorphic state | ||
slots: null, | ||
@@ -1287,3 +1305,4 @@ attributes: changeSet(), | ||
function mountBlock(component, injector, get) { | ||
return updateBlock({ | ||
/** @type {BlockContext} */ | ||
const ctx = { | ||
component, | ||
@@ -1294,4 +1313,6 @@ injector, | ||
fn: null, | ||
update: null, | ||
}); | ||
update: null | ||
}; | ||
updateBlock(ctx); | ||
return ctx; | ||
} | ||
@@ -1302,5 +1323,6 @@ | ||
* @param {BlockContext} ctx | ||
* @returns {BlockContext} | ||
* @returns {number} Returns `1` if block was updated, `0` otherwise | ||
*/ | ||
function updateBlock(ctx) { | ||
let updated = 0; | ||
const { component, injector, block: block$$1, update } = ctx; | ||
@@ -1311,2 +1333,3 @@ const scope = getScope(component); | ||
if (ctx.fn !== fn) { | ||
updated = 1; | ||
// Unmount previously rendered content | ||
@@ -1320,6 +1343,6 @@ ctx.fn && dispose(injector, block$$1, false); | ||
// Update rendered result | ||
run(injector, block$$1, update, component, scope); | ||
updated = run(injector, block$$1, update, component, scope) ? 1 : 0; | ||
} | ||
return ctx; | ||
return updated; | ||
} | ||
@@ -1329,9 +1352,11 @@ | ||
* Mounts iterator block | ||
* @param {Comment} host | ||
* @param {Component} host | ||
* @param {Injector} injector | ||
* @param {function} get A function that returns collection to iterate | ||
* @param {function} body A function that renders item of iterated collection | ||
* @param {Function} get A function that returns collection to iterate | ||
* @param {Function} body A function that renders item of iterated collection | ||
* @returns {IteratorContext} | ||
*/ | ||
function mountIterator(host, injector, get, body) { | ||
return updateIterator({ | ||
/** @type {IteratorContext} */ | ||
const ctx = { | ||
host, | ||
@@ -1343,4 +1368,7 @@ injector, | ||
index: 0, | ||
rendered: [] | ||
}); | ||
rendered: [], | ||
updated: 0 | ||
}; | ||
updateIterator(ctx); | ||
return ctx; | ||
} | ||
@@ -1350,11 +1378,19 @@ | ||
* Updates iterator block defined in `ctx` | ||
* @param {object} ctx | ||
* @param {IteratorContext} ctx | ||
* @returns {number} Returns `1` if iterator was updated, `0` otherwise | ||
*/ | ||
function updateIterator(ctx) { | ||
run(ctx.injector, ctx.block, iteratorHost, ctx.host, ctx); | ||
return ctx; | ||
run(ctx.injector, ctx.block, iteratorHost, ctx.host, ctx) ? 1 : 0; | ||
return ctx.updated; | ||
} | ||
/** | ||
* | ||
* @param {Component} host | ||
* @param {Injector} injector | ||
* @param {IteratorContext} ctx | ||
*/ | ||
function iteratorHost(host, injector, ctx) { | ||
ctx.index = 0; | ||
ctx.updated = 0; | ||
const collection = ctx.get(host, getScope(host)); | ||
@@ -1367,2 +1403,3 @@ if (collection && typeof collection.forEach === 'function') { | ||
while (ctx.rendered.length > ctx.index) { | ||
ctx.updated = 1; | ||
dispose(injector, ctx.rendered.pop()[0], true); | ||
@@ -1372,2 +1409,7 @@ } | ||
/** | ||
* @this {IteratorContext} | ||
* @param {*} value | ||
* @param {*} key | ||
*/ | ||
function iterator(value, key) { | ||
@@ -1381,3 +1423,5 @@ const { host, injector, rendered, index } = this; | ||
setScope(host, assign(scope, localScope)); | ||
run(injector, b, update, host, scope); | ||
if (run(injector, b, update, host, scope)) { | ||
this.updated = 1; | ||
} | ||
exitScope(host); | ||
@@ -1391,2 +1435,3 @@ } else { | ||
rendered.push([b, update, scope]); | ||
this.updated = 1; | ||
} | ||
@@ -1404,5 +1449,7 @@ | ||
* @param {Function} body | ||
* @returns {KeyIteratorContext} | ||
*/ | ||
function mountKeyIterator(host, injector, get, keyExpr, body) { | ||
return updateKeyIterator({ | ||
/** @type {KeyIteratorContext} */ | ||
const ctx = { | ||
host, | ||
@@ -1416,4 +1463,7 @@ injector, | ||
index: 0, | ||
updated: 1, | ||
used: null | ||
}); | ||
}; | ||
updateKeyIterator(ctx); | ||
return ctx; | ||
} | ||
@@ -1423,7 +1473,8 @@ | ||
* Updates iterator block defined in `ctx` | ||
* @param {object} ctx | ||
* @param {KeyIteratorContext} ctx | ||
* @returns {number} Returns `1` if iterator was updated, `0` otherwise | ||
*/ | ||
function updateKeyIterator(ctx) { | ||
run(ctx.injector, ctx.block, keyIteratorHost, ctx.host, ctx); | ||
return ctx; | ||
return ctx.updated; | ||
} | ||
@@ -1435,3 +1486,3 @@ | ||
* @param {Injector} injector | ||
* @param {object} ctx | ||
* @param {KeyIteratorContext} ctx | ||
*/ | ||
@@ -1441,2 +1492,3 @@ function keyIteratorHost(host, injector, ctx) { | ||
ctx.index = 0; | ||
ctx.updated = 1; | ||
@@ -1451,2 +1503,3 @@ const collection = ctx.get(host, getScope(host)); | ||
for (let i = 0, items = ctx.rendered[k]; i < items.length; i++) { | ||
ctx.updated = 1; | ||
dispose(injector, items[i][0], true); | ||
@@ -1459,2 +1512,7 @@ } | ||
/** | ||
* @this {KeyIteratorContext} | ||
* @param {*} value | ||
* @param {*} key | ||
*/ | ||
function iterator$1(value, key) { | ||
@@ -1471,3 +1529,5 @@ const { host, injector, index, used, rendered, keyExpr, body } = this; | ||
move(injector, b, injector.ptr); | ||
run(injector, b, update, host, scope); | ||
if (run(injector, b, update, host, scope)) { | ||
this.updated = 1; | ||
} | ||
exitScope(host); | ||
@@ -1479,2 +1539,3 @@ } else { | ||
const update = run(injector, b, body, host, scope); | ||
this.updated = 1; | ||
exitScope(host); | ||
@@ -1500,5 +1561,8 @@ entry = [b, update, scope]; | ||
* @param {HTMLElement} elem | ||
* @returns {number} Update status. Refs must be explicitly finalized, thus | ||
* we always return `0` as nothing was changed | ||
*/ | ||
function setRef(host, name, elem) { | ||
host.componentModel.refs.cur[name] = elem; | ||
return 0; | ||
} | ||
@@ -1520,3 +1584,3 @@ | ||
* @param {Component} host | ||
* @returns {boolean} Update status | ||
* @returns {number} Update status | ||
*/ | ||
@@ -1551,10 +1615,12 @@ function finalizeRefs(host) { | ||
* Renders code, returned from `get` function, as HTML | ||
* @param {Component} component | ||
* @param {Component} host | ||
* @param {Injector} injector | ||
* @param {function} get | ||
* @returns {function} | ||
* @param {Function} get | ||
* @param {string} slotName | ||
* @returns {InnerHtmlContext} | ||
*/ | ||
function mountInnerHTML(component, injector, get, slotName) { | ||
return updateInnerHTML({ | ||
component, | ||
function mountInnerHTML(host, injector, get, slotName) { | ||
/** @type {InnerHtmlContext} */ | ||
const ctx = { | ||
host, | ||
injector, | ||
@@ -1565,3 +1631,5 @@ block: block(injector), | ||
slotName | ||
}); | ||
}; | ||
updateInnerHTML(ctx); | ||
return ctx; | ||
} | ||
@@ -1571,15 +1639,18 @@ | ||
* Updates inner HTML of block, defined in `ctx` | ||
* @param {object} ctx | ||
* @param {InnerHtmlContext} ctx | ||
* @returns {number} Returns `1` if inner HTML was updated, `0` otherwise | ||
*/ | ||
function updateInnerHTML(ctx) { | ||
const { component, injector, block: block$$1 } = ctx; | ||
const code = ctx.get(component, injector); | ||
const { host, injector, block: block$$1 } = ctx; | ||
const code = ctx.get(host, injector); | ||
let updated = 0; | ||
if (code !== ctx.code) { | ||
updated = 1; | ||
ctx.code = code; | ||
dispose(injector, block$$1, false); | ||
isDefined(code) && run(injector, block$$1, renderHTML, component, ctx); | ||
isDefined(code) && run(injector, block$$1, renderHTML, host, ctx); | ||
} | ||
return ctx; | ||
return updated; | ||
} | ||
@@ -1590,3 +1661,3 @@ | ||
* @param {Injector} injector | ||
* @param {Object} ctx | ||
* @param {InnerHtmlContext} ctx | ||
*/ | ||
@@ -1625,2 +1696,3 @@ function renderHTML(host, injector, ctx) { | ||
* @param {Object} args | ||
* @return {PartialContext} | ||
*/ | ||
@@ -1630,10 +1702,13 @@ function mountPartial(host, injector, partial, args) { | ||
// across renders | ||
return updatePartial({ | ||
/** @type {PartialContext} */ | ||
const ctx = { | ||
host, | ||
injector, | ||
block: block(injector), | ||
scope: createScope(host), | ||
scope: null, | ||
update: null, | ||
partial: null | ||
}, partial, args); | ||
}; | ||
updatePartial(ctx, partial, args); | ||
return ctx; | ||
} | ||
@@ -1643,9 +1718,10 @@ | ||
* Updates mounted partial | ||
* @param {Object} ctx | ||
* @param {PartialContext} ctx | ||
* @param {Object} partial | ||
* @param {Object} args | ||
* @return {Object} | ||
* @returns {number} Returns `1` if partial was updated, `0` otherwise | ||
*/ | ||
function updatePartial(ctx, partial, args) { | ||
const { host, injector, scope, block: block$$1 } = ctx; | ||
const { host, injector, block: block$$1 } = ctx; | ||
let updated = 0; | ||
@@ -1657,14 +1733,17 @@ if (ctx.partial !== partial) { | ||
// Mount new partial | ||
setScope(host, assign(scope, partial.defaults, args)); | ||
const scope = ctx.scope = enterScope(host, assign(obj(partial.defaults), args)); | ||
ctx.update = partial ? run(injector, block$$1, partial.body, host, scope) : null; | ||
ctx.partial = partial; | ||
exitScope(host); | ||
updated = 1; | ||
} else if (ctx.update) { | ||
// Update rendered partial | ||
setScope(host, assign(scope, partial.defaults, args)); | ||
run(injector, block$$1, ctx.update, host, scope); | ||
setScope(host, assign(ctx.scope, args)); | ||
if (run(injector, block$$1, ctx.update, host, ctx.scope)) { | ||
updated = 1; | ||
} | ||
exitScope(host); | ||
} | ||
return ctx; | ||
return updated; | ||
} | ||
@@ -1839,3 +1918,3 @@ | ||
export { get, filter, mountBlock, updateBlock, mountIterator, updateIterator, mountKeyIterator, updateKeyIterator, createInjector, block, run, insert, move, dispose, enterScope, exitScope, createScope, setScope, getScope, getProp, getState, getVar, setVar, setAttribute, updateAttribute, updateProps, addClass, finalizeAttributes, finalizeProps, addEvent, addStaticEvent, finalizeEvents, getEventHandler, mountSlot, updateSlots, setRef, setStaticRef, finalizeRefs, createComponent, mountComponent, updateComponent, unmountComponent, subscribeStore, scheduleRender, renderComponent, mountInnerHTML, updateInnerHTML, elem, elemNS, elemWithText, elemNSWithText, text, updateText, mountPartial, updatePartial, Store }; | ||
export { get, filter, mountBlock, updateBlock, mountIterator, updateIterator, mountKeyIterator, updateKeyIterator, createInjector, block, run, insert, move, dispose, enterScope, exitScope, createScope, setScope, getScope, getProp, getState, getVar, setVar, setAttribute, updateAttribute, updateProps, addClass, finalizeAttributes, normalizeClassName, addEvent, addStaticEvent, finalizeEvents, getEventHandler, mountSlot, updateSlots, markSlotUpdate, setRef, setStaticRef, finalizeRefs, createComponent, mountComponent, updateComponent, unmountComponent, subscribeStore, scheduleRender, renderComponent, mountInnerHTML, updateInnerHTML, elem, elemNS, elemWithText, elemNSWithText, text, updateText, mountPartial, updatePartial, Store }; | ||
//# sourceMappingURL=runtime.es.js.map |
{ | ||
"name": "@endorphinjs/template-runtime", | ||
"version": "0.1.9", | ||
"version": "0.1.10", | ||
"description": "EndorphinJS template runtime, embedded with template bundles", | ||
@@ -23,2 +23,3 @@ "main": "./dist/runtime.cjs.js", | ||
"devDependencies": { | ||
"@endorphinjs/template-compiler": "^0.1.10", | ||
"mocha": "^5.2.0", | ||
@@ -25,0 +26,0 @@ "reify": "^0.18.1", |
@@ -54,3 +54,3 @@ import { Store } from './lib/store'; | ||
*/ | ||
setProps(value: object, silent?: boolean): void; | ||
setProps(value: object): void; | ||
@@ -62,3 +62,3 @@ /** | ||
*/ | ||
setState(value: object, silent: boolean): void; | ||
setState(value: object): void; | ||
} | ||
@@ -109,2 +109,9 @@ | ||
/** | ||
* Slots update status | ||
*/ | ||
slotStatus?: { | ||
[name: string]: number | ||
}; | ||
/** | ||
* Indicates that component was mounted | ||
@@ -126,2 +133,7 @@ * @private | ||
rendering: boolean; | ||
/** | ||
* Default props values | ||
*/ | ||
defaultProps: object; | ||
} | ||
@@ -275,3 +287,5 @@ | ||
*/ | ||
slots: object; | ||
slots?: { | ||
[name: string]: DocumentFragment | Element | ||
}; | ||
@@ -349,2 +363,41 @@ /** | ||
interface IteratorContext { | ||
host: Component; | ||
injector: Injector; | ||
get: Function; | ||
body: Function; | ||
block: Block; | ||
index: number; | ||
updated: number; | ||
rendered: Array<[Block, Function, Object]>; | ||
} | ||
interface KeyIteratorContext extends IteratorContext { | ||
keyExpr: Function; | ||
used: { | ||
[key: string]: Array<[Block, Function, Object]> | ||
} | ||
rendered: { | ||
[key: string]: Array<[Block, Function, Object]> | ||
} | ||
} | ||
interface InnerHtmlContext { | ||
host: Component; | ||
injector: Injector; | ||
block: Block; | ||
get: Function; | ||
code?: string; | ||
slotName: string; | ||
} | ||
interface PartialContext { | ||
host: Component; | ||
injector: Injector; | ||
block: Block, | ||
update?: Function, | ||
scope?: object, | ||
partial?: object | ||
} | ||
interface StoreUpdateHandler { | ||
@@ -351,0 +404,0 @@ (state: object, changes: object): void |
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
283050
9
3693
4