浏览代码

Moved CSS definitions to proper package.

Kamil Piechaczek 5 年之前
父节点
当前提交
e2d0ad1b14

+ 63 - 78
packages/ckeditor5-html-embed/src/htmlembedediting.js

@@ -56,14 +56,6 @@ export default class HTMLEmbedEditing extends Plugin {
 				};
 			}
 		} );
-
-		/**
-		 * A collection that contains all events that must be attached directly to the DOM elements.
-		 *
-		 * @private
-		 * @type {Set.<Object>}
-		 */
-		this._domListeners = new Set();
 	}
 
 	/**
@@ -89,34 +81,16 @@ export default class HTMLEmbedEditing extends Plugin {
 	}
 
 	/**
-	 * @inheritDoc
-	 */
-	destroy() {
-		for ( const item of this._domListeners ) {
-			item.element.removeEventListener( item.event, item.listener );
-		}
-
-		this._domListeners.clear();
-
-		return super.destroy();
-	}
-
-	/**
 	 * Set-ups converters for the feature.
 	 *
 	 * @private
 	 */
 	_setupConversion() {
-		// TODO: Typing around the widget does not work after adding the 'data-cke-ignore-events` attribute.
-		// TODO: Wrapping the inner views in another container with the attribute resolved WTA issue but events
-		// TODO: inside the views are not triggered.
 		const editor = this.editor;
 		const t = editor.t;
 		const view = editor.editing.view;
 
 		const htmlEmbedConfig = editor.config.get( 'htmlEmbed' );
-		const domListeners = this._domListeners;
-
 		const upcastWriter = new UpcastWriter( view.document );
 		const htmlProcessor = new HtmlDataProcessor( view.document );
 
@@ -150,23 +124,31 @@ export default class HTMLEmbedEditing extends Plugin {
 				const widgetLabel = t( 'HTML snippet' );
 				const placeholder = t( 'Paste the raw code here.' );
 
-				const viewWrapper = writer.createContainerElement( 'div', {
-					class: 'raw-html',
+				const widgetView = writer.createContainerElement( 'div', {
+					class: 'raw-html'
+				} );
+
+				const rawHtmlContainer = writer.createContainerElement( 'div', {
 					'data-cke-ignore-events': true
 				} );
 
 				// Whether to show a preview mode or editing area.
-				writer.setCustomProperty( 'isEditingSourceActive', false, viewWrapper );
+				writer.setCustomProperty( 'isEditingSourceActive', false, rawHtmlContainer );
+
+				const textareaAttributes = {
+					placeholder,
+					disabled: true,
+					class: 'raw-html__source'
+				};
 
 				// The editing raw HTML field.
-				const textarea = writer.createUIElement( 'textarea', { placeholder }, function( domDocument ) {
+				const sourceElement = writer.createUIElement( 'textarea', textareaAttributes, function( domDocument ) {
 					const root = this.toDomElement( domDocument );
 
-					writer.setCustomProperty( 'DOMElement', root, textarea );
-
+					writer.setCustomProperty( 'domElement', root, sourceElement );
 					root.value = modelElement.getAttribute( 'value' ) || '';
 
-					attachDomListener( root, 'input', () => {
+					root.addEventListener( 'input', () => {
 						editor.execute( 'htmlEmbedUpdate', root.value );
 					} );
 
@@ -177,85 +159,88 @@ export default class HTMLEmbedEditing extends Plugin {
 				const toggleButton = writer.createUIElement( 'div', { class: 'raw-html__switch-mode' }, function( domDocument ) {
 					const root = this.toDomElement( domDocument );
 
-					writer.setCustomProperty( 'DOMElement', root, toggleButton );
+					root.innerHTML = htmlEmbedModeIcon;
+					writer.setCustomProperty( 'domElement', root, toggleButton );
 
-					attachDomListener( root, 'click', evt => {
+					root.addEventListener( 'click', evt => {
 						view.change( writer => {
-							const isEditingSourceActive = viewWrapper.getCustomProperty( 'isEditingSourceActive' );
-
-							if ( isEditingSourceActive ) {
-								writer.removeClass( 'raw-html--edit-source', viewWrapper );
-							} else {
-								writer.addClass( 'raw-html--edit-source', viewWrapper );
+							const isEditingSourceActive = rawHtmlContainer.getCustomProperty( 'isEditingSourceActive' );
+
+							if ( htmlEmbedConfig.previewsInData ) {
+								if ( !isEditingSourceActive ) {
+									writer.removeClass( 'raw-html--display-preview', widgetView );
+								} else {
+									writer.addClass( 'raw-html--display-preview', widgetView );
+								}
 							}
 
-							writer.setCustomProperty( 'isEditingSourceActive', !isEditingSourceActive, viewWrapper );
-							evt.preventDefault();
+							const textarea = sourceElement.getCustomProperty( 'domElement' );
+							textarea.disabled = !textarea.disabled;
+
+							writer.setCustomProperty( 'isEditingSourceActive', !isEditingSourceActive, rawHtmlContainer );
 						} );
-					} );
 
-					root.innerHTML = htmlEmbedModeIcon;
+						evt.preventDefault();
+					} );
 
 					return root;
 				} );
 
-				// The container that renders the HTML.
-				const previewContainer = writer.createRawElement( 'div', { class: 'raw-html__preview' }, function( domElement ) {
-					writer.setCustomProperty( 'DOMElement', domElement, previewContainer );
+				writer.insert( writer.createPositionAt( widgetView, 0 ), rawHtmlContainer );
+				writer.insert( writer.createPositionAt( rawHtmlContainer, 0 ), toggleButton );
+				writer.insert( writer.createPositionAt( rawHtmlContainer, 1 ), sourceElement );
 
-					if ( htmlEmbedConfig.previewsInData ) {
-						const sanitizeOutput = htmlEmbedConfig.sanitizeHtml( modelElement.getAttribute( 'value' ) || '' );
+				// The container that renders the HTML should be created only when `htmlEmbed.previewsInData=true` in the config.
+				if ( htmlEmbedConfig.previewsInData ) {
+					writer.addClass( 'raw-html--preview-enabled', widgetView );
+					writer.addClass( 'raw-html--display-preview', widgetView );
 
-						domElement.innerHTML = sanitizeOutput.html;
-					} else {
-						domElement.innerHTML = '<div class="raw-html__preview-placeholder">Raw HTML snippet.</div>';
-					}
-				} );
+					const previewContainer = writer.createRawElement( 'div', { class: 'raw-html__preview' }, function( domElement ) {
+						writer.setCustomProperty( 'domElement', domElement, previewContainer );
+
+						if ( htmlEmbedConfig.previewsInData ) {
+							const sanitizeOutput = htmlEmbedConfig.sanitizeHtml( modelElement.getAttribute( 'value' ) || '' );
 
-				writer.insert( writer.createPositionAt( viewWrapper, 0 ), toggleButton );
-				writer.insert( writer.createPositionAt( viewWrapper, 1 ), textarea );
-				writer.insert( writer.createPositionAt( viewWrapper, 2 ), previewContainer );
+							domElement.innerHTML = sanitizeOutput.html;
+						}
+					} );
+
+					writer.insert( writer.createPositionAt( rawHtmlContainer, 2 ), previewContainer );
+				}
 
-				return toRawHtmlWidget( viewWrapper, writer, widgetLabel );
+				return toRawHtmlWidget( widgetView, writer, widgetLabel );
 			}
 		} );
 
 		editor.conversion.for( 'editingDowncast' ).add( downcastRawHtmlValueAttribute( htmlEmbedConfig ) );
-
-		// Attaches an event listener to the specified element.
-		//
-		// @params {HTMLElement} element An element that the event will be attached.
-		// @params {String} event A name of the event.
-		// @params {Function} listener A listener that will be executed.
-		function attachDomListener( element, event, listener ) {
-			element.addEventListener( event, listener );
-			domListeners.add( { element, event, listener } );
-		}
 	}
 }
 
 // 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.
+// It updates the source (`textarea`) value and passes an HTML to the preview element in `htmlEmbed.previewsInData=true` mode.
 //
 // @params {module:html-embed/htmlembed~MediaEmbedConfig} htmlEmbedConfig
 // @returns {Function}
 function downcastRawHtmlValueAttribute( htmlEmbedConfig ) {
 	return dispatcher => {
 		dispatcher.on( 'attribute:value:rawHtml', ( evt, data, conversionApi ) => {
-			const viewWrapper = conversionApi.mapper.toViewElement( data.item );
+			const widgetView = conversionApi.mapper.toViewElement( data.item );
+			const rawHtmlContainer = widgetView.getChild( 0 );
 
-			const sourceDOMElement = viewWrapper.getChild( 1 ).getCustomProperty( 'DOMElement' );
-			const previewDOMElement = viewWrapper.getChild( 2 ).getCustomProperty( 'DOMElement' );
+			const textareaDomElement = rawHtmlContainer.getChild( 1 ).getCustomProperty( 'domElement' );
 
-			if ( sourceDOMElement ) {
-				sourceDOMElement.value = data.item.getAttribute( 'value' );
+			if ( textareaDomElement ) {
+				textareaDomElement.value = data.item.getAttribute( 'value' );
 			}
 
-			if ( htmlEmbedConfig.previewsInData && previewDOMElement ) {
-				const sanitizeOutput = htmlEmbedConfig.sanitizeHtml( data.item.getAttribute( 'value' ) );
+			if ( htmlEmbedConfig.previewsInData ) {
+				const previewDomElement = rawHtmlContainer.getChild( 2 ).getCustomProperty( 'domElement' );
 
-				previewDOMElement.innerHTML = sanitizeOutput.html;
+				if ( previewDomElement ) {
+					const sanitizeOutput = htmlEmbedConfig.sanitizeHtml( data.item.getAttribute( 'value' ) );
+					previewDomElement.innerHTML = sanitizeOutput.html;
+				}
 			}
 		} );
 	};

+ 4 - 3
packages/ckeditor5-html-embed/src/htmlembedui.js

@@ -40,13 +40,14 @@ export default class HTMLEmbedUI extends Plugin {
 				editor.execute( 'htmlEmbedInsert' );
 				editor.editing.view.focus();
 
-				const rawHtmlWidget = getSelectedRawHtmlViewWidget( editor.editing.view.document.selection );
+				const widgetWrapper = getSelectedRawHtmlViewWidget( editor.editing.view.document.selection );
+				const rawHtmlContainer = widgetWrapper.getChild( 0 );
 
 				// After inserting a new element, switch to "Edit source" mode.
-				rawHtmlWidget.getChild( 0 ).getCustomProperty( 'DOMElement' ).click();
+				rawHtmlContainer.getChild( 0 ).getCustomProperty( 'domElement' ).click();
 
 				// And focus the edit source element (`textarea`).
-				rawHtmlWidget.getChild( 1 ).getCustomProperty( 'DOMElement' ).focus();
+				rawHtmlContainer.getChild( 1 ).getCustomProperty( 'domElement' ).focus();
 			} );
 
 			return view;

+ 2 - 2
packages/ckeditor5-html-embed/tests/htmlembedui.js

@@ -66,7 +66,7 @@ describe( 'HTMLEMbedEditing', () => {
 	it( 'should switch to edit source mode after inserting the element', () => {
 		htmlEmbedView.fire( 'execute' );
 
-		const editSourceView = viewDocument.getRoot().getChild( 0 ).getChild( 1 );
-		expect( document.activeElement ).to.equal( editSourceView.getCustomProperty( 'DOMElement' ) );
+		const editSourceView = viewDocument.getRoot().getChild( 0 ).getChild( 0 ).getChild( 1 );
+		expect( document.activeElement ).to.equal( editSourceView.getCustomProperty( 'domElement' ) );
 	} );
 } );

+ 0 - 51
packages/ckeditor5-html-embed/theme/htmlembed.css

@@ -2,54 +2,3 @@
  * Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
-
-/* Widget container. */
-.ck-editor__editable .raw-html {
-	position: relative;
-	margin-top: 1em;
-	margin-bottom: 1em;
-}
-
-/* Switch mode button. */
-.ck-editor__editable .raw-html .raw-html__switch-mode {
-	position: absolute;
-	top: 0;
-	right: 0;
-	width: 5em;
-	height: 5em;
-	cursor: pointer;
-}
-
-/* Edit source element. */
-.ck-editor__editable .raw-html textarea {
-	width: 30em;
-	height: 5em;
-	resize: none;
-}
-
-/* Edit source mode is enabled. */
-.ck-editor__editable .raw-html.raw-html--edit-source textarea {
-	display: block;
-}
-
-.ck-editor__editable .raw-html .raw-html__preview {
-	min-height: 5em;
-	min-width: 30em;
-}
-
-/* Edit source mode is enabled. */
-.ck-editor__editable .raw-html.raw-html--edit-source .raw-html__preview {
-	display: none;
-}
-
-/* Preview mode is enabled. */
-.ck-editor__editable .raw-html:not(.raw-html--edit-source) textarea {
-	display: none;
-}
-
-.ck-editor__editable .raw-html__preview-placeholder {
-	height: 5em;
-	background-color: hsl(0, 0%, 50%);
-	text-align: center;
-	line-height: 5em;
-}

+ 54 - 0
packages/ckeditor5-theme-lark/theme/ckeditor5-html-embed/htmlembed.css

@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+.ck-editor__editable {
+	/* The feature container. */
+	& .raw-html {
+		position: relative;
+
+		/* The switch mode button. */
+		& .raw-html__switch-mode {
+			position: absolute;
+			top: 0;
+			right: 0;
+			width: 5em;
+			height: 5em;
+			cursor: pointer;
+		}
+
+		/* The edit source element. */
+		& .raw-html__source {
+			width: 30em;
+			height: 5em;
+			resize: none;
+		}
+	}
+
+	/* Using the feature with enabled previews in data. */
+	& .raw-html--preview-enabled {
+		/* The preview data container. */
+		& .raw-html__preview {
+			min-height: 5em;
+			min-width: 30em;
+			width: calc(100% - 5em);
+		}
+
+		/* Mode: preview the HTML. */
+		&.raw-html--display-preview {
+			& .raw-html__source {
+				display: none;
+			}
+
+			& .raw-html__preview {
+				display: block;
+			}
+		}
+
+		/* Mode: edit the HTML source. */
+		&:not(.raw-html--display-preview) .raw-html__preview {
+			display: none;
+		}
+	}
+}