/
register-format-type.js
131 lines (116 loc) · 3.56 KB
/
register-format-type.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/**
* WordPress dependencies
*/
import { select, dispatch } from '@wordpress/data';
/**
* Internal dependencies
*/
import { store as richTextStore } from './store';
/**
* @typedef {Object} WPFormat
*
* @property {string} name A string identifying the format. Must be
* unique across all registered formats.
* @property {string} tagName The HTML tag this format will wrap the
* selection with.
* @property {string} [className] A class to match the format.
* @property {string} title Name of the format.
* @property {Function} edit Should return a component for the user to
* interact with the new registered format.
*/
/**
* Registers a new format provided a unique name and an object defining its
* behavior.
*
* @param {string} name Format name.
* @param {WPFormat} settings Format settings.
*
* @return {WPFormat|undefined} The format, if it has been successfully
* registered; otherwise `undefined`.
*/
export function registerFormatType( name, settings ) {
settings = {
name,
...settings,
};
if ( typeof settings.name !== 'string' ) {
window.console.error( 'Format names must be strings.' );
return;
}
if ( ! /^[a-z][a-z0-9-]*\/[a-z][a-z0-9-]*$/.test( settings.name ) ) {
window.console.error(
'Format names must contain a namespace prefix, include only lowercase alphanumeric characters or dashes, and start with a letter. Example: my-plugin/my-custom-format'
);
return;
}
if ( select( richTextStore ).getFormatType( settings.name ) ) {
window.console.error(
'Format "' + settings.name + '" is already registered.'
);
return;
}
if ( typeof settings.tagName !== 'string' || settings.tagName === '' ) {
window.console.error( 'Format tag names must be a string.' );
return;
}
if (
( typeof settings.className !== 'string' ||
settings.className === '' ) &&
settings.className !== null
) {
window.console.error(
'Format class names must be a string, or null to handle bare elements.'
);
return;
}
if ( ! /^[_a-zA-Z]+[a-zA-Z0-9-]*$/.test( settings.className ) ) {
window.console.error(
'A class name must begin with a letter, followed by any number of hyphens, letters, or numbers.'
);
return;
}
if ( settings.className === null ) {
const formatTypeForBareElement = select(
richTextStore
).getFormatTypeForBareElement( settings.tagName );
if (
formatTypeForBareElement &&
formatTypeForBareElement.name !== 'core/unknown'
) {
window.console.error(
`Format "${ formatTypeForBareElement.name }" is already registered to handle bare tag name "${ settings.tagName }".`
);
return;
}
} else {
const formatTypeForClassName = select(
richTextStore
).getFormatTypeForClassName( settings.className );
if ( formatTypeForClassName ) {
window.console.error(
`Format "${ formatTypeForClassName.name }" is already registered to handle class name "${ settings.className }".`
);
return;
}
}
if ( ! ( 'title' in settings ) || settings.title === '' ) {
window.console.error(
'The format "' + settings.name + '" must have a title.'
);
return;
}
if ( 'keywords' in settings && settings.keywords.length > 3 ) {
window.console.error(
'The format "' +
settings.name +
'" can have a maximum of 3 keywords.'
);
return;
}
if ( typeof settings.title !== 'string' ) {
window.console.error( 'Format titles must be strings.' );
return;
}
dispatch( richTextStore ).addFormatTypes( settings );
return settings;
}