Start work to also enable highlighting for list items
This commit is contained in:
parent
56b973f02e
commit
4464b56cbb
|
|
@ -32,9 +32,17 @@ const isInsideViewport = (position: number) => {
|
|||
return position >= TOP_TRESHOLD && position <= BOTTOM_TRESHOLD;
|
||||
};
|
||||
|
||||
const findClosestAncestorWithTag = (node: Node, tag: string): HTMLElement | null => {
|
||||
const findClosestAncestorWithTag = (node: Node, tags: string | string[]): HTMLElement | null => {
|
||||
let tagList = tags;
|
||||
if (!Array.isArray(tagList)) {
|
||||
tagList = [tagList];
|
||||
}
|
||||
let currentNode: Node | null = node;
|
||||
while (currentNode && currentNode.nodeName.toLowerCase() !== tag && currentNode.nodeName.toLowerCase() !== 'body') {
|
||||
while (
|
||||
currentNode &&
|
||||
!tagList.includes(currentNode.nodeName.toLowerCase()) &&
|
||||
currentNode.nodeName.toLowerCase() !== 'body'
|
||||
) {
|
||||
currentNode = currentNode.parentNode;
|
||||
}
|
||||
if (currentNode) {
|
||||
|
|
@ -93,34 +101,31 @@ export const getSelectionHandler =
|
|||
const rect = el.getBoundingClientRect();
|
||||
if (isInsideViewport(rect.top) || isInsideViewport(rect.bottom)) {
|
||||
// the listener only does something if the `el` is visible in the viewport, to save resources
|
||||
|
||||
// now we check if the selection is inside our container
|
||||
|
||||
const selection = rangy.getSelection();
|
||||
if (selection.rangeCount && !selection.isCollapsed) {
|
||||
// ⬆️ sat least one selection exists and is not of length 0
|
||||
const range = selection.getRangeAt(0);
|
||||
if (range.intersectsNode(el)) {
|
||||
// the selection is inside our container, so we can do something with it
|
||||
const { startContainer, endContainer } = range;
|
||||
const paragraph = findClosestAncestorWithTag(startContainer, 'p');
|
||||
const endAncestor = findClosestAncestorWithTag(endContainer, 'p');
|
||||
|
||||
if (!paragraph) {
|
||||
throw Error('This should not be happening, but there was no paragraph');
|
||||
const startAncestor = findClosestAncestorWithTag(startContainer, ['p', 'li']);
|
||||
// const endAncestor = findClosestAncestorWithTag(endContainer, 'p');
|
||||
if (!startAncestor) {
|
||||
throw Error('This should not be happening, but there was no paragraph or list item');
|
||||
}
|
||||
if (paragraph === endAncestor) {
|
||||
// should have the same tag as the start item
|
||||
const endAncestor = findClosestAncestorWithTag(endContainer, startAncestor.tagName);
|
||||
|
||||
if (startAncestor === endAncestor) {
|
||||
const contentComponent = findClosestAncestorWithClass(startContainer, 'content-component');
|
||||
if (contentComponent) {
|
||||
// our selection is wholly inside the container node, we continue with it
|
||||
const position = findPositionInParent(contentComponent);
|
||||
const siblings = Array.from(paragraph.parentElement?.children || []);
|
||||
const positionInTextBlock = siblings.indexOf(paragraph);
|
||||
const siblings = Array.from(startAncestor.parentElement?.children || []);
|
||||
const positionInTextBlock = siblings.indexOf(startAncestor);
|
||||
|
||||
const numOfParagraphs = Array.from(contentComponent.children[1].children).filter(
|
||||
(child) => child.nodeName.toLowerCase() === 'p'
|
||||
).length;
|
||||
|
||||
const { start, end } = range.toCharacterRange(paragraph);
|
||||
const { start, end } = range.toCharacterRange(startAncestor);
|
||||
const uuid = contentComponent.dataset.uuid || '';
|
||||
const highlightedText: Highlight = {
|
||||
contentBlock: contentBlock.id,
|
||||
|
|
@ -134,7 +139,7 @@ export const getSelectionHandler =
|
|||
console.log(highlightedText);
|
||||
|
||||
const positionOfContentBlock = el.getBoundingClientRect();
|
||||
const positionOfSelection = paragraph?.getBoundingClientRect();
|
||||
const positionOfSelection = startAncestor?.getBoundingClientRect();
|
||||
const offsetTop = positionOfSelection.top - positionOfContentBlock.top;
|
||||
popover
|
||||
.show({
|
||||
|
|
@ -144,11 +149,6 @@ export const getSelectionHandler =
|
|||
console.log('chosenColor', color);
|
||||
highlightedText.color = color;
|
||||
onUpdateHighlight(highlightedText);
|
||||
// const newHighlight: Highlight = {
|
||||
// contentBlock: contentBlock.id,
|
||||
// contentIndex:
|
||||
//
|
||||
// };
|
||||
},
|
||||
})
|
||||
.then(() => {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ interface Options {
|
|||
offsetTop: number;
|
||||
onChooseColor: (color: string) => void;
|
||||
// we don't use the id as a param here, because the calling component knows already which entity it is
|
||||
onDelete: () => void;
|
||||
onDelete?: () => void;
|
||||
}
|
||||
|
||||
export default {
|
||||
|
|
@ -48,7 +48,9 @@ export default {
|
|||
_reject();
|
||||
},
|
||||
onDelete() {
|
||||
onDelete();
|
||||
if (onDelete) {
|
||||
onDelete();
|
||||
}
|
||||
cleanUp();
|
||||
},
|
||||
onChooseColor,
|
||||
|
|
|
|||
Loading…
Reference in New Issue