qms-angular 1.1.76 → 1.1.77
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/bundles/qms-angular.umd.js +18 -7
- package/bundles/qms-angular.umd.js.map +1 -1
- package/esm2015/lib/model/en.js +6 -2
- package/esm2015/lib/model/no.js +6 -2
- package/esm2015/lib/qms-ckeditor-components/common/functions/resource.function.js +9 -6
- package/fesm2015/qms-angular.js +18 -7
- package/fesm2015/qms-angular.js.map +1 -1
- package/lib/model/en.d.ts +4 -0
- package/lib/model/no.d.ts +4 -0
- package/lib/qms-ckeditor-components/common/functions/resource.function.d.ts +8 -5
- package/package.json +1 -1
- package/qms-angular.metadata.json +1 -1
- package/src/assets/qms-ckeditor-plugin/build/ckeditor.js +2 -2
- package/src/assets/qms-ckeditor-plugin/build/ckeditor.js.map +1 -1
- package/src/assets/qms-ckeditor-plugin/src/ckeditor.js +6 -2
- package/src/assets/qms-ckeditor-plugin/src/plugins/collapsible/collapsible.js +229 -0
- package/src/assets/qms-ckeditor-plugin/src/plugins/collapsible/collapsiblecommand.js +13 -0
- package/src/assets/qms-ckeditor-plugin/src/plugins/heading/headingediting.js +165 -163
- package/src/assets/qms-ckeditor-plugin/src/plugins/heading/headingui.js +18 -8
- package/src/assets/qms-ckeditor-plugin/src/plugins/heading/ingress/ingress.js +63 -0
- package/src/assets/qms-ckeditor-plugin/src/plugins/heading/ingress/ingresscommand.js +33 -0
- package/src/assets/qms-ckeditor-plugin/src/plugins/heading/theme/heading.css +44 -35
- package/src/assets/qms-ckeditor-plugin/src/plugins/heading/utils.js +2 -1
- package/src/assets/qms-ckeditor-plugin/src/plugins/table/commands/setheadercolumncommand.js +99 -95
- package/src/assets/qms-ckeditor-plugin/src/plugins/table/commands/setheaderrowcommand.js +110 -105
- package/src/assets/qms-ckeditor-plugin/src/plugins/table/converters/downcast.js +529 -529
- package/src/assets/qms-ckeditor-plugin/src/plugins/table/theme/table.css +67 -67
- package/src/assets/qms-ckeditor-plugin/src/plugins/tooltip/tooltipcommand.js +74 -75
- package/src/assets/qms-ckeditor-plugin/src/themes/icons/angles-up-down.svg +1 -0
@@ -45,8 +45,9 @@ export default class HeadingUI extends Plugin {
|
|
45
45
|
|
46
46
|
const headingCommand = editor.commands.get( 'heading' );
|
47
47
|
const paragraphCommand = editor.commands.get( 'paragraph' );
|
48
|
+
const ingressCommand = editor.commands.get( 'ingress' );
|
48
49
|
|
49
|
-
const commands = [ headingCommand ];
|
50
|
+
const commands = [ headingCommand, ingressCommand ];
|
50
51
|
|
51
52
|
for ( const option of options ) {
|
52
53
|
const def = {
|
@@ -58,10 +59,19 @@ export default class HeadingUI extends Plugin {
|
|
58
59
|
} )
|
59
60
|
};
|
60
61
|
|
61
|
-
if ( option.model === 'paragraph' ) {
|
62
|
-
|
63
|
-
|
64
|
-
|
62
|
+
if ( option.model === 'paragraph' || option.model === 'ingress' ) {
|
63
|
+
if(option.model === 'paragraph'){
|
64
|
+
def.model.bind( 'isOn' ).to( paragraphCommand, 'value' );
|
65
|
+
def.model.set( 'commandName', 'paragraph' );
|
66
|
+
commands.push( paragraphCommand );
|
67
|
+
}
|
68
|
+
if ( option.model === 'ingress' ) {
|
69
|
+
def.model.bind( 'isOn' ).to( ingressCommand, 'value', value => value === option.model );
|
70
|
+
def.model.set( {
|
71
|
+
commandName: 'ingress',
|
72
|
+
commandValue: option.model
|
73
|
+
} );
|
74
|
+
}
|
65
75
|
} else {
|
66
76
|
def.model.bind( 'isOn' ).to( headingCommand, 'value', value => value === option.model );
|
67
77
|
def.model.set( {
|
@@ -97,12 +107,12 @@ export default class HeadingUI extends Plugin {
|
|
97
107
|
return areEnabled.some( isEnabled => isEnabled );
|
98
108
|
} );
|
99
109
|
|
100
|
-
dropdownView.buttonView.bind( 'label' ).to( headingCommand, 'value', paragraphCommand, 'value', (
|
101
|
-
const whichModel =
|
110
|
+
dropdownView.buttonView.bind( 'label' ).to( headingCommand, 'value', paragraphCommand, 'value',ingressCommand, 'value', ( head, para, ingrs ) => {
|
111
|
+
const whichModel = head || ingrs && 'ingress' || para && 'paragraph';
|
102
112
|
// If none of the commands is active, display default title.
|
103
113
|
return titles[ whichModel ] ? titles[ whichModel ] : defaultTitle;
|
104
114
|
} );
|
105
|
-
|
115
|
+
|
106
116
|
// Execute command when an item from the dropdown is selected.
|
107
117
|
this.listenTo( dropdownView, 'execute', evt => {
|
108
118
|
editor.execute( evt.source.commandName, evt.source.commandValue ? { value: evt.source.commandValue } : undefined );
|
@@ -0,0 +1,63 @@
|
|
1
|
+
import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
|
2
|
+
import IngressCommand from './ingresscommand';
|
3
|
+
|
4
|
+
export default class Ingress extends Plugin {
|
5
|
+
|
6
|
+
static get pluginName() {
|
7
|
+
return 'Ingress';
|
8
|
+
}
|
9
|
+
|
10
|
+
init() {
|
11
|
+
const editor = this.editor;
|
12
|
+
const model = editor.model;
|
13
|
+
|
14
|
+
editor.commands.add( 'ingress', new IngressCommand( editor ) );
|
15
|
+
|
16
|
+
// Schema.
|
17
|
+
model.schema.register( 'ingress', { inheritAllFrom: '$block' } );
|
18
|
+
editor.conversion.elementToElement( { model: 'ingress', view: 'p' } );
|
19
|
+
|
20
|
+
// Conversion for paragraph-like elements which has not been converted by any plugin.
|
21
|
+
// editor.conversion.for( 'upcast' ).elementToElement( {
|
22
|
+
// model: ( viewElement, { writer } ) => {
|
23
|
+
// if ( !Ingress.paragraphLikeElements.has( viewElement.name ) ) {
|
24
|
+
// return null;
|
25
|
+
// }
|
26
|
+
|
27
|
+
// // Do not auto-paragraph empty elements.
|
28
|
+
// if ( viewElement.isEmpty ) {
|
29
|
+
// return null;
|
30
|
+
// }
|
31
|
+
|
32
|
+
// return writer.createElement( 'ingress' );
|
33
|
+
// },
|
34
|
+
// view: /.+/,
|
35
|
+
// converterPriority: 'low'
|
36
|
+
// } );
|
37
|
+
|
38
|
+
editor.conversion.for( 'downcast' ).add( dispatcher => {
|
39
|
+
dispatcher.on( 'insert:ingress', ( evt, data, conversionApi ) => {
|
40
|
+
const viewWriter = conversionApi.writer;
|
41
|
+
|
42
|
+
viewWriter.addClass( 'radEdIngress', conversionApi.mapper.toViewElement( data.item ) );
|
43
|
+
}, { priority: 'low' } );
|
44
|
+
} );
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
Ingress.paragraphLikeElements = new Set( [
|
49
|
+
'blockquote',
|
50
|
+
'dd',
|
51
|
+
'div',
|
52
|
+
'dt',
|
53
|
+
'h1',
|
54
|
+
'h2',
|
55
|
+
'h3',
|
56
|
+
'h4',
|
57
|
+
'h5',
|
58
|
+
'h6',
|
59
|
+
'li',
|
60
|
+
'p',
|
61
|
+
'td',
|
62
|
+
'th'
|
63
|
+
] );
|
@@ -0,0 +1,33 @@
|
|
1
|
+
import Command from '@ckeditor/ckeditor5-core/src/command';
|
2
|
+
import first from '@ckeditor/ckeditor5-utils/src/first';
|
3
|
+
|
4
|
+
|
5
|
+
export default class IngressCommand extends Command {
|
6
|
+
refresh() {
|
7
|
+
const model = this.editor.model;
|
8
|
+
const document = model.document;
|
9
|
+
const block = first( document.selection.getSelectedBlocks() );
|
10
|
+
|
11
|
+
this.value = !!block && block.is( 'element', 'ingress' );
|
12
|
+
this.isEnabled = !!block && checkCanBecomeIngress( block, model.schema );
|
13
|
+
}
|
14
|
+
|
15
|
+
execute( options = {} ) {
|
16
|
+
const model = this.editor.model;
|
17
|
+
const document = model.document;
|
18
|
+
|
19
|
+
model.change( writer => {
|
20
|
+
const blocks = ( options.selection || document.selection ).getSelectedBlocks();
|
21
|
+
|
22
|
+
for ( const block of blocks ) {
|
23
|
+
if ( !block.is( 'element', 'ingress' ) && checkCanBecomeIngress( block, model.schema ) ) {
|
24
|
+
writer.rename( block, 'ingress' );
|
25
|
+
}
|
26
|
+
}
|
27
|
+
} );
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
function checkCanBecomeIngress( block, schema ) {
|
32
|
+
return schema.checkChild( block.parent, 'ingress' ) && !schema.isObject( block );
|
33
|
+
}
|
@@ -1,35 +1,44 @@
|
|
1
|
-
/*
|
2
|
-
* 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
|
-
.ck.ck-heading_heading1 {
|
7
|
-
font-size: 20px;
|
8
|
-
}
|
9
|
-
|
10
|
-
.ck.ck-heading_heading2 {
|
11
|
-
font-size: 17px;
|
12
|
-
}
|
13
|
-
|
14
|
-
.ck.ck-heading_heading3 {
|
15
|
-
font-size: 14px;
|
16
|
-
}
|
17
|
-
|
18
|
-
.ck[class*="ck-heading_heading"] {
|
19
|
-
font-weight: bold;
|
20
|
-
}
|
21
|
-
|
22
|
-
.ck h1.radEdH1{
|
23
|
-
font: bold 14pt Cambria, sans-serif;
|
24
|
-
color: #003388;
|
25
|
-
}
|
26
|
-
|
27
|
-
.ck h2.radEdH2{
|
28
|
-
font: bold 13pt Cambria, sans-serif;
|
29
|
-
color: #003388;
|
30
|
-
}
|
31
|
-
|
32
|
-
.ck h3.radEdH3{
|
33
|
-
font: bold 12pt Cambria, sans-serif;
|
34
|
-
color: #003388;
|
35
|
-
}
|
1
|
+
/*
|
2
|
+
* 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
|
+
.ck.ck-heading_heading1 {
|
7
|
+
font-size: 20px;
|
8
|
+
}
|
9
|
+
|
10
|
+
.ck.ck-heading_heading2 {
|
11
|
+
font-size: 17px;
|
12
|
+
}
|
13
|
+
|
14
|
+
.ck.ck-heading_heading3 {
|
15
|
+
font-size: 14px;
|
16
|
+
}
|
17
|
+
|
18
|
+
.ck[class*="ck-heading_heading"] {
|
19
|
+
font-weight: bold;
|
20
|
+
}
|
21
|
+
|
22
|
+
.ck h1.radEdH1{
|
23
|
+
font: bold 14pt Cambria, sans-serif;
|
24
|
+
color: #003388;
|
25
|
+
}
|
26
|
+
|
27
|
+
.ck h2.radEdH2{
|
28
|
+
font: bold 13pt Cambria, sans-serif;
|
29
|
+
color: #003388;
|
30
|
+
}
|
31
|
+
|
32
|
+
.ck h3.radEdH3{
|
33
|
+
font: bold 12pt Cambria, sans-serif;
|
34
|
+
color: #003388;
|
35
|
+
}
|
36
|
+
|
37
|
+
.ck .ck-heading_ingress {
|
38
|
+
font-size: 20px !important;
|
39
|
+
font-weight: bold;
|
40
|
+
}
|
41
|
+
|
42
|
+
.radEdIngress{
|
43
|
+
font: bold 14pt Cambria, sans-serif;
|
44
|
+
}
|
@@ -21,7 +21,8 @@
|
|
21
21
|
export function getLocalizedOptions( editor ) {
|
22
22
|
const t = editor.t;
|
23
23
|
const localizedTitles = {
|
24
|
-
Paragraph: t( '
|
24
|
+
Paragraph: t( 'Default' ),
|
25
|
+
Ingress: t( 'Ingress' ),
|
25
26
|
'Heading 1': t( 'Heading %0', '1' ),
|
26
27
|
'Heading 2': t( 'Heading %0', '2' ),
|
27
28
|
'Heading 3': t( 'Heading %0', '3' ),
|
@@ -1,95 +1,99 @@
|
|
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 table/commands/setheadercolumncommand
|
8
|
-
*/
|
9
|
-
|
10
|
-
import { Command } from 'ckeditor5/src/core';
|
11
|
-
|
12
|
-
import {
|
13
|
-
isHeadingColumnCell,
|
14
|
-
updateNumericAttribute
|
15
|
-
} from '../utils/common';
|
16
|
-
import { getColumnIndexes, getSelectionAffectedTableCells } from '../utils/selection';
|
17
|
-
import { getHorizontallyOverlappingCells, splitVertically } from '../utils/structure';
|
18
|
-
|
19
|
-
/**
|
20
|
-
* The header column command.
|
21
|
-
*
|
22
|
-
* The command is registered by {@link module:table/tableediting~TableEditing} as the `'setTableColumnHeader'` editor command.
|
23
|
-
*
|
24
|
-
* You can make the column containing the selected cell a [header](https://www.w3.org/TR/html50/tabular-data.html#the-th-element)
|
25
|
-
* by executing:
|
26
|
-
*
|
27
|
-
* editor.execute( 'setTableColumnHeader' );
|
28
|
-
*
|
29
|
-
* **Note:** All preceding columns will also become headers. If the current column is already a header, executing this command
|
30
|
-
* will make it a regular column back again (including the following columns).
|
31
|
-
*
|
32
|
-
* @extends module:core/command~Command
|
33
|
-
*/
|
34
|
-
export default class SetHeaderColumnCommand extends Command {
|
35
|
-
/**
|
36
|
-
* @inheritDoc
|
37
|
-
*/
|
38
|
-
refresh() {
|
39
|
-
const model = this.editor.model;
|
40
|
-
const selectedCells = getSelectionAffectedTableCells( model.document.selection );
|
41
|
-
const tableUtils = this.editor.plugins.get( 'TableUtils' );
|
42
|
-
const isInTable = selectedCells.length > 0;
|
43
|
-
|
44
|
-
this.isEnabled = isInTable;
|
45
|
-
|
46
|
-
/**
|
47
|
-
* Flag indicating whether the command is active. The command is active when the
|
48
|
-
* {@link module:engine/model/selection~Selection} is in a header column.
|
49
|
-
*
|
50
|
-
* @observable
|
51
|
-
* @readonly
|
52
|
-
* @member {Boolean} #value
|
53
|
-
*/
|
54
|
-
this.value = isInTable && selectedCells.every( cell => isHeadingColumnCell( tableUtils, cell ) );
|
55
|
-
}
|
56
|
-
|
57
|
-
/**
|
58
|
-
* Executes the command.
|
59
|
-
*
|
60
|
-
* When the selection is in a non-header column, the command will set the `headingColumns` table attribute to cover that column.
|
61
|
-
*
|
62
|
-
* When the selection is already in a header column, it will set `headingColumns` so the heading section will end before that column.
|
63
|
-
*
|
64
|
-
* @fires execute
|
65
|
-
* @param {Object} [options]
|
66
|
-
* @param {Boolean} [options.forceValue] If set, the command will set (`true`) or unset (`false`) the header columns according to
|
67
|
-
* the `forceValue` parameter instead of the current model state.
|
68
|
-
*/
|
69
|
-
execute( options = {} ) {
|
70
|
-
if ( options.forceValue === this.value ) {
|
71
|
-
return;
|
72
|
-
}
|
73
|
-
|
74
|
-
const model = this.editor.model;
|
75
|
-
const selectedCells = getSelectionAffectedTableCells( model.document.selection );
|
76
|
-
const table = selectedCells[ 0 ].findAncestor( 'table' );
|
77
|
-
|
78
|
-
const { first, last } = getColumnIndexes( selectedCells );
|
79
|
-
const headingColumnsToSet = this.value ? first : last + 1;
|
80
|
-
|
81
|
-
model.change( writer => {
|
82
|
-
if
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
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 table/commands/setheadercolumncommand
|
8
|
+
*/
|
9
|
+
|
10
|
+
import { Command } from 'ckeditor5/src/core';
|
11
|
+
|
12
|
+
import {
|
13
|
+
isHeadingColumnCell,
|
14
|
+
updateNumericAttribute
|
15
|
+
} from '../utils/common';
|
16
|
+
import { getColumnIndexes, getSelectionAffectedTableCells } from '../utils/selection';
|
17
|
+
import { getHorizontallyOverlappingCells, splitVertically } from '../utils/structure';
|
18
|
+
|
19
|
+
/**
|
20
|
+
* The header column command.
|
21
|
+
*
|
22
|
+
* The command is registered by {@link module:table/tableediting~TableEditing} as the `'setTableColumnHeader'` editor command.
|
23
|
+
*
|
24
|
+
* You can make the column containing the selected cell a [header](https://www.w3.org/TR/html50/tabular-data.html#the-th-element)
|
25
|
+
* by executing:
|
26
|
+
*
|
27
|
+
* editor.execute( 'setTableColumnHeader' );
|
28
|
+
*
|
29
|
+
* **Note:** All preceding columns will also become headers. If the current column is already a header, executing this command
|
30
|
+
* will make it a regular column back again (including the following columns).
|
31
|
+
*
|
32
|
+
* @extends module:core/command~Command
|
33
|
+
*/
|
34
|
+
export default class SetHeaderColumnCommand extends Command {
|
35
|
+
/**
|
36
|
+
* @inheritDoc
|
37
|
+
*/
|
38
|
+
refresh() {
|
39
|
+
const model = this.editor.model;
|
40
|
+
const selectedCells = getSelectionAffectedTableCells( model.document.selection );
|
41
|
+
const tableUtils = this.editor.plugins.get( 'TableUtils' );
|
42
|
+
const isInTable = selectedCells.length > 0;
|
43
|
+
|
44
|
+
this.isEnabled = isInTable;
|
45
|
+
|
46
|
+
/**
|
47
|
+
* Flag indicating whether the command is active. The command is active when the
|
48
|
+
* {@link module:engine/model/selection~Selection} is in a header column.
|
49
|
+
*
|
50
|
+
* @observable
|
51
|
+
* @readonly
|
52
|
+
* @member {Boolean} #value
|
53
|
+
*/
|
54
|
+
this.value = isInTable && selectedCells.every( cell => isHeadingColumnCell( tableUtils, cell ) );
|
55
|
+
}
|
56
|
+
|
57
|
+
/**
|
58
|
+
* Executes the command.
|
59
|
+
*
|
60
|
+
* When the selection is in a non-header column, the command will set the `headingColumns` table attribute to cover that column.
|
61
|
+
*
|
62
|
+
* When the selection is already in a header column, it will set `headingColumns` so the heading section will end before that column.
|
63
|
+
*
|
64
|
+
* @fires execute
|
65
|
+
* @param {Object} [options]
|
66
|
+
* @param {Boolean} [options.forceValue] If set, the command will set (`true`) or unset (`false`) the header columns according to
|
67
|
+
* the `forceValue` parameter instead of the current model state.
|
68
|
+
*/
|
69
|
+
execute( options = {} ) {
|
70
|
+
if ( options.forceValue === this.value ) {
|
71
|
+
return;
|
72
|
+
}
|
73
|
+
|
74
|
+
const model = this.editor.model;
|
75
|
+
const selectedCells = getSelectionAffectedTableCells( model.document.selection );
|
76
|
+
const table = selectedCells[ 0 ].findAncestor( 'table' );
|
77
|
+
|
78
|
+
const { first, last } = getColumnIndexes( selectedCells );
|
79
|
+
const headingColumnsToSet = this.value ? first : last + 1;
|
80
|
+
|
81
|
+
model.change( writer => {
|
82
|
+
if(headingColumnsToSet > 1){
|
83
|
+
return;
|
84
|
+
}
|
85
|
+
|
86
|
+
if ( headingColumnsToSet ) {
|
87
|
+
// Changing heading columns requires to check if any of a heading cell is overlapping horizontally the table head.
|
88
|
+
// Any table cell that has a colspan attribute > 1 will not exceed the table head so we need to fix it in columns before.
|
89
|
+
const overlappingCells = getHorizontallyOverlappingCells( table, headingColumnsToSet );
|
90
|
+
|
91
|
+
for ( const { cell, column } of overlappingCells ) {
|
92
|
+
splitVertically( cell, column, headingColumnsToSet, writer );
|
93
|
+
}
|
94
|
+
}
|
95
|
+
|
96
|
+
updateNumericAttribute( 'headingColumns', headingColumnsToSet, table, writer, 0 );
|
97
|
+
} );
|
98
|
+
}
|
99
|
+
}
|
@@ -1,105 +1,110 @@
|
|
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 table/commands/setheaderrowcommand
|
8
|
-
*/
|
9
|
-
|
10
|
-
import { Command } from 'ckeditor5/src/core';
|
11
|
-
|
12
|
-
import { updateNumericAttribute } from '../utils/common';
|
13
|
-
import { getRowIndexes, getSelectionAffectedTableCells } from '../utils/selection';
|
14
|
-
import { getVerticallyOverlappingCells, splitHorizontally } from '../utils/structure';
|
15
|
-
|
16
|
-
/**
|
17
|
-
* The header row command.
|
18
|
-
*
|
19
|
-
* The command is registered by {@link module:table/tableediting~TableEditing} as the `'setTableColumnHeader'` editor command.
|
20
|
-
*
|
21
|
-
* You can make the row containing the selected cell a [header](https://www.w3.org/TR/html50/tabular-data.html#the-th-element) by executing:
|
22
|
-
*
|
23
|
-
* editor.execute( 'setTableRowHeader' );
|
24
|
-
*
|
25
|
-
* **Note:** All preceding rows will also become headers. If the current row is already a header, executing this command
|
26
|
-
* will make it a regular row back again (including the following rows).
|
27
|
-
*
|
28
|
-
* @extends module:core/command~Command
|
29
|
-
*/
|
30
|
-
export default class SetHeaderRowCommand extends Command {
|
31
|
-
/**
|
32
|
-
* @inheritDoc
|
33
|
-
*/
|
34
|
-
refresh() {
|
35
|
-
const model = this.editor.model;
|
36
|
-
const selectedCells = getSelectionAffectedTableCells( model.document.selection );
|
37
|
-
const isInTable = selectedCells.length > 0;
|
38
|
-
|
39
|
-
this.isEnabled = isInTable;
|
40
|
-
|
41
|
-
/**
|
42
|
-
* Flag indicating whether the command is active. The command is active when the
|
43
|
-
* {@link module:engine/model/selection~Selection} is in a header row.
|
44
|
-
*
|
45
|
-
* @observable
|
46
|
-
* @readonly
|
47
|
-
* @member {Boolean} #value
|
48
|
-
*/
|
49
|
-
this.value = isInTable && selectedCells.every( cell => this._isInHeading( cell, cell.parent.parent ) );
|
50
|
-
}
|
51
|
-
|
52
|
-
/**
|
53
|
-
* Executes the command.
|
54
|
-
*
|
55
|
-
* When the selection is in a non-header row, the command will set the `headingRows` table attribute to cover that row.
|
56
|
-
*
|
57
|
-
* When the selection is already in a header row, it will set `headingRows` so the heading section will end before that row.
|
58
|
-
*
|
59
|
-
* @fires execute
|
60
|
-
* @param {Object} options
|
61
|
-
* @param {Boolean} [options.forceValue] If set, the command will set (`true`) or unset (`false`) the header rows according to
|
62
|
-
* the `forceValue` parameter instead of the current model state.
|
63
|
-
*/
|
64
|
-
execute( options = {} ) {
|
65
|
-
if ( options.forceValue === this.value ) {
|
66
|
-
return;
|
67
|
-
}
|
68
|
-
const model = this.editor.model;
|
69
|
-
const selectedCells = getSelectionAffectedTableCells( model.document.selection );
|
70
|
-
const table = selectedCells[ 0 ].findAncestor( 'table' );
|
71
|
-
|
72
|
-
const { first, last } = getRowIndexes( selectedCells );
|
73
|
-
const headingRowsToSet = this.value ? first : last + 1;
|
74
|
-
const currentHeadingRows = table.getAttribute( 'headingRows' ) || 0;
|
75
|
-
|
76
|
-
model.change( writer => {
|
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
|
-
|
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 table/commands/setheaderrowcommand
|
8
|
+
*/
|
9
|
+
|
10
|
+
import { Command } from 'ckeditor5/src/core';
|
11
|
+
|
12
|
+
import { updateNumericAttribute } from '../utils/common';
|
13
|
+
import { getRowIndexes, getSelectionAffectedTableCells } from '../utils/selection';
|
14
|
+
import { getVerticallyOverlappingCells, splitHorizontally } from '../utils/structure';
|
15
|
+
|
16
|
+
/**
|
17
|
+
* The header row command.
|
18
|
+
*
|
19
|
+
* The command is registered by {@link module:table/tableediting~TableEditing} as the `'setTableColumnHeader'` editor command.
|
20
|
+
*
|
21
|
+
* You can make the row containing the selected cell a [header](https://www.w3.org/TR/html50/tabular-data.html#the-th-element) by executing:
|
22
|
+
*
|
23
|
+
* editor.execute( 'setTableRowHeader' );
|
24
|
+
*
|
25
|
+
* **Note:** All preceding rows will also become headers. If the current row is already a header, executing this command
|
26
|
+
* will make it a regular row back again (including the following rows).
|
27
|
+
*
|
28
|
+
* @extends module:core/command~Command
|
29
|
+
*/
|
30
|
+
export default class SetHeaderRowCommand extends Command {
|
31
|
+
/**
|
32
|
+
* @inheritDoc
|
33
|
+
*/
|
34
|
+
refresh() {
|
35
|
+
const model = this.editor.model;
|
36
|
+
const selectedCells = getSelectionAffectedTableCells( model.document.selection );
|
37
|
+
const isInTable = selectedCells.length > 0;
|
38
|
+
|
39
|
+
this.isEnabled = isInTable;
|
40
|
+
|
41
|
+
/**
|
42
|
+
* Flag indicating whether the command is active. The command is active when the
|
43
|
+
* {@link module:engine/model/selection~Selection} is in a header row.
|
44
|
+
*
|
45
|
+
* @observable
|
46
|
+
* @readonly
|
47
|
+
* @member {Boolean} #value
|
48
|
+
*/
|
49
|
+
this.value = isInTable && selectedCells.every( cell => this._isInHeading( cell, cell.parent.parent ) );
|
50
|
+
}
|
51
|
+
|
52
|
+
/**
|
53
|
+
* Executes the command.
|
54
|
+
*
|
55
|
+
* When the selection is in a non-header row, the command will set the `headingRows` table attribute to cover that row.
|
56
|
+
*
|
57
|
+
* When the selection is already in a header row, it will set `headingRows` so the heading section will end before that row.
|
58
|
+
*
|
59
|
+
* @fires execute
|
60
|
+
* @param {Object} options
|
61
|
+
* @param {Boolean} [options.forceValue] If set, the command will set (`true`) or unset (`false`) the header rows according to
|
62
|
+
* the `forceValue` parameter instead of the current model state.
|
63
|
+
*/
|
64
|
+
execute( options = {} ) {
|
65
|
+
if ( options.forceValue === this.value ) {
|
66
|
+
return;
|
67
|
+
}
|
68
|
+
const model = this.editor.model;
|
69
|
+
const selectedCells = getSelectionAffectedTableCells( model.document.selection );
|
70
|
+
const table = selectedCells[ 0 ].findAncestor( 'table' );
|
71
|
+
|
72
|
+
const { first, last } = getRowIndexes( selectedCells );
|
73
|
+
const headingRowsToSet = this.value ? first : last + 1; // Only first row, origin is last + 1
|
74
|
+
const currentHeadingRows = table.getAttribute( 'headingRows' ) || 0;
|
75
|
+
|
76
|
+
model.change( writer => {
|
77
|
+
|
78
|
+
if(headingRowsToSet > 1){
|
79
|
+
return;
|
80
|
+
}
|
81
|
+
|
82
|
+
if ( headingRowsToSet ) {
|
83
|
+
// Changing heading rows requires to check if any of a heading cell is overlapping vertically the table head.
|
84
|
+
// Any table cell that has a rowspan attribute > 1 will not exceed the table head so we need to fix it in rows below.
|
85
|
+
const startRow = headingRowsToSet > currentHeadingRows ? currentHeadingRows : 0;
|
86
|
+
const overlappingCells = getVerticallyOverlappingCells( table, headingRowsToSet, startRow );
|
87
|
+
|
88
|
+
for ( const { cell } of overlappingCells ) {
|
89
|
+
splitHorizontally( cell, headingRowsToSet, writer );
|
90
|
+
}
|
91
|
+
}
|
92
|
+
|
93
|
+
updateNumericAttribute( 'headingRows', headingRowsToSet, table, writer, 0 );
|
94
|
+
} );
|
95
|
+
}
|
96
|
+
|
97
|
+
/**
|
98
|
+
* Checks if a table cell is in the heading section.
|
99
|
+
*
|
100
|
+
* @param {module:engine/model/element~Element} tableCell
|
101
|
+
* @param {module:engine/model/element~Element} table
|
102
|
+
* @returns {Boolean}
|
103
|
+
* @private
|
104
|
+
*/
|
105
|
+
_isInHeading( tableCell, table ) {
|
106
|
+
const headingRows = parseInt( table.getAttribute( 'headingRows' ) || 0 );
|
107
|
+
|
108
|
+
return !!headingRows && tableCell.parent.index < headingRows;
|
109
|
+
}
|
110
|
+
}
|