editor.js/src/components/domIterator.ts
Peter Savchenko ac93017c70
Release 2.16 (#966)
* 2.16.0

* [Refactor] Separate internal and external settings (#845)

* Enable flipping tools via standalone class (#830)

* Enable flipping tools via standalone class

* use flipper to refactor (#842)

* use flipper to refactor

* save changes

* update

* fix flipper on inline toolbar

* ready for testing

* requested changes

* update doc

* updates

* destroy flippers

* some requested changes

* update

* update

* ready

* update

* last changes

* update docs

* Hghl active button of CT, simplify activate/deactivate

* separate dom iterator

* unhardcode directions

* fixed a link in readme.md (#856)

* Fix Block selection via CMD+A (#829)

* Fix Block selection via CMD+A

* Delete editor.js.map

* update

* update

* Update CHANGELOG.md

* Improve style of selected blocks (#858)

* Cross-block-selection style improved

* Update CHANGELOG.md

* Fix case when property 'observer' in modificationObserver is not defined (#866)

* Bump lodash.template from 4.4.0 to 4.5.0 (#885)

Bumps [lodash.template](https://github.com/lodash/lodash) from 4.4.0 to 4.5.0.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.4.0...4.5.0)

Signed-off-by: dependabot[bot] <support@github.com>

* Bump eslint-utils from 1.3.1 to 1.4.2 (#886)

Bumps [eslint-utils](https://github.com/mysticatea/eslint-utils) from 1.3.1 to 1.4.2.
- [Release notes](https://github.com/mysticatea/eslint-utils/releases)
- [Commits](https://github.com/mysticatea/eslint-utils/compare/v1.3.1...v1.4.2)

Signed-off-by: dependabot[bot] <support@github.com>

* Bump mixin-deep from 1.3.1 to 1.3.2 (#887)

Bumps [mixin-deep](https://github.com/jonschlinkert/mixin-deep) from 1.3.1 to 1.3.2.
- [Release notes](https://github.com/jonschlinkert/mixin-deep/releases)
- [Commits](https://github.com/jonschlinkert/mixin-deep/compare/1.3.1...1.3.2)

Signed-off-by: dependabot[bot] <support@github.com>

* update bundle and readme

* Update README.md

* upd codeowners, fix funding

* Minor Docs Fix according to main Readme (#916)

* Inline Toolbar now contains Conversion Toolbar (#932)

* Block lifecycle hooks (#906)

* [Fix] Arrow selection (#964)

* Fix arrow selection

* Add docs

* [issue-926]: fix dom iterator leafing when items are empty (#958)

* [issue-926]: fix dom iterator leafing when items are empty

* update Changelog

* Issue 869 (#963)

* Fix issue 943 (#965)

* [Draft] Feature/tooltip enhancements (#907)

* initial

* update

* make module standalone

* use tooltips as external module

* update

* build via prod mode

* add tooltips as external module

* add declaration file and options param

* add api tooltip

* update

* removed submodule

* removed due to the incorrect setip

* setup tooltips again

* wip

* update tooltip module

* toolbox, inline toolbar

* Tooltips in block tunes not uses shorthand

* shorthand in a plus and block settings

* fix doc

* Update tools-inline.md

* Delete tooltip.css

* Update CHANGELOG.md

* Update codex.tooltips

* Update api.md

* [issue-779]: Grammarly conflicts (#956)

* grammarly conflicts

* update

* upd bundle

* Submodule Header now on master

* Submodule Marker now on master

* Submodule Paragraph now on master

* Submodule InlineCode now on master

* Submodule Simple Image now on master

* [issue-868]: Deleting multiple blocks triggers back button in Firefox (#967)

* Deleting multiple blocks triggers back button in Firefox

@evgenusov

* Update editor.js

* Update CHANGELOG.md

* pass options on removeEventListener (#904)

* pass options on removeEventListener by removeAll

* rebuild

* Merge branch 'release/2.16' into pr/904

* Update CHANGELOG.md

* Update inline.ts

* [Fix] Selection rangecount (#968)

* Fix #952 (#969)

* Update codex.tooltips

* Selection bugfix (#970)

* Selection bugfix

* fix cross block selection

* close inline toolbar when blocks selected via shift

* remove inline toolbar closing on cross block selection mouse up due to the bug (#972)

* [Feature] Log levels (#971)

* Decrease margins (#973)

* Decrease margins

* Update editor.licenses.txt

* Update src/components/domIterator.ts

Co-Authored-By: Murod Khaydarov <murod.haydarov@gmail.com>

* [Fix] Fix delete blocks api method (#974)

* Update docs/usage.md

Co-Authored-By: Murod Khaydarov <murod.haydarov@gmail.com>

* rm unused

* Update yarn.lock file

* upd bundle, changelog
2019-11-30 23:42:39 +03:00

171 lines
4.2 KiB
TypeScript

import Dom from './dom';
/**
* Iterator above passed Elements list.
* Each next or previous action adds provides CSS-class and sets cursor to this item
*/
export default class DomIterator {
/**
* This is a static property that defines iteration directions
* @type {{RIGHT: string, LEFT: string}}
*/
public static directions = {
RIGHT: 'right',
LEFT: 'left',
};
/**
* User-provided CSS-class name for focused button
*/
private focusedCssClass: string;
/**
* Focused button index.
* Default is -1 which means nothing is active
* @type {number}
*/
private cursor: number = -1;
/**
* Items to flip
*/
private items: HTMLElement[] = [];
/**
* @param {HTMLElement[]} nodeList — the list of iterable HTML-items
* @param {string} focusedCssClass - user-provided CSS-class that will be set in flipping process
*/
constructor(
nodeList: HTMLElement[],
focusedCssClass: string,
) {
this.items = nodeList || [];
this.focusedCssClass = focusedCssClass;
}
/**
* Returns Focused button Node
* @return {HTMLElement}
*/
public get currentItem(): HTMLElement {
if (this.cursor === -1) {
return null;
}
return this.items[this.cursor];
}
/**
* Sets items. Can be used when iterable items changed dynamically
* @param {HTMLElement[]} nodeList
*/
public setItems(nodeList: HTMLElement[]): void {
this.items = nodeList;
}
/**
* Sets cursor next to the current
*/
public next(): void {
this.cursor = this.leafNodesAndReturnIndex(DomIterator.directions.RIGHT);
}
/**
* Sets cursor before current
*/
public previous(): void {
this.cursor = this.leafNodesAndReturnIndex(DomIterator.directions.LEFT);
}
/**
* Sets cursor to the default position and removes CSS-class from previously focused item
*/
public dropCursor(): void {
if (this.cursor === -1) {
return;
}
this.items[this.cursor].classList.remove(this.focusedCssClass);
this.cursor = -1;
}
/**
* Leafs nodes inside the target list from active element
*
* @param {string} direction - leaf direction. Can be 'left' or 'right'
* @return {Number} index of focused node
*/
private leafNodesAndReturnIndex(direction: string): number {
/**
* if items are empty then there is nothing to leaf
*/
if (this.items.length === 0) {
return this.cursor;
}
let focusedButtonIndex = this.cursor;
/**
* If activeButtonIndex === -1 then we have no chosen Tool in Toolbox
*/
if (focusedButtonIndex === -1) {
/**
* Normalize "previous" Tool index depending on direction.
* We need to do this to highlight "first" Tool correctly
*
* Order of Tools: [0] [1] ... [n - 1]
* [0 = n] because of: n % n = 0 % n
*
* Direction 'right': for [0] the [n - 1] is a previous index
* [n - 1] -> [0]
*
* Direction 'left': for [n - 1] the [0] is a previous index
* [n - 1] <- [0]
*
* @type {number}
*/
focusedButtonIndex = direction === DomIterator.directions.RIGHT ? -1 : 0;
} else {
/**
* If we have chosen Tool then remove highlighting
*/
this.items[focusedButtonIndex].classList.remove(this.focusedCssClass);
}
/**
* Count index for next Tool
*/
if (direction === DomIterator.directions.RIGHT) {
/**
* If we go right then choose next (+1) Tool
* @type {number}
*/
focusedButtonIndex = (focusedButtonIndex + 1) % this.items.length;
} else {
/**
* If we go left then choose previous (-1) Tool
* Before counting module we need to add length before because of "The JavaScript Modulo Bug"
* @type {number}
*/
focusedButtonIndex = (this.items.length + focusedButtonIndex - 1) % this.items.length;
}
if (Dom.isNativeInput(this.items[focusedButtonIndex])) {
/**
* Focus input
*/
this.items[focusedButtonIndex].focus();
}
/**
* Highlight new chosen Tool
*/
this.items[focusedButtonIndex].classList.add(this.focusedCssClass);
/**
* Return focused button's index
*/
return focusedButtonIndex;
}
}