Update: Solved, see bottom if you have the same issue:
I wish to add the orig
attribute to an image, to keep track of it’s original source URL.
Here I extend the built in the schema to add the orig
attribute:
import { Schema, NodeSpec } from "prosemirror-model";
import { EditorView } from "prosemirror-view";
// add the attribute `orig` to the image node
const imageNodeSpec: NodeSpec = {
inline: true,
attrs: {
src: {},
alt: { default: null },
title: { default: null },
orig: { default: null },
},
group: "inline",
draggable: true,
parseDOM: [
{
tag: "img[src]",
getAttrs: (dom) => {
const element = dom as HTMLElement;
return {
src: element.getAttribute("src"),
title: element.getAttribute("title"),
alt: element.getAttribute("alt"),
orig: element.getAttribute("orig"),
};
},
},
],
toDOM: (node) => ["img", node.attrs],
};
// Create a new schema based on the existing one with the new image node spec
const customSchema = new Schema({
nodes: schema.spec.nodes.update("image", imageNodeSpec),
marks: schema.spec.marks,
});
console.log("new schema", customSchema);
And I can see the customShechma
’s img node has the additional orig
attribute.
For now I am just hardcoding the return of pastePlugin to isolate. Although it returns an <img> tag with the
origattribute, the
orig` attribute is removed when the prose editor processes the return value, why is that?
export function pastePlugin(apiService: ApiService, navigationService: NavigationService) {
return new Plugin({
props: {
transformPastedHTML: (html: string, editorView: EditorView) => {
return `<img src="https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png" orig="https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png"><p>INFILTRATED</p>`;
},
},
});
}
Schema is used:
this.editor = new Editor({
content: "",
plugins: [pastePlugin(this.apiService, this.navigationService)],
nodeViews: {},
history: true,
keyboardShortcuts: true,
inputRules: true,
schema: customSchema,
});
But the orig
attribute is being removed. editorView.state.schema
within the pastePlugin
shows the orig
attribute is there.
I finally got it to preserve the attributes, if I create a custom Node view for an image (but then the resize functionality is lost):
// This works, but surely is not required? Is that a bug?
class ImageView {
dom: HTMLElement;
constructor(
private node: any,
private view: EditorView,
private getPos: () => number | undefined
) {
this.dom = document.createElement("img");
(this.dom as HTMLImageElement).src = node.attrs.src;
if (node.attrs.orig) {
this.dom.setAttribute("orig", node.attrs.orig);
}
(this.dom as HTMLImageElement).alt = node.attrs.alt || "";
this.dom.title = node.attrs.title || "";
this.dom.addEventListener("click", (e) => {
console.log("Image clicked:", node.attrs.src);
e.preventDefault();
});
}
update(node: any) {
if (node.type !== this.node.type) return false;
(this.dom as HTMLImageElement).src = node.attrs.src;
if (node.attrs.orig) {
this.dom.setAttribute("orig", node.attrs.orig);
} else {
this.dom.removeAttribute("orig");
}
(this.dom as HTMLImageElement).alt = node.attrs.alt || "";
this.dom.title = node.attrs.title || "";
return true;
}
}
For anyone else the reason if because I am using ngx-editor
, and uses a custom ImageView, see here: ngx-editor/projects/ngx-editor/src/lib/plugins/image-resize.ts at 7f400933653bbb373221b50cd6db7909e47c979f · sibiraj-s/ngx-editor · GitHub