Skip to content

Latest commit

 

History

History
84 lines (73 loc) · 4.54 KB

lindt.md

File metadata and controls

84 lines (73 loc) · 4.54 KB

Lindt - Master Chocolatier

(If you want chocolates you can actually eat, the creations of the Lindt & Sprungli company are spectacular, and are what inspired the name of this module.)

Rather than building your chocolates yourself, call on a master chocolatier! This has overhead, of course, but can offer some hefty benefits. Replace all use of 'choc' with 'lindt', and of 'set_content' with 'replace_content', and our craftsmen will assemble chocolate to your exacting specifications.

Here's how you make your own chocolate:

import {choc, set_content, on, DOM} from "https://rosuav.github.io/choc/factory.js";
const {FORM, INPUT, LABEL} = choc; //autoimport
set_content("body", FORM(
    LABEL(["Speak thy mind:", INPUT({name: "thought"})])
);

Here's how you get a chocolatier to make it for you:

import {lindt, replace_content, on, DOM} from "https://rosuav.github.io/choc/factory.js";
const {FORM, INPUT, LABEL} = lindt; //autoimport
replace_content("body", FORM(
    LABEL(["Speak thy mind:", INPUT({name: "thought"})])
);

It's that simple! Of course, there are a number of consequences. Here are the differences between choc/set_content and lindt/replace_content:

  • The elements returned by lindt constructors aren't actual DOM elements; they are templates that can only be used by replace_content.
  • Direct DOM manipulation will cause problems for replace_content; at best, you lose the benefits, and at worst, you can have corrupted results. If you use replace_content to set an element's content, always and only use replace_content for that element.
  • For best results, it is sometimes necessary to set a key on lindt elements. This is optional but can improve performance. It's completely unnecessary with choc/set_content.
  • Using set_content with lindt objects won't work. Using replace_content with choc objects will work, but without the benefits of lindt.

The key benefit of replace_content is that it will reuse existing DOM elements rather than construct new ones. This means less flicker, hopefully less CPU load, and better handling of user changes in inputs and textareas.

Stuff to keep in mind

  • Whatever array you pass to replace_content, don't mutate it. That's usually not a problem, as any array you create will need to be mapped through element creation anyway; but mutating this array can cause desynchronization, so don't.
  • If your elements can be reordered within their arrays, consider giving them key attributes (eg INPUT({key: "foo"})) to ensure that they will be properly recognized and reused.
  • To set a key on an array, use lindt({key: "..."}, [...]). This is lightweight as arrays always are (there's no corresponding DOM element), but it will be recognized by its key, not its position.
  • Lindt is designed to do the right thing with minimal guidance, but in some cases, it will do more work than necessary. Ensure that variable-length sections are in their own arrays for best results (eg by mapping over an array of data to form an array of elements).
  • Changes to the template get propagated into the DOM, but changes in the DOM are ignored. This has a few consequences, particularly with the 'value' attribute of an INPUT element:
    • Setting the value on a newly-created input will set its default/initial value
    • Keeping the template unchanged will allow the user to make changes, which are not affected by rerendering through replace_content
    • Changing the value in the template will change the input's contents to that value, as long as it isn't already set to that.
    • It is NOT possible to query an input, then force it back to its default by re-assigning that. To accomplish this, the easiest way is to explicitly set the input's value; it may also be possible to trick replace_content into doing this for you, but this would be less efficient.
    • Certain special attributes (volume and value) cannot currently be removed from an object if they are removed from the template. I consider this to be a flaw, but one that's not easy to fix, and easy enough to work around (set them to plausible defaults instead of removing them altogether).
    • TEXTAREA and OPTION elements have value attributes that behave the same way. In the case of the TEXTAREA, a value attribute takes precedence over contained text and behaves as above; contained text is used only as the initial value, and will not be updated subsequently.
  • Eat some Lindor balls while coding. They're worth it.