8
0
Quellcode durchsuchen

Initial, test implementation.

Kamil Piechaczek vor 5 Jahren
Ursprung
Commit
eebe876cb5

+ 2 - 1
packages/ckeditor5-html-embed/lang/contexts.json

@@ -1,3 +1,4 @@
 {
-  "Insert HTML": "Toolbar button tooltip for the HTML embed feature."
+  "Insert HTML": "Toolbar button tooltip for the HTML embed feature.",
+  "HTML snippet": "The HTML snippet."
 }

+ 6 - 2
packages/ckeditor5-html-embed/package.json

@@ -10,9 +10,13 @@
     "ckeditor5-plugin"
   ],
   "dependencies": {
+    "@ckeditor/ckeditor5-core": "^23.0.0",
+    "@ckeditor/ckeditor5-engine": "^23.0.0",
+    "@ckeditor/ckeditor5-ui": "^23.0.0",
+    "@ckeditor/ckeditor5-widget": "^23.0.0",
+    "sanitize-html": "^2.1.0"
   },
-  "devDependencies": {
-  },
+  "devDependencies": {},
   "engines": {
     "node": ">=12.0.0",
     "npm": ">=5.7.1"

+ 55 - 4
packages/ckeditor5-html-embed/src/htmlembedediting.js

@@ -7,10 +7,13 @@
  * @module html-embed/htmlembedediting
  */
 
+import sanitizeHtml from 'sanitize-html';
 import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
 import HTMLEmbedCommand from './htmlembedcommand';
 
 import '../theme/htmlembed.css';
+import { toWidget } from '@ckeditor/ckeditor5-widget/src/utils';
+import { stringify as viewStringify } from '@ckeditor/ckeditor5-engine/src/dev-utils/view';
 
 /**
  * The HTML embed editing feature.
@@ -30,26 +33,74 @@ export default class HTMLEmbedEditing extends Plugin {
 	 */
 	init() {
 		const editor = this.editor;
+		const t = editor.t;
 		const schema = editor.model.schema;
 		const conversion = editor.conversion;
 
-		schema.register( 'horizontalLine', {
+		schema.register( 'rawHtml', {
 			isObject: true,
-			allowWhere: '$block'
+			allowWhere: '$block',
+			allowAttributes: [ 'value' ]
+		} );
+
+		conversion.for( 'upcast' ).elementToElement( {
+			view: {
+				name: 'div',
+				classes: 'raw-html-embed'
+			},
+			model: ( viewElement, { writer } ) => {
+				// Replace all view elements with their string presentations.
+				const innerHTML = [ ...viewElement.getChildren() ]
+					.map( child => viewStringify( child ) )
+					.join( '' );
+
+				return writer.createElement( 'rawHtml', {
+					value: innerHTML
+				} );
+			}
 		} );
 
 		conversion.for( 'dataDowncast' ).elementToElement( {
 			model: 'rawHtml',
-			view: () => {
+			view: ( modelElement, { writer } ) => {
+				return writer.createRawElement( 'div', { class: 'raw-html-embed' }, function( domElement ) {
+					domElement.innerHTML = modelElement.getAttribute( 'value' );
+				} );
 			}
 		} );
 
 		conversion.for( 'editingDowncast' ).elementToElement( {
 			model: 'rawHtml',
-			view: () => {
+			view: ( modelElement, { writer } ) => {
+				const label = t( 'HTML snippet' );
+				const viewWrapper = writer.createContainerElement( 'div' );
+
+				// TODO: `viewWrapper` should not be here but `toWidget` can be used only with the container element.
+				const rawElement = writer.createRawElement( 'div', { class: 'raw-html-embed' }, function( domElement ) {
+					domElement.innerHTML = sanitizeHtml( modelElement.getAttribute( 'value' ) );
+				} );
+
+				writer.insert( writer.createPositionAt( viewWrapper, 0 ), rawElement );
+
+				return toRawHtmlWidget( viewWrapper, writer, label );
 			}
 		} );
 
 		editor.commands.add( 'htmlEmbed', new HTMLEmbedCommand( editor ) );
 	}
 }
+
+// Converts a given {@link module:engine/view/element~Element} to a html widget:
+// * Adds a {@link module:engine/view/element~Element#_setCustomProperty custom property} allowing to
+//   recognize the html 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 toRawHtmlWidget( viewElement, writer, label ) {
+	writer.setCustomProperty( 'rawHTML', true, viewElement );
+
+	return toWidget( viewElement, writer, { label } );
+}

+ 19 - 0
packages/ckeditor5-html-embed/tests/manual/htmlembed.html

@@ -1,2 +1,21 @@
 <div id="editor">
+    <div class="raw-html-embed">
+        <h2>Ingredients</h2>
+        <p>Ingredients required for making a coffee:</p>
+        <ul style="list-style-type:circle;">
+            <li>15g ground coffee</li>
+            <li>water</li>
+            <li>milk <i>(optional)</i></li>
+        </ul>
+        <h2>Instructions</h2>
+        <p>How to prepare a cup of coffee:</p>
+        <ol style="list-style-type:decimal-leading-zero;">
+            <li>Gather the ingredients.</li>
+            <li>Put 15g of ground coffee in the cup.</li>
+            <li>Boil 200ml of water.</li>
+            <li>Pour the water into the cup.</li>
+            <li>Optional: Add milk.</li>
+        </ol>
+        <script>alert(1)</script>
+    </div>
 </div>