diff --git a/modules/keyboard.js b/modules/keyboard.js
index a8e14d86d1..42193c9b8a 100644
--- a/modules/keyboard.js
+++ b/modules/keyboard.js
@@ -451,8 +451,10 @@ Keyboard.DEFAULTS = {
},
tab: {
key: 'tab',
- handler(range, context) {
- if (context.format.table) return true;
+ handler(range, { format }) {
+ const isInTable = format.tableCellLine || format.tableHeaderCellLine
+ || format.tableHeaderCell || format.table;
+ if (isInTable) return true;
this.quill.history.cutoff();
const delta = new Delta()
.retain(range.index)
diff --git a/test/unit/modules/keyboard.js b/test/unit/modules/keyboard.js
index aa56494a71..3824b3299f 100644
--- a/test/unit/modules/keyboard.js
+++ b/test/unit/modules/keyboard.js
@@ -1,4 +1,8 @@
import Keyboard, { SHORTKEY, normalize } from '../../../modules/keyboard';
+import { Range } from '../../../core/selection';
+import Quill from '../../../core/quill';
+import TableLite from '../../../modules/table/lite';
+import TableMain from '../../../modules/table';
describe('Keyboard', function () {
describe('match', function () {
@@ -257,4 +261,248 @@ describe('Keyboard', function () {
quillMock.root.addEventListener = nativeAddEventListener;
});
});
+
+ describe('tab navigation on main table', function () {
+ const markup = `
+
+
+
+ head1 |
+ head2 |
+ head3 |
+
+
+
+
+ data1 |
+ data2 |
+ data3 |
+
+
+ data1 |
+ data2 |
+ data3 |
+
+
+
+ `;
+
+ it('should select next cell on tab click', function () {
+ const quill = this.initialize(Quill, markup, this.container, {
+ modules: {
+ table: true,
+ },
+ });
+ quill.setSelection(18);
+ const keydownEvent = new KeyboardEvent('keydown', {
+ key: 'tab',
+ });
+
+ quill.root.dispatchEvent(keydownEvent);
+ expect(quill.getSelection()).toEqual(new Range(24));
+ });
+
+ it('should select the first cell in the by tab press if cursor is in the last cell of the first row', function () {
+ const quill = this.initialize(Quill, markup, this.container, {
+ modules: {
+ table: true,
+ },
+ });
+ quill.setSelection(30);
+ const keydownEvent = new KeyboardEvent('keydown', {
+ key: 'tab',
+ });
+
+ quill.root.dispatchEvent(keydownEvent);
+ expect(quill.getSelection()).toEqual(new Range(36));
+ });
+
+ it('should select previous cell on tab + shift click', function () {
+ const quill = this.initialize(Quill, markup, this.container, {
+ modules: {
+ table: true,
+ },
+ });
+ quill.setSelection(31);
+ const keydownEvent = new KeyboardEvent('keydown', {
+ key: 'tab',
+ shiftKey: true,
+ });
+
+ quill.root.dispatchEvent(keydownEvent);
+ expect(quill.getSelection()).toEqual(new Range(29));
+ });
+
+ it('should select last cell of the first row by tab+shift if cursor is in the first cell of the second row', function () {
+ const quill = this.initialize(Quill, markup, this.container, {
+ modules: {
+ table: true,
+ },
+ });
+ quill.setSelection(38);
+ const keydownEvent = new KeyboardEvent('keydown', {
+ key: 'tab',
+ shiftKey: true,
+ });
+
+ quill.root.dispatchEvent(keydownEvent);
+ expect(quill.getSelection()).toEqual(new Range(35));
+ });
+
+ it('should select next cell in header on tab click', function () {
+ const quill = this.initialize(Quill, markup, this.container, {
+ modules: {
+ table: true,
+ },
+ });
+ quill.setSelection(0);
+ const keydownEvent = new KeyboardEvent('keydown', {
+ key: 'tab',
+ });
+
+ quill.root.dispatchEvent(keydownEvent);
+ expect(quill.getSelection()).toEqual(new Range(6));
+ });
+
+ it('should select previous cell in header on tab + shift click', function () {
+ const quill = this.initialize(Quill, markup, this.container, {
+ modules: {
+ table: true,
+ },
+ });
+ quill.setSelection(8);
+ const keydownEvent = new KeyboardEvent('keydown', {
+ key: 'tab',
+ shiftKey: true,
+ });
+
+ quill.root.dispatchEvent(keydownEvent);
+ expect(quill.getSelection()).toEqual(new Range(5));
+ });
+ });
+
+ describe('tab navigation on lite table', function () {
+ beforeAll(function () {
+ Quill.register({ 'modules/table': TableLite }, true);
+ });
+ afterAll(function () {
+ Quill.register({ 'modules/table': TableMain }, true);
+ });
+ const markup = `
+
+
+
+ head1 |
+ head2 |
+ head3 |
+
+
+
+
+ data1 |
+ data2 |
+ data3 |
+
+
+ data1 |
+ data2 |
+ data3 |
+
+
+
+ `;
+
+ it('should select next cell on tab click', function () {
+ const quill = this.initialize(Quill, markup, this.container, {
+ modules: {
+ table: true,
+ },
+ });
+ quill.setSelection(18);
+ const keydownEvent = new KeyboardEvent('keydown', {
+ key: 'tab',
+ });
+
+ quill.root.dispatchEvent(keydownEvent);
+ expect(quill.getSelection()).toEqual(new Range(24));
+ });
+
+ it('should select the first cell in the by tab press if cursor is in the last cell of the first row', function () {
+ const quill = this.initialize(Quill, markup, this.container, {
+ modules: {
+ table: true,
+ },
+ });
+ quill.setSelection(30);
+ const keydownEvent = new KeyboardEvent('keydown', {
+ key: 'tab',
+ });
+
+ quill.root.dispatchEvent(keydownEvent);
+ expect(quill.getSelection()).toEqual(new Range(36));
+ });
+
+ it('should select previous cell on tab + shift click', function () {
+ const quill = this.initialize(Quill, markup, this.container, {
+ modules: {
+ table: true,
+ },
+ });
+ quill.setSelection(31);
+ const keydownEvent = new KeyboardEvent('keydown', {
+ key: 'tab',
+ shiftKey: true,
+ });
+
+ quill.root.dispatchEvent(keydownEvent);
+ expect(quill.getSelection()).toEqual(new Range(29));
+ });
+
+ it('should select last cell of the first row by tab+shift if cursor is in the first cell of the second row', function () {
+ const quill = this.initialize(Quill, markup, this.container, {
+ modules: {
+ table: true,
+ },
+ });
+ quill.setSelection(38);
+ const keydownEvent = new KeyboardEvent('keydown', {
+ key: 'tab',
+ shiftKey: true,
+ });
+
+ quill.root.dispatchEvent(keydownEvent);
+ expect(quill.getSelection()).toEqual(new Range(35));
+ });
+
+ it('should select next cell in header on tab click', function () {
+ const quill = this.initialize(Quill, markup, this.container, {
+ modules: {
+ table: true,
+ },
+ });
+ quill.setSelection(0);
+ const keydownEvent = new KeyboardEvent('keydown', {
+ key: 'tab',
+ });
+
+ quill.root.dispatchEvent(keydownEvent);
+ expect(quill.getSelection()).toEqual(new Range(6));
+ });
+
+ it('should select previous cell in header on tab + shift click', function () {
+ const quill = this.initialize(Quill, markup, this.container, {
+ modules: {
+ table: true,
+ },
+ });
+ quill.setSelection(8);
+ const keydownEvent = new KeyboardEvent('keydown', {
+ key: 'tab',
+ shiftKey: true,
+ });
+
+ quill.root.dispatchEvent(keydownEvent);
+ expect(quill.getSelection()).toEqual(new Range(5));
+ });
+ });
});