瀏覽代碼

Updated to new changes in the engine.

Szymon Kupś 7 年之前
父節點
當前提交
4b5acb8665

+ 9 - 4
packages/ckeditor5-widget/src/highlightstack.js

@@ -34,8 +34,9 @@ export default class HighlightStack {
 	 *
 	 * @fires change:top
 	 * @param {module:engine/conversion/downcast-converters~HighlightDescriptor} descriptor
+	 * @param {module:engine/view/writer~Writer} writer
 	 */
-	add( descriptor ) {
+	add( descriptor, writer ) {
 		const stack = this._stack;
 
 		// Save top descriptor and insert new one. If top is changed - fire event.
@@ -47,7 +48,8 @@ export default class HighlightStack {
 		if ( oldTop !== newTop && !compareDescriptors( oldTop, newTop ) ) {
 			this.fire( 'change:top', {
 				oldDescriptor: oldTop,
-				newDescriptor: newTop
+				newDescriptor: newTop,
+				writer
 			} );
 		}
 	}
@@ -57,8 +59,9 @@ export default class HighlightStack {
 	 *
 	 * @fires change:top
 	 * @param {String} id Id of the descriptor to remove.
+	 * @param {module:engine/view/writer~Writer} writer
 	 */
-	remove( id ) {
+	remove( id, writer ) {
 		const stack = this._stack;
 
 		const oldTop = stack[ 0 ];
@@ -69,7 +72,8 @@ export default class HighlightStack {
 		if ( oldTop !== newTop && !compareDescriptors( oldTop, newTop ) ) {
 			this.fire( 'change:top', {
 				oldDescriptor: oldTop,
-				newDescriptor: newTop
+				newDescriptor: newTop,
+				writer
 			} );
 		}
 	}
@@ -168,4 +172,5 @@ function classesToString( classes ) {
  * descriptor. It will be `undefined` when last descriptor is removed from the stack.
  * @param {module:engine/conversion/downcast-converters~HighlightDescriptor} [data.oldDescriptor] Old highlight
  * descriptor. It will be `undefined` when first descriptor is added to the stack.
+ * @param {module:engine/view/writer~Writer} writer View writer that can be used to modify element.
  */

+ 24 - 20
packages/ckeditor5-widget/src/utils.js

@@ -45,25 +45,27 @@ export function isWidget( element ) {
  * * implements `addHighlight` and `removeHighlight` custom properties to handle view highlight on widgets.
  *
  * @param {module:engine/view/element~Element} element
+ * @param {module:engine/view/writer~Writer} writer
  * @param {Object} [options={}]
  * @param {String|Function} [options.label] Element's label provided to {@link ~setLabel} function. It can be passed as
  * a plain string or a function returning a string.
  * @returns {module:engine/view/element~Element} Returns same element.
  */
-export function toWidget( element, options = {} ) {
-	element.setAttribute( 'contenteditable', 'false' );
+export function toWidget( element, writer, options = {} ) {
+	writer.setAttribute( 'contenteditable', 'false', element );
+	writer.addClass( WIDGET_CLASS_NAME, element );
+	writer.setCustomProperty( widgetSymbol, true, element );
 	element.getFillerOffset = getFillerOffset;
-	element.addClass( WIDGET_CLASS_NAME );
-	element.setCustomProperty( widgetSymbol, true );
 
 	if ( options.label ) {
-		setLabel( element, options.label );
+		setLabel( element, options.label, writer );
 	}
 
 	setHighlightHandling(
 		element,
-		( element, descriptor ) => element.addClass( ...normalizeToArray( descriptor.class ) ),
-		( element, descriptor ) => element.removeClass( ...normalizeToArray( descriptor.class ) )
+		writer,
+		( element, descriptor, writer ) => writer.addClass( normalizeToArray( descriptor.class ), element ),
+		( element, descriptor, writer ) => writer.removeClass( normalizeToArray( descriptor.class ), element )
 	);
 
 	return element;
@@ -79,24 +81,25 @@ export function toWidget( element, options = {} ) {
  * properly determine which highlight descriptor should be used at given time.
  *
  * @param {module:engine/view/element~Element} element
+ * @param {module:engine/view/writer~Writer} writer
  * @param {Function} add
  * @param {Function} remove
  */
-export function setHighlightHandling( element, add, remove ) {
+export function setHighlightHandling( element, writer, add, remove ) {
 	const stack = new HighlightStack();
 
 	stack.on( 'change:top', ( evt, data ) => {
 		if ( data.oldDescriptor ) {
-			remove( element, data.oldDescriptor );
+			remove( element, data.oldDescriptor, data.writer );
 		}
 
 		if ( data.newDescriptor ) {
-			add( element, data.newDescriptor );
+			add( element, data.newDescriptor, data.writer );
 		}
 	} );
 
-	element.setCustomProperty( 'addHighlight', ( element, descriptor ) => stack.add( descriptor ) );
-	element.setCustomProperty( 'removeHighlight', ( element, id ) => stack.remove( id ) );
+	writer.setCustomProperty( 'addHighlight', ( element, descriptor, writer ) => stack.add( descriptor, writer ), element );
+	writer.setCustomProperty( 'removeHighlight', ( element, id, writer ) => stack.remove( id, writer ), element );
 }
 
 /**
@@ -106,9 +109,10 @@ export function setHighlightHandling( element, add, remove ) {
  *
  * @param {module:engine/view/element~Element} element
  * @param {String|Function} labelOrCreator
+ *  * @param {module:engine/view/writer~Writer} writer
  */
-export function setLabel( element, labelOrCreator ) {
-	element.setCustomProperty( labelSymbol, labelOrCreator );
+export function setLabel( element, labelOrCreator, writer ) {
+	writer.setCustomProperty( labelSymbol, labelOrCreator, element );
 }
 
 /**
@@ -137,22 +141,22 @@ export function getLabel( element ) {
  * @param {module:engine/view/editableelement~EditableElement} editable
  * @returns {module:engine/view/editableelement~EditableElement} Returns same element that was provided in `editable` param.
  */
-export function toWidgetEditable( editable ) {
-	editable.addClass( 'ck-editable' );
+export function toWidgetEditable( editable, writer ) {
+	writer.addClass( 'ck-editable', editable );
 
 	// Set initial contenteditable value.
-	editable.setAttribute( 'contenteditable', editable.isReadOnly ? 'false' : 'true' );
+	writer.setAttribute( 'contenteditable', editable.isReadOnly ? 'false' : 'true', editable );
 
 	// Bind contenteditable property to element#isReadOnly.
 	editable.on( 'change:isReadOnly', ( evt, property, is ) => {
-		editable.setAttribute( 'contenteditable', is ? 'false' : 'true' );
+		writer.setAttribute( 'contenteditable', is ? 'false' : 'true', editable );
 	} );
 
 	editable.on( 'change:isFocused', ( evt, property, is ) => {
 		if ( is ) {
-			editable.addClass( 'ck-editable_focused' );
+			writer.addClass( 'ck-editable_focused', editable );
 		} else {
-			editable.removeClass( 'ck-editable_focused' );
+			writer.removeClass( 'ck-editable_focused', editable );
 		}
 	} );
 

+ 6 - 4
packages/ckeditor5-widget/src/widget.js

@@ -57,7 +57,7 @@ export default class Widget extends Plugin {
 		// Converts selection placed over widget element to fake selection
 		this.editor.editing.downcastDispatcher.on( 'selection', ( evt, data, consumable, conversionApi ) => {
 			// Remove selected class from previously selected widgets.
-			this._clearPreviouslySelectedWidgets();
+			this._clearPreviouslySelectedWidgets( conversionApi.writer );
 
 			const viewWriter = conversionApi.writer;
 			const viewSelection = viewWriter.document.selection;
@@ -68,7 +68,7 @@ export default class Widget extends Plugin {
 					const node = value.item;
 
 					if ( node.is( 'element' ) && isWidget( node ) ) {
-						node.addClass( WIDGET_SELECTED_CLASS_NAME );
+						viewWriter.addClass( WIDGET_SELECTED_CLASS_NAME, node );
 						this._previouslySelected.add( node );
 
 						// Check if widget is a single element selected.
@@ -345,11 +345,13 @@ export default class Widget extends Plugin {
 
 	/**
 	 * Removes CSS class from previously selected widgets.
+	 *
 	 * @private
+	 * @param {module:engine/view/writer~Writer} writer
 	 */
-	_clearPreviouslySelectedWidgets() {
+	_clearPreviouslySelectedWidgets( writer ) {
 		for ( const widget of this._previouslySelected ) {
-			widget.removeClass( WIDGET_SELECTED_CLASS_NAME );
+			writer.removeClass( WIDGET_SELECTED_CLASS_NAME, widget );
 		}
 
 		this._previouslySelected.clear();

+ 26 - 22
packages/ckeditor5-widget/tests/utils.js

@@ -3,6 +3,7 @@
  * For licensing, see LICENSE.md.
  */
 
+import Writer from '@ckeditor/ckeditor5-engine/src/view/writer';
 import ViewElement from '@ckeditor/ckeditor5-engine/src/view/element';
 import ViewEditableElement from '@ckeditor/ckeditor5-engine/src/view/editableelement';
 import ViewDocument from '@ckeditor/ckeditor5-engine/src/view/document';
@@ -17,11 +18,14 @@ import {
 } from '../src/utils';
 
 describe( 'widget utils', () => {
-	let element;
+	let element, writer, viewDocument;
 
 	beforeEach( () => {
-		element = new ViewElement( 'div' );
-		toWidget( element );
+		viewDocument = new ViewDocument();
+		writer = new Writer( viewDocument );
+
+		element = writer.createContainerElement( 'div' );
+		toWidget( element, writer );
 	} );
 
 	describe( 'toWidget()', () => {
@@ -39,19 +43,19 @@ describe( 'widget utils', () => {
 		} );
 
 		it( 'should add element\'s label if one is provided', () => {
-			toWidget( element, { label: 'foo bar baz label' } );
+			toWidget( element, writer, { label: 'foo bar baz label' } );
 
 			expect( getLabel( element ) ).to.equal( 'foo bar baz label' );
 		} );
 
 		it( 'should add element\'s label if one is provided as function', () => {
-			toWidget( element, { label: () => 'foo bar baz label' } );
+			toWidget( element, writer, { label: () => 'foo bar baz label' } );
 
 			expect( getLabel( element ) ).to.equal( 'foo bar baz label' );
 		} );
 
 		it( 'should set default highlight handling methods', () => {
-			toWidget( element );
+			toWidget( element, writer );
 
 			const set = element.getCustomProperty( 'addHighlight' );
 			const remove = element.getCustomProperty( 'removeHighlight' );
@@ -59,15 +63,15 @@ describe( 'widget utils', () => {
 			expect( typeof set ).to.equal( 'function' );
 			expect( typeof remove ).to.equal( 'function' );
 
-			set( element, { priority: 1, class: 'highlight', id: 'highlight' } );
+			set( element, { priority: 1, class: 'highlight', id: 'highlight' }, writer );
 			expect( element.hasClass( 'highlight' ) ).to.be.true;
 
-			remove( element, 'highlight' );
+			remove( element, 'highlight', writer );
 			expect( element.hasClass( 'highlight' ) ).to.be.false;
 		} );
 
 		it( 'should set default highlight handling methods - CSS classes array', () => {
-			toWidget( element );
+			toWidget( element, writer );
 
 			const set = element.getCustomProperty( 'addHighlight' );
 			const remove = element.getCustomProperty( 'removeHighlight' );
@@ -75,11 +79,11 @@ describe( 'widget utils', () => {
 			expect( typeof set ).to.equal( 'function' );
 			expect( typeof remove ).to.equal( 'function' );
 
-			set( element, { priority: 1, class: [ 'highlight', 'foo' ], id: 'highlight' } );
+			set( element, { priority: 1, class: [ 'highlight', 'foo' ], id: 'highlight' }, writer );
 			expect( element.hasClass( 'highlight' ) ).to.be.true;
 			expect( element.hasClass( 'foo' ) ).to.be.true;
 
-			remove( element, 'highlight' );
+			remove( element, 'highlight', writer );
 			expect( element.hasClass( 'highlight' ) ).to.be.false;
 			expect( element.hasClass( 'foo' ) ).to.be.false;
 		} );
@@ -98,7 +102,7 @@ describe( 'widget utils', () => {
 	describe( 'label utils', () => {
 		it( 'should allow to set label for element', () => {
 			const element = new ViewElement( 'p' );
-			setLabel( element, 'foo bar baz' );
+			setLabel( element, 'foo bar baz', writer );
 
 			expect( getLabel( element ) ).to.equal( 'foo bar baz' );
 		} );
@@ -112,7 +116,7 @@ describe( 'widget utils', () => {
 		it( 'should allow to use a function as label creator', () => {
 			const element = new ViewElement( 'p' );
 			let caption = 'foo';
-			setLabel( element, () => caption );
+			setLabel( element, () => caption, writer );
 
 			expect( getLabel( element ) ).to.equal( 'foo' );
 			caption = 'bar';
@@ -126,8 +130,8 @@ describe( 'widget utils', () => {
 		beforeEach( () => {
 			viewDocument = new ViewDocument();
 			element = new ViewEditableElement( 'div' );
-			element.document = viewDocument;
-			toWidgetEditable( element );
+			element._document = viewDocument;
+			toWidgetEditable( element, writer );
 		} );
 
 		it( 'should be created in context of proper document', () => {
@@ -140,9 +144,9 @@ describe( 'widget utils', () => {
 
 		it( 'should add proper contenteditable value when element is read-only - initialization', () => {
 			const element = new ViewEditableElement( 'div' );
-			element.document = viewDocument;
+			element._document = viewDocument;
 			element.isReadOnly = true;
-			toWidgetEditable( element );
+			toWidgetEditable( element, writer );
 
 			expect( element.getAttribute( 'contenteditable' ) ).to.equal( 'false' );
 		} );
@@ -172,7 +176,7 @@ describe( 'widget utils', () => {
 			addSpy = sinon.spy();
 			removeSpy = sinon.spy();
 
-			setHighlightHandling( element, addSpy, removeSpy );
+			setHighlightHandling( element, writer, addSpy, removeSpy );
 			set = element.getCustomProperty( 'addHighlight' );
 			remove = element.getCustomProperty( 'removeHighlight' );
 		} );
@@ -185,14 +189,14 @@ describe( 'widget utils', () => {
 		it( 'should call highlight methods when descriptor is added and removed', () => {
 			const descriptor = { priority: 10, class: 'highlight', id: 'highlight' };
 
-			set( element, descriptor );
-			remove( element, descriptor.id );
+			set( element, descriptor, writer );
+			remove( element, descriptor.id, writer );
 
 			sinon.assert.calledOnce( addSpy );
-			sinon.assert.calledWithExactly( addSpy, element, descriptor );
+			sinon.assert.calledWithExactly( addSpy, element, descriptor, writer );
 
 			sinon.assert.calledOnce( removeSpy );
-			sinon.assert.calledWithExactly( removeSpy, element, descriptor );
+			sinon.assert.calledWithExactly( removeSpy, element, descriptor, writer );
 		} );
 
 		it( 'should call highlight methods when next descriptor is added', () => {

+ 9 - 9
packages/ckeditor5-widget/tests/widget.js

@@ -9,10 +9,8 @@ import Typing from '@ckeditor/ckeditor5-typing/src/typing';
 import MouseObserver from '@ckeditor/ckeditor5-engine/src/view/observer/mouseobserver';
 import { downcastElementToElement } from '@ckeditor/ckeditor5-engine/src/conversion/downcast-converters';
 import { toWidget } from '../src/utils';
-import ViewContainer from '@ckeditor/ckeditor5-engine/src/view/containerelement';
-import ViewEditable from '@ckeditor/ckeditor5-engine/src/view/editableelement';
 import DomEventData from '@ckeditor/ckeditor5-engine/src/view/observer/domeventdata';
-import AttributeContainer from '@ckeditor/ckeditor5-engine/src/view/attributeelement';
+import ViewPosition from '@ckeditor/ckeditor5-engine/src/view/position';
 import { setData as setModelData, getData as getModelData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
 import { getData as getViewData } from '@ckeditor/ckeditor5-engine/src/dev-utils/view';
 import { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard';
@@ -79,20 +77,22 @@ describe( 'Widget', () => {
 					.add( downcastElementToElement( { model: 'div', view: 'div' } ) )
 					.add( downcastElementToElement( {
 						model: 'widget',
-						view: () => {
-							const b = new AttributeContainer( 'b' );
-							const div = new ViewContainer( 'div', null, b );
+						view: ( item, consumable, api ) => {
+							const writer = api.writer;
+							const b = writer.createAttributeElement( 'b' );
+							const div = writer.createContainerElement( 'div' );
+							writer.insert( ViewPosition.createAt( div ), b );
 
-							return toWidget( div, { label: 'element label' } );
+							return toWidget( div, writer, { label: 'element label' } );
 						}
 					} ) )
 					.add( downcastElementToElement( {
 						model: 'nested',
-						view: () => new ViewEditable( 'figcaption', { contenteditable: true } )
+						view: ( item, consumable, api ) => api.writer.createEditableElement( 'figcaption', { contenteditable: true } )
 					} ) )
 					.add( downcastElementToElement( {
 						model: 'editable',
-						view: () => new ViewEditable( 'figcaption', { contenteditable: true } )
+						view: ( item, consumable, api ) => api.writer.createEditableElement( 'figcaption', { contenteditable: true } )
 					} ) );
 			} );
 	} );