@ckeditor/ckeditor5-engine 30.0.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.
Files changed (117) hide show
  1. package/LICENSE.md +17 -0
  2. package/README.md +30 -0
  3. package/package.json +70 -0
  4. package/src/controller/datacontroller.js +563 -0
  5. package/src/controller/editingcontroller.js +149 -0
  6. package/src/conversion/conversion.js +644 -0
  7. package/src/conversion/conversionhelpers.js +40 -0
  8. package/src/conversion/downcastdispatcher.js +914 -0
  9. package/src/conversion/downcasthelpers.js +1706 -0
  10. package/src/conversion/mapper.js +696 -0
  11. package/src/conversion/modelconsumable.js +329 -0
  12. package/src/conversion/upcastdispatcher.js +807 -0
  13. package/src/conversion/upcasthelpers.js +997 -0
  14. package/src/conversion/viewconsumable.js +623 -0
  15. package/src/dataprocessor/basichtmlwriter.js +32 -0
  16. package/src/dataprocessor/dataprocessor.jsdoc +64 -0
  17. package/src/dataprocessor/htmldataprocessor.js +159 -0
  18. package/src/dataprocessor/htmlwriter.js +22 -0
  19. package/src/dataprocessor/xmldataprocessor.js +161 -0
  20. package/src/dev-utils/model.js +482 -0
  21. package/src/dev-utils/operationreplayer.js +140 -0
  22. package/src/dev-utils/utils.js +103 -0
  23. package/src/dev-utils/view.js +1091 -0
  24. package/src/index.js +52 -0
  25. package/src/model/batch.js +82 -0
  26. package/src/model/differ.js +1282 -0
  27. package/src/model/document.js +483 -0
  28. package/src/model/documentfragment.js +390 -0
  29. package/src/model/documentselection.js +1261 -0
  30. package/src/model/element.js +438 -0
  31. package/src/model/history.js +138 -0
  32. package/src/model/item.jsdoc +14 -0
  33. package/src/model/liveposition.js +182 -0
  34. package/src/model/liverange.js +221 -0
  35. package/src/model/markercollection.js +553 -0
  36. package/src/model/model.js +934 -0
  37. package/src/model/node.js +507 -0
  38. package/src/model/nodelist.js +217 -0
  39. package/src/model/operation/attributeoperation.js +202 -0
  40. package/src/model/operation/detachoperation.js +103 -0
  41. package/src/model/operation/insertoperation.js +188 -0
  42. package/src/model/operation/markeroperation.js +154 -0
  43. package/src/model/operation/mergeoperation.js +216 -0
  44. package/src/model/operation/moveoperation.js +209 -0
  45. package/src/model/operation/nooperation.js +58 -0
  46. package/src/model/operation/operation.js +139 -0
  47. package/src/model/operation/operationfactory.js +49 -0
  48. package/src/model/operation/renameoperation.js +155 -0
  49. package/src/model/operation/rootattributeoperation.js +211 -0
  50. package/src/model/operation/splitoperation.js +254 -0
  51. package/src/model/operation/transform.js +2389 -0
  52. package/src/model/operation/utils.js +292 -0
  53. package/src/model/position.js +1164 -0
  54. package/src/model/range.js +1049 -0
  55. package/src/model/rootelement.js +111 -0
  56. package/src/model/schema.js +1851 -0
  57. package/src/model/selection.js +902 -0
  58. package/src/model/text.js +138 -0
  59. package/src/model/textproxy.js +279 -0
  60. package/src/model/treewalker.js +414 -0
  61. package/src/model/utils/autoparagraphing.js +77 -0
  62. package/src/model/utils/deletecontent.js +528 -0
  63. package/src/model/utils/getselectedcontent.js +150 -0
  64. package/src/model/utils/insertcontent.js +824 -0
  65. package/src/model/utils/modifyselection.js +229 -0
  66. package/src/model/utils/selection-post-fixer.js +297 -0
  67. package/src/model/writer.js +1574 -0
  68. package/src/view/attributeelement.js +274 -0
  69. package/src/view/containerelement.js +123 -0
  70. package/src/view/document.js +221 -0
  71. package/src/view/documentfragment.js +273 -0
  72. package/src/view/documentselection.js +387 -0
  73. package/src/view/domconverter.js +1437 -0
  74. package/src/view/downcastwriter.js +2121 -0
  75. package/src/view/editableelement.js +118 -0
  76. package/src/view/element.js +945 -0
  77. package/src/view/elementdefinition.jsdoc +59 -0
  78. package/src/view/emptyelement.js +119 -0
  79. package/src/view/filler.js +161 -0
  80. package/src/view/item.jsdoc +14 -0
  81. package/src/view/matcher.js +776 -0
  82. package/src/view/node.js +391 -0
  83. package/src/view/observer/arrowkeysobserver.js +58 -0
  84. package/src/view/observer/bubblingemittermixin.js +307 -0
  85. package/src/view/observer/bubblingeventinfo.js +71 -0
  86. package/src/view/observer/clickobserver.js +46 -0
  87. package/src/view/observer/compositionobserver.js +79 -0
  88. package/src/view/observer/domeventdata.js +82 -0
  89. package/src/view/observer/domeventobserver.js +99 -0
  90. package/src/view/observer/fakeselectionobserver.js +118 -0
  91. package/src/view/observer/focusobserver.js +106 -0
  92. package/src/view/observer/inputobserver.js +44 -0
  93. package/src/view/observer/keyobserver.js +83 -0
  94. package/src/view/observer/mouseobserver.js +56 -0
  95. package/src/view/observer/mutationobserver.js +345 -0
  96. package/src/view/observer/observer.js +118 -0
  97. package/src/view/observer/selectionobserver.js +242 -0
  98. package/src/view/placeholder.js +285 -0
  99. package/src/view/position.js +426 -0
  100. package/src/view/range.js +533 -0
  101. package/src/view/rawelement.js +148 -0
  102. package/src/view/renderer.js +1037 -0
  103. package/src/view/rooteditableelement.js +107 -0
  104. package/src/view/selection.js +718 -0
  105. package/src/view/styles/background.js +73 -0
  106. package/src/view/styles/border.js +362 -0
  107. package/src/view/styles/margin.js +41 -0
  108. package/src/view/styles/padding.js +40 -0
  109. package/src/view/styles/utils.js +277 -0
  110. package/src/view/stylesmap.js +938 -0
  111. package/src/view/text.js +147 -0
  112. package/src/view/textproxy.js +199 -0
  113. package/src/view/treewalker.js +496 -0
  114. package/src/view/uielement.js +238 -0
  115. package/src/view/upcastwriter.js +484 -0
  116. package/src/view/view.js +721 -0
  117. package/theme/placeholder.css +27 -0
