@wordpress/annotations 3.43.1-next.v.202604091042.0 → 3.44.0
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/CHANGELOG.md +2 -0
- package/build/block/index.cjs +8 -7
- package/build/block/index.cjs.map +3 -3
- package/build/format/annotation.cjs +25 -10
- package/build/format/annotation.cjs.map +3 -3
- package/build/format/index.cjs +3 -1
- package/build/format/index.cjs.map +3 -3
- package/build/index.cjs +2 -1
- package/build/index.cjs.map +2 -2
- package/build/store/actions.cjs +3 -2
- package/build/store/actions.cjs.map +3 -3
- package/build/store/constants.cjs +2 -1
- package/build/store/constants.cjs.map +3 -3
- package/build/store/index.cjs +2 -1
- package/build/store/index.cjs.map +3 -3
- package/build/store/reducer.cjs +13 -8
- package/build/store/reducer.cjs.map +3 -3
- package/build/store/selectors.cjs +9 -4
- package/build/store/selectors.cjs.map +3 -3
- package/build/types.cjs +19 -0
- package/build/types.cjs.map +7 -0
- package/build-module/block/index.mjs +6 -7
- package/build-module/block/index.mjs.map +3 -3
- package/build-module/format/annotation.mjs +24 -10
- package/build-module/format/annotation.mjs.map +3 -3
- package/build-module/format/index.mjs +1 -1
- package/build-module/format/index.mjs.map +3 -3
- package/build-module/index.mjs +1 -1
- package/build-module/index.mjs.map +1 -1
- package/build-module/store/actions.mjs +2 -2
- package/build-module/store/actions.mjs.map +3 -3
- package/build-module/store/constants.mjs +1 -1
- package/build-module/store/constants.mjs.map +3 -3
- package/build-module/store/index.mjs +1 -1
- package/build-module/store/index.mjs.map +3 -3
- package/build-module/store/reducer.mjs +12 -8
- package/build-module/store/reducer.mjs.map +3 -3
- package/build-module/store/selectors.mjs +8 -4
- package/build-module/store/selectors.mjs.map +3 -3
- package/build-module/types.mjs +1 -0
- package/build-module/types.mjs.map +7 -0
- package/build-types/block/index.d.ts +2 -0
- package/build-types/block/index.d.ts.map +1 -0
- package/build-types/format/annotation.d.ts +19 -0
- package/build-types/format/annotation.d.ts.map +1 -0
- package/build-types/format/index.d.ts +2 -0
- package/build-types/format/index.d.ts.map +1 -0
- package/build-types/index.d.ts +7 -0
- package/build-types/index.d.ts.map +1 -0
- package/build-types/store/actions.d.ts +48 -0
- package/build-types/store/actions.d.ts.map +1 -0
- package/build-types/store/constants.d.ts +5 -0
- package/build-types/store/constants.d.ts.map +1 -0
- package/build-types/store/index.d.ts +9 -0
- package/build-types/store/index.d.ts.map +1 -0
- package/build-types/store/reducer.d.ts +14 -0
- package/build-types/store/reducer.d.ts.map +1 -0
- package/build-types/store/selectors.d.ts +34 -0
- package/build-types/store/selectors.d.ts.map +1 -0
- package/build-types/types.d.ts +113 -0
- package/build-types/types.d.ts.map +1 -0
- package/package.json +8 -6
- package/src/block/index.ts +52 -0
- package/src/format/{annotation.js → annotation.ts} +69 -34
- package/src/format/{index.js → index.ts} +1 -1
- package/src/store/actions.ts +105 -0
- package/src/store/{constants.js → constants.ts} +0 -2
- package/src/store/{index.js → index.ts} +0 -2
- package/src/store/{reducer.js → reducer.ts} +58 -34
- package/src/store/{selectors.js → selectors.ts} +36 -22
- package/src/store/test/{reducer.js → reducer.ts} +17 -5
- package/src/types.ts +133 -0
- package/src/block/index.js +0 -40
- package/src/store/actions.js +0 -105
- /package/src/{index.js → index.ts} +0 -0
|
@@ -1,13 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal dependencies
|
|
3
|
+
*/
|
|
4
|
+
import type {
|
|
5
|
+
AnnotationAction,
|
|
6
|
+
AnnotationsState,
|
|
7
|
+
Annotation,
|
|
8
|
+
AnnotationRange,
|
|
9
|
+
} from '../types';
|
|
10
|
+
|
|
1
11
|
/**
|
|
2
12
|
* Filters an array based on the predicate, but keeps the reference the same if
|
|
3
13
|
* the array hasn't changed.
|
|
4
14
|
*
|
|
5
|
-
* @param
|
|
6
|
-
* @param
|
|
7
|
-
*
|
|
8
|
-
* @return
|
|
15
|
+
* @param collection The collection to filter.
|
|
16
|
+
* @param predicate Function that determines if the item should stay
|
|
17
|
+
* in the array.
|
|
18
|
+
* @return Filtered array.
|
|
9
19
|
*/
|
|
10
|
-
function filterWithReference
|
|
20
|
+
function filterWithReference< T >(
|
|
21
|
+
collection: T[],
|
|
22
|
+
predicate: ( item: T ) => boolean
|
|
23
|
+
): T[] {
|
|
11
24
|
const filteredCollection = collection.filter( predicate );
|
|
12
25
|
|
|
13
26
|
return collection.length === filteredCollection.length
|
|
@@ -19,46 +32,57 @@ function filterWithReference( collection, predicate ) {
|
|
|
19
32
|
* Creates a new object with the same keys, but with `callback()` called as
|
|
20
33
|
* a transformer function on each of the values.
|
|
21
34
|
*
|
|
22
|
-
* @param
|
|
23
|
-
* @param
|
|
24
|
-
* @return
|
|
35
|
+
* @param obj The object to transform.
|
|
36
|
+
* @param callback The function to transform each object value.
|
|
37
|
+
* @return Transformed object.
|
|
25
38
|
*/
|
|
26
|
-
const mapValues =
|
|
27
|
-
|
|
28
|
-
|
|
39
|
+
const mapValues = < T, U >(
|
|
40
|
+
obj: Partial< Record< string, T > >,
|
|
41
|
+
callback: ( value: T ) => U
|
|
42
|
+
): Partial< Record< string, U > > =>
|
|
43
|
+
Object.entries( obj ).reduce( ( acc, [ key, value ] ) => {
|
|
44
|
+
if ( value === undefined ) {
|
|
45
|
+
return acc;
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
29
48
|
...acc,
|
|
30
49
|
[ key ]: callback( value ),
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
);
|
|
50
|
+
};
|
|
51
|
+
}, {} );
|
|
34
52
|
|
|
35
53
|
/**
|
|
36
54
|
* Verifies whether the given annotations is a valid annotation.
|
|
37
55
|
*
|
|
38
|
-
* @param
|
|
39
|
-
* @
|
|
56
|
+
* @param annotation The annotation to verify.
|
|
57
|
+
* @param annotation.range The range property of the annotation.
|
|
58
|
+
* @return Whether the given annotation is valid.
|
|
40
59
|
*/
|
|
41
|
-
function isValidAnnotationRange( annotation
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
annotation.
|
|
60
|
+
function isValidAnnotationRange( annotation: {
|
|
61
|
+
range?: AnnotationRange | null;
|
|
62
|
+
} ): boolean {
|
|
63
|
+
return Boolean(
|
|
64
|
+
annotation.range &&
|
|
65
|
+
typeof annotation.range.start === 'number' &&
|
|
66
|
+
typeof annotation.range.end === 'number' &&
|
|
67
|
+
annotation.range.start <= annotation.range.end
|
|
46
68
|
);
|
|
47
69
|
}
|
|
48
70
|
|
|
49
71
|
/**
|
|
50
72
|
* Reducer managing annotations.
|
|
51
73
|
*
|
|
52
|
-
* @param
|
|
53
|
-
* @param
|
|
54
|
-
*
|
|
55
|
-
* @return {Array} Updated state.
|
|
74
|
+
* @param state The annotations currently shown in the editor.
|
|
75
|
+
* @param action Dispatched action.
|
|
76
|
+
* @return Updated state.
|
|
56
77
|
*/
|
|
57
|
-
export function annotations(
|
|
78
|
+
export function annotations(
|
|
79
|
+
state: AnnotationsState = {},
|
|
80
|
+
action: AnnotationAction
|
|
81
|
+
): AnnotationsState {
|
|
58
82
|
switch ( action.type ) {
|
|
59
83
|
case 'ANNOTATION_ADD':
|
|
60
84
|
const blockClientId = action.blockClientId;
|
|
61
|
-
const newAnnotation = {
|
|
85
|
+
const newAnnotation: Annotation = {
|
|
62
86
|
id: action.id,
|
|
63
87
|
blockClientId,
|
|
64
88
|
richTextIdentifier: action.richTextIdentifier,
|
|
@@ -69,7 +93,7 @@ export function annotations( state = {}, action ) {
|
|
|
69
93
|
|
|
70
94
|
if (
|
|
71
95
|
newAnnotation.selector === 'range' &&
|
|
72
|
-
! isValidAnnotationRange( newAnnotation
|
|
96
|
+
! isValidAnnotationRange( newAnnotation )
|
|
73
97
|
) {
|
|
74
98
|
return state;
|
|
75
99
|
}
|
|
@@ -85,21 +109,21 @@ export function annotations( state = {}, action ) {
|
|
|
85
109
|
};
|
|
86
110
|
|
|
87
111
|
case 'ANNOTATION_REMOVE':
|
|
88
|
-
return mapValues( state, ( annotationsForBlock ) => {
|
|
112
|
+
return mapValues( state, ( annotationsForBlock: Annotation[] ) => {
|
|
89
113
|
return filterWithReference(
|
|
90
114
|
annotationsForBlock,
|
|
91
|
-
( annotation ) => {
|
|
115
|
+
( annotation: Annotation ) => {
|
|
92
116
|
return annotation.id !== action.annotationId;
|
|
93
117
|
}
|
|
94
118
|
);
|
|
95
119
|
} );
|
|
96
120
|
|
|
97
121
|
case 'ANNOTATION_UPDATE_RANGE':
|
|
98
|
-
return mapValues( state, ( annotationsForBlock ) => {
|
|
122
|
+
return mapValues( state, ( annotationsForBlock: Annotation[] ) => {
|
|
99
123
|
let hasChangedRange = false;
|
|
100
124
|
|
|
101
125
|
const newAnnotations = annotationsForBlock.map(
|
|
102
|
-
( annotation ) => {
|
|
126
|
+
( annotation: Annotation ) => {
|
|
103
127
|
if ( annotation.id === action.annotationId ) {
|
|
104
128
|
hasChangedRange = true;
|
|
105
129
|
return {
|
|
@@ -119,10 +143,10 @@ export function annotations( state = {}, action ) {
|
|
|
119
143
|
} );
|
|
120
144
|
|
|
121
145
|
case 'ANNOTATION_REMOVE_SOURCE':
|
|
122
|
-
return mapValues( state, ( annotationsForBlock ) => {
|
|
146
|
+
return mapValues( state, ( annotationsForBlock: Annotation[] ) => {
|
|
123
147
|
return filterWithReference(
|
|
124
148
|
annotationsForBlock,
|
|
125
|
-
( annotation ) => {
|
|
149
|
+
( annotation: Annotation ) => {
|
|
126
150
|
return annotation.source !== action.source;
|
|
127
151
|
}
|
|
128
152
|
);
|
|
@@ -3,38 +3,42 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { createSelector } from '@wordpress/data';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Internal dependencies
|
|
8
|
+
*/
|
|
9
|
+
import type { AnnotationsState, Annotation } from '../types';
|
|
10
|
+
|
|
6
11
|
/**
|
|
7
12
|
* Shared reference to an empty array for cases where it is important to avoid
|
|
8
13
|
* returning a new array reference on every invocation, as in a connected or
|
|
9
14
|
* other pure component which performs `shouldComponentUpdate` check on props.
|
|
10
15
|
* This should be used as a last resort, since the normalized data should be
|
|
11
16
|
* maintained by the reducer result in state.
|
|
12
|
-
*
|
|
13
|
-
* @type {Array}
|
|
14
17
|
*/
|
|
15
|
-
const EMPTY_ARRAY = [];
|
|
18
|
+
const EMPTY_ARRAY: Annotation[] = [];
|
|
16
19
|
|
|
17
20
|
/**
|
|
18
21
|
* Returns the annotations for a specific client ID.
|
|
19
22
|
*
|
|
20
|
-
* @param
|
|
21
|
-
* @param
|
|
22
|
-
*
|
|
23
|
-
* @return {Array} The annotations applicable to this block.
|
|
23
|
+
* @param state Editor state.
|
|
24
|
+
* @param blockClientId The ID of the block to get the annotations for.
|
|
25
|
+
* @return The annotations applicable to this block.
|
|
24
26
|
*/
|
|
25
27
|
export const __experimentalGetAnnotationsForBlock = createSelector(
|
|
26
|
-
( state, blockClientId ) => {
|
|
28
|
+
( state: AnnotationsState, blockClientId: string ): Annotation[] => {
|
|
27
29
|
return ( state?.[ blockClientId ] ?? [] ).filter( ( annotation ) => {
|
|
28
30
|
return annotation.selector === 'block';
|
|
29
31
|
} );
|
|
30
32
|
},
|
|
31
|
-
( state, blockClientId ) => [
|
|
33
|
+
( state: AnnotationsState, blockClientId: string ) => [
|
|
34
|
+
state?.[ blockClientId ] ?? EMPTY_ARRAY,
|
|
35
|
+
]
|
|
32
36
|
);
|
|
33
37
|
|
|
34
38
|
export function __experimentalGetAllAnnotationsForBlock(
|
|
35
|
-
state,
|
|
36
|
-
blockClientId
|
|
37
|
-
) {
|
|
39
|
+
state: AnnotationsState,
|
|
40
|
+
blockClientId: string
|
|
41
|
+
): Annotation[] {
|
|
38
42
|
return state?.[ blockClientId ] ?? EMPTY_ARRAY;
|
|
39
43
|
}
|
|
40
44
|
|
|
@@ -45,13 +49,17 @@ export function __experimentalGetAllAnnotationsForBlock(
|
|
|
45
49
|
* a block might have multiple `RichText` components. This does mean that every
|
|
46
50
|
* block needs to implement annotations itself.
|
|
47
51
|
*
|
|
48
|
-
* @param
|
|
49
|
-
* @param
|
|
50
|
-
* @param
|
|
51
|
-
* @return
|
|
52
|
+
* @param state Editor state.
|
|
53
|
+
* @param blockClientId The client ID for the block.
|
|
54
|
+
* @param richTextIdentifier Unique identifier that identifies the given RichText.
|
|
55
|
+
* @return All the annotations relevant for the `RichText`.
|
|
52
56
|
*/
|
|
53
57
|
export const __experimentalGetAnnotationsForRichText = createSelector(
|
|
54
|
-
(
|
|
58
|
+
(
|
|
59
|
+
state: AnnotationsState,
|
|
60
|
+
blockClientId: string,
|
|
61
|
+
richTextIdentifier: string
|
|
62
|
+
): Annotation[] => {
|
|
55
63
|
return ( state?.[ blockClientId ] ?? [] )
|
|
56
64
|
.filter( ( annotation ) => {
|
|
57
65
|
return (
|
|
@@ -68,15 +76,21 @@ export const __experimentalGetAnnotationsForRichText = createSelector(
|
|
|
68
76
|
};
|
|
69
77
|
} );
|
|
70
78
|
},
|
|
71
|
-
( state, blockClientId ) => [
|
|
79
|
+
( state: AnnotationsState, blockClientId: string ) => [
|
|
80
|
+
state?.[ blockClientId ] ?? EMPTY_ARRAY,
|
|
81
|
+
]
|
|
72
82
|
);
|
|
73
83
|
|
|
74
84
|
/**
|
|
75
85
|
* Returns all annotations in the editor state.
|
|
76
86
|
*
|
|
77
|
-
* @param
|
|
78
|
-
* @return
|
|
87
|
+
* @param state Editor state.
|
|
88
|
+
* @return All annotations currently applied.
|
|
79
89
|
*/
|
|
80
|
-
export function __experimentalGetAnnotations(
|
|
81
|
-
|
|
90
|
+
export function __experimentalGetAnnotations(
|
|
91
|
+
state: AnnotationsState
|
|
92
|
+
): Annotation[] {
|
|
93
|
+
return Object.values( state )
|
|
94
|
+
.filter( ( arr ): arr is Annotation[] => Boolean( arr ) )
|
|
95
|
+
.flat();
|
|
82
96
|
}
|
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
* Internal dependencies
|
|
3
3
|
*/
|
|
4
4
|
import { annotations } from '../reducer';
|
|
5
|
+
import type { AnnotationAction, AnnotationsState } from '../../types';
|
|
5
6
|
|
|
6
7
|
describe( 'annotations', () => {
|
|
7
|
-
const initialState = {};
|
|
8
|
+
const initialState: AnnotationsState = {};
|
|
8
9
|
|
|
9
10
|
it( 'returns all annotations and annotation IDs per block', () => {
|
|
10
|
-
const state = annotations( undefined, {} );
|
|
11
|
+
const state = annotations( undefined, {} as AnnotationAction );
|
|
11
12
|
|
|
12
13
|
expect( state ).toEqual( initialState );
|
|
13
14
|
} );
|
|
@@ -63,14 +64,14 @@ describe( 'annotations', () => {
|
|
|
63
64
|
blockClientId: 'blockClientId',
|
|
64
65
|
richTextIdentifier: 'identifier',
|
|
65
66
|
source: 'default',
|
|
66
|
-
selector: 'block',
|
|
67
|
+
selector: 'block' as const,
|
|
67
68
|
};
|
|
68
69
|
const annotation2 = {
|
|
69
70
|
id: 'annotationId2',
|
|
70
71
|
blockClientId: 'blockClientId2',
|
|
71
72
|
richTextIdentifier: 'identifier2',
|
|
72
73
|
source: 'other-source',
|
|
73
|
-
selector: 'block',
|
|
74
|
+
selector: 'block' as const,
|
|
74
75
|
};
|
|
75
76
|
const state = annotations(
|
|
76
77
|
{
|
|
@@ -129,7 +130,7 @@ describe( 'annotations', () => {
|
|
|
129
130
|
blockClientId: 'blockClientId',
|
|
130
131
|
richTextIdentifier: 'identifier',
|
|
131
132
|
source: 'default',
|
|
132
|
-
selector: 'range',
|
|
133
|
+
selector: 'range' as const,
|
|
133
134
|
range: {
|
|
134
135
|
start: 0,
|
|
135
136
|
end: 100,
|
|
@@ -165,6 +166,9 @@ describe( 'annotations', () => {
|
|
|
165
166
|
it( 'rejects invalid annotations', () => {
|
|
166
167
|
let state = annotations( undefined, {
|
|
167
168
|
type: 'ANNOTATION_ADD',
|
|
169
|
+
id: 'test1',
|
|
170
|
+
blockClientId: 'blockClientId',
|
|
171
|
+
richTextIdentifier: 'identifier',
|
|
168
172
|
source: 'default',
|
|
169
173
|
selector: 'range',
|
|
170
174
|
range: {
|
|
@@ -174,19 +178,27 @@ describe( 'annotations', () => {
|
|
|
174
178
|
} );
|
|
175
179
|
state = annotations( state, {
|
|
176
180
|
type: 'ANNOTATION_ADD',
|
|
181
|
+
id: 'test2',
|
|
182
|
+
blockClientId: 'blockClientId',
|
|
183
|
+
richTextIdentifier: 'identifier',
|
|
177
184
|
source: 'default',
|
|
178
185
|
selector: 'range',
|
|
179
186
|
range: {
|
|
187
|
+
// @ts-expect-error Testing invalid input
|
|
180
188
|
start: 'not a number',
|
|
181
189
|
end: 100,
|
|
182
190
|
},
|
|
183
191
|
} );
|
|
184
192
|
state = annotations( state, {
|
|
185
193
|
type: 'ANNOTATION_ADD',
|
|
194
|
+
id: 'test3',
|
|
195
|
+
blockClientId: 'blockClientId',
|
|
196
|
+
richTextIdentifier: 'identifier',
|
|
186
197
|
source: 'default',
|
|
187
198
|
selector: 'range',
|
|
188
199
|
range: {
|
|
189
200
|
start: 100,
|
|
201
|
+
// @ts-expect-error Testing invalid input
|
|
190
202
|
end: 'not a number',
|
|
191
203
|
},
|
|
192
204
|
} );
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents a range in text content.
|
|
3
|
+
*/
|
|
4
|
+
export interface AnnotationRange {
|
|
5
|
+
/** The offset where the annotation should start. */
|
|
6
|
+
start: number;
|
|
7
|
+
/** The offset where the annotation should end. */
|
|
8
|
+
end: number;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Represents an annotation selector type.
|
|
13
|
+
*/
|
|
14
|
+
export type AnnotationSelector = 'range' | 'block';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Base annotation interface.
|
|
18
|
+
*/
|
|
19
|
+
export interface Annotation {
|
|
20
|
+
/** Unique identifier for the annotation. */
|
|
21
|
+
id: string;
|
|
22
|
+
/** The block client ID this annotation applies to. */
|
|
23
|
+
blockClientId: string;
|
|
24
|
+
/** The source that created this annotation. */
|
|
25
|
+
source: string;
|
|
26
|
+
/** The type of selector used for this annotation. */
|
|
27
|
+
selector: AnnotationSelector;
|
|
28
|
+
/** Rich text identifier for range annotations. */
|
|
29
|
+
richTextIdentifier?: string | null;
|
|
30
|
+
/** Range for range-based annotations. */
|
|
31
|
+
range?: AnnotationRange | null;
|
|
32
|
+
/** Start position for annotations returned from selectors. */
|
|
33
|
+
start?: number;
|
|
34
|
+
/** End position for annotations returned from selectors. */
|
|
35
|
+
end?: number;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Parameters for adding an annotation.
|
|
40
|
+
*/
|
|
41
|
+
export interface AddAnnotationParameters {
|
|
42
|
+
/** The blockClientId to add the annotation to. */
|
|
43
|
+
blockClientId: string;
|
|
44
|
+
/** Identifier for the RichText instance the annotation applies to. */
|
|
45
|
+
richTextIdentifier?: string | null;
|
|
46
|
+
/** The range at which to apply this annotation. */
|
|
47
|
+
range?: AnnotationRange | null;
|
|
48
|
+
/** The way to apply this annotation. */
|
|
49
|
+
selector?: AnnotationSelector;
|
|
50
|
+
/** The source that added the annotation. */
|
|
51
|
+
source?: string;
|
|
52
|
+
/** The ID the annotation should have. Generates a UUID by default. */
|
|
53
|
+
id?: string;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Store state interface.
|
|
58
|
+
*/
|
|
59
|
+
export type AnnotationsState = Partial< Record< string, Annotation[] > >;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Action types.
|
|
63
|
+
*/
|
|
64
|
+
export type AnnotationAction =
|
|
65
|
+
| {
|
|
66
|
+
type: 'ANNOTATION_ADD';
|
|
67
|
+
id: string;
|
|
68
|
+
blockClientId: string;
|
|
69
|
+
richTextIdentifier: string | null;
|
|
70
|
+
source: string;
|
|
71
|
+
selector: AnnotationSelector;
|
|
72
|
+
range?: AnnotationRange;
|
|
73
|
+
}
|
|
74
|
+
| {
|
|
75
|
+
type: 'ANNOTATION_REMOVE';
|
|
76
|
+
annotationId: string;
|
|
77
|
+
}
|
|
78
|
+
| {
|
|
79
|
+
type: 'ANNOTATION_UPDATE_RANGE';
|
|
80
|
+
annotationId: string;
|
|
81
|
+
start: number;
|
|
82
|
+
end: number;
|
|
83
|
+
}
|
|
84
|
+
| {
|
|
85
|
+
type: 'ANNOTATION_REMOVE_SOURCE';
|
|
86
|
+
source: string;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Format registration interface for annotations.
|
|
91
|
+
*/
|
|
92
|
+
export interface AnnotationFormat {
|
|
93
|
+
name: string;
|
|
94
|
+
title: string;
|
|
95
|
+
tagName: string;
|
|
96
|
+
className: string;
|
|
97
|
+
attributes: {
|
|
98
|
+
className: string;
|
|
99
|
+
id: string;
|
|
100
|
+
};
|
|
101
|
+
interactive: boolean;
|
|
102
|
+
object: boolean;
|
|
103
|
+
edit: () => null;
|
|
104
|
+
__experimentalGetPropsForEditableTreePreparation: (
|
|
105
|
+
select: any,
|
|
106
|
+
props: {
|
|
107
|
+
richTextIdentifier: string;
|
|
108
|
+
blockClientId: string;
|
|
109
|
+
}
|
|
110
|
+
) => {
|
|
111
|
+
annotations: Annotation[];
|
|
112
|
+
};
|
|
113
|
+
__experimentalCreatePrepareEditableTree: ( props: {
|
|
114
|
+
annotations: Annotation[];
|
|
115
|
+
} ) => ( formats: any[], text: string ) => any[];
|
|
116
|
+
__experimentalGetPropsForEditableTreeChangeHandler: ( dispatch: any ) => {
|
|
117
|
+
removeAnnotation: ( annotationId: string ) => void;
|
|
118
|
+
updateAnnotationRange: (
|
|
119
|
+
annotationId: string,
|
|
120
|
+
start: number,
|
|
121
|
+
end: number
|
|
122
|
+
) => void;
|
|
123
|
+
};
|
|
124
|
+
__experimentalCreateOnChangeEditableValue: ( props: {
|
|
125
|
+
removeAnnotation: ( annotationId: string ) => void;
|
|
126
|
+
updateAnnotationRange: (
|
|
127
|
+
annotationId: string,
|
|
128
|
+
start: number,
|
|
129
|
+
end: number
|
|
130
|
+
) => void;
|
|
131
|
+
annotations: Annotation[];
|
|
132
|
+
} ) => ( formats: any[] ) => void;
|
|
133
|
+
}
|
package/src/block/index.js
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* WordPress dependencies
|
|
3
|
-
*/
|
|
4
|
-
import { addFilter } from '@wordpress/hooks';
|
|
5
|
-
import { withSelect } from '@wordpress/data';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Internal dependencies
|
|
9
|
-
*/
|
|
10
|
-
import { STORE_NAME } from '../store/constants';
|
|
11
|
-
/**
|
|
12
|
-
* Adds annotation className to the block-list-block component.
|
|
13
|
-
*
|
|
14
|
-
* @param {Object} OriginalComponent The original BlockListBlock component.
|
|
15
|
-
* @return {Object} The enhanced component.
|
|
16
|
-
*/
|
|
17
|
-
const addAnnotationClassName = ( OriginalComponent ) => {
|
|
18
|
-
return withSelect( ( select, { clientId, className } ) => {
|
|
19
|
-
const annotations =
|
|
20
|
-
select( STORE_NAME ).__experimentalGetAnnotationsForBlock(
|
|
21
|
-
clientId
|
|
22
|
-
);
|
|
23
|
-
|
|
24
|
-
return {
|
|
25
|
-
className: annotations
|
|
26
|
-
.map( ( annotation ) => {
|
|
27
|
-
return 'is-annotated-by-' + annotation.source;
|
|
28
|
-
} )
|
|
29
|
-
.concat( className )
|
|
30
|
-
.filter( Boolean )
|
|
31
|
-
.join( ' ' ),
|
|
32
|
-
};
|
|
33
|
-
} )( OriginalComponent );
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
addFilter(
|
|
37
|
-
'editor.BlockListBlock',
|
|
38
|
-
'core/annotations',
|
|
39
|
-
addAnnotationClassName
|
|
40
|
-
);
|
package/src/store/actions.js
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* External dependencies
|
|
3
|
-
*/
|
|
4
|
-
import { v4 as uuid } from 'uuid';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* @typedef WPAnnotationRange
|
|
8
|
-
*
|
|
9
|
-
* @property {number} start The offset where the annotation should start.
|
|
10
|
-
* @property {number} end The offset where the annotation should end.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Adds an annotation to a block.
|
|
15
|
-
*
|
|
16
|
-
* The `block` attribute refers to a block ID that needs to be annotated.
|
|
17
|
-
* `isBlockAnnotation` controls whether or not the annotation is a block
|
|
18
|
-
* annotation. The `source` is the source of the annotation, this will be used
|
|
19
|
-
* to identity groups of annotations.
|
|
20
|
-
*
|
|
21
|
-
* The `range` property is only relevant if the selector is 'range'.
|
|
22
|
-
*
|
|
23
|
-
* @param {Object} annotation The annotation to add.
|
|
24
|
-
* @param {string} annotation.blockClientId The blockClientId to add the annotation to.
|
|
25
|
-
* @param {string} annotation.richTextIdentifier Identifier for the RichText instance the annotation applies to.
|
|
26
|
-
* @param {WPAnnotationRange} annotation.range The range at which to apply this annotation.
|
|
27
|
-
* @param {string} [annotation.selector="range"] The way to apply this annotation.
|
|
28
|
-
* @param {string} [annotation.source="default"] The source that added the annotation.
|
|
29
|
-
* @param {string} [annotation.id] The ID the annotation should have. Generates a UUID by default.
|
|
30
|
-
*
|
|
31
|
-
* @return {Object} Action object.
|
|
32
|
-
*/
|
|
33
|
-
export function __experimentalAddAnnotation( {
|
|
34
|
-
blockClientId,
|
|
35
|
-
richTextIdentifier = null,
|
|
36
|
-
range = null,
|
|
37
|
-
selector = 'range',
|
|
38
|
-
source = 'default',
|
|
39
|
-
id = uuid(),
|
|
40
|
-
} ) {
|
|
41
|
-
const action = {
|
|
42
|
-
type: 'ANNOTATION_ADD',
|
|
43
|
-
id,
|
|
44
|
-
blockClientId,
|
|
45
|
-
richTextIdentifier,
|
|
46
|
-
source,
|
|
47
|
-
selector,
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
if ( selector === 'range' ) {
|
|
51
|
-
action.range = range;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return action;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Removes an annotation with a specific ID.
|
|
59
|
-
*
|
|
60
|
-
* @param {string} annotationId The annotation to remove.
|
|
61
|
-
*
|
|
62
|
-
* @return {Object} Action object.
|
|
63
|
-
*/
|
|
64
|
-
export function __experimentalRemoveAnnotation( annotationId ) {
|
|
65
|
-
return {
|
|
66
|
-
type: 'ANNOTATION_REMOVE',
|
|
67
|
-
annotationId,
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Updates the range of an annotation.
|
|
73
|
-
*
|
|
74
|
-
* @param {string} annotationId ID of the annotation to update.
|
|
75
|
-
* @param {number} start The start of the new range.
|
|
76
|
-
* @param {number} end The end of the new range.
|
|
77
|
-
*
|
|
78
|
-
* @return {Object} Action object.
|
|
79
|
-
*/
|
|
80
|
-
export function __experimentalUpdateAnnotationRange(
|
|
81
|
-
annotationId,
|
|
82
|
-
start,
|
|
83
|
-
end
|
|
84
|
-
) {
|
|
85
|
-
return {
|
|
86
|
-
type: 'ANNOTATION_UPDATE_RANGE',
|
|
87
|
-
annotationId,
|
|
88
|
-
start,
|
|
89
|
-
end,
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Removes all annotations of a specific source.
|
|
95
|
-
*
|
|
96
|
-
* @param {string} source The source to remove.
|
|
97
|
-
*
|
|
98
|
-
* @return {Object} Action object.
|
|
99
|
-
*/
|
|
100
|
-
export function __experimentalRemoveAnnotationsBySource( source ) {
|
|
101
|
-
return {
|
|
102
|
-
type: 'ANNOTATION_REMOVE_SOURCE',
|
|
103
|
-
source,
|
|
104
|
-
};
|
|
105
|
-
}
|
|
File without changes
|