ember-legacy-class-transform
Version:
The default blueprint for ember-cli addons.
119 lines • 3.87 kB
JavaScript
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;
}
}
}