text-input-guard 0.2.1 → 0.2.2
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.
- package/README.md +14 -6
- package/dist/cjs/text-input-guard.cjs +87 -27
- package/dist/cjs/text-input-guard.min.cjs +1 -1
- package/dist/esm/text-input-guard.js +87 -27
- package/dist/esm/text-input-guard.min.js +1 -1
- package/dist/umd/text-input-guard.js +87 -27
- package/dist/umd/text-input-guard.min.js +1 -1
- package/package.json +1 -1
|
@@ -169,6 +169,7 @@
|
|
|
169
169
|
// raw化(送信担当)
|
|
170
170
|
input.type = "hidden";
|
|
171
171
|
input.removeAttribute("id");
|
|
172
|
+
input.removeAttribute("class");
|
|
172
173
|
input.className = "";
|
|
173
174
|
input.dataset.tigRole = "raw";
|
|
174
175
|
|
|
@@ -176,6 +177,9 @@
|
|
|
176
177
|
if (this.originalId) {
|
|
177
178
|
input.dataset.tigOriginalId = this.originalId;
|
|
178
179
|
}
|
|
180
|
+
if (this.originalClass) {
|
|
181
|
+
input.dataset.tigOriginalClass = this.originalClass;
|
|
182
|
+
}
|
|
179
183
|
if (this.originalName) {
|
|
180
184
|
input.dataset.tigOriginalName = this.originalName;
|
|
181
185
|
}
|
|
@@ -196,7 +200,10 @@
|
|
|
196
200
|
display.id = this.originalId;
|
|
197
201
|
}
|
|
198
202
|
|
|
199
|
-
|
|
203
|
+
if (this.originalClass) {
|
|
204
|
+
display.className = this.originalClass;
|
|
205
|
+
}
|
|
206
|
+
|
|
200
207
|
display.value = raw.value;
|
|
201
208
|
|
|
202
209
|
for (const [name, v] of Object.entries(this.originalUiAttrs)) {
|
|
@@ -257,6 +264,7 @@
|
|
|
257
264
|
|
|
258
265
|
delete raw.dataset.tigRole;
|
|
259
266
|
delete raw.dataset.tigOriginalId;
|
|
267
|
+
delete raw.dataset.tigOriginalClass;
|
|
260
268
|
delete raw.dataset.tigOriginalName;
|
|
261
269
|
}
|
|
262
270
|
}
|
|
@@ -450,6 +458,28 @@
|
|
|
450
458
|
}
|
|
451
459
|
}
|
|
452
460
|
|
|
461
|
+
/**
|
|
462
|
+
* input / textarea 要素と内部 Guard インスタンスの対応表
|
|
463
|
+
*
|
|
464
|
+
* - key: displayElement
|
|
465
|
+
* - value: InputGuard(内部実装)
|
|
466
|
+
*
|
|
467
|
+
* @type {WeakMap<HTMLInputElement|HTMLTextAreaElement, InputGuard>}
|
|
468
|
+
*/
|
|
469
|
+
const guardMap = new WeakMap();
|
|
470
|
+
|
|
471
|
+
document.addEventListener("selectionchange", () => {
|
|
472
|
+
const el = document.activeElement;
|
|
473
|
+
if (!(el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement)) {
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
const inputGuard = guardMap.get(el);
|
|
477
|
+
if (!inputGuard) {
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
inputGuard.onSelectionChange();
|
|
481
|
+
});
|
|
482
|
+
|
|
453
483
|
/**
|
|
454
484
|
* 指定した1要素に対してガードを適用し、Guard API を返す
|
|
455
485
|
* @param {HTMLInputElement|HTMLTextAreaElement} element
|
|
@@ -457,9 +487,12 @@
|
|
|
457
487
|
* @returns {Guard}
|
|
458
488
|
*/
|
|
459
489
|
function attach(element, options = {}) {
|
|
460
|
-
const
|
|
461
|
-
|
|
462
|
-
|
|
490
|
+
const inputGuard = new InputGuard(element, options);
|
|
491
|
+
inputGuard.init();
|
|
492
|
+
const guard = inputGuard.getGuard();
|
|
493
|
+
const display = guard.getDisplayElement();
|
|
494
|
+
guardMap.set(display, inputGuard);
|
|
495
|
+
return guard;
|
|
463
496
|
}
|
|
464
497
|
|
|
465
498
|
/**
|
|
@@ -555,7 +588,7 @@
|
|
|
555
588
|
/**
|
|
556
589
|
* ユーザーが直接入力する表示側要素
|
|
557
590
|
* swapしない場合は originalElement と同一
|
|
558
|
-
* @type {
|
|
591
|
+
* @type {HTMLInputElement|HTMLTextAreaElement}
|
|
559
592
|
*/
|
|
560
593
|
this.displayElement = element;
|
|
561
594
|
|
|
@@ -677,6 +710,12 @@
|
|
|
677
710
|
*/
|
|
678
711
|
this.pendingCompositionCommit = false;
|
|
679
712
|
|
|
713
|
+
/**
|
|
714
|
+
* selection 更新のフレーム予約ID
|
|
715
|
+
* @type {number|null}
|
|
716
|
+
*/
|
|
717
|
+
this.selectionFrameId = null;
|
|
718
|
+
|
|
680
719
|
/**
|
|
681
720
|
* 直前に受理した表示値、正しい情報のスナップショットのような情報(block時の戻し先)
|
|
682
721
|
* @type {string}
|
|
@@ -722,9 +761,11 @@
|
|
|
722
761
|
* @returns {SelectionState}
|
|
723
762
|
*/
|
|
724
763
|
readSelection(el) {
|
|
764
|
+
const start = el.selectionStart ?? 0;
|
|
765
|
+
const end = el.selectionEnd ?? start;
|
|
725
766
|
return {
|
|
726
|
-
start
|
|
727
|
-
end
|
|
767
|
+
start,
|
|
768
|
+
end,
|
|
728
769
|
direction: el.selectionDirection
|
|
729
770
|
};
|
|
730
771
|
}
|
|
@@ -838,6 +879,8 @@
|
|
|
838
879
|
* @returns {void}
|
|
839
880
|
*/
|
|
840
881
|
detach() {
|
|
882
|
+
// 管理マップから削除
|
|
883
|
+
guardMap.delete(this.displayElement);
|
|
841
884
|
// イベント解除(displayElementがswap後の可能性があるので先に外す)
|
|
842
885
|
this.unbindEvents();
|
|
843
886
|
// swap復元
|
|
@@ -898,15 +941,7 @@
|
|
|
898
941
|
this.displayElement.addEventListener("input", this.onInput);
|
|
899
942
|
this.displayElement.addEventListener("beforeinput", this.onBeforeInput);
|
|
900
943
|
this.displayElement.addEventListener("blur", this.onBlur);
|
|
901
|
-
|
|
902
|
-
// フォーカスで編集用に戻す
|
|
903
944
|
this.displayElement.addEventListener("focus", this.onFocus);
|
|
904
|
-
|
|
905
|
-
// キャレット/選択範囲の変化を拾う(block時の不自然ジャンプ対策)
|
|
906
|
-
this.displayElement.addEventListener("keyup", this.onSelectionChange);
|
|
907
|
-
this.displayElement.addEventListener("mouseup", this.onSelectionChange);
|
|
908
|
-
this.displayElement.addEventListener("select", this.onSelectionChange);
|
|
909
|
-
this.displayElement.addEventListener("focus", this.onSelectionChange);
|
|
910
945
|
}
|
|
911
946
|
|
|
912
947
|
/**
|
|
@@ -920,10 +955,6 @@
|
|
|
920
955
|
this.displayElement.removeEventListener("beforeinput", this.onBeforeInput);
|
|
921
956
|
this.displayElement.removeEventListener("blur", this.onBlur);
|
|
922
957
|
this.displayElement.removeEventListener("focus", this.onFocus);
|
|
923
|
-
this.displayElement.removeEventListener("keyup", this.onSelectionChange);
|
|
924
|
-
this.displayElement.removeEventListener("mouseup", this.onSelectionChange);
|
|
925
|
-
this.displayElement.removeEventListener("select", this.onSelectionChange);
|
|
926
|
-
this.displayElement.removeEventListener("focus", this.onSelectionChange);
|
|
927
958
|
}
|
|
928
959
|
|
|
929
960
|
/**
|
|
@@ -1291,12 +1322,41 @@
|
|
|
1291
1322
|
* @returns {void}
|
|
1292
1323
|
*/
|
|
1293
1324
|
onSelectionChange() {
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1325
|
+
const requestFrame =
|
|
1326
|
+
typeof requestAnimationFrame === "function"
|
|
1327
|
+
? requestAnimationFrame
|
|
1328
|
+
: (
|
|
1329
|
+
/** @param {FrameRequestCallback} cb */
|
|
1330
|
+
(cb) => setTimeout(cb, 0)
|
|
1331
|
+
);
|
|
1332
|
+
|
|
1333
|
+
const cancelFrame =
|
|
1334
|
+
typeof cancelAnimationFrame === "function"
|
|
1335
|
+
? cancelAnimationFrame
|
|
1336
|
+
: clearTimeout;
|
|
1337
|
+
|
|
1338
|
+
// すでに予約済みならキャンセル(selectionchange は連続発火するため)
|
|
1339
|
+
if (this.selectionFrameId != null) {
|
|
1340
|
+
cancelFrame(this.selectionFrameId);
|
|
1297
1341
|
}
|
|
1298
|
-
|
|
1299
|
-
this.
|
|
1342
|
+
|
|
1343
|
+
this.selectionFrameId = requestFrame(() => {
|
|
1344
|
+
this.selectionFrameId = null;
|
|
1345
|
+
|
|
1346
|
+
// IME変換中は無視(キャレット位置が不安定になるため)
|
|
1347
|
+
if (this.composing) {
|
|
1348
|
+
return;
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
const el = /** @type {HTMLInputElement|HTMLTextAreaElement} */ (this.displayElement);
|
|
1352
|
+
|
|
1353
|
+
// 要素がフォーカスされていない場合は無視
|
|
1354
|
+
if (document.activeElement !== el) {
|
|
1355
|
+
return;
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1358
|
+
this.lastAcceptedSelection = this.readSelection(el);
|
|
1359
|
+
});
|
|
1300
1360
|
}
|
|
1301
1361
|
|
|
1302
1362
|
/**
|
|
@@ -7035,7 +7095,7 @@
|
|
|
7035
7095
|
code: "bytes.max_overflow",
|
|
7036
7096
|
rule: "bytes",
|
|
7037
7097
|
phase: "validate",
|
|
7038
|
-
detail: {
|
|
7098
|
+
detail: { limit: opt.max, actual: len }
|
|
7039
7099
|
});
|
|
7040
7100
|
}
|
|
7041
7101
|
}
|
|
@@ -7381,11 +7441,11 @@
|
|
|
7381
7441
|
|
|
7382
7442
|
/**
|
|
7383
7443
|
* バージョン(ビルド時に置換したいならここを差し替える)
|
|
7384
|
-
* 例: rollup replace で ""0.2.
|
|
7444
|
+
* 例: rollup replace で ""0.2.2"" を package.json の version に置換
|
|
7385
7445
|
*/
|
|
7386
7446
|
// @ts-ignore
|
|
7387
7447
|
// eslint-disable-next-line no-undef
|
|
7388
|
-
const version = "0.2.
|
|
7448
|
+
const version = "0.2.2" ;
|
|
7389
7449
|
|
|
7390
7450
|
exports.ascii = ascii;
|
|
7391
7451
|
exports.attach = attach;
|