Compare commits

...

4 commits

View file

@ -35,13 +35,6 @@ const snakeToCSS = key => key.replace(/^[A-Z]/, a => "-" + a).replace(/[A-Z]/g,
* @property {function(Node):boolean} [filter]
*/
/**
* Returns a fallback if value is fallback
* @param {any} value
* @param {any} whenUndefined
*/
const fallback = (value, whenUndefined) => typeof value != "undefined" ? value : whenUndefined
/** @typedef {EventTarget & {value: any}} Observable */
/** Cancelable event triggered when a reactive element gets replaced with something else */
@ -92,48 +85,13 @@ export class AttributeEvent extends Event {
* @param {function(event) : event} fn
* @return {function(event)}
*/
export const handle = fn => event => { event.preventDefault(); return fn(event) }
export const noDefault = fn => event => { event.preventDefault(); return fn(event) }
/** A reference to an element that follows it around through replacements */
export class Ref {
/** @type {WeakMap<Text|Element,Text|Element>} */
static #map = new WeakMap()
/** @type {Element|Text} */
#element
/** @param {Element|Text} element */
constructor(element) {
this.#element = element
}
/** @return {Element|Text} */
deref() {
const next = Ref.newer(this.#element)
if (next) {
this.#element = next
return this.deref()
} else {
return this.#element
}
}
/** @param {Element|Text} element */
static newer(element) {
return this.#map.get(element)
}
/**
* @param {Element|Text} previous
* @param {Element|Text} next
*/
static replace(previous, next) {
if (this.newer(previous))
throw "Element has already been replaced with newer one"
this.#map.set(previous, next)
}
}
/** Wraps an event handler in a function that calls preventDefault on the event
* @param {function(event) : event} fn
* @return {function(event)}
*/
export const noPropagate = fn => event => { event.stopPropagation(); return fn(event) }
/** Main class doing all the rendering */
export class Renderer {
@ -257,7 +215,6 @@ export class DomRenderer extends Renderer {
const next = this.toElement(observable.value)
if (element?.dispatchEvent(new BeforeReplaceEvent(next))) {
element.replaceWith(next)
Ref.replace(element, next)
next.dispatchEvent(new ReplacedEvent(element))
element.dispatchEvent(new AfterReplaceEvent(next))
ref = new WeakRef(next)
@ -403,33 +360,6 @@ export class DomHtmlRenderer extends DomRenderer {
return document.createElement(name.replace(/([a-z])([A-Z])/g, "$1-$2"), options)
}
/** Creates a new node and make it a custom element if necessary
* @param {String} name
* @param {Array} args
*/
node(name, args) {
const custom = this.getCustom(args)
const opts = custom && { is: String(custom) }
const element = this.createElement(name, opts)
this.constructor.apply(element, args)
return element
}
/** Recursively finds the last 'is' attribute in a list nested array of objects
* @param {Array} args
*/
getCustom(args) {
return args.reduce(
(current, argument) => Array.isArray(argument)
? fallback(this.getCustom(argument), current)
: (argument && typeof argument == "object")
? fallback(argument.is, current)
: current
, undefined
)
}
/** @type {Object<string,SpecialAttributeDescriptor>} */
static specialAttributes = {
value: {