Access to internal variables in schema?

Hey, I am trying to connect images which are ordered in an internal dict with the schema. So for example an image node has the attribute ID = ‘P123’, and in the dict of images, we can find the URL for that (ImageDB['P123'].image).

Until now, I have made this work by doing as part of the serializeDOM of the element in question:

dom.firstChild.appendChild(serializer.elt("img", {
            "src": ImageDB[node.attrs.image].image
        }))

However, this was only possible because ImageDB was available in the global namespace (window.ImageDB). I would like to move it away from there. Now I wonder whether:

A) There is a way to hand another variable to the serializeDOM function that is not in the global namespace.

or

B) Whether it is better to not have anything about the connection to the ImageDB in the schema and instead just leave an empty container into which a picture can be put by other code later on, and then have a separate function that is being triggered by the UpdateScheduler on any changes that will then have access to the image data and always adds images to any Image node that lacks an <IMG>-element.

Any thoughts?

I have a similar use case and solved it by using the options that can be passed to the dom serializer, which gets passed to the serializeDOM method.

In your case this could look something like this:

// Call serializeTo passing in the imageDB as an option
serializeTo(node, 'dom', {imageDB: ImageDB})

YourNode.prototype.serializeDOM = (node, serializer) => {
  // Here you can access serializer.options.imageDB[node.attrs.image]
}

I also needed this to work for text serialization and implemented a custom text serializer which accepts an additional options argument. If you’re interested I can post it too, but it’s more or less a copy of the original text serializer with the added options argument. If more people need this, it might be a good idea to make this part of the default text serializer.

Using options is one way (I hadn’t thought of). Another possibility, which might also be helpful in other contexts, is to store a reference to the DB in the schema (which you can get at with node.type.schema). There’s no clean way to do that yet (I should add one, opened #290), but schema.cached is a namespace object specifically intended for allowing external code to store stuff in a schema. So you could assign to that (using a somewhat long property name to avoid possible clashes), and read from it later.

mySchema.cached.imageDB = ImageDB

YourNode.prototype.serializeDOM = (node, serializer) =>
  serializer.elt("img", {
    src: node.type.schema.cached.imageDB[node.attrs.id].src
  })
)

Ah! Thanks for those ideas. Very helpful. I went with the one using schema.cached. This is working perfectly, but I agree that it would probably better to have it work some more intuitive way.