浏览代码

Merge branch 'master' into t/ckeditor5/742

Kamil Piechaczek 7 年之前
父节点
当前提交
d3a1caee5a

+ 28 - 1
packages/ckeditor5-engine/src/model/documentselection.js

@@ -376,7 +376,7 @@ export default class DocumentSelection {
 
 	/**
 	 * Removes an attribute with given key from the selection.
-	 * If the given attribute was set on the selection, fires the {@link module:engine/model/selection~Selection#event:change}
+	 * If the given attribute was set on the selection, fires the {@link module:engine/model/selection~Selection#event:change:range}
 	 * event with removed attribute key.
 	 * Should be used only within the {@link module:engine/model/writer~Writer#removeSelectionAttribute} method.
 	 *
@@ -451,6 +451,33 @@ export default class DocumentSelection {
 
 mix( DocumentSelection, EmitterMixin );
 
+/**
+ * Fired when selection range(s) changed.
+ *
+ * @event change:range
+ * @param {Boolean} directChange In case of {@link module:engine/model/selection~Selection} class it is always set
+ * to `true` which indicates that the selection change was caused by a direct use of selection's API.
+ * The {@link module:engine/model/documentselection~DocumentSelection}, however, may change because its position
+ * was directly changed through the {@link module:engine/model/writer~Writer writer} or because its position was
+ * changed because the structure of the model has been changed (which means an indirect change).
+ * The indirect change does not occur in case of normal (detached) selections because they are "static" (as "not live")
+ * which mean that they are not updated once the document changes.
+ */
+
+/**
+ * Fired when selection attribute changed.
+ *
+ * @event change:attribute
+ * @param {Boolean} directChange In case of {@link module:engine/model/selection~Selection} class it is always set
+ * to `true` which indicates that the selection change was caused by a direct use of selection's API.
+ * The {@link module:engine/model/documentselection~DocumentSelection}, however, may change because its attributes
+ * were directly changed through the {@link module:engine/model/writer~Writer writer} or because its position was
+ * changed in the model and its attributes were refreshed (which means an indirect change).
+ * The indirect change does not occur in case of normal (detached) selections because they are "static" (as "not live")
+ * which mean that they are not updated once the document changes.
+ * @param {Array.<String>} attributeKeys Array containing keys of attributes that changed.
+ */
+
 // `LiveSelection` is used internally by {@link module:engine/model/documentselection~DocumentSelection} and shouldn't be used directly.
 //
 // LiveSelection` is automatically updated upon changes in the {@link module:engine/model/document~Document document}

+ 18 - 14
packages/ckeditor5-engine/src/model/selection.js

@@ -544,7 +544,7 @@ export default class Selection {
 	/**
 	 * Removes an attribute with given key from the selection.
 	 *
-	 * If given attribute was set on the selection, fires the {@link #event:change} event with
+	 * If given attribute was set on the selection, fires the {@link #event:change:range} event with
 	 * removed attribute key.
 	 *
 	 * @fires change:attribute
@@ -561,7 +561,7 @@ export default class Selection {
 	/**
 	 * Sets attribute on the selection. If attribute with the same key already is set, it's value is overwritten.
 	 *
-	 * If the attribute value has changed, fires the {@link #event:change} event with
+	 * If the attribute value has changed, fires the {@link #event:change:range} event with
 	 * the attribute key.
 	 *
 	 * @fires change:attribute
@@ -725,25 +725,29 @@ export default class Selection {
 	}
 
 	/**
-	 * @event change
-	 */
-
-	/**
-	 * Fired whenever selection ranges are changed.
+	 * Fired when selection range(s) changed.
 	 *
 	 * @event change:range
-	 * @param {Boolean} directChange Specifies whether the range change was caused by direct usage of `Selection` API (`true`)
-	 * or by changes done to {@link module:engine/model/document~Document model document}
-	 * using {@link module:engine/model/batch~Batch Batch} API (`false`).
+	 * @param {Boolean} directChange In case of {@link module:engine/model/selection~Selection} class it is always set
+	 * to `true` which indicates that the selection change was caused by a direct use of selection's API.
+	 * The {@link module:engine/model/documentselection~DocumentSelection}, however, may change because its position
+	 * was directly changed through the {@link module:engine/model/writer~Writer writer} or because its position was
+	 * changed because the structure of the model has been changed (which means an indirect change).
+	 * The indirect change does not occur in case of normal (detached) selections because they are "static" (as "not live")
+	 * which mean that they are not updated once the document changes.
 	 */
 
 	/**
-	 * Fired whenever selection attributes are changed.
+	 * Fired when selection attribute changed.
 	 *
 	 * @event change:attribute
-	 * @param {Boolean} directChange Specifies whether the attributes changed by direct usage of the Selection API (`true`)
-	 * or by changes done to the {@link module:engine/model/document~Document model document}
-	 * using the {@link module:engine/model/batch~Batch Batch} API (`false`).
+	 * @param {Boolean} directChange In case of {@link module:engine/model/selection~Selection} class it is always set
+	 * to `true` which indicates that the selection change was caused by a direct use of selection's API.
+	 * The {@link module:engine/model/documentselection~DocumentSelection}, however, may change because its attributes
+	 * were directly changed through the {@link module:engine/model/writer~Writer writer} or because its position was
+	 * changed in the model and its attributes were refreshed (which means an indirect change).
+	 * The indirect change does not occur in case of normal (detached) selections because they are "static" (as "not live")
+	 * which mean that they are not updated once the document changes.
 	 * @param {Array.<String>} attributeKeys Array containing keys of attributes that changed.
 	 */
 }

+ 9 - 9
packages/ckeditor5-engine/src/view/placeholder.js

@@ -54,7 +54,7 @@ export function detachPlaceholder( view, element ) {
 	}
 
 	view.change( writer => {
-		writer.removeClass( 'ck-placeholder', element );
+		writer.removeClass( [ 'ck', 'ck-placeholder' ], element );
 		writer.removeAttribute( 'data-placeholder', element );
 	} );
 }
@@ -105,8 +105,8 @@ function updateSinglePlaceholder( writer, element, info ) {
 
 	// If checkFunction is provided and returns false - remove placeholder.
 	if ( checkFunction && !checkFunction() ) {
-		if ( element.hasClass( 'ck-placeholder' ) ) {
-			writer.removeClass( 'ck-placeholder', element );
+		if ( element.hasClass( 'ck', 'ck-placeholder' ) ) {
+			writer.removeClass( [ 'ck', 'ck-placeholder' ], element );
 			changed = true;
 		}
 
@@ -119,8 +119,8 @@ function updateSinglePlaceholder( writer, element, info ) {
 
 	// If element is empty and editor is blurred.
 	if ( !document.isFocused && isEmptyish ) {
-		if ( !element.hasClass( 'ck-placeholder' ) ) {
-			writer.addClass( 'ck-placeholder', element );
+		if ( !element.hasClass( 'ck', 'ck-placeholder' ) ) {
+			writer.addClass( [ 'ck', 'ck-placeholder' ], element );
 			changed = true;
 		}
 
@@ -129,13 +129,13 @@ function updateSinglePlaceholder( writer, element, info ) {
 
 	// It there are no child elements and selection is not placed inside element.
 	if ( isEmptyish && anchor && anchor.parent !== element ) {
-		if ( !element.hasClass( 'ck-placeholder' ) ) {
-			writer.addClass( 'ck-placeholder', element );
+		if ( !element.hasClass( 'ck', 'ck-placeholder' ) ) {
+			writer.addClass( [ 'ck', 'ck-placeholder' ], element );
 			changed = true;
 		}
 	} else {
-		if ( element.hasClass( 'ck-placeholder' ) ) {
-			writer.removeClass( 'ck-placeholder', element );
+		if ( element.hasClass( 'ck', 'ck-placeholder' ) ) {
+			writer.removeClass( [ 'ck', 'ck-placeholder' ], element );
 			changed = true;
 		}
 	}

+ 19 - 19
packages/ckeditor5-engine/tests/view/placeholder.js

@@ -27,7 +27,7 @@ describe( 'placeholder', () => {
 			attachPlaceholder( view, element, 'foo bar baz' );
 
 			expect( element.getAttribute( 'data-placeholder' ) ).to.equal( 'foo bar baz' );
-			expect( element.hasClass( 'ck-placeholder' ) ).to.be.true;
+			expect( element.hasClass( 'ck', 'ck-placeholder' ) ).to.be.true;
 		} );
 
 		it( 'if element has children set only data attribute', () => {
@@ -37,7 +37,7 @@ describe( 'placeholder', () => {
 			attachPlaceholder( view, element, 'foo bar baz' );
 
 			expect( element.getAttribute( 'data-placeholder' ) ).to.equal( 'foo bar baz' );
-			expect( element.hasClass( 'ck-placeholder' ) ).to.be.false;
+			expect( element.hasClass( 'ck', 'ck-placeholder' ) ).to.be.false;
 		} );
 
 		it( 'if element has only ui elements, set CSS class and data attribute', () => {
@@ -47,7 +47,7 @@ describe( 'placeholder', () => {
 			attachPlaceholder( view, element, 'foo bar baz' );
 
 			expect( element.getAttribute( 'data-placeholder' ) ).to.equal( 'foo bar baz' );
-			expect( element.hasClass( 'ck-placeholder' ) ).to.be.true;
+			expect( element.hasClass( 'ck', 'ck-placeholder' ) ).to.be.true;
 		} );
 
 		it( 'if element has selection inside set only data attribute', () => {
@@ -57,7 +57,7 @@ describe( 'placeholder', () => {
 			attachPlaceholder( view, element, 'foo bar baz' );
 
 			expect( element.getAttribute( 'data-placeholder' ) ).to.equal( 'foo bar baz' );
-			expect( element.hasClass( 'ck-placeholder' ) ).to.be.false;
+			expect( element.hasClass( 'ck', 'ck-placeholder' ) ).to.be.false;
 		} );
 
 		it( 'if element has selection inside but document is blurred should contain placeholder CSS class', () => {
@@ -68,7 +68,7 @@ describe( 'placeholder', () => {
 			attachPlaceholder( view, element, 'foo bar baz' );
 
 			expect( element.getAttribute( 'data-placeholder' ) ).to.equal( 'foo bar baz' );
-			expect( element.hasClass( 'ck-placeholder' ) ).to.be.true;
+			expect( element.hasClass( 'ck', 'ck-placeholder' ) ).to.be.true;
 		} );
 
 		it( 'use check function if one is provided', () => {
@@ -81,11 +81,11 @@ describe( 'placeholder', () => {
 
 			sinon.assert.called( spy );
 			expect( element.getAttribute( 'data-placeholder' ) ).to.equal( 'foo bar baz' );
-			expect( element.hasClass( 'ck-placeholder' ) ).to.be.true;
+			expect( element.hasClass( 'ck', 'ck-placeholder' ) ).to.be.true;
 
 			result = false;
 			view.render();
-			expect( element.hasClass( 'ck-placeholder' ) ).to.be.false;
+			expect( element.hasClass( 'ck', 'ck-placeholder' ) ).to.be.false;
 		} );
 
 		it( 'should remove CSS class if selection is moved inside', () => {
@@ -95,13 +95,13 @@ describe( 'placeholder', () => {
 			attachPlaceholder( view, element, 'foo bar baz' );
 
 			expect( element.getAttribute( 'data-placeholder' ) ).to.equal( 'foo bar baz' );
-			expect( element.hasClass( 'ck-placeholder' ) ).to.be.true;
+			expect( element.hasClass( 'ck', 'ck-placeholder' ) ).to.be.true;
 
 			view.change( writer => {
 				writer.setSelection( ViewRange.createIn( element ) );
 			} );
 
-			expect( element.hasClass( 'ck-placeholder' ) ).to.be.false;
+			expect( element.hasClass( 'ck', 'ck-placeholder' ) ).to.be.false;
 		} );
 
 		it( 'should change placeholder settings when called twice', () => {
@@ -112,7 +112,7 @@ describe( 'placeholder', () => {
 			attachPlaceholder( view, element, 'new text' );
 
 			expect( element.getAttribute( 'data-placeholder' ) ).to.equal( 'new text' );
-			expect( element.hasClass( 'ck-placeholder' ) ).to.be.true;
+			expect( element.hasClass( 'ck', 'ck-placeholder' ) ).to.be.true;
 		} );
 
 		it( 'should not throw when element is no longer in document', () => {
@@ -140,10 +140,10 @@ describe( 'placeholder', () => {
 			attachPlaceholder( secondView, secondElement, 'second placeholder' );
 
 			expect( element.getAttribute( 'data-placeholder' ) ).to.equal( 'first placeholder' );
-			expect( element.hasClass( 'ck-placeholder' ) ).to.be.true;
+			expect( element.hasClass( 'ck', 'ck-placeholder' ) ).to.be.true;
 
 			expect( secondElement.getAttribute( 'data-placeholder' ) ).to.equal( 'second placeholder' );
-			expect( secondElement.hasClass( 'ck-placeholder' ) ).to.be.true;
+			expect( secondElement.hasClass( 'ck', 'ck-placeholder' ) ).to.be.true;
 
 			// Move selection to the elements with placeholders.
 			view.change( writer => {
@@ -155,10 +155,10 @@ describe( 'placeholder', () => {
 			} );
 
 			expect( element.getAttribute( 'data-placeholder' ) ).to.equal( 'first placeholder' );
-			expect( element.hasClass( 'ck-placeholder' ) ).to.be.false;
+			expect( element.hasClass( 'ck', 'ck-placeholder' ) ).to.be.false;
 
 			expect( secondElement.getAttribute( 'data-placeholder' ) ).to.equal( 'second placeholder' );
-			expect( secondElement.hasClass( 'ck-placeholder' ) ).to.be.false;
+			expect( secondElement.hasClass( 'ck', 'ck-placeholder' ) ).to.be.false;
 		} );
 
 		it( 'should update placeholder before rendering', () => {
@@ -172,11 +172,11 @@ describe( 'placeholder', () => {
 
 				// Here we are before rendering - placeholder is visible in first element;
 				expect( element.getAttribute( 'data-placeholder' ) ).to.equal( 'foo bar baz' );
-				expect( element.hasClass( 'ck-placeholder' ) ).to.be.true;
+				expect( element.hasClass( 'ck', 'ck-placeholder' ) ).to.be.true;
 			} );
 
 			// After rendering - placeholder should be invisible since selection is moved there.
-			expect( element.hasClass( 'ck-placeholder' ) ).to.be.false;
+			expect( element.hasClass( 'ck', 'ck-placeholder' ) ).to.be.false;
 		} );
 	} );
 
@@ -188,12 +188,12 @@ describe( 'placeholder', () => {
 			attachPlaceholder( view, element, 'foo bar baz' );
 
 			expect( element.getAttribute( 'data-placeholder' ) ).to.equal( 'foo bar baz' );
-			expect( element.hasClass( 'ck-placeholder' ) ).to.be.true;
+			expect( element.hasClass( 'ck', 'ck-placeholder' ) ).to.be.true;
 
 			detachPlaceholder( view, element );
 
 			expect( element.hasAttribute( 'data-placeholder' ) ).to.be.false;
-			expect( element.hasClass( 'ck-placeholder' ) ).to.be.false;
+			expect( element.hasClass( 'ck', 'ck-placeholder' ) ).to.be.false;
 		} );
 
 		it( 'should not blow up when called on element without placeholder', () => {
@@ -203,7 +203,7 @@ describe( 'placeholder', () => {
 			detachPlaceholder( view, element );
 
 			expect( element.hasAttribute( 'data-placeholder' ) ).to.be.false;
-			expect( element.hasClass( 'ck-placeholder' ) ).to.be.false;
+			expect( element.hasClass( 'ck', 'ck-placeholder' ) ).to.be.false;
 		} );
 	} );
 } );

+ 1 - 1
packages/ckeditor5-engine/theme/placeholder.css

@@ -3,7 +3,7 @@
  * For licensing, see LICENSE.md.
  */
 
-.ck-placeholder::before {
+.ck.ck-placeholder::before {
 	content: attr( data-placeholder );
 
 	/* See ckeditor/ckeditor5#469. */