@lightningjs/blits
Advanced tools
Comparing version 0.3.15 to 0.4.0
@@ -34,4 +34,4 @@ { | ||
"dependencies": { | ||
"@lightningjs/blits": "^0.3.15" | ||
"@lightningjs/blits": "^0.4.0" | ||
} | ||
} |
# Changelog | ||
## v0.4.0 | ||
_9 nov 2023_ | ||
- Fixed bug related to animating percentage based values | ||
- Added (customizable) navigation transitions to the router | ||
- Renamed `.eslintrc.js` to `.eslintrc.cjs` in boilerplate code to make linting work on new projects | ||
- Fixed issue in Settings when the default value was set to `false` | ||
- Replace underscored keys for private properties with Symbols | ||
- Added `keepAlive` option to the router (i.e. keeping a page in memory when navigating to a new page) | ||
- Introduced a `this.$trigger` function to force a reevaluation of a reactive value (without changing the value) | ||
- Exposed `currentRoute`, `routes` and `navigating` on the `this.$router` object | ||
- Upgraded to lates version of `@lightningjs/renderer` (v0.5.0) | ||
## v0.3.15 | ||
@@ -4,0 +18,0 @@ |
{ | ||
"name": "@lightningjs/blits", | ||
"version": "0.3.15", | ||
"version": "0.4.0", | ||
"description": "Blits: The Lightning 3 App Development Framework", | ||
@@ -9,3 +9,4 @@ "bin": "bin/index.cjs", | ||
"./vite": "./vite/index.js", | ||
"./fontloader": "./src/fontLoader.js" | ||
"./fontloader": "./src/fontLoader.js", | ||
"./transitions": "./src/router/transitions/index.js" | ||
}, | ||
@@ -45,5 +46,5 @@ "scripts": { | ||
"dependencies": { | ||
"@lightningjs/renderer": "^0.4.0", | ||
"@lightningjs/renderer": "^0.5.0", | ||
"@lightningjs/vite-plugin-import-chunk-url": "^0.3.0" | ||
} | ||
} |
@@ -22,4 +22,63 @@ /* | ||
interface Route { | ||
interface Transition { | ||
/** | ||
* Name of the prop to transition (i.e. 'x', 'y', 'alpha', 'color') | ||
*/ | ||
prop: string, | ||
/** | ||
* Value the prop should transition to (i.e. 0, 100, '#223388') | ||
*/ | ||
value: any, | ||
/** | ||
* Duration of the transition in milliseconds, defaults to 300 | ||
*/ | ||
duration?: number, | ||
/** | ||
* Easing function to apply to the transition | ||
*/ | ||
function?: string, | ||
/** | ||
* Delay before the transition starts in milliseconds | ||
*/ | ||
delay?: number | ||
} | ||
interface Before { | ||
/** | ||
* Name of the prop to set before the transition starts | ||
*/ | ||
prop: string, | ||
/** | ||
* Value the prop to set before the transition starts | ||
*/ | ||
value: any, | ||
} | ||
interface RouteTransition { | ||
/** | ||
* Setting or Array of Settings before new view enters into the router view | ||
*/ | ||
before: Before | Before[], | ||
/** | ||
* Transition or Array of Transitions for new view to enters into the router view | ||
*/ | ||
in: Transition | Transition[], | ||
/** | ||
* Transition or Array of Transitions for old view to leave the router view | ||
*/ | ||
out: Transition | Transition[], | ||
} | ||
type RouteTransitionFunction = (previousRoute: Route, currentRoute: Route) => RequireAtLeastOne<RouteTransition> | ||
function Application( | ||
config: Application.ApplicationConfig | ||
) : Application.ApplicationInstance | ||
type RequireAtLeastOne<T> = { | ||
[K in keyof T]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<keyof T, K>>> | ||
}[keyof T] | ||
type Route = { | ||
/** | ||
* URI path for the route | ||
@@ -31,3 +90,11 @@ */ | ||
*/ | ||
component: typeof ComponentInstance | ||
component: typeof ComponentInstance, | ||
/** | ||
* Transition configuration for the route | ||
*/ | ||
transition?: RequireAtLeastOne<RouteTransition> | RouteTransitionFunction, | ||
/** | ||
* Extra route options | ||
*/ | ||
options?: object // todo: specify which options are available | ||
} | ||
@@ -51,3 +118,3 @@ | ||
*/ | ||
routes: Route[] | ||
routes?: Route[] | ||
} | ||
@@ -54,0 +121,0 @@ } |
@@ -22,2 +22,4 @@ /* | ||
import symbols from './lib/symbols.js' | ||
const Application = (config) => { | ||
@@ -47,7 +49,7 @@ const defaultKeyMap = { | ||
config.hooks.___destroy = function () { | ||
config.hooks[symbols.destroy] = function () { | ||
document.removeEventListener('keydown', handler) | ||
} | ||
config.hooks.___init = function () { | ||
config.hooks[symbols.init] = function () { | ||
const keyMap = { ...defaultKeyMap, ...Settings.get('keymap', {}) } | ||
@@ -62,3 +64,4 @@ | ||
Focus.set(this) | ||
// next tick | ||
setTimeout(() => Focus.set(this)) | ||
} | ||
@@ -65,0 +68,0 @@ |
@@ -24,3 +24,3 @@ /* | ||
import { createHumanReadableId, createInternalId } from './lib/componentId.js' | ||
import { registerHooks, emit } from './lib/hooks.js' | ||
import { registerHooks, emit, privateEmit } from './lib/hooks.js' | ||
@@ -39,2 +39,4 @@ import { reactive } from './lib/reactivity/reactive.js' | ||
import symbols from './lib/symbols.js' | ||
const stage = { | ||
@@ -106,3 +108,3 @@ element, | ||
// emit 'private' hook | ||
emit(`___${v}`, name, scope) | ||
privateEmit(v, name, scope) | ||
// emit 'public' hook | ||
@@ -124,2 +126,3 @@ emit(v, name, scope) | ||
this.parent = parentComponent | ||
this.wrapper = parentEl | ||
@@ -139,3 +142,3 @@ Object.defineProperties(this, { | ||
}, | ||
___id: { | ||
[symbols.id]: { | ||
value: createInternalId(), | ||
@@ -146,3 +149,3 @@ writable: false, | ||
}, | ||
___props: { | ||
[symbols.props]: { | ||
value: reactive(opts.props || {}), | ||
@@ -155,6 +158,4 @@ writable: false, | ||
Object.defineProperty(this, '___state', { | ||
value: reactive( | ||
(config.state && typeof config.state === 'function' && config.state.apply(this)) || {} | ||
), | ||
Object.defineProperty(this, symbols.originalState, { | ||
value: (config.state && typeof config.state === 'function' && config.state.apply(this)) || {}, | ||
writable: false, | ||
@@ -165,5 +166,12 @@ enumerable: false, | ||
Object.defineProperty(this, symbols.state, { | ||
value: reactive(this[symbols.originalState]), | ||
writable: false, | ||
enumerable: false, | ||
configurable: false, | ||
}) | ||
this.lifecycle.state = 'init' | ||
Object.defineProperty(this, '___children', { | ||
Object.defineProperty(this, symbols.children, { | ||
value: code.render.apply(stage, [parentEl, this, code.context]), | ||
@@ -175,4 +183,4 @@ writable: false, | ||
Object.defineProperty(this, '___slots', { | ||
value: this.___children.filter((child) => child.___isSlot), | ||
Object.defineProperty(this, symbols.slots, { | ||
value: this[symbols.children].filter((child) => child[symbols.isSlot]), | ||
writable: false, | ||
@@ -185,12 +193,12 @@ enumerable: false, | ||
effect(() => { | ||
eff.apply(stage, [this, this.___children, code.context]) | ||
eff.apply(stage, [this, this[symbols.children], code.context]) | ||
}) | ||
}) | ||
if (this.___watchers) { | ||
Object.keys(this.___watchers).forEach((watchKey) => { | ||
if (this[symbols.watchers]) { | ||
Object.keys(this[symbols.watchers]).forEach((watchKey) => { | ||
let old = this[watchKey] | ||
effect(() => { | ||
if (old !== this[watchKey]) { | ||
this.___watchers[watchKey].apply(this, [this[watchKey], old]) | ||
effect((force = false) => { | ||
if (old !== this[watchKey] || force === true) { | ||
this[symbols.watchers][watchKey].apply(this, [this[watchKey], old]) | ||
old = this[watchKey] | ||
@@ -197,0 +205,0 @@ } |
@@ -19,3 +19,3 @@ /* | ||
import Component from '../component.js' | ||
import Router from '../router.js' | ||
import Router from '../router/router.js' | ||
@@ -27,3 +27,3 @@ let handler | ||
template: ` | ||
<Element></Element> | ||
<Element w="100%" height="100%"></Element> | ||
`, | ||
@@ -30,0 +30,0 @@ hooks: { |
@@ -20,2 +20,4 @@ /* | ||
import symbols from '../lib/symbols.js' | ||
export default () => | ||
@@ -40,3 +42,3 @@ Component('Sprite', { | ||
if (this.spriteTexture && options) { | ||
return this.___renderer.createTexture('SubTexture', { | ||
return this[symbols.renderer].createTexture('SubTexture', { | ||
texture: this.spriteTexture, | ||
@@ -53,3 +55,3 @@ x: options.x, | ||
ready() { | ||
this.spriteTexture = this.___renderer.createTexture('ImageTexture', { | ||
this.spriteTexture = this[symbols.renderer].createTexture('ImageTexture', { | ||
src: `${window.location.protocol}//${window.location.host}/${this.image}`, | ||
@@ -56,0 +58,0 @@ }) |
@@ -22,2 +22,3 @@ /* | ||
import { Log } from './lib/log.js' | ||
import symbols from './lib/symbols.js' | ||
@@ -178,4 +179,4 @@ const isTransition = (value) => { | ||
if (props.___isSlot) { | ||
this.___isSlot = true | ||
if (props[symbols.isSlot]) { | ||
this[symbols.isSlot] = true | ||
} | ||
@@ -197,5 +198,4 @@ | ||
if (props['@loaded']) { | ||
const event = props.__textnode ? 'textLoaded' : 'txLoaded' | ||
this.node.on(event, (el, { width: w, height: h }) => { | ||
props['@loaded']({ w, h }, this) | ||
this.node.on('loaded', (el, { type, dimensions }) => { | ||
props['@loaded']({ w: dimensions.width, h: dimensions.height, type }, this) | ||
}) | ||
@@ -205,4 +205,3 @@ } | ||
if (props['@error']) { | ||
const event = props.__textnode ? 'textFailed' : 'txFailed' | ||
this.node.on(event, (el, error) => { | ||
this.node.on('failed', (el, error) => { | ||
props['@error'](error, this) | ||
@@ -260,3 +259,3 @@ }) | ||
if (typeof value === 'string' && props[prop].endsWith('%')) { | ||
if (typeof props[prop] === 'string' && props[prop].endsWith('%')) { | ||
transformations.percentage.call(this, props, prop) | ||
@@ -271,4 +270,7 @@ } | ||
}) | ||
value.delay ? setTimeout(() => f.start(), value.delay) : f.start() | ||
return new Promise((resolve) => { | ||
value.delay | ||
? setTimeout(() => f.start().waitUntilStopped().then(resolve), value.delay) | ||
: f.start().waitUntilStopped().then(resolve) | ||
}) | ||
} | ||
@@ -275,0 +277,0 @@ }, |
@@ -18,2 +18,5 @@ /* | ||
import symbols from './lib/symbols.js' | ||
import { navigating } from './router/router.js' | ||
let focusedComponent = null | ||
@@ -38,2 +41,3 @@ | ||
input(key, event) { | ||
if (navigating === true) return | ||
const focusChain = walkChain([focusedComponent], key) | ||
@@ -47,6 +51,6 @@ const componentWithInputEvent = focusChain.shift() | ||
} | ||
if (componentWithInputEvent.___inputEvents[key]) { | ||
componentWithInputEvent.___inputEvents[key].call(componentWithInputEvent, event) | ||
} else if (componentWithInputEvent.___inputEvents.any) { | ||
componentWithInputEvent.___inputEvents.any.call(componentWithInputEvent, event) | ||
if (componentWithInputEvent[symbols.inputEvents][key]) { | ||
componentWithInputEvent[symbols.inputEvents][key].call(componentWithInputEvent, event) | ||
} else if (componentWithInputEvent[symbols.inputEvents].any) { | ||
componentWithInputEvent[symbols.inputEvents].any.call(componentWithInputEvent, event) | ||
} | ||
@@ -59,5 +63,5 @@ } | ||
if ( | ||
components[0].___inputEvents && | ||
(typeof components[0].___inputEvents[key] === 'function' || | ||
typeof components[0].___inputEvents.any === 'function') | ||
components[0][symbols.inputEvents] && | ||
(typeof components[0][symbols.inputEvents][key] === 'function' || | ||
typeof components[0][symbols.inputEvents].any === 'function') | ||
) { | ||
@@ -64,0 +68,0 @@ return components |
@@ -59,3 +59,3 @@ /* | ||
if(!${elm}) { | ||
${elm} = this.element({componentId: component.___id, parent: parent || 'root'}) | ||
${elm} = this.element({componentId: component[Symbol.for('id')], parent: parent || 'root'}) | ||
} | ||
@@ -71,3 +71,3 @@ const elementConfig${counter} = {} | ||
if (templateObject[key] === 'Slot') { | ||
renderCode.push(`elementConfig${counter}['___isSlot'] = true`) | ||
renderCode.push(`elementConfig${counter}[Symbol.for('isSlot')] = true`) | ||
} | ||
@@ -79,3 +79,3 @@ return | ||
renderCode.push(` | ||
elementConfig${counter}['parent'] = component.___slots.filter(slot => slot.ref === '${templateObject.slot}').shift() || component.___slots[0] || parent | ||
elementConfig${counter}['parent'] = component[Symbol.for('slots')].filter(slot => slot.ref === '${templateObject.slot}').shift() || component[Symbol.for('slots')][0] || parent | ||
`) | ||
@@ -126,3 +126,3 @@ } | ||
(context.components && context.components['${templateObject.type}']) || | ||
component.___components['${templateObject.type}'] | ||
component[Symbol.for('components')]['${templateObject.type}'] | ||
`) | ||
@@ -159,3 +159,3 @@ | ||
this.effectsCode.push(` | ||
${elm}.___props['${key.substring(1)}'] = ${interpolate( | ||
${elm}[Symbol.for('props')]['${key.substring(1)}'] = ${interpolate( | ||
templateObject[key], | ||
@@ -179,8 +179,8 @@ options.component | ||
if(!${elm}) { | ||
${elm} = (context.components && context.components['${templateObject.type}'] || component.___components['${templateObject.type}'] || (() => { console.log('component ${templateObject.type} not found')})).call(null, {props: props${counter}}, ${parent}, component) | ||
if (${elm}.___slots[0]) { | ||
parent = ${elm}.___slots[0] | ||
${elm} = (context.components && context.components['${templateObject.type}'] || component[Symbol.for('components')]['${templateObject.type}'] || (() => { console.log('component ${templateObject.type} not found')})).call(null, {props: props${counter}}, ${parent}, component) | ||
if (${elm}[Symbol.for('slots')][0]) { | ||
parent = ${elm}[Symbol.for('slots')][0] | ||
component = ${elm} | ||
} else { | ||
parent = ${elm}.___children[0] | ||
parent = ${elm}[Symbol.for('children')][0] | ||
} | ||
@@ -187,0 +187,0 @@ } |
@@ -110,3 +110,3 @@ /* | ||
elms[1] = this.element({componentId: component.___id, parentId: parent && parent.nodeId || 'root'}) | ||
elms[1] = this.element({componentId: component[Symbol.for('id')], parentId: parent && parent.nodeId || 'root'}) | ||
const elementConfig1 = {} | ||
@@ -153,3 +153,3 @@ | ||
elms[1] = this.element({componentId: component.___id, parentId: parent && parent.nodeId || 'root'}) | ||
elms[1] = this.element({componentId: component[Symbol.for('id')], parentId: parent && parent.nodeId || 'root'}) | ||
const elementConfig1 = {} | ||
@@ -163,3 +163,3 @@ | ||
elms[2] = this.element({componentId: component.___id, parentId: parent && parent.nodeId || 'root'}) | ||
elms[2] = this.element({componentId: component[Symbol.for('id')], parentId: parent && parent.nodeId || 'root'}) | ||
const elementConfig2 = {} | ||
@@ -204,3 +204,3 @@ | ||
elms[1] = this.element({componentId: component.___id, parentId: parent && parent.nodeId || 'root'}) | ||
elms[1] = this.element({componentId: component[Symbol.for('id')], parentId: parent && parent.nodeId || 'root'}) | ||
const elementConfig1 = {} | ||
@@ -253,3 +253,3 @@ | ||
elms[1] = this.element({componentId: component.___id, parentId: parent && parent.nodeId || 'root'}) | ||
elms[1] = this.element({componentId: component[Symbol.for('id')], parentId: parent && parent.nodeId || 'root'}) | ||
const elementConfig1 = {} | ||
@@ -265,3 +265,3 @@ | ||
elms[2] = this.element({componentId: component.___id, parentId: parent && parent.nodeId || 'root'}) | ||
elms[2] = this.element({componentId: component[Symbol.for('id')], parentId: parent && parent.nodeId || 'root'}) | ||
const elementConfig2 = {} | ||
@@ -322,3 +322,3 @@ | ||
elms[1] = this.element({componentId: component.___id, parentId: parent && parent.nodeId || 'root'}) | ||
elms[1] = this.element({componentId: component[Symbol.for('id')], parentId: parent && parent.nodeId || 'root'}) | ||
const elementConfig1 = {} | ||
@@ -334,3 +334,3 @@ | ||
elms[2] = this.element({componentId: component.___id, parentId: parent && parent.nodeId || 'root'}) | ||
elms[2] = this.element({componentId: component[Symbol.for('id')], parentId: parent && parent.nodeId || 'root'}) | ||
const elementConfig2 = {} | ||
@@ -347,3 +347,3 @@ | ||
elms[3] = this.element({componentId: component.___id, parentId: parent && parent.nodeId || 'root'}) | ||
elms[3] = this.element({componentId: component[Symbol.for('id')], parentId: parent && parent.nodeId || 'root'}) | ||
const elementConfig3 = {} | ||
@@ -415,3 +415,3 @@ | ||
elms[1] = this.element({componentId: component.___id, parentId: parent && parent.nodeId || 'root'}) | ||
elms[1] = this.element({componentId: component[Symbol.for('id')], parentId: parent && parent.nodeId || 'root'}) | ||
const elementConfig1 = {} | ||
@@ -427,3 +427,3 @@ | ||
elms[2] = this.element({componentId: component.___id, parentId: parent && parent.nodeId || 'root'}) | ||
elms[2] = this.element({componentId: component[Symbol.for('id')], parentId: parent && parent.nodeId || 'root'}) | ||
const elementConfig2 = {} | ||
@@ -440,3 +440,3 @@ | ||
elms[3] = this.element({componentId: component.___id, parentId: parent && parent.nodeId || 'root'}) | ||
elms[3] = this.element({componentId: component[Symbol.for('id')], parentId: parent && parent.nodeId || 'root'}) | ||
const elementConfig3 = {} | ||
@@ -453,3 +453,3 @@ | ||
elms[4] = this.element({componentId: component.___id, parentId: parent && parent.nodeId || 'root'}) | ||
elms[4] = this.element({componentId: component[Symbol.for('id')], parentId: parent && parent.nodeId || 'root'}) | ||
const elementConfig4 = {} | ||
@@ -464,3 +464,3 @@ | ||
elms[5] = this.element({componentId: component.___id, parentId: parent && parent.nodeId || 'root'}) | ||
elms[5] = this.element({componentId: component[Symbol.for('id')], parentId: parent && parent.nodeId || 'root'}) | ||
const elementConfig5 = {} | ||
@@ -509,3 +509,3 @@ | ||
elms[1] = this.element({componentId: component.___id, parentId: parent && parent.nodeId || 'root'}) | ||
elms[1] = this.element({componentId: component[Symbol.for('id')], parentId: parent && parent.nodeId || 'root'}) | ||
const elementConfig1 = {} | ||
@@ -577,3 +577,3 @@ | ||
elms[1] = this.element({componentId: component.___id, parentId: parent && parent.nodeId || 'root'}) | ||
elms[1] = this.element({componentId: component[Symbol.for('id')], parentId: parent && parent.nodeId || 'root'}) | ||
const elementConfig1 = {} | ||
@@ -623,3 +623,3 @@ | ||
elms[1] = this.element({componentId: component.___id, parentId: parent && parent.nodeId || 'root'}) | ||
elms[1] = this.element({componentId: component[Symbol.for('id')], parentId: parent && parent.nodeId || 'root'}) | ||
const elementConfig1 = {} | ||
@@ -710,3 +710,3 @@ | ||
elms[1] = this.element({componentId: component.___id, parentId: parent && parent.nodeId || 'root'}) | ||
elms[1] = this.element({componentId: component[Symbol.for('id')], parentId: parent && parent.nodeId || 'root'}) | ||
const elementConfig1 = {} | ||
@@ -767,3 +767,3 @@ | ||
elms[1] = this.element({componentId: component.___id, parentId: parent && parent.nodeId || 'root'}) | ||
elms[1] = this.element({componentId: component[Symbol.for('id')], parentId: parent && parent.nodeId || 'root'}) | ||
const elementConfig1 = {} | ||
@@ -779,3 +779,3 @@ | ||
elms[3] = this.element({componentId: component.___id, parentId: parent && parent.nodeId || 'root'}) | ||
elms[3] = this.element({componentId: component[Symbol.for('id')], parentId: parent && parent.nodeId || 'root'}) | ||
const elementConfig3 = {} | ||
@@ -836,3 +836,3 @@ | ||
elms[1] = this.element({componentId: component.___id, parentId: parent && parent.nodeId || 'root'}) | ||
elms[1] = this.element({componentId: component[Symbol.for('id')], parentId: parent && parent.nodeId || 'root'}) | ||
const elementConfig1 = {} | ||
@@ -900,3 +900,3 @@ | ||
elms[1] = this.element({componentId: component.___id, parentId: parent && parent.nodeId || 'root'}) | ||
elms[1] = this.element({componentId: component[Symbol.for('id')], parentId: parent && parent.nodeId || 'root'}) | ||
const elementConfig1 = {} | ||
@@ -920,3 +920,3 @@ | ||
function anonymous(component,elms,context) { | ||
elms[2].___props.img = component.image | ||
elms[2][Symbol.for('props')].img = component.image | ||
} | ||
@@ -927,3 +927,3 @@ ` | ||
function anonymous(component,elms,context) { | ||
elms[3].___props.img = component.image | ||
elms[3][Symbol.for('props')].img = component.image | ||
} | ||
@@ -973,3 +973,3 @@ ` | ||
elms[1] = this.element({componentId: component.___id, parentId: parent && parent.nodeId || 'root'}) | ||
elms[1] = this.element({componentId: component[Symbol.for('id')], parentId: parent && parent.nodeId || 'root'}) | ||
const elementConfig1 = {} | ||
@@ -976,0 +976,0 @@ |
@@ -18,2 +18,4 @@ /* | ||
import symbols from './symbols.js' | ||
const cbs = {} | ||
@@ -25,7 +27,14 @@ | ||
export const privateEmit = (hook, name, scope) => { | ||
const symHook = symbols[hook] | ||
cbs[name] && cbs[name][symHook] && cbs[name][symHook].apply(scope) | ||
} | ||
export const registerHooks = (hooks = {}, name) => { | ||
cbs[name] = {} | ||
Object.keys(hooks).forEach((hook) => { | ||
// Combines enumerable keys and symbol properties of the 'hooks' object | ||
const hookKeys = [...Object.keys(hooks), ...Object.getOwnPropertySymbols(hooks)] | ||
hookKeys.forEach((hook) => { | ||
if (typeof hooks[hook] === 'function') cbs[name][hook] = hooks[hook] | ||
}) | ||
} |
@@ -37,3 +37,3 @@ /* | ||
export const trigger = (target, key) => { | ||
export const trigger = (target, key, force = false) => { | ||
const effectsMap = objectMap.get(target) | ||
@@ -46,3 +46,3 @@ if (!effectsMap) { | ||
effects.forEach((effect) => { | ||
effect() | ||
effect(force) | ||
}) | ||
@@ -49,0 +49,0 @@ } |
@@ -20,3 +20,3 @@ /* | ||
import Focus from '../../focus.js' | ||
import { to } from '../../router.js' | ||
import { to, currentRoute, navigating } from '../../router/router.js' | ||
import Image from '../../components/Image.js' | ||
@@ -29,3 +29,6 @@ import Circle from '../../components/Circle.js' | ||
import { default as log, Log } from '../log.js' | ||
import symbols from '../symbols.js' | ||
import { trigger } from '../reactivity/effect.js' | ||
const shaders = { | ||
@@ -64,10 +67,10 @@ radius: 'radius', | ||
this.lifecycle.state = 'destroy' | ||
for (let i = 0; i < this.___timeouts.length; i++) { | ||
clearTimeout(this.___timeouts[i]) | ||
for (let i = 0; i < this[symbols.timeouts].length; i++) { | ||
clearTimeout(this[symbols.timeouts][i]) | ||
} | ||
for (let i = 0; i < this.___intervals.length; i++) { | ||
clearInterval(this.___intervals[i]) | ||
for (let i = 0; i < this[symbols.intervals].length; i++) { | ||
clearInterval(this[symbols.intervals][i]) | ||
} | ||
eventListeners.removeListeners(this) | ||
deleteChildren(this.___children) | ||
deleteChildren(this[symbols.children]) | ||
Log.debug(`Destroyed component ${this.componentId}`) | ||
@@ -82,3 +85,3 @@ }, | ||
let selected = null | ||
this.___children.forEach((child) => { | ||
this[symbols.children].forEach((child) => { | ||
if (Array.isArray(child)) { | ||
@@ -121,2 +124,11 @@ child.forEach((c) => { | ||
to, | ||
get currentRoute() { | ||
return currentRoute | ||
}, | ||
get routes() { | ||
return component.prototype[symbols.routes] | ||
}, | ||
get navigating() { | ||
return navigating | ||
}, | ||
}, | ||
@@ -127,3 +139,3 @@ writable: false, | ||
}, | ||
___components: { | ||
[symbols.components]: { | ||
value: { | ||
@@ -140,3 +152,3 @@ Image: Image(), | ||
}, | ||
___timeouts: { | ||
[symbols.timeouts]: { | ||
value: [], | ||
@@ -151,3 +163,3 @@ writable: false, | ||
() => { | ||
this.____timeouts = this.___timeouts.filter((id) => id !== timeoutId) | ||
this[symbols._timeouts] = this[symbols.timeouts].filter((id) => id !== timeoutId) | ||
fn.apply(null, params) | ||
@@ -158,3 +170,3 @@ }, | ||
) | ||
this.___timeouts.push(timeoutId) | ||
this[symbols.timeouts].push(timeoutId) | ||
return timeoutId | ||
@@ -166,3 +178,3 @@ }, | ||
}, | ||
___intervals: { | ||
[symbols.intervals]: { | ||
value: [], | ||
@@ -177,3 +189,3 @@ writable: false, | ||
() => { | ||
this.____intervals = this.___intervals.filter((id) => id !== intervalId) | ||
this[symbols._intervals] = this[symbols.intervals].filter((id) => id !== intervalId) | ||
fn.apply(null, params) | ||
@@ -184,3 +196,3 @@ }, | ||
) | ||
this.___intervals.push(intervalId) | ||
this[symbols.intervals].push(intervalId) | ||
return intervalId | ||
@@ -208,3 +220,3 @@ }, | ||
}, | ||
___renderer: { | ||
[symbols.renderer]: { | ||
value: renderer, | ||
@@ -221,2 +233,11 @@ writable: false, | ||
}, | ||
$trigger: { | ||
value: function (key) { | ||
// trigger with force set to true | ||
trigger(this[symbols.originalState], key, true) | ||
}, | ||
writable: false, | ||
enumerable: false, | ||
configurable: false, | ||
}, | ||
}) | ||
@@ -223,0 +244,0 @@ } |
@@ -20,12 +20,17 @@ /* | ||
import symbols from '../symbols.js' | ||
export default (component, computeds) => { | ||
component.___computedKeys = [] | ||
component[symbols.computedKeys] = [] | ||
for (let computed in computeds) { | ||
// test for reserved keys? | ||
if (component.___stateKeys && component.___stateKeys.indexOf(computed) > -1) { | ||
if (component[symbols.stateKeys] && component[symbols.stateKeys].indexOf(computed) > -1) { | ||
Log.error(`${computed} already exists as a prop`) | ||
} else if (component.___propKeys && component.___propKeys.indexOf(computed) > -1) { | ||
} else if (component[symbols.propKeys] && component[symbols.propKeys].indexOf(computed) > -1) { | ||
Log.error(`${computed} already exists as a prop`) | ||
} else if (component.___methodKeys && component.___methodKeys.indexOf(computed) > -1) { | ||
} else if ( | ||
component[symbols.methodKeys] && | ||
component[symbols.methodKeys].indexOf(computed) > -1 | ||
) { | ||
Log.error(`${computed} already exists as a method`) | ||
@@ -36,3 +41,3 @@ } else { | ||
} | ||
component.___computedKeys.push(computed) | ||
component[symbols.computedKeys].push(computed) | ||
Object.defineProperty(component.prototype, computed, { | ||
@@ -39,0 +44,0 @@ get() { |
@@ -20,4 +20,6 @@ /* | ||
import symbols from '../symbols.js' | ||
export default (component, input) => { | ||
component.prototype.___inputEvents = [] | ||
component.prototype[symbols.inputEvents] = [] | ||
Object.keys(input).forEach((key) => { | ||
@@ -27,4 +29,4 @@ if (typeof input[key] !== 'function') { | ||
} | ||
component.prototype.___inputEvents[key] = input[key] | ||
component.prototype[symbols.inputEvents][key] = input[key] | ||
}) | ||
} |
@@ -20,8 +20,10 @@ /* | ||
import symbols from '../symbols.js' | ||
export default (component, methods) => { | ||
component.___methodsKeys = [] | ||
component[symbols.methodKeys] = [] | ||
for (let method in methods) { | ||
// test for reserved keys? | ||
if (component.___propKeys && component.___propKeys.indexOf(method) > -1) { | ||
if (component[symbols.propKeys] && component[symbols.propKeys].indexOf(method) > -1) { | ||
Log.error(`${method} already exists as a prop`) | ||
@@ -32,3 +34,3 @@ } else { | ||
} | ||
component.___methodsKeys.push(method) | ||
component[symbols.methodKeys].push(method) | ||
component.prototype[method] = methods[method] | ||
@@ -35,0 +37,0 @@ } |
@@ -20,2 +20,4 @@ /* | ||
import symbols from '../symbols.js' | ||
const baseProp = { | ||
@@ -30,11 +32,11 @@ cast: (v) => v, | ||
} | ||
component.___propKeys = [] | ||
component[symbols.propKeys] = [] | ||
props.forEach((prop) => { | ||
prop = { ...baseProp, ...(typeof prop === 'object' ? prop : { key: prop }) } | ||
component.___propKeys.push(prop.key) | ||
component[symbols.propKeys].push(prop.key) | ||
Object.defineProperty(component.prototype, prop.key, { | ||
get() { | ||
const value = prop.cast( | ||
this.___props && prop.key in this.___props | ||
? this.___props[prop.key] | ||
this[symbols.props] && prop.key in this[symbols.props] | ||
? this[symbols.props][prop.key] | ||
: prop.default || undefined | ||
@@ -51,3 +53,3 @@ ) | ||
Log.warn(`Warning! Avoid mutating props directly (${prop.key})`) | ||
this.___props[prop.key] = v | ||
this[symbols.props][prop.key] = v | ||
}, | ||
@@ -54,0 +56,0 @@ }) |
@@ -22,2 +22,4 @@ /* | ||
import symbols from '../symbols.js' | ||
initLog() | ||
@@ -33,12 +35,8 @@ | ||
test('Create a ___propkeys on component', (assert) => { | ||
test('Has correct symbols', (assert) => { | ||
const component = new Function() | ||
const props = ['index', 'img', 'url'] | ||
propsFn(component, props) | ||
/* eslint-disable */ | ||
assert.false(component.hasOwnProperty('___propKeys'), 'Component should not have a ___propKeys key') | ||
propsFn(component) | ||
/* eslint-disable */ | ||
assert.true(component.hasOwnProperty('___propKeys'), 'Component should have a ___propKeys key') | ||
assert.true(component[symbols.propKeys], 'Component should have a propKey symbol') | ||
assert.end() | ||
@@ -52,4 +50,4 @@ }) | ||
assert.equal(props.length, component.___propKeys.length, 'All passed props should be stored on ___propKeys') | ||
assert.equal(props.length, props.map(prop => component.___propKeys.indexOf(prop) > -1).filter(prop => prop === true).length, 'All passed props should be stored on ___propKeys') | ||
assert.equal(props.length, component[symbols.propKeys].length, 'All passed props should be stored on propKeys') | ||
assert.equal(props.length, props.map(prop => component[symbols.propKeys].indexOf(prop) > -1).filter(prop => prop === true).length, 'All passed props should be stored on propKeys') | ||
@@ -68,3 +66,3 @@ props.forEach((prop) => { | ||
const componentInstance = new component | ||
componentInstance.___props = { | ||
componentInstance[symbols.props] = { | ||
index: 1, | ||
@@ -76,3 +74,3 @@ img: 'lorem-ipsum.jpg', | ||
const componentInstance2 = new component | ||
componentInstance2.___props = { | ||
componentInstance2[symbols.props] = { | ||
index: 2, | ||
@@ -87,4 +85,4 @@ img: 'bla.jpg', | ||
props.forEach((prop) => { | ||
assert.equal(componentInstance[prop], componentInstance.___props[prop], `The correct value of ${prop} should be returned via the getter`) | ||
assert.equal(componentInstance2[prop], componentInstance2.___props[prop], `The correct value of ${prop} should be returned via the getter`) | ||
assert.equal(componentInstance[prop], componentInstance[symbols.props][prop], `The correct value of ${prop} should be returned via the getter`) | ||
assert.equal(componentInstance2[prop], componentInstance2[symbols.props][prop], `The correct value of ${prop} should be returned via the getter`) | ||
}) | ||
@@ -102,4 +100,4 @@ | ||
assert.equal(props.length, component.___propKeys.length, 'All passed props should be stored on ___propKeys') | ||
assert.equal(props.length, props.map(prop => component.___propKeys.indexOf(typeof prop === 'object' ? prop.key : prop) > -1).filter(prop => prop === true).length, 'All passed props should be stored on ___propKeys') | ||
assert.equal(props.length, component[symbols.propKeys].length, 'All passed props should be stored on propKeys') | ||
assert.equal(props.length, props.map(prop => component[symbols.propKeys].indexOf(typeof prop === 'object' ? prop.key : prop) > -1).filter(prop => prop === true).length, 'All passed props should be stored on propKeys') | ||
@@ -119,4 +117,4 @@ props.forEach((prop) => { | ||
assert.equal(props.length, component.___propKeys.length, 'All passed props should be stored on ___propKeys') | ||
assert.equal(props.length, props.map(prop => component.___propKeys.indexOf(typeof prop === 'object' ? prop.key : prop) > -1).filter(prop => prop === true).length, 'All passed props should be stored on ___propKeys') | ||
assert.equal(props.length, component[symbols.propKeys].length, 'All passed props should be stored on propKeys') | ||
assert.equal(props.length, props.map(prop => component[symbols.propKeys].indexOf(typeof prop === 'object' ? prop.key : prop) > -1).filter(prop => prop === true).length, 'All passed props should be stored on propKeys') | ||
@@ -134,3 +132,3 @@ props.forEach((prop) => { | ||
const componentInstance = new component | ||
componentInstance.___props = { | ||
componentInstance[symbols.props] = { | ||
number: '1', | ||
@@ -137,0 +135,0 @@ string: 100, |
@@ -18,8 +18,10 @@ /* | ||
import symbols from '../symbols.js' | ||
export default (component, routes) => { | ||
component.prototype.___routes = [] | ||
component.prototype[symbols.routes] = [] | ||
Object.keys(routes).forEach((key) => { | ||
// todo: validate routes[key] for expected format etc. | ||
component.prototype.___routes[key] = routes[key] | ||
component.prototype[symbols.routes][key] = routes[key] | ||
}) | ||
} |
@@ -20,21 +20,23 @@ /* | ||
import symbols from '../symbols.js' | ||
export default (component, state) => { | ||
component.___stateKeys = [] | ||
component[symbols.stateKeys] = [] | ||
state = state.apply(component.prototype) | ||
Object.keys(state).forEach((key) => { | ||
if (component.___propKeys && component.___propKeys.indexOf(key) > -1) { | ||
if (component[symbols.propKeys] && component[symbols.propKeys].indexOf(key) > -1) { | ||
Log.error(`State ${key} already exists as a prop`) | ||
} | ||
if (component.___methodKeys && component.___methodKeys.indexOf(key) > -1) { | ||
if (component[symbols.methodKeys] && component[symbols.methodKeys].indexOf(key) > -1) { | ||
Log.error(`State ${key} already exists as a method`) | ||
} | ||
component.___stateKeys.push(key) | ||
component[symbols.stateKeys].push(key) | ||
try { | ||
Object.defineProperty(component.prototype, key, { | ||
get() { | ||
return this.___state && key in this.___state && this.___state[key] | ||
return this[symbols.state] && key in this[symbols.state] && this[symbols.state][key] | ||
}, | ||
set(v) { | ||
if (this.___state) this.___state[key] = v | ||
if (this[symbols.state]) this[symbols.state][key] = v | ||
}, | ||
@@ -41,0 +43,0 @@ }) |
@@ -18,5 +18,7 @@ /* | ||
import symbols from '../symbols.js' | ||
export default (component, watchers) => { | ||
component.prototype.___watchKeys = [] | ||
component.prototype.___watchers = {} | ||
component.prototype[symbols.watchKeys] = [] | ||
component.prototype[symbols.watchers] = {} | ||
@@ -28,5 +30,5 @@ for (let watch in watchers) { | ||
component.prototype.___watchKeys.push(watch) | ||
component.prototype[symbols.watchKeys].push(watch) | ||
component.prototype.___watchers[watch] = function (v, old) { | ||
component.prototype[symbols.watchers][watch] = function (v, old) { | ||
watchers[watch].call(this, v, old) | ||
@@ -33,0 +35,0 @@ } |
@@ -18,2 +18,4 @@ /* | ||
import symbols from '../symbols.js' | ||
class TemplateParseError extends Error { | ||
@@ -86,3 +88,3 @@ constructor(message, name, context) { | ||
if (match) { | ||
tags.push({ type: null, __type: 'opening', __level: currentLevel }) | ||
tags.push({ type: null, [symbols.type]: 'opening', [symbols.level]: currentLevel }) | ||
currentLevel++ | ||
@@ -99,3 +101,3 @@ parseLoop(parseEmptyTagStart) | ||
currentLevel-- | ||
tags.push({ type: null, __type: 'closing', __level: currentLevel }) | ||
tags.push({ type: null, [symbols.type]: 'closing', [symbols.level]: currentLevel }) | ||
parseLoop(parseEmptyTagStart) | ||
@@ -112,5 +114,5 @@ } else { | ||
currentLevel-- | ||
currentTag = { type: match[1], __type: 'closing', __level: currentLevel } | ||
currentTag = { type: match[1], [symbols.type]: 'closing', [symbols.level]: currentLevel } | ||
} else { | ||
currentTag = { type: match[1], __type: 'opening', __level: currentLevel } | ||
currentTag = { type: match[1], [symbols.type]: 'opening', [symbols.level]: currentLevel } | ||
currentLevel++ | ||
@@ -128,3 +130,3 @@ } | ||
if (match[1] === '/>') { | ||
currentTag.__type = 'self-closing' | ||
currentTag[symbols.type] = 'self-closing' | ||
currentLevel-- // because it was parsed as opening tag before | ||
@@ -135,3 +137,3 @@ } | ||
// rule: < char cannot be used in between tags even in escaped form | ||
if (currentTag.__type === 'opening') { | ||
if (currentTag[symbols.type] === 'opening') { | ||
const tagContent = template.slice(cursor, template.indexOf('<', cursor)) | ||
@@ -187,8 +189,8 @@ if (tagContent) { | ||
for (const item of data) { | ||
const { type, __type, __level } = item | ||
const { type, [symbols.type]: __type, [symbols.level]: __level } = item | ||
// Check for unclosed tags | ||
while (stack.length && stack[stack.length - 1].__level >= __level) { | ||
while (stack.length && stack[stack.length - 1][symbols.level] >= __level) { | ||
const popped = stack.pop() | ||
if (popped.__type === 'opening') { | ||
if (popped[symbols.type] === 'opening') { | ||
throw new TemplateParseError('MismatchedClosingTag', `tag: ${popped.type || 'null'}`) | ||
@@ -216,4 +218,4 @@ } | ||
const newItem = { ...item } | ||
delete newItem.__type | ||
delete newItem.__level | ||
delete newItem[symbols.type] | ||
delete newItem[symbols.level] | ||
@@ -220,0 +222,0 @@ if (__type === 'opening') { |
@@ -20,2 +20,4 @@ /* | ||
import symbols from './lib/symbols.js' | ||
export const getHash = () => { | ||
@@ -35,22 +37,25 @@ return (document.location.hash || '/').replace(/^#/, '') | ||
export const navigate = function () { | ||
if (this.parent.___routes) { | ||
if (this.parent[symbols.routes]) { | ||
const hash = getHash() | ||
const route = matchHash(hash, this.parent.___routes) | ||
const route = matchHash(hash, this.parent[symbols.routes]) | ||
if (route) { | ||
if (this.__currentView) { | ||
for (let i = 0; i < this.__currentView.___children.length - 1; i++) { | ||
if (this.__currentView.___children[i] && this.__currentView.___children[i].destroy) { | ||
this.__currentView.___children[i].destroy() | ||
this.__currentView.___children[i] = null | ||
if (this[symbols.currentView]) { | ||
for (let i = 0; i < this[symbols.currentView][symbols.children].length - 1; i++) { | ||
if ( | ||
this[symbols.currentView][symbols.children][i] && | ||
this[symbols.currentView][symbols.children][i].destroy | ||
) { | ||
this[symbols.currentView][symbols.children][i].destroy() | ||
this[symbols.currentView][symbols.children][i] = null | ||
} | ||
} | ||
this.__currentView.destroy() | ||
this.__currentView = null | ||
this[symbols.currentView].destroy() | ||
this[symbols.currentView] = null | ||
} | ||
this.___children[1] = this.__currentView = route.component( | ||
this.___props, | ||
this.___children[0], | ||
this[symbols.children][1] = this[symbols.currentView] = route.component( | ||
this[symbols.props], | ||
this[symbols.children][0], | ||
this | ||
) | ||
this.__currentView.focus() | ||
this[symbols.currentView].focus() | ||
} else { | ||
@@ -57,0 +62,0 @@ Log.error(`Route ${hash} not found`) |
@@ -18,6 +18,12 @@ /* | ||
import symbols from './lib/symbols.js' | ||
const settings = { | ||
___settings: {}, | ||
[symbols.settings]: {}, | ||
get(key, defaultValue = null) { | ||
return (key in this.___settings && this.___settings[key]) || defaultValue | ||
if (key in this[symbols.settings]) { | ||
return this[symbols.settings][key] | ||
} else { | ||
return defaultValue | ||
} | ||
}, | ||
@@ -30,3 +36,3 @@ set(key, value) { | ||
} else { | ||
this.___settings[key] = value | ||
this[symbols.settings][key] = value | ||
} | ||
@@ -33,0 +39,0 @@ }, |
899877
100
22025
+ Added@lightningjs/renderer@0.5.0(transitive)
- Removed@lightningjs/renderer@0.4.2(transitive)
Updated@lightningjs/renderer@^0.5.0