Remove highlight upon entering span
Browse files- .gitignore +9 -0
- src/frontend/HighlightedTextbox.svelte +33 -2
- src/frontend/utils.ts +36 -0
- src/pyproject.toml +1 -1
.gitignore
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.eggs/
|
| 2 |
+
dist/
|
| 3 |
+
*.pyc
|
| 4 |
+
__pycache__/
|
| 5 |
+
*.py[cod]
|
| 6 |
+
*$py.class
|
| 7 |
+
__tmp/*
|
| 8 |
+
*.pyi
|
| 9 |
+
node_modules
|
src/frontend/HighlightedTextbox.svelte
CHANGED
|
@@ -10,7 +10,7 @@
|
|
| 10 |
import { fade } from "svelte/transition";
|
| 11 |
import type { SelectData } from "@gradio/utils";
|
| 12 |
import { get_next_color } from "@gradio/utils";
|
| 13 |
-
import { correct_color_map } from "./utils";
|
| 14 |
|
| 15 |
const browser = typeof document !== "undefined";
|
| 16 |
export let value: [string, string | null][] = [];
|
|
@@ -146,6 +146,33 @@
|
|
| 146 |
copied = false;
|
| 147 |
}, 1000);
|
| 148 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 149 |
</script>
|
| 150 |
|
| 151 |
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
@@ -208,6 +235,10 @@
|
|
| 208 |
on:input
|
| 209 |
on:focus
|
| 210 |
on:change
|
|
|
|
|
|
|
|
|
|
|
|
|
| 211 |
/>
|
| 212 |
{/if}
|
| 213 |
</label>
|
|
@@ -280,7 +311,7 @@
|
|
| 280 |
font-size: var(--input-text-size);
|
| 281 |
width: 100%;
|
| 282 |
line-height: var(--line-sm);
|
| 283 |
-
word-break: break-
|
| 284 |
border: var(--input-border-width) solid var(--input-border-color);
|
| 285 |
cursor: text;
|
| 286 |
}
|
|
|
|
| 10 |
import { fade } from "svelte/transition";
|
| 11 |
import type { SelectData } from "@gradio/utils";
|
| 12 |
import { get_next_color } from "@gradio/utils";
|
| 13 |
+
import { correct_color_map, getParentCursorPosition, getNodeAndOffset } from "./utils";
|
| 14 |
|
| 15 |
const browser = typeof document !== "undefined";
|
| 16 |
export let value: [string, string | null][] = [];
|
|
|
|
| 146 |
copied = false;
|
| 147 |
}, 1000);
|
| 148 |
}
|
| 149 |
+
|
| 150 |
+
// Method to remove highlight if cursor is inside
|
| 151 |
+
function checkAndRemoveHighlight() {
|
| 152 |
+
const selection = window.getSelection();
|
| 153 |
+
const cursorPosition = selection.anchorOffset;
|
| 154 |
+
if (selection.rangeCount > 0) {
|
| 155 |
+
var currParent = selection.getRangeAt(0).commonAncestorContainer.parentElement;
|
| 156 |
+
if (currParent && currParent.tagName.toLowerCase() === 'mark') {
|
| 157 |
+
const text = currParent.textContent;
|
| 158 |
+
// replace the mark tag with its text content
|
| 159 |
+
var textContainer = currParent.parentElement;
|
| 160 |
+
var newTextNode = document.createTextNode(text);
|
| 161 |
+
textContainer.replaceChild(newTextNode, currParent);
|
| 162 |
+
marked_el_text = textContainer.innerHTML;
|
| 163 |
+
// set the cursor position to the same position as before
|
| 164 |
+
var range = document.createRange()
|
| 165 |
+
var newSelection = window.getSelection()
|
| 166 |
+
const newCursorPosition = cursorPosition + getParentCursorPosition(textContainer)
|
| 167 |
+
var nodeAndOffset = getNodeAndOffset(textContainer, newCursorPosition);
|
| 168 |
+
range.setStart(nodeAndOffset.node, nodeAndOffset.offset);
|
| 169 |
+
range.setEnd(nodeAndOffset.node, nodeAndOffset.offset);
|
| 170 |
+
newSelection.removeAllRanges();
|
| 171 |
+
newSelection.addRange(range);
|
| 172 |
+
handle_blur();
|
| 173 |
+
}
|
| 174 |
+
}
|
| 175 |
+
}
|
| 176 |
</script>
|
| 177 |
|
| 178 |
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
|
|
| 235 |
on:input
|
| 236 |
on:focus
|
| 237 |
on:change
|
| 238 |
+
on:mousedown={checkAndRemoveHighlight}
|
| 239 |
+
on:keydown={checkAndRemoveHighlight}
|
| 240 |
+
on:mouseup={checkAndRemoveHighlight}
|
| 241 |
+
on:keyup={checkAndRemoveHighlight}
|
| 242 |
/>
|
| 243 |
{/if}
|
| 244 |
</label>
|
|
|
|
| 311 |
font-size: var(--input-text-size);
|
| 312 |
width: 100%;
|
| 313 |
line-height: var(--line-sm);
|
| 314 |
+
word-break: break-word;
|
| 315 |
border: var(--input-border-width) solid var(--input-border-color);
|
| 316 |
cursor: text;
|
| 317 |
}
|
src/frontend/utils.ts
CHANGED
|
@@ -71,4 +71,40 @@ export function merge_elements(
|
|
| 71 |
}
|
| 72 |
|
| 73 |
return result;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 74 |
}
|
|
|
|
| 71 |
}
|
| 72 |
|
| 73 |
return result;
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
|
| 77 |
+
export function getParentCursorPosition(textbox) {
|
| 78 |
+
const selection = window.getSelection()!;
|
| 79 |
+
if (selection.rangeCount > 0) {
|
| 80 |
+
const range = document.createRange();
|
| 81 |
+
range.setStart(textbox, 0);
|
| 82 |
+
if (selection.anchorNode !== null) {
|
| 83 |
+
range.setEnd(selection.anchorNode, selection.anchorOffset);
|
| 84 |
+
}
|
| 85 |
+
const cursorPosition = range.toString().length;
|
| 86 |
+
return cursorPosition;
|
| 87 |
+
}
|
| 88 |
+
return -1;
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
export function getNodeAndOffset(root, index) {
|
| 92 |
+
var walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
|
| 93 |
+
var node = walker.nextNode();
|
| 94 |
+
if (!node || !node.textContent) {
|
| 95 |
+
// empty root node
|
| 96 |
+
return null;
|
| 97 |
+
}
|
| 98 |
+
var runningTotal = node.textContent.length;
|
| 99 |
+
while (runningTotal < index) {
|
| 100 |
+
node = walker.nextNode();
|
| 101 |
+
if (node && node.textContent) {
|
| 102 |
+
runningTotal += node.textContent.length;
|
| 103 |
+
} else {
|
| 104 |
+
// index is out of range
|
| 105 |
+
return null;
|
| 106 |
+
}
|
| 107 |
+
}
|
| 108 |
+
var offset = node.textContent.length - (runningTotal - index);
|
| 109 |
+
return { node: node, offset: offset };
|
| 110 |
}
|
src/pyproject.toml
CHANGED
|
@@ -36,7 +36,7 @@ classifiers = [
|
|
| 36 |
dev = ["build", "twine"]
|
| 37 |
|
| 38 |
[tool.hatch.build]
|
| 39 |
-
artifacts = ["/backend/gradio_highlightedtextbox/templates", "*.pyi", "backend/gradio_highlightedtextbox/templates", "backend/gradio_highlightedtextbox/templates"]
|
| 40 |
|
| 41 |
[tool.hatch.build.targets.wheel]
|
| 42 |
packages = ["/backend/gradio_highlightedtextbox"]
|
|
|
|
| 36 |
dev = ["build", "twine"]
|
| 37 |
|
| 38 |
[tool.hatch.build]
|
| 39 |
+
artifacts = ["/backend/gradio_highlightedtextbox/templates", "*.pyi", "backend/gradio_highlightedtextbox/templates", "backend/gradio_highlightedtextbox/templates", "Users/gsarti/Documents/projects/highlightedtextbox/backend/gradio_highlightedtextbox/templates", "Users/gsarti/Documents/projects/highlightedtextbox/backend/gradio_highlightedtextbox/templates"]
|
| 40 |
|
| 41 |
[tool.hatch.build.targets.wheel]
|
| 42 |
packages = ["/backend/gradio_highlightedtextbox"]
|