Bläddra i källkod

Update the snippet code.

Maciej Gołaszewski 5 år sedan
förälder
incheckning
ce4d76d115

+ 9 - 1
packages/ckeditor5-engine/docs/_snippets/framework/element-reconversion-demo.html

@@ -9,7 +9,8 @@
 	.ck-content .info-box-actions button {
 		font-size: 0.8em;
 		border: 1px solid hsl(0, 0%, 80%);
-		padding: 2px;
+		padding: 2px 4px;
+		margin-right: 0.5em;
 	}
 
 	.ck-content .info-box-title {
@@ -50,6 +51,13 @@
 	.ck-content .info-box-content p:last-child {
 		margin-bottom: 0;
 	}
+
+	.ck-content .info-box-url {
+		margin: 0.5em 0;
+		font-style: italic;
+		font-size: 0.8em;
+		color: hsl(0, 0%, 20%);
+	}
 </style>
 
 <div id="editor-element-reconversion">

+ 67 - 30
packages/ckeditor5-engine/docs/_snippets/framework/element-reconversion-demo.js

@@ -29,35 +29,54 @@ const upcastInfoBox = ( viewElement, { writer } ) => {
 	return complexInfoBox;
 };
 
-const renderActionsView = ( editor, modelElement ) => function( domElement ) {
+function addActionButton( text, callback, domElement, editor ) {
 	const domDocument = domElement.ownerDocument;
-	const urlButton = createElement( domDocument, 'button', {}, 'Set URL' );
 
-	urlButton.addEventListener( 'click', () => {
+	const button = createElement( domDocument, 'button', {}, [ text ] );
+
+	button.addEventListener( 'click', () => {
+		editor.model.change( callback );
+	} );
+
+	domElement.appendChild( button );
+
+	return button;
+}
+
+const renderActionsView = ( editor, modelElement ) => function( domElement ) {
+	addActionButton( 'Set URL', writer => {
 		// eslint-disable-next-line no-alert
 		const newURL = prompt( 'Set URL', modelElement.getAttribute( 'infoBoxURL' ) || '' );
 
-		editor.model.change( writer => {
-			writer.setAttribute( 'infoBoxURL', newURL, modelElement );
-		} );
-	} );
+		writer.setAttribute( 'infoBoxURL', newURL, modelElement );
+	}, domElement, editor );
 
 	const currentType = modelElement.getAttribute( 'infoBoxType' );
 	const newType = currentType === 'info' ? 'warning' : 'info';
 
-	const typeButton = createElement( domDocument, 'button', {}, `Change to ${ newType }` );
+	addActionButton( `Change to ${ newType }`, writer => {
+		writer.setAttribute( 'infoBoxType', newType, modelElement );
+	}, domElement, editor );
 
-	typeButton.addEventListener( 'click', () => {
-		editor.model.change( writer => {
-			writer.setAttribute( 'infoBoxType', newType, modelElement );
-		} );
-	} );
+	const childCount = modelElement.childCount;
+
+	const addButton = addActionButton( 'Add content box', writer => {
+		writer.insertElement( 'complexInfoBoxContent', modelElement, 'end' );
+	}, domElement, editor );
+
+	if ( childCount > 4 ) {
+		addButton.setAttribute( 'disabled', 'disabled' );
+	}
+
+	const removeButton = addActionButton( 'Remove content box', writer => {
+		writer.remove( modelElement.getChild( childCount - 1 ) );
+	}, domElement, editor );
 
-	domElement.appendChild( urlButton );
-	domElement.appendChild( typeButton );
+	if ( childCount < 3 ) {
+		removeButton.setAttribute( 'disabled', 'disabled' );
+	}
 };
 
-// TODO: simplify to hide complexity
 const downcastInfoBox = editor => {
 	return ( modelElement, { writer, consumable, mapper } ) => {
 		const complexInfoBoxView = writer.createContainerElement( 'div', {
@@ -68,14 +87,6 @@ const downcastInfoBox = editor => {
 
 		writer.addClass( `info-box-${ type }`, complexInfoBoxView );
 
-		const actionsView = writer.createRawElement( 'div', {
-			class: 'info-box-actions',
-			contenteditable: 'false', 			// Prevent editing of the element:
-			'data-cke-ignore-events': 'true'	// Allows using custom UI elements inside editing view.
-		}, renderActionsView( editor, modelElement ) );
-
-		writer.insert( writer.createPositionAt( complexInfoBoxView, 'end' ), actionsView );
-
 		for ( const child of modelElement.getChildren() ) {
 			const childView = writer.createContainerElement( 'div' );
 
@@ -87,9 +98,26 @@ const downcastInfoBox = editor => {
 
 			consumable.consume( child, 'insert' );
 			mapper.bindElements( child, childView );
+
 			writer.insert( writer.createPositionAt( complexInfoBoxView, 'end' ), childView );
 		}
 
+		const urlBox = writer.createRawElement( 'div', {
+			class: 'info-box-url'
+		}, function( domElement ) {
+			domElement.innerText = `URL: "${ modelElement.getAttribute( 'infoBoxURL' ) }"`;
+		} );
+
+		writer.insert( writer.createPositionAt( complexInfoBoxView, 'end' ), urlBox );
+
+		const actionsView = writer.createRawElement( 'div', {
+			class: 'info-box-actions',
+			contenteditable: 'false', 			// Prevent editing of the element:
+			'data-cke-ignore-events': 'true'	// Allows using custom UI elements inside editing view.
+		}, renderActionsView( editor, modelElement ) );
+
+		writer.insert( writer.createPositionAt( complexInfoBoxView, 'end' ), actionsView );
+
 		return complexInfoBoxView;
 	};
 };
@@ -101,7 +129,9 @@ class ComplexInfoBox {
 	}
 
 	_defineConversion( editor ) {
-		editor.conversion.for( 'upcast' )
+		const conversion = editor.conversion;
+
+		conversion.for( 'upcast' )
 			.elementToElement( {
 				view: { name: 'div', classes: [ 'info-box' ] },
 				model: upcastInfoBox
@@ -116,7 +146,7 @@ class ComplexInfoBox {
 			} );
 
 		// The downcast conversion must be split as you need a widget in the editing pipeline.
-		editor.conversion.for( 'downcast' ).elementToElement( {
+		conversion.for( 'downcast' ).elementToElement( {
 			model: 'complexInfoBox',
 			view: downcastInfoBox( editor ),
 			triggerBy: {
@@ -127,8 +157,10 @@ class ComplexInfoBox {
 	}
 
 	_defineSchema( editor ) {
+		const schema = editor.model.schema;
+
 		// The main element with attributes for type and URL:
-		editor.model.schema.register( 'complexInfoBox', {
+		schema.register( 'complexInfoBox', {
 			allowWhere: '$block',
 			allowContentOf: '$root',
 			isObject: true,
@@ -136,14 +168,19 @@ class ComplexInfoBox {
 		} );
 
 		// A text-only title.
-		editor.model.schema.register( 'complexInfoBoxTitle', {
+		schema.register( 'complexInfoBoxTitle', {
 			isLimit: true,
 			allowIn: 'complexInfoBox'
 		} );
-		editor.model.schema.extend( '$text', { allowIn: 'complexInfoBoxTitle' } );
+		schema.extend( '$text', { allowIn: 'complexInfoBoxTitle' } );
+		schema.addAttributeCheck( context => {
+			if ( context.endsWith( 'complexInfoBoxTitle $text' ) ) {
+				return false;
+			}
+		} );
 
 		// A content which can have any content allowed in $root.
-		editor.model.schema.register( 'complexInfoBoxContent', {
+		schema.register( 'complexInfoBoxContent', {
 			isLimit: true,
 			allowIn: 'complexInfoBox',
 			allowContentOf: '$root'

+ 7 - 6
packages/ckeditor5-engine/docs/framework/guides/deep-dive/element-reconversion.md

@@ -29,10 +29,10 @@ Let's take a look at the below enhanced info box might behave:
 
 The above demo assumes that each box:
 
-- have 1 title
-- have multiple content-boxes
-- have a type ("info" or "warning")
-- have a URL
+- Always have a title.
+- Have 1 to 4 content-boxes.
+- Have "info" or "warning" type.
+- Have a URL.
 
 Those can be represented in the editor's {@link framework/guides/deep-dive/schema schema} as follows:
 
@@ -88,7 +88,7 @@ Note that, when using `children` configuration option the current implementation
 * will have a "flat" structure
 </info-box>
 
-A simplified model markup for the info box from the {@link #demo}:
+A simplified model markup for the info box from the {@link framework/guides/deep-dive/element-reconversion#demo}:
 
 ```html
 <complexInfoBox infoBoxType="info" infoBoxURL="http://cksource.com">
@@ -225,7 +225,8 @@ I think that an image here might be useful. To not loose the idea - it might be
 
 ### Upcast conversion
 
-THe upcast conversion uses standard element-to-element converters for box & title and a custom converter for the info box to extract metadata from the data.
+The upcast conversion uses standard element-to-element converters for box & title and a custom converter for the info box to extract
+metadata from the data.
 
 ```js
 editor.conversion.for( 'upcast' )