71 lines
2.3 KiB
JavaScript
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;
|
||
|
|
}
|
||
|
|
}
|