@portabletext/plugin-typography 0.0.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/LICENSE +21 -0
- package/README.md +122 -0
- package/dist/index.cjs +235 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +246 -0
- package/dist/index.d.ts +246 -0
- package/dist/index.js +238 -0
- package/dist/index.js.map +1 -0
- package/package.json +84 -0
- package/src/create-decorator-guard.ts +58 -0
- package/src/disallow-in-code.feature +54 -0
- package/src/disallow-in-code.test.tsx +41 -0
- package/src/global.d.ts +4 -0
- package/src/index.ts +3 -0
- package/src/input-rule.ellipsis.feature +96 -0
- package/src/input-rule.ellipsis.test.tsx +31 -0
- package/src/input-rule.em-dash.feature +104 -0
- package/src/input-rule.em-dash.test.tsx +31 -0
- package/src/input-rule.multiplication.feature +26 -0
- package/src/input-rule.multiplication.test.tsx +31 -0
- package/src/input-rule.smart-quotes.feature +73 -0
- package/src/input-rule.smart-quotes.test.tsx +31 -0
- package/src/input-rules.typography.ts +190 -0
- package/src/plugin.typography.tsx +182 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
Feature: Disallow in code
|
|
2
|
+
|
|
3
|
+
Background:
|
|
4
|
+
Given the editor is focused
|
|
5
|
+
And a global keymap
|
|
6
|
+
|
|
7
|
+
Scenario Outline: Decorated text
|
|
8
|
+
Given the text <text>
|
|
9
|
+
And "code" around <decorated>
|
|
10
|
+
When the caret is put <position>
|
|
11
|
+
And "->" is typed
|
|
12
|
+
Then the text is <new text>
|
|
13
|
+
|
|
14
|
+
Examples:
|
|
15
|
+
| text | decorated | position | new text |
|
|
16
|
+
| "foo" | "foo" | after "foo" | "foo->" |
|
|
17
|
+
| "foo bar baz" | "bar" | after "bar" | "foo ,bar->, baz" |
|
|
18
|
+
| "foo bar baz" | "bar" | before "bar" | "foo →,bar, baz" |
|
|
19
|
+
| "foo bar baz" | "bar" | before "ar baz" | "foo ,b->ar, baz" |
|
|
20
|
+
|
|
21
|
+
Scenario Outline: Partially decorated text
|
|
22
|
+
Given the text "foo bar2x baz"
|
|
23
|
+
And "code" around "bar2x"
|
|
24
|
+
When the caret is put after "bar2x"
|
|
25
|
+
And "2" is typed
|
|
26
|
+
Then the text is "foo ,bar2x2, baz"
|
|
27
|
+
|
|
28
|
+
Scenario Outline: Partially decorated text with decorator toggled off
|
|
29
|
+
Given the text <text>
|
|
30
|
+
And "code" around <decorated>
|
|
31
|
+
When the caret is put <position>
|
|
32
|
+
And "code" is toggled
|
|
33
|
+
And <inserted text> is typed
|
|
34
|
+
Then the text is <new text>
|
|
35
|
+
|
|
36
|
+
Examples:
|
|
37
|
+
| text | decorated | position | inserted text | new text |
|
|
38
|
+
| "foo bar baz" | "bar" | after "bar" | "2x2" | "foo ,bar,2×2 baz" |
|
|
39
|
+
| "foo bar2 baz" | "bar2" | after "bar2" | "x2" | "foo ,bar2,x2 baz" |
|
|
40
|
+
| "foo bar2x baz" | "bar2x" | after "bar2x" | "2" | "foo ,bar2x,2 baz" |
|
|
41
|
+
|
|
42
|
+
Scenario Outline: Decorated and annotated text
|
|
43
|
+
Given the text "foo bar baz"
|
|
44
|
+
And "code" around "bar"
|
|
45
|
+
And a "link" "l1" around "bar"
|
|
46
|
+
When the caret is put <position>
|
|
47
|
+
And "->" is typed
|
|
48
|
+
Then the text is <new text>
|
|
49
|
+
|
|
50
|
+
Examples:
|
|
51
|
+
| position | new text |
|
|
52
|
+
| after "bar" | "foo ,bar,→ baz" |
|
|
53
|
+
| before "bar" | "foo →,bar, baz" |
|
|
54
|
+
| before "ar baz" | "foo ,b->ar, baz" |
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import {parameterTypes} from '@portabletext/editor/test'
|
|
2
|
+
import {
|
|
3
|
+
createTestEditor,
|
|
4
|
+
stepDefinitions,
|
|
5
|
+
type Context,
|
|
6
|
+
} from '@portabletext/editor/test/vitest'
|
|
7
|
+
import {defineSchema} from '@portabletext/schema'
|
|
8
|
+
import {Before} from 'racejar'
|
|
9
|
+
import {Feature} from 'racejar/vitest'
|
|
10
|
+
import {createDecoratorGuard} from './create-decorator-guard'
|
|
11
|
+
import disallowInCodeFeature from './disallow-in-code.feature?raw'
|
|
12
|
+
import {TypographyPlugin} from './plugin.typography'
|
|
13
|
+
|
|
14
|
+
const codeGuard = createDecoratorGuard({
|
|
15
|
+
decorators: ({schema}) =>
|
|
16
|
+
schema.decorators.flatMap((decorator) =>
|
|
17
|
+
decorator.name === 'code' ? [decorator.name] : [],
|
|
18
|
+
),
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
Feature({
|
|
22
|
+
hooks: [
|
|
23
|
+
Before(async (context: Context) => {
|
|
24
|
+
const {editor, locator} = await createTestEditor({
|
|
25
|
+
children: (
|
|
26
|
+
<TypographyPlugin guard={codeGuard} rules={{multiplication: 'on'}} />
|
|
27
|
+
),
|
|
28
|
+
schemaDefinition: defineSchema({
|
|
29
|
+
decorators: [{name: 'strong'}, {name: 'code'}],
|
|
30
|
+
annotations: [{name: 'link'}],
|
|
31
|
+
}),
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
context.locator = locator
|
|
35
|
+
context.editor = editor
|
|
36
|
+
}),
|
|
37
|
+
],
|
|
38
|
+
featureText: disallowInCodeFeature,
|
|
39
|
+
stepDefinitions,
|
|
40
|
+
parameterTypes,
|
|
41
|
+
})
|
package/src/global.d.ts
ADDED
package/src/index.ts
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
Feature: Ellipsis Input Rule
|
|
2
|
+
|
|
3
|
+
Background:
|
|
4
|
+
Given the editor is focused
|
|
5
|
+
And a global keymap
|
|
6
|
+
|
|
7
|
+
Scenario Outline: Inserting ellipsis in unformatted text
|
|
8
|
+
Given the text <text>
|
|
9
|
+
# The "When {string} is inserted" step inserts all characters at once to
|
|
10
|
+
# mimic how insert.text behaves on Android
|
|
11
|
+
When <inserted text> is inserted
|
|
12
|
+
Then the text is <before undo>
|
|
13
|
+
When undo is performed
|
|
14
|
+
Then the text is <after undo>
|
|
15
|
+
|
|
16
|
+
Examples:
|
|
17
|
+
| text | inserted text | before undo | after undo |
|
|
18
|
+
| ".." | "." | "…" | "..." |
|
|
19
|
+
| "" | "..." | "…" | "..." |
|
|
20
|
+
| "foo" | "..." | "foo…" | "foo..." |
|
|
21
|
+
| "" | "foo..." | "foo…" | "foo..." |
|
|
22
|
+
| "foo.." | ".bar" | "foo…bar" | "foo...bar" |
|
|
23
|
+
| "" | "foo...bar..." | "foo…bar…" | "foo...bar..." |
|
|
24
|
+
| "foo...bar..." | "baz..." | "foo...bar...baz…" | "foo...bar...baz..." |
|
|
25
|
+
|
|
26
|
+
Scenario: Inserting ellipsis inside a decorator
|
|
27
|
+
Given the text "foo.."
|
|
28
|
+
And "strong" around "foo.."
|
|
29
|
+
When the caret is put after "foo.."
|
|
30
|
+
And "." is typed
|
|
31
|
+
Then the text is "foo…"
|
|
32
|
+
And "foo…" has marks "strong"
|
|
33
|
+
|
|
34
|
+
Scenario: Inserting ellipsis at the edge of a decorator
|
|
35
|
+
Given the text "foo.."
|
|
36
|
+
And "strong" around "foo"
|
|
37
|
+
When the caret is put after "foo.."
|
|
38
|
+
And "." is typed
|
|
39
|
+
Then the text is "foo,…"
|
|
40
|
+
And "foo" has marks "strong"
|
|
41
|
+
And "…" has no marks
|
|
42
|
+
|
|
43
|
+
Scenario: Inserting ellipsis inside an annotation
|
|
44
|
+
Given the text "foo.."
|
|
45
|
+
And a "link" "l1" around "foo.."
|
|
46
|
+
When the caret is put after "foo.."
|
|
47
|
+
And "." is typed
|
|
48
|
+
Then the text is "foo…"
|
|
49
|
+
And "foo…" has marks "l1"
|
|
50
|
+
|
|
51
|
+
Scenario: Inserting ellipsis at the edge of an annotation
|
|
52
|
+
Given the text "foo.."
|
|
53
|
+
And a "link" "l1" around "foo"
|
|
54
|
+
When the caret is put after "foo.."
|
|
55
|
+
And "." is typed
|
|
56
|
+
Then the text is "foo,…"
|
|
57
|
+
And "foo" has marks "l1"
|
|
58
|
+
And "…" has no marks
|
|
59
|
+
|
|
60
|
+
Scenario Outline: Smart undo with Backspace
|
|
61
|
+
Given the text <text>
|
|
62
|
+
When <inserted text> is inserted
|
|
63
|
+
And "{Backspace}" is pressed
|
|
64
|
+
Then the text is <new text>
|
|
65
|
+
|
|
66
|
+
Examples:
|
|
67
|
+
| text | inserted text | new text |
|
|
68
|
+
| ".." | "." | "..." |
|
|
69
|
+
| "" | "..." | "..." |
|
|
70
|
+
| "foo" | "..." | "foo..." |
|
|
71
|
+
| "" | "foo..." | "foo..." |
|
|
72
|
+
| "foo.." | ".bar" | "foo...bar" |
|
|
73
|
+
| "" | "foo...bar..." | "foo...bar..." |
|
|
74
|
+
| "foo...bar..." | "baz..." | "foo...bar...baz..." |
|
|
75
|
+
|
|
76
|
+
Scenario Outline: Smart undo aborted after text changes
|
|
77
|
+
Given the text <text>
|
|
78
|
+
When <inserted text> is inserted
|
|
79
|
+
And <new text> is inserted
|
|
80
|
+
And "{Backspace}" is pressed
|
|
81
|
+
Then the text is <final text>
|
|
82
|
+
|
|
83
|
+
Examples:
|
|
84
|
+
| text | inserted text | new text | final text |
|
|
85
|
+
| "" | "..." | "new" | "…ne" |
|
|
86
|
+
|
|
87
|
+
Scenario Outline: Smart undo aborted after selection changes
|
|
88
|
+
Given the text <text>
|
|
89
|
+
When <inserted text> is inserted
|
|
90
|
+
And "{ArrowLeft}" is pressed
|
|
91
|
+
And "{Backspace}" is pressed
|
|
92
|
+
Then the text is <final text>
|
|
93
|
+
|
|
94
|
+
Examples:
|
|
95
|
+
| text | inserted text | final text |
|
|
96
|
+
| "foo" | "..." | "fo…" |
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {parameterTypes} from '@portabletext/editor/test'
|
|
2
|
+
import {
|
|
3
|
+
createTestEditor,
|
|
4
|
+
stepDefinitions,
|
|
5
|
+
type Context,
|
|
6
|
+
} from '@portabletext/editor/test/vitest'
|
|
7
|
+
import {defineSchema} from '@portabletext/schema'
|
|
8
|
+
import {Before} from 'racejar'
|
|
9
|
+
import {Feature} from 'racejar/vitest'
|
|
10
|
+
import ellipsisFeature from './input-rule.ellipsis.feature?raw'
|
|
11
|
+
import {TypographyPlugin} from './plugin.typography'
|
|
12
|
+
|
|
13
|
+
Feature({
|
|
14
|
+
hooks: [
|
|
15
|
+
Before(async (context: Context) => {
|
|
16
|
+
const {editor, locator} = await createTestEditor({
|
|
17
|
+
children: <TypographyPlugin />,
|
|
18
|
+
schemaDefinition: defineSchema({
|
|
19
|
+
decorators: [{name: 'strong'}],
|
|
20
|
+
annotations: [{name: 'link'}],
|
|
21
|
+
}),
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
context.locator = locator
|
|
25
|
+
context.editor = editor
|
|
26
|
+
}),
|
|
27
|
+
],
|
|
28
|
+
featureText: ellipsisFeature,
|
|
29
|
+
stepDefinitions,
|
|
30
|
+
parameterTypes,
|
|
31
|
+
})
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
Feature: Em Dash Input Rule
|
|
2
|
+
|
|
3
|
+
Background:
|
|
4
|
+
Given the editor is focused
|
|
5
|
+
And a global keymap
|
|
6
|
+
|
|
7
|
+
Scenario Outline: Inserting em dash in unformatted text
|
|
8
|
+
Given the text <text>
|
|
9
|
+
# The "When {string} is inserted" step inserts all characters at once to
|
|
10
|
+
# mimic how insert.text behaves on Android
|
|
11
|
+
When <inserted text> is inserted
|
|
12
|
+
Then the text is <before undo>
|
|
13
|
+
When undo is performed
|
|
14
|
+
Then the text is <after undo>
|
|
15
|
+
|
|
16
|
+
Examples:
|
|
17
|
+
| text | inserted text | before undo | after undo |
|
|
18
|
+
| "-" | "-" | "—" | "--" |
|
|
19
|
+
| "" | "--" | "—" | "--" |
|
|
20
|
+
| "foo" | "--" | "foo—" | "foo--" |
|
|
21
|
+
| "" | "foo--" | "foo—" | "foo--" |
|
|
22
|
+
| "foo-" | "-bar" | "foo—bar" | "foo--bar" |
|
|
23
|
+
| "" | "foo--bar--" | "foo—bar—" | "foo--bar--" |
|
|
24
|
+
| "foo--bar--" | "baz--" | "foo--bar--baz—" | "foo--bar--baz--" |
|
|
25
|
+
|
|
26
|
+
Scenario: Inserting em dash inside a decorator
|
|
27
|
+
Given the text "foo-"
|
|
28
|
+
And "strong" around "foo-"
|
|
29
|
+
When the caret is put after "foo-"
|
|
30
|
+
And "-" is typed
|
|
31
|
+
Then the text is "foo—"
|
|
32
|
+
And "foo—" has marks "strong"
|
|
33
|
+
|
|
34
|
+
Scenario: Inserting em dash at the edge of a decorator
|
|
35
|
+
Given the text "foo-"
|
|
36
|
+
And "strong" around "foo"
|
|
37
|
+
When the caret is put after "foo-"
|
|
38
|
+
And "-" is typed
|
|
39
|
+
Then the text is "foo,—"
|
|
40
|
+
And "foo" has marks "strong"
|
|
41
|
+
And "—" has no marks
|
|
42
|
+
|
|
43
|
+
Scenario: Inserting em dash inside an annotation
|
|
44
|
+
Given the text "foo-"
|
|
45
|
+
And a "link" "l1" around "foo-"
|
|
46
|
+
When the caret is put after "foo-"
|
|
47
|
+
And "-" is typed
|
|
48
|
+
Then the text is "foo—"
|
|
49
|
+
And "foo—" has marks "l1"
|
|
50
|
+
|
|
51
|
+
Scenario: Inserting em dash halfway inside an annotation
|
|
52
|
+
Given the text "foo-"
|
|
53
|
+
And a "link" "l1" around "foo-"
|
|
54
|
+
When the caret is put after "foo-"
|
|
55
|
+
And "-" is typed
|
|
56
|
+
Then the text is "foo—"
|
|
57
|
+
And "foo—" has marks "l1"
|
|
58
|
+
|
|
59
|
+
Scenario: Inserting em dash at the edge of an annotation
|
|
60
|
+
Given the text "foo-"
|
|
61
|
+
And a "link" "l1" around "foo"
|
|
62
|
+
When the caret is put after "foo-"
|
|
63
|
+
And "-" is typed
|
|
64
|
+
Then the text is "foo,—"
|
|
65
|
+
And "foo" has marks "l1"
|
|
66
|
+
And "—" has no marks
|
|
67
|
+
|
|
68
|
+
Scenario Outline: Smart undo with Backspace
|
|
69
|
+
Given the text <text>
|
|
70
|
+
When <inserted text> is inserted
|
|
71
|
+
And "{Backspace}" is pressed
|
|
72
|
+
Then the text is <new text>
|
|
73
|
+
|
|
74
|
+
Examples:
|
|
75
|
+
| text | inserted text | new text |
|
|
76
|
+
| "-" | "-" | "--" |
|
|
77
|
+
| "" | "--" | "--" |
|
|
78
|
+
| "foo" | "--" | "foo--" |
|
|
79
|
+
| "" | "foo--" | "foo--" |
|
|
80
|
+
| "foo-" | "-bar" | "foo--bar" |
|
|
81
|
+
| "" | "foo--bar--" | "foo--bar--" |
|
|
82
|
+
| "foo--bar--" | "baz--" | "foo--bar--baz--" |
|
|
83
|
+
|
|
84
|
+
Scenario Outline: Smart undo aborted after text changes
|
|
85
|
+
Given the text <text>
|
|
86
|
+
When <inserted text> is inserted
|
|
87
|
+
And <new text> is inserted
|
|
88
|
+
And "{Backspace}" is pressed
|
|
89
|
+
Then the text is <final text>
|
|
90
|
+
|
|
91
|
+
Examples:
|
|
92
|
+
| text | inserted text | new text | final text |
|
|
93
|
+
| "" | "--" | "new" | "—ne" |
|
|
94
|
+
|
|
95
|
+
Scenario Outline: Smart undo aborted after selection changes
|
|
96
|
+
Given the text <text>
|
|
97
|
+
When <inserted text> is inserted
|
|
98
|
+
And "{ArrowLeft}" is pressed
|
|
99
|
+
And "{Backspace}" is pressed
|
|
100
|
+
Then the text is <final text>
|
|
101
|
+
|
|
102
|
+
Examples:
|
|
103
|
+
| text | inserted text | final text |
|
|
104
|
+
| "foo" | "--" | "fo—" |
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {parameterTypes} from '@portabletext/editor/test'
|
|
2
|
+
import {
|
|
3
|
+
createTestEditor,
|
|
4
|
+
stepDefinitions,
|
|
5
|
+
type Context,
|
|
6
|
+
} from '@portabletext/editor/test/vitest'
|
|
7
|
+
import {defineSchema} from '@portabletext/schema'
|
|
8
|
+
import {Before} from 'racejar'
|
|
9
|
+
import {Feature} from 'racejar/vitest'
|
|
10
|
+
import emDashFeature from './input-rule.em-dash.feature?raw'
|
|
11
|
+
import {TypographyPlugin} from './plugin.typography'
|
|
12
|
+
|
|
13
|
+
Feature({
|
|
14
|
+
hooks: [
|
|
15
|
+
Before(async (context: Context) => {
|
|
16
|
+
const {editor, locator} = await createTestEditor({
|
|
17
|
+
children: <TypographyPlugin />,
|
|
18
|
+
schemaDefinition: defineSchema({
|
|
19
|
+
decorators: [{name: 'strong'}],
|
|
20
|
+
annotations: [{name: 'link'}],
|
|
21
|
+
}),
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
context.locator = locator
|
|
25
|
+
context.editor = editor
|
|
26
|
+
}),
|
|
27
|
+
],
|
|
28
|
+
featureText: emDashFeature,
|
|
29
|
+
stepDefinitions,
|
|
30
|
+
parameterTypes,
|
|
31
|
+
})
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
Feature: Multiplication Input Rule
|
|
2
|
+
|
|
3
|
+
Background:
|
|
4
|
+
Given the editor is focused
|
|
5
|
+
And a global keymap
|
|
6
|
+
|
|
7
|
+
Scenario Outline: Inserting multiplication sign
|
|
8
|
+
Given the text <text>
|
|
9
|
+
When <inserted text> is inserted
|
|
10
|
+
Then the text is <new text>
|
|
11
|
+
|
|
12
|
+
Examples:
|
|
13
|
+
| text | inserted text | new text |
|
|
14
|
+
| "" | "1*2" | "1×2" |
|
|
15
|
+
| "" | "1*2*3" | "1×2×3" |
|
|
16
|
+
|
|
17
|
+
Scenario Outline: Inserting multiplication sign and writing afterwards
|
|
18
|
+
Given the text <text>
|
|
19
|
+
When <inserted text> is inserted
|
|
20
|
+
And "new" is typed
|
|
21
|
+
Then the text is <new text>
|
|
22
|
+
|
|
23
|
+
Examples:
|
|
24
|
+
| text | inserted text | new text |
|
|
25
|
+
| "" | "1*2" | "1×2new" |
|
|
26
|
+
| "" | "1*2*3" | "1×2×3new" |
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {parameterTypes} from '@portabletext/editor/test'
|
|
2
|
+
import {
|
|
3
|
+
createTestEditor,
|
|
4
|
+
stepDefinitions,
|
|
5
|
+
type Context,
|
|
6
|
+
} from '@portabletext/editor/test/vitest'
|
|
7
|
+
import {defineSchema} from '@portabletext/schema'
|
|
8
|
+
import {Before} from 'racejar'
|
|
9
|
+
import {Feature} from 'racejar/vitest'
|
|
10
|
+
import multiplicationFeature from './input-rule.multiplication.feature?raw'
|
|
11
|
+
import {TypographyPlugin} from './plugin.typography'
|
|
12
|
+
|
|
13
|
+
Feature({
|
|
14
|
+
hooks: [
|
|
15
|
+
Before(async (context: Context) => {
|
|
16
|
+
const {editor, locator} = await createTestEditor({
|
|
17
|
+
children: <TypographyPlugin rules={{multiplication: 'on'}} />,
|
|
18
|
+
schemaDefinition: defineSchema({
|
|
19
|
+
decorators: [{name: 'strong'}],
|
|
20
|
+
annotations: [{name: 'link'}],
|
|
21
|
+
}),
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
context.locator = locator
|
|
25
|
+
context.editor = editor
|
|
26
|
+
}),
|
|
27
|
+
],
|
|
28
|
+
featureText: multiplicationFeature,
|
|
29
|
+
stepDefinitions,
|
|
30
|
+
parameterTypes,
|
|
31
|
+
})
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
Feature: Smart Quotes Input Rule
|
|
2
|
+
|
|
3
|
+
Background:
|
|
4
|
+
Given the editor is focused
|
|
5
|
+
And a global keymap
|
|
6
|
+
|
|
7
|
+
Scenario Outline: Typing turns double quotes into smart quotes
|
|
8
|
+
Given the text <text>
|
|
9
|
+
When <inserted text> is typed
|
|
10
|
+
Then the text is <new text>
|
|
11
|
+
|
|
12
|
+
Examples:
|
|
13
|
+
| text | inserted text | new text |
|
|
14
|
+
| "" | "\"foo\"" | "“foo”" |
|
|
15
|
+
| "“foo”" | " \"bar\"" | "“foo” “bar”" |
|
|
16
|
+
| "" | "\"foo\" \"bar\"" | "“foo” “bar”" |
|
|
17
|
+
|
|
18
|
+
Scenario Outline: Inserting double smart quotes in unformatted text
|
|
19
|
+
Given the text <text>
|
|
20
|
+
# The "When {string} is inserted" step inserts all characters at once to
|
|
21
|
+
# mimic how insert.text behaves on Android
|
|
22
|
+
When <inserted text> is inserted
|
|
23
|
+
Then the text is <before undo>
|
|
24
|
+
When undo is performed
|
|
25
|
+
Then the text is <after undo>
|
|
26
|
+
|
|
27
|
+
Examples:
|
|
28
|
+
| text | inserted text | before undo | after undo |
|
|
29
|
+
| "" | "\"" | "“" | """ |
|
|
30
|
+
| "" | "\"\"" | "““" | """" |
|
|
31
|
+
| "" | "\"\"\"" | "“““" | """"" |
|
|
32
|
+
| "”" | "\"" | "””" | "”"" |
|
|
33
|
+
# | "”" | "\"\"" | "”””" | "””"" |
|
|
34
|
+
| "" | "\"foo\"" | "“foo”" | ""foo"" |
|
|
35
|
+
| "“foo" | "\"" | "“foo”" | "“foo"" |
|
|
36
|
+
| ""foo" | "\"" | ""foo”" | ""foo"" |
|
|
37
|
+
| ""foo"" | "\"bar\"" | ""foo"“bar”" | ""foo""bar"" |
|
|
38
|
+
| "“foo”" | "\"" | "“foo””" | "“foo”"" |
|
|
39
|
+
|
|
40
|
+
# | "“foo”" | "\"\"" | "“foo”””" | "“foo”""" |
|
|
41
|
+
Scenario Outline: Inserting single smart quotes in unformatted text
|
|
42
|
+
Given the text <text>
|
|
43
|
+
# The "When {string} is inserted" step inserts all characters at once to
|
|
44
|
+
# mimic how insert.text behaves on Android
|
|
45
|
+
When <inserted text> is inserted
|
|
46
|
+
Then the text is <before undo>
|
|
47
|
+
When undo is performed
|
|
48
|
+
Then the text is <after undo>
|
|
49
|
+
|
|
50
|
+
Examples:
|
|
51
|
+
| text | inserted text | before undo | after undo |
|
|
52
|
+
| "" | "'" | "‘" | "'" |
|
|
53
|
+
| "" | "'foo'" | "‘foo’" | "'foo'" |
|
|
54
|
+
| "‘foo" | "'" | "‘foo’" | "‘foo'" |
|
|
55
|
+
| "'foo" | "'" | "'foo’" | "'foo'" |
|
|
56
|
+
| "'foo'" | "'bar'" | "'foo'‘bar’" | "'foo''bar'" |
|
|
57
|
+
|
|
58
|
+
Scenario: Mixed quotes
|
|
59
|
+
Given the text ""
|
|
60
|
+
When "\"'sorry' you say?\" she asked" is typed
|
|
61
|
+
Then the text is "“‘sorry’ you say?” she asked"
|
|
62
|
+
|
|
63
|
+
Scenario Outline: Contractions
|
|
64
|
+
When <text> is typed
|
|
65
|
+
Then the text is <new text>
|
|
66
|
+
|
|
67
|
+
Examples:
|
|
68
|
+
| text | new text |
|
|
69
|
+
| "it's" | "it’s" |
|
|
70
|
+
| "don't" | "don’t" |
|
|
71
|
+
| "won't" | "won’t" |
|
|
72
|
+
| "I'm" | "I’m" |
|
|
73
|
+
| "you're" | "you’re" |
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {parameterTypes} from '@portabletext/editor/test'
|
|
2
|
+
import {
|
|
3
|
+
createTestEditor,
|
|
4
|
+
stepDefinitions,
|
|
5
|
+
type Context,
|
|
6
|
+
} from '@portabletext/editor/test/vitest'
|
|
7
|
+
import {defineSchema} from '@portabletext/schema'
|
|
8
|
+
import {Before} from 'racejar'
|
|
9
|
+
import {Feature} from 'racejar/vitest'
|
|
10
|
+
import smartQuotesFeature from './input-rule.smart-quotes.feature?raw'
|
|
11
|
+
import {TypographyPlugin} from './plugin.typography'
|
|
12
|
+
|
|
13
|
+
Feature({
|
|
14
|
+
hooks: [
|
|
15
|
+
Before(async (context: Context) => {
|
|
16
|
+
const {editor, locator} = await createTestEditor({
|
|
17
|
+
children: <TypographyPlugin />,
|
|
18
|
+
schemaDefinition: defineSchema({
|
|
19
|
+
decorators: [{name: 'strong'}],
|
|
20
|
+
annotations: [{name: 'link'}],
|
|
21
|
+
}),
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
context.locator = locator
|
|
25
|
+
context.editor = editor
|
|
26
|
+
}),
|
|
27
|
+
],
|
|
28
|
+
featureText: smartQuotesFeature,
|
|
29
|
+
stepDefinitions,
|
|
30
|
+
parameterTypes,
|
|
31
|
+
})
|