@atlaskit/editor-common
Version:
A package that contains common classes and components for editor and renderer
96 lines (93 loc) • 2.78 kB
JavaScript
import { getBooleanFF } from '@atlaskit/platform-feature-flags';
export const canApplyAnnotationOnRange = (rangeSelection, doc, schema) => {
const {
from,
to
} = rangeSelection;
if (isNaN(from + to) || to - from <= 0 || to < 0 || from < 0) {
return false;
}
const {
inlineCard
} = schema.nodes;
let foundInvalid = false;
doc.nodesBetween(rangeSelection.from, rangeSelection.to, (node, _pos, parent) => {
// Special exception for hardBreak nodes
if (schema.nodes.hardBreak === node.type) {
return false;
}
// For block elements or text nodes, we want to check
// if annotations are allowed inside this tree
// or if we're leaf and not text
if (getBooleanFF('platform.editor.allow-inline-comments-for-inline-nodes')) {
if (node.isInline && !node.isText && node.type !== inlineCard || node.isLeaf && !node.isText && node.type !== inlineCard || node.isText && !(parent !== null && parent !== void 0 && parent.type.allowsMarkType(schema.marks.annotation))) {
foundInvalid = true;
return false;
}
} else {
if (node.isInline && !node.isText || node.isLeaf && !node.isText || node.isText && !(parent !== null && parent !== void 0 && parent.type.allowsMarkType(schema.marks.annotation))) {
foundInvalid = true;
return false;
}
}
return true;
});
return !foundInvalid;
};
export const getAnnotationIdsFromRange = (rangeSelection, doc, schema) => {
const {
from,
to
} = rangeSelection;
let annotations = new Set();
doc.nodesBetween(from, to, node => {
if (!node.marks) {
return true;
}
node.marks.forEach(mark => {
if (mark.type === schema.marks.annotation && mark.attrs) {
annotations.add(mark.attrs.id);
}
});
return true;
});
return Array.from(annotations);
};
/*
* verifies if node contains annotation mark
*/
export function hasAnnotationMark(node, state) {
const {
schema: {
marks: {
annotation: annotationMark
}
}
} = state;
return !!(annotationMark && node && node.marks.length && annotationMark.isInSet(node.marks));
}
/*
* verifies that slice contains any annotations
*/
export function containsAnyAnnotations(slice, state) {
if (!slice.content.size) {
return false;
}
let hasAnnotation = false;
slice.content.forEach(node => {
hasAnnotation = hasAnnotation || hasAnnotationMark(node, state);
// return early if annotation found already
if (hasAnnotation) {
return true;
}
// check annotations in descendants
node.descendants(node => {
if (hasAnnotationMark(node, state)) {
hasAnnotation = true;
return false;
}
return true;
});
});
return hasAnnotation;
}