@taufik-nurrohman/text-editor.key 1.0.7 → 1.0.9

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 CHANGED
@@ -1,8 +1,7 @@
1
1
  [Text Editor](https://github.com/taufik-nurrohman/text-editor) » Key
2
2
  ==========================================================================
3
3
 
4
- Key extension for [Text Editor](https://github.com/taufik-nurrohman/text-editor). This extension provides a feature to
5
- easily interact with the keyboard keys.
4
+ This extension provides a feature to easily interact with the keyboard keys.
6
5
 
7
6
  ![index.js](https://img.shields.io/github/size/taufik-nurrohman/text-editor.key/index.js?branch=main&color=%23f1e05a&label=index.js&labelColor=%231f2328&style=flat-square)
8
7
  ![index.min.js](https://img.shields.io/github/size/taufik-nurrohman/text-editor.key/index.min.js?branch=main&color=%23f1e05a&label=index.min.js&labelColor=%231f2328&style=flat-square)
package/index.js CHANGED
@@ -36,8 +36,12 @@
36
36
  var isFunction = function isFunction(x) {
37
37
  return 'function' === typeof x;
38
38
  };
39
- var isInstance = function isInstance(x, of) {
40
- return x && isSet(of) && x instanceof of ;
39
+ var isInstance = function isInstance(x, of, exact) {
40
+ if (!x || 'object' !== typeof x) {
41
+ return false;
42
+ } {
43
+ return isSet(of) && isSet(x.constructor) && of === x.constructor;
44
+ }
41
45
  };
42
46
  var isNull = function isNull(x) {
43
47
  return null === x;
@@ -46,7 +50,7 @@
46
50
  if (isPlain === void 0) {
47
51
  isPlain = true;
48
52
  }
49
- if ('object' !== typeof x) {
53
+ if (!x || 'object' !== typeof x) {
50
54
  return false;
51
55
  }
52
56
  return isPlain ? isInstance(x, Object) : true;
@@ -57,55 +61,14 @@
57
61
  var isString = function isString(x) {
58
62
  return 'string' === typeof x;
59
63
  };
60
- var hasValue = function hasValue(x, data) {
61
- return -1 !== data.indexOf(x);
62
- };
63
- var fromStates = function fromStates() {
64
- for (var _len = arguments.length, lot = new Array(_len), _key = 0; _key < _len; _key++) {
65
- lot[_key] = arguments[_key];
66
- }
67
- var out = lot.shift();
68
- for (var i = 0, j = toCount(lot); i < j; ++i) {
69
- for (var k in lot[i]) {
70
- // Assign value
71
- if (!isSet(out[k])) {
72
- out[k] = lot[i][k];
73
- continue;
74
- }
75
- // Merge array
76
- if (isArray(out[k]) && isArray(lot[i][k])) {
77
- out[k] = [ /* Clone! */ ].concat(out[k]);
78
- for (var ii = 0, jj = toCount(lot[i][k]); ii < jj; ++ii) {
79
- if (!hasValue(lot[i][k][ii], out[k])) {
80
- out[k].push(lot[i][k][ii]);
81
- }
82
- }
83
- // Merge object recursive
84
- } else if (isObject(out[k]) && isObject(lot[i][k])) {
85
- out[k] = fromStates({
86
- /* Clone! */ }, out[k], lot[i][k]);
87
- // Replace value
88
- } else {
89
- out[k] = lot[i][k];
90
- }
91
- }
92
- }
93
- return out;
94
- };
95
- var toCount = function toCount(x) {
96
- return x.length;
97
- };
98
- var toObjectKeys = function toObjectKeys(x) {
99
- return Object.keys(x);
100
- };
101
64
 
102
65
  function Key(self) {
103
66
  var $ = this;
104
67
  $.commands = {};
105
68
  $.key = null;
106
69
  $.keys = {};
107
- $.queue = {};
108
70
  $.self = self || $;
71
+ $.set = new Set();
109
72
  return $;
110
73
  }
111
74
  var $$ = Key.prototype;
@@ -141,16 +104,19 @@
141
104
  var $ = this;
142
105
  $.key = null;
143
106
  if (!isSet(key)) {
144
- return $.queue = {}, $;
107
+ return $.set = new Set(), $;
145
108
  }
146
- return delete $.queue[key], $;
109
+ return $.set.delete(key), $;
147
110
  };
148
111
  $$.push = function (key) {
149
112
  var $ = this;
150
- return $.queue[$.key = key] = 1, $;
113
+ return $.set.add($.key = key, 1), $;
114
+ };
115
+ $$.toArray = function () {
116
+ return Array.from(this.set);
151
117
  };
152
118
  $$.toString = function () {
153
- return toObjectKeys(this.queue).join('-');
119
+ return this.toArray().join('-');
154
120
  };
155
121
  Object.defineProperty(Key, 'name', {
156
122
  value: 'Key'
@@ -166,22 +132,74 @@
166
132
  }, time);
167
133
  };
168
134
  };
135
+ var hasValue = function hasValue(x, data) {
136
+ return -1 !== data.indexOf(x);
137
+ };
138
+ var toCount = function toCount(x) {
139
+ return x.length;
140
+ };
141
+ var _fromStates = function fromStates() {
142
+ for (var _len = arguments.length, lot = new Array(_len), _key = 0; _key < _len; _key++) {
143
+ lot[_key] = arguments[_key];
144
+ }
145
+ var out = lot.shift();
146
+ for (var i = 0, j = toCount(lot); i < j; ++i) {
147
+ for (var k in lot[i]) {
148
+ // Assign value
149
+ if (!isSet(out[k])) {
150
+ out[k] = lot[i][k];
151
+ continue;
152
+ }
153
+ // Merge array
154
+ if (isArray(out[k]) && isArray(lot[i][k])) {
155
+ out[k] = [ /* Clone! */ ].concat(out[k]);
156
+ for (var ii = 0, jj = toCount(lot[i][k]); ii < jj; ++ii) {
157
+ if (!hasValue(lot[i][k][ii], out[k])) {
158
+ out[k].push(lot[i][k][ii]);
159
+ }
160
+ }
161
+ // Merge object recursive
162
+ } else if (isObject(out[k]) && isObject(lot[i][k])) {
163
+ out[k] = _fromStates({
164
+ /* Clone! */ }, out[k], lot[i][k]);
165
+ // Replace value
166
+ } else {
167
+ out[k] = lot[i][k];
168
+ }
169
+ }
170
+ }
171
+ return out;
172
+ };
169
173
  var offEventDefault = function offEventDefault(e) {
170
174
  return e && e.preventDefault();
171
175
  };
172
176
  var offEventPropagation = function offEventPropagation(e) {
173
177
  return e && e.stopPropagation();
174
178
  };
175
- var bounce = debounce(function (map) {
176
- return map.pull();
179
+ var bounce = debounce(function (map, e) {
180
+ // Remove all keys
181
+ map.pull();
182
+ // Make the `Alt`, `Control`, and `Shift` keys sticky (does not require the user to release all keys first to repeat or change the current key combination).
183
+ e.altKey && map.push('Alt');
184
+ e.ctrlKey && map.push('Control');
185
+ e.shiftKey && map.push('Shift');
177
186
  }, 1000);
178
187
  var name = 'TextEditor.Key';
179
- var id = '_Key';
188
+ var references = new WeakMap();
189
+
190
+ function getReference(key) {
191
+ return references.get(key) || null;
192
+ }
193
+
194
+ function letReference(key) {
195
+ return references.delete(key);
196
+ }
180
197
 
181
198
  function onBlur(e) {
182
- var $ = this;
199
+ var $ = this,
200
+ map = getReference($);
183
201
  $._event = e;
184
- $[id].pull(); // Reset all key(s)
202
+ map.pull(); // Reset all key(s)
185
203
  }
186
204
 
187
205
  function onInput(e) {
@@ -191,9 +209,14 @@
191
209
  function onKeyDown(e) {
192
210
  var $ = this;
193
211
  var command,
194
- map = $[id],
212
+ map = getReference($),
195
213
  v;
196
- map.push(e.key); // Add current key to the queue
214
+ // Make the `Alt`, `Control`, and `Shift` keys sticky (does not require the user to release all keys first to repeat or change the current key combination).
215
+ map[e.altKey ? 'push' : 'pull']('Alt');
216
+ map[e.ctrlKey ? 'push' : 'pull']('Control');
217
+ map[e.shiftKey ? 'push' : 'pull']('Shift');
218
+ // Add the actual key to the queue. Don’t worry, this will not mistakenly add a key that already exists in the queue.
219
+ map.push(e.key);
197
220
  $._event = e;
198
221
  if (command = map.command()) {
199
222
  v = map.fire(command);
@@ -204,42 +227,35 @@
204
227
  console.warn('Unknown command: `' + command + '`');
205
228
  }
206
229
  }
207
- bounce(map); // Reset all key(s) after 1 second idle
230
+ bounce(map, e); // Reset all key(s) after 1 second idle.
208
231
  }
209
232
 
210
233
  function onKeyUp(e) {
211
- var $ = this;
234
+ var $ = this,
235
+ map = getReference($);
212
236
  $._event = e;
213
- $[id].pull(e.key); // Reset current key
237
+ map.pull(e.key); // Reset current key.
238
+ }
239
+
240
+ function setReference(key, value) {
241
+ return references.set(key, value);
214
242
  }
215
243
 
216
244
  function attach() {
217
245
  var $ = this;
218
246
  var $$ = $.constructor.prototype;
219
247
  var map = new Key($);
220
- $.commands = fromStates($.commands = map.commands, $.state.commands || {});
221
- $.keys = fromStates($.keys = map.keys, $.state.keys || {});
248
+ $.commands = _fromStates($.commands = map.commands, $.state.commands || {});
249
+ $.keys = _fromStates($.keys = map.keys, $.state.keys || {});
222
250
  !isFunction($$.command) && ($$.command = function (command, of) {
223
251
  var $ = this;
224
252
  return $.commands[command] = of, $;
225
253
  });
226
254
  !isFunction($$.k) && ($$.k = function (join) {
227
255
  var $ = this,
228
- key = $[id] + "",
229
- keys;
230
- if (isSet(join) && '-' !== join) {
231
- keys = "" !== key ? key.split(/-(?!$)/) : [];
232
- if (false !== join) {
233
- return keys.join(join);
234
- }
235
- }
236
- if (false === join) {
237
- if ('-' === key) {
238
- return [key];
239
- }
240
- return keys;
241
- }
242
- return key;
256
+ map = getReference($),
257
+ keys = map.toArray();
258
+ return false === join ? keys : keys.join(join || '-');
243
259
  });
244
260
  !isFunction($$.key) && ($$.key = function (key, of) {
245
261
  var $ = this;
@@ -249,18 +265,18 @@
249
265
  $.on('input', onInput);
250
266
  $.on('key.down', onKeyDown);
251
267
  $.on('key.up', onKeyUp);
252
- return $[id] = map, $;
268
+ return setReference($, map), $;
253
269
  }
254
270
 
255
271
  function detach() {
256
- var $ = this;
257
- $[id].pull();
272
+ var $ = this,
273
+ map = getReference($);
274
+ map.pull();
258
275
  $.off('blur', onBlur);
259
276
  $.off('input', onInput);
260
277
  $.off('key.down', onKeyDown);
261
278
  $.off('key.up', onKeyUp);
262
- delete $[id];
263
- return $;
279
+ return letReference($), $;
264
280
  }
265
281
  var index_js = {
266
282
  attach: attach,
package/index.min.js CHANGED
@@ -23,4 +23,4 @@
23
23
  * SOFTWARE.
24
24
  *
25
25
  */
26
- !function(n,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):((n="undefined"!=typeof globalThis?globalThis:n||self).TextEditor=n.TextEditor||{},n.TextEditor.Key=t())}(this,(function(){"use strict";var n=function(n){return Array.isArray(n)},t=function(n){return"function"==typeof n},e=function(n,t){return void 0===t&&(t=!0),"object"==typeof n&&(!t||function(n,t){return n&&r(t)&&n instanceof t}(n,Object))},r=function(n){return function(n){return void 0!==n}(n)&&!function(n){return null===n}(n)},o=function(n){return"string"==typeof n},u=function t(){for(var o=arguments.length,u=Array(o),f=0;f<o;f++)u[f]=arguments[f];for(var c,s=u.shift(),a=0,l=i(u);a<l;++a)for(var y in u[a])if(r(s[y]))if(n(s[y])&&n(u[a][y])){s[y]=[].concat(s[y]);for(var d=0,p=i(u[a][y]);d<p;++d)c=u[a][y][d],-1===s[y].indexOf(c)&&s[y].push(u[a][y][d])}else e(s[y])&&e(u[a][y])?s[y]=t({},s[y],u[a][y]):s[y]=u[a][y];else s[y]=u[a][y];return s},i=function(n){return n.length};function f(n){var t=this;return t.commands={},t.key=null,t.keys={},t.queue={},t.self=n||t,t}var c=f.prototype;c.command=function(n){var t=this;if(o(n))return n===t.toString();var e=t.keys[t.toString()];return!!r(e)&&e},c.fire=function(e){var u,i,f=this,c=f.self||f;if(t(e))u=e.call(c),i=!0;else if(o(e)&&(e=f.commands[e]))u=e.call(c),i=!0;else if(n(e)){var s=e[1]||[];(e=f.commands[e[0]])&&(u=e.apply(c,s),i=!0)}return i?!r(u)||u:null},c.pull=function(n){var t=this;return t.key=null,r(n)?(delete t.queue[n],t):(t.queue={},t)},c.push=function(n){var t=this;return t.queue[t.key=n]=1,t},c.toString=function(){return(n=this.queue,Object.keys(n)).join("-");var n},Object.defineProperty(f,"name",{value:"Key"});var s,a,l,y=function(n){return n&&n.preventDefault()},d=function(n){return n&&n.stopPropagation()},p=(s=function(n){return n.pull()},a=1e3,function(){var n=arguments,t=this;l&&clearTimeout(l),l=setTimeout((function(){return s.apply(t,n)}),a)}),m="_Key";function h(n){this._event=n,this[m].pull()}function v(n){h.call(this,n)}function k(n){var t,e,r=this[m];r.push(n.key),this._event=n,(t=r.command())&&(!1===(e=r.fire(t))?(y(n),d(n)):null===e&&console.warn("Unknown command: `"+t+"`")),p(r)}function b(n){this._event=n,this[m].pull(n.key)}var g={attach:function(){var n=this,e=n.constructor.prototype,o=new f(n);return n.commands=u(n.commands=o.commands,n.state.commands||{}),n.keys=u(n.keys=o.keys,n.state.keys||{}),!t(e.command)&&(e.command=function(n,t){return this.commands[n]=t,this}),!t(e.k)&&(e.k=function(n){var t,e=this[m]+"";return r(n)&&"-"!==n&&(t=""!==e?e.split(/-(?!$)/):[],!1!==n)?t.join(n):!1===n?"-"===e?[e]:t:e}),!t(e.key)&&(e.key=function(n,t){return this.keys[n]=t,this}),n.on("blur",h),n.on("input",v),n.on("key.down",k),n.on("key.up",b),n[m]=o,n},detach:function(){var n=this;return n[m].pull(),n.off("blur",h),n.off("input",v),n.off("key.down",k),n.off("key.up",b),delete n[m],n},name:"TextEditor.Key"};return g}));
26
+ !function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):((t="undefined"!=typeof globalThis?globalThis:t||self).TextEditor=t.TextEditor||{},t.TextEditor.Key=n())}(this,(function(){"use strict";var t=function(t){return Array.isArray(t)},n=function(t){return"function"==typeof t},e=function(t,n){return void 0===n&&(n=!0),!(!t||"object"!=typeof t)&&(!n||function(t,n){return!(!t||"object"!=typeof t)&&r(n)&&r(t.constructor)&&n===t.constructor}(t,Object))},r=function(t){return function(t){return void 0!==t}(t)&&!function(t){return null===t}(t)},o=function(t){return"string"==typeof t};function u(t){var n=this;return n.commands={},n.key=null,n.keys={},n.self=t||n,n.set=new Set,n}var i=u.prototype;i.command=function(t){var n=this;if(o(t))return t===n.toString();var e=n.keys[n.toString()];return!!r(e)&&e},i.fire=function(e){var u,i,f=this,s=f.self||f;if(n(e))u=e.call(s),i=!0;else if(o(e)&&(e=f.commands[e]))u=e.call(s),i=!0;else if(t(e)){var c=e[1]||[];(e=f.commands[e[0]])&&(u=e.apply(s,c),i=!0)}return i?!r(u)||u:null},i.pull=function(t){var n=this;return n.key=null,r(t)?(n.set.delete(t),n):(n.set=new Set,n)},i.push=function(t){var n=this;return n.set.add(n.key=t,1),n},i.toArray=function(){return Array.from(this.set)},i.toString=function(){return this.toArray().join("-")},Object.defineProperty(u,"name",{value:"Key"});var f,s,c,a=function(t){return t.length},l=function(){for(var n=arguments.length,o=Array(n),u=0;u<n;u++)o[u]=arguments[u];for(var i,f=o.shift(),s=0,c=a(o);s<c;++s)for(var y in o[s])if(r(f[y]))if(t(f[y])&&t(o[s][y])){f[y]=[].concat(f[y]);for(var p=0,h=a(o[s][y]);p<h;++p)i=o[s][y][p],-1===f[y].indexOf(i)&&f[y].push(o[s][y][p])}else e(f[y])&&e(o[s][y])?f[y]=l({},f[y],o[s][y]):f[y]=o[s][y];else f[y]=o[s][y];return f},y=(f=function(t,n){t.pull(),n.altKey&&t.push("Alt"),n.ctrlKey&&t.push("Control"),n.shiftKey&&t.push("Shift")},s=1e3,function(){var t=arguments,n=this;c&&clearTimeout(c),c=setTimeout((function(){return f.apply(n,t)}),s)}),p=new WeakMap;function h(t){return p.get(t)||null}function d(t){var n=h(this);this._event=t,n.pull()}function m(t){d.call(this,t)}function v(t){var n,e,r=h(this);r[t.altKey?"push":"pull"]("Alt"),r[t.ctrlKey?"push":"pull"]("Control"),r[t.shiftKey?"push":"pull"]("Shift"),r.push(t.key),this._event=t,(n=r.command())&&(!1===(e=r.fire(n))?(function(t){t&&t.preventDefault()}(t),function(t){t&&t.stopPropagation()}(t)):null===e&&console.warn("Unknown command: `"+n+"`")),y(r,t)}function k(t){var n=h(this);this._event=t,n.pull(t.key)}var g={attach:function(){var t,e,r=this,o=r.constructor.prototype,i=new u(r);return r.commands=l(r.commands=i.commands,r.state.commands||{}),r.keys=l(r.keys=i.keys,r.state.keys||{}),!n(o.command)&&(o.command=function(t,n){return this.commands[t]=n,this}),!n(o.k)&&(o.k=function(t){var n=h(this).toArray();return!1===t?n:n.join(t||"-")}),!n(o.key)&&(o.key=function(t,n){return this.keys[t]=n,this}),r.on("blur",d),r.on("input",m),r.on("key.down",v),r.on("key.up",k),t=r,e=i,p.set(t,e),r},detach:function(){var t,n=this;return h(n).pull(),n.off("blur",d),n.off("input",m),n.off("key.down",v),n.off("key.up",k),t=n,p.delete(t),n},name:"TextEditor.Key"};return g}));
package/index.mjs CHANGED
@@ -4,15 +4,31 @@ import {fromStates} from '@taufik-nurrohman/from';
4
4
  import {isFunction, isSet} from '@taufik-nurrohman/is';
5
5
  import {offEventDefault, offEventPropagation} from '@taufik-nurrohman/event';
6
6
 
7
- const bounce = debounce(map => map.pull(), 1000);
7
+ const bounce = debounce((map, e) => {
8
+ // Remove all keys
9
+ map.pull();
10
+ // Make the `Alt`, `Control`, and `Shift` keys sticky (does not require the user to release all keys first to repeat or change the current key combination).
11
+ e.altKey && map.push('Alt');
12
+ e.ctrlKey && map.push('Control');
13
+ e.shiftKey && map.push('Shift');
14
+ }, 1000);
15
+
8
16
  const name = 'TextEditor.Key';
17
+ const references = new WeakMap;
18
+
19
+ function getReference(key) {
20
+ return references.get(key) || null;
21
+ }
9
22
 
10
- const id = '_Key';
23
+ function letReference(key) {
24
+ return references.delete(key);
25
+ }
11
26
 
12
27
  function onBlur(e) {
13
- let $ = this;
28
+ let $ = this,
29
+ map = getReference($);
14
30
  $._event = e;
15
- $[id].pull(); // Reset all key(s)
31
+ map.pull(); // Reset all key(s)
16
32
  }
17
33
 
18
34
  function onInput(e) {
@@ -21,8 +37,13 @@ function onInput(e) {
21
37
 
22
38
  function onKeyDown(e) {
23
39
  let $ = this;
24
- let command, map = $[id], v;
25
- map.push(e.key); // Add current key to the queue
40
+ let command, map = getReference($), v;
41
+ // Make the `Alt`, `Control`, and `Shift` keys sticky (does not require the user to release all keys first to repeat or change the current key combination).
42
+ map[e.altKey ? 'push' : 'pull']('Alt');
43
+ map[e.ctrlKey ? 'push' : 'pull']('Control');
44
+ map[e.shiftKey ? 'push' : 'pull']('Shift');
45
+ // Add the actual key to the queue. Don’t worry, this will not mistakenly add a key that already exists in the queue.
46
+ map.push(e.key);
26
47
  $._event = e;
27
48
  if (command = map.command()) {
28
49
  v = map.fire(command);
@@ -33,13 +54,18 @@ function onKeyDown(e) {
33
54
  console.warn('Unknown command: `' + command + '`');
34
55
  }
35
56
  }
36
- bounce(map); // Reset all key(s) after 1 second idle
57
+ bounce(map, e); // Reset all key(s) after 1 second idle.
37
58
  }
38
59
 
39
60
  function onKeyUp(e) {
40
- let $ = this;
61
+ let $ = this,
62
+ map = getReference($);
41
63
  $._event = e;
42
- $[id].pull(e.key); // Reset current key
64
+ map.pull(e.key); // Reset current key.
65
+ }
66
+
67
+ function setReference(key, value) {
68
+ return references.set(key, value);
43
69
  }
44
70
 
45
71
  function attach() {
@@ -54,21 +80,9 @@ function attach() {
54
80
  });
55
81
  !isFunction($$.k) && ($$.k = function (join) {
56
82
  let $ = this,
57
- key = $[id] + "",
58
- keys;
59
- if (isSet(join) && '-' !== join) {
60
- keys = "" !== key ? key.split(/-(?!$)/) : [];
61
- if (false !== join) {
62
- return keys.join(join);
63
- }
64
- }
65
- if (false === join) {
66
- if ('-' === key) {
67
- return [key];
68
- }
69
- return keys;
70
- }
71
- return key;
83
+ map = getReference($),
84
+ keys = map.toArray();
85
+ return false === join ? keys : keys.join(join || '-');
72
86
  });
73
87
  !isFunction($$.key) && ($$.key = function (key, of) {
74
88
  let $ = this;
@@ -78,18 +92,18 @@ function attach() {
78
92
  $.on('input', onInput);
79
93
  $.on('key.down', onKeyDown);
80
94
  $.on('key.up', onKeyUp);
81
- return ($[id] = map), $;
95
+ return setReference($, map), $;
82
96
  }
83
97
 
84
98
  function detach() {
85
- let $ = this;
86
- $[id].pull();
99
+ let $ = this,
100
+ map = getReference($);
101
+ map.pull();
87
102
  $.off('blur', onBlur);
88
103
  $.off('input', onInput);
89
104
  $.off('key.down', onKeyDown);
90
105
  $.off('key.up', onKeyUp);
91
- delete $[id];
92
- return $;
106
+ return letReference($), $;
93
107
  }
94
108
 
95
109
  export default {attach, detach, name};
package/package.json CHANGED
@@ -46,5 +46,5 @@
46
46
  "scripts": {
47
47
  "pack": "pack --clean=false --from=.factory --js-format=umd --js-name=TextEditor.Key --js-top='%(js.license)' --mjs=true --to=."
48
48
  },
49
- "version": "1.0.7"
49
+ "version": "1.0.9"
50
50
  }