svedit 0.11.0 → 0.11.1
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/dist/Command.svelte.d.ts +0 -1
- package/dist/Command.svelte.d.ts.map +1 -1
- package/dist/Command.svelte.js +1 -3
- package/dist/KeyMapper.svelte.d.ts.map +1 -1
- package/dist/KeyMapper.svelte.js +18 -6
- package/dist/utils.d.ts +14 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +28 -7
- package/package.json +1 -1
- package/src/lib/Command.svelte.js +1 -3
- package/src/lib/KeyMapper.svelte.js +18 -6
- package/src/lib/utils.js +28 -7
package/dist/Command.svelte.d.ts
CHANGED
|
@@ -85,7 +85,6 @@ export class ToggleAnnotationCommand extends Command {
|
|
|
85
85
|
/**
|
|
86
86
|
* Command that adds a new line character at the current caret position.
|
|
87
87
|
* Only works in text selections where newlines are allowed.
|
|
88
|
-
* Disabled on mobile browsers where Shift+Enter has different behavior.
|
|
89
88
|
*/
|
|
90
89
|
export class AddNewLineCommand extends Command {
|
|
91
90
|
is_enabled(): any;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Command.svelte.d.ts","sourceRoot":"","sources":["../src/lib/Command.svelte.js"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH;IAOC;;;;OAIG;IACH,qBAFW,GAAG,EAIb;IAbD;;;OAGG;IACH,kBAAwC;IAQvC,aAAsB;IAGvB;;;;;OAKG;IACH,cAFa,OAAO,CAInB;IAED;;;;;;OAMG;IACH,WAFa,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAIhC;CACD;AAED;;GAEG;AACH;IACC,kBAEC;IAED,gBAEC;CACD;AAED;;GAEG;AACH;IACC,kBAEC;IAED,gBAEC;CACD;AAED;;;GAGG;AACH;IASC,gBAEC;CACD;AAED;;;GAGG;AACH;IACC,0CAGC;IADA,eAA0B;IAG3B,YAAoC;IAEpC,iBAEC;IAED,kBAqBC;IAED,gBAEC;CACD;AAED
|
|
1
|
+
{"version":3,"file":"Command.svelte.d.ts","sourceRoot":"","sources":["../src/lib/Command.svelte.js"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH;IAOC;;;;OAIG;IACH,qBAFW,GAAG,EAIb;IAbD;;;OAGG;IACH,kBAAwC;IAQvC,aAAsB;IAGvB;;;;;OAKG;IACH,cAFa,OAAO,CAInB;IAED;;;;;;OAMG;IACH,WAFa,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAIhC;CACD;AAED;;GAEG;AACH;IACC,kBAEC;IAED,gBAEC;CACD;AAED;;GAEG;AACH;IACC,kBAEC;IAED,gBAEC;CACD;AAED;;;GAGG;AACH;IASC,gBAEC;CACD;AAED;;;GAGG;AACH;IACC,0CAGC;IADA,eAA0B;IAG3B,YAAoC;IAEpC,iBAEC;IAED,kBAqBC;IAED,gBAEC;CACD;AAED;;;GAGG;AACH;IACC,kBASC;IAED,gBAqBC;CACD;AAED;;;;GAIG;AACH;IAaC,gBAKC;CACD;AAED;;;GAGG;AACH;IACC,kBAEC;IAED,gBAwGC;CACD;AAED;;;GAGG;AACH;IAUC,gBAIC;CACD"}
|
package/dist/Command.svelte.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { insert_default_node, break_text_node } from './transforms.svelte.js';
|
|
2
2
|
import { can_switch_annotation_type } from './doc_utils.js';
|
|
3
|
-
import { is_selection_collapsed,
|
|
3
|
+
import { is_selection_collapsed, get_char_length, char_slice } from './utils.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Base class for commands that can be executed in response to user actions
|
|
@@ -153,7 +153,6 @@ export class ToggleAnnotationCommand extends Command {
|
|
|
153
153
|
/**
|
|
154
154
|
* Command that adds a new line character at the current caret position.
|
|
155
155
|
* Only works in text selections where newlines are allowed.
|
|
156
|
-
* Disabled on mobile browsers where Shift+Enter has different behavior.
|
|
157
156
|
*/
|
|
158
157
|
export class AddNewLineCommand extends Command {
|
|
159
158
|
is_enabled() {
|
|
@@ -162,7 +161,6 @@ export class AddNewLineCommand extends Command {
|
|
|
162
161
|
|
|
163
162
|
return (
|
|
164
163
|
this.context.editable &&
|
|
165
|
-
!is_mobile_browser() &&
|
|
166
164
|
selection?.type === 'text' &&
|
|
167
165
|
session.inspect(selection.path).allow_newlines
|
|
168
166
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"KeyMapper.svelte.d.ts","sourceRoot":"","sources":["../src/lib/KeyMapper.svelte.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"KeyMapper.svelte.d.ts","sourceRoot":"","sources":["../src/lib/KeyMapper.svelte.js"],"names":[],"mappings":"AAUA;;;;;GAKG;AACH,gDAgBC;AAuED;;;;;;;;;;;GAWG;AACH;IAEE,mBAAqB;IACrB,wBAA2B;IAG5B;;OAEG;IACH,8BAGC;IAED;;OAEG;IACH,iBAIC;IAED;;OAEG;IACH,iCAUC;CACD"}
|
package/dist/KeyMapper.svelte.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { is_virtual_keyboard_active } from './utils.js';
|
|
2
|
+
|
|
1
3
|
const MODIFIER_KEYS = ['meta', 'ctrl', 'alt', 'shift'];
|
|
2
4
|
const MODIFIER_EVENT_KEYS = {
|
|
3
5
|
meta: 'metaKey',
|
|
@@ -34,7 +36,7 @@ export function define_keymap(keymap) {
|
|
|
34
36
|
* Matches a keyboard event against a key combo string.
|
|
35
37
|
* Example: 'meta+e,ctrl+e' matches either (metaKey && key==='e') OR (ctrlKey && key==='e')
|
|
36
38
|
*/
|
|
37
|
-
function matches_key_combo(key_combo, event) {
|
|
39
|
+
function matches_key_combo(key_combo, event, virtual_keyboard_active = false) {
|
|
38
40
|
const alternatives = key_combo.split(',');
|
|
39
41
|
|
|
40
42
|
return alternatives.some((alternative) => {
|
|
@@ -42,14 +44,22 @@ function matches_key_combo(key_combo, event) {
|
|
|
42
44
|
const modifiers = parts.filter((part) => MODIFIER_KEYS.includes(part));
|
|
43
45
|
const non_modifier = parts.find((part) => !MODIFIER_KEYS.includes(part));
|
|
44
46
|
|
|
47
|
+
if (virtual_keyboard_active && modifiers.length > 0) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
|
|
45
51
|
// Check if all specified modifiers are pressed
|
|
46
52
|
const modifiers_match = modifiers.every((mod) => event[MODIFIER_EVENT_KEYS[mod]]);
|
|
47
53
|
|
|
48
54
|
// Check if no unspecified modifiers are pressed
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
55
|
+
// NOTE: On virtual keyboards (iOS / Anroid) modifier keys are just ignored, because
|
|
56
|
+
// they must be assumed accidental (e.g. Shift activated as a result of auto-capitalization)
|
|
57
|
+
const no_extra_modifiers = virtual_keyboard_active
|
|
58
|
+
? true
|
|
59
|
+
: MODIFIER_KEYS.every((mod) => {
|
|
60
|
+
if (modifiers.includes(mod)) return true; // This modifier is expected
|
|
61
|
+
return !event[MODIFIER_EVENT_KEYS[mod]]; // This modifier should NOT be pressed
|
|
62
|
+
});
|
|
53
63
|
|
|
54
64
|
// Check if the key matches
|
|
55
65
|
const key_matches = event.key.toLowerCase() === non_modifier;
|
|
@@ -65,8 +75,10 @@ function matches_key_combo(key_combo, event) {
|
|
|
65
75
|
* but don't crash the application.
|
|
66
76
|
*/
|
|
67
77
|
function handle_key_map(key_map, event) {
|
|
78
|
+
const virtual_keyboard_active = is_virtual_keyboard_active();
|
|
79
|
+
|
|
68
80
|
for (const [key_combo, commands] of Object.entries(key_map)) {
|
|
69
|
-
if (matches_key_combo(key_combo, event)) {
|
|
81
|
+
if (matches_key_combo(key_combo, event, virtual_keyboard_active)) {
|
|
70
82
|
// Find the first enabled command and execute it
|
|
71
83
|
const enabled_command = commands.find((cmd) => cmd.is_enabled());
|
|
72
84
|
if (enabled_command) {
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Detect if the
|
|
2
|
+
* Detect if the virtual keyboard is likely visible.
|
|
3
|
+
*
|
|
4
|
+
* This is a heuristic based on the visual viewport becoming smaller than the
|
|
5
|
+
* layout viewport.
|
|
6
|
+
*
|
|
7
|
+
* @returns {boolean} true if the virtual keyboard is likely active, false otherwise
|
|
8
|
+
*/
|
|
9
|
+
export function is_virtual_keyboard_active(): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Detect if the current browser is likely on a mobile device.
|
|
12
|
+
*
|
|
13
|
+
* This uses the user agent only so touch-capable laptops are not treated as
|
|
14
|
+
* mobile browsers.
|
|
15
|
+
*
|
|
3
16
|
* @returns {boolean} true if mobile browser, false otherwise
|
|
4
17
|
*/
|
|
5
18
|
export function is_mobile_browser(): boolean;
|
package/dist/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/lib/utils.js"],"names":[],"mappings":"AAMA
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/lib/utils.js"],"names":[],"mappings":"AAMA;;;;;;;GAOG;AACH,8CAFa,OAAO,CAanB;AAED;;;;;;;GAOG;AACH,qCAFa,OAAO,CASnB;AAGD;;;GAGG;AACH,6CAFa,OAAO,CAUnB;AAED;;;;;;;;;;;;;GAaG;AACH,qCARW,MAAM,GACJ,MAAM,CASlB;AAGD;;;;;;;;;;;;;;GAcG;AACH,iCATW,MAAM,SACN,MAAM,GACJ,MAAM,CAUlB;AAED;;;;;;;;;;;;;;GAcG;AACH,gCATW,MAAM,SACN,MAAM,QACN,MAAM,GACJ,MAAM,CAYlB;AAED;;;;;;;;;;;;;GAaG;AACH,0CARW,MAAM,gBACN,MAAM,GACJ,MAAM,CAmBlB;AAED;;;;;;;;;;;;;GAaG;AACH,0CARW,MAAM,eACN,MAAM,GACJ,MAAM,CAelB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,4DAZW,aAAa,eACb,MAAM,GACJ,CAAC,aAAa,EAAE,aAAa,CAAC,CA6C1C;AAED;;;;;;;;;;;;;GAaG;AACH,gDARW,aAAa,eACb,aAAa,GACX,aAAa,CA4CzB;AAED;;;;;;;;GAQG;AACH,qCANW,MAAM,GACJ,MAAM,CAUlB;AAMD;;;;;;;;;GASG;AACH,sDAHW,MAAM,GACJ,OAAO,CAQnB;AAED;;;;;;GAMG;AACH,oDAJW,MAAM,UACN,MAAM,GACJ,IAAI,CAQhB;AAED;;;;;;;;;;;;GAYG;AACH,qCANW,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,GACpB,MAAM,CAmBlB;AAED;;;;;;;;GAQG;AACH,kDANW,MAAM,GACJ,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAuBlC;AAED;;;;;;GAMG;AACH,+BAJW,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,KACtB,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,GACpB,OAAO,CAKnB;AAED,uEAgCC;AAED;;;;;GAKG;AACH,gDAHW,SAAS,GACP,cAAc,GAAG,IAAI,CAWjC;AAED,gEAMC;AApKD,6BAA8B,IAAI,CAAC;mCA3SsC,cAAc;+BAAd,cAAc;oCAAd,cAAc"}
|
package/dist/utils.js
CHANGED
|
@@ -5,20 +5,41 @@
|
|
|
5
5
|
const SEGMENTER = new Intl.Segmenter('en', { granularity: 'grapheme' });
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* Detect if the
|
|
8
|
+
* Detect if the virtual keyboard is likely visible.
|
|
9
|
+
*
|
|
10
|
+
* This is a heuristic based on the visual viewport becoming smaller than the
|
|
11
|
+
* layout viewport.
|
|
12
|
+
*
|
|
13
|
+
* @returns {boolean} true if the virtual keyboard is likely active, false otherwise
|
|
14
|
+
*/
|
|
15
|
+
export function is_virtual_keyboard_active() {
|
|
16
|
+
if (typeof window === 'undefined' || typeof document === 'undefined') {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const visual_viewport = window.visualViewport;
|
|
21
|
+
if (!visual_viewport) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return visual_viewport.height < document.documentElement.clientHeight;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Detect if the current browser is likely on a mobile device.
|
|
30
|
+
*
|
|
31
|
+
* This uses the user agent only so touch-capable laptops are not treated as
|
|
32
|
+
* mobile browsers.
|
|
33
|
+
*
|
|
9
34
|
* @returns {boolean} true if mobile browser, false otherwise
|
|
10
35
|
*/
|
|
11
36
|
export function is_mobile_browser() {
|
|
12
|
-
if (typeof
|
|
37
|
+
if (typeof navigator === 'undefined') {
|
|
13
38
|
return false;
|
|
14
39
|
}
|
|
15
40
|
|
|
16
41
|
const user_agent = navigator.userAgent;
|
|
17
|
-
return (
|
|
18
|
-
/iPhone|iPad|iPod|Android|Mobile/i.test(user_agent) ||
|
|
19
|
-
'ontouchstart' in window ||
|
|
20
|
-
navigator.maxTouchPoints > 0
|
|
21
|
-
);
|
|
42
|
+
return /iPhone|iPad|iPod|Android|Mobile/i.test(user_agent);
|
|
22
43
|
}
|
|
23
44
|
|
|
24
45
|
// ‼️‼️‼️‼️‼️‼️ UNUSED UTILITY BELOW ‼️‼️‼️‼️‼️‼️
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { insert_default_node, break_text_node } from './transforms.svelte.js';
|
|
2
2
|
import { can_switch_annotation_type } from './doc_utils.js';
|
|
3
|
-
import { is_selection_collapsed,
|
|
3
|
+
import { is_selection_collapsed, get_char_length, char_slice } from './utils.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Base class for commands that can be executed in response to user actions
|
|
@@ -153,7 +153,6 @@ export class ToggleAnnotationCommand extends Command {
|
|
|
153
153
|
/**
|
|
154
154
|
* Command that adds a new line character at the current caret position.
|
|
155
155
|
* Only works in text selections where newlines are allowed.
|
|
156
|
-
* Disabled on mobile browsers where Shift+Enter has different behavior.
|
|
157
156
|
*/
|
|
158
157
|
export class AddNewLineCommand extends Command {
|
|
159
158
|
is_enabled() {
|
|
@@ -162,7 +161,6 @@ export class AddNewLineCommand extends Command {
|
|
|
162
161
|
|
|
163
162
|
return (
|
|
164
163
|
this.context.editable &&
|
|
165
|
-
!is_mobile_browser() &&
|
|
166
164
|
selection?.type === 'text' &&
|
|
167
165
|
session.inspect(selection.path).allow_newlines
|
|
168
166
|
);
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { is_virtual_keyboard_active } from './utils.js';
|
|
2
|
+
|
|
1
3
|
const MODIFIER_KEYS = ['meta', 'ctrl', 'alt', 'shift'];
|
|
2
4
|
const MODIFIER_EVENT_KEYS = {
|
|
3
5
|
meta: 'metaKey',
|
|
@@ -34,7 +36,7 @@ export function define_keymap(keymap) {
|
|
|
34
36
|
* Matches a keyboard event against a key combo string.
|
|
35
37
|
* Example: 'meta+e,ctrl+e' matches either (metaKey && key==='e') OR (ctrlKey && key==='e')
|
|
36
38
|
*/
|
|
37
|
-
function matches_key_combo(key_combo, event) {
|
|
39
|
+
function matches_key_combo(key_combo, event, virtual_keyboard_active = false) {
|
|
38
40
|
const alternatives = key_combo.split(',');
|
|
39
41
|
|
|
40
42
|
return alternatives.some((alternative) => {
|
|
@@ -42,14 +44,22 @@ function matches_key_combo(key_combo, event) {
|
|
|
42
44
|
const modifiers = parts.filter((part) => MODIFIER_KEYS.includes(part));
|
|
43
45
|
const non_modifier = parts.find((part) => !MODIFIER_KEYS.includes(part));
|
|
44
46
|
|
|
47
|
+
if (virtual_keyboard_active && modifiers.length > 0) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
|
|
45
51
|
// Check if all specified modifiers are pressed
|
|
46
52
|
const modifiers_match = modifiers.every((mod) => event[MODIFIER_EVENT_KEYS[mod]]);
|
|
47
53
|
|
|
48
54
|
// Check if no unspecified modifiers are pressed
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
55
|
+
// NOTE: On virtual keyboards (iOS / Anroid) modifier keys are just ignored, because
|
|
56
|
+
// they must be assumed accidental (e.g. Shift activated as a result of auto-capitalization)
|
|
57
|
+
const no_extra_modifiers = virtual_keyboard_active
|
|
58
|
+
? true
|
|
59
|
+
: MODIFIER_KEYS.every((mod) => {
|
|
60
|
+
if (modifiers.includes(mod)) return true; // This modifier is expected
|
|
61
|
+
return !event[MODIFIER_EVENT_KEYS[mod]]; // This modifier should NOT be pressed
|
|
62
|
+
});
|
|
53
63
|
|
|
54
64
|
// Check if the key matches
|
|
55
65
|
const key_matches = event.key.toLowerCase() === non_modifier;
|
|
@@ -65,8 +75,10 @@ function matches_key_combo(key_combo, event) {
|
|
|
65
75
|
* but don't crash the application.
|
|
66
76
|
*/
|
|
67
77
|
function handle_key_map(key_map, event) {
|
|
78
|
+
const virtual_keyboard_active = is_virtual_keyboard_active();
|
|
79
|
+
|
|
68
80
|
for (const [key_combo, commands] of Object.entries(key_map)) {
|
|
69
|
-
if (matches_key_combo(key_combo, event)) {
|
|
81
|
+
if (matches_key_combo(key_combo, event, virtual_keyboard_active)) {
|
|
70
82
|
// Find the first enabled command and execute it
|
|
71
83
|
const enabled_command = commands.find((cmd) => cmd.is_enabled());
|
|
72
84
|
if (enabled_command) {
|
package/src/lib/utils.js
CHANGED
|
@@ -5,20 +5,41 @@
|
|
|
5
5
|
const SEGMENTER = new Intl.Segmenter('en', { granularity: 'grapheme' });
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* Detect if the
|
|
8
|
+
* Detect if the virtual keyboard is likely visible.
|
|
9
|
+
*
|
|
10
|
+
* This is a heuristic based on the visual viewport becoming smaller than the
|
|
11
|
+
* layout viewport.
|
|
12
|
+
*
|
|
13
|
+
* @returns {boolean} true if the virtual keyboard is likely active, false otherwise
|
|
14
|
+
*/
|
|
15
|
+
export function is_virtual_keyboard_active() {
|
|
16
|
+
if (typeof window === 'undefined' || typeof document === 'undefined') {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const visual_viewport = window.visualViewport;
|
|
21
|
+
if (!visual_viewport) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return visual_viewport.height < document.documentElement.clientHeight;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Detect if the current browser is likely on a mobile device.
|
|
30
|
+
*
|
|
31
|
+
* This uses the user agent only so touch-capable laptops are not treated as
|
|
32
|
+
* mobile browsers.
|
|
33
|
+
*
|
|
9
34
|
* @returns {boolean} true if mobile browser, false otherwise
|
|
10
35
|
*/
|
|
11
36
|
export function is_mobile_browser() {
|
|
12
|
-
if (typeof
|
|
37
|
+
if (typeof navigator === 'undefined') {
|
|
13
38
|
return false;
|
|
14
39
|
}
|
|
15
40
|
|
|
16
41
|
const user_agent = navigator.userAgent;
|
|
17
|
-
return (
|
|
18
|
-
/iPhone|iPad|iPod|Android|Mobile/i.test(user_agent) ||
|
|
19
|
-
'ontouchstart' in window ||
|
|
20
|
-
navigator.maxTouchPoints > 0
|
|
21
|
-
);
|
|
42
|
+
return /iPhone|iPad|iPod|Android|Mobile/i.test(user_agent);
|
|
22
43
|
}
|
|
23
44
|
|
|
24
45
|
// ‼️‼️‼️‼️‼️‼️ UNUSED UTILITY BELOW ‼️‼️‼️‼️‼️‼️
|