-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
/
tableproperties.js
126 lines (111 loc) · 4.04 KB
/
tableproperties.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
/**
* @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/
/**
* @module table/converters/tableproperites
*/
/**
* Conversion helper for upcasting attributes using normalized styles.
*
* @param {module:engine/conversion/conversion~Conversion} conversion
* @param {String} modelElement
* @param {String} modelAttribute
* @param {String} styleName
*/
export function upcastStyleToAttribute( conversion, modelElement, modelAttribute, styleName ) {
conversion.for( 'upcast' ).attributeToAttribute( {
view: {
styles: {
[ styleName ]: /[\s\S]+/
}
},
model: {
name: modelElement,
key: modelAttribute,
value: viewElement => viewElement.getNormalizedStyle( styleName )
}
} );
}
/**
* Conversion helper for upcasting border styles for view elements.
*
* @param {module:engine/conversion/conversion~Conversion} conversion
* @param {String} viewElementName
*/
export function upcastBorderStyles( conversion, viewElementName ) {
conversion.for( 'upcast' ).add( dispatcher => dispatcher.on( 'element:' + viewElementName, ( evt, data, conversionApi ) => {
// TODO: this is counter-intuitive: ie.: if only `border-top` is defined then `hasStyle( 'border' )` also returns true.
// TODO: this might needs to be fixed in styles normalizer.
const stylesToConsume = [
'border-top',
'border-right',
'border-bottom',
'border-left'
].filter( styleName => data.viewItem.hasStyle( styleName ) );
if ( !stylesToConsume.length ) {
return;
}
const matcherPattern = {
styles: stylesToConsume
};
// Try to consume appropriate values from consumable values list.
if ( !conversionApi.consumable.test( data.viewItem, matcherPattern ) ) {
return;
}
// This can happen when the upcasted table is nested table. As to why it happens, it remains a mystery.
// Take a look at https://github.com/ckeditor/ckeditor5/issues/6177.
if ( !data.modelRange ) {
data = Object.assign( data, conversionApi.convertChildren( data.viewItem, data.modelCursor ) );
}
const modelElement = [ ...data.modelRange.getItems( { shallow: true } ) ].pop();
conversionApi.consumable.consume( data.viewItem, matcherPattern );
conversionApi.writer.setAttribute( 'borderStyle', data.viewItem.getNormalizedStyle( 'border-style' ), modelElement );
conversionApi.writer.setAttribute( 'borderColor', data.viewItem.getNormalizedStyle( 'border-color' ), modelElement );
conversionApi.writer.setAttribute( 'borderWidth', data.viewItem.getNormalizedStyle( 'border-width' ), modelElement );
} ) );
}
/**
* Conversion helper for downcasting an attribute to a style.
*
* @param {module:engine/conversion/conversion~Conversion} conversion
* @param {String} modelElement
* @param {String} modelAttribute
* @param {String} styleName
*/
export function downcastAttributeToStyle( conversion, modelElement, modelAttribute, styleName ) {
conversion.for( 'downcast' ).attributeToAttribute( {
model: {
name: modelElement,
key: modelAttribute
},
view: modelAttributeValue => ( {
key: 'style',
value: {
[ styleName ]: modelAttributeValue
}
} )
} );
}
/**
* Conversion helper for downcasting attributes from the model table to a view table (not to `<figure>`).
*
* @param {module:engine/conversion/conversion~Conversion} conversion
* @param {String} modelAttribute
* @param {String} styleName
*/
export function downcastTableAttribute( conversion, modelAttribute, styleName ) {
conversion.for( 'downcast' ).add( dispatcher => dispatcher.on( `attribute:${ modelAttribute }:table`, ( evt, data, conversionApi ) => {
const { item, attributeNewValue } = data;
const { mapper, writer } = conversionApi;
if ( !conversionApi.consumable.consume( data.item, evt.name ) ) {
return;
}
const table = [ ...mapper.toViewElement( item ).getChildren() ].find( child => child.is( 'table' ) );
if ( attributeNewValue ) {
writer.setStyle( styleName, attributeNewValue, table );
} else {
writer.removeStyle( styleName, table );
}
} ) );
}