Comparing version 0.0.0-experimental-c450721b1-20240312 to 0.0.0-experimental-cb3cbcb83-20240318
@@ -59,11 +59,3 @@ export declare class Attributor { | ||
domNode: Node; | ||
statics: { | ||
allowedChildren?: BlotConstructor[]; | ||
blotName: string; | ||
className?: string; | ||
defaultChild?: BlotConstructor; | ||
requiredContainer?: BlotConstructor; | ||
scope: Scope; | ||
tagName: string | string[]; | ||
}; | ||
statics: BlotConstructor; | ||
attach(): void; | ||
@@ -73,3 +65,10 @@ clone(): Blot; | ||
isolate(index: number, length: number): Blot; | ||
/** | ||
* For leaves, length of blot's value() | ||
* For parents, sum of children's values | ||
*/ | ||
length(): number; | ||
/** | ||
* Returns offset between this blot and an ancestor's | ||
*/ | ||
offset(root?: Blot): number; | ||
@@ -85,2 +84,7 @@ remove(): void; | ||
insertAt(index: number, value: string, def?: any): void; | ||
/** | ||
* Called after update cycle completes. Cannot change the value or length | ||
* of the document, and any DOM operation must reduce complexity of the DOM | ||
* tree. A shared context object is passed through all blots. | ||
*/ | ||
optimize(context: { | ||
@@ -92,2 +96,8 @@ [key: string]: any; | ||
}): void; | ||
/** | ||
* Called when blot changes, with the mutation records of its change. | ||
* Internal records of the blot values can be updated, and modifications of | ||
* the blot itself is permitted. Can be trigger from user change or API call. | ||
* A shared context object is passed through all blots. | ||
*/ | ||
update(mutations: MutationRecord[], context: { | ||
@@ -99,7 +109,14 @@ [key: string]: any; | ||
export declare interface BlotConstructor { | ||
new (...args: any[]): Blot; | ||
/** | ||
* Creates corresponding DOM node | ||
*/ | ||
create(value?: any): Node; | ||
blotName: string; | ||
tagName: string | string[]; | ||
scope: Scope; | ||
className?: string; | ||
tagName: string | string[]; | ||
new (...args: any[]): Blot; | ||
create(value?: any): Node; | ||
requiredContainer?: BlotConstructor; | ||
allowedChildren?: BlotConstructor[]; | ||
defaultChild?: BlotConstructor; | ||
} | ||
@@ -139,3 +156,9 @@ | ||
export declare interface Formattable extends Blot { | ||
/** | ||
* Apply format to blot. Should not pass onto child or other blot. | ||
*/ | ||
format(name: string, value: any): void; | ||
/** | ||
* Return formats represented by blot, including from Attributors. | ||
*/ | ||
formats(): { | ||
@@ -178,5 +201,23 @@ [index: string]: any; | ||
static scope: Scope; | ||
/** | ||
* Returns the value represented by domNode if it is this Blot's type | ||
* No checking that domNode can represent this Blot type is required so | ||
* applications needing it should check externally before calling. | ||
*/ | ||
static value(_domNode: Node): any; | ||
/** | ||
* Given location represented by node and offset from DOM Selection Range, | ||
* return index to that location. | ||
*/ | ||
index(node: Node, offset: number): number; | ||
/** | ||
* Given index to location within blot, return node and offset representing | ||
* that location, consumable by DOM Selection Range | ||
*/ | ||
position(index: number, _inclusive?: boolean): [Node, number]; | ||
/** | ||
* Return value represented by this blot | ||
* Should not change without interaction from API or | ||
* user change detectable by update() | ||
*/ | ||
value(): any; | ||
@@ -227,3 +268,9 @@ } | ||
export declare class ParentBlot extends ShadowBlot implements Parent { | ||
static allowedChildren: BlotConstructor[] | null; | ||
/** | ||
* Whitelist array of Blots that can be direct children. | ||
*/ | ||
static allowedChildren?: BlotConstructor[]; | ||
/** | ||
* Default child blot to be inserted if this blot becomes empty. | ||
*/ | ||
static defaultChild?: BlotConstructor; | ||
@@ -238,2 +285,5 @@ static uiClass: string; | ||
attachUI(node: HTMLElement): void; | ||
/** | ||
* Called during construction, should fill its own children LinkedList. | ||
*/ | ||
build(): void; | ||
@@ -240,0 +290,0 @@ deleteAt(index: number, length: number): void; |
@@ -1,152 +0,154 @@ | ||
var l = /* @__PURE__ */ ((a) => (a[a.TYPE = 3] = "TYPE", a[a.LEVEL = 12] = "LEVEL", a[a.ATTRIBUTE = 13] = "ATTRIBUTE", a[a.BLOT = 14] = "BLOT", a[a.INLINE = 7] = "INLINE", a[a.BLOCK = 11] = "BLOCK", a[a.BLOCK_BLOT = 10] = "BLOCK_BLOT", a[a.INLINE_BLOT = 6] = "INLINE_BLOT", a[a.BLOCK_ATTRIBUTE = 9] = "BLOCK_ATTRIBUTE", a[a.INLINE_ATTRIBUTE = 5] = "INLINE_ATTRIBUTE", a[a.ANY = 15] = "ANY", a))(l || {}); | ||
class b { | ||
constructor(t, e, s = {}) { | ||
this.attrName = t, this.keyName = e; | ||
const r = l.TYPE & l.ATTRIBUTE; | ||
this.scope = s.scope != null ? ( | ||
var Scope = /* @__PURE__ */ ((Scope2) => (Scope2[Scope2.TYPE = 3] = "TYPE", Scope2[Scope2.LEVEL = 12] = "LEVEL", Scope2[Scope2.ATTRIBUTE = 13] = "ATTRIBUTE", Scope2[Scope2.BLOT = 14] = "BLOT", Scope2[Scope2.INLINE = 7] = "INLINE", Scope2[Scope2.BLOCK = 11] = "BLOCK", Scope2[Scope2.BLOCK_BLOT = 10] = "BLOCK_BLOT", Scope2[Scope2.INLINE_BLOT = 6] = "INLINE_BLOT", Scope2[Scope2.BLOCK_ATTRIBUTE = 9] = "BLOCK_ATTRIBUTE", Scope2[Scope2.INLINE_ATTRIBUTE = 5] = "INLINE_ATTRIBUTE", Scope2[Scope2.ANY = 15] = "ANY", Scope2))(Scope || {}); | ||
class Attributor { | ||
constructor(attrName, keyName, options = {}) { | ||
this.attrName = attrName, this.keyName = keyName; | ||
const attributeBit = Scope.TYPE & Scope.ATTRIBUTE; | ||
this.scope = options.scope != null ? ( | ||
// Ignore type bits, force attribute bit | ||
s.scope & l.LEVEL | r | ||
) : l.ATTRIBUTE, s.whitelist != null && (this.whitelist = s.whitelist); | ||
options.scope & Scope.LEVEL | attributeBit | ||
) : Scope.ATTRIBUTE, options.whitelist != null && (this.whitelist = options.whitelist); | ||
} | ||
static keys(t) { | ||
return Array.from(t.attributes).map((e) => e.name); | ||
static keys(node) { | ||
return Array.from(node.attributes).map((item) => item.name); | ||
} | ||
add(t, e) { | ||
return this.canAdd(t, e) ? (t.setAttribute(this.keyName, e), !0) : !1; | ||
add(node, value) { | ||
return this.canAdd(node, value) ? (node.setAttribute(this.keyName, value), !0) : !1; | ||
} | ||
canAdd(t, e) { | ||
return this.whitelist == null ? !0 : typeof e == "string" ? this.whitelist.indexOf(e.replace(/["']/g, "")) > -1 : this.whitelist.indexOf(e) > -1; | ||
canAdd(_node, value) { | ||
return this.whitelist == null ? !0 : typeof value == "string" ? this.whitelist.indexOf(value.replace(/["']/g, "")) > -1 : this.whitelist.indexOf(value) > -1; | ||
} | ||
remove(t) { | ||
t.removeAttribute(this.keyName); | ||
remove(node) { | ||
node.removeAttribute(this.keyName); | ||
} | ||
value(t) { | ||
const e = t.getAttribute(this.keyName); | ||
return this.canAdd(t, e) && e ? e : ""; | ||
value(node) { | ||
const value = node.getAttribute(this.keyName); | ||
return this.canAdd(node, value) && value ? value : ""; | ||
} | ||
} | ||
class N extends Error { | ||
constructor(t) { | ||
t = "[Parchment] " + t, super(t), this.message = t, this.name = this.constructor.name; | ||
class ParchmentError extends Error { | ||
constructor(message) { | ||
message = "[Parchment] " + message, super(message), this.message = message, this.name = this.constructor.name; | ||
} | ||
} | ||
const g = class g { | ||
const _Registry = class _Registry { | ||
constructor() { | ||
this.attributes = {}, this.classes = {}, this.tags = {}, this.types = {}; | ||
} | ||
static find(t, e = !1) { | ||
if (t == null) | ||
static find(node, bubble = !1) { | ||
if (node == null) | ||
return null; | ||
if (this.blots.has(t)) | ||
return this.blots.get(t) || null; | ||
if (e) { | ||
let s = null; | ||
if (this.blots.has(node)) | ||
return this.blots.get(node) || null; | ||
if (bubble) { | ||
let parentNode = null; | ||
try { | ||
s = t.parentNode; | ||
parentNode = node.parentNode; | ||
} catch { | ||
return null; | ||
} | ||
return this.find(s, e); | ||
return this.find(parentNode, bubble); | ||
} | ||
return null; | ||
} | ||
create(t, e, s) { | ||
const r = this.query(e); | ||
if (r == null) | ||
throw new N(`Unable to create ${e} blot`); | ||
const i = r, h = ( | ||
create(scroll, input, value) { | ||
const match2 = this.query(input); | ||
if (match2 == null) | ||
throw new ParchmentError(`Unable to create ${input} blot`); | ||
const blotClass = match2, node = ( | ||
// @ts-expect-error Fix me later | ||
e instanceof Node || e.nodeType === Node.TEXT_NODE ? e : i.create(s) | ||
), n = new i(t, h, s); | ||
return g.blots.set(n.domNode, n), n; | ||
input instanceof Node || input.nodeType === Node.TEXT_NODE ? input : blotClass.create(value) | ||
), blot = new blotClass(scroll, node, value); | ||
return _Registry.blots.set(blot.domNode, blot), blot; | ||
} | ||
find(t, e = !1) { | ||
return g.find(t, e); | ||
find(node, bubble = !1) { | ||
return _Registry.find(node, bubble); | ||
} | ||
query(t, e = l.ANY) { | ||
let s; | ||
return typeof t == "string" ? s = this.types[t] || this.attributes[t] : t instanceof Text || t.nodeType === Node.TEXT_NODE ? s = this.types.text : typeof t == "number" ? t & l.LEVEL & l.BLOCK ? s = this.types.block : t & l.LEVEL & l.INLINE && (s = this.types.inline) : t instanceof Element && ((t.getAttribute("class") || "").split(/\s+/).some((i) => (s = this.classes[i], !!s)), s = s || this.tags[t.tagName]), s == null ? null : "scope" in s && e & l.LEVEL & s.scope && e & l.TYPE & s.scope ? s : null; | ||
query(query, scope = Scope.ANY) { | ||
let match2; | ||
return typeof query == "string" ? match2 = this.types[query] || this.attributes[query] : query instanceof Text || query.nodeType === Node.TEXT_NODE ? match2 = this.types.text : typeof query == "number" ? query & Scope.LEVEL & Scope.BLOCK ? match2 = this.types.block : query & Scope.LEVEL & Scope.INLINE && (match2 = this.types.inline) : query instanceof Element && ((query.getAttribute("class") || "").split(/\s+/).some((name) => (match2 = this.classes[name], !!match2)), match2 = match2 || this.tags[query.tagName]), match2 == null ? null : "scope" in match2 && scope & Scope.LEVEL & match2.scope && scope & Scope.TYPE & match2.scope ? match2 : null; | ||
} | ||
register(...t) { | ||
return t.map((e) => { | ||
const s = "blotName" in e, r = "attrName" in e; | ||
if (!s && !r) | ||
throw new N("Invalid definition"); | ||
if (s && e.blotName === "abstract") | ||
throw new N("Cannot register abstract class"); | ||
const i = s ? e.blotName : r ? e.attrName : void 0; | ||
return this.types[i] = e, r ? typeof e.keyName == "string" && (this.attributes[e.keyName] = e) : s && (e.className && (this.classes[e.className] = e), e.tagName && (Array.isArray(e.tagName) ? e.tagName = e.tagName.map((n) => n.toUpperCase()) : e.tagName = e.tagName.toUpperCase(), (Array.isArray(e.tagName) ? e.tagName : [e.tagName]).forEach((n) => { | ||
(this.tags[n] == null || e.className == null) && (this.tags[n] = e); | ||
}))), e; | ||
register(...definitions) { | ||
return definitions.map((definition) => { | ||
const isBlot = "blotName" in definition, isAttr = "attrName" in definition; | ||
if (!isBlot && !isAttr) | ||
throw new ParchmentError("Invalid definition"); | ||
if (isBlot && definition.blotName === "abstract") | ||
throw new ParchmentError("Cannot register abstract class"); | ||
const key = isBlot ? definition.blotName : isAttr ? definition.attrName : void 0; | ||
return this.types[key] = definition, isAttr ? typeof definition.keyName == "string" && (this.attributes[definition.keyName] = definition) : isBlot && (definition.className && (this.classes[definition.className] = definition), definition.tagName && (Array.isArray(definition.tagName) ? definition.tagName = definition.tagName.map((tagName) => tagName.toUpperCase()) : definition.tagName = definition.tagName.toUpperCase(), (Array.isArray(definition.tagName) ? definition.tagName : [definition.tagName]).forEach((tag) => { | ||
(this.tags[tag] == null || definition.className == null) && (this.tags[tag] = definition); | ||
}))), definition; | ||
}); | ||
} | ||
}; | ||
g.blots = /* @__PURE__ */ new WeakMap(); | ||
let y = g; | ||
function M(a, t) { | ||
return (a.getAttribute("class") || "").split(/\s+/).filter((s) => s.indexOf(`${t}-`) === 0); | ||
_Registry.blots = /* @__PURE__ */ new WeakMap(); | ||
let Registry = _Registry; | ||
function match(node, prefix) { | ||
return (node.getAttribute("class") || "").split(/\s+/).filter((name) => name.indexOf(`${prefix}-`) === 0); | ||
} | ||
class K extends b { | ||
static keys(t) { | ||
return (t.getAttribute("class") || "").split(/\s+/).map((e) => e.split("-").slice(0, -1).join("-")); | ||
class ClassAttributor extends Attributor { | ||
static keys(node) { | ||
return (node.getAttribute("class") || "").split(/\s+/).map((name) => name.split("-").slice(0, -1).join("-")); | ||
} | ||
add(t, e) { | ||
return this.canAdd(t, e) ? (this.remove(t), t.classList.add(`${this.keyName}-${e}`), !0) : !1; | ||
add(node, value) { | ||
return this.canAdd(node, value) ? (this.remove(node), node.classList.add(`${this.keyName}-${value}`), !0) : !1; | ||
} | ||
remove(t) { | ||
M(t, this.keyName).forEach((s) => { | ||
t.classList.remove(s); | ||
}), t.classList.length === 0 && t.removeAttribute("class"); | ||
remove(node) { | ||
match(node, this.keyName).forEach((name) => { | ||
node.classList.remove(name); | ||
}), node.classList.length === 0 && node.removeAttribute("class"); | ||
} | ||
value(t) { | ||
const s = (M(t, this.keyName)[0] || "").slice(this.keyName.length + 1); | ||
return this.canAdd(t, s) ? s : ""; | ||
value(node) { | ||
const value = (match(node, this.keyName)[0] || "").slice(this.keyName.length + 1); | ||
return this.canAdd(node, value) ? value : ""; | ||
} | ||
} | ||
function x(a) { | ||
const t = a.split("-"), e = t.slice(1).map((s) => s[0].toUpperCase() + s.slice(1)).join(""); | ||
return t[0] + e; | ||
const ClassAttributor$1 = ClassAttributor; | ||
function camelize(name) { | ||
const parts = name.split("-"), rest = parts.slice(1).map((part) => part[0].toUpperCase() + part.slice(1)).join(""); | ||
return parts[0] + rest; | ||
} | ||
class Y extends b { | ||
static keys(t) { | ||
return (t.getAttribute("style") || "").split(";").map((e) => e.split(":")[0].trim()); | ||
class StyleAttributor extends Attributor { | ||
static keys(node) { | ||
return (node.getAttribute("style") || "").split(";").map((value) => value.split(":")[0].trim()); | ||
} | ||
add(t, e) { | ||
return this.canAdd(t, e) ? (t.style[x(this.keyName)] = e, !0) : !1; | ||
add(node, value) { | ||
return this.canAdd(node, value) ? (node.style[camelize(this.keyName)] = value, !0) : !1; | ||
} | ||
remove(t) { | ||
t.style[x(this.keyName)] = "", t.getAttribute("style") || t.removeAttribute("style"); | ||
remove(node) { | ||
node.style[camelize(this.keyName)] = "", node.getAttribute("style") || node.removeAttribute("style"); | ||
} | ||
value(t) { | ||
const e = t.style[x(this.keyName)]; | ||
return this.canAdd(t, e) ? e : ""; | ||
value(node) { | ||
const value = node.style[camelize(this.keyName)]; | ||
return this.canAdd(node, value) ? value : ""; | ||
} | ||
} | ||
class D { | ||
constructor(t) { | ||
this.attributes = {}, this.domNode = t, this.build(); | ||
const StyleAttributor$1 = StyleAttributor; | ||
class AttributorStore { | ||
constructor(domNode) { | ||
this.attributes = {}, this.domNode = domNode, this.build(); | ||
} | ||
attribute(t, e) { | ||
e ? t.add(this.domNode, e) && (t.value(this.domNode) != null ? this.attributes[t.attrName] = t : delete this.attributes[t.attrName]) : (t.remove(this.domNode), delete this.attributes[t.attrName]); | ||
attribute(attribute, value) { | ||
value ? attribute.add(this.domNode, value) && (attribute.value(this.domNode) != null ? this.attributes[attribute.attrName] = attribute : delete this.attributes[attribute.attrName]) : (attribute.remove(this.domNode), delete this.attributes[attribute.attrName]); | ||
} | ||
build() { | ||
this.attributes = {}; | ||
const t = y.find(this.domNode); | ||
if (t == null) | ||
const blot = Registry.find(this.domNode); | ||
if (blot == null) | ||
return; | ||
const e = b.keys(this.domNode), s = K.keys(this.domNode), r = Y.keys(this.domNode); | ||
e.concat(s).concat(r).forEach((i) => { | ||
const h = t.scroll.query(i, l.ATTRIBUTE); | ||
h instanceof b && (this.attributes[h.attrName] = h); | ||
const attributes = Attributor.keys(this.domNode), classes = ClassAttributor$1.keys(this.domNode), styles = StyleAttributor$1.keys(this.domNode); | ||
attributes.concat(classes).concat(styles).forEach((name) => { | ||
const attr = blot.scroll.query(name, Scope.ATTRIBUTE); | ||
attr instanceof Attributor && (this.attributes[attr.attrName] = attr); | ||
}); | ||
} | ||
copy(t) { | ||
Object.keys(this.attributes).forEach((e) => { | ||
const s = this.attributes[e].value(this.domNode); | ||
t.format(e, s); | ||
copy(target) { | ||
Object.keys(this.attributes).forEach((key) => { | ||
const value = this.attributes[key].value(this.domNode); | ||
target.format(key, value); | ||
}); | ||
} | ||
move(t) { | ||
this.copy(t), Object.keys(this.attributes).forEach((e) => { | ||
this.attributes[e].remove(this.domNode); | ||
move(target) { | ||
this.copy(target), Object.keys(this.attributes).forEach((key) => { | ||
this.attributes[key].remove(this.domNode); | ||
}), this.attributes = {}; | ||
@@ -156,3 +158,3 @@ } | ||
return Object.keys(this.attributes).reduce( | ||
(t, e) => (t[e] = this.attributes[e].value(this.domNode), t), | ||
(attributes, name) => (attributes[name] = this.attributes[name].value(this.domNode), attributes), | ||
{} | ||
@@ -162,11 +164,11 @@ ); | ||
} | ||
const k = class k { | ||
constructor(t, e) { | ||
this.scroll = t, this.domNode = e, y.blots.set(e, this), this.prev = null, this.next = null; | ||
const AttributorStore$1 = AttributorStore, _ShadowBlot = class _ShadowBlot { | ||
constructor(scroll, domNode) { | ||
this.scroll = scroll, this.domNode = domNode, Registry.blots.set(domNode, this), this.prev = null, this.next = null; | ||
} | ||
static create(t) { | ||
static create(rawValue) { | ||
if (this.tagName == null) | ||
throw new N("Blot definition missing tagName"); | ||
let e, s; | ||
return Array.isArray(this.tagName) ? (typeof t == "string" ? (s = t.toUpperCase(), parseInt(s, 10).toString() === s && (s = parseInt(s, 10))) : typeof t == "number" && (s = t), typeof s == "number" ? e = document.createElement(this.tagName[s - 1]) : s && this.tagName.indexOf(s) > -1 ? e = document.createElement(s) : e = document.createElement(this.tagName[0])) : e = document.createElement(this.tagName), this.className && e.classList.add(this.className), e; | ||
throw new ParchmentError("Blot definition missing tagName"); | ||
let node, value; | ||
return Array.isArray(this.tagName) ? (typeof rawValue == "string" ? (value = rawValue.toUpperCase(), parseInt(value, 10).toString() === value && (value = parseInt(value, 10))) : typeof rawValue == "number" && (value = rawValue), typeof value == "number" ? node = document.createElement(this.tagName[value - 1]) : value && this.tagName.indexOf(value) > -1 ? node = document.createElement(value) : node = document.createElement(this.tagName[0])) : node = document.createElement(this.tagName), this.className && node.classList.add(this.className), node; | ||
} | ||
@@ -180,29 +182,29 @@ // Hack for accessing inherited static methods | ||
clone() { | ||
const t = this.domNode.cloneNode(!1); | ||
return this.scroll.create(t); | ||
const domNode = this.domNode.cloneNode(!1); | ||
return this.scroll.create(domNode); | ||
} | ||
detach() { | ||
this.parent != null && this.parent.removeChild(this), y.blots.delete(this.domNode); | ||
this.parent != null && this.parent.removeChild(this), Registry.blots.delete(this.domNode); | ||
} | ||
deleteAt(t, e) { | ||
this.isolate(t, e).remove(); | ||
deleteAt(index, length) { | ||
this.isolate(index, length).remove(); | ||
} | ||
formatAt(t, e, s, r) { | ||
const i = this.isolate(t, e); | ||
if (this.scroll.query(s, l.BLOT) != null && r) | ||
i.wrap(s, r); | ||
else if (this.scroll.query(s, l.ATTRIBUTE) != null) { | ||
const h = this.scroll.create(this.statics.scope); | ||
i.wrap(h), h.format(s, r); | ||
formatAt(index, length, name, value) { | ||
const blot = this.isolate(index, length); | ||
if (this.scroll.query(name, Scope.BLOT) != null && value) | ||
blot.wrap(name, value); | ||
else if (this.scroll.query(name, Scope.ATTRIBUTE) != null) { | ||
const parent = this.scroll.create(this.statics.scope); | ||
blot.wrap(parent), parent.format(name, value); | ||
} | ||
} | ||
insertAt(t, e, s) { | ||
const r = s == null ? this.scroll.create("text", e) : this.scroll.create(e, s), i = this.split(t); | ||
this.parent.insertBefore(r, i || void 0); | ||
insertAt(index, value, def) { | ||
const blot = def == null ? this.scroll.create("text", value) : this.scroll.create(value, def), ref = this.split(index); | ||
this.parent.insertBefore(blot, ref || void 0); | ||
} | ||
isolate(t, e) { | ||
const s = this.split(t); | ||
if (s == null) | ||
isolate(index, length) { | ||
const target = this.split(index); | ||
if (target == null) | ||
throw new Error("Attempt to isolate at end"); | ||
return s.split(e), s; | ||
return target.split(length), target; | ||
} | ||
@@ -212,6 +214,6 @@ length() { | ||
} | ||
offset(t = this.parent) { | ||
return this.parent == null || this === t ? 0 : this.parent.children.offset(this) + this.parent.offset(t); | ||
offset(root = this.parent) { | ||
return this.parent == null || this === root ? 0 : this.parent.children.offset(this) + this.parent.offset(root); | ||
} | ||
optimize(t) { | ||
optimize(_context) { | ||
this.statics.requiredContainer && !(this.parent instanceof this.statics.requiredContainer) && this.wrap(this.statics.requiredContainer.blotName); | ||
@@ -222,31 +224,49 @@ } | ||
} | ||
replaceWith(t, e) { | ||
const s = typeof t == "string" ? this.scroll.create(t, e) : t; | ||
return this.parent != null && (this.parent.insertBefore(s, this.next || void 0), this.remove()), s; | ||
replaceWith(name, value) { | ||
const replacement = typeof name == "string" ? this.scroll.create(name, value) : name; | ||
return this.parent != null && (this.parent.insertBefore(replacement, this.next || void 0), this.remove()), replacement; | ||
} | ||
split(t, e) { | ||
return t === 0 ? this : this.next; | ||
split(index, _force) { | ||
return index === 0 ? this : this.next; | ||
} | ||
update(t, e) { | ||
update(_mutations, _context) { | ||
} | ||
wrap(t, e) { | ||
const s = typeof t == "string" ? this.scroll.create(t, e) : t; | ||
if (this.parent != null && this.parent.insertBefore(s, this.next || void 0), typeof s.appendChild != "function") | ||
throw new N(`Cannot wrap ${t}`); | ||
return s.appendChild(this), s; | ||
wrap(name, value) { | ||
const wrapper = typeof name == "string" ? this.scroll.create(name, value) : name; | ||
if (this.parent != null && this.parent.insertBefore(wrapper, this.next || void 0), typeof wrapper.appendChild != "function") | ||
throw new ParchmentError(`Cannot wrap ${name}`); | ||
return wrapper.appendChild(this), wrapper; | ||
} | ||
}; | ||
k.blotName = "abstract"; | ||
let C = k; | ||
const B = class B extends C { | ||
static value(t) { | ||
_ShadowBlot.blotName = "abstract"; | ||
let ShadowBlot = _ShadowBlot; | ||
const _LeafBlot = class _LeafBlot extends ShadowBlot { | ||
/** | ||
* Returns the value represented by domNode if it is this Blot's type | ||
* No checking that domNode can represent this Blot type is required so | ||
* applications needing it should check externally before calling. | ||
*/ | ||
static value(_domNode) { | ||
return !0; | ||
} | ||
index(t, e) { | ||
return this.domNode === t || this.domNode.compareDocumentPosition(t) & Node.DOCUMENT_POSITION_CONTAINED_BY ? Math.min(e, 1) : -1; | ||
/** | ||
* Given location represented by node and offset from DOM Selection Range, | ||
* return index to that location. | ||
*/ | ||
index(node, offset) { | ||
return this.domNode === node || this.domNode.compareDocumentPosition(node) & Node.DOCUMENT_POSITION_CONTAINED_BY ? Math.min(offset, 1) : -1; | ||
} | ||
position(t, e) { | ||
let r = Array.from(this.parent.domNode.childNodes).indexOf(this.domNode); | ||
return t > 0 && (r += 1), [this.parent.domNode, r]; | ||
/** | ||
* Given index to location within blot, return node and offset representing | ||
* that location, consumable by DOM Selection Range | ||
*/ | ||
position(index, _inclusive) { | ||
let offset = Array.from(this.parent.domNode.childNodes).indexOf(this.domNode); | ||
return index > 0 && (offset += 1), [this.parent.domNode, offset]; | ||
} | ||
/** | ||
* Return value represented by this blot | ||
* Should not change without interaction from API or | ||
* user change detectable by update() | ||
*/ | ||
value() { | ||
@@ -258,246 +278,250 @@ return { | ||
}; | ||
B.scope = l.INLINE_BLOT; | ||
let A = B; | ||
class q { | ||
_LeafBlot.scope = Scope.INLINE_BLOT; | ||
let LeafBlot = _LeafBlot; | ||
const LeafBlot$1 = LeafBlot; | ||
class LinkedList { | ||
constructor() { | ||
this.head = null, this.tail = null, this.length = 0; | ||
} | ||
append(...t) { | ||
if (this.insertBefore(t[0], null), t.length > 1) { | ||
const e = t.slice(1); | ||
this.append(...e); | ||
append(...nodes) { | ||
if (this.insertBefore(nodes[0], null), nodes.length > 1) { | ||
const rest = nodes.slice(1); | ||
this.append(...rest); | ||
} | ||
} | ||
at(t) { | ||
const e = this.iterator(); | ||
let s = e(); | ||
for (; s && t > 0; ) | ||
t -= 1, s = e(); | ||
return s; | ||
at(index) { | ||
const next = this.iterator(); | ||
let cur = next(); | ||
for (; cur && index > 0; ) | ||
index -= 1, cur = next(); | ||
return cur; | ||
} | ||
contains(t) { | ||
const e = this.iterator(); | ||
let s = e(); | ||
for (; s; ) { | ||
if (s === t) | ||
contains(node) { | ||
const next = this.iterator(); | ||
let cur = next(); | ||
for (; cur; ) { | ||
if (cur === node) | ||
return !0; | ||
s = e(); | ||
cur = next(); | ||
} | ||
return !1; | ||
} | ||
indexOf(t) { | ||
const e = this.iterator(); | ||
let s = e(), r = 0; | ||
for (; s; ) { | ||
if (s === t) | ||
return r; | ||
r += 1, s = e(); | ||
indexOf(node) { | ||
const next = this.iterator(); | ||
let cur = next(), index = 0; | ||
for (; cur; ) { | ||
if (cur === node) | ||
return index; | ||
index += 1, cur = next(); | ||
} | ||
return -1; | ||
} | ||
insertBefore(t, e) { | ||
t != null && (this.remove(t), t.next = e, e != null ? (t.prev = e.prev, e.prev != null && (e.prev.next = t), e.prev = t, e === this.head && (this.head = t)) : this.tail != null ? (this.tail.next = t, t.prev = this.tail, this.tail = t) : (t.prev = null, this.head = this.tail = t), this.length += 1); | ||
insertBefore(node, refNode) { | ||
node != null && (this.remove(node), node.next = refNode, refNode != null ? (node.prev = refNode.prev, refNode.prev != null && (refNode.prev.next = node), refNode.prev = node, refNode === this.head && (this.head = node)) : this.tail != null ? (this.tail.next = node, node.prev = this.tail, this.tail = node) : (node.prev = null, this.head = this.tail = node), this.length += 1); | ||
} | ||
offset(t) { | ||
let e = 0, s = this.head; | ||
for (; s != null; ) { | ||
if (s === t) | ||
return e; | ||
e += s.length(), s = s.next; | ||
offset(target) { | ||
let index = 0, cur = this.head; | ||
for (; cur != null; ) { | ||
if (cur === target) | ||
return index; | ||
index += cur.length(), cur = cur.next; | ||
} | ||
return -1; | ||
} | ||
remove(t) { | ||
this.contains(t) && (t.prev != null && (t.prev.next = t.next), t.next != null && (t.next.prev = t.prev), t === this.head && (this.head = t.next), t === this.tail && (this.tail = t.prev), this.length -= 1); | ||
remove(node) { | ||
this.contains(node) && (node.prev != null && (node.prev.next = node.next), node.next != null && (node.next.prev = node.prev), node === this.head && (this.head = node.next), node === this.tail && (this.tail = node.prev), this.length -= 1); | ||
} | ||
iterator(t = this.head) { | ||
iterator(curNode = this.head) { | ||
return () => { | ||
const e = t; | ||
return t != null && (t = t.next), e; | ||
const ret = curNode; | ||
return curNode != null && (curNode = curNode.next), ret; | ||
}; | ||
} | ||
find(t, e = !1) { | ||
const s = this.iterator(); | ||
let r = s(); | ||
for (; r; ) { | ||
const i = r.length(); | ||
if (t < i || e && t === i && (r.next == null || r.next.length() !== 0)) | ||
return [r, t]; | ||
t -= i, r = s(); | ||
find(index, inclusive = !1) { | ||
const next = this.iterator(); | ||
let cur = next(); | ||
for (; cur; ) { | ||
const length = cur.length(); | ||
if (index < length || inclusive && index === length && (cur.next == null || cur.next.length() !== 0)) | ||
return [cur, index]; | ||
index -= length, cur = next(); | ||
} | ||
return [null, 0]; | ||
} | ||
forEach(t) { | ||
const e = this.iterator(); | ||
let s = e(); | ||
for (; s; ) | ||
t(s), s = e(); | ||
forEach(callback) { | ||
const next = this.iterator(); | ||
let cur = next(); | ||
for (; cur; ) | ||
callback(cur), cur = next(); | ||
} | ||
forEachAt(t, e, s) { | ||
if (e <= 0) | ||
forEachAt(index, length, callback) { | ||
if (length <= 0) | ||
return; | ||
const [r, i] = this.find(t); | ||
let h = t - i; | ||
const n = this.iterator(r); | ||
let o = n(); | ||
for (; o && h < t + e; ) { | ||
const c = o.length(); | ||
t > h ? s( | ||
o, | ||
t - h, | ||
Math.min(e, h + c - t) | ||
) : s(o, 0, Math.min(c, t + e - h)), h += c, o = n(); | ||
const [startNode, offset] = this.find(index); | ||
let curIndex = index - offset; | ||
const next = this.iterator(startNode); | ||
let cur = next(); | ||
for (; cur && curIndex < index + length; ) { | ||
const curLength = cur.length(); | ||
index > curIndex ? callback( | ||
cur, | ||
index - curIndex, | ||
Math.min(length, curIndex + curLength - index) | ||
) : callback(cur, 0, Math.min(curLength, index + length - curIndex)), curIndex += curLength, cur = next(); | ||
} | ||
} | ||
map(t) { | ||
return this.reduce((e, s) => (e.push(t(s)), e), []); | ||
map(callback) { | ||
return this.reduce((memo, cur) => (memo.push(callback(cur)), memo), []); | ||
} | ||
reduce(t, e) { | ||
const s = this.iterator(); | ||
let r = s(); | ||
for (; r; ) | ||
e = t(e, r), r = s(); | ||
return e; | ||
reduce(callback, memo) { | ||
const next = this.iterator(); | ||
let cur = next(); | ||
for (; cur; ) | ||
memo = callback(memo, cur), cur = next(); | ||
return memo; | ||
} | ||
} | ||
function U(a, t) { | ||
const e = t.find(a); | ||
if (e) | ||
return e; | ||
function makeAttachedBlot(node, scroll) { | ||
const found = scroll.find(node); | ||
if (found) | ||
return found; | ||
try { | ||
return t.create(a); | ||
return scroll.create(node); | ||
} catch { | ||
const r = t.create(l.INLINE); | ||
return Array.from(a.childNodes).forEach((i) => { | ||
r.domNode.appendChild(i); | ||
}), a.parentNode && a.parentNode.replaceChild(r.domNode, a), r.attach(), r; | ||
const blot = scroll.create(Scope.INLINE); | ||
return Array.from(node.childNodes).forEach((child) => { | ||
blot.domNode.appendChild(child); | ||
}), node.parentNode && node.parentNode.replaceChild(blot.domNode, node), blot.attach(), blot; | ||
} | ||
} | ||
const f = class f extends C { | ||
constructor(t, e) { | ||
super(t, e), this.uiNode = null, this.build(); | ||
const _ParentBlot = class _ParentBlot extends ShadowBlot { | ||
constructor(scroll, domNode) { | ||
super(scroll, domNode), this.uiNode = null, this.build(); | ||
} | ||
appendChild(t) { | ||
this.insertBefore(t); | ||
appendChild(other) { | ||
this.insertBefore(other); | ||
} | ||
attach() { | ||
super.attach(), this.children.forEach((t) => { | ||
t.attach(); | ||
super.attach(), this.children.forEach((child) => { | ||
child.attach(); | ||
}); | ||
} | ||
attachUI(t) { | ||
this.uiNode != null && this.uiNode.remove(), this.uiNode = t, f.uiClass && this.uiNode.classList.add(f.uiClass), this.uiNode.setAttribute("contenteditable", "false"), this.domNode.insertBefore(this.uiNode, this.domNode.firstChild); | ||
attachUI(node) { | ||
this.uiNode != null && this.uiNode.remove(), this.uiNode = node, _ParentBlot.uiClass && this.uiNode.classList.add(_ParentBlot.uiClass), this.uiNode.setAttribute("contenteditable", "false"), this.domNode.insertBefore(this.uiNode, this.domNode.firstChild); | ||
} | ||
/** | ||
* Called during construction, should fill its own children LinkedList. | ||
*/ | ||
build() { | ||
this.children = new q(), Array.from(this.domNode.childNodes).filter((t) => t !== this.uiNode).reverse().forEach((t) => { | ||
this.children = new LinkedList(), Array.from(this.domNode.childNodes).filter((node) => node !== this.uiNode).reverse().forEach((node) => { | ||
try { | ||
const e = U(t, this.scroll); | ||
this.insertBefore(e, this.children.head || void 0); | ||
} catch (e) { | ||
if (e instanceof N) | ||
const child = makeAttachedBlot(node, this.scroll); | ||
this.insertBefore(child, this.children.head || void 0); | ||
} catch (err) { | ||
if (err instanceof ParchmentError) | ||
return; | ||
throw e; | ||
throw err; | ||
} | ||
}); | ||
} | ||
deleteAt(t, e) { | ||
if (t === 0 && e === this.length()) | ||
deleteAt(index, length) { | ||
if (index === 0 && length === this.length()) | ||
return this.remove(); | ||
this.children.forEachAt(t, e, (s, r, i) => { | ||
s.deleteAt(r, i); | ||
this.children.forEachAt(index, length, (child, offset, childLength) => { | ||
child.deleteAt(offset, childLength); | ||
}); | ||
} | ||
descendant(t, e = 0) { | ||
const [s, r] = this.children.find(e); | ||
return t.blotName == null && t(s) || t.blotName != null && s instanceof t ? [s, r] : s instanceof f ? s.descendant(t, r) : [null, -1]; | ||
descendant(criteria, index = 0) { | ||
const [child, offset] = this.children.find(index); | ||
return criteria.blotName == null && criteria(child) || criteria.blotName != null && child instanceof criteria ? [child, offset] : child instanceof _ParentBlot ? child.descendant(criteria, offset) : [null, -1]; | ||
} | ||
descendants(t, e = 0, s = Number.MAX_VALUE) { | ||
let r = [], i = s; | ||
descendants(criteria, index = 0, length = Number.MAX_VALUE) { | ||
let descendants = [], lengthLeft = length; | ||
return this.children.forEachAt( | ||
e, | ||
s, | ||
(h, n, o) => { | ||
(t.blotName == null && t(h) || t.blotName != null && h instanceof t) && r.push(h), h instanceof f && (r = r.concat( | ||
h.descendants(t, n, i) | ||
)), i -= o; | ||
index, | ||
length, | ||
(child, childIndex, childLength) => { | ||
(criteria.blotName == null && criteria(child) || criteria.blotName != null && child instanceof criteria) && descendants.push(child), child instanceof _ParentBlot && (descendants = descendants.concat( | ||
child.descendants(criteria, childIndex, lengthLeft) | ||
)), lengthLeft -= childLength; | ||
} | ||
), r; | ||
), descendants; | ||
} | ||
detach() { | ||
this.children.forEach((t) => { | ||
t.detach(); | ||
this.children.forEach((child) => { | ||
child.detach(); | ||
}), super.detach(); | ||
} | ||
enforceAllowedChildren() { | ||
let t = !1; | ||
this.children.forEach((e) => { | ||
t || this.statics.allowedChildren.some( | ||
(r) => e instanceof r | ||
) || (e.statics.scope === l.BLOCK_BLOT ? (e.next != null && this.splitAfter(e), e.prev != null && this.splitAfter(e.prev), e.parent.unwrap(), t = !0) : e instanceof f ? e.unwrap() : e.remove()); | ||
let done = !1; | ||
this.children.forEach((child) => { | ||
done || this.statics.allowedChildren.some( | ||
(def) => child instanceof def | ||
) || (child.statics.scope === Scope.BLOCK_BLOT ? (child.next != null && this.splitAfter(child), child.prev != null && this.splitAfter(child.prev), child.parent.unwrap(), done = !0) : child instanceof _ParentBlot ? child.unwrap() : child.remove()); | ||
}); | ||
} | ||
formatAt(t, e, s, r) { | ||
this.children.forEachAt(t, e, (i, h, n) => { | ||
i.formatAt(h, n, s, r); | ||
formatAt(index, length, name, value) { | ||
this.children.forEachAt(index, length, (child, offset, childLength) => { | ||
child.formatAt(offset, childLength, name, value); | ||
}); | ||
} | ||
insertAt(t, e, s) { | ||
const [r, i] = this.children.find(t); | ||
if (r) | ||
r.insertAt(i, e, s); | ||
insertAt(index, value, def) { | ||
const [child, offset] = this.children.find(index); | ||
if (child) | ||
child.insertAt(offset, value, def); | ||
else { | ||
const h = s == null ? this.scroll.create("text", e) : this.scroll.create(e, s); | ||
this.appendChild(h); | ||
const blot = def == null ? this.scroll.create("text", value) : this.scroll.create(value, def); | ||
this.appendChild(blot); | ||
} | ||
} | ||
insertBefore(t, e) { | ||
t.parent != null && t.parent.children.remove(t); | ||
let s = null; | ||
this.children.insertBefore(t, e || null), t.parent = this, e != null && (s = e.domNode), (this.domNode.parentNode !== t.domNode || this.domNode.nextSibling !== s) && this.domNode.insertBefore(t.domNode, s), t.attach(); | ||
insertBefore(childBlot, refBlot) { | ||
childBlot.parent != null && childBlot.parent.children.remove(childBlot); | ||
let refDomNode = null; | ||
this.children.insertBefore(childBlot, refBlot || null), childBlot.parent = this, refBlot != null && (refDomNode = refBlot.domNode), (this.domNode.parentNode !== childBlot.domNode || this.domNode.nextSibling !== refDomNode) && this.domNode.insertBefore(childBlot.domNode, refDomNode), childBlot.attach(); | ||
} | ||
length() { | ||
return this.children.reduce((t, e) => t + e.length(), 0); | ||
return this.children.reduce((memo, child) => memo + child.length(), 0); | ||
} | ||
moveChildren(t, e) { | ||
this.children.forEach((s) => { | ||
t.insertBefore(s, e); | ||
moveChildren(targetParent, refNode) { | ||
this.children.forEach((child) => { | ||
targetParent.insertBefore(child, refNode); | ||
}); | ||
} | ||
optimize(t) { | ||
if (super.optimize(t), this.enforceAllowedChildren(), this.uiNode != null && this.uiNode !== this.domNode.firstChild && this.domNode.insertBefore(this.uiNode, this.domNode.firstChild), this.children.length === 0) | ||
optimize(context) { | ||
if (super.optimize(context), this.enforceAllowedChildren(), this.uiNode != null && this.uiNode !== this.domNode.firstChild && this.domNode.insertBefore(this.uiNode, this.domNode.firstChild), this.children.length === 0) | ||
if (this.statics.defaultChild != null) { | ||
const e = this.scroll.create(this.statics.defaultChild.blotName); | ||
this.appendChild(e); | ||
const child = this.scroll.create(this.statics.defaultChild.blotName); | ||
this.appendChild(child); | ||
} else | ||
this.remove(); | ||
} | ||
path(t, e = !1) { | ||
const [s, r] = this.children.find(t, e), i = [[this, t]]; | ||
return s instanceof f ? i.concat(s.path(r, e)) : (s != null && i.push([s, r]), i); | ||
path(index, inclusive = !1) { | ||
const [child, offset] = this.children.find(index, inclusive), position = [[this, index]]; | ||
return child instanceof _ParentBlot ? position.concat(child.path(offset, inclusive)) : (child != null && position.push([child, offset]), position); | ||
} | ||
removeChild(t) { | ||
this.children.remove(t); | ||
removeChild(child) { | ||
this.children.remove(child); | ||
} | ||
replaceWith(t, e) { | ||
const s = typeof t == "string" ? this.scroll.create(t, e) : t; | ||
return s instanceof f && this.moveChildren(s), super.replaceWith(s); | ||
replaceWith(name, value) { | ||
const replacement = typeof name == "string" ? this.scroll.create(name, value) : name; | ||
return replacement instanceof _ParentBlot && this.moveChildren(replacement), super.replaceWith(replacement); | ||
} | ||
split(t, e = !1) { | ||
if (!e) { | ||
if (t === 0) | ||
split(index, force = !1) { | ||
if (!force) { | ||
if (index === 0) | ||
return this; | ||
if (t === this.length()) | ||
if (index === this.length()) | ||
return this.next; | ||
} | ||
const s = this.clone(); | ||
return this.parent && this.parent.insertBefore(s, this.next || void 0), this.children.forEachAt(t, this.length(), (r, i, h) => { | ||
const n = r.split(i, e); | ||
n != null && s.appendChild(n); | ||
}), s; | ||
const after = this.clone(); | ||
return this.parent && this.parent.insertBefore(after, this.next || void 0), this.children.forEachAt(index, this.length(), (child, offset, _length) => { | ||
const split = child.split(offset, force); | ||
split != null && after.appendChild(split); | ||
}), after; | ||
} | ||
splitAfter(t) { | ||
const e = this.clone(); | ||
for (; t.next != null; ) | ||
e.appendChild(t.next); | ||
return this.parent && this.parent.insertBefore(e, this.next || void 0), e; | ||
splitAfter(child) { | ||
const after = this.clone(); | ||
for (; child.next != null; ) | ||
after.appendChild(child.next); | ||
return this.parent && this.parent.insertBefore(after, this.next || void 0), after; | ||
} | ||
@@ -507,124 +531,125 @@ unwrap() { | ||
} | ||
update(t, e) { | ||
const s = [], r = []; | ||
t.forEach((i) => { | ||
i.target === this.domNode && i.type === "childList" && (s.push(...i.addedNodes), r.push(...i.removedNodes)); | ||
}), r.forEach((i) => { | ||
if (i.parentNode != null && // @ts-expect-error Fix me later | ||
i.tagName !== "IFRAME" && document.body.compareDocumentPosition(i) & Node.DOCUMENT_POSITION_CONTAINED_BY) | ||
update(mutations, _context) { | ||
const addedNodes = [], removedNodes = []; | ||
mutations.forEach((mutation) => { | ||
mutation.target === this.domNode && mutation.type === "childList" && (addedNodes.push(...mutation.addedNodes), removedNodes.push(...mutation.removedNodes)); | ||
}), removedNodes.forEach((node) => { | ||
if (node.parentNode != null && // @ts-expect-error Fix me later | ||
node.tagName !== "IFRAME" && document.body.compareDocumentPosition(node) & Node.DOCUMENT_POSITION_CONTAINED_BY) | ||
return; | ||
const h = this.scroll.find(i); | ||
h != null && (h.domNode.parentNode == null || h.domNode.parentNode === this.domNode) && h.detach(); | ||
}), s.filter((i) => i.parentNode === this.domNode && i !== this.uiNode).sort((i, h) => i === h ? 0 : i.compareDocumentPosition(h) & Node.DOCUMENT_POSITION_FOLLOWING ? 1 : -1).forEach((i) => { | ||
let h = null; | ||
i.nextSibling != null && (h = this.scroll.find(i.nextSibling)); | ||
const n = U(i, this.scroll); | ||
(n.next !== h || n.next == null) && (n.parent != null && n.parent.removeChild(this), this.insertBefore(n, h || void 0)); | ||
const blot = this.scroll.find(node); | ||
blot != null && (blot.domNode.parentNode == null || blot.domNode.parentNode === this.domNode) && blot.detach(); | ||
}), addedNodes.filter((node) => node.parentNode === this.domNode && node !== this.uiNode).sort((a, b) => a === b ? 0 : a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING ? 1 : -1).forEach((node) => { | ||
let refBlot = null; | ||
node.nextSibling != null && (refBlot = this.scroll.find(node.nextSibling)); | ||
const blot = makeAttachedBlot(node, this.scroll); | ||
(blot.next !== refBlot || blot.next == null) && (blot.parent != null && blot.parent.removeChild(this), this.insertBefore(blot, refBlot || void 0)); | ||
}), this.enforceAllowedChildren(); | ||
} | ||
}; | ||
f.uiClass = ""; | ||
let m = f; | ||
function V(a, t) { | ||
if (Object.keys(a).length !== Object.keys(t).length) | ||
_ParentBlot.uiClass = ""; | ||
let ParentBlot = _ParentBlot; | ||
const ParentBlot$1 = ParentBlot; | ||
function isEqual(obj1, obj2) { | ||
if (Object.keys(obj1).length !== Object.keys(obj2).length) | ||
return !1; | ||
for (const e in a) | ||
if (a[e] !== t[e]) | ||
for (const prop in obj1) | ||
if (obj1[prop] !== obj2[prop]) | ||
return !1; | ||
return !0; | ||
} | ||
const u = class u extends m { | ||
constructor(t, e) { | ||
super(t, e), this.attributes = new D(this.domNode); | ||
const _InlineBlot = class _InlineBlot extends ParentBlot$1 { | ||
static create(value) { | ||
return super.create(value); | ||
} | ||
static create(t) { | ||
return super.create(t); | ||
} | ||
static formats(t, e) { | ||
const s = e.query(u.blotName); | ||
if (!(s != null && t.tagName === s.tagName)) { | ||
static formats(domNode, scroll) { | ||
const match2 = scroll.query(_InlineBlot.blotName); | ||
if (!(match2 != null && domNode.tagName === match2.tagName)) { | ||
if (typeof this.tagName == "string") | ||
return !0; | ||
if (Array.isArray(this.tagName)) | ||
return t.tagName.toLowerCase(); | ||
return domNode.tagName.toLowerCase(); | ||
} | ||
} | ||
format(t, e) { | ||
if (t === this.statics.blotName && !e) | ||
this.children.forEach((s) => { | ||
s instanceof u || (s = s.wrap(u.blotName, !0)), this.attributes.copy(s); | ||
constructor(scroll, domNode) { | ||
super(scroll, domNode), this.attributes = new AttributorStore$1(this.domNode); | ||
} | ||
format(name, value) { | ||
if (name === this.statics.blotName && !value) | ||
this.children.forEach((child) => { | ||
child instanceof _InlineBlot || (child = child.wrap(_InlineBlot.blotName, !0)), this.attributes.copy(child); | ||
}), this.unwrap(); | ||
else { | ||
const s = this.scroll.query(t, l.INLINE); | ||
if (s == null) | ||
const format = this.scroll.query(name, Scope.INLINE); | ||
if (format == null) | ||
return; | ||
s instanceof b ? this.attributes.attribute(s, e) : e && (t !== this.statics.blotName || this.formats()[t] !== e) && this.replaceWith(t, e); | ||
format instanceof Attributor ? this.attributes.attribute(format, value) : value && (name !== this.statics.blotName || this.formats()[name] !== value) && this.replaceWith(name, value); | ||
} | ||
} | ||
formats() { | ||
const t = this.attributes.values(), e = this.statics.formats(this.domNode, this.scroll); | ||
return e != null && (t[this.statics.blotName] = e), t; | ||
const formats = this.attributes.values(), format = this.statics.formats(this.domNode, this.scroll); | ||
return format != null && (formats[this.statics.blotName] = format), formats; | ||
} | ||
formatAt(t, e, s, r) { | ||
this.formats()[s] != null || this.scroll.query(s, l.ATTRIBUTE) ? this.isolate(t, e).format(s, r) : super.formatAt(t, e, s, r); | ||
formatAt(index, length, name, value) { | ||
this.formats()[name] != null || this.scroll.query(name, Scope.ATTRIBUTE) ? this.isolate(index, length).format(name, value) : super.formatAt(index, length, name, value); | ||
} | ||
optimize(t) { | ||
super.optimize(t); | ||
const e = this.formats(); | ||
if (Object.keys(e).length === 0) | ||
optimize(context) { | ||
super.optimize(context); | ||
const formats = this.formats(); | ||
if (Object.keys(formats).length === 0) | ||
return this.unwrap(); | ||
const s = this.next; | ||
s instanceof u && s.prev === this && V(e, s.formats()) && (s.moveChildren(this), s.remove()); | ||
const next = this.next; | ||
next instanceof _InlineBlot && next.prev === this && isEqual(formats, next.formats()) && (next.moveChildren(this), next.remove()); | ||
} | ||
replaceWith(t, e) { | ||
const s = super.replaceWith(t, e); | ||
return this.attributes.copy(s), s; | ||
replaceWith(name, value) { | ||
const replacement = super.replaceWith(name, value); | ||
return this.attributes.copy(replacement), replacement; | ||
} | ||
update(t, e) { | ||
super.update(t, e), t.some( | ||
(r) => r.target === this.domNode && r.type === "attributes" | ||
update(mutations, context) { | ||
super.update(mutations, context), mutations.some( | ||
(mutation) => mutation.target === this.domNode && mutation.type === "attributes" | ||
) && this.attributes.build(); | ||
} | ||
wrap(t, e) { | ||
const s = super.wrap(t, e); | ||
return s instanceof u && this.attributes.move(s), s; | ||
wrap(name, value) { | ||
const wrapper = super.wrap(name, value); | ||
return wrapper instanceof _InlineBlot && this.attributes.move(wrapper), wrapper; | ||
} | ||
}; | ||
u.allowedChildren = [u, A], u.blotName = "inline", u.scope = l.INLINE_BLOT, u.tagName = "SPAN"; | ||
let O = u; | ||
const d = class d extends m { | ||
constructor(t, e) { | ||
super(t, e), this.attributes = new D(this.domNode); | ||
_InlineBlot.allowedChildren = [_InlineBlot, LeafBlot$1], _InlineBlot.blotName = "inline", _InlineBlot.scope = Scope.INLINE_BLOT, _InlineBlot.tagName = "SPAN"; | ||
let InlineBlot = _InlineBlot; | ||
const InlineBlot$1 = InlineBlot, _BlockBlot = class _BlockBlot extends ParentBlot$1 { | ||
static create(value) { | ||
return super.create(value); | ||
} | ||
static create(t) { | ||
return super.create(t); | ||
} | ||
static formats(t, e) { | ||
const s = e.query(d.blotName); | ||
if (!(s != null && t.tagName === s.tagName)) { | ||
static formats(domNode, scroll) { | ||
const match2 = scroll.query(_BlockBlot.blotName); | ||
if (!(match2 != null && domNode.tagName === match2.tagName)) { | ||
if (typeof this.tagName == "string") | ||
return !0; | ||
if (Array.isArray(this.tagName)) | ||
return t.tagName.toLowerCase(); | ||
return domNode.tagName.toLowerCase(); | ||
} | ||
} | ||
format(t, e) { | ||
const s = this.scroll.query(t, l.BLOCK); | ||
s != null && (s instanceof b ? this.attributes.attribute(s, e) : t === this.statics.blotName && !e ? this.replaceWith(d.blotName) : e && (t !== this.statics.blotName || this.formats()[t] !== e) && this.replaceWith(t, e)); | ||
constructor(scroll, domNode) { | ||
super(scroll, domNode), this.attributes = new AttributorStore$1(this.domNode); | ||
} | ||
format(name, value) { | ||
const format = this.scroll.query(name, Scope.BLOCK); | ||
format != null && (format instanceof Attributor ? this.attributes.attribute(format, value) : name === this.statics.blotName && !value ? this.replaceWith(_BlockBlot.blotName) : value && (name !== this.statics.blotName || this.formats()[name] !== value) && this.replaceWith(name, value)); | ||
} | ||
formats() { | ||
const t = this.attributes.values(), e = this.statics.formats(this.domNode, this.scroll); | ||
return e != null && (t[this.statics.blotName] = e), t; | ||
const formats = this.attributes.values(), format = this.statics.formats(this.domNode, this.scroll); | ||
return format != null && (formats[this.statics.blotName] = format), formats; | ||
} | ||
formatAt(t, e, s, r) { | ||
this.scroll.query(s, l.BLOCK) != null ? this.format(s, r) : super.formatAt(t, e, s, r); | ||
formatAt(index, length, name, value) { | ||
this.scroll.query(name, Scope.BLOCK) != null ? this.format(name, value) : super.formatAt(index, length, name, value); | ||
} | ||
insertAt(t, e, s) { | ||
if (s == null || this.scroll.query(e, l.INLINE) != null) | ||
super.insertAt(t, e, s); | ||
insertAt(index, value, def) { | ||
if (def == null || this.scroll.query(value, Scope.INLINE) != null) | ||
super.insertAt(index, value, def); | ||
else { | ||
const r = this.split(t); | ||
if (r != null) { | ||
const i = this.scroll.create(e, s); | ||
r.parent.insertBefore(i, r); | ||
const after = this.split(index); | ||
if (after != null) { | ||
const blot = this.scroll.create(value, def); | ||
after.parent.insertBefore(blot, after); | ||
} else | ||
@@ -634,45 +659,46 @@ throw new Error("Attempt to insertAt after block boundaries"); | ||
} | ||
replaceWith(t, e) { | ||
const s = super.replaceWith(t, e); | ||
return this.attributes.copy(s), s; | ||
replaceWith(name, value) { | ||
const replacement = super.replaceWith(name, value); | ||
return this.attributes.copy(replacement), replacement; | ||
} | ||
update(t, e) { | ||
super.update(t, e), t.some( | ||
(r) => r.target === this.domNode && r.type === "attributes" | ||
update(mutations, context) { | ||
super.update(mutations, context), mutations.some( | ||
(mutation) => mutation.target === this.domNode && mutation.type === "attributes" | ||
) && this.attributes.build(); | ||
} | ||
}; | ||
d.blotName = "block", d.scope = l.BLOCK_BLOT, d.tagName = "P", d.allowedChildren = [ | ||
O, | ||
d, | ||
A | ||
_BlockBlot.blotName = "block", _BlockBlot.scope = Scope.BLOCK_BLOT, _BlockBlot.tagName = "P", _BlockBlot.allowedChildren = [ | ||
InlineBlot$1, | ||
_BlockBlot, | ||
LeafBlot$1 | ||
]; | ||
let T = d; | ||
const L = class L extends m { | ||
let BlockBlot = _BlockBlot; | ||
const BlockBlot$1 = BlockBlot, _ContainerBlot = class _ContainerBlot extends ParentBlot$1 { | ||
checkMerge() { | ||
return this.next !== null && this.next.statics.blotName === this.statics.blotName; | ||
} | ||
deleteAt(t, e) { | ||
super.deleteAt(t, e), this.enforceAllowedChildren(); | ||
deleteAt(index, length) { | ||
super.deleteAt(index, length), this.enforceAllowedChildren(); | ||
} | ||
formatAt(t, e, s, r) { | ||
super.formatAt(t, e, s, r), this.enforceAllowedChildren(); | ||
formatAt(index, length, name, value) { | ||
super.formatAt(index, length, name, value), this.enforceAllowedChildren(); | ||
} | ||
insertAt(t, e, s) { | ||
super.insertAt(t, e, s), this.enforceAllowedChildren(); | ||
insertAt(index, value, def) { | ||
super.insertAt(index, value, def), this.enforceAllowedChildren(); | ||
} | ||
optimize(t) { | ||
super.optimize(t), this.children.length > 0 && this.next != null && this.checkMerge() && (this.next.moveChildren(this), this.next.remove()); | ||
optimize(context) { | ||
super.optimize(context), this.children.length > 0 && this.next != null && this.checkMerge() && (this.next.moveChildren(this), this.next.remove()); | ||
} | ||
}; | ||
L.blotName = "container", L.scope = l.BLOCK_BLOT; | ||
let I = L; | ||
class X extends A { | ||
static formats(t, e) { | ||
_ContainerBlot.blotName = "container", _ContainerBlot.scope = Scope.BLOCK_BLOT; | ||
let ContainerBlot = _ContainerBlot; | ||
const ContainerBlot$1 = ContainerBlot; | ||
class EmbedBlot extends LeafBlot$1 { | ||
static formats(_domNode, _scroll) { | ||
} | ||
format(t, e) { | ||
super.formatAt(0, this.length(), t, e); | ||
format(name, value) { | ||
super.formatAt(0, this.length(), name, value); | ||
} | ||
formatAt(t, e, s, r) { | ||
t === 0 && e === this.length() ? this.format(s, r) : super.formatAt(t, e, s, r); | ||
formatAt(index, length, name, value) { | ||
index === 0 && length === this.length() ? this.format(name, value) : super.formatAt(index, length, name, value); | ||
} | ||
@@ -683,3 +709,3 @@ formats() { | ||
} | ||
const j = { | ||
const EmbedBlot$1 = EmbedBlot, OBSERVER_CONFIG = { | ||
attributes: !0, | ||
@@ -690,20 +716,20 @@ characterData: !0, | ||
subtree: !0 | ||
}, $ = 100, p = class p extends m { | ||
constructor(t, e) { | ||
super(null, e), this.registry = t, this.scroll = this, this.build(), this.observer = new MutationObserver((s) => { | ||
this.update(s); | ||
}), this.observer.observe(this.domNode, j), this.attach(); | ||
}, MAX_OPTIMIZE_ITERATIONS = 100, _ScrollBlot = class _ScrollBlot extends ParentBlot$1 { | ||
constructor(registry, node) { | ||
super(null, node), this.registry = registry, this.scroll = this, this.build(), this.observer = new MutationObserver((mutations) => { | ||
this.update(mutations); | ||
}), this.observer.observe(this.domNode, OBSERVER_CONFIG), this.attach(); | ||
} | ||
create(t, e) { | ||
return this.registry.create(this, t, e); | ||
create(input, value) { | ||
return this.registry.create(this, input, value); | ||
} | ||
find(t, e = !1) { | ||
const s = this.registry.find(t, e); | ||
return s ? s.scroll === this ? s : e ? this.find(s.scroll.domNode.parentNode, !0) : null : null; | ||
find(node, bubble = !1) { | ||
const blot = this.registry.find(node, bubble); | ||
return blot ? blot.scroll === this ? blot : bubble ? this.find(blot.scroll.domNode.parentNode, !0) : null : null; | ||
} | ||
query(t, e = l.ANY) { | ||
return this.registry.query(t, e); | ||
query(query, scope = Scope.ANY) { | ||
return this.registry.query(query, scope); | ||
} | ||
register(...t) { | ||
return this.registry.register(...t); | ||
register(...definitions) { | ||
return this.registry.register(...definitions); | ||
} | ||
@@ -716,71 +742,71 @@ build() { | ||
} | ||
deleteAt(t, e) { | ||
this.update(), t === 0 && e === this.length() ? this.children.forEach((s) => { | ||
s.remove(); | ||
}) : super.deleteAt(t, e); | ||
deleteAt(index, length) { | ||
this.update(), index === 0 && length === this.length() ? this.children.forEach((child) => { | ||
child.remove(); | ||
}) : super.deleteAt(index, length); | ||
} | ||
formatAt(t, e, s, r) { | ||
this.update(), super.formatAt(t, e, s, r); | ||
formatAt(index, length, name, value) { | ||
this.update(), super.formatAt(index, length, name, value); | ||
} | ||
insertAt(t, e, s) { | ||
this.update(), super.insertAt(t, e, s); | ||
insertAt(index, value, def) { | ||
this.update(), super.insertAt(index, value, def); | ||
} | ||
optimize(t = [], e = {}) { | ||
super.optimize(e); | ||
const s = e.mutationsMap || /* @__PURE__ */ new WeakMap(); | ||
let r = Array.from(this.observer.takeRecords()); | ||
for (; r.length > 0; ) | ||
t.push(r.pop()); | ||
const i = (o, c = !0) => { | ||
o == null || o === this || o.domNode.parentNode != null && (s.has(o.domNode) || s.set(o.domNode, []), c && i(o.parent)); | ||
}, h = (o) => { | ||
s.has(o.domNode) && (o instanceof m && o.children.forEach(h), s.delete(o.domNode), o.optimize(e)); | ||
optimize(mutations = [], context = {}) { | ||
super.optimize(context); | ||
const mutationsMap = context.mutationsMap || /* @__PURE__ */ new WeakMap(); | ||
let records = Array.from(this.observer.takeRecords()); | ||
for (; records.length > 0; ) | ||
mutations.push(records.pop()); | ||
const mark = (blot, markParent = !0) => { | ||
blot == null || blot === this || blot.domNode.parentNode != null && (mutationsMap.has(blot.domNode) || mutationsMap.set(blot.domNode, []), markParent && mark(blot.parent)); | ||
}, optimize = (blot) => { | ||
mutationsMap.has(blot.domNode) && (blot instanceof ParentBlot$1 && blot.children.forEach(optimize), mutationsMap.delete(blot.domNode), blot.optimize(context)); | ||
}; | ||
let n = t; | ||
for (let o = 0; n.length > 0; o += 1) { | ||
if (o >= $) | ||
let remaining = mutations; | ||
for (let i = 0; remaining.length > 0; i += 1) { | ||
if (i >= MAX_OPTIMIZE_ITERATIONS) | ||
throw new Error("[Parchment] Maximum optimize iterations reached"); | ||
for (n.forEach((c) => { | ||
const v = this.find(c.target, !0); | ||
v != null && (v.domNode === c.target && (c.type === "childList" ? (i(this.find(c.previousSibling, !1)), Array.from(c.addedNodes).forEach((P) => { | ||
const w = this.find(P, !1); | ||
i(w, !1), w instanceof m && w.children.forEach((W) => { | ||
i(W, !1); | ||
for (remaining.forEach((mutation) => { | ||
const blot = this.find(mutation.target, !0); | ||
blot != null && (blot.domNode === mutation.target && (mutation.type === "childList" ? (mark(this.find(mutation.previousSibling, !1)), Array.from(mutation.addedNodes).forEach((node) => { | ||
const child = this.find(node, !1); | ||
mark(child, !1), child instanceof ParentBlot$1 && child.children.forEach((grandChild) => { | ||
mark(grandChild, !1); | ||
}); | ||
})) : c.type === "attributes" && i(v.prev)), i(v)); | ||
}), this.children.forEach(h), n = Array.from(this.observer.takeRecords()), r = n.slice(); r.length > 0; ) | ||
t.push(r.pop()); | ||
})) : mutation.type === "attributes" && mark(blot.prev)), mark(blot)); | ||
}), this.children.forEach(optimize), remaining = Array.from(this.observer.takeRecords()), records = remaining.slice(); records.length > 0; ) | ||
mutations.push(records.pop()); | ||
} | ||
} | ||
update(t, e = {}) { | ||
t = t || this.observer.takeRecords(); | ||
const s = /* @__PURE__ */ new WeakMap(); | ||
t.map((r) => { | ||
const i = this.find(r.target, !0); | ||
return i == null ? null : s.has(i.domNode) ? (s.get(i.domNode).push(r), null) : (s.set(i.domNode, [r]), i); | ||
}).forEach((r) => { | ||
r != null && r !== this && s.has(r.domNode) && r.update(s.get(r.domNode) || [], e); | ||
}), e.mutationsMap = s, s.has(this.domNode) && super.update(s.get(this.domNode), e), this.optimize(t, e); | ||
update(mutations, context = {}) { | ||
mutations = mutations || this.observer.takeRecords(); | ||
const mutationsMap = /* @__PURE__ */ new WeakMap(); | ||
mutations.map((mutation) => { | ||
const blot = this.find(mutation.target, !0); | ||
return blot == null ? null : mutationsMap.has(blot.domNode) ? (mutationsMap.get(blot.domNode).push(mutation), null) : (mutationsMap.set(blot.domNode, [mutation]), blot); | ||
}).forEach((blot) => { | ||
blot != null && blot !== this && mutationsMap.has(blot.domNode) && blot.update(mutationsMap.get(blot.domNode) || [], context); | ||
}), context.mutationsMap = mutationsMap, mutationsMap.has(this.domNode) && super.update(mutationsMap.get(this.domNode), context), this.optimize(mutations, context); | ||
} | ||
}; | ||
p.blotName = "scroll", p.defaultChild = T, p.allowedChildren = [T, I], p.scope = l.BLOCK_BLOT, p.tagName = "DIV"; | ||
let z = p; | ||
const E = class E extends A { | ||
constructor(t, e) { | ||
super(t, e), this.text = this.statics.value(this.domNode); | ||
_ScrollBlot.blotName = "scroll", _ScrollBlot.defaultChild = BlockBlot$1, _ScrollBlot.allowedChildren = [BlockBlot$1, ContainerBlot$1], _ScrollBlot.scope = Scope.BLOCK_BLOT, _ScrollBlot.tagName = "DIV"; | ||
let ScrollBlot = _ScrollBlot; | ||
const ScrollBlot$1 = ScrollBlot, _TextBlot = class _TextBlot extends LeafBlot$1 { | ||
static create(value) { | ||
return document.createTextNode(value); | ||
} | ||
static create(t) { | ||
return document.createTextNode(t); | ||
static value(domNode) { | ||
return domNode.data; | ||
} | ||
static value(t) { | ||
return t.data; | ||
constructor(scroll, node) { | ||
super(scroll, node), this.text = this.statics.value(this.domNode); | ||
} | ||
deleteAt(t, e) { | ||
this.domNode.data = this.text = this.text.slice(0, t) + this.text.slice(t + e); | ||
deleteAt(index, length) { | ||
this.domNode.data = this.text = this.text.slice(0, index) + this.text.slice(index + length); | ||
} | ||
index(t, e) { | ||
return this.domNode === t ? e : -1; | ||
index(node, offset) { | ||
return this.domNode === node ? offset : -1; | ||
} | ||
insertAt(t, e, s) { | ||
s == null ? (this.text = this.text.slice(0, t) + e + this.text.slice(t), this.domNode.data = this.text) : super.insertAt(t, e, s); | ||
insertAt(index, value, def) { | ||
def == null ? (this.text = this.text.slice(0, index) + value + this.text.slice(index), this.domNode.data = this.text) : super.insertAt(index, value, def); | ||
} | ||
@@ -790,20 +816,20 @@ length() { | ||
} | ||
optimize(t) { | ||
super.optimize(t), this.text = this.statics.value(this.domNode), this.text.length === 0 ? this.remove() : this.next instanceof E && this.next.prev === this && (this.insertAt(this.length(), this.next.value()), this.next.remove()); | ||
optimize(context) { | ||
super.optimize(context), this.text = this.statics.value(this.domNode), this.text.length === 0 ? this.remove() : this.next instanceof _TextBlot && this.next.prev === this && (this.insertAt(this.length(), this.next.value()), this.next.remove()); | ||
} | ||
position(t, e = !1) { | ||
return [this.domNode, t]; | ||
position(index, _inclusive = !1) { | ||
return [this.domNode, index]; | ||
} | ||
split(t, e = !1) { | ||
if (!e) { | ||
if (t === 0) | ||
split(index, force = !1) { | ||
if (!force) { | ||
if (index === 0) | ||
return this; | ||
if (t === this.length()) | ||
if (index === this.length()) | ||
return this.next; | ||
} | ||
const s = this.scroll.create(this.domNode.splitText(t)); | ||
return this.parent.insertBefore(s, this.next || void 0), this.text = this.statics.value(this.domNode), s; | ||
const after = this.scroll.create(this.domNode.splitText(index)); | ||
return this.parent.insertBefore(after, this.next || void 0), this.text = this.statics.value(this.domNode), after; | ||
} | ||
update(t, e) { | ||
t.some((s) => s.type === "characterData" && s.target === this.domNode) && (this.text = this.statics.value(this.domNode)); | ||
update(mutations, _context) { | ||
mutations.some((mutation) => mutation.type === "characterData" && mutation.target === this.domNode) && (this.text = this.statics.value(this.domNode)); | ||
} | ||
@@ -814,20 +840,21 @@ value() { | ||
}; | ||
E.blotName = "text", E.scope = l.INLINE_BLOT; | ||
let R = E; | ||
_TextBlot.blotName = "text", _TextBlot.scope = Scope.INLINE_BLOT; | ||
let TextBlot = _TextBlot; | ||
const TextBlot$1 = TextBlot; | ||
export { | ||
b as Attributor, | ||
D as AttributorStore, | ||
T as BlockBlot, | ||
K as ClassAttributor, | ||
I as ContainerBlot, | ||
X as EmbedBlot, | ||
O as InlineBlot, | ||
A as LeafBlot, | ||
m as ParentBlot, | ||
y as Registry, | ||
l as Scope, | ||
z as ScrollBlot, | ||
Y as StyleAttributor, | ||
R as TextBlot | ||
Attributor, | ||
AttributorStore$1 as AttributorStore, | ||
BlockBlot$1 as BlockBlot, | ||
ClassAttributor$1 as ClassAttributor, | ||
ContainerBlot$1 as ContainerBlot, | ||
EmbedBlot$1 as EmbedBlot, | ||
InlineBlot$1 as InlineBlot, | ||
LeafBlot$1 as LeafBlot, | ||
ParentBlot$1 as ParentBlot, | ||
Registry, | ||
Scope, | ||
ScrollBlot$1 as ScrollBlot, | ||
StyleAttributor$1 as StyleAttributor, | ||
TextBlot$1 as TextBlot | ||
}; | ||
//# sourceMappingURL=parchment.js.map |
{ | ||
"name": "parchment", | ||
"version": "0.0.0-experimental-c450721b1-20240312", | ||
"version": "0.0.0-experimental-cb3cbcb83-20240318", | ||
"description": "A document model for rich text editors", | ||
@@ -10,2 +10,3 @@ "author": "Jason Chen <jhchen7@gmail.com>", | ||
"type": "module", | ||
"sideEffects": false, | ||
"files": [ | ||
@@ -20,15 +21,16 @@ "tsconfig.json", | ||
"@types/node": "^18.15.11", | ||
"@typescript-eslint/eslint-plugin": "^6.2.0", | ||
"@typescript-eslint/parser": "^6.2.0", | ||
"@vitest/browser": "^0.33.0", | ||
"del-cli": "^5.0.0", | ||
"@typescript-eslint/eslint-plugin": "^7.2.0", | ||
"@typescript-eslint/parser": "^7.2.0", | ||
"@vitest/browser": "^1.4.0", | ||
"del-cli": "^5.1.0", | ||
"eslint": "^8.46.0", | ||
"eslint-config-prettier": "^8.9.0", | ||
"eslint-plugin-prettier": "^5.0.0", | ||
"eslint-config-prettier": "^9.1.0", | ||
"eslint-plugin-prettier": "^5.1.3", | ||
"eslint-plugin-require-extensions": "^0.1.3", | ||
"playwright": "^1.36.2", | ||
"prettier": "^3.0.0", | ||
"typescript": "^5.1.6", | ||
"vite": "^4.4.7", | ||
"vitest": "^0.33.0" | ||
"eslint-plugin-tree-shaking": "^1.12.1", | ||
"playwright": "1.42.1", | ||
"prettier": "^3.2.5", | ||
"typescript": "^5.4.2", | ||
"vite": "^5.1.6", | ||
"vitest": "^1.4.0" | ||
}, | ||
@@ -46,5 +48,4 @@ "prettier": { | ||
"prepare": "npm run build", | ||
"test": "npm run test:unit && npm run test:types", | ||
"test:unit": "vitest", | ||
"test:types": "vitest typecheck", | ||
"test": "npm run test:unit", | ||
"test:unit": "vitest --typecheck", | ||
"test:pkg": "attw $(npm pack)" | ||
@@ -51,0 +52,0 @@ }, |
@@ -1,2 +0,2 @@ | ||
# Parchment [![Build Status](https://github.com/quilljs/parchment/actions/workflows/main.yml/badge.svg?branch=2.0)](https://github.com/quilljs/parchment/actions?query=branch%3A2.0) | ||
# Parchment [![Build Status](https://github.com/quilljs/parchment/actions/workflows/main.yml/badge.svg?branch=main)](https://github.com/quilljs/parchment/actions?query=branch%3Amain) | ||
@@ -7,3 +7,3 @@ Parchment is [Quill](https://quilljs.com)'s document model. It is a parallel tree structure to the DOM tree, and provides functionality useful for content editors, like Quill. A Parchment tree is made up of [Blots](#blots), which mirror a DOM node counterpart. Blots can provide structure, formatting, and/or content. [Attributors](#attributors) can also provide lightweight formatting information. | ||
`npm install --save parchment` | ||
`npm install parchment` | ||
@@ -52,11 +52,10 @@ See [Cloning Medium with Parchment](https://quilljs.com/guides/cloning-medium-with-parchment/) for a guide on how Quill uses Parchment its document model. | ||
// tree. A shared context object is passed through all blots. | ||
optimize(context: {[key: string]: any}): void; | ||
optimize(context: { [key: string]: any }): void; | ||
// Called when blot changes, with the mutation records of its change. | ||
// Internal records of the blot values can be updated, and modifcations of | ||
// Internal records of the blot values can be updated, and modifications of | ||
// the blot itself is permitted. Can be trigger from user change or API call. | ||
// A shared context object is passed through all blots. | ||
update(mutations: MutationRecord[], context: {[key: string]: any}); | ||
update(mutations: MutationRecord[], context: { [key: string]: any }); | ||
/** Leaf Blots only **/ | ||
@@ -82,7 +81,6 @@ | ||
/** Parent blots only **/ | ||
// Whitelist array of Blots that can be direct children. | ||
static allowedChildren: Blot[]; | ||
static allowedChildren: Registry.BlotConstructor[]; | ||
@@ -98,6 +96,5 @@ // Default child blot to be inserted if this blot becomes empty. | ||
// Useful search functions for descendant(s), should not modify | ||
descendant(type: BlotClass, index: number, inclusive): Blot | ||
descendant(type: BlotClass, index: number, inclusive): Blot; | ||
descendants(type: BlotClass, index: number, length: number): Blot[]; | ||
/** Formattable blots only **/ | ||
@@ -125,2 +122,5 @@ | ||
class LinkBlot extends Parchment.Inline { | ||
static blotName = 'link'; | ||
static tagName = 'A'; | ||
static create(url) { | ||
@@ -152,4 +152,2 @@ let node = super.create(); | ||
} | ||
LinkBlot.blotName = 'link'; | ||
LinkBlot.tagName = 'A'; | ||
@@ -159,3 +157,3 @@ Parchment.register(LinkBlot); | ||
Quill also provides many great example implementions in its [source code](https://github.com/quilljs/quill/tree/develop/formats). | ||
Quill also provides many great example implementations in its [source code](https://github.com/quilljs/quill/tree/develop/formats). | ||
@@ -168,3 +166,3 @@ ### Block Blot | ||
Basic implementation of an inline scoped formattable parent Blot. Formatting an inline blot by default either wraps itself with another blot or passes the call to the approprate child. | ||
Basic implementation of an inline scoped formattable parent Blot. Formatting an inline blot by default either wraps itself with another blot or passes the call to the appropriate child. | ||
@@ -179,3 +177,2 @@ ### Embed Blot | ||
## Attributors | ||
@@ -219,6 +216,6 @@ | ||
Width.add(imageNode, '10px'); | ||
console.log(imageNode.outerHTML); // Will print <img width="10px"> | ||
Width.value(imageNode); // Will return 10px | ||
console.log(imageNode.outerHTML); // Will print <img width="10px"> | ||
Width.value(imageNode); // Will return 10px | ||
Width.remove(imageNode); | ||
console.log(imageNode.outerHTML); // Will print <img> | ||
console.log(imageNode.outerHTML); // Will print <img> | ||
``` | ||
@@ -238,3 +235,3 @@ | ||
Align.add(node, 'right'); | ||
console.log(node.outerHTML); // Will print <div class="blot-align-right"></div> | ||
console.log(node.outerHTML); // Will print <div class="blot-align-right"></div> | ||
``` | ||
@@ -250,3 +247,3 @@ | ||
let Align = new Parchment.Attributor.Style('align', 'text-align', { | ||
whitelist: ['right', 'center', 'justify'] // Having no value implies left align | ||
whitelist: ['right', 'center', 'justify'], // Having no value implies left align | ||
}); | ||
@@ -257,3 +254,3 @@ Parchment.register(Align); | ||
Align.add(node, 'right'); | ||
console.log(node.outerHTML); // Will print <div style="text-align: right;"></div> | ||
console.log(node.outerHTML); // Will print <div style="text-align: right;"></div> | ||
``` | ||
@@ -260,0 +257,0 @@ |
@@ -7,7 +7,16 @@ import type LinkedList from '../../collection/linked-list.js'; | ||
export interface BlotConstructor { | ||
new (...args: any[]): Blot; | ||
/** | ||
* Creates corresponding DOM node | ||
*/ | ||
create(value?: any): Node; | ||
blotName: string; | ||
tagName: string | string[]; | ||
scope: Scope; | ||
className?: string; | ||
tagName: string | string[]; | ||
new (...args: any[]): Blot; | ||
create(value?: any): Node; | ||
requiredContainer?: BlotConstructor; | ||
allowedChildren?: BlotConstructor[]; | ||
defaultChild?: BlotConstructor; | ||
} | ||
@@ -22,11 +31,3 @@ | ||
statics: { | ||
allowedChildren?: BlotConstructor[]; | ||
blotName: string; | ||
className?: string; | ||
defaultChild?: BlotConstructor; | ||
requiredContainer?: BlotConstructor; | ||
scope: Scope; | ||
tagName: string | string[]; | ||
}; | ||
statics: BlotConstructor; | ||
@@ -37,3 +38,12 @@ attach(): void; | ||
isolate(index: number, length: number): Blot; | ||
/** | ||
* For leaves, length of blot's value() | ||
* For parents, sum of children's values | ||
*/ | ||
length(): number; | ||
/** | ||
* Returns offset between this blot and an ancestor's | ||
*/ | ||
offset(root?: Blot): number; | ||
@@ -50,4 +60,17 @@ remove(): void; | ||
insertAt(index: number, value: string, def?: any): void; | ||
/** | ||
* Called after update cycle completes. Cannot change the value or length | ||
* of the document, and any DOM operation must reduce complexity of the DOM | ||
* tree. A shared context object is passed through all blots. | ||
*/ | ||
optimize(context: { [key: string]: any }): void; | ||
optimize(mutations: MutationRecord[], context: { [key: string]: any }): void; | ||
/** | ||
* Called when blot changes, with the mutation records of its change. | ||
* Internal records of the blot values can be updated, and modifications of | ||
* the blot itself is permitted. Can be trigger from user change or API call. | ||
* A shared context object is passed through all blots. | ||
*/ | ||
update(mutations: MutationRecord[], context: { [key: string]: any }): void; | ||
@@ -83,3 +106,10 @@ } | ||
export interface Formattable extends Blot { | ||
/** | ||
* Apply format to blot. Should not pass onto child or other blot. | ||
*/ | ||
format(name: string, value: any): void; | ||
/** | ||
* Return formats represented by blot, including from Attributors. | ||
*/ | ||
formats(): { [index: string]: any }; | ||
@@ -86,0 +116,0 @@ } |
@@ -8,2 +8,7 @@ import Scope from '../../scope.js'; | ||
/** | ||
* Returns the value represented by domNode if it is this Blot's type | ||
* No checking that domNode can represent this Blot type is required so | ||
* applications needing it should check externally before calling. | ||
*/ | ||
public static value(_domNode: Node): any { | ||
@@ -13,2 +18,6 @@ return true; | ||
/** | ||
* Given location represented by node and offset from DOM Selection Range, | ||
* return index to that location. | ||
*/ | ||
public index(node: Node, offset: number): number { | ||
@@ -25,2 +34,6 @@ if ( | ||
/** | ||
* Given index to location within blot, return node and offset representing | ||
* that location, consumable by DOM Selection Range | ||
*/ | ||
public position(index: number, _inclusive?: boolean): [Node, number] { | ||
@@ -35,2 +48,7 @@ const childNodes: Node[] = Array.from(this.parent.domNode.childNodes); | ||
/** | ||
* Return value represented by this blot | ||
* Should not change without interaction from API or | ||
* user change detectable by update() | ||
*/ | ||
public value(): any { | ||
@@ -37,0 +55,0 @@ return { |
@@ -26,3 +26,10 @@ import LinkedList from '../../collection/linked-list.js'; | ||
class ParentBlot extends ShadowBlot implements Parent { | ||
public static allowedChildren: BlotConstructor[] | null; | ||
/** | ||
* Whitelist array of Blots that can be direct children. | ||
*/ | ||
public static allowedChildren?: BlotConstructor[]; | ||
/** | ||
* Default child blot to be inserted if this blot becomes empty. | ||
*/ | ||
public static defaultChild?: BlotConstructor; | ||
@@ -63,2 +70,5 @@ public static uiClass = ''; | ||
/** | ||
* Called during construction, should fill its own children LinkedList. | ||
*/ | ||
public build(): void { | ||
@@ -65,0 +75,0 @@ this.children = new LinkedList<Blot>(); |
@@ -122,4 +122,4 @@ import Attributor from './attributor/attributor.js'; | ||
: isAttr | ||
? definition.attrName | ||
: (undefined as never); // already handled by above checks | ||
? definition.attrName | ||
: (undefined as never); // already handled by above checks | ||
this.types[key] = definition; | ||
@@ -126,0 +126,0 @@ |
@@ -10,3 +10,3 @@ { | ||
"strict": true, | ||
"moduleResolution": "node", | ||
"moduleResolution": "Bundler", | ||
"noUnusedLocals": true, | ||
@@ -13,0 +13,0 @@ "noUnusedParameters": true, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
314709
3301
17
272