am-editor11212/docs/plugin/tutorials-list.md

4.0 KiB

List plugin

List node plugin

Usually used for ordered lists, unordered lists, and custom lists. For example, the task list is a custom list, and the checkbox inside is an implementation of card of type inline

For this type of plug-in, we need to inherit the ListPlugin abstract class. The ListPlugin abstract class extends some properties and methods on the basis of inheriting the BlockPlugin abstract class. So the plug-in that inherits ListPlugin also has all the attributes and methods of the BlockPlugin abstract class

Inheritance

Inherit the ListPlugin abstract class

import {ListPlugin} from'@aomao/engine'

export default class extends ListPlugin {
...
}

Attributes

ListPlugin has all the attributes and methods of BlockPlugin ElementPlugin Plugin inherited

cardName

Card name, optional.

When we customize the list, cardName is necessary

The card component corresponding to the card name must be of type inline, not of type block

Type: string

cardName = 'checkbox';

Method

init

Initialization, optional

The ListPlugin plugin has implemented the init method, if you need to use it, you need to manually call it again. Otherwise there will be unexpected situations

export default class extends ListPlugin {
...
    init(){
        super.init()
    }
}

isCurrent

To determine whether the node is the node required by the current list, it must be implemented

We need to use this method to determine which plug-in a list node attribute

isCurrent(node: NodeInterface) {
    //li node, must include the style of the `CUSTOMZIE_LI_CLASS` custom list, and the first child node under li should be a card, the card name corresponds to the cardName we set
    if (node.name ==='li')
        return (
            node.hasClass(this.editor.list.CUSTOMZIE_LI_CLASS) &&
            node.first()?.attributes(CARD_KEY) === this.cardName
        );
    //ul node should contain `CUSTOMZIE_UI_CLASS` custom list style. And there are also our custom styles
    return node.hasClass(this.editor.list.CUSTOMZIE_UI_CLASS) && node.hasClass('data-list-task');
}

queryState

The ListPlugin plugin has implemented the queryState method, if you need to use it, you can override this method

queryState() {
    if (!isEngine(this.editor)) return false;
    return (
        this.editor.list.getPluginNameByNodes(this.editor.change.blocks) ===
        (this.constructor as PluginEntryType).pluginName
    );
}

execute

Need to use API call method to realize the package of the list node, and remove

//Non-engine
if (!isEngine(this.editor)) return;
const { change, list, block } = this.editor;
//First cut the list, <ul><li /><anchor /><li /><focus /><li /></ul> -> <ul><li /></ul><anchor / ><ul><li /><focus /></ul><ul><li /></ul>
list.split();
//Get the current cursor
const range = change.range.get();
//Get all current block nodes after the season
const activeBlocks = block.findBlocks(range);
if (activeBlocks) {
	//Create a marker node at the cursor
	const selection = range.createSelection();
	//Determine whether it belongs to the custom list node of the current plug-in type
	if (list.isSpecifiedType(activeBlocks, 'ul', 'checkbox')) {
		//Remove package
		list.unwrap(activeBlocks);
	} else {
		//Convert all currently activated block nodes into a custom list
		const listBlocks = list.toCustomize(
			activeBlocks,
			'checkbox',
			//The value of the checkbox card is determined by the value when the checkbox is defined. For example, whether checked is checked
			{
				checked: boolean,
			},
		) as Array<NodeInterface>;
		//After the conversion is completed, add our custom styles in a loop
		listBlocks.forEach((list) => {
			if (this.editor.node.isList(list)) list.addClass('data-list-task');
		});
	}
	//Remove the mark and restore the cursor
	selection.move();
	//Reselect the new cursor position
	change.range.select(range);
	//Merge adjacent and identical list nodes, if any
	list.merge();
}