Spaces:
Runtime error
Runtime error
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"]
|