marathi_typing 0.1.3 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8f9141d8b16760161d8c02f9611f2b28faf4c51430bf02dc4c9ea958cd5aa2c6
|
4
|
+
data.tar.gz: d080cc2cdc1cd09aac409e3dee8d069205f3582950aefe0828787f96c08071ee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d0cbb74bb7d19520fdd564cc6eeaecca4504d96cbcf0638e4c50f9c13f94cb627bb600d7afa5e13dd28e69790dc6a765dbf81dfe6fd3db79e964101b8d7ba4ed
|
7
|
+
data.tar.gz: 37d6525b0e2d1e04152d79e710666f18fd5feb208e18852e0de93dd9c55a0b46f44437ea475974f0b03cbc6b470b61e3748c96810ce905231ea50cab9b4e48f1
|
@@ -1,7 +1,8 @@
|
|
1
1
|
import { Controller } from "@hotwired/stimulus"
|
2
2
|
|
3
3
|
export default class extends Controller {
|
4
|
-
static targets = ["input"]
|
4
|
+
static targets = ["input"];
|
5
|
+
|
5
6
|
timeout = null
|
6
7
|
|
7
8
|
|
@@ -14,16 +15,13 @@ export default class extends Controller {
|
|
14
15
|
this.suggestionsTarget = this.buildSuggestionsBox()
|
15
16
|
|
16
17
|
input.addEventListener("keydown", (e) => {
|
17
|
-
|
18
18
|
if (e.key === " ") {
|
19
19
|
this.skipNextSuggestionFetch = true;
|
20
20
|
}
|
21
21
|
});
|
22
22
|
|
23
23
|
input.addEventListener("input", (e) => {
|
24
|
-
|
25
24
|
if (this.skipNextSuggestionFetch) {
|
26
|
-
|
27
25
|
this.skipNextSuggestionFetch = false;
|
28
26
|
return;
|
29
27
|
}
|
@@ -33,13 +31,11 @@ export default class extends Controller {
|
|
33
31
|
input.addEventListener("keyup", (e) => {
|
34
32
|
|
35
33
|
if (e.key === " ") {
|
36
|
-
|
37
34
|
this.selectFirstSuggestion();
|
38
35
|
}
|
39
36
|
});
|
40
37
|
|
41
38
|
document.addEventListener("click", this.handleClickOutside);
|
42
|
-
|
43
39
|
}
|
44
40
|
|
45
41
|
fetchSuggestions(event) {
|
@@ -48,14 +44,21 @@ export default class extends Controller {
|
|
48
44
|
|
49
45
|
clearTimeout(this.timeout)
|
50
46
|
this.timeout = setTimeout(() => {
|
51
|
-
const lastWord = value.split(" ").pop()
|
52
47
|
|
53
|
-
|
48
|
+
const { word: currentWord } = this.getCurrentWordAtCursor(this.inputTarget);
|
49
|
+
|
50
|
+
console.log("currentWord: ", currentWord)
|
51
|
+
|
52
|
+
if (!currentWord || !/^[a-zA-Z]+$/.test(currentWord)) return;
|
53
|
+
// if (!currentWord) return;
|
54
|
+
|
55
|
+
|
56
|
+
fetch(`${this.apiUrl}?text=${currentWord}&itc=mr-t-i0-und&num=5&cp=0&cs=1&ie=utf-8&oe=utf-8&app=demopage`)
|
54
57
|
.then(res => res.json())
|
55
58
|
.then(data => {
|
56
59
|
if (data[0] === "SUCCESS") {
|
57
60
|
const suggestions = data[1][0][1]
|
58
|
-
this.showSuggestions(suggestions,
|
61
|
+
this.showSuggestions(suggestions, currentWord)
|
59
62
|
}
|
60
63
|
})
|
61
64
|
}, 300)
|
@@ -66,13 +69,12 @@ export default class extends Controller {
|
|
66
69
|
const box = document.createElement("div")
|
67
70
|
box.className = "marathi-suggestions";
|
68
71
|
box.style.position = "absolute";
|
69
|
-
box.style.background = "#
|
72
|
+
box.style.background = "#808080";
|
70
73
|
box.style.border = "0px solid #ccc";
|
71
74
|
box.style.zIndex = "9999";
|
72
75
|
box.style.padding = "0px";
|
73
76
|
box.style.color = "black";
|
74
77
|
|
75
|
-
// Get the position of the input field
|
76
78
|
const rect = this.inputTarget.getBoundingClientRect();
|
77
79
|
const scrollOffset = window.scrollY || window.pageYOffset;
|
78
80
|
|
@@ -85,10 +87,7 @@ export default class extends Controller {
|
|
85
87
|
}
|
86
88
|
|
87
89
|
showSuggestions(suggestions, lastWord) {
|
88
|
-
this.
|
89
|
-
this.suggestionsTarget.style.border = "1px solid #ccc";
|
90
|
-
this.suggestionsTarget.style.border = "4px";
|
91
|
-
|
90
|
+
this.showSuggestionsBox();
|
92
91
|
|
93
92
|
suggestions.forEach(suggestion => {
|
94
93
|
const option = document.createElement("div")
|
@@ -107,37 +106,55 @@ export default class extends Controller {
|
|
107
106
|
this.suggestionsTarget.appendChild(originalOption);
|
108
107
|
}
|
109
108
|
|
110
|
-
selectFirstSuggestion() {
|
111
109
|
|
110
|
+
|
111
|
+
selectFirstSuggestion() {
|
112
112
|
if (!this.suggestionsTarget || this.suggestionsTarget.children.length === 0) return;
|
113
113
|
|
114
114
|
const firstOption = this.suggestionsTarget.querySelector(".marathi-suggestion");
|
115
115
|
|
116
116
|
if (firstOption) {
|
117
117
|
const suggestion = firstOption.textContent;
|
118
|
-
const
|
119
|
-
|
120
|
-
|
118
|
+
const input = this.inputTarget;
|
119
|
+
let { word: currentWord } = this.getCurrentWordAtCursor(input);
|
120
|
+
|
121
|
+
// If space was pressed, caret is after the space => no current word
|
122
|
+
if (!currentWord) {
|
123
|
+
const valueBeforeCursor = input.value.slice(0, input.selectionStart).trimEnd();
|
124
|
+
const words = valueBeforeCursor.split(/\s+/);
|
125
|
+
currentWord = words[words.length - 1] || "";
|
126
|
+
}
|
127
|
+
|
128
|
+
|
129
|
+
if (!currentWord) return;
|
130
|
+
|
131
|
+
console.log("currentWord:", currentWord, " suggestion:", suggestion);
|
132
|
+
|
133
|
+
|
134
|
+
this.selectSuggestion(suggestion, currentWord);
|
121
135
|
}
|
122
136
|
}
|
123
137
|
|
138
|
+
selectSuggestion(selected, originalWord) {
|
139
|
+
const input = this.inputTarget;
|
140
|
+
const { wordStart, wordEnd } = this.getCurrentWordAtCursor(input);
|
124
141
|
|
125
|
-
|
126
|
-
let currentValue = this.inputTarget.value;
|
127
|
-
const trailingSpace = currentValue.endsWith(" ") ? " " : "";
|
142
|
+
if (wordStart == null || wordEnd == null) return;
|
128
143
|
|
129
|
-
|
130
|
-
currentValue = currentValue.trimEnd();
|
144
|
+
const value = input.value;
|
131
145
|
|
132
|
-
//
|
133
|
-
const newValue =
|
146
|
+
// Reconstruct the value with the selected word
|
147
|
+
const newValue = value.slice(0, wordStart) + selected + value.slice(wordEnd);
|
134
148
|
|
135
|
-
//
|
136
|
-
|
149
|
+
// Update the input value and set caret after inserted suggestion
|
150
|
+
input.value = newValue;
|
151
|
+
|
152
|
+
// Move caret to after the inserted suggestion
|
153
|
+
const caretPos = wordStart + selected.length;
|
154
|
+
input.setSelectionRange(caretPos, caretPos);
|
155
|
+
|
156
|
+
this.hideSuggestions();
|
137
157
|
|
138
|
-
this.suggestionsTarget.innerHTML = "";
|
139
|
-
this.suggestionsTarget.style.border = "0";
|
140
|
-
this.suggestionsTarget.style.padding = "0";
|
141
158
|
}
|
142
159
|
|
143
160
|
handleClickOutside = (event) => {
|
@@ -145,12 +162,56 @@ export default class extends Controller {
|
|
145
162
|
const isClickInsideSuggestions = this.suggestionsTarget?.contains(event.target);
|
146
163
|
|
147
164
|
if (!isClickInsideInput && !isClickInsideSuggestions) {
|
148
|
-
this.
|
149
|
-
this.suggestionsTarget.style.border = "0";
|
150
|
-
this.suggestionsTarget.style.padding = "0";
|
165
|
+
this.hideSuggestions();
|
151
166
|
}
|
152
167
|
};
|
153
168
|
|
154
169
|
|
155
|
-
|
170
|
+
getCurrentWordAtCursor(input) {
|
171
|
+
const value = input.value;
|
172
|
+
let cursorPos = input.selectionStart;
|
173
|
+
|
174
|
+
// If cursor is just after a space, move it back to find previous word
|
175
|
+
if (cursorPos > 0 && value[cursorPos - 1] === " ") {
|
176
|
+
cursorPos--;
|
177
|
+
}
|
178
|
+
|
179
|
+
// Skip any Devanagari characters while going backwards
|
180
|
+
let wordStart = cursorPos;
|
181
|
+
while (
|
182
|
+
wordStart > 0 &&
|
183
|
+
value[wordStart - 1].match(/[a-zA-Z0-9]/) // Only count English letters and numbers
|
184
|
+
) {
|
185
|
+
wordStart--;
|
186
|
+
}
|
187
|
+
|
188
|
+
// Skip Devanagari going forward too
|
189
|
+
let wordEnd = cursorPos;
|
190
|
+
while (
|
191
|
+
wordEnd < value.length &&
|
192
|
+
value[wordEnd].match(/[a-zA-Z0-9]/)
|
193
|
+
) {
|
194
|
+
wordEnd++;
|
195
|
+
}
|
196
|
+
|
197
|
+
|
198
|
+
let word = value.slice(wordStart, wordEnd);
|
199
|
+
|
200
|
+
return { word, wordStart, wordEnd };
|
201
|
+
}
|
156
202
|
|
203
|
+
|
204
|
+
|
205
|
+
hideSuggestions() {
|
206
|
+
this.suggestionsTarget.innerHTML = "";
|
207
|
+
this.suggestionsTarget.style.border = "0";
|
208
|
+
this.suggestionsTarget.style.padding = "0";
|
209
|
+
}
|
210
|
+
|
211
|
+
showSuggestionsBox() {
|
212
|
+
this.suggestionsTarget.innerHTML = "";
|
213
|
+
this.suggestionsTarget.style.border = "1px solid #0a0a0a";
|
214
|
+
this.suggestionsTarget.style.padding = "4px";
|
215
|
+
}
|
216
|
+
|
217
|
+
}
|