js_lis 2.0.7 → 2.0.8
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.
- package/VirtualKeyboard.js +121 -12
- package/package.json +1 -1
package/VirtualKeyboard.js
CHANGED
|
@@ -79,15 +79,26 @@ export class VirtualKeyboard {
|
|
|
79
79
|
const target = e.target;
|
|
80
80
|
if ((target.tagName === "INPUT" || target.tagName === "TEXTAREA") && target === this.currentInput) {
|
|
81
81
|
if (!this.isVirtualKeyboardActive) {
|
|
82
|
-
this.handleRealKeyboardInput(target);
|
|
82
|
+
this.handleRealKeyboardInput(target, e);
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
});
|
|
86
86
|
|
|
87
|
-
// Add real keyboard
|
|
87
|
+
// Add real keyboard keydown listener for proper character tracking
|
|
88
88
|
document.addEventListener("keydown", (e) => {
|
|
89
89
|
const target = e.target;
|
|
90
90
|
if ((target.tagName === "INPUT" || target.tagName === "TEXTAREA") && target === this.currentInput) {
|
|
91
|
+
// Reset the virtual keyboard flag when real keyboard is used
|
|
92
|
+
if (!['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'End'].includes(e.code)) {
|
|
93
|
+
this.isVirtualKeyboardActive = false;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Handle real keyboard input
|
|
97
|
+
if (!this.isVirtualKeyboardActive) {
|
|
98
|
+
this.handleRealKeyboardKeydown(target, e);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Handle arrow keys for all input types
|
|
91
102
|
if (['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'End'].includes(e.code)) {
|
|
92
103
|
setTimeout(() => {
|
|
93
104
|
target.focus();
|
|
@@ -156,6 +167,7 @@ export class VirtualKeyboard {
|
|
|
156
167
|
|
|
157
168
|
const layoutSelector = document.createElement("select");
|
|
158
169
|
layoutSelector.id = "layout-selector";
|
|
170
|
+
layoutSelector.setAttribute("aria-label", "Select keyboard layout"); // ✅ เพิ่มบรรทัดนี้
|
|
159
171
|
layoutSelector.onchange = (e) => this.changeLayout(e.target.value);
|
|
160
172
|
|
|
161
173
|
const layouts = ["full", "en", "th", "numpad", "symbols"];
|
|
@@ -168,6 +180,7 @@ export class VirtualKeyboard {
|
|
|
168
180
|
layoutSelector.value = this.currentLayout;
|
|
169
181
|
controlsContainer.appendChild(layoutSelector);
|
|
170
182
|
|
|
183
|
+
|
|
171
184
|
keyboard.appendChild(controlsContainer);
|
|
172
185
|
|
|
173
186
|
const layout = this.layouts[this.currentLayout];
|
|
@@ -188,13 +201,14 @@ export class VirtualKeyboard {
|
|
|
188
201
|
keyElement.classList.add("concat-keys");
|
|
189
202
|
}
|
|
190
203
|
|
|
191
|
-
if (key === "
|
|
204
|
+
if (key === " ") {
|
|
192
205
|
keyElement.className += " space";
|
|
206
|
+
keyElement.innerHTML = 'ฺ';
|
|
193
207
|
}
|
|
194
208
|
|
|
195
209
|
if (key === "backspace" || key === "Backspace") {
|
|
196
210
|
keyElement.className += " backspacew";
|
|
197
|
-
keyElement.innerHTML = '<i class="fa fa-backspace"></i
|
|
211
|
+
keyElement.innerHTML = '<i class="fa fa-backspace"></i>ฺ';
|
|
198
212
|
}
|
|
199
213
|
|
|
200
214
|
keyElement.onclick = (e) => {
|
|
@@ -474,6 +488,9 @@ export class VirtualKeyboard {
|
|
|
474
488
|
this.currentInput.focus();
|
|
475
489
|
const event = new Event("input", { bubbles: true });
|
|
476
490
|
this.currentInput.dispatchEvent(event);
|
|
491
|
+
|
|
492
|
+
// Reset the flag after virtual keyboard operation is complete
|
|
493
|
+
this.isVirtualKeyboardActive = false;
|
|
477
494
|
}
|
|
478
495
|
|
|
479
496
|
// [3]
|
|
@@ -525,18 +542,110 @@ export class VirtualKeyboard {
|
|
|
525
542
|
}
|
|
526
543
|
}
|
|
527
544
|
|
|
528
|
-
// Handle real keyboard input
|
|
529
|
-
|
|
545
|
+
// Handle real keyboard keydown events to track actual input before masking
|
|
546
|
+
handleRealKeyboardKeydown(input, event) {
|
|
530
547
|
if (!input) return;
|
|
531
548
|
|
|
532
|
-
|
|
533
|
-
const
|
|
549
|
+
const key = event.key;
|
|
550
|
+
const start = input.selectionStart;
|
|
551
|
+
const end = input.selectionEnd;
|
|
552
|
+
const buffer = this.getCurrentBuffer();
|
|
553
|
+
|
|
554
|
+
// Skip modifier keys and special keys
|
|
555
|
+
if (event.ctrlKey || event.altKey || event.metaKey ||
|
|
556
|
+
['Shift', 'Control', 'Alt', 'Meta', 'CapsLock', 'Tab', 'Escape',
|
|
557
|
+
'ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'End',
|
|
558
|
+
'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12'].includes(key)) {
|
|
559
|
+
return;
|
|
560
|
+
}
|
|
534
561
|
|
|
535
|
-
|
|
536
|
-
|
|
562
|
+
let newBuffer = buffer;
|
|
563
|
+
|
|
564
|
+
if (key === 'Backspace') {
|
|
565
|
+
if (start === end && start > 0) {
|
|
566
|
+
// Single character deletion
|
|
567
|
+
newBuffer = buffer.slice(0, start - 1) + buffer.slice(start);
|
|
568
|
+
} else if (start !== end) {
|
|
569
|
+
// Range deletion
|
|
570
|
+
newBuffer = buffer.slice(0, start) + buffer.slice(end);
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
// Prevent default and update manually
|
|
574
|
+
event.preventDefault();
|
|
575
|
+
this.setCurrentBuffer(newBuffer);
|
|
576
|
+
this.updateDisplayedValue(false);
|
|
577
|
+
|
|
578
|
+
// Set cursor position
|
|
579
|
+
const newCursorPos = start === end ? Math.max(0, start - 1) : start;
|
|
580
|
+
setTimeout(() => {
|
|
581
|
+
input.setSelectionRange(newCursorPos, newCursorPos);
|
|
582
|
+
input.focus();
|
|
583
|
+
}, 0);
|
|
584
|
+
|
|
585
|
+
} else if (key === 'Delete') {
|
|
586
|
+
if (start === end && start < buffer.length) {
|
|
587
|
+
// Single character deletion forward
|
|
588
|
+
newBuffer = buffer.slice(0, start) + buffer.slice(start + 1);
|
|
589
|
+
} else if (start !== end) {
|
|
590
|
+
// Range deletion
|
|
591
|
+
newBuffer = buffer.slice(0, start) + buffer.slice(end);
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
// Prevent default and update manually
|
|
595
|
+
event.preventDefault();
|
|
596
|
+
this.setCurrentBuffer(newBuffer);
|
|
597
|
+
this.updateDisplayedValue(false);
|
|
598
|
+
|
|
599
|
+
// Set cursor position
|
|
600
|
+
setTimeout(() => {
|
|
601
|
+
input.setSelectionRange(start, start);
|
|
602
|
+
input.focus();
|
|
603
|
+
}, 0);
|
|
604
|
+
|
|
605
|
+
} else if (key === 'Enter') {
|
|
606
|
+
if (input.tagName === 'TEXTAREA') {
|
|
607
|
+
newBuffer = buffer.slice(0, start) + '\n' + buffer.slice(end);
|
|
608
|
+
|
|
609
|
+
// Prevent default and update manually
|
|
610
|
+
event.preventDefault();
|
|
611
|
+
this.setCurrentBuffer(newBuffer);
|
|
612
|
+
this.updateDisplayedValue(false);
|
|
613
|
+
|
|
614
|
+
// Set cursor position
|
|
615
|
+
const newCursorPos = start + 1;
|
|
616
|
+
setTimeout(() => {
|
|
617
|
+
input.setSelectionRange(newCursorPos, newCursorPos);
|
|
618
|
+
input.focus();
|
|
619
|
+
}, 0);
|
|
620
|
+
}
|
|
621
|
+
// For input fields, let the default behavior handle form submission
|
|
622
|
+
|
|
623
|
+
} else if (key.length === 1) {
|
|
624
|
+
// Regular character input
|
|
625
|
+
newBuffer = buffer.slice(0, start) + key + buffer.slice(end);
|
|
626
|
+
|
|
627
|
+
// Prevent default and update manually
|
|
628
|
+
event.preventDefault();
|
|
629
|
+
this.setCurrentBuffer(newBuffer);
|
|
630
|
+
this.updateDisplayedValue(false);
|
|
631
|
+
|
|
632
|
+
// Set cursor position
|
|
633
|
+
const newCursorPos = start + key.length;
|
|
634
|
+
setTimeout(() => {
|
|
635
|
+
input.setSelectionRange(newCursorPos, newCursorPos);
|
|
636
|
+
input.focus();
|
|
637
|
+
}, 0);
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
// Handle real keyboard input and encrypt it (simplified version)
|
|
642
|
+
handleRealKeyboardInput(input, event) {
|
|
643
|
+
if (!input) return;
|
|
537
644
|
|
|
538
|
-
//
|
|
539
|
-
|
|
645
|
+
// For most cases, the keydown handler already took care of updating the buffer
|
|
646
|
+
// This method now just ensures the encryption is up to date
|
|
647
|
+
const currentBuffer = this.getCurrentBuffer();
|
|
648
|
+
this.updateDomEncrypted(input, currentBuffer);
|
|
540
649
|
}
|
|
541
650
|
|
|
542
651
|
// Helper: encrypt and store ciphertext in DOM attribute
|