UNPKG

taggedjs

Version:

tagged template reactive html

164 lines 6.79 kB
import { output } from '../tag/output.function.js'; import { getInnerHTML } from '../TagJsTags/getInnerHTML.function.js'; import { callback, promise, setUseMemory, state } from '../state/index.js'; import { getTemplaterResult } from '../tag/getTemplaterResult.function.js'; import { tags } from '../tag/tag.utils.js'; import { getTagWrap } from '../tag/getTagWrap.function.js'; import { ValueTypes } from '../tag/ValueTypes.enum.js'; import { processTagComponentInit } from '../tag/update/processTagComponentInit.function.js'; import { checkTagValueChangeAndUpdate } from '../tag/checkTagValueChange.function.js'; import { destroySupportByContextItem } from '../tag/destroySupportByContextItem.function.js'; import { tagValueUpdateHandler } from '../tag/update/tagValueUpdateHandler.function.js'; import { getContextInCycle, getElement as getTagElement } from '../tag/cycles/setContextInCycle.function.js'; import { tagInject } from './tagInject.function.js'; import { onInit as tagOnInit } from '../state/onInit.function.js'; import { onDestroy as tagOnDestroy } from '../state/onDestroy.function.js'; import { callback as tagCallback } from '../state/callback.function.js'; import { onRender as tagOnRender } from '../state/onRender.function.js'; let tagCount = 0; const onClick = makeEventListener('click'); const onMouseDown = makeEventListener('mousedown'); function makeEventListener(type) { return function eventListener(toBeCalled) { const wrapped = callback(toBeCalled); // should cause render to occur // run one time state(() => { const element = getTagElement(); element.addEventListener(type, wrapped); }); return wrapped; // this is what you remove }; } const tagElement = { get: getTagElement, onclick: onClick, click: onClick, onClick, mousedown: onMouseDown, onmousedown: onMouseDown, onMouseDown: onMouseDown, }; defineGetSet('onclick', onClick); defineGetSet('click', onClick); defineGetSet('onMouseDown', onMouseDown); defineGetSet('onmousedown', onMouseDown); defineGetSet('mousedown', onMouseDown); function defineGetSet(name, eventFn) { Object.defineProperty(tag, name, { get() { return eventFn; }, set(fn) { return eventFn(fn); }, }); } /** How to handle checking for prop changes aka argument changes */ export var PropWatches; (function (PropWatches) { PropWatches["DEEP"] = "deep"; /** checks all values up to 2 levels deep */ PropWatches["SHALLOW"] = "shallow"; PropWatches["NONE"] = "none"; PropWatches["IMMUTABLE"] = "immutable"; })(PropWatches || (PropWatches = {})); /** Wraps a function tag in a state manager and calls wrapped function on event cycles */ export function tag(tagComponent, propWatch = PropWatches.SHALLOW) { const isRunningContent = getContextInCycle(); if (isRunningContent) { throw new Error('A TaggedJs tag was created within a running tag. All component tags must be created outside of anyother tag'); } // ): TagJsComponent<any> { /** function developer triggers */ const parentWrap = function tagWrapper(...props) { const templater = getTemplaterResult(propWatch, props); templater.tagJsType = ValueTypes.tagComponent; templater.processInit = processTagComponentInit; templater.hasValueChanged = checkTagValueChangeAndUpdate; // attach memory back to original function that contains developer display logic const innerTagWrap = getTagWrap(templater, parentWrap); innerTagWrap.original = tagComponent; templater.wrapper = innerTagWrap; return templater; }; // we override the function provided and pretend original is what's returned const tag = tagComponent; parentWrap.original = tagComponent; // group tags together and have hmr pickup tag.tags = tags; tag.setUse = setUseMemory; tag.ValueTypes = ValueTypes; tag.tagIndex = tagCount++; // needed for things like HMR tags.push(parentWrap); const returnWrap = parentWrap; /* Used for setting arguments as inputs and outputs. Runs every init and update of tag */ returnWrap.inputs = (handler) => { const context = getContextInCycle(); context.inputsHandler = handler; const tagJsVar = context.tagJsVar; // const value = context.value as any // handler(value.props) handler(tagJsVar.props); return true; }; // used for argument updates returnWrap.updates = (handler) => { const context = getContextInCycle(); context.updatesHandler = handler; return true; }; returnWrap.getInnerHTML = getInnerHTML; // returnWrap.tagJsType = 'component' return returnWrap; } /** Use to structure and define a browser tag route handler * Example: export default tag.route = (routeProps: RouteProps) => (state) => html`` */ function routeFn(_routeProps) { throw new Error('Do not call tag.route as a function but instead set it as: `tag.route = (routeProps: RouteProps) => (state) => html`` `'); } /** Used to create variable scoping when calling a function that lives within a prop container function */ function tagUseFn() { throw new Error('Do not call tag.use as a function but instead set it as: `(props) => tag.use = (use) => html`` `'); } // actually placing of items into tag memory ; tag.element = tagElement; tag.use = tagUseFn; tag.deepPropWatch = tag; tag.route = routeFn; tag.inject = tagInject; tag.output = output; tag.onInit = tagOnInit; tag.onDestroy = tagOnDestroy; tag.callback = tagCallback; tag.onRender = tagOnRender; tag.getInnerHTML = getInnerHTML; tag.app = function (_routeTag) { throw new Error('Do not call tag.route as a function but instead set it as: `tag.route = (routeProps: RouteProps) => (state) => html`` `'); }; tag.immutableProps = function immutableProps(tagComponent) { return tag(tagComponent, PropWatches.IMMUTABLE); }; tag.watchProps = function watchProps(tagComponent) { return tag(tagComponent, PropWatches.SHALLOW); }; /* BELOW: Cast functions into setters with no getters */ Object.defineProperty(tag, 'use', { set(renderFunction) { renderFunction.original = { setUse: setUseMemory, tags, }; renderFunction.tagJsType = ValueTypes.stateRender; renderFunction.processInit = processTagComponentInit; renderFunction.processUpdate = tagValueUpdateHandler; renderFunction.hasValueChanged = checkTagValueChangeAndUpdate; renderFunction.destroy = destroySupportByContextItem; }, }); Object.defineProperty(tag, 'promise', { set(target) { promise(target); }, }); //# sourceMappingURL=tag.function.js.map