diff --git a/module.js b/module.js index f23198d..93d3192 100644 --- a/module.js +++ b/module.js @@ -1,7 +1,31 @@ + +import TemplateRenderer, { cache } from './modules/renderer-template.js'; + +export default function Literal(id) { + // TODO: I don't think this works, it replaces whatever template is in the + // DOM, it it probably isn't in the DOM if it's cached? + + const id = typeof id === 'object' ? + id.id || '' : + id ; + + if (cache[id]) { + return cache[id].create(); + } + + const template = typeof id === 'object' ? + id : + document.getElementById(id) ; + + return new TemplateRenderer(template) ; +} + +// TODO: Legacy, remove +export { TemplateRenderer as Renderer }; + export { compiled } from './modules/renderer/compile.js'; export { default as config } from './modules/config.js'; export { default as Data, observe } from './modules/data.js'; -export { default as Renderer } from './modules/renderer-template.js'; export { default as scope } from './modules/scope.js'; export { urls } from './modules/urls.js'; diff --git a/modules/config.js b/modules/config.js index 5e7f058..14768fc 100644 --- a/modules/config.js +++ b/modules/config.js @@ -2,9 +2,27 @@ /* config Configure Literal's behaviour. + +```js + // An event dispatched when Literal updates input values. Default is `false`. + config.updateEvent = CustomEvent('ping'); + + // Run templates in sloppy mode inside a `with(data)` statement, making + // `${ data.name }` available as simply `${ name }` in a template. + // Warning: MDN says `with` should be considered deprecated: + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with + // I really don't see how they can remove it, though. + useWith: false +``` */ export default { // An event dispatched when Literal updates input values. May be false. - updateEvent: false + updateEvent: false, + // Runs templates in sloppy mode inside a `with(data)` statment, making + // `${ data.name }` available as simply `${ name }` in a template. + // Warning: MDN says with should be considered deprecated: + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with + // I don't see how anyone can remove it, though. + useWith: false } diff --git a/modules/data.js b/modules/data.js index ef56665..24b3761 100644 --- a/modules/data.js +++ b/modules/data.js @@ -1,7 +1,9 @@ import { Observer as Data, getTarget } from '../../fn/observer/observer.js'; +import observe from '../../fn/observer/observe.js'; Data.getObject = getTarget; +Data.observe = observe; export default Data; -export { default as observe } from '../../fn/observer/observe.js'; +export { observe }; diff --git a/modules/renderer-template.js b/modules/renderer-template.js index 456f5c2..f104fd2 100644 --- a/modules/renderer-template.js +++ b/modules/renderer-template.js @@ -1,6 +1,6 @@ /** -TemplateRenderer(template, element, parameters) +TemplateRenderer(template, element, parameters, options) Import the `TemplateRenderer` constructor: @@ -40,7 +40,7 @@ import { groupCollapsed, groupEnd } from './log.js'; const assign = Object.assign; const keys = Object.keys; -const cache = {}; +export const cache = {}; const nodes = []; @@ -98,19 +98,19 @@ function prepareContent(content) { } } -function compileContent(content, message) { +function compileContent(content, message, options) { if (window.DEBUG) { groupCollapsed('compile', message, 'yellow'); } prepareContent(content); - const renderers = compileNode([], content, '', message); + const renderers = compileNode([], content, '', message, options); if (window.DEBUG) { groupEnd(); } return renderers; } -function compileTemplate(template, id) { +function compileTemplate(template, id, options) { const content = template.content || create('fragment', template.childNodes, template) ; - const renderers = compileContent(content, '#' + id); + const renderers = compileContent(content, '#' + id, options); return { id, content, renderers }; } @@ -136,7 +136,9 @@ export default function TemplateRenderer(template, element = template.parentElem const id = identify(template) ; const { content, renderers } = cache[id] - || (cache[id] = compileTemplate(template, id)); + || (cache[id] = compileTemplate(template, id, { + sloppy: template.hasAttribute('nostrict') + })); this.element = element; this.parameters = parameters; diff --git a/modules/renderer/compile-attribute.js b/modules/renderer/compile-attribute.js index 0066dc8..f8e1e32 100644 --- a/modules/renderer/compile-attribute.js +++ b/modules/renderer/compile-attribute.js @@ -17,6 +17,10 @@ compileAttributes(renderers, element, attribute, path, message) **/ const constructors = { + class: TokensRenderer, + value: ValueRenderer, + checked: CheckedRenderer, + async: BooleanRenderer, autofocus: BooleanRenderer, autoplay: BooleanRenderer, @@ -38,19 +42,16 @@ const constructors = { reversed: BooleanRenderer, selected: BooleanRenderer, default: BooleanRenderer, - checked: CheckedRenderer, - class: TokensRenderer, - value: ValueRenderer, // Workaround attribute used in cases where ${} cannot be added directly to // HTML, such as in or - 'inner-html': function(path, name, source, message, element) { + 'inner-html': function(path, name, source, message, options, element) { element.removeAttribute(name); - return new TextRenderer(path, 0, decode(source), message, element.childNodes[0]); + return new TextRenderer(path, 0, decode(source), message, options, element.childNodes[0]); } }; -export default function compileAttribute(renderers, element, attribute, path, message = '') { +export default function compileAttribute(renderers, element, attribute, path, message = '', options) { const name = attribute.localName; const source = attribute.value; @@ -65,6 +66,6 @@ export default function compileAttribute(renderers, element, attribute, path, me } const Constructor = constructors[name] || AttributeRenderer; - renderers.push(new Constructor(path, name, source, message, element)); + renderers.push(new Constructor(path, name, source, message, options, element)); return renderers; } diff --git a/modules/renderer/compile-node.js b/modules/renderer/compile-node.js index a6c371b..5761d27 100644 --- a/modules/renderer/compile-node.js +++ b/modules/renderer/compile-node.js @@ -15,10 +15,10 @@ const assign = Object.assign; /* -compileChildren(renderers, element, path, message) +compileChildren(renderers, element, path, message, options) */ -function compileChildren(renderers, element, path, message = '') { +function compileChildren(renderers, element, path, message = '', options) { // Children may mutate during compile, and we only want to compile // current children const children = Array.from(element.childNodes); @@ -51,7 +51,7 @@ function compileChildren(renderers, element, path, message = '') { } } - compileNode(renderers, children[n], path, message); + compileNode(renderers, children[n], path, message, options); } } @@ -60,16 +60,16 @@ function compileChildren(renderers, element, path, message = '') { /* -compileAttributes(renderers, node, path, message) +compileAttributes(renderers, node, path, message, options) */ -function compileAttributes(renderers, element, path, message = '') { +function compileAttributes(renderers, element, path, message = '', options) { // Attributes may be removed during parsing so copy the list before looping const attributes = Array.from(element.attributes); let n = -1, attribute; while (attribute = attributes[++n]) { - compileAttribute(renderers, element, attribute, path, message); + compileAttribute(renderers, element, attribute, path, message, options); } return renderers; @@ -77,7 +77,7 @@ function compileAttributes(renderers, element, path, message = '') { /* -compileElement(renderers, node, path, message) +compileElement(renderers, node, path, message, options) */ const compileElement = overload((renderers, element) => element.tagName.toLowerCase(), { @@ -89,31 +89,31 @@ const compileElement = overload((renderers, element) => element.tagName.toLowerC // Do not parse the inner DOM of scripts 'script': compileAttributes, - 'textarea': (renderers, element, path, message) => { + 'textarea': (renderers, element, path, message, options) => { // A