js_lis 1.0.8 → 1.0.10

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.
@@ -5,16 +5,75 @@ export class VirtualKeyboard {
5
5
  this.currentLayout = 'en';
6
6
  this.isVisible = false;
7
7
  this.container = document.getElementById('keyboard-container');
8
- this.currentInput = null;
8
+ this.currentInput = null;
9
9
  this.layouts = layouts;
10
10
  this.isDragging = false;
11
11
  this.offsetX = 0;
12
12
  this.offsetY = 0;
13
13
  this.shiftActive = false;
14
14
  this.capsLockActive = false;
15
-
15
+ this.secretKey = '1234567890abcdef'; // คีย์ที่ใช้ในการเข้ารหัส
16
+ // ใช้ Web Crypto API สำหรับการจัดการคีย์
17
+ this.cryptoKey = null;
18
+ this.iv = window.crypto.getRandomValues(new Uint8Array(12)); // สร้าง IV สำหรับการเข้ารหัส/ถอดรหัส
19
+ this.generateKey();
20
+
16
21
  this.render();
17
- this.initializeInputListeners();
22
+ this.initialize();
23
+ }
24
+
25
+ async initialize() {
26
+ await this.generateKey();
27
+ this.render();
28
+ this.initializeInputListeners();
29
+ }
30
+
31
+ async generateKey() {
32
+ this.cryptoKey = await window.crypto.subtle.generateKey(
33
+ { name: "AES-GCM", length: 256 },
34
+ true,
35
+ ["encrypt", "decrypt"]
36
+ );
37
+ }
38
+
39
+ async encodeText(text) {
40
+ const encodedData = new TextEncoder().encode(text);
41
+ const encryptedData = await window.crypto.subtle.encrypt(
42
+ { name: "AES-GCM", iv: this.iv },
43
+ this.cryptoKey,
44
+ encodedData
45
+ );
46
+ return this.arrayBufferToBase64(encryptedData); // แปลงเป็น Base64
47
+ }
48
+
49
+ async decodeText(base64Text) {
50
+ const encryptedData = this.base64ToArrayBuffer(base64Text);
51
+ const decryptedData = await window.crypto.subtle.decrypt(
52
+ { name: "AES-GCM", iv: this.iv },
53
+ this.cryptoKey,
54
+ encryptedData
55
+ );
56
+ return new TextDecoder().decode(decryptedData);
57
+ }
58
+
59
+ arrayBufferToBase64(buffer) {
60
+ let binary = '';
61
+ const bytes = new Uint8Array(buffer);
62
+ const len = bytes.byteLength;
63
+ for (let i = 0; i < len; i++) {
64
+ binary += String.fromCharCode(bytes[i]);
65
+ }
66
+ return window.btoa(binary);
67
+ }
68
+
69
+ base64ToArrayBuffer(base64) {
70
+ const binaryString = window.atob(base64);
71
+ const len = binaryString.length;
72
+ const bytes = new Uint8Array(len);
73
+ for (let i = 0; i < len; i++) {
74
+ bytes[i] = binaryString.charCodeAt(i);
75
+ }
76
+ return bytes.buffer;
18
77
  }
19
78
 
20
79
  getLayoutName(layout) {
@@ -29,7 +88,6 @@ export class VirtualKeyboard {
29
88
  }
30
89
 
31
90
  initializeInputListeners() {
32
- // เพิ่ม event listener สำหรับทุก input และ textarea
33
91
  document.addEventListener('click', (e) => {
34
92
  const target = e.target;
35
93
  if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA') {
@@ -37,7 +95,6 @@ export class VirtualKeyboard {
37
95
  }
38
96
  });
39
97
 
40
- // เพิ่ม event listener สำหรับ focus
41
98
  document.addEventListener('focus', (e) => {
42
99
  const target = e.target;
43
100
  if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA') {
@@ -48,40 +105,35 @@ export class VirtualKeyboard {
48
105
  document.addEventListener('click', (e) => {
49
106
  const target = document.getElementById("toggle");
50
107
  target.addEventListener('click', this.toggle.bind(this), { once: true });
51
- });
108
+ });
52
109
  }
53
110
 
54
111
  setCurrentInput(inputElement) {
55
- // ถ้ามี input เก่า ให้ลบ class active
56
112
  if (this.currentInput) {
57
113
  this.currentInput.classList.remove('keyboard-active');
58
114
  }
59
-
60
- // เซ็ต input ใหม่และเพิ่ม class active
115
+
61
116
  this.currentInput = inputElement;
62
117
  this.currentInput.classList.add('keyboard-active');
63
118
  }
64
-
119
+
65
120
  render() {
66
121
  const keyboard = document.createElement('div');
67
122
  keyboard.className = 'virtual-keyboard';
68
123
  keyboard.style.display = this.isVisible ? 'block' : 'none';
69
-
70
- // Add the ID for easy reference in dragging
71
124
  keyboard.id = 'keyboard';
72
-
73
- // New: Add Layout selector at the top inside the keyboard div
125
+
74
126
  const controlsContainer = document.createElement('div');
75
127
  controlsContainer.className = 'controls';
76
128
  controlsContainer.style.display = 'flex';
77
129
  controlsContainer.style.justifyContent = 'center';
78
130
  controlsContainer.style.alignItems = 'center';
79
- controlsContainer.style.marginBottom = '10px'; // Optional: Add some space below the selector
80
-
131
+ controlsContainer.style.marginBottom = '10px';
132
+
81
133
  const layoutSelector = document.createElement('select');
82
134
  layoutSelector.id = 'layout-selector';
83
135
  layoutSelector.onchange = (e) => this.changeLayout(e.target.value);
84
-
136
+
85
137
  const layouts = ['en', 'enSc', 'th', 'thSc', 'numpad', 'scNum'];
86
138
  layouts.forEach(layout => {
87
139
  const option = document.createElement('option');
@@ -91,32 +143,31 @@ export class VirtualKeyboard {
91
143
  });
92
144
  layoutSelector.value = this.currentLayout;
93
145
  controlsContainer.appendChild(layoutSelector);
94
-
146
+
95
147
  keyboard.appendChild(controlsContainer);
96
-
148
+
97
149
  const layout = this.layouts[this.currentLayout];
98
-
150
+
99
151
  layout.forEach(row => {
100
152
  const rowElement = document.createElement('div');
101
153
  rowElement.className = 'keyboard-row';
102
-
154
+
103
155
  row.forEach(key => {
104
156
  const keyElement = document.createElement('button');
105
- keyElement.className = 'keyboard-key key'; // Add key class
157
+ keyElement.className = 'keyboard-key key';
106
158
  keyElement.textContent = key;
107
159
  keyElement.type = 'button';
108
-
109
- // Add data-key to each key for reference
160
+
110
161
  keyElement.dataset.key = key;
111
-
162
+
112
163
  if (key === 'Space') {
113
164
  keyElement.className += ' space';
114
165
  }
115
-
166
+
116
167
  if (key === 'backspace') {
117
168
  keyElement.className += ' backspacew';
118
169
  }
119
-
170
+
120
171
  keyElement.onclick = (e) => {
121
172
  e.preventDefault();
122
173
  const keyPressed = keyElement.dataset.key || keyElement.textContent;
@@ -126,57 +177,53 @@ export class VirtualKeyboard {
126
177
  console.error("The key element does not have a valid key value.");
127
178
  }
128
179
  };
129
-
180
+
130
181
  rowElement.appendChild(keyElement);
131
182
  });
132
-
183
+
133
184
  keyboard.appendChild(rowElement);
134
185
  });
135
-
186
+
136
187
  this.container.innerHTML = '';
137
188
  this.container.appendChild(keyboard);
138
-
189
+
139
190
  if (this.currentLayout === "scNum") {
140
191
  this.scrambleKeyboard();
141
192
  }
142
-
193
+
143
194
  if (this.currentLayout === "enSc") {
144
195
  this.scrambleEnglishKeys();
145
196
  }
146
-
197
+
147
198
  if (this.currentLayout === "thSc") {
148
199
  this.scrambleThaiKeys();
149
200
  }
150
-
151
- // Add drag functionality to the keyboard
201
+
152
202
  keyboard.addEventListener('mousedown', (event) => this.startDrag(event));
153
203
  }
154
-
155
-
156
-
157
- handleKeyPress(keyPressed) {
204
+
205
+ async handleKeyPress(keyPressed) {
158
206
  if (!this.currentInput) return;
159
-
207
+
160
208
  const start = this.currentInput.selectionStart;
161
209
  const end = this.currentInput.selectionEnd;
162
210
  const value = this.currentInput.value;
163
-
211
+
164
212
  const isCapsActive = this.capsLockActive;
165
213
  const isShiftActive = this.shiftActive;
166
-
214
+
167
215
  const convertToCorrectCase = (char) => {
168
216
  if (isCapsActive || isShiftActive) {
169
217
  return char.toUpperCase();
170
218
  }
171
219
  return char.toLowerCase();
172
220
  };
173
-
174
- // ตรวจสอบค่า keyPressed
221
+
175
222
  if (!keyPressed) {
176
223
  console.error("Invalid key pressed.");
177
224
  return;
178
225
  }
179
-
226
+
180
227
  switch(keyPressed) {
181
228
  case 'Backspace':
182
229
  case 'backspace':
@@ -188,32 +235,32 @@ export class VirtualKeyboard {
188
235
  this.currentInput.selectionStart = this.currentInput.selectionEnd = start;
189
236
  }
190
237
  break;
191
-
238
+
192
239
  case 'Space':
193
- this.insertText(' ');
240
+ await this.insertText(' ');
194
241
  break;
195
-
242
+
196
243
  case 'Tab':
197
- this.insertText('\t');
244
+ await this.insertText('\t');
198
245
  break;
199
-
246
+
200
247
  case 'Enter':
201
248
  if (this.currentInput.tagName === 'TEXTAREA') {
202
- this.insertText('\n');
249
+ await this.insertText('\n');
203
250
  }
204
251
  break;
205
-
252
+
206
253
  case 'Caps':
207
254
  this.toggleCapsLock();
208
255
  break;
209
-
256
+
210
257
  case 'Shift':
211
258
  this.toggleShift();
212
259
  break;
213
-
260
+
214
261
  default:
215
- this.insertText(convertToCorrectCase(keyPressed));
216
-
262
+ const encryptedText = await this.encodeText(convertToCorrectCase(keyPressed));
263
+ await this.insertText(encryptedText);
217
264
  }
218
265
 
219
266
  if (isShiftActive && !isCapsActive) {
@@ -223,6 +270,17 @@ export class VirtualKeyboard {
223
270
  this.currentInput.focus();
224
271
  const event = new Event('input', { bubbles: true });
225
272
  this.currentInput.dispatchEvent(event);
273
+ // console.log(this.encodeText(convertToCorrectCase(keyPressed)));
274
+ // console.log(keyPressed);
275
+ }
276
+
277
+ async insertText(text) {
278
+ const start = this.currentInput.selectionStart;
279
+ const end = this.currentInput.selectionEnd;
280
+ const decodedText = await this.decodeText(text); // ใช้ถอดรหัสก่อนแทรก
281
+
282
+ this.currentInput.value = this.currentInput.value.slice(0, start) + decodedText + this.currentInput.value.slice(end);
283
+ this.currentInput.selectionStart = this.currentInput.selectionEnd = start + decodedText.length;
226
284
  }
227
285
 
228
286
  toggleCapsLock() {
@@ -356,13 +414,6 @@ export class VirtualKeyboard {
356
414
  ฝ: "ฦ",
357
415
  };
358
416
 
359
- insertText(text) {
360
- const start = this.currentInput.selectionStart;
361
- const end = this.currentInput.selectionEnd;
362
- this.currentInput.value = this.currentInput.value.slice(0, start) + text + this.currentInput.value.slice(end);
363
- this.currentInput.selectionStart = this.currentInput.selectionEnd = start + text.length;
364
- }
365
-
366
417
  toggle() {
367
418
  this.isVisible = !this.isVisible;
368
419
  this.render();
package/main.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { VirtualKeyboard } from './VirtualKeyboard.js';
2
2
 
3
- // Create global instance
4
- window.keyboard = new VirtualKeyboard();
3
+ window.onload = () => {
4
+ window.keyboard = new VirtualKeyboard();
5
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "js_lis",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"