js_lis 1.0.22 → 1.0.23

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 +537 -491
  2. package/package.json +1 -1
@@ -1,547 +1,593 @@
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();
295
- }
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;
322
- }
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;
323
248
  }
249
+ break;
324
250
 
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
- }
251
+ case "Space":
252
+ await this.insertText(" ");
253
+ break;
348
254
 
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'])"
366
- );
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
- }
255
+ case "Tab":
256
+ await this.insertText("\t");
257
+ break;
390
258
 
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
- });
413
- }
259
+ case "Enter":
260
+ if (this.currentInput.tagName === "TEXTAREA") {
261
+ await this.insertText("\n");
262
+ }
263
+ break;
414
264
 
415
- EngAlphabetShift = {
416
- "`": "~", 1: "!", 2: "@", 3: "#", 4: "$", 5: "%", 6: "^", 7: "&", 8: "*", 9: "(", 0: ")", "-": "_", "=": "+",
417
- "[": "{", "]": "}", "\\": "|", ";": ":", "'": '"', ",": "<", ".": ">", "/": "?"
418
- };
265
+ case "Caps":
266
+ this.toggleCapsLock();
267
+ break;
419
268
 
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
- };
269
+ case "Shift":
270
+ this.toggleShift();
271
+ break;
469
272
 
470
- toggle() {
471
- this.isVisible = !this.isVisible;
472
- this.render();
273
+ default:
274
+ const encryptedText = await this.encodeText(
275
+ convertToCorrectCase(keyPressed)
276
+ );
277
+ await this.insertText(encryptedText);
473
278
  }
474
279
 
475
- changeLayout(layout) {
476
- this.currentLayout = layout;
477
- this.render();
280
+ if (isShiftActive && !isCapsActive) {
281
+ this.toggleShift();
478
282
  }
479
283
 
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]];
284
+ this.currentInput.focus();
285
+ const event = new Event("input", { bubbles: true });
286
+ this.currentInput.dispatchEvent(event);
287
+ // console.log(this.encodeText(convertToCorrectCase(keyPressed)));
288
+ // console.log(keyPressed);
289
+ }
290
+
291
+ async insertText(text) {
292
+ const start = this.currentInput.selectionStart;
293
+ const end = this.currentInput.selectionEnd;
294
+ const decodedText = await this.decodeText(text); // ใช้ถอดรหัสก่อนแทรก
295
+
296
+ this.currentInput.value =
297
+ this.currentInput.value.slice(0, start) +
298
+ decodedText +
299
+ this.currentInput.value.slice(end);
300
+ this.currentInput.selectionStart = this.currentInput.selectionEnd =
301
+ start + decodedText.length;
302
+ }
303
+
304
+ toggleCapsLock() {
305
+ this.capsLockActive = !this.capsLockActive;
306
+ document.querySelectorAll('.key[data-key="Caps"]').forEach((key) => {
307
+ key.classList.toggle("active", this.capsLockActive);
308
+ key.classList.toggle("bg-gray-400", this.capsLockActive);
309
+ });
310
+
311
+ document.querySelectorAll(".key").forEach((key) => {
312
+ if (key.dataset.key.length === 1 && /[a-zA-Zก-๙]/.test(key.dataset.key)) {
313
+ key.textContent = this.capsLockActive
314
+ ? key.dataset.key.toUpperCase()
315
+ : key.dataset.key.toLowerCase();
316
+ }
317
+ });
318
+
319
+ const keyboardKeys = document.querySelectorAll(
320
+ ".key:not([data-key='Caps'])"
321
+ );
322
+ keyboardKeys.forEach((key) => {
323
+ const currentChar = key.textContent.trim();
324
+ if (
325
+ this.capsLockActive &&
326
+ this.currentLayout === "th" &&
327
+ this.ThaiAlphabetShift[currentChar]
328
+ ) {
329
+ key.textContent = this.ThaiAlphabetShift[currentChar];
330
+ key.dataset.key = this.ThaiAlphabetShift[currentChar];
331
+ } else if (
332
+ !this.capsLockActive &&
333
+ this.currentLayout === "th" &&
334
+ Object.values(this.ThaiAlphabetShift).includes(currentChar)
335
+ ) {
336
+ // เปลี่ยนกลับเมื่อปิด Shift
337
+ const originalKey = Object.keys(this.ThaiAlphabetShift).find(
338
+ (key) => this.ThaiAlphabetShift[key] === currentChar
339
+ );
340
+ if (originalKey) {
341
+ key.textContent = originalKey;
342
+ key.dataset.key = originalKey;
484
343
  }
485
344
  }
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'])"
345
+
346
+ if (
347
+ this.capsLockActive &&
348
+ this.currentLayout === "en" &&
349
+ this.EngAlphabetShift[currentChar]
350
+ ) {
351
+ key.textContent = this.EngAlphabetShift[currentChar];
352
+ key.dataset.key = this.EngAlphabetShift[currentChar];
353
+ } else if (
354
+ !this.capsLockActive &&
355
+ this.currentLayout === "en" &&
356
+ Object.values(this.EngAlphabetShift).includes(currentChar)
357
+ ) {
358
+ // เปลี่ยนกลับเมื่อปิด Shift
359
+ const originalKey = Object.keys(this.EngAlphabetShift).find(
360
+ (key) => this.EngAlphabetShift[key] === currentChar
490
361
  );
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
- });
362
+ if (originalKey) {
363
+ key.textContent = originalKey;
364
+ key.dataset.key = originalKey;
365
+ }
366
+ }
367
+ });
368
+ }
369
+
370
+ toggleShift() {
371
+ if (this.capsLockActive) {
372
+ return this.toggleCapsLock();
373
+ }
374
+
375
+ this.shiftActive = !this.shiftActive;
376
+ document.querySelectorAll('.key[data-key="Shift"]').forEach((key) => {
377
+ key.classList.toggle("active", this.shiftActive);
378
+ key.classList.toggle("bg-gray-400", this.shiftActive);
379
+ });
380
+
381
+ document.querySelectorAll(".key").forEach((key) => {
382
+ if (key.dataset.key.length === 1 && /[a-zA-Zก-๙]/.test(key.dataset.key)) {
383
+ key.textContent = this.shiftActive
384
+ ? key.dataset.key.toUpperCase()
385
+ : key.dataset.key.toLowerCase();
497
386
  }
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='='])"
387
+ });
388
+
389
+ const keyboardKeys = document.querySelectorAll(
390
+ ".key:not([data-key='Shift'])"
391
+ );
392
+ keyboardKeys.forEach((key) => {
393
+ const currentChar = key.textContent.trim();
394
+ if (
395
+ this.shiftActive &&
396
+ this.currentLayout === "th" &&
397
+ this.ThaiAlphabetShift[currentChar]
398
+ ) {
399
+ key.textContent = this.ThaiAlphabetShift[currentChar];
400
+ key.dataset.key = this.ThaiAlphabetShift[currentChar];
401
+ } else if (
402
+ !this.shiftActive &&
403
+ this.currentLayout === "th" &&
404
+ Object.values(this.ThaiAlphabetShift).includes(currentChar)
405
+ ) {
406
+ // เปลี่ยนกลับเมื่อปิด Shift
407
+ const originalKey = Object.keys(this.ThaiAlphabetShift).find(
408
+ (key) => this.ThaiAlphabetShift[key] === currentChar
502
409
  );
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
- });
410
+ if (originalKey) {
411
+ key.textContent = originalKey;
412
+ key.dataset.key = originalKey;
413
+ }
509
414
  }
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'])"
415
+
416
+ if (
417
+ this.shiftActive &&
418
+ this.currentLayout === "en" &&
419
+ this.EngAlphabetShift[currentChar]
420
+ ) {
421
+ key.textContent = this.EngAlphabetShift[currentChar];
422
+ key.dataset.key = this.EngAlphabetShift[currentChar];
423
+ } else if (
424
+ !this.shiftActive &&
425
+ this.currentLayout === "en" &&
426
+ Object.values(this.EngAlphabetShift).includes(currentChar)
427
+ ) {
428
+ // เปลี่ยนกลับเมื่อปิด Shift
429
+ const originalKey = Object.keys(this.EngAlphabetShift).find(
430
+ (key) => this.EngAlphabetShift[key] === currentChar
514
431
  );
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
- });
537
- }
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`;
432
+ if (originalKey) {
433
+ key.textContent = originalKey;
434
+ key.dataset.key = originalKey;
544
435
  }
436
+ }
437
+ });
438
+ }
439
+
440
+ EngAlphabetShift = {
441
+ "`": "~",
442
+ 1: "!",
443
+ 2: "@",
444
+ 3: "#",
445
+ 4: "$",
446
+ 5: "%",
447
+ 6: "^",
448
+ 7: "&",
449
+ 8: "*",
450
+ 9: "(",
451
+ 0: ")",
452
+ "-": "_",
453
+ "=": "+",
454
+ "[": "{",
455
+ "]": "}",
456
+ "\\": "|",
457
+ ";": ":",
458
+ "'": '"',
459
+ ",": "<",
460
+ ".": ">",
461
+ "/": "?",
462
+ };
463
+
464
+ ThaiAlphabetShift = {
465
+ _: "%",
466
+ ๅ: "+",
467
+ "/": "๑",
468
+ "-": "๒",
469
+ ภ: "๓",
470
+ ถ: "๔",
471
+ "ุ": "ู",
472
+ "ึ": "฿",
473
+ ค: "๕",
474
+ ต: "๖",
475
+ จ: "๗",
476
+ ข: "๘",
477
+ ช: "๙",
478
+ ๆ: "๐",
479
+ ไ: '"',
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
+ toggle() {
515
+ this.isVisible = !this.isVisible;
516
+ this.render();
517
+ }
518
+
519
+ changeLayout(layout) {
520
+ this.currentLayout = layout;
521
+ this.render();
522
+ }
523
+
524
+ shuffleArray(array) {
525
+ for (let i = array.length - 1; i > 0; i--) {
526
+ const j = Math.floor(Math.random() * (i + 1));
527
+ [array[i], array[j]] = [array[j], array[i]];
545
528
  }
546
-
529
+ }
530
+
531
+ scrambleKeyboard() {
532
+ const keys = document.querySelectorAll(
533
+ ".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'])"
534
+ );
535
+ const numbers = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"];
536
+ this.shuffleArray(numbers);
537
+ keys.forEach((key, index) => {
538
+ key.textContent = numbers[index];
539
+ key.dataset.key = numbers[index];
540
+ });
541
+ }
542
+
543
+ scrambleEnglishKeys() {
544
+ const keys = document.querySelectorAll(
545
+ ".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='='])"
546
+ );
547
+ const englishAlphabet = "abcdefghijklmnopqrstuvwxyz".split("");
548
+ this.shuffleArray(englishAlphabet);
549
+ keys.forEach((key, index) => {
550
+ key.textContent = englishAlphabet[index];
551
+ key.dataset.key = englishAlphabet[index];
552
+ });
553
+ }
554
+
555
+ scrambleThaiKeys() {
556
+ const keys = document.querySelectorAll(
557
+ ".key:not([data-key='Backspace']):not([data-key='Caps']):not([data-key='Shift']):not([data-key='Enter']):not([data-key='Space'])"
558
+ );
559
+ const ThaiAlphabet = "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮ".split(
560
+ ""
561
+ );
562
+ this.shuffleArray(ThaiAlphabet); // สับเปลี่ยนลำดับของตัวอักษร
563
+
564
+ keys.forEach((key, index) => {
565
+ // อัพเดต textContent และ dataset.key ให้ตรงกับค่าใหม่ที่สับเปลี่ยน
566
+ key.textContent = ThaiAlphabet[index];
567
+ key.dataset.key = ThaiAlphabet[index]; // อัพเดต dataset.key ด้วยค่าใหม่
568
+ });
569
+ }
570
+
571
+ // จัดการการลากคีย์บอร์ด
572
+ startDrag(event) {
573
+ this.isDragging = true;
574
+ this.offsetX =
575
+ event.clientX - document.getElementById("keyboard").offsetLeft;
576
+ this.offsetY =
577
+ event.clientY - document.getElementById("keyboard").offsetTop;
578
+
579
+ document.addEventListener("mousemove", this.drag.bind(this)); // Use bind to preserve `this` context
580
+ document.addEventListener("mouseup", () => {
581
+ this.isDragging = false;
582
+ document.removeEventListener("mousemove", this.drag.bind(this));
583
+ });
584
+ }
585
+
586
+ drag(event) {
587
+ if (this.isDragging) {
588
+ const keyboard = document.getElementById("keyboard");
589
+ keyboard.style.left = `${event.clientX - this.offsetX}px`;
590
+ keyboard.style.top = `${event.clientY - this.offsetY}px`;
591
+ }
592
+ }
547
593
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "js_lis",
3
- "version": "1.0.22",
3
+ "version": "1.0.23",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"