8
0
Просмотр исходного кода

An initial implementation of ListStyleCommand.

Kamil Piechaczek 5 лет назад
Родитель
Сommit
f3df0054e7

+ 91 - 0
packages/ckeditor5-list/src/liststylescommand.js

@@ -0,0 +1,91 @@
+/**
+ * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+/**
+ * @module list/liststylescommand
+ */
+
+import Command from '@ckeditor/ckeditor5-core/src/command';
+import { getSiblingNodes } from './utils';
+
+/**
+ * The list style command. It is used by the {@link module:list/liststyles~ListStyles list styles feature}.
+ *
+ * @extends module:core/command~Command
+ */
+export default class ListStylesCommand extends Command {
+	/**
+	 * @inheritDoc
+	 */
+	refresh() {
+		this.value = this._getValue();
+		this.isEnabled = this._checkEnabled();
+	}
+
+	/**
+	 * Executes the command.
+	 *
+	 * @param {Object} options
+	 * @param {String|null} options.type The type of the list styles, e.g. 'disc' or 'square'. If `null` specified, the default
+	 * style will be applied.
+	 * @protected
+	 */
+	execute( options = {} ) {
+		const model = this.editor.model;
+		const document = model.document;
+		const position = findPositionInsideList( document.selection );
+
+		if ( !position ) {
+			return;
+		}
+
+		const listItems = [
+			...getSiblingNodes( position, 'backward' ),
+			...getSiblingNodes( position, 'forward' )
+		];
+
+		model.change( writer => {
+			for ( const item of listItems ) {
+				writer.setAttribute( 'listStyle', options.type || 'default', item );
+			}
+		} );
+	}
+
+	/**
+	 * Checks the command's {@link #value}.
+	 *
+	 * @private
+	 * @returns {Boolean} The current value.
+	 */
+	_getValue() {
+
+	}
+
+	/**
+	 * Checks whether the command can be enabled in the current context.
+	 *
+	 * @private
+	 * @returns {Boolean} Whether the command should be enabled.
+	 */
+	_checkEnabled() {
+		return true;
+	}
+}
+
+function findPositionInsideList( selection ) {
+	const startPosition = selection.getFirstPosition();
+
+	if ( startPosition.parent.is( 'element', 'listItem' ) ) {
+		return startPosition;
+	}
+
+	const lastPosition = selection.getLastPosition();
+
+	if ( lastPosition.parent.is( 'element', 'listItem' ) ) {
+		return lastPosition;
+	}
+
+	return null;
+}

+ 49 - 0
packages/ckeditor5-list/src/utils.js

@@ -9,6 +9,7 @@
 
 import { getFillerOffset } from '@ckeditor/ckeditor5-engine/src/view/containerelement';
 import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';
+import TreeWalker from '@ckeditor/ckeditor5-engine/src/model/treewalker';
 
 /**
  * Creates a list item {@link module:engine/view/containerelement~ContainerElement}.
@@ -279,6 +280,54 @@ export function findNestedList( viewElement ) {
 	return null;
 }
 
+export function getSiblingNodes( fromOrBoundaries, direction ) {
+	const items = [];
+	const walkerOptions = {
+		ignoreElementEnd: true,
+		shallow: true,
+		direction
+	};
+	let parentElement;
+
+	if ( fromOrBoundaries.is( 'range' ) ) {
+		walkerOptions.boundaries = fromOrBoundaries;
+		parentElement = fromOrBoundaries.start.parent;
+	} else {
+		walkerOptions.startPosition = fromOrBoundaries;
+		parentElement = fromOrBoundaries.parent;
+	}
+
+	const nodes = [ ...new TreeWalker( walkerOptions ) ]
+		.filter( value => value.item.is( 'element' ) )
+		.map( value => value.item );
+
+	for ( const element of nodes ) {
+		if ( !element.is( 'element', 'listItem' ) ) {
+			break;
+		}
+
+		if ( element.getAttribute( 'listIndent' ) !== parentElement.getAttribute( 'listIndent' ) ) {
+			break;
+		}
+
+		if ( element.getAttribute( 'listType' ) !== parentElement.getAttribute( 'listType' ) ) {
+			break;
+		}
+
+		if ( element.getAttribute( 'listStyle' ) !== parentElement.getAttribute( 'listStyle' ) ) {
+			break;
+		}
+
+		if ( direction === 'backward' ) {
+			items.unshift( element );
+		} else {
+			items.push( element );
+		}
+	}
+
+	return items;
+}
+
 // Implementation of getFillerOffset for view list item element.
 //
 // @returns {Number|null} Block filler offset or `null` if block filler is not needed.