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