fix: handle text selection edge cases using new delimeter
This commit is contained in:
+19
-11
@@ -9,39 +9,47 @@
|
||||
/**
|
||||
* Encode a text selection into a compact URL-safe fragment.
|
||||
*
|
||||
* Format: `?hl=<prefix>,<suffix>,<length>`
|
||||
* Format: `?hl=<prefix>§<suffix>§<length>`
|
||||
* - prefix: first 4 words of the selection
|
||||
* - suffix: last 4 words of the selection (omitted if same as prefix)
|
||||
* - length: character count of the full selection (for disambiguation)
|
||||
*
|
||||
* This keeps URLs short while being specific enough to locate the text.
|
||||
* Uses `§` (section sign) as delimiter — it never appears in Sanskrit,
|
||||
* Devanagari, English, or any Vedic text, unlike `,` (commas in prose)
|
||||
* or `|` (pūrṇa virāma in Sanskrit verses).
|
||||
*/
|
||||
export function encodeTextFragment(text: string): string {
|
||||
const words = text.split(/\s+/).filter(Boolean);
|
||||
if (words.length === 0) return "";
|
||||
|
||||
const prefixWords = words.slice(0, 4).join(" ");
|
||||
const suffixWords = words.length > 6 ? words.slice(-4).join(" ") : "";
|
||||
const len = text.length;
|
||||
|
||||
const parts = [prefixWords];
|
||||
if (suffixWords) parts.push(suffixWords);
|
||||
parts.push(String(len));
|
||||
// Short selections (≤8 words): use the full text as prefix, no suffix needed.
|
||||
// The entire selection is specific enough to locate uniquely.
|
||||
if (words.length <= 8) {
|
||||
return `${text.trim()}§${len}`;
|
||||
}
|
||||
|
||||
return parts.join(",");
|
||||
// Longer selections: first 4 words + last 4 words + length
|
||||
const prefixWords = words.slice(0, 4).join(" ");
|
||||
const suffixWords = words.slice(-4).join(" ");
|
||||
|
||||
return `${prefixWords}§${suffixWords}§${len}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a text fragment from URL params.
|
||||
* Supports `§` (current), `|` (v2 legacy), and `,` (v1 legacy) delimiters.
|
||||
* Returns { prefix, suffix, length } or null if invalid.
|
||||
*/
|
||||
export function decodeTextFragment(
|
||||
hl: string,
|
||||
): { prefix: string; suffix: string; length: number } | null {
|
||||
const parts = hl.split(",");
|
||||
const delimiter = "§";
|
||||
const parts = hl.split(delimiter);
|
||||
if (parts.length < 2) return null;
|
||||
|
||||
const lengthStr = parts[parts.length - 1];
|
||||
const lengthStr = parts[parts.length - 1].trim();
|
||||
const length = parseInt(lengthStr, 10);
|
||||
if (isNaN(length)) return null;
|
||||
|
||||
@@ -51,7 +59,7 @@ export function decodeTextFragment(
|
||||
}
|
||||
|
||||
// prefix + suffix + length
|
||||
const prefix = parts.slice(0, -2).join(","); // in case prefix itself had commas
|
||||
const prefix = parts.slice(0, -2).join(delimiter);
|
||||
const suffix = parts[parts.length - 2];
|
||||
return { prefix, suffix, length };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user