From db6a621bf8e166e4d51417541e428c80824c6826 Mon Sep 17 00:00:00 2001 From: Shpileva Yuliya Date: Wed, 19 Jul 2023 10:33:15 +0400 Subject: [PATCH] fix table navigation on tab --- modules/keyboard.js | 6 +- test/unit/modules/keyboard.js | 248 ++++++++++++++++++++++++++++++++++ 2 files changed, 252 insertions(+), 2 deletions(-) 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)); + }); + }); });