This repository has been archived by the owner on Jun 26, 2020. It is now read-only.
/
pagebreakediting.js
128 lines (104 loc) · 4.06 KB
/
pagebreakediting.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
/**
* @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 page-break/pagebreakediting
*/
import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
import PageBreakCommand from './pagebreakcommand';
import { toWidget } from '@ckeditor/ckeditor5-widget/src/utils';
import first from '@ckeditor/ckeditor5-utils/src/first';
import '../theme/pagebreak.css';
/**
* The page break editing feature.
*
* @extends module:core/plugin~Plugin
*/
export default class PageBreakEditing extends Plugin {
/**
* @inheritDoc
*/
static get pluginName() {
return 'PageBreakEditing';
}
/**
* @inheritDoc
*/
init() {
const editor = this.editor;
const schema = editor.model.schema;
const t = editor.t;
const conversion = editor.conversion;
schema.register( 'pageBreak', {
isObject: true,
allowWhere: '$block'
} );
conversion.for( 'dataDowncast' ).elementToElement( {
model: 'pageBreak',
view: ( modelElement, viewWriter ) => {
const divElement = viewWriter.createContainerElement( 'div', {
class: 'page-break',
// If user has no `.ck-content` styles, it should always break a page during print.
style: 'page-break-after: always'
} );
// For a rationale of using span inside a div see:
// https://github.com/ckeditor/ckeditor5-page-break/pull/1#discussion_r328934062.
const spanElement = viewWriter.createContainerElement( 'span', {
style: 'display: none'
} );
viewWriter.insert( viewWriter.createPositionAt( divElement, 0 ), spanElement );
return divElement;
}
} );
conversion.for( 'editingDowncast' ).elementToElement( {
model: 'pageBreak',
view: ( modelElement, viewWriter ) => {
const label = t( 'Page break' );
const viewWrapper = viewWriter.createContainerElement( 'div' );
const viewLabelElement = viewWriter.createContainerElement( 'span' );
const innerText = viewWriter.createText( t( 'Page break' ) );
viewWriter.addClass( 'page-break', viewWrapper );
viewWriter.setCustomProperty( 'pageBreak', true, viewWrapper );
viewWriter.addClass( 'page-break__label', viewLabelElement );
viewWriter.insert( viewWriter.createPositionAt( viewWrapper, 0 ), viewLabelElement );
viewWriter.insert( viewWriter.createPositionAt( viewLabelElement, 0 ), innerText );
return toPageBreakWidget( viewWrapper, viewWriter, label );
}
} );
conversion.for( 'upcast' )
.elementToElement( {
view: element => {
// The "page break" div must have specified value for the 'page-break-after' definition and single child only.
if ( !element.is( 'div' ) || element.getStyle( 'page-break-after' ) != 'always' || element.childCount != 1 ) {
return;
}
const viewSpan = first( element.getChildren() );
// The child must be the "span" element that is not displayed and has a space inside.
if ( !viewSpan.is( 'span' ) || viewSpan.getStyle( 'display' ) != 'none' || viewSpan.childCount != 1 ) {
return;
}
const text = first( viewSpan.getChildren() );
if ( !text.is( 'text' ) || text.data !== ' ' ) {
return;
}
return { name: true };
},
model: 'pageBreak'
} );
editor.commands.add( 'pageBreak', new PageBreakCommand( editor ) );
}
}
// Converts a given {@link module:engine/view/element~Element} to a page break widget:
// * Adds a {@link module:engine/view/element~Element#_setCustomProperty custom property} allowing to
// recognize the page break widget element.
// * Calls the {@link module:widget/utils~toWidget} function with the proper element's label creator.
//
// @param {module:engine/view/element~Element} viewElement
// @param {module:engine/view/downcastwriter~DowncastWriter} writer An instance of the view writer.
// @param {String} label The element's label.
// @returns {module:engine/view/element~Element}
function toPageBreakWidget( viewElement, writer, label ) {
writer.setCustomProperty( 'pageBreak', true, viewElement );
return toWidget( viewElement, writer, { label } );
}