1
0
mirror of https://github.com/BookStackApp/BookStack.git synced 2025-08-07 23:03:00 +03:00

Comments: Added inline comment marker/highlight logic

This commit is contained in:
Dan Brown
2025-04-19 14:07:52 +01:00
parent 2e7544a865
commit 18ede9bbd3
5 changed files with 126 additions and 6 deletions

View File

@@ -1,3 +1,5 @@
import {cyrb53} from "./util";
/**
* Check if the given param is a HTMLElement
*/
@@ -181,6 +183,9 @@ export function htmlToDom(html: string): HTMLElement {
return firstChild;
}
/**
* For the given node and offset, return an adjusted offset that's relative to the given parent element.
*/
export function normalizeNodeTextOffsetToParent(node: Node, offset: number, parentElement: HTMLElement): number {
if (!parentElement.contains(node)) {
throw new Error('ParentElement must be a prent of element');
@@ -201,3 +206,54 @@ export function normalizeNodeTextOffsetToParent(node: Node, offset: number, pare
return normalizedOffset;
}
/**
* Find the target child node and adjusted offset based on a parent node and text offset.
* Returns null if offset not found within the given parent node.
*/
export function findTargetNodeAndOffset(parentNode: HTMLElement, offset: number): ({node: Node, offset: number}|null) {
if (offset === 0) {
return { node: parentNode, offset: 0 };
}
let currentOffset = 0;
let currentNode = null;
for (let i = 0; i < parentNode.childNodes.length; i++) {
currentNode = parentNode.childNodes[i];
if (currentNode.nodeType === Node.TEXT_NODE) {
// For text nodes, count the length of their content
// Returns if within range
const textLength = currentNode.textContent.length;
if (currentOffset + textLength >= offset) {
return {
node: currentNode,
offset: offset - currentOffset
};
}
currentOffset += textLength;
} else if (currentNode.nodeType === Node.ELEMENT_NODE) {
// Otherwise, if an element, track the text length and search within
// if in range for the target offset
const elementTextLength = currentNode.textContent.length;
if (currentOffset + elementTextLength >= offset) {
return findTargetNodeAndOffset(currentNode, offset - currentOffset);
}
currentOffset += elementTextLength;
}
}
// Return null if not found within range
return null;
}
/**
* Create a hash for the given HTML element.
*/
export function hashElement(element: HTMLElement): string {
const normalisedElemHtml = element.outerHTML.replace(/\s{2,}/g, '');
return cyrb53(normalisedElemHtml);
}