@@ -0,0 +1,73 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+
6
+ /**
7
+ * @module engine/view/styles/background
8
+ */
9
+
10
+ import { getShorthandValues, isAttachment, isColor, isPosition, isRepeat, isURL } from './utils';
11
+
12
+ /**
13
+ * Adds a background CSS styles processing rules.
14
+ *
15
+ * editor.data.addStyleProcessorRules( addBackgroundRules );
16
+ *
17
+ * The normalized value is stored as:
18
+ *
19
+ * const styles = {
20
+ * background: {
21
+ * color,
22
+ * repeat,
23
+ * position,
24
+ * attachment,
25
+ * image
26
+ * }
27
+ * };
28
+ *
29
+ * **Note**: Currently only `'background-color'` longhand value is parsed besides `'background'` shorthand. The reducer also supports only
30
+ * `'background-color'` value.
31
+ *
32
+ * @param {module:engine/view/stylesmap~StylesProcessor} stylesProcessor
33
+ */
34
+ export function addBackgroundRules( stylesProcessor ) {
35
+ stylesProcessor.setNormalizer( 'background', normalizeBackground );
36
+ stylesProcessor.setNormalizer( 'background-color', value => ( { path: 'background.color', value } ) );
37
+ stylesProcessor.setReducer( 'background', value => {
38
+ const ret = [];
39
+
40
+ ret.push( [ 'background-color', value.color ] );
41
+
42
+ return ret;
43
+ } );
44
+
45
+ stylesProcessor.setStyleRelation( 'background', [ 'background-color' ] );
46
+ }
47
+
48
+ function normalizeBackground( value ) {
49
+ const background = {};
50
+
51
+ const parts = getShorthandValues( value );
52
+
53
+ for ( const part of parts ) {
54
+ if ( isRepeat( part ) ) {
55
+ background.repeat = background.repeat || [];
56
+ background.repeat.push( part );
57
+ } else if ( isPosition( part ) ) {
58
+ background.position = background.position || [];
59
+ background.position.push( part );
60
+ } else if ( isAttachment( part ) ) {
61
+ background.attachment = part;
62
+ } else if ( isColor( part ) ) {
63
+ background.color = part;
64
+ } else if ( isURL( part ) ) {
65
+ background.image = part;
66
+ }
67
+ }
68
+
69
+ return {
70
+ path: 'background',
71
+ value: background
72
+ };
73
+ }
@@ -0,0 +1,362 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+
6
+ /**
7
+ * @module engine/view/styles/border
8
+ */
9
+
10
+ import { getShorthandValues, getBoxSidesValueReducer, getBoxSidesValues, isLength, isLineStyle } from './utils';
11
+
12
+ /**
13
+ * Adds a border CSS styles processing rules.
14
+ *
15
+ * editor.data.addStyleProcessorRules( addBorderRules );
16
+ *
17
+ * This rules merges all [border](https://developer.mozilla.org/en-US/docs/Web/CSS/border) styles notation shorthands:
18
+ *
19
+ * - border
20
+ * - border-top
21
+ * - border-right
22
+ * - border-bottom
23
+ * - border-left
24
+ * - border-color
25
+ * - border-style
26
+ * - border-width
27
+ *
28
+ * and all corresponding longhand forms (like `border-top-color`, `border-top-style`, etc).
29
+ *
30
+ * It does not handle other shorthands (like `border-radius` or `border-image`).
31
+ *
32
+ * The normalized model stores border values as:
33
+ *
34
+ * const styles = {
35
+ * border: {
36
+ * color: { top, right, bottom, left },
37
+ * style: { top, right, bottom, left },
38
+ * width: { top, right, bottom, left },
39
+ * }
40
+ * };
41
+ *
42
+ * @param {module:engine/view/stylesmap~StylesProcessor} stylesProcessor
43
+ */
44
+ export function addBorderRules( stylesProcessor ) {
45
+ stylesProcessor.setNormalizer( 'border', borderNormalizer );
46
+
47
+ // Border-position shorthands.
48
+ stylesProcessor.setNormalizer( 'border-top', getBorderPositionNormalizer( 'top' ) );
49
+ stylesProcessor.setNormalizer( 'border-right', getBorderPositionNormalizer( 'right' ) );
50
+ stylesProcessor.setNormalizer( 'border-bottom', getBorderPositionNormalizer( 'bottom' ) );
51
+ stylesProcessor.setNormalizer( 'border-left', getBorderPositionNormalizer( 'left' ) );
52
+
53
+ // Border-property shorthands.
54
+ stylesProcessor.setNormalizer( 'border-color', getBorderPropertyNormalizer( 'color' ) );
55
+ stylesProcessor.setNormalizer( 'border-width', getBorderPropertyNormalizer( 'width' ) );
56
+ stylesProcessor.setNormalizer( 'border-style', getBorderPropertyNormalizer( 'style' ) );
57
+
58
+ // Border longhands.
59
+ stylesProcessor.setNormalizer( 'border-top-color', getBorderPropertyPositionNormalizer( 'color', 'top' ) );
60
+ stylesProcessor.setNormalizer( 'border-top-style', getBorderPropertyPositionNormalizer( 'style', 'top' ) );
61
+ stylesProcessor.setNormalizer( 'border-top-width', getBorderPropertyPositionNormalizer( 'width', 'top' ) );
62
+
63
+ stylesProcessor.setNormalizer( 'border-right-color', getBorderPropertyPositionNormalizer( 'color', 'right' ) );
64
+ stylesProcessor.setNormalizer( 'border-right-style', getBorderPropertyPositionNormalizer( 'style', 'right' ) );
65
+ stylesProcessor.setNormalizer( 'border-right-width', getBorderPropertyPositionNormalizer( 'width', 'right' ) );
66
+
67
+ stylesProcessor.setNormalizer( 'border-bottom-color', getBorderPropertyPositionNormalizer( 'color', 'bottom' ) );
68
+ stylesProcessor.setNormalizer( 'border-bottom-style', getBorderPropertyPositionNormalizer( 'style', 'bottom' ) );
69
+ stylesProcessor.setNormalizer( 'border-bottom-width', getBorderPropertyPositionNormalizer( 'width', 'bottom' ) );
70
+
71
+ stylesProcessor.setNormalizer( 'border-left-color', getBorderPropertyPositionNormalizer( 'color', 'left' ) );
72
+ stylesProcessor.setNormalizer( 'border-left-style', getBorderPropertyPositionNormalizer( 'style', 'left' ) );
73
+ stylesProcessor.setNormalizer( 'border-left-width', getBorderPropertyPositionNormalizer( 'width', 'left' ) );
74
+
75
+ stylesProcessor.setExtractor( 'border-top', getBorderPositionExtractor( 'top' ) );
76
+ stylesProcessor.setExtractor( 'border-right', getBorderPositionExtractor( 'right' ) );
77
+ stylesProcessor.setExtractor( 'border-bottom', getBorderPositionExtractor( 'bottom' ) );
78
+ stylesProcessor.setExtractor( 'border-left', getBorderPositionExtractor( 'left' ) );
79
+
80
+ stylesProcessor.setExtractor( 'border-top-color', 'border.color.top' );
81
+ stylesProcessor.setExtractor( 'border-right-color', 'border.color.right' );
82
+ stylesProcessor.setExtractor( 'border-bottom-color', 'border.color.bottom' );
83
+ stylesProcessor.setExtractor( 'border-left-color', 'border.color.left' );
84
+
85
+ stylesProcessor.setExtractor( 'border-top-width', 'border.width.top' );
86
+ stylesProcessor.setExtractor( 'border-right-width', 'border.width.right' );
87
+ stylesProcessor.setExtractor( 'border-bottom-width', 'border.width.bottom' );
88
+ stylesProcessor.setExtractor( 'border-left-width', 'border.width.left' );
89
+
90
+ stylesProcessor.setExtractor( 'border-top-style', 'border.style.top' );
91
+ stylesProcessor.setExtractor( 'border-right-style', 'border.style.right' );
92
+ stylesProcessor.setExtractor( 'border-bottom-style', 'border.style.bottom' );
93
+ stylesProcessor.setExtractor( 'border-left-style', 'border.style.left' );
94
+
95
+ stylesProcessor.setReducer( 'border-color', getBoxSidesValueReducer( 'border-color' ) );
96
+ stylesProcessor.setReducer( 'border-style', getBoxSidesValueReducer( 'border-style' ) );
97
+ stylesProcessor.setReducer( 'border-width', getBoxSidesValueReducer( 'border-width' ) );
98
+ stylesProcessor.setReducer( 'border-top', getBorderPositionReducer( 'top' ) );
99
+ stylesProcessor.setReducer( 'border-right', getBorderPositionReducer( 'right' ) );
100
+ stylesProcessor.setReducer( 'border-bottom', getBorderPositionReducer( 'bottom' ) );
101
+ stylesProcessor.setReducer( 'border-left', getBorderPositionReducer( 'left' ) );
102
+ stylesProcessor.setReducer( 'border', getBorderReducer() );
103
+
104
+ stylesProcessor.setStyleRelation( 'border', [
105
+ 'border-color', 'border-style', 'border-width',
106
+ 'border-top', 'border-right', 'border-bottom', 'border-left',
107
+ 'border-top-color', 'border-right-color', 'border-bottom-color', 'border-left-color',
108
+ 'border-top-style', 'border-right-style', 'border-bottom-style', 'border-left-style',
109
+ 'border-top-width', 'border-right-width', 'border-bottom-width', 'border-left-width'
110
+ ] );
111
+
112
+ stylesProcessor.setStyleRelation( 'border-color', [
113
+ 'border-top-color', 'border-right-color', 'border-bottom-color', 'border-left-color'
114
+ ] );
115
+ stylesProcessor.setStyleRelation( 'border-style', [
116
+ 'border-top-style', 'border-right-style', 'border-bottom-style', 'border-left-style'
117
+ ] );
118
+ stylesProcessor.setStyleRelation( 'border-width', [
119
+ 'border-top-width', 'border-right-width', 'border-bottom-width', 'border-left-width'
120
+ ] );
121
+
122
+ stylesProcessor.setStyleRelation( 'border-top', [ 'border-top-color', 'border-top-style', 'border-top-width' ] );
123
+ stylesProcessor.setStyleRelation( 'border-right', [ 'border-right-color', 'border-right-style', 'border-right-width' ] );
124
+ stylesProcessor.setStyleRelation( 'border-bottom', [ 'border-bottom-color', 'border-bottom-style', 'border-bottom-width' ] );
125
+ stylesProcessor.setStyleRelation( 'border-left', [ 'border-left-color', 'border-left-style', 'border-left-width' ] );
126
+ }
127
+
128
+ function borderNormalizer( value ) {
129
+ const { color, style, width } = normalizeBorderShorthand( value );
130
+
131
+ return {
132
+ path: 'border',
133
+ value: {
134
+ color: getBoxSidesValues( color ),
135
+ style: getBoxSidesValues( style ),
136
+ width: getBoxSidesValues( width )
137
+ }
138
+ };
139
+ }
140
+
141
+ function getBorderPositionNormalizer( side ) {
142
+ return value => {
143
+ const { color, style, width } = normalizeBorderShorthand( value );
144
+
145
+ const border = {};
146
+
147
+ if ( color !== undefined ) {
148
+ border.color = { [ side ]: color };
149
+ }
150
+
151
+ if ( style !== undefined ) {
152
+ border.style = { [ side ]: style };
153
+ }
154
+
155
+ if ( width !== undefined ) {
156
+ border.width = { [ side ]: width };
157
+ }
158
+
159
+ return {
160
+ path: 'border',
161
+ value: border
162
+ };
163
+ };
164
+ }
165
+
166
+ function getBorderPropertyNormalizer( propertyName ) {
167
+ return value => {
168
+ return {
169
+ path: 'border',
170
+ value: toBorderPropertyShorthand( value, propertyName )
171
+ };
172
+ };
173
+ }
174
+
175
+ function toBorderPropertyShorthand( value, property ) {
176
+ return {
177
+ [ property ]: getBoxSidesValues( value )
178
+ };
179
+ }
180
+
181
+ function getBorderPropertyPositionNormalizer( property, side ) {
182
+ return value => {
183
+ return {
184
+ path: 'border',
185
+ value: {
186
+ [ property ]: {
187
+ [ side ]: value
188
+ }
189
+ }
190
+ };
191
+ };
192
+ }
193
+
194
+ function getBorderPositionExtractor( which ) {
195
+ return ( name, styles ) => {
196
+ if ( styles.border ) {
197
+ return extractBorderPosition( styles.border, which );
198
+ }
199
+ };
200
+ }
201
+
202
+ function extractBorderPosition( border, which ) {
203
+ const value = {};
204
+
205
+ if ( border.width && border.width[ which ] ) {
206
+ value.width = border.width[ which ];
207
+ }
208
+
209
+ if ( border.style && border.style[ which ] ) {
210
+ value.style = border.style[ which ];
211
+ }
212
+
213
+ if ( border.color && border.color[ which ] ) {
214
+ value.color = border.color[ which ];
215
+ }
216
+
217
+ return value;
218
+ }
219
+
220
+ function normalizeBorderShorthand( string ) {
221
+ const result = {};
222
+
223
+ const parts = getShorthandValues( string );
224
+
225
+ for ( const part of parts ) {
226
+ if ( isLength( part ) || /thin|medium|thick/.test( part ) ) {
227
+ result.width = part;
228
+ } else if ( isLineStyle( part ) ) {
229
+ result.style = part;
230
+ } else {
231
+ result.color = part;
232
+ }
233
+ }
234
+
235
+ return result;
236
+ }
237
+
238
+ // The border reducer factory.
239
+ //
240
+ // It tries to produce the most optimal output for the specified styles.
241
+ //
242
+ // For a border style:
243
+ //
244
+ // style: {top: "solid", bottom: "solid", right: "solid", left: "solid"}
245
+ //
246
+ // It will produce: `border-style: solid`.
247
+ // For a border style and color:
248
+ //
249
+ // color: {top: "#ff0", bottom: "#ff0", right: "#ff0", left: "#ff0"}
250
+ // style: {top: "solid", bottom: "solid", right: "solid", left: "solid"}
251
+ //
252
+ // It will produce: `border-color: #ff0; border-style: solid`.
253
+ // If all border parameters are specified:
254
+ //
255
+ // color: {top: "#ff0", bottom: "#ff0", right: "#ff0", left: "#ff0"}
256
+ // style: {top: "solid", bottom: "solid", right: "solid", left: "solid"}
257
+ // width: {top: "2px", bottom: "2px", right: "2px", left: "2px"}
258
+ //
259
+ // It will combine everything into a single property: `border: 2px solid #ff0`.
260
+ //
261
+ // The definitions are merged only if all border selectors have the same values.
262
+ //
263
+ // @returns {Function}
264
+ function getBorderReducer() {
265
+ return value => {
266
+ const topStyles = extractBorderPosition( value, 'top' );
267
+ const rightStyles = extractBorderPosition( value, 'right' );
268
+ const bottomStyles = extractBorderPosition( value, 'bottom' );
269
+ const leftStyles = extractBorderPosition( value, 'left' );
270
+
271
+ const borderStyles = [ topStyles, rightStyles, bottomStyles, leftStyles ];
272
+
273
+ const borderStylesByType = {
274
+ width: getReducedStyleValueForType( borderStyles, 'width' ),
275
+ style: getReducedStyleValueForType( borderStyles, 'style' ),
276
+ color: getReducedStyleValueForType( borderStyles, 'color' )
277
+ };
278
+
279
+ // Try reducing to a single `border:` property.
280
+ const reducedBorderStyle = reduceBorderPosition( borderStylesByType, 'all' );
281
+
282
+ if ( reducedBorderStyle.length ) {
283
+ return reducedBorderStyle;
284
+ }
285
+
286
+ // Try reducing to `border-style:`, `border-width:`, `border-color:` properties.
287
+ const reducedStyleTypes = Object.entries( borderStylesByType ).reduce( ( reducedStyleTypes, [ type, value ] ) => {
288
+ if ( value ) {
289
+ reducedStyleTypes.push( [ `border-${ type }`, value ] );
290
+
291
+ // Remove it from the full set to not include it in the most specific properties later.
292
+ borderStyles.forEach( style => ( style[ type ] = null ) );
293
+ }
294
+
295
+ return reducedStyleTypes;
296
+ }, [] );
297
+
298
+ // The reduced properties (by type) and all that remains that could not be reduced.
299
+ return [
300
+ ...reducedStyleTypes,
301
+ ...reduceBorderPosition( topStyles, 'top' ),
302
+ ...reduceBorderPosition( rightStyles, 'right' ),
303
+ ...reduceBorderPosition( bottomStyles, 'bottom' ),
304
+ ...reduceBorderPosition( leftStyles, 'left' )
305
+ ];
306
+ };
307
+
308
+ // @param {Array.<Object>} styles The array of objects with `style`, `color`, `width` properties.
309
+ // @param {'width'|'style'|'color'} type
310
+ function getReducedStyleValueForType( styles, type ) {
311
+ return styles
312
+ .map( style => style[ type ] )
313
+ .reduce( ( result, style ) => result == style ? result : null );
314
+ }
315
+ }
316
+
317
+ function getBorderPositionReducer( which ) {
318
+ return value => reduceBorderPosition( value, which );
319
+ }
320
+
321
+ // Returns an array with reduced border styles depending on the specified values.
322
+ //
323
+ // If all border properties (width, style, color) are specified, the returned selector will be
324
+ // merged into a group: `border-*: [width] [style] [color]`.
325
+ //
326
+ // Otherwise, the specific definitions will be returned: `border-(width|style|color)-*: [value]`.
327
+ //
328
+ // @param {Object|null} value Styles if defined.
329
+ // @param {'top'|'right'|'bottom'|'left'|'all'} which The border position.
330
+ // @returns {Array}
331
+ function reduceBorderPosition( value, which ) {
332
+ const borderTypes = [];
333
+
334
+ if ( value && value.width ) {
335
+ borderTypes.push( 'width' );
336
+ }
337
+
338
+ if ( value && value.style ) {
339
+ borderTypes.push( 'style' );
340
+ }
341
+
342
+ if ( value && value.color ) {
343
+ borderTypes.push( 'color' );
344
+ }
345
+
346
+ if ( borderTypes.length == 3 ) {
347
+ const borderValue = borderTypes.map( item => value[ item ] ).join( ' ' );
348
+
349
+ return [
350
+ which == 'all' ? [ 'border', borderValue ] : [ `border-${ which }`, borderValue ]
351
+ ];
352
+ }
353
+
354
+ // We are unable to reduce to a single `border:` property.
355
+ if ( which == 'all' ) {
356
+ return [];
357
+ }
358
+
359
+ return borderTypes.map( type => {
360
+ return [ `border-${ which }-${ type }`, value[ type ] ];
361
+ } );
362
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+
6
+ /**
7
+ * @module engine/view/styles/margin
8
+ */
9
+
10
+ import { getPositionShorthandNormalizer, getBoxSidesValueReducer } from './utils';
11
+
12
+ /**
13
+ * Adds a margin CSS styles processing rules.
14
+ *
15
+ * editor.data.addStyleProcessorRules( addMarginRules );
16
+ *
17
+ * The normalized value is stored as:
18
+ *
19
+ * const styles = {
20
+ * margin: {
21
+ * top,
22
+ * right,
23
+ * bottom,
24
+ * left
25
+ * }
26
+ * };
27
+ *
28
+ * @param {module:engine/view/stylesmap~StylesProcessor} stylesProcessor
29
+ */
30
+ export function addMarginRules( stylesProcessor ) {
31
+ stylesProcessor.setNormalizer( 'margin', getPositionShorthandNormalizer( 'margin' ) );
32
+
33
+ stylesProcessor.setNormalizer( 'margin-top', value => ( { path: 'margin.top', value } ) );
34
+ stylesProcessor.setNormalizer( 'margin-right', value => ( { path: 'margin.right', value } ) );
35
+ stylesProcessor.setNormalizer( 'margin-bottom', value => ( { path: 'margin.bottom', value } ) );
36
+ stylesProcessor.setNormalizer( 'margin-left', value => ( { path: 'margin.left', value } ) );
37
+
38
+ stylesProcessor.setReducer( 'margin', getBoxSidesValueReducer( 'margin' ) );
39
+
40
+ stylesProcessor.setStyleRelation( 'margin', [ 'margin-top', 'margin-right', 'margin-bottom', 'margin-left' ] );
41
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+
6
+ /**
7
+ * @module engine/view/styles/padding
8
+ */
9
+
10
+ import { getPositionShorthandNormalizer, getBoxSidesValueReducer } from './utils';
11
+
12
+ /**
13
+ * Adds a margin CSS styles processing rules.
14
+ *
15
+ * editor.data.addStyleProcessorRules( addPaddingRules );
16
+ *
17
+ * The normalized value is stored as:
18
+ *
19
+ * const styles = {
20
+ * padding: {
21
+ * top,
22
+ * right,
23
+ * bottom,
24
+ * left
25
+ * }
26
+ * };
27
+ *
28
+ * @param {module:engine/view/stylesmap~StylesProcessor} stylesProcessor
29
+ */
30
+ export function addPaddingRules( stylesProcessor ) {
31
+ stylesProcessor.setNormalizer( 'padding', getPositionShorthandNormalizer( 'padding' ) );
32
+ stylesProcessor.setNormalizer( 'padding-top', value => ( { path: 'padding.top', value } ) );
33
+ stylesProcessor.setNormalizer( 'padding-right', value => ( { path: 'padding.right', value } ) );
34
+ stylesProcessor.setNormalizer( 'padding-bottom', value => ( { path: 'padding.bottom', value } ) );
35
+ stylesProcessor.setNormalizer( 'padding-left', value => ( { path: 'padding.left', value } ) );
36
+
37
+ stylesProcessor.setReducer( 'padding', getBoxSidesValueReducer( 'padding' ) );
38
+
39
+ stylesProcessor.setStyleRelation( 'padding', [ 'padding-top', 'padding-right', 'padding-bottom', 'padding-left' ] );
40
+ }