js_lis 1.0.23 → 1.0.25

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.
@@ -2,7 +2,7 @@ import { layouts } from "./layouts.js";
2
2
 
3
3
  export class VirtualKeyboard {
4
4
  constructor() {
5
- this.currentLayout = "en";
5
+ this.currentLayout = "full";
6
6
  this.isVisible = false;
7
7
  this.container = document.getElementById("keyboard-container");
8
8
  this.currentInput = null;
@@ -74,6 +74,8 @@ export class VirtualKeyboard {
74
74
 
75
75
  getLayoutName(layout) {
76
76
  switch (layout) {
77
+ case "full":
78
+ return "Full Keyboard";
77
79
  case "en":
78
80
  return "English Keyboard";
79
81
  case "enSc":
@@ -127,7 +129,7 @@ export class VirtualKeyboard {
127
129
 
128
130
  render() {
129
131
  const keyboard = document.createElement("div");
130
- keyboard.className = "virtual-keyboard";
132
+ keyboard.className = `virtual-keyboard ${this.currentLayout}`;
131
133
  keyboard.style.display = this.isVisible ? "block" : "none";
132
134
  keyboard.id = "keyboard";
133
135
 
@@ -142,7 +144,7 @@ export class VirtualKeyboard {
142
144
  layoutSelector.id = "layout-selector";
143
145
  layoutSelector.onchange = (e) => this.changeLayout(e.target.value);
144
146
 
145
- const layouts = ["en", "enSc", "th", "thSc", "numpad", "scNum"];
147
+ const layouts = ["full", "en", "enSc", "th", "thSc", "numpad", "scNum"];
146
148
  layouts.forEach((layout) => {
147
149
  const option = document.createElement("option");
148
150
  option.value = layout;
@@ -160,7 +162,7 @@ export class VirtualKeyboard {
160
162
  const rowElement = document.createElement("div");
161
163
  rowElement.className = "keyboard-row";
162
164
 
163
- row.forEach((key) => {
165
+ row.forEach((key, index) => {
164
166
  const keyElement = document.createElement("button");
165
167
  keyElement.className = "keyboard-key key";
166
168
  keyElement.textContent = key;
@@ -168,6 +170,10 @@ export class VirtualKeyboard {
168
170
 
169
171
  keyElement.dataset.key = key;
170
172
 
173
+ if (index >= row.length - 4) {
174
+ keyElement.classList.add("concat-keys");
175
+ }
176
+
171
177
  if (key === "Space") {
172
178
  keyElement.className += " space";
173
179
  }
@@ -234,6 +240,95 @@ export class VirtualKeyboard {
234
240
  }
235
241
 
236
242
  switch (keyPressed) {
243
+ case "Esc":
244
+ // ปิดหน้าต่างป๊อปอัพหรือยกเลิกการทำงานปัจจุบัน
245
+ const modals = document.querySelectorAll(".modal");
246
+ if (modals.length === 0) {
247
+ document.exitFullscreen();
248
+ console.warn("No modals found to close.");
249
+ }
250
+ modals.forEach((modal) => {
251
+ modal.classList.add("hidden"); // ซ่อน modal
252
+ });
253
+ break;
254
+
255
+ case "F1":
256
+ break;
257
+
258
+ case "F2":
259
+ // เปิดโหมดแก้ไขสำหรับ element ที่เลือก
260
+ const activeElement = document.activeElement;
261
+ if (activeElement && activeElement.contentEditable !== undefined) {
262
+ activeElement.contentEditable = true;
263
+ activeElement.focus();
264
+ console.log(activeElement.contentEditable);
265
+ } else {
266
+ console.warn("No editable element found.");
267
+ }
268
+ break;
269
+
270
+ case "F3":
271
+ // เปิดการค้นหา
272
+ event.preventDefault();
273
+ this.option.openSearch();
274
+ break;
275
+
276
+ case "F4":
277
+ // เปิดเมนูการตั้งค่า
278
+ event.preventDefault();
279
+ this.option.openSettings();
280
+ break;
281
+
282
+ case "F5":
283
+ // รีโหลดหน้าเว็บ (คงเดิม)
284
+ window.location.reload();
285
+ break;
286
+
287
+ case "F6":
288
+ // สลับระหว่างโหมดกลางวัน/กลางคืน
289
+ document.body.classList.toggle("dark-mode");
290
+ break;
291
+
292
+ case "F7":
293
+ break;
294
+
295
+ case "F8":
296
+ break;
297
+
298
+ case "F9":
299
+ break;
300
+
301
+ case "F10":
302
+ break;
303
+
304
+ case "F11":
305
+ if (!document.fullscreenElement) {
306
+ document.documentElement
307
+ .requestFullscreen()
308
+ .catch((err) =>
309
+ console.error("Error attempting to enable fullscreen:", err)
310
+ );
311
+ } else {
312
+ document
313
+ .exitFullscreen()
314
+ .catch((err) =>
315
+ console.error("Error attempting to exit fullscreen:", err)
316
+ );
317
+ }
318
+ break;
319
+
320
+ case "F12":
321
+ break;
322
+
323
+ case "HOME":
324
+ this.currentInput.setSelectionRange(Math.max(0, 0), Math.max(0, 0));
325
+ break;
326
+
327
+ case "END":
328
+ const length = this.currentInput.value.length;
329
+ this.currentInput.setSelectionRange(length, length);
330
+ break;
331
+
237
332
  case "Backspace":
238
333
  case "backspace":
239
334
  if (start === end && start > 0) {
@@ -248,28 +343,98 @@ export class VirtualKeyboard {
248
343
  }
249
344
  break;
250
345
 
346
+ case "DEL⌦":
347
+ if (start === end && start < value.length) {
348
+ this.currentInput.value =
349
+ value.slice(0, start) + value.slice(end + 1);
350
+ this.currentInput.selectionStart = this.currentInput.selectionEnd =
351
+ start;
352
+ } else {
353
+ this.currentInput.value = value.slice(0, start) + value.slice(end);
354
+ this.currentInput.selectionStart = this.currentInput.selectionEnd =
355
+ start;
356
+ }
357
+ break;
358
+
251
359
  case "Space":
252
360
  await this.insertText(" ");
253
361
  break;
254
362
 
255
- case "Tab":
363
+ case "Tab":
256
364
  await this.insertText("\t");
257
365
  break;
258
366
 
259
367
  case "Enter":
260
368
  if (this.currentInput.tagName === "TEXTAREA") {
261
- await this.insertText("\n");
369
+ this.currentInput.value =
370
+ value.slice(0, start) + "\n" + value.slice(end);
371
+ this.currentInput.setSelectionRange(start + 1, start + 1);
372
+ } else if (
373
+ this.currentInput.tagName === "INPUT" ||
374
+ this.currentInput.type === "password" ||
375
+ this.currentInput.type === "text"
376
+ ) {
377
+ if (this.currentInput.form) {
378
+ const submitButton = this.currentInput.form.querySelector(
379
+ 'input[type="submit"], button[type="submit"], button[type="button"], button[onclick]'
380
+ );
381
+ if (submitButton) {
382
+ submitButton.click();
383
+ } else {
384
+ this.currentInput.form.submit();
385
+ }
386
+ } else {
387
+ this.currentInput.value += "\n";
388
+ }
262
389
  }
263
390
  break;
264
391
 
265
- case "Caps":
392
+ case "Caps 🄰":
266
393
  this.toggleCapsLock();
267
394
  break;
268
395
 
269
- case "Shift":
396
+ case "Shift":
270
397
  this.toggleShift();
271
398
  break;
272
399
 
400
+ case "←":
401
+ this.currentInput.setSelectionRange(
402
+ Math.max(0, start - 1),
403
+ Math.max(0, start - 1)
404
+ );
405
+ break;
406
+
407
+ case "→":
408
+ this.currentInput.setSelectionRange(start + 1, start + 1);
409
+ break;
410
+
411
+ case "↑":
412
+ case "↓":
413
+ const text = this.currentInput.value;
414
+ const lines = text.substring(0, start).split("\n");
415
+ const currentLineIndex = lines.length - 1;
416
+ const currentLine = lines[currentLineIndex];
417
+ const columnIndex = start - text.lastIndexOf("\n", start - 1) - 1;
418
+
419
+ if (keyPressed === "↑" && currentLineIndex > 0) {
420
+ const prevLineLength = lines[currentLineIndex - 1].length;
421
+ const newPos =
422
+ start -
423
+ currentLine.length -
424
+ 1 -
425
+ Math.min(columnIndex, prevLineLength);
426
+ this.currentInput.setSelectionRange(newPos, newPos);
427
+ } else if (keyPressed === "↓" && currentLineIndex < lines.length - 1) {
428
+ const nextLine = lines[currentLineIndex + 1];
429
+ const newPos =
430
+ start +
431
+ currentLine.length +
432
+ 1 +
433
+ Math.min(columnIndex, nextLine.length);
434
+ this.currentInput.setSelectionRange(newPos, newPos);
435
+ }
436
+ break;
437
+
273
438
  default:
274
439
  const encryptedText = await this.encodeText(
275
440
  convertToCorrectCase(keyPressed)
@@ -284,8 +449,6 @@ export class VirtualKeyboard {
284
449
  this.currentInput.focus();
285
450
  const event = new Event("input", { bubbles: true });
286
451
  this.currentInput.dispatchEvent(event);
287
- // console.log(this.encodeText(convertToCorrectCase(keyPressed)));
288
- // console.log(keyPressed);
289
452
  }
290
453
 
291
454
  async insertText(text) {
@@ -303,7 +466,7 @@ export class VirtualKeyboard {
303
466
 
304
467
  toggleCapsLock() {
305
468
  this.capsLockActive = !this.capsLockActive;
306
- document.querySelectorAll('.key[data-key="Caps"]').forEach((key) => {
469
+ document.querySelectorAll('.key[data-key="Caps 🄰"]').forEach((key) => {
307
470
  key.classList.toggle("active", this.capsLockActive);
308
471
  key.classList.toggle("bg-gray-400", this.capsLockActive);
309
472
  });
@@ -317,7 +480,7 @@ export class VirtualKeyboard {
317
480
  });
318
481
 
319
482
  const keyboardKeys = document.querySelectorAll(
320
- ".key:not([data-key='Caps'])"
483
+ ".key:not([data-key='Caps 🄰'])"
321
484
  );
322
485
  keyboardKeys.forEach((key) => {
323
486
  const currentChar = key.textContent.trim();
@@ -345,17 +508,16 @@ export class VirtualKeyboard {
345
508
 
346
509
  if (
347
510
  this.capsLockActive &&
348
- this.currentLayout === "en" &&
511
+ (this.currentLayout === "en" || this.currentLayout === "enSc") &&
349
512
  this.EngAlphabetShift[currentChar]
350
513
  ) {
351
514
  key.textContent = this.EngAlphabetShift[currentChar];
352
515
  key.dataset.key = this.EngAlphabetShift[currentChar];
353
516
  } else if (
354
517
  !this.capsLockActive &&
355
- this.currentLayout === "en" &&
518
+ (this.currentLayout === "en" || this.currentLayout === "enSc") &&
356
519
  Object.values(this.EngAlphabetShift).includes(currentChar)
357
520
  ) {
358
- // เปลี่ยนกลับเมื่อปิด Shift
359
521
  const originalKey = Object.keys(this.EngAlphabetShift).find(
360
522
  (key) => this.EngAlphabetShift[key] === currentChar
361
523
  );
@@ -368,14 +530,9 @@ export class VirtualKeyboard {
368
530
  }
369
531
 
370
532
  toggleShift() {
371
- if (this.capsLockActive) {
372
- return this.toggleCapsLock();
373
- }
374
-
375
533
  this.shiftActive = !this.shiftActive;
376
- document.querySelectorAll('.key[data-key="Shift"]').forEach((key) => {
534
+ document.querySelectorAll('.key[data-key="Shift"]').forEach((key) => {
377
535
  key.classList.toggle("active", this.shiftActive);
378
- key.classList.toggle("bg-gray-400", this.shiftActive);
379
536
  });
380
537
 
381
538
  document.querySelectorAll(".key").forEach((key) => {
@@ -387,10 +544,11 @@ export class VirtualKeyboard {
387
544
  });
388
545
 
389
546
  const keyboardKeys = document.querySelectorAll(
390
- ".key:not([data-key='Shift'])"
547
+ ".key:not([data-key='Shift'])"
391
548
  );
392
549
  keyboardKeys.forEach((key) => {
393
550
  const currentChar = key.textContent.trim();
551
+ keyboardKeys.className += " space";
394
552
  if (
395
553
  this.shiftActive &&
396
554
  this.currentLayout === "th" &&
@@ -415,14 +573,14 @@ export class VirtualKeyboard {
415
573
 
416
574
  if (
417
575
  this.shiftActive &&
418
- this.currentLayout === "en" &&
576
+ (this.currentLayout === "en" || this.currentLayout === "enSc") &&
419
577
  this.EngAlphabetShift[currentChar]
420
578
  ) {
421
579
  key.textContent = this.EngAlphabetShift[currentChar];
422
580
  key.dataset.key = this.EngAlphabetShift[currentChar];
423
581
  } else if (
424
582
  !this.shiftActive &&
425
- this.currentLayout === "en" &&
583
+ (this.currentLayout === "en" || this.currentLayout === "enSc") &&
426
584
  Object.values(this.EngAlphabetShift).includes(currentChar)
427
585
  ) {
428
586
  // เปลี่ยนกลับเมื่อปิด Shift
@@ -530,7 +688,7 @@ export class VirtualKeyboard {
530
688
 
531
689
  scrambleKeyboard() {
532
690
  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'])"
691
+ ".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='(']):not([data-key=')']):not([data-key='_'])"
534
692
  );
535
693
  const numbers = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"];
536
694
  this.shuffleArray(numbers);
@@ -542,7 +700,7 @@ export class VirtualKeyboard {
542
700
 
543
701
  scrambleEnglishKeys() {
544
702
  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='='])"
703
+ ".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='=']):not([data-key='~']):not([data-key='!']):not([data-key='@']):not([data-key='#']):not([data-key='$']):not([data-key='%']):not([data-key='^']):not([data-key='&']):not([data-key='*']):not([data-key='(']):not([data-key=')']):not([data-key='_'])"
546
704
  );
547
705
  const englishAlphabet = "abcdefghijklmnopqrstuvwxyz".split("");
548
706
  this.shuffleArray(englishAlphabet);
@@ -554,7 +712,7 @@ export class VirtualKeyboard {
554
712
 
555
713
  scrambleThaiKeys() {
556
714
  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'])"
715
+ ".key:not([data-key='Backspace']):not([data-key='Caps 🄰']):not([data-key='Shift']):not([data-key='Enter']):not([data-key='Space'])"
558
716
  );
559
717
  const ThaiAlphabet = "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮ".split(
560
718
  ""
package/layouts.js CHANGED
@@ -1,31 +1,41 @@
1
1
  export const layouts = {
2
+ full: [
3
+ ["Esc", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "DEL⌦", "HOME", "END"],
4
+ ["`", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "=", "Backspace"].concat(["+", "-", "*","/"]),
5
+ ["Tab ↹", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "[", "]", "\\"].concat(["7", "8", "9", "%"]),
6
+ ["Caps 🄰", "a", "s", "d", "f", "g", "h", "j", "k", "l", ";", "'", "Enter"].concat(["4", "5", "6", "_"]),
7
+ ["Shift ⇧", "z", "x", "c", "v", "b", "n", "m", ",", ".", "/", "Shift ⇧", "↑"].concat(["1", "2", "3", "="]),
8
+ ["Space", "←", "↓", "→"].concat(["0", "."]),
9
+ ],
2
10
  en: [
3
11
  ["`", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "=", "Backspace"],
4
- ["Tab", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "[", "]", "\\"],
5
- ["Caps", "a", "s", "d", "f", "g", "h", "j", "k", "l", ";", "'", "Enter"],
6
- ["Shift", "z", "x", "c", "v", "b", "n", "m", ",", ".", "/", "Shift"],
12
+ ["Tab", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "[", "]", "\\"],
13
+ ["Caps 🄰", "a", "s", "d", "f", "g", "h", "j", "k", "l", ";", "'", "Enter"],
14
+ ["Shift", "z", "x", "c", "v", "b", "n", "m", ",", ".", "/", "Shift"],
7
15
  ["Space"],
8
16
  ],
9
17
  th: [
10
18
  ["_", "ๅ", "/", "-", "ภ", "ถ", "ุ", "ึ", "ค", "ต", "จ", "ข", "ช", "Backspace"],
11
- ["Tab", "ๆ", "ไ", "ำ", "พ", "ะ", "ั", "ี", "ร", "น", "ย", "บ", "ล", "ฃ"],
12
- ["Caps", "ฟ", "ห", "ก", "ด", "เ", "้", "่", "า", "ส", "ว", "ง", "Enter"],
13
- ["Shift", "ผ", "ป", "แ", "อ", "ิ", "ื", "ท", "ม", "ใ", "ฝ", "Shift"],
19
+ ["Tab", "ๆ", "ไ", "ำ", "พ", "ะ", "ั", "ี", "ร", "น", "ย", "บ", "ล", "ฃ"],
20
+ ["Caps 🄰", "ฟ", "ห", "ก", "ด", "เ", "้", "่", "า", "ส", "ว", "ง", "Enter"],
21
+ ["Shift", "ผ", "ป", "แ", "อ", "ิ", "ื", "ท", "ม", "ใ", "ฝ", "Shift"],
14
22
  ["Space"],
15
23
  ],
16
24
  numpad: [
17
25
  ["+", "-", "*", "/"],
18
26
  ["1", "2", "3", "%"],
19
- ["4", "5", "6", "."],
20
- ["7", "8", "9", "="],
21
- ["00", "0", "backspace"],
27
+ ["4", "5", "6", "_"],
28
+ ["7", "8", "9", "."],
29
+ ["(", "0", ")", "="],
30
+ ["backspace"]
22
31
  ],
23
32
  scNum: [
24
33
  ["+", "-", "*", "/"],
25
34
  ["1", "2", "3", "%"],
26
- ["4", "5", "6", "."],
27
- ["7", "8", "9", "="],
28
- ["00", "0", "backspace"],
35
+ ["4", "5", "6", "_"],
36
+ ["7", "8", "9", "."],
37
+ ["(", "0", ")", "="],
38
+ ["backspace"]
29
39
  ],
30
40
  thSc: [
31
41
  ["ก", "ข", "ฃ", "ค", "ฅ", "ฆ", "ง", "จ", "ฉ", "ช", "ซ", "ฌ", "Backspace"],
@@ -36,9 +46,9 @@ export const layouts = {
36
46
  ],
37
47
  enSc: [
38
48
  ["`", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "="],
39
- ["Tab", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "Backspace"],
40
- ["Caps", "a", "s", "d", "f", "g", "h", "j", "k", "l", "Enter"],
41
- ["Shift", "z", "x", "c", "v", "b", "n", "m", "Shift"],
49
+ ["Tab", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "Backspace"],
50
+ ["Caps 🄰", "a", "s", "d", "f", "g", "h", "j", "k", "l", "Enter"],
51
+ ["Shift", "z", "x", "c", "v", "b", "n", "m", "Shift"],
42
52
  ["Space"],
43
53
  ],
44
54
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "js_lis",
3
- "version": "1.0.23",
3
+ "version": "1.0.25",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"