-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(composer): Fix several composer issues and refactor Contenteditable
Summary: - Fixes T5819 issues - Adds ContenteditbalePlugin mechanism to allow extension of Contenteditable functionality, and completely removes lifecycleCallbacks from Contenteditable - Refactors list functionality outside of Contenteditable and into a plugin - Updates ComposerView to apply DraftStoreExtensions through a ContentEditablePlugin - Moves spell checking logic outside of Contenteditable into the spellcheck package Fixes T5824 (atom.assert) Fixes T5951 (shift-tabbing) bullets Test Plan: - Unit tests and manual Reviewers: evan, bengotow Reviewed By: bengotow Maniphest Tasks: T5951, T5824, T5819 Differential Revision: https://phab.nylas.com/D2261
- Loading branch information
Showing
12 changed files
with
702 additions
and
351 deletions.
There are no files selected for viewing
38 changes: 33 additions & 5 deletions
38
internal_packages/composer-spellcheck/lib/draft-extension.coffee
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
internal_packages/composer/lib/composer-extensions-plugin.coffee
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
{DraftStore, DOMUtils, ContenteditablePlugin} = require 'nylas-exports' | ||
|
||
class ComposerExtensionsPlugin extends ContenteditablePlugin | ||
@onInput: (event, editableNode, selection, innerStateProxy) -> | ||
for extension in DraftStore.extensions() | ||
extension.onInput?(editableNode, event) | ||
|
||
@onKeyDown: (event, editableNode, selection, innerStateProxy) -> | ||
if event.key is "Tab" | ||
range = DOMUtils.getRangeInScope(editableNode) | ||
for extension in DraftStore.extensions() | ||
extension.onTabDown?(editableNode, range, event) | ||
|
||
@onShowContextMenu: (args...) -> | ||
for extension in DraftStore.extensions() | ||
extension.onShowContextMenu?(args...) | ||
|
||
@onClick: (event, editableNode, selection, innerStateProxy) -> | ||
range = DOMUtils.getRangeInScope(editableNode) | ||
return unless range | ||
try | ||
for extension in DraftStore.extensions() | ||
extension.onMouseUp?(editableNode, range, event) | ||
catch e | ||
console.error('DraftStore extension raised an error: '+e.toString()) | ||
|
||
module.exports = ComposerExtensionsPlugin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
105 changes: 105 additions & 0 deletions
105
spec/components/contenteditable/automatic-list-manager-spec.coffee
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
|
||
xdescribe "ListManager", -> | ||
beforeEach -> | ||
@ce = new ContenteditableTestHarness | ||
|
||
it "Creates ordered lists", -> | ||
@ce.type ['1', '.', ' '] | ||
@ce.expectHTML "<ol><li></li></ol>" | ||
@ce.expectSelection (dom) -> | ||
dom.querySelectorAll("li")[0] | ||
|
||
it "Undoes ordered list creation with backspace", -> | ||
@ce.type ['1', '.', ' ', 'backspace'] | ||
@ce.expectHTML "1. " | ||
@ce.expectSelection (dom) -> | ||
node: dom.childNodes[0] | ||
offset: 3 | ||
|
||
it "Creates unordered lists with star", -> | ||
@ce.type ['*', ' '] | ||
@ce.expectHTML "<ul><li></li></ul>" | ||
@ce.expectSelection (dom) -> | ||
dom.querySelectorAll("li")[0] | ||
|
||
it "Undoes unordered list creation with backspace", -> | ||
@ce.type ['*', ' ', 'backspace'] | ||
@ce.expectHTML "* " | ||
@ce.expectSelection (dom) -> | ||
node: dom.childNodes[0] | ||
offset: 2 | ||
|
||
it "Creates unordered lists with dash", -> | ||
@ce.type ['-', ' '] | ||
@ce.expectHTML "<ul><li></li></ul>" | ||
@ce.expectSelection (dom) -> | ||
dom.querySelectorAll("li")[0] | ||
|
||
it "Undoes unordered list creation with backspace", -> | ||
@ce.type ['-', ' ', 'backspace'] | ||
@ce.expectHTML "- " | ||
@ce.expectSelection (dom) -> | ||
node: dom.childNodes[0] | ||
offset: 2 | ||
|
||
it "create a single item then delete it with backspace", -> | ||
@ce.type ['-', ' ', 'a', 'left', 'backspace'] | ||
@ce.expectHTML "a" | ||
@ce.expectSelection (dom) -> | ||
node: dom.childNodes[0] | ||
offset: 0 | ||
|
||
it "create a single item then delete it with tab", -> | ||
@ce.type ['-', ' ', 'a', 'shift-tab'] | ||
@ce.expectHTML "a" | ||
@ce.expectSelection (dom) -> dom.childNodes[0] | ||
node: dom.childNodes[0] | ||
offset: 1 | ||
|
||
describe "when creating two items in a list", -> | ||
beforeEach -> | ||
@twoItemKeys = ['-', ' ', 'a', 'enter', 'b'] | ||
|
||
it "creates two items with enter at end", -> | ||
@ce.type @twoItemKeys | ||
@ce.expectHTML "<ul><li>a</li><li>b</li></ul>" | ||
@ce.expectSelection (dom) -> | ||
node: dom.querySelectorAll('li')[1].childNodes[0] | ||
offset: 1 | ||
|
||
it "backspace from the start of the 1st item outdents", -> | ||
@ce.type @twoItemKeys.concat ['left', 'up', 'backspace'] | ||
|
||
it "backspace from the start of the 2nd item outdents", -> | ||
@ce.type @twoItemKeys.concat ['left', 'backspace'] | ||
|
||
it "shift-tab from the start of the 1st item outdents", -> | ||
@ce.type @twoItemKeys.concat ['left', 'up', 'shift-tab'] | ||
|
||
it "shift-tab from the start of the 2nd item outdents", -> | ||
@ce.type @twoItemKeys.concat ['left', 'shift-tab'] | ||
|
||
it "shift-tab from the end of the 1st item outdents", -> | ||
@ce.type @twoItemKeys.concat ['up', 'shift-tab'] | ||
|
||
it "shift-tab from the end of the 2nd item outdents", -> | ||
@ce.type @twoItemKeys.concat ['shift-tab'] | ||
|
||
it "backspace from the end of the 1st item doesn't outdent", -> | ||
@ce.type @twoItemKeys.concat ['up', 'backspace'] | ||
|
||
it "backspace from the end of the 2nd item doesn't outdent", -> | ||
@ce.type @twoItemKeys.concat ['backspace'] | ||
|
||
describe "multi-depth bullets", -> | ||
it "creates multi level bullet when tabbed in", -> | ||
@ce.type ['-', ' ', 'a', 'tab'] | ||
|
||
it "creates multi level bullet when tabbed in", -> | ||
@ce.type ['-', ' ', 'tab', 'a'] | ||
|
||
it "returns to single level bullet on backspace", -> | ||
@ce.type ['-', ' ', 'a', 'tab', 'left', 'backspace'] | ||
|
||
it "returns to single level bullet on shift-tab", -> | ||
@ce.type ['-', ' ', 'a', 'tab', 'shift-tab'] |
26 changes: 26 additions & 0 deletions
26
src/components/contenteditable/contenteditable-plugin.coffee
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
### | ||
ContenteditablePlugin is an abstract base class. Implementations of this | ||
are used to make additional changes to a <Contenteditable /> component | ||
beyond a user's input intents. | ||
While some ContenteditablePlugins are included with the core | ||
<Contenteditable /> component, others may be added via the `plugins` | ||
prop. | ||
### | ||
class ContenteditablePlugin | ||
|
||
# The onInput event can be triggered by a variety of events, some of | ||
# which could have been already been looked at by a callback. | ||
# Pretty much any DOM mutation will fire this. | ||
# Sometimes those mutations are the cause of callbacks. | ||
@onInput: (event, editableNode, selection, innerStateProxy) -> | ||
|
||
@onBlur: (event, editableNode, selection, innerStateProxy) -> | ||
|
||
@onFocus: (event, editableNode, selection, innerStateProxy) -> | ||
|
||
@onClick: (event, editableNode, selection, innerStateProxy) -> | ||
|
||
@onKeyDown: (event, editableNode, selection, innerStateProxy) -> | ||
|
||
@onShowContextMenu: (event, editableNode, selection, innerStateProxy, menu) -> |
Oops, something went wrong.