Make the highlight selection and the marking more robust
Also cover the case when there are paragraphs and unordered lists in the same ContentComponent
This commit is contained in:
parent
8ef3f23edc
commit
2121f01a9c
|
|
@ -18,6 +18,7 @@
|
||||||
<component
|
<component
|
||||||
v-bind="component"
|
v-bind="component"
|
||||||
:parent="parent"
|
:parent="parent"
|
||||||
|
class="content-component__content"
|
||||||
:is="componentType"
|
:is="componentType"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -148,16 +149,22 @@ const componentClass = computed(() => {
|
||||||
}
|
}
|
||||||
return classes;
|
return classes;
|
||||||
});
|
});
|
||||||
const paragraphs = computed(() => {
|
const childElements = computed(() => {
|
||||||
if (contentComponentDiv.value) {
|
if (contentComponentDiv.value) {
|
||||||
let elements: HTMLCollection;
|
const parent = contentComponentDiv.value.querySelector('.content-component__content');
|
||||||
elements = contentComponentDiv.value.getElementsByTagName('p');
|
if (!parent) {
|
||||||
if (!elements.length) {
|
console.warn('Parent does not exist, this should not be possible');
|
||||||
const uls = contentComponentDiv.value.getElementsByTagName('ul');
|
// or can it be, if the children did not load yet, e.g. with a dynamic component?
|
||||||
const ul = uls[0];
|
return [];
|
||||||
elements = ul.getElementsByTagName('li');
|
|
||||||
}
|
}
|
||||||
return elements;
|
// make a flat list from all <li>-elements and all the others
|
||||||
|
const elements = Array.from(parent.children).reduce((acc: Element[], current: Element) => {
|
||||||
|
if (current.tagName.toLowerCase() === 'ul') {
|
||||||
|
return [...acc, ...current.children];
|
||||||
|
}
|
||||||
|
return [...acc, current];
|
||||||
|
}, []);
|
||||||
|
return elements as HTMLElement[];
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
});
|
});
|
||||||
|
|
@ -165,7 +172,7 @@ const paragraphs = computed(() => {
|
||||||
watch(
|
watch(
|
||||||
() => filteredHighlights.value.map((h) => h.color),
|
() => filteredHighlights.value.map((h) => h.color),
|
||||||
() => {
|
() => {
|
||||||
for (const paragraph of paragraphs.value) {
|
for (const paragraph of childElements.value) {
|
||||||
const instance = new Mark(paragraph);
|
const instance = new Mark(paragraph);
|
||||||
instance.unmark();
|
instance.unmark();
|
||||||
}
|
}
|
||||||
|
|
@ -234,7 +241,7 @@ const { mutate: doDeleteHighlight } = useMutation(
|
||||||
|
|
||||||
const markHighlights = () => {
|
const markHighlights = () => {
|
||||||
for (const highlight of filteredHighlights.value) {
|
for (const highlight of filteredHighlights.value) {
|
||||||
const element = paragraphs.value[highlight.paragraphIndex];
|
const element = childElements.value[highlight.paragraphIndex];
|
||||||
const instance = new Mark(element);
|
const instance = new Mark(element);
|
||||||
const ranges: Mark.Range[] = [
|
const ranges: Mark.Range[] = [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,30 @@ const findPositionInParent = (element: HTMLElement, className: string = 'content
|
||||||
return children.indexOf(element);
|
return children.indexOf(element);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getParentElement = (element: HTMLElement): HTMLElement | null => {
|
||||||
|
if (element.tagName.toLowerCase() === 'li') {
|
||||||
|
return element.parentElement?.parentElement || null;
|
||||||
|
} else {
|
||||||
|
return element.parentElement || null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getSiblings = (element: HTMLElement): Element[] => {
|
||||||
|
const parent = getParentElement(element);
|
||||||
|
if (!parent) {
|
||||||
|
throw Error('element has no parent, this should not be possible');
|
||||||
|
}
|
||||||
|
let children: Element[] = [];
|
||||||
|
for (const child of parent.children) {
|
||||||
|
if (child.tagName.toLowerCase() === 'ul') {
|
||||||
|
children = [...children, ...child.children];
|
||||||
|
} else {
|
||||||
|
children = [...children, child];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return children;
|
||||||
|
};
|
||||||
|
|
||||||
export const getSelectionHandler =
|
export const getSelectionHandler =
|
||||||
(el: HTMLElement, contentBlock: ContentBlockNode, onUpdateHighlight: (highlight: any) => void = () => {}) =>
|
(el: HTMLElement, contentBlock: ContentBlockNode, onUpdateHighlight: (highlight: any) => void = () => {}) =>
|
||||||
(_e: Event) => {
|
(_e: Event) => {
|
||||||
|
|
@ -123,11 +147,13 @@ export const getSelectionHandler =
|
||||||
if (contentComponent) {
|
if (contentComponent) {
|
||||||
// our selection is wholly inside the container node, we continue with it
|
// our selection is wholly inside the container node, we continue with it
|
||||||
const position = findPositionInParent(contentComponent);
|
const position = findPositionInParent(contentComponent);
|
||||||
const siblings = Array.from(startAncestor.parentElement?.children || []);
|
const uuid = contentComponent.dataset.uuid || '';
|
||||||
|
|
||||||
|
// const siblings = Array.from(startAncestor.parentElement?.children || []);
|
||||||
|
const siblings = getSiblings(startAncestor);
|
||||||
const positionInTextBlock = siblings.indexOf(startAncestor);
|
const positionInTextBlock = siblings.indexOf(startAncestor);
|
||||||
|
|
||||||
const { start, end } = range.toCharacterRange(startAncestor);
|
const { start, end } = range.toCharacterRange(startAncestor);
|
||||||
const uuid = contentComponent.dataset.uuid || '';
|
|
||||||
const highlightedText: Highlight = {
|
const highlightedText: Highlight = {
|
||||||
contentBlock: contentBlock.id,
|
contentBlock: contentBlock.id,
|
||||||
contentIndex: position,
|
contentIndex: position,
|
||||||
|
|
@ -137,7 +163,6 @@ export const getSelectionHandler =
|
||||||
selectionLength: end - start,
|
selectionLength: end - start,
|
||||||
text: range.toString(),
|
text: range.toString(),
|
||||||
};
|
};
|
||||||
console.log(highlightedText);
|
|
||||||
|
|
||||||
const positionOfContentBlock = el.getBoundingClientRect();
|
const positionOfContentBlock = el.getBoundingClientRect();
|
||||||
const positionOfSelection = startAncestor?.getBoundingClientRect();
|
const positionOfSelection = startAncestor?.getBoundingClientRect();
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
"checkJs": false,
|
"checkJs": false,
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"allowSyntheticDefaultImports": true,
|
"allowSyntheticDefaultImports": true,
|
||||||
"lib": ["es2017", "dom"],
|
"lib": ["es2017", "dom", "dom.iterable"],
|
||||||
"target": "es6",
|
"target": "es6",
|
||||||
"module": "es2022",
|
"module": "es2022",
|
||||||
"strict": true,
|
"strict": true,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue