js_lis 1.0.22 → 1.0.24

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.
Files changed (2) hide show
  1. package/VirtualKeyboard.js +551 -490
  2. package/package.json +1 -1
@@ -1,547 +1,608 @@
1
- import { layouts } from './layouts.js';
1
+ import { layouts } from "./layouts.js";
2
2
 
3
3
  export class VirtualKeyboard {
4
- constructor() {
5
- this.currentLayout = 'en';
6
- this.isVisible = false;
7
- this.container = document.getElementById('keyboard-container');
8
- this.currentInput = null;
9
- this.layouts = layouts;
10
- this.isDragging = false;
11
- this.offsetX = 0;
12
- this.offsetY = 0;
13
- this.shiftActive = false;
14
- this.capsLockActive = false;
15
-
16
- // กำหนดคีย์และ IV สำหรับการเข้ารหัส
17
- this.secretKey = '1234567890abcdef1234567890abcdef'; // คีย์ความยาว 32 bytes
18
- this.iv = CryptoJS.lib.WordArray.random(16); // สร้าง IV ความยาว 16 bytes
19
-
20
- this.initialize();
21
- }
4
+ constructor() {
5
+ this.currentLayout = "en";
6
+ this.isVisible = false;
7
+ this.container = document.getElementById("keyboard-container");
8
+ this.currentInput = null;
9
+ this.layouts = layouts;
10
+ this.isDragging = false;
11
+ this.offsetX = 0;
12
+ this.offsetY = 0;
13
+ this.shiftActive = false;
14
+ this.capsLockActive = false;
15
+
16
+ // กำหนดคีย์และ IV สำหรับการเข้ารหัส
17
+ this.secretKey = "1234567890abcdef1234567890abcdef"; // คีย์ความยาว 32 bytes
18
+ this.iv = CryptoJS.lib.WordArray.random(16); // สร้าง IV ความยาว 16 bytes
19
+
20
+ this.initialize();
21
+ }
22
22
 
23
- async initialize() {
24
- try {
25
- this.render();
26
- this.initializeInputListeners();
27
- console.log("VirtualKeyboard initialized successfully.");
28
- } catch (error) {
29
- console.error("Error initializing VirtualKeyboard:", error);
30
- }
23
+ async initialize() {
24
+ try {
25
+ this.render();
26
+ this.initializeInputListeners();
27
+ console.log("VirtualKeyboard initialized successfully.");
28
+ } catch (error) {
29
+ console.error("Error initializing VirtualKeyboard:", error);
31
30
  }
31
+ }
32
32
 
33
- encodeText(text) {
34
- const encrypted = CryptoJS.AES.encrypt(text, CryptoJS.enc.Hex.parse(this.secretKey), {
35
- iv: this.iv,
36
- mode: CryptoJS.mode.CBC,
37
- padding: CryptoJS.pad.Pkcs7
38
- });
39
- return {
40
- encrypted: encrypted.ciphertext.toString(CryptoJS.enc.Base64),
41
- iv: this.iv.toString(CryptoJS.enc.Base64)
42
- };
43
- }
33
+ encodeText(text) {
34
+ const encrypted = CryptoJS.AES.encrypt(
35
+ text,
36
+ CryptoJS.enc.Hex.parse(this.secretKey),
37
+ {
38
+ iv: this.iv,
39
+ mode: CryptoJS.mode.CBC,
40
+ padding: CryptoJS.pad.Pkcs7,
41
+ }
42
+ );
43
+ return {
44
+ encrypted: encrypted.ciphertext.toString(CryptoJS.enc.Base64),
45
+ iv: this.iv.toString(CryptoJS.enc.Base64),
46
+ };
47
+ }
44
48
 
45
- decodeText(encryptedData) {
46
- if (!encryptedData || !encryptedData.encrypted || !encryptedData.iv) {
47
- if (encryptedData === "\t") {
48
- return "\t";
49
- } else {
50
- return " ";
51
- }
52
- }
53
-
54
- try {
55
- const decrypted = CryptoJS.AES.decrypt(
56
- { ciphertext: CryptoJS.enc.Base64.parse(encryptedData.encrypted) },
57
- CryptoJS.enc.Hex.parse(this.secretKey),
58
- {
59
- iv: CryptoJS.enc.Base64.parse(encryptedData.iv),
60
- mode: CryptoJS.mode.CBC,
61
- padding: CryptoJS.pad.Pkcs7
62
- }
63
- );
64
- return decrypted.toString(CryptoJS.enc.Utf8);
65
- } catch (error) {
66
- console.error("Error decoding text:", error);
49
+ decodeText(encryptedData) {
50
+ if (!encryptedData || !encryptedData.encrypted || !encryptedData.iv) {
51
+ if (encryptedData === "\t") {
52
+ return "\t";
53
+ } else {
67
54
  return " ";
68
55
  }
69
56
  }
70
-
71
-
72
-
73
- getLayoutName(layout) {
74
- switch (layout) {
75
- case 'en': return 'English Keyboard';
76
- case 'enSc': return 'English scrambled';
77
- case 'th': return 'Thai keyboard';
78
- case 'thSc': return 'Thai scrambled';
79
- case 'numpad': return 'Numpad Keyboard';
80
- case 'scNum': return 'Scrambled Keyboard';
81
- default: return 'Unknown Layout';
57
+
58
+ try {
59
+ const decrypted = CryptoJS.AES.decrypt(
60
+ { ciphertext: CryptoJS.enc.Base64.parse(encryptedData.encrypted) },
61
+ CryptoJS.enc.Hex.parse(this.secretKey),
62
+ {
63
+ iv: CryptoJS.enc.Base64.parse(encryptedData.iv),
64
+ mode: CryptoJS.mode.CBC,
65
+ padding: CryptoJS.pad.Pkcs7,
82
66
  }
67
+ );
68
+ return decrypted.toString(CryptoJS.enc.Utf8);
69
+ } catch (error) {
70
+ console.error("Error decoding text:", error);
71
+ return " ";
83
72
  }
73
+ }
84
74
 
85
- initializeInputListeners() {
86
- document.addEventListener('click', (e) => {
87
- const target = e.target;
88
- if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA') {
89
- this.setCurrentInput(target);
90
- }
91
- });
92
-
93
- document.addEventListener('focus', (e) => {
94
- const target = e.target;
95
- if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA') {
96
- this.setCurrentInput(target);
97
- }
98
- }, true);
99
-
100
- const toggle = document.getElementById("toggle");
101
- if (toggle) {
102
- toggle.addEventListener('click', this.toggle.bind(this));
103
- }
75
+ getLayoutName(layout) {
76
+ switch (layout) {
77
+ case "en":
78
+ return "English Keyboard";
79
+ case "enSc":
80
+ return "English scrambled";
81
+ case "th":
82
+ return "Thai keyboard";
83
+ case "thSc":
84
+ return "Thai scrambled";
85
+ case "numpad":
86
+ return "Numpad Keyboard";
87
+ case "scNum":
88
+ return "Scrambled Keyboard";
89
+ default:
90
+ return "Unknown Layout";
104
91
  }
92
+ }
105
93
 
106
- setCurrentInput(inputElement) {
107
- if (this.currentInput) {
108
- this.currentInput.classList.remove('keyboard-active');
94
+ initializeInputListeners() {
95
+ document.addEventListener("click", (e) => {
96
+ const target = e.target;
97
+ if (target.tagName === "INPUT" || target.tagName === "TEXTAREA") {
98
+ this.setCurrentInput(target);
99
+ }
100
+ });
101
+
102
+ document.addEventListener(
103
+ "focus",
104
+ (e) => {
105
+ const target = e.target;
106
+ if (target.tagName === "INPUT" || target.tagName === "TEXTAREA") {
107
+ this.setCurrentInput(target);
109
108
  }
109
+ },
110
+ true
111
+ );
110
112
 
111
- this.currentInput = inputElement;
112
- this.currentInput.classList.add('keyboard-active');
113
+ const toggle = document.getElementById("toggle");
114
+ if (toggle) {
115
+ toggle.addEventListener("click", this.toggle.bind(this));
113
116
  }
117
+ }
114
118
 
115
- render() {
116
- const keyboard = document.createElement('div');
117
- keyboard.className = 'virtual-keyboard';
118
- keyboard.style.display = this.isVisible ? 'block' : 'none';
119
- keyboard.id = 'keyboard';
120
-
121
- const controlsContainer = document.createElement('div');
122
- controlsContainer.className = 'controls';
123
- controlsContainer.style.display = 'flex';
124
- controlsContainer.style.justifyContent = 'center';
125
- controlsContainer.style.alignItems = 'center';
126
- controlsContainer.style.marginBottom = '10px';
127
-
128
- const layoutSelector = document.createElement('select');
129
- layoutSelector.id = 'layout-selector';
130
- layoutSelector.onchange = (e) => this.changeLayout(e.target.value);
131
-
132
- const layouts = ['en', 'enSc', 'th', 'thSc', 'numpad', 'scNum'];
133
- layouts.forEach(layout => {
134
- const option = document.createElement('option');
135
- option.value = layout;
136
- option.innerText = this.getLayoutName(layout);
137
- layoutSelector.appendChild(option);
138
- });
139
- layoutSelector.value = this.currentLayout;
140
- controlsContainer.appendChild(layoutSelector);
141
-
142
- keyboard.appendChild(controlsContainer);
143
-
144
- const layout = this.layouts[this.currentLayout];
145
-
146
- layout.forEach(row => {
147
- const rowElement = document.createElement('div');
148
- rowElement.className = 'keyboard-row';
149
-
150
- row.forEach(key => {
151
- const keyElement = document.createElement('button');
152
- keyElement.className = 'keyboard-key key';
153
- keyElement.textContent = key;
154
- keyElement.type = 'button';
155
-
156
- keyElement.dataset.key = key;
157
-
158
- if (key === 'Space') {
159
- keyElement.className += ' space';
160
- }
161
-
162
- if (key === 'backspace' || key === 'Backspace') {
163
- keyElement.className += ' backspacew';
164
- keyElement.innerHTML = '<i class="fa fa-backspace"></i>';
165
- }
166
-
167
-
168
- keyElement.onclick = (e) => {
169
- e.preventDefault();
170
- const keyPressed = keyElement.dataset.key || keyElement.textContent;
171
- if (keyPressed) {
172
- this.handleKeyPress(keyPressed);
173
- } else {
174
- console.error("The key element does not have a valid key value.");
175
- }
176
- };
177
-
178
- rowElement.appendChild(keyElement);
179
- });
180
-
181
- keyboard.appendChild(rowElement);
182
- });
183
-
184
- this.container.innerHTML = '';
185
- this.container.appendChild(keyboard);
186
-
187
- if (this.currentLayout === "scNum") {
188
- this.scrambleKeyboard();
189
- }
119
+ setCurrentInput(inputElement) {
120
+ if (this.currentInput) {
121
+ this.currentInput.classList.remove("keyboard-active");
122
+ }
123
+
124
+ this.currentInput = inputElement;
125
+ this.currentInput.classList.add("keyboard-active");
126
+ }
190
127
 
191
- if (this.currentLayout === "enSc") {
192
- this.scrambleEnglishKeys();
128
+ render() {
129
+ const keyboard = document.createElement("div");
130
+ keyboard.className = "virtual-keyboard";
131
+ keyboard.style.display = this.isVisible ? "block" : "none";
132
+ keyboard.id = "keyboard";
133
+
134
+ const controlsContainer = document.createElement("div");
135
+ controlsContainer.className = "controls";
136
+ controlsContainer.style.display = "flex";
137
+ controlsContainer.style.justifyContent = "center";
138
+ controlsContainer.style.alignItems = "center";
139
+ controlsContainer.style.marginBottom = "10px";
140
+
141
+ const layoutSelector = document.createElement("select");
142
+ layoutSelector.id = "layout-selector";
143
+ layoutSelector.onchange = (e) => this.changeLayout(e.target.value);
144
+
145
+ const layouts = ["en", "enSc", "th", "thSc", "numpad", "scNum"];
146
+ layouts.forEach((layout) => {
147
+ const option = document.createElement("option");
148
+ option.value = layout;
149
+ option.innerText = this.getLayoutName(layout);
150
+ layoutSelector.appendChild(option);
151
+ });
152
+ layoutSelector.value = this.currentLayout;
153
+ controlsContainer.appendChild(layoutSelector);
154
+
155
+ keyboard.appendChild(controlsContainer);
156
+
157
+ const layout = this.layouts[this.currentLayout];
158
+
159
+ layout.forEach((row) => {
160
+ const rowElement = document.createElement("div");
161
+ rowElement.className = "keyboard-row";
162
+
163
+ row.forEach((key) => {
164
+ const keyElement = document.createElement("button");
165
+ keyElement.className = "keyboard-key key";
166
+ keyElement.textContent = key;
167
+ keyElement.type = "button";
168
+
169
+ keyElement.dataset.key = key;
170
+
171
+ if (key === "Space") {
172
+ keyElement.className += " space";
193
173
  }
194
174
 
195
- if (this.currentLayout === "thSc") {
196
- this.scrambleThaiKeys();
175
+ if (key === "backspace" || key === "Backspace") {
176
+ keyElement.className += " backspacew";
177
+ keyElement.innerHTML = '<i class="fa fa-backspace"></i>';
197
178
  }
198
179
 
199
- keyboard.addEventListener('mousedown', (event) => this.startDrag(event));
200
- }
180
+ keyElement.onclick = (e) => {
181
+ e.preventDefault();
182
+ const keyPressed = keyElement.dataset.key || keyElement.textContent;
183
+ if (keyPressed) {
184
+ this.handleKeyPress(keyPressed);
185
+ } else {
186
+ console.error("The key element does not have a valid key value.");
187
+ }
188
+ };
201
189
 
202
- async handleKeyPress(keyPressed) {
203
- if (!this.currentInput) return;
190
+ rowElement.appendChild(keyElement);
191
+ });
204
192
 
205
- const start = this.currentInput.selectionStart;
206
- const end = this.currentInput.selectionEnd;
207
- const value = this.currentInput.value;
193
+ keyboard.appendChild(rowElement);
194
+ });
208
195
 
209
- const isCapsActive = this.capsLockActive;
210
- const isShiftActive = this.shiftActive;
196
+ this.container.innerHTML = "";
197
+ this.container.appendChild(keyboard);
211
198
 
212
- const convertToCorrectCase = (char) => {
213
- if (isCapsActive || isShiftActive) {
214
- return char.toUpperCase();
215
- }
216
- return char.toLowerCase();
217
- };
199
+ if (this.currentLayout === "scNum") {
200
+ this.scrambleKeyboard();
201
+ }
218
202
 
219
- if (!keyPressed) {
220
- console.error("Invalid key pressed.");
221
- return;
222
- }
203
+ if (this.currentLayout === "enSc") {
204
+ this.scrambleEnglishKeys();
205
+ }
223
206
 
224
- switch(keyPressed) {
225
- case 'Backspace':
226
- case 'backspace':
227
- if (start === end && start > 0) {
228
- this.currentInput.value = value.slice(0, start - 1) + value.slice(end);
229
- this.currentInput.selectionStart = this.currentInput.selectionEnd = start - 1;
230
- } else {
231
- this.currentInput.value = value.slice(0, start) + value.slice(end);
232
- this.currentInput.selectionStart = this.currentInput.selectionEnd = start;
233
- }
234
- break;
235
-
236
- case 'Space':
237
- await this.insertText(' ');
238
- break;
239
-
240
- case 'Tab':
241
- await this.insertText('\t');
242
- break;
243
-
244
- case 'Enter':
245
- if (this.currentInput.tagName === 'TEXTAREA') {
246
- await this.insertText('\n');
247
- }
248
- break;
249
-
250
- case 'Caps':
251
- this.toggleCapsLock();
252
- break;
253
-
254
- case 'Shift':
255
- this.toggleShift();
256
- break;
257
-
258
- default:
259
- const encryptedText = await this.encodeText(convertToCorrectCase(keyPressed));
260
- await this.insertText(encryptedText);
261
- }
207
+ if (this.currentLayout === "thSc") {
208
+ this.scrambleThaiKeys();
209
+ }
262
210
 
263
- if (isShiftActive && !isCapsActive) {
264
- this.toggleShift();
265
- }
211
+ keyboard.addEventListener("mousedown", (event) => this.startDrag(event));
212
+ }
266
213
 
267
- this.currentInput.focus();
268
- const event = new Event('input', { bubbles: true });
269
- this.currentInput.dispatchEvent(event);
270
- // console.log(this.encodeText(convertToCorrectCase(keyPressed)));
271
- // console.log(keyPressed);
272
- }
214
+ async handleKeyPress(keyPressed) {
215
+ if (!this.currentInput) return;
216
+
217
+ const start = this.currentInput.selectionStart;
218
+ const end = this.currentInput.selectionEnd;
219
+ const value = this.currentInput.value;
220
+
221
+ const isCapsActive = this.capsLockActive;
222
+ const isShiftActive = this.shiftActive;
273
223
 
274
- async insertText(text) {
275
- const start = this.currentInput.selectionStart;
276
- const end = this.currentInput.selectionEnd;
277
- const decodedText = await this.decodeText(text); // ใช้ถอดรหัสก่อนแทรก
224
+ const convertToCorrectCase = (char) => {
225
+ if (isCapsActive || isShiftActive) {
226
+ return char.toUpperCase();
227
+ }
228
+ return char.toLowerCase();
229
+ };
278
230
 
279
- this.currentInput.value = this.currentInput.value.slice(0, start) + decodedText + this.currentInput.value.slice(end);
280
- this.currentInput.selectionStart = this.currentInput.selectionEnd = start + decodedText.length;
231
+ if (!keyPressed) {
232
+ console.error("Invalid key pressed.");
233
+ return;
281
234
  }
282
235
 
283
- toggleCapsLock() {
284
- this.capsLockActive = !this.capsLockActive;
285
- document.querySelectorAll('.key[data-key="Caps"]').forEach((key) => {
286
- key.classList.toggle("active", this.capsLockActive);
287
- key.classList.toggle("bg-gray-400", this.capsLockActive);
288
- });
289
-
290
- document.querySelectorAll(".key").forEach((key) => {
291
- if (key.dataset.key.length === 1 && /[a-zA-Zก-๙]/.test(key.dataset.key)) {
292
- key.textContent = this.capsLockActive
293
- ? key.dataset.key.toUpperCase()
294
- : key.dataset.key.toLowerCase();
236
+ switch (keyPressed) {
237
+ case "Backspace":
238
+ case "backspace":
239
+ if (start === end && start > 0) {
240
+ this.currentInput.value =
241
+ value.slice(0, start - 1) + value.slice(end);
242
+ this.currentInput.selectionStart = this.currentInput.selectionEnd =
243
+ start - 1;
244
+ } else {
245
+ this.currentInput.value = value.slice(0, start) + value.slice(end);
246
+ this.currentInput.selectionStart = this.currentInput.selectionEnd =
247
+ start;
295
248
  }
296
- });
297
-
298
- const keyboardKeys = document.querySelectorAll(
299
- ".key:not([data-key='Caps'])"
300
- );
301
- keyboardKeys.forEach((key) => {
302
- const currentChar = key.textContent.trim();
303
- if (
304
- this.capsLockActive &&
305
- this.currentLayout === "th" &&
306
- this.ThaiAlphabetShift[currentChar]
307
- ) {
308
- key.textContent = this.ThaiAlphabetShift[currentChar];
309
- key.dataset.key = this.ThaiAlphabetShift[currentChar];
310
- } else if (
311
- !this.capsLockActive &&
312
- this.currentLayout === "th" &&
313
- Object.values(this.ThaiAlphabetShift).includes(currentChar)
314
- ) {
315
- // เปลี่ยนกลับเมื่อปิด Shift
316
- const originalKey = Object.keys(this.ThaiAlphabetShift).find(
317
- (key) => this.ThaiAlphabetShift[key] === currentChar
318
- );
319
- if (originalKey) {
320
- key.textContent = originalKey;
321
- key.dataset.key = originalKey;
249
+ break;
250
+
251
+ case "Space":
252
+ await this.insertText(" ");
253
+ break;
254
+
255
+ case "Tab":
256
+ await this.insertText("\t");
257
+ break;
258
+
259
+ case 'Enter':
260
+ if (this.currentInput.tagName === "TEXTAREA") {
261
+ const start = this.currentInput.selectionStart;
262
+ const end = this.currentInput.selectionEnd;
263
+ const value = this.currentInput.value;
264
+ this.currentInput.value = value.slice(0, start) + "\n" + value.slice(end);
265
+ this.currentInput.setSelectionRange(start + 1, start + 1);
266
+ } else if (this.currentInput.tagName === "INPUT" || this.currentInput.type === "password" || this.currentInput.type === "text") {
267
+ if (this.currentInput.form) {
268
+ const submitButton = this.currentInput.form.querySelector('input[type="submit"], button[type="submit"], button[type="button"], button[onclick]');
269
+ if (submitButton) {
270
+ submitButton.click();
271
+ } else {
272
+ this.currentInput.form.submit();
273
+ }
274
+ } else {
275
+ this.currentInput.value += '\n';
322
276
  }
323
277
  }
278
+ break;
324
279
 
325
- if (
326
- this.capsLockActive &&
327
- this.currentLayout === "en" &&
328
- this.EngAlphabetShift[currentChar]
329
- ) {
330
- key.textContent = this.EngAlphabetShift[currentChar];
331
- key.dataset.key = this.EngAlphabetShift[currentChar];
332
- } else if (
333
- !this.capsLockActive &&
334
- this.currentLayout === "en" &&
335
- Object.values(this.EngAlphabetShift).includes(currentChar)
336
- ) {
337
- // เปลี่ยนกลับเมื่อปิด Shift
338
- const originalKey = Object.keys(this.EngAlphabetShift).find(
339
- (key) => this.EngAlphabetShift[key] === currentChar
340
- );
341
- if (originalKey) {
342
- key.textContent = originalKey;
343
- key.dataset.key = originalKey;
344
- }
345
- }
346
- });
347
- }
280
+ case "Caps":
281
+ this.toggleCapsLock();
282
+ break;
348
283
 
349
- toggleShift() {
350
- this.shiftActive = !this.shiftActive;
351
- document.querySelectorAll('.key[data-key="Shift"]').forEach((key) => {
352
- key.classList.toggle("active", this.shiftActive);
353
- key.classList.toggle("bg-gray-400", this.shiftActive);
354
- });
355
-
356
- document.querySelectorAll(".key").forEach((key) => {
357
- if (key.dataset.key.length === 1 && /[a-zA-Zก-๙]/.test(key.dataset.key)) {
358
- key.textContent = this.shiftActive
359
- ? key.dataset.key.toUpperCase()
360
- : key.dataset.key.toLowerCase();
361
- }
362
- });
363
-
364
- const keyboardKeys = document.querySelectorAll(
365
- ".key:not([data-key='Shift'])"
284
+ case "Shift":
285
+ this.toggleShift();
286
+ break;
287
+
288
+ default:
289
+ const encryptedText = await this.encodeText(
290
+ convertToCorrectCase(keyPressed)
366
291
  );
367
- keyboardKeys.forEach((key) => {
368
- const currentChar = key.textContent.trim();
369
- if (
370
- this.shiftActive &&
371
- this.currentLayout === "th" &&
372
- this.ThaiAlphabetShift[currentChar]
373
- ) {
374
- key.textContent = this.ThaiAlphabetShift[currentChar];
375
- key.dataset.key = this.ThaiAlphabetShift[currentChar];
376
- } else if (
377
- !this.shiftActive &&
378
- this.currentLayout === "th" &&
379
- Object.values(this.ThaiAlphabetShift).includes(currentChar)
380
- ) {
381
- // เปลี่ยนกลับเมื่อปิด Shift
382
- const originalKey = Object.keys(this.ThaiAlphabetShift).find(
383
- (key) => this.ThaiAlphabetShift[key] === currentChar
384
- );
385
- if (originalKey) {
386
- key.textContent = originalKey;
387
- key.dataset.key = originalKey;
388
- }
389
- }
292
+ await this.insertText(encryptedText);
293
+ }
390
294
 
391
- if (
392
- this.shiftActive &&
393
- this.currentLayout === "en" &&
394
- this.EngAlphabetShift[currentChar]
395
- ) {
396
- key.textContent = this.EngAlphabetShift[currentChar];
397
- key.dataset.key = this.EngAlphabetShift[currentChar];
398
- } else if (
399
- !this.shiftActive &&
400
- this.currentLayout === "en" &&
401
- Object.values(this.EngAlphabetShift).includes(currentChar)
402
- ) {
403
- // เปลี่ยนกลับเมื่อปิด Shift
404
- const originalKey = Object.keys(this.EngAlphabetShift).find(
405
- (key) => this.EngAlphabetShift[key] === currentChar
406
- );
407
- if (originalKey) {
408
- key.textContent = originalKey;
409
- key.dataset.key = originalKey;
410
- }
411
- }
412
- });
295
+ if (isShiftActive && !isCapsActive) {
296
+ this.toggleShift();
413
297
  }
414
298
 
415
- EngAlphabetShift = {
416
- "`": "~", 1: "!", 2: "@", 3: "#", 4: "$", 5: "%", 6: "^", 7: "&", 8: "*", 9: "(", 0: ")", "-": "_", "=": "+",
417
- "[": "{", "]": "}", "\\": "|", ";": ":", "'": '"', ",": "<", ".": ">", "/": "?"
418
- };
299
+ this.currentInput.focus();
300
+ const event = new Event("input", { bubbles: true });
301
+ this.currentInput.dispatchEvent(event);
302
+ // console.log(this.encodeText(convertToCorrectCase(keyPressed)));
303
+ // console.log(keyPressed);
304
+ }
419
305
 
420
- ThaiAlphabetShift = {
421
- _: "%",
422
- ๅ: "+",
423
- "/": "๑",
424
- "-": "๒",
425
- ภ: "๓",
426
- ถ: "๔",
427
- "ุ": "ู",
428
- "ึ": "฿",
429
- ค: "๕",
430
- ต: "๖",
431
- จ: "๗",
432
- ข: "๘",
433
- ช: "๙",
434
- ๆ: "๐",
435
- ไ: '"',
436
- ำ: "ฎ",
437
- พ: "ฑ",
438
- ะ: "ธ",
439
- "ั": "ํ",
440
- "ี": "๋",
441
- ร: "ณ",
442
- น: "ฯ",
443
- ย: "ญ",
444
- บ: "ฐ",
445
- ล: ",",
446
- ฃ: "ฅ",
447
- ฟ: "ฤ",
448
- ห: "ฆ",
449
- ก: "ฏ",
450
- ด: "โ",
451
- เ: "ฌ",
452
- "้": "็",
453
- "่": "๋",
454
- า: "ษ",
455
- ส: "ศ",
456
- ว: "ซ",
457
- ง: ".",
458
- ผ: "(",
459
- ป: ")",
460
- แ: "ฉ",
461
- อ: "ฮ",
462
- "ิ": "ฺ",
463
- "ื": "์",
464
- ท: "?",
465
- ม: "ฒ",
466
- ใ: "ฬ",
467
- ฝ: "ฦ",
468
- };
306
+ async insertText(text) {
307
+ const start = this.currentInput.selectionStart;
308
+ const end = this.currentInput.selectionEnd;
309
+ const decodedText = await this.decodeText(text); // ใช้ถอดรหัสก่อนแทรก
310
+
311
+ this.currentInput.value =
312
+ this.currentInput.value.slice(0, start) +
313
+ decodedText +
314
+ this.currentInput.value.slice(end);
315
+ this.currentInput.selectionStart = this.currentInput.selectionEnd =
316
+ start + decodedText.length;
317
+ }
469
318
 
470
- toggle() {
471
- this.isVisible = !this.isVisible;
472
- this.render();
473
- }
319
+ toggleCapsLock() {
320
+ this.capsLockActive = !this.capsLockActive;
321
+ document.querySelectorAll('.key[data-key="Caps"]').forEach((key) => {
322
+ key.classList.toggle("active", this.capsLockActive);
323
+ key.classList.toggle("bg-gray-400", this.capsLockActive);
324
+ });
325
+
326
+ document.querySelectorAll(".key").forEach((key) => {
327
+ if (key.dataset.key.length === 1 && /[a-zA-Zก-๙]/.test(key.dataset.key)) {
328
+ key.textContent = this.capsLockActive
329
+ ? key.dataset.key.toUpperCase()
330
+ : key.dataset.key.toLowerCase();
331
+ }
332
+ });
333
+
334
+ const keyboardKeys = document.querySelectorAll(
335
+ ".key:not([data-key='Caps'])"
336
+ );
337
+ keyboardKeys.forEach((key) => {
338
+ const currentChar = key.textContent.trim();
339
+ if (
340
+ this.capsLockActive &&
341
+ this.currentLayout === "th" &&
342
+ this.ThaiAlphabetShift[currentChar]
343
+ ) {
344
+ key.textContent = this.ThaiAlphabetShift[currentChar];
345
+ key.dataset.key = this.ThaiAlphabetShift[currentChar];
346
+ } else if (
347
+ !this.capsLockActive &&
348
+ this.currentLayout === "th" &&
349
+ Object.values(this.ThaiAlphabetShift).includes(currentChar)
350
+ ) {
351
+ // เปลี่ยนกลับเมื่อปิด Shift
352
+ const originalKey = Object.keys(this.ThaiAlphabetShift).find(
353
+ (key) => this.ThaiAlphabetShift[key] === currentChar
354
+ );
355
+ if (originalKey) {
356
+ key.textContent = originalKey;
357
+ key.dataset.key = originalKey;
358
+ }
359
+ }
360
+
361
+ if (
362
+ this.capsLockActive &&
363
+ this.currentLayout === "en" &&
364
+ this.EngAlphabetShift[currentChar]
365
+ ) {
366
+ key.textContent = this.EngAlphabetShift[currentChar];
367
+ key.dataset.key = this.EngAlphabetShift[currentChar];
368
+ } else if (
369
+ !this.capsLockActive &&
370
+ this.currentLayout === "en" &&
371
+ Object.values(this.EngAlphabetShift).includes(currentChar)
372
+ ) {
373
+ // เปลี่ยนกลับเมื่อปิด Shift
374
+ const originalKey = Object.keys(this.EngAlphabetShift).find(
375
+ (key) => this.EngAlphabetShift[key] === currentChar
376
+ );
377
+ if (originalKey) {
378
+ key.textContent = originalKey;
379
+ key.dataset.key = originalKey;
380
+ }
381
+ }
382
+ });
383
+ }
474
384
 
475
- changeLayout(layout) {
476
- this.currentLayout = layout;
477
- this.render();
385
+ toggleShift() {
386
+ if (this.capsLockActive) {
387
+ return this.toggleCapsLock();
478
388
  }
479
389
 
480
- shuffleArray(array) {
481
- for (let i = array.length - 1; i > 0; i--) {
482
- const j = Math.floor(Math.random() * (i + 1));
483
- [array[i], array[j]] = [array[j], array[i]];
484
- }
390
+ this.shiftActive = !this.shiftActive;
391
+ document.querySelectorAll('.key[data-key="Shift"]').forEach((key) => {
392
+ key.classList.toggle("active", this.shiftActive);
393
+ key.classList.toggle("bg-gray-400", this.shiftActive);
394
+ });
395
+
396
+ document.querySelectorAll(".key").forEach((key) => {
397
+ if (key.dataset.key.length === 1 && /[a-zA-Zก-๙]/.test(key.dataset.key)) {
398
+ key.textContent = this.shiftActive
399
+ ? key.dataset.key.toUpperCase()
400
+ : key.dataset.key.toLowerCase();
485
401
  }
486
-
487
- scrambleKeyboard() {
488
- const keys = document.querySelectorAll(
489
- ".key:not([data-key=backspace]):not([data-key='+']):not([data-key='-']):not([data-key='*']):not([data-key='/']):not([data-key='%']):not([data-key='=']):not([data-key='.']):not([data-key='00'])"
402
+ });
403
+
404
+ const keyboardKeys = document.querySelectorAll(
405
+ ".key:not([data-key='Shift'])"
406
+ );
407
+ keyboardKeys.forEach((key) => {
408
+ const currentChar = key.textContent.trim();
409
+ if (
410
+ this.shiftActive &&
411
+ this.currentLayout === "th" &&
412
+ this.ThaiAlphabetShift[currentChar]
413
+ ) {
414
+ key.textContent = this.ThaiAlphabetShift[currentChar];
415
+ key.dataset.key = this.ThaiAlphabetShift[currentChar];
416
+ } else if (
417
+ !this.shiftActive &&
418
+ this.currentLayout === "th" &&
419
+ Object.values(this.ThaiAlphabetShift).includes(currentChar)
420
+ ) {
421
+ // เปลี่ยนกลับเมื่อปิด Shift
422
+ const originalKey = Object.keys(this.ThaiAlphabetShift).find(
423
+ (key) => this.ThaiAlphabetShift[key] === currentChar
490
424
  );
491
- const numbers = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"];
492
- this.shuffleArray(numbers);
493
- keys.forEach((key, index) => {
494
- key.textContent = numbers[index];
495
- key.dataset.key = numbers[index];
496
- });
425
+ if (originalKey) {
426
+ key.textContent = originalKey;
427
+ key.dataset.key = originalKey;
428
+ }
497
429
  }
498
-
499
- scrambleEnglishKeys() {
500
- const keys = document.querySelectorAll(
501
- ".key:not([data-key='Space']):not([data-key='Backspace']):not([data-key='Caps']):not([data-key='Shift']):not([data-key='Enter']):not([data-key='Tab']):not([data-key='`']):not([data-key='1']):not([data-key='2']):not([data-key='3']):not([data-key='4']):not([data-key='5']):not([data-key='6']):not([data-key='7']):not([data-key='8']):not([data-key='9']):not([data-key='0']):not([data-key='-']):not([data-key='+']):not([data-key='='])"
430
+
431
+ if (
432
+ this.shiftActive &&
433
+ this.currentLayout === "en" &&
434
+ this.EngAlphabetShift[currentChar]
435
+ ) {
436
+ key.textContent = this.EngAlphabetShift[currentChar];
437
+ key.dataset.key = this.EngAlphabetShift[currentChar];
438
+ } else if (
439
+ !this.shiftActive &&
440
+ this.currentLayout === "en" &&
441
+ Object.values(this.EngAlphabetShift).includes(currentChar)
442
+ ) {
443
+ // เปลี่ยนกลับเมื่อปิด Shift
444
+ const originalKey = Object.keys(this.EngAlphabetShift).find(
445
+ (key) => this.EngAlphabetShift[key] === currentChar
502
446
  );
503
- const englishAlphabet = "abcdefghijklmnopqrstuvwxyz".split("");
504
- this.shuffleArray(englishAlphabet);
505
- keys.forEach((key, index) => {
506
- key.textContent = englishAlphabet[index];
507
- key.dataset.key = englishAlphabet[index];
508
- });
447
+ if (originalKey) {
448
+ key.textContent = originalKey;
449
+ key.dataset.key = originalKey;
450
+ }
509
451
  }
510
-
511
- scrambleThaiKeys() {
512
- const keys = document.querySelectorAll(
513
- ".key:not([data-key='Backspace']):not([data-key='Caps']):not([data-key='Shift']):not([data-key='Enter']):not([data-key='Space'])"
514
- );
515
- const ThaiAlphabet = "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮ".split("");
516
- this.shuffleArray(ThaiAlphabet); // สับเปลี่ยนลำดับของตัวอักษร
517
-
518
- keys.forEach((key, index) => {
519
- // อัพเดต textContent และ dataset.key ให้ตรงกับค่าใหม่ที่สับเปลี่ยน
520
- key.textContent = ThaiAlphabet[index];
521
- key.dataset.key = ThaiAlphabet[index]; // อัพเดต dataset.key ด้วยค่าใหม่
522
- });
523
- }
524
-
525
-
526
- // จัดการการลากคีย์บอร์ด
527
- startDrag(event) {
528
- this.isDragging = true;
529
- this.offsetX = event.clientX - document.getElementById("keyboard").offsetLeft;
530
- this.offsetY = event.clientY - document.getElementById("keyboard").offsetTop;
531
-
532
- document.addEventListener("mousemove", this.drag.bind(this)); // Use bind to preserve `this` context
533
- document.addEventListener("mouseup", () => {
534
- this.isDragging = false;
535
- document.removeEventListener("mousemove", this.drag.bind(this));
536
- });
452
+ });
453
+ }
454
+
455
+ EngAlphabetShift = {
456
+ "`": "~",
457
+ 1: "!",
458
+ 2: "@",
459
+ 3: "#",
460
+ 4: "$",
461
+ 5: "%",
462
+ 6: "^",
463
+ 7: "&",
464
+ 8: "*",
465
+ 9: "(",
466
+ 0: ")",
467
+ "-": "_",
468
+ "=": "+",
469
+ "[": "{",
470
+ "]": "}",
471
+ "\\": "|",
472
+ ";": ":",
473
+ "'": '"',
474
+ ",": "<",
475
+ ".": ">",
476
+ "/": "?",
477
+ };
478
+
479
+ ThaiAlphabetShift = {
480
+ _: "%",
481
+ ๅ: "+",
482
+ "/": "๑",
483
+ "-": "๒",
484
+ ภ: "๓",
485
+ ถ: "๔",
486
+ "ุ": "ู",
487
+ "ึ": "฿",
488
+ ค: "๕",
489
+ ต: "๖",
490
+ จ: "๗",
491
+ ข: "๘",
492
+ ช: "๙",
493
+ ๆ: "๐",
494
+ ไ: '"',
495
+ ำ: "ฎ",
496
+ พ: "ฑ",
497
+ ะ: "ธ",
498
+ "ั": "ํ",
499
+ "ี": "๋",
500
+ ร: "ณ",
501
+ น: "ฯ",
502
+ ย: "ญ",
503
+ บ: "ฐ",
504
+ ล: ",",
505
+ ฃ: "ฅ",
506
+ ฟ: "ฤ",
507
+ ห: "ฆ",
508
+ ก: "ฏ",
509
+ ด: "โ",
510
+ เ: "ฌ",
511
+ "้": "็",
512
+ "่": "๋",
513
+ า: "ษ",
514
+ ส: "ศ",
515
+ ว: "ซ",
516
+ ง: ".",
517
+ ผ: "(",
518
+ ป: ")",
519
+ แ: "ฉ",
520
+ อ: "ฮ",
521
+ "ิ": "ฺ",
522
+ "ื": "์",
523
+ ท: "?",
524
+ ม: "ฒ",
525
+ ใ: "ฬ",
526
+ ฝ: "ฦ",
527
+ };
528
+
529
+ toggle() {
530
+ this.isVisible = !this.isVisible;
531
+ this.render();
532
+ }
533
+
534
+ changeLayout(layout) {
535
+ this.currentLayout = layout;
536
+ this.render();
537
+ }
538
+
539
+ shuffleArray(array) {
540
+ for (let i = array.length - 1; i > 0; i--) {
541
+ const j = Math.floor(Math.random() * (i + 1));
542
+ [array[i], array[j]] = [array[j], array[i]];
537
543
  }
538
-
539
- drag(event) {
540
- if (this.isDragging) {
541
- const keyboard = document.getElementById("keyboard");
542
- keyboard.style.left = `${event.clientX - this.offsetX}px`;
543
- keyboard.style.top = `${event.clientY - this.offsetY}px`;
544
- }
544
+ }
545
+
546
+ scrambleKeyboard() {
547
+ const keys = document.querySelectorAll(
548
+ ".key:not([data-key=backspace]):not([data-key='+']):not([data-key='-']):not([data-key='*']):not([data-key='/']):not([data-key='%']):not([data-key='=']):not([data-key='.']):not([data-key='00'])"
549
+ );
550
+ const numbers = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"];
551
+ this.shuffleArray(numbers);
552
+ keys.forEach((key, index) => {
553
+ key.textContent = numbers[index];
554
+ key.dataset.key = numbers[index];
555
+ });
556
+ }
557
+
558
+ scrambleEnglishKeys() {
559
+ const keys = document.querySelectorAll(
560
+ ".key:not([data-key='Space']):not([data-key='Backspace']):not([data-key='Caps']):not([data-key='Shift']):not([data-key='Enter']):not([data-key='Tab']):not([data-key='`']):not([data-key='1']):not([data-key='2']):not([data-key='3']):not([data-key='4']):not([data-key='5']):not([data-key='6']):not([data-key='7']):not([data-key='8']):not([data-key='9']):not([data-key='0']):not([data-key='-']):not([data-key='+']):not([data-key='='])"
561
+ );
562
+ const englishAlphabet = "abcdefghijklmnopqrstuvwxyz".split("");
563
+ this.shuffleArray(englishAlphabet);
564
+ keys.forEach((key, index) => {
565
+ key.textContent = englishAlphabet[index];
566
+ key.dataset.key = englishAlphabet[index];
567
+ });
568
+ }
569
+
570
+ scrambleThaiKeys() {
571
+ const keys = document.querySelectorAll(
572
+ ".key:not([data-key='Backspace']):not([data-key='Caps']):not([data-key='Shift']):not([data-key='Enter']):not([data-key='Space'])"
573
+ );
574
+ const ThaiAlphabet = "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮ".split(
575
+ ""
576
+ );
577
+ this.shuffleArray(ThaiAlphabet); // สับเปลี่ยนลำดับของตัวอักษร
578
+
579
+ keys.forEach((key, index) => {
580
+ // อัพเดต textContent และ dataset.key ให้ตรงกับค่าใหม่ที่สับเปลี่ยน
581
+ key.textContent = ThaiAlphabet[index];
582
+ key.dataset.key = ThaiAlphabet[index]; // อัพเดต dataset.key ด้วยค่าใหม่
583
+ });
584
+ }
585
+
586
+ // จัดการการลากคีย์บอร์ด
587
+ startDrag(event) {
588
+ this.isDragging = true;
589
+ this.offsetX =
590
+ event.clientX - document.getElementById("keyboard").offsetLeft;
591
+ this.offsetY =
592
+ event.clientY - document.getElementById("keyboard").offsetTop;
593
+
594
+ document.addEventListener("mousemove", this.drag.bind(this)); // Use bind to preserve `this` context
595
+ document.addEventListener("mouseup", () => {
596
+ this.isDragging = false;
597
+ document.removeEventListener("mousemove", this.drag.bind(this));
598
+ });
599
+ }
600
+
601
+ drag(event) {
602
+ if (this.isDragging) {
603
+ const keyboard = document.getElementById("keyboard");
604
+ keyboard.style.left = `${event.clientX - this.offsetX}px`;
605
+ keyboard.style.top = `${event.clientY - this.offsetY}px`;
545
606
  }
546
-
607
+ }
547
608
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "js_lis",
3
- "version": "1.0.22",
3
+ "version": "1.0.24",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"