Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

issue-705: Leaf BlockSettings and InlineTools via keyboard #723

Merged
merged 51 commits into from
May 24, 2019
Merged
Changes from 11 commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
84689b5
Do not start multi-block selection on UI elements (#662)
gohabereg Apr 4, 2019
d2cb37f
Add link to issue
gohabereg Apr 5, 2019
7d1ce59
Merge branch 'release/2.12' of https://github.com/codex-team/codex.ed…
Apr 5, 2019
a750894
Fix loss of pointer (#666)
gohabereg Apr 5, 2019
4073724
Update shortcuts module (#685)
khaydarov Apr 6, 2019
a146c2e
Remove margin top for inline-link icon (#690)
talyguryn Apr 6, 2019
f0d9548
Pull fresh tools
talyguryn Apr 6, 2019
d5bc6fa
Remove changelog contents from readme (#700)
kabachook Apr 8, 2019
57b5a09
Merge branch 'master' of https://github.com/codex-team/codex.editor i…
gohabereg Apr 10, 2019
f554945
#665 API to open and close inline-toolbar (#711)
tanmayv Apr 11, 2019
53df2d5
leaf buttons: initial
khaydarov Apr 12, 2019
ee9321a
leaf inline toolbar buttons
khaydarov Apr 12, 2019
5f71c6f
Allow holderId work with ref on dom element (#710)
dimensi Apr 15, 2019
00622cd
leaf inline tools and drop index after click
khaydarov Apr 26, 2019
b2d0acc
leaf toolbox and clear active button after activation
khaydarov Apr 26, 2019
72c0987
debugging blockSettings
khaydarov Apr 26, 2019
5f0d242
Activating Open Collective (#736)
monkeywithacupcake Apr 27, 2019
800657e
Do not install editor.js as dev-dependency (#731)
davidsneighbour Apr 27, 2019
2de4318
Move codex-notifier to dependencies for typescript declarations (#728)
gohabereg Apr 27, 2019
27cbaa5
Close inline toolbar after creating new link by pressing ENTER (#722)
tanmayv Apr 27, 2019
ca58f74
Link Logo Image to homepage (#738)
goldensunliu Apr 27, 2019
3befe95
Update README.md (#744)
neSpecc Apr 27, 2019
f518a67
Config minHeight option that allows to customize bottom zone (#745)
neSpecc Apr 28, 2019
1cd6149
issue-739: allow Block's editable element selection (#747)
khaydarov Apr 28, 2019
0ab6a29
Fix typo in example paragraph (#749)
stephan281094 Apr 29, 2019
4816fb4
minor release
neSpecc Apr 29, 2019
f25c497
Merge branch 'release/2.13' into issue-705-block-actions-from-keyboard
khaydarov May 19, 2019
b730ed8
done
khaydarov May 19, 2019
e99b21c
requested changes
khaydarov May 20, 2019
1ca9b64
production build
khaydarov May 20, 2019
c5f1ba3
Merge branch 'release/2.14' into issue-705-block-actions-from-keyboard
khaydarov May 20, 2019
ffcf176
update package.json
khaydarov May 20, 2019
9ebc7a4
some improvements
khaydarov May 20, 2019
9d2a009
ready for testing
khaydarov May 20, 2019
e37b3bf
Merge branch 'release/2.14' into issue-705-block-actions-from-keyboard
khaydarov May 22, 2019
0f68cfd
update
khaydarov May 22, 2019
2bac1a6
ready
khaydarov May 22, 2019
3d3e7f6
requested changes
khaydarov May 23, 2019
14a3b30
updates
khaydarov May 23, 2019
7ac2e42
use setToBlock instead of focus
khaydarov May 23, 2019
1b176a5
active -> focused
khaydarov May 23, 2019
5a734b3
update
khaydarov May 23, 2019
eb32095
refactor types
khaydarov May 23, 2019
460bf4b
fix inline tools flipping
khaydarov May 23, 2019
202f5eb
inhancements
khaydarov May 24, 2019
369ce68
rm check for focus at the handleShowingEvent
neSpecc May 24, 2019
f4dd0c9
fix IT closing after second enter
neSpecc May 24, 2019
092281e
add animation to settings buttons
khaydarov May 24, 2019
a7d5123
Click animation
neSpecc May 24, 2019
e64e948
Add changelog
neSpecc May 24, 2019
031d687
do not patch version
neSpecc May 24, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 4 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
@@ -18,43 +18,6 @@ Join [public Telegram-chat](//t.me/codex_editor) or [Gitter-channel](https://git
| --------- | --------- | --------- | --------- | --------- | --------- |
| Edge 12+ | Firefox 18+ | Chrome 49+ | Safari 10+ | Safari 10+ | Opera 36+

### 2.7-2.9 changelog

- `Fix` - Clear focus when click is outside the Editor instance
- `Fix` — Fix CMD+A Selection on multiple Editor instances
- `New` — Toolbox now have beautiful helpers with Tool names and shortcuts
- `Improvements` — Prevent navigating back on Firefox when Block is removing by backspace
- `New` — Blocks selected with Rectangle Selection can be also removed, copied or cut
- `New` — Migrate from `postcss-cssnext` to `postcss-preset-env` and disable `postcss-custom-properties` which conflicts with `postcss-preset-env`
- `New` *RectangeSelection* — Ability to select Block or several Blocks with mouse

### 2.2—2.7 changelog

- `New` *Sanitize API* — [Sanitize Config](https://github.com/codex-team/editor.js/blob/master/docs/tools.md#automatic-sanitize) of `Block Tools` now automatically extends by tags of `Inline Tools` that is enabled by current Tool by `inlineToolbar` option. You don't need more to specify `a, b, mark, code` manually. This feature will be added to fields that supports inline markup.
- `New` *Block Selection* — Ability to select Block by `CMD+A`, and the whole Editor by double `CMD+A`. After that, you can copy (`CMD+C`), remove (`Backspace`) or clear (`Enter`) selected Blocks.
- `New` *[Styles API](https://github.com/codex-team/editor.js/blob/master/types/api/styles.d.ts)* — Added `button` class for stylization of any buttons provided by Tools with one unified style.
- `New` *[Notifier API](https://github.com/codex-team/editor.js/blob/master/docs/api.md#notifierapi)* — methods for showing user notifications: on success, errors, warnings, etc.
- `New` *Block Tool* — [Table](http://github.com/editor-js/table) constructor 💪
- `New` If one of the Tools is unavailable on Editor initialization, its Blocks will be rendered with *Dummy Block*, describing that user can not edit content of this Block. Dummy Blocks can be moved, removed and saved as normal Blocks. So saved data won't be lost if one of the Tools is failed
- `New` [Public TS-types](https://github.com/codex-team/editor.js/tree/master/types) are presented.
- `Changes` *Tools API* — options `irreplaceable` and `contentless` was removed.
- `Changes` *Tools API* — [Paste API](https://github.com/codex-team/editor.js/blob/master/docs/tools.md#paste-handling): tags, patterns and mime-types now should be specified by Tool's `pasteConfig` static property. Custom Paste Event should be handled by `onPaste(event)` that should not be static from now.
- `Changes` *Tools API* — options `displayInToolbox ` and `toolboxIcon` was removed. Use [`toolbox`](https://github.com/codex-team/editor.js/blob/master/docs/tools.md#internal-tool-settings) instead, that should return object with `icon` and `title` field, or `false` if Tool should not be placed at the Toolbox. Also, there are a way to override `toolbox {icon, title}` settings provided by Tool with you own settings at the Initial Config.
- `Improvements` — All Projects code now on TypeScript
- `Improvements` — NPM package size decreased from 1300kb to 422kb
- `Improvements` — Bundle size decreased from 438kb to 252kb
- `Improvements` — `Inline Toolbar`: when you add a Link to the selected fragment, Editor will highlight this fragment even when Caret is placed into the URL-input.
- `Improvements` — Block Settings won't be shown near empty Blocks of `initialType` by default. You should click on them instead.
- `Improvements` — `onChange`-callback now will be fired even with children attributes changing.
- `Improvements` — HTMLJanitor package was updated due to found vulnerability
- `Improvements` — Logging improved: now all Editor's logs will be preceded by beautiful label with current Editor version.
- `Improvements` — Internal `isEmpty` checking was improved for Blocks with many children nodes (200 and more)
- `Improvements` — Paste improvements: tags that can be substituted by Tool now will matched even on deep-level of pasted DOM three.
- `Improvements` — There is no more «unavailable» sound on copying Block by `CMD+C` on macOS
- `Improvements` — Dozens of bugfixes and small improvements

See a whole [Changelog](/docs/CHANGELOG.md)

## Documentation

While we develop the new Documentation Site with all stuff, you can check some available docs at the [docs/](docs/) dir.
@@ -258,6 +221,10 @@ editor.saver.save()

Take a look at the [example.html](example/example.html) to view more detailed examples.

## Changelog

See a whole [Changelog](/docs/CHANGELOG.md)

## Credits and references

- We use [HTMLJanitor](https://github.com/guardian/html-janitor) module in our Sanitizer module.
24,386 changes: 24,370 additions & 16 deletions dist/editor.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions dist/editor.js.map

Large diffs are not rendered by default.

64 changes: 64 additions & 0 deletions src/components/dom.ts
Original file line number Diff line number Diff line change
@@ -518,4 +518,68 @@ export default class Dom {
return [...result, ...Dom.getDeepestBlockElements(element as HTMLElement)];
}, []);
}

/**
* Leafs nodes inside the target list from active element
*
* @param {HTMLElement[]} nodeList - target list of nodes
* @param {number} activeIndex — index of active node. By default it must be -1
* @param {string} direction - leaf direction. Can be 'left' or 'right'
*/
public static leafNodes(nodeList, activeIndex, direction) {
/**
* If activeButtonIndex === -1 then we have no chosen Tool in Toolbox
*/
if (activeIndex === -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}
*/
activeIndex = direction === 'right' ? -1 : 0;
} else {
/**
* If we have chosen Tool then remove highlighting
*/
(nodeList[activeIndex] as HTMLElement).classList.remove('cdx-settings-button--active');
}

/**
* Count index for next Tool
*/
if (direction === 'right') {
/**
* If we go right then choose next (+1) Tool
* @type {number}
*/
activeIndex = (activeIndex + 1) % nodeList.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}
*/
activeIndex = (nodeList.length + activeIndex - 1) % nodeList.length;
}

/**
* Highlight new chosen Tool
*/
(nodeList[activeIndex] as HTMLElement).classList.add('cdx-settings-button--active');

/**
* Return Active index
*/
return activeIndex;
}
}
102 changes: 86 additions & 16 deletions src/components/modules/blockEvents.ts
Original file line number Diff line number Diff line change
@@ -3,8 +3,16 @@
*/
import Module from '../__module';
import _ from '../utils';
import SelectionUtils from '../selection';

export default class BlockEvents extends Module {

/**
* SelectionUtils instance
* @type {SelectionUtils}
*/
private selection: SelectionUtils = new SelectionUtils();

/**
* All keydowns on Block
* @param {KeyboardEvent} event - keydown
@@ -62,7 +70,9 @@ export default class BlockEvents extends Module {
return;
}

this.Editor.Toolbar.close();
if (event.keyCode !== _.keyCodes.TAB) {
neSpecc marked this conversation as resolved.
Show resolved Hide resolved
this.Editor.Toolbar.close();
}

const cmdKey = event.ctrlKey || event.metaKey;
const altKey = event.altKey;
@@ -118,32 +128,69 @@ export default class BlockEvents extends Module {
const shiftKey = event.shiftKey,
direction = shiftKey ? 'left' : 'right';

/**
* Don't show Plus and Toolbox near not-inital Tools
*/
if (!this.Editor.Tools.isInitial(currentBlock.tool)) {
return;
}

if (currentBlock.isEmpty) {
neSpecc marked this conversation as resolved.
Show resolved Hide resolved
/**
* Work with Toolbox
* ------------------
*
* If Toolbox is not open, then just open it and show plus button
* Next Tab press will leaf Toolbox Tools
*/
if (!this.Editor.Toolbar.opened) {
this.Editor.Toolbar.open(false , false);
this.Editor.Toolbar.plusButton.show();
} else {
this.Editor.Toolbox.leaf(direction);
}

this.Editor.Toolbox.open();
}

if (this.Editor.Toolbox.opened) {
this.Editor.Toolbox.leaf(direction);
} else if (!currentBlock.isEmpty && SelectionUtils.isTextSelected) {
/**
* Work with Inline Tools
* -----------------------
*
* If InlineToolbar is not open, just open it and focus first button
* Next Tab press will leaf InlineToolbar Tools
*/
if (this.Editor.InlineToolbar.opened) {
this.Editor.InlineToolbar.leaf(direction);
}
} else {
this.Editor.Toolbar.open(true, false);
this.Editor.Toolbar.plusButton.hide();
this.selection.save();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

к сейфу нужен коммент — когда будет restore

/**
* Work with Block Tunes
* ----------------------
*
* If BlockSettings is not open, then open BlockSettings
* Next Tab press will leaf Settings Buttons
*/
if (!this.Editor.BlockSettings.opened) {
this.Editor.BlockSettings.open();
} else {
this.Editor.BlockSettings.leaf(direction);
}
}
}

/**
* Escape pressed
* @param event
* If some of Toolbar components are opened, then close it otherwise close Toolbar
*
* @param {Event} event
*/
public escapePressed(event): void { }
public escapePressed(event): void {
if (this.Editor.Toolbox.opened) {
this.Editor.Toolbox.close();
} else if (this.Editor.BlockSettings.opened) {
this.Editor.BlockSettings.close();
} else if (this.Editor.InlineToolbar.opened) {
this.Editor.InlineToolbar.close();
} else {
this.Editor.Toolbar.close();
}
}

/**
* Add drop target styles
@@ -243,6 +290,28 @@ export default class BlockEvents extends Module {
return;
}

if (this.Editor.BlockSettings.opened && this.Editor.BlockSettings.getActiveButton) {
event.preventDefault();
event.stopPropagation();
event.stopImmediatePropagation();

/** Click on settings button */
this.Editor.BlockSettings.getActiveButton.click();

/** Restore selection */
// this.selection.restore();
return;
}

if (this.Editor.InlineToolbar.opened && this.Editor.InlineToolbar.getActiveButton) {
event.preventDefault();
event.stopPropagation();
event.stopImmediatePropagation();

(this.Editor.InlineToolbar.getActiveButton as HTMLElement).click();
return;
}

/**
* Allow to create linebreaks by Shift+Enter
*/
@@ -441,8 +510,9 @@ export default class BlockEvents extends Module {
*/
private needToolbarClosing(event) {
const toolboxItemSelected = (event.keyCode === _.keyCodes.ENTER && this.Editor.Toolbox.opened),
flippingToolboxItems = event.keyCode === _.keyCodes.TAB;
blockSettingsItemSelected = (event.keyCode === _.keyCodes.ENTER && this.Editor.BlockSettings.opened),
flippingToolBarItems = event.keyCode === _.keyCodes.TAB;

return !(event.shiftKey || flippingToolboxItems || toolboxItemSelected);
return !(event.shiftKey || flippingToolBarItems || toolboxItemSelected || blockSettingsItemSelected);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. сложное условие, надо оставить понятный коммент или упростить с помощью доп. переменных
  2. ToolBar -> Toolbar

}
}
67 changes: 67 additions & 0 deletions src/components/modules/toolbar/blockSettings.ts
Original file line number Diff line number Diff line change
@@ -58,6 +58,16 @@ export default class BlockSettings extends Module {
defaultSettings: null,
};

/**
* List of buttons
*/
private buttons: HTMLElement[] = [];

/**
* Index of active button
*/
private activeButtonIndex: number = -1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

focusedButtonIndex


/**
* Panel with block settings with 2 sections:
* - Tool's Settings
@@ -106,8 +116,65 @@ export default class BlockSettings extends Module {

/** Tell to subscribers that block settings is closed */
this.Editor.Events.emit(this.events.closed);

/** Clear cached buttons */
this.buttons = [];

/** Clear focus on active button */
this.activeButtonIndex = -1;

}

/**
* @todo optimize
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

как? может сразу сделать?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

надо оптимизировать код и удалить todo

* @return {HTMLElement[]}
*/
public blockTunesButtons(): HTMLElement[] {
/**
* Return from cache
*/
if (this.buttons.length !== 0) {
return this.buttons;
}

const toolSettings = this.nodes.toolSettings.querySelectorAll(`.${this.Editor.StylesAPI.classes.settingsButton}`);
const defaultSettings = this.nodes.defaultSettings.querySelectorAll(`.${BlockSettings.CSS.button}`);

const allSettings = [];
toolSettings.forEach((item, index) => {
allSettings.push(item);
if (item.classList.contains('cdx-settings-button--active')) {
this.activeButtonIndex = index;
}
});

defaultSettings.forEach((item) => {
allSettings.push(item);
});

this.buttons = allSettings;
return this.buttons;
}

/**
* Leaf Block Tunes
* @param {string} direction
*/
public leaf(direction: string = 'right'): void {
const buttonsList = this.blockTunesButtons();
this.activeButtonIndex = $.leafNodes(buttonsList, this.activeButtonIndex, direction);
}

/**
* @return {HTMLElement}
neSpecc marked this conversation as resolved.
Show resolved Hide resolved
*/
public get getActiveButton(): HTMLElement {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getFocusedButton

if (this.activeButtonIndex === -1) {
return null;
}

return this.buttons[this.activeButtonIndex];
}
/**
* Add Tool's settings
*/
Loading