UNPKG

ember-legacy-class-transform

Version:
119 lines 3.87 kB
import { unreachable } from '@glimmer/util'; import { clear, single, SingleNodeBounds } from './bounds'; export function isSafeString(value) { return typeof value === 'object' && value !== null && typeof value.toHTML === 'function'; } export function isNode(value) { return typeof value === 'object' && value !== null && typeof value.nodeType === 'number'; } export function isString(value) { return typeof value === 'string'; } class Upsert { constructor(bounds) { this.bounds = bounds; } } export default Upsert; export function cautiousInsert(dom, cursor, value) { if (isString(value)) { return TextUpsert.insert(dom, cursor, value); } if (isSafeString(value)) { return SafeStringUpsert.insert(dom, cursor, value); } if (isNode(value)) { return NodeUpsert.insert(dom, cursor, value); } throw unreachable(); } export function trustingInsert(dom, cursor, value) { if (isString(value)) { return HTMLUpsert.insert(dom, cursor, value); } if (isNode(value)) { return NodeUpsert.insert(dom, cursor, value); } throw unreachable(); } class TextUpsert extends Upsert { static insert(dom, cursor, value) { let textNode = dom.createTextNode(value); dom.insertBefore(cursor.element, textNode, cursor.nextSibling); let bounds = new SingleNodeBounds(cursor.element, textNode); return new TextUpsert(bounds, textNode); } constructor(bounds, textNode) { super(bounds); this.textNode = textNode; } update(_dom, value) { if (isString(value)) { let { textNode } = this; textNode.nodeValue = value; return true; } else { return false; } } } class HTMLUpsert extends Upsert { static insert(dom, cursor, value) { let bounds = dom.insertHTMLBefore(cursor.element, cursor.nextSibling, value); return new HTMLUpsert(bounds); } update(dom, value) { if (isString(value)) { let { bounds } = this; let parentElement = bounds.parentElement(); let nextSibling = clear(bounds); this.bounds = dom.insertHTMLBefore(parentElement, nextSibling, value); return true; } else { return false; } } } class SafeStringUpsert extends Upsert { constructor(bounds, lastStringValue) { super(bounds); this.lastStringValue = lastStringValue; } static insert(dom, cursor, value) { let stringValue = value.toHTML(); let bounds = dom.insertHTMLBefore(cursor.element, cursor.nextSibling, stringValue); return new SafeStringUpsert(bounds, stringValue); } update(dom, value) { if (isSafeString(value)) { let stringValue = value.toHTML(); if (stringValue !== this.lastStringValue) { let { bounds } = this; let parentElement = bounds.parentElement(); let nextSibling = clear(bounds); this.bounds = dom.insertHTMLBefore(parentElement, nextSibling, stringValue); this.lastStringValue = stringValue; } return true; } else { return false; } } } class NodeUpsert extends Upsert { static insert(dom, cursor, node) { dom.insertBefore(cursor.element, node, cursor.nextSibling); return new NodeUpsert(single(cursor.element, node)); } update(dom, value) { if (isNode(value)) { let { bounds } = this; let parentElement = bounds.parentElement(); let nextSibling = clear(bounds); this.bounds = dom.insertNodeBefore(parentElement, value, nextSibling); return true; } else { return false; } } }