|
|
@@ -0,0 +1,104 @@
|
|
|
+/**
|
|
|
+ * @license Copyright (c) 2003-2019, 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
|
|
|
+ */
|
|
|
+ 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', {
|
|
|
+ style: 'page-break-after: always'
|
|
|
+ } );
|
|
|
+
|
|
|
+ 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' );
|
|
|
+
|
|
|
+ viewWriter.addClass( 'ck-page-break', viewWrapper );
|
|
|
+ viewWriter.setCustomProperty( 'pageBreak', true, viewWrapper );
|
|
|
+
|
|
|
+ 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 doesn't have any child.
|
|
|
+ if ( !viewSpan.is( 'span' ) || viewSpan.getStyle( 'display' ) != 'none' || viewSpan.childCount != 0 ) {
|
|
|
+ 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 } );
|
|
|
+}
|