-
Getting a hold of DOM serializer’s
document
intoDOM()
seems to involve:serializeNodeInner()
(passdocument
to node spec’stoDOM()
),serializeNode()
(passdocument
toserializeMark()
),serializeMark()
(passdocument
to mark spec’stoDOM()
), and- updating node/mark spec’s
toDOM()
TypeScript signature (backwards compatible).
For example, in case of
serializeNodeInner()
, just this call (lines split for legibility) would change fromrenderSpec( doc(options), this.nodes[node.type.name](node), null, node.attrs)
to
const dom = doc(options) renderSpec( dom, this.nodes[node.type.name](node, dom), null, node.attrs)
-
Regarding what
document
entails, for ProseMirror’s purposes (meaning both what callers must pass toserializeNode()
and what it’d pass to spec’stoDOM()
per (1) above) it seems to be a tiny subset ofDocument
with only the following:.createTextNode()
(called here).createDocumentFragment()
(called here).createElement[NS]()
(called here, and presumably in atoDOM()
that wishes to return a DOM node)
Concerning the
HTMLElement
orDocumentFragment
returned from the above functions, for PM’s purposes it seems they only must implement:.nodeType
property, only applicable to HTMLElement.setAttribute[NS]()
(called here), only applicable to HTMLElement.appendChild()
(called here and here)
This is based on prosemirror-model’s
to_dom.ts
, let me know if there’re other modules of concern.Narrowing down the type can be done easily with TypeScript’s built-in
Pick
type:type BareDocument = Pick<Document, | "createTextNode" | "createDocumentFragment" | ...>;
Notes;
-
The above changes are backward compatible and don’t affect existing users.
-
The changes are independent of each other, though I would say it’d be better to narrow down
Document
first, if it’s to be added totoDOM()
’s signature. -
In fact, instead of giving
toDOM()
access todocument
, even a narrowed-down version, it could be worth passing just an element constructor function:toDOM( node: Node, createDOMElement: BareDocument["createElement"], ): ...