Skip to content

Commit

Permalink
human-readable textBefore, text and textAfter; remove originalText
Browse files Browse the repository at this point in the history
  • Loading branch information
KevinWang15 committed Feb 18, 2022
1 parent 36dbe90 commit d7fe15a
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 69 deletions.
83 changes: 62 additions & 21 deletions src/lib/classes/Marker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import HighlightPainter from "./HighlightPainter";
import EventHandlerContext from "./Context";
import Context from "./Context";
import SerializedRange from "./SerializedRange";
import resolveSerializedRangeOffsetInText from "../../utils/resolveSerializedRangeOffsetInText";
import DeserializationError from "./errors/DeserializationError";

const HighlightTagName = "web-marker-highlight";
const HighlightBlacklistedElementClassName = "web-marker-black-listed-element";
const AttributeNameHighlightId = "highlight-id";

const defaultCharsToKeepForTextBeforeAndTextAfter = 128;
const blackListedElementStyle = document.createElement("style");
blackListedElementStyle.innerText = `.${HighlightBlacklistedElementClassName} {display:none;};`;

Expand Down Expand Up @@ -163,7 +164,8 @@ class Marker {
range: Range,
options: { uid?: string; charsToKeepForTextBeforeAndTextAfter?: number } = {
uid: undefined,
charsToKeepForTextBeforeAndTextAfter: 16,
charsToKeepForTextBeforeAndTextAfter:
defaultCharsToKeepForTextBeforeAndTextAfter,
}
): SerializedRange | null {
document.head.appendChild(blackListedElementStyle);
Expand All @@ -172,24 +174,23 @@ class Marker {
this.adjustRangeAroundBlackListedElement(range);
const uid = options?.uid || makeid();
const charsToKeepForTextBeforeAndTextAfter =
options?.charsToKeepForTextBeforeAndTextAfter || 16;
options?.charsToKeepForTextBeforeAndTextAfter ||
defaultCharsToKeepForTextBeforeAndTextAfter;
const selection = Marker.convertRangeToSelection(range);

let originalText = selection.toString();
let text = Marker.normalizeText(originalText);
if (text) {
let text = selection.toString();
let textNormalized = Marker.normalizeText(text);
if (textNormalized) {
let textBefore = "";
let textAfter = "";

{
// find textBefore
textBefore =
textBefore +
Marker.normalizeText(
this.getInnerText(range.startContainer).substr(
0,
range.startOffset
)
this.getInnerText(range.startContainer).substr(
0,
range.startOffset
);

let ptr = range.startContainer as Node | null;
Expand All @@ -199,8 +200,7 @@ class Marker {
// already reached the front
break;
}
textBefore =
Marker.normalizeText((ptr as any).textContent) + textBefore;
textBefore = (ptr as any) + textBefore;
}
if (textBefore.length > charsToKeepForTextBeforeAndTextAfter) {
textBefore = textBefore.substr(
Expand All @@ -213,9 +213,7 @@ class Marker {
// find textAfter
textAfter =
textAfter +
Marker.normalizeText(
this.getInnerText(range.endContainer).substr(range.endOffset)
);
this.getInnerText(range.endContainer).substr(range.endOffset);

let ptr = range.endContainer as Node | null;
while (textAfter.length < charsToKeepForTextBeforeAndTextAfter) {
Expand All @@ -224,8 +222,7 @@ class Marker {
// already reached the end
break;
}
textAfter =
textAfter + Marker.normalizeText((ptr as any).textContent);
textAfter = textAfter + (ptr as any).textContent;
}

if (textAfter.length > charsToKeepForTextBeforeAndTextAfter) {
Expand All @@ -240,7 +237,6 @@ class Marker {
uid,
textBefore,
text,
originalText,
textAfter,
};
return this.state.uidToSerializedRange[uid];
Expand Down Expand Up @@ -337,14 +333,14 @@ class Marker {
try {
this.state.uidToSerializedRange[serializedRange.uid] = serializedRange;
const rootText = this.getNormalizedInnerText(this.rootElement);
const offset = resolveSerializedRangeOffsetInText(
const offset = this.resolveSerializedRangeOffsetInText(
rootText,
serializedRange
);
const start = this.findElementAtOffset(this.rootElement, offset);
const end = this.findElementAtOffset(
this.rootElement,
offset + serializedRange.text.length
offset + Marker.normalizeText(serializedRange.text).length
);
const range = document.createRange();
range.setStart(
Expand Down Expand Up @@ -691,7 +687,52 @@ class Marker {
public getSerializedRangeFromUid(uid: string): SerializedRange | null {
return this.state.uidToSerializedRange[uid] || null;
}

resolveSerializedRangeOffsetInText(
text: any,
serializedRange: SerializedRange
): number {
// TODO: optimize algorithm, maybe use https://github.com/google/diff-match-patch
const textBeforeNormalized = Marker.normalizeText(
serializedRange.textBefore
);
const textAfterNormalized = Marker.normalizeText(serializedRange.textAfter);
const textNormalized = Marker.normalizeText(serializedRange.text);

for (let strategy of resolveSerializedRangeOffsetInTextStrategies) {
const textToSearch =
(strategy.textBefore ? textBeforeNormalized : "") +
textNormalized +
(strategy.textAfter ? textAfterNormalized : "");

const index = text.indexOf(textToSearch);
if (index >= 0) {
return index + (strategy.textBefore ? textBeforeNormalized.length : 0);
}
}

throw new DeserializationError();
}
}

const resolveSerializedRangeOffsetInTextStrategies = [
{
textBefore: true,
textAfter: true,
},
{
textBefore: false,
textAfter: true,
},
{
textBefore: true,
textAfter: false,
},
{
textBefore: false,
textAfter: false,
},
];

export default Marker;
export type { MarkerConstructorArgs };
9 changes: 4 additions & 5 deletions src/lib/classes/SerializedRange.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
interface SerializedRange {
uid: string;
textBefore: string;
text: string;
originalText: string;
textAfter: string;
uid: string;
textBefore: string;
text: string;
textAfter: string;
}

export default SerializedRange;
43 changes: 0 additions & 43 deletions src/utils/resolveSerializedRangeOffsetInText.ts

This file was deleted.

0 comments on commit d7fe15a

Please sign in to comment.