Browse Source

Docs and wording.

Kamil Piechaczek 5 years ago
parent
commit
642feaf02a

+ 55 - 3
packages/ckeditor5-html-embed/src/htmlembed.js

@@ -52,13 +52,65 @@ export default class HtmlEmbed extends Plugin {
  */
 
 /**
- * TODO
+ * Controls the view produced by the feature.
  *
- * @member {Boolean} [module:html-embed/htmlembed~HtmlEmbedConfig#previewsInData=false]
+ * When `false` (default), the feature produces the `<textarea>` element in the view.
+ *
+ * When `true`, the inserted HTML will be injected directly to the editor.
+ *
+ * **Note:** If the option was set to `true`, do not forget about implementing
+ * the {@link module:html-embed/htmlembed~HtmlEmbedConfig#sanitizeHtml `htmlEmbed.sanitizeHtml()`} function that will control
+ * the output HTML.
+ *
+ * @member {Boolean} [module:html-embed/htmlembed~HtmlEmbedConfig#showPreviews=false]
  */
 
 /**
- * TODO
+ * Allows modifying an input HTML before injecting it directly to the editor's view.
+ *
+ * We strongly recommend to overwrite the default function to avoid XSS vulnerability.
+ *
+ * The function receives an input HTML (`String`), and should return an object
+ * that match to the {@link module:html-embed/htmlembed~HtmlEmbedSanitizeOutput} interface.
+ *
+ *  	ClassicEditor
+ *			.create( editorElement, {
+ * 				htmlEmbed: {
+ * 				    showPreviews: true,
+ * 				    sanitizeHtml( inputHtml ) {
+ * 				        // Strip dangerous elements and attributes, e.g.:
+ * 				        // the `<script>` elements or `[on*]` attributes.
+ *
+ * 				        return {
+ * 				            html: ...,
+ * 				            hasModified: ...
+ * 				        }
+ * 				    },
+ * 				}
+ *			} )
+ *			.then( ... )
+ *			.catch( ... );
+ *
+ *	**Note:** The function is used only if the feature has enabled previews in the view
+ *	({@link module:html-embed/htmlembed~HtmlEmbedConfig#showPreviews} is set to `true`).
  *
  * @member {Function} [module:html-embed/htmlembed~HtmlEmbedConfig#sanitizeHtml]
  */
+
+/**
+ * An object returned by the {@link module:html-embed/htmlembed~HtmlEmbedConfig#sanitizeHtml} function should match to this interface.
+ *
+ * @interface HtmlEmbedSanitizeOutput
+ */
+
+/**
+ * An output HTML that will be inserted into the {@glink framework/guides/architecture/editing-engine editing view}.
+ *
+ * @member {String} module:html-embed/htmlembed~HtmlEmbedSanitizeOutput#html
+ */
+
+/**
+ * A flag that describes whether the output HTML is different that an input value.
+ *
+ * @member {Boolean} [module:html-embed/htmlembed~HtmlEmbedSanitizeOutput#hasModified]
+ */

+ 8 - 8
packages/ckeditor5-html-embed/src/htmlembedediting.js

@@ -42,10 +42,10 @@ export default class HtmlEmbedEditing extends Plugin {
 		super( editor );
 
 		editor.config.define( 'htmlEmbed', {
-			previewsInData: false,
+			showPreviews: false,
 			sanitizeHtml: rawHtml => {
 				/**
-				 * When using the HTML embed feature with `htmlEmbed.previewsInData=true` option, it is strongly recommended to
+				 * When using the HTML embed feature with `htmlEmbed.showPreviews=true` option, it is strongly recommended to
 				 * define a sanitize function that will clean up an input HTML in order to avoid XSS vulnerability.
 				 *
 				 * For a detailed overview, check the {@glink features/html-embed HTML embed feature} documentation.
@@ -174,7 +174,7 @@ export default class HtmlEmbedEditing extends Plugin {
 
 					root.addEventListener( 'click', evt => {
 						view.change( writer => {
-							if ( htmlEmbedConfig.previewsInData ) {
+							if ( htmlEmbedConfig.showPreviews ) {
 								if ( widgetView.hasClass( DISPLAY_PREVIEW_CLASS ) ) {
 									writer.removeClass( DISPLAY_PREVIEW_CLASS, widgetView );
 								} else {
@@ -199,8 +199,8 @@ export default class HtmlEmbedEditing extends Plugin {
 				writer.insert( writer.createPositionAt( rawHtmlContainer, 0 ), toggleButton );
 				writer.insert( writer.createPositionAt( rawHtmlContainer, 1 ), sourceElement );
 
-				// The container that renders the HTML should be created only when `htmlEmbed.previewsInData=true` in the config.
-				if ( htmlEmbedConfig.previewsInData ) {
+				// The container that renders the HTML should be created only when `htmlEmbed.showPreviews=true` in the config.
+				if ( htmlEmbedConfig.showPreviews ) {
 					writer.addClass( [ 'raw-html--preview-enabled', DISPLAY_PREVIEW_CLASS ], widgetView );
 
 					const previewContainer = writer.createRawElement( 'div', { class: 'raw-html__preview' }, function( domElement ) {
@@ -228,7 +228,7 @@ export default class HtmlEmbedEditing extends Plugin {
 
 // Returns a converter that handles the `value` attribute of the `rawHtml` element.
 //
-// It updates the source (`textarea`) value and passes an HTML to the preview element if `htmlEmbed.previewsInData=true`.
+// It updates the source (`textarea`) value and passes an HTML to the preview element if `htmlEmbed.showPreviews=true`.
 //
 // @params {module:html-embed/htmlembed~HtmlEmbedConfig} htmlEmbedConfig
 // @returns {Function}
@@ -244,11 +244,11 @@ function downcastRawHtmlValueAttribute( htmlEmbedConfig ) {
 				textareaDomElement.value = data.item.getAttribute( 'value' );
 			}
 
-			if ( htmlEmbedConfig.previewsInData ) {
+			if ( htmlEmbedConfig.showPreviews ) {
 				const previewDomElement = rawHtmlContainer.getChild( 2 ).getCustomProperty( 'domElement' );
 
 				if ( previewDomElement ) {
-					const sanitizeOutput = htmlEmbedConfig.sanitizeHtml( data.item.getAttribute( 'value' ) );
+					const sanitizeOutput = htmlEmbedConfig.sanitizeHtml( data.item.getAttribute( 'value' ) || '' );
 					previewDomElement.innerHTML = sanitizeOutput.html;
 				}
 			}

+ 33 - 5
packages/ckeditor5-html-embed/tests/htmlembedediting.js

@@ -76,9 +76,9 @@ describe( 'HtmlEmbedEditing', () => {
 			htmlEmbed = editor.config.get( 'htmlEmbed' );
 		} );
 
-		describe( 'htmlEmbed.previewsInData', () => {
+		describe( 'htmlEmbed.showPreviews', () => {
 			it( 'should be set to `false` by default', () => {
-				expect( htmlEmbed.previewsInData ).to.equal( false );
+				expect( htmlEmbed.showPreviews ).to.equal( false );
 			} );
 		} );
 
@@ -229,7 +229,7 @@ describe( 'HtmlEmbedEditing', () => {
 	} );
 
 	describe( 'conversion in editing pipeline (model to view)', () => {
-		describe( 'without previews (htmlEmbed.dataInPreviews=false)', () => {
+		describe( 'without previews (htmlEmbed.showPreviews=false)', () => {
 			it( 'converted element should be widgetized', () => {
 				setModelData( model, '<rawHtml></rawHtml>' );
 				const widget = viewDocument.getRoot().getChild( 0 );
@@ -434,7 +434,7 @@ describe( 'HtmlEmbedEditing', () => {
 			} );
 		} );
 
-		describe( 'with previews (htmlEmbed.dataInPreviews=true)', () => {
+		describe( 'with previews (htmlEmbed.showPreviews=true)', () => {
 			let element, editor, model, view, viewDocument, sanitizeHtml;
 
 			testUtils.createSinonSandbox();
@@ -450,7 +450,7 @@ describe( 'HtmlEmbedEditing', () => {
 					.create( element, {
 						plugins: [ HtmlEmbedEditing ],
 						htmlEmbed: {
-							previewsInData: true,
+							showPreviews: true,
 							sanitizeHtml
 						}
 					} )
@@ -561,6 +561,34 @@ describe( 'HtmlEmbedEditing', () => {
 				expect( previewElement.getCustomProperty( 'domElement' ).innerHTML ).to.equal( '<b>Foo.</b>' );
 			} );
 
+			it( 'should pass an empty string if the `value` attribute is empty', () => {
+				setModelData( model, '<rawHtml value="Foo"></rawHtml>' );
+
+				model.change( writer => {
+					writer.setAttribute( 'value', '', model.document.getRoot().getChild( 0 ) );
+				} );
+
+				const widget = viewDocument.getRoot().getChild( 0 );
+				const viewHtmlContainer = widget.getChild( 0 );
+
+				const previewElement = viewHtmlContainer.getChild( 2 ).getCustomProperty( 'domElement' );
+				expect( previewElement.innerHTML ).to.equal( '' );
+			} );
+
+			it( 'should pass an empty string if the `value` attribute was removed', () => {
+				setModelData( model, '<rawHtml value="Foo"></rawHtml>' );
+
+				model.change( writer => {
+					writer.removeAttribute( 'value', model.document.getRoot().getChild( 0 ) );
+				} );
+
+				const widget = viewDocument.getRoot().getChild( 0 );
+				const viewHtmlContainer = widget.getChild( 0 );
+
+				const previewElement = viewHtmlContainer.getChild( 2 ).getCustomProperty( 'domElement' );
+				expect( previewElement.innerHTML ).to.equal( '' );
+			} );
+
 			it( 'should allows modifying the source after clicking the toggle button', () => {
 				setModelData( model, '<rawHtml></rawHtml>' );
 

+ 3 - 3
packages/ckeditor5-html-embed/tests/manual/htmlembed.html

@@ -3,9 +3,9 @@
 </head>
 
 <p>
-    <b>Mode of HTML previews</b>:
-    <input type="radio" id="mode-enabled" name="mode" value="enabled" checked><label for="mode-enabled">Enabled</label>
-    <input type="radio" id="mode-disabled" name="mode" value="disabled"><label for="mode-disabled">Disabled</label>
+    <b>Value of the <code>"htmlEmbed.showPreviews"</code></b>:
+    <input type="radio" id="mode-enabled" name="mode" value="enabled" checked><label for="mode-enabled"><code>true</code></label>
+    <input type="radio" id="mode-disabled" name="mode" value="disabled"><label for="mode-disabled"><code>false</code></label>
 </p>
 
 <div id="editor">

+ 1 - 1
packages/ckeditor5-html-embed/tests/manual/htmlembed.js

@@ -35,7 +35,7 @@ async function startMode( selectedMode ) {
 async function startEnabledPreviewsMode() {
 	await reloadEditor( {
 		htmlEmbed: {
-			previewsInData: true,
+			showPreviews: true,
 			sanitizeHtml( rawHtml ) {
 				const config = getSanitizeHtmlConfig( sanitizeHtml.defaults );
 				const cleanHtml = sanitizeHtml( rawHtml, config );

+ 1 - 1
packages/ckeditor5-html-embed/tests/manual/htmlembed.md

@@ -28,7 +28,7 @@ After the editor initialization, it should contain 5 widgets with embedded HTML:
 
 All resources are provided by the ["Sample Files for Development"](http://techslides.com/sample-files-for-development) article. Thanks!
 
-By default, the previews in data mode is enabled. It means that previews should be visible. 
+By default, the "previews in view" mode is enabled. It means that previews should be visible. 
 
 We use the [`sanitize-html`](https://www.npmjs.com/package/sanitize-html) package to clean up the input HTML. It means that some of the 
 elements or attributes may be not rendered in the editing view. However, they still will be returned in the editor's data.