Trying to serialize JSON back to HTML using Node.fromJSON and DOMSerializer


#1

I’m trying to convert the JSON output back into HTML using Node. Based on what I read, I tried the following:

  1. create a new node by passing it the JSON and matching schema (saved in a separate file)
  2. run the node content through DOMSerializer (passing it a document object as an option)

What I have so far:

const {schema} = require("./schema")
const {Node, DOMSerializer} = require("prosemirror-model")
const jsdom = require("jsdom").JSDOM;

let dom = new jsdom('<!DOCTYPE html><div id="content"></div>')
let doc = dom.window.document
let content = {"doc":{"type":"doc","content":[{"type":"paragraph","attrs":{"align":"left"},"content":[{"type":"text","text":"My sample text"}]}]},"selection":{"type":"text","anchor":16,"head":16}}

let contentNode = Node.fromJSON(schema, content.doc)

DOMSerializer
    .fromSchema(schema)
    .serializeFragment(contentNode.content, {"document": doc })

The code is failing at the Serializer step. As I am a new user, any pointers as to what I could be doing wrong would be welcome.


#2

Nothing looks obviously wrong in that snippet. A more precise description of what ‘the code is failing’ means (i.e. error message and stack trace) might help.


#3

Thank you for the quick reply. I was trying to reproduce the stack error just now to post it, and… the code works. Must have been a typo.

Correction: Acutally, the code executes, but no nodes get attached to the DOM of the document, as shown below (the last statement is a console log of the innerHTML of the document.body):

Node {
  type:
   NodeType {
     name: 'doc',
     schema:
      Schema {
        spec: [Object],
        nodes: [Object],
        marks: [Object],
        nodeFromJSON: [Function: bound nodeFromJSON],
        markFromJSON: [Function: bound markFromJSON],
        topNodeType: [Circular],
        cached: [Object] },
     spec: { content: 'block+' },
     groups: [],
     attrs: {},
     defaultAttrs: {},
     contentMatch: ContentMatch { validEnd: false, next: [Array], wrapCache: [] },
     markSet: [],
     inlineContent: false,
     isBlock: true,
     isText: false },
  attrs: {},
  content: Fragment { content: [ [Object] ], size: 17 },
  marks: [] }
<div id="content"></div>

So I guess it doesn’t quite work still. Any thoughts why the HTML would not show up in the doc?

Nevermind, I found my own solution: I added the #content DIV as target for the DOMSerializer, like so:

let target = doc.querySelector("div")

DOMSerializer
    .fromSchema(schema)
    .serializeFragment(contentNode.content, {"document": doc }, target)

I now get the HTML output, as expected:

<div id="content"><p>My sample text</p></div>