Files
2025-01-04 00:34:03 +01:00

71 lines
2.3 KiB
JavaScript

import {mergeObject} from "../../utils/helpers.mjs";
import ImageNode from "./image-node.mjs";
import LinkMark from "./link-mark.mjs";
import SchemaDefinition from "./schema-definition.mjs";
/**
* A class responsible for encapsulating logic around image-link nodes in the ProseMirror schema.
* @extends {SchemaDefinition}
*/
export default class ImageLinkNode extends SchemaDefinition {
/** @override */
static tag = "a";
/* -------------------------------------------- */
/** @override */
static get attrs() {
return mergeObject(ImageNode.attrs, LinkMark.attrs);
}
/* -------------------------------------------- */
/** @override */
static getAttrs(el) {
if ( (el.children.length !== 1) || (el.children[0].tagName !== "IMG") ) return false;
const attrs = ImageNode.getAttrs(el.children[0]);
attrs.href = el.href;
attrs.title = el.title;
return attrs;
}
/* -------------------------------------------- */
/** @override */
static toDOM(node) {
const spec = LinkMark.toDOM(node);
spec.push(ImageNode.toDOM(node));
return spec;
}
/* -------------------------------------------- */
/** @inheritdoc */
static make() {
return mergeObject(super.make(), {
group: "block",
draggable: true,
managed: { styles: ["float"], classes: ["centered"] }
});
}
/* -------------------------------------------- */
/**
* Handle clicking on image links while editing.
* @param {EditorView} view The ProseMirror editor view.
* @param {number} pos The position in the ProseMirror document that the click occurred at.
* @param {PointerEvent} event The click event.
* @param {Node} node The Node instance.
*/
static onClick(view, pos, event, node) {
if ( (event.ctrlKey || event.metaKey) && node.attrs.href ) window.open(node.attrs.href, "_blank");
// For some reason, calling event.preventDefault in this (mouseup) handler is not enough to cancel the default click
// behaviour. It seems to be related to the outer anchor being set to contenteditable="false" by ProseMirror.
// This workaround seems to prevent the click.
const parent = event.target.parentElement;
if ( (parent.tagName === "A") && !parent.isContentEditable ) parent.contentEditable = "true";
return true;
}
}