Skip to content

Commit

Permalink
move enter, delete, backspace handler
Browse files Browse the repository at this point in the history
alllow easier overriding as instance methods
  • Loading branch information
jhchen committed Apr 29, 2019
1 parent 5b28603 commit 88f2369
Showing 1 changed file with 107 additions and 92 deletions.
199 changes: 107 additions & 92 deletions modules/keyboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class Keyboard extends Module {
this.addBinding(this.options.bindings[name]);
}
});
this.addBinding({ key: 'Enter', shiftKey: null }, handleEnter);
this.addBinding({ key: 'Enter', shiftKey: null }, this.handleEnter);
this.addBinding(
{ key: 'Enter', metaKey: null, ctrlKey: null, altKey: null },
() => {},
Expand All @@ -41,27 +41,35 @@ class Keyboard extends Module {
this.addBinding(
{ key: 'Backspace' },
{ collapsed: true },
handleBackspace,
this.handleBackspace,
);
this.addBinding(
{ key: 'Delete' },
{ collapsed: true },
this.handleDelete,
);
this.addBinding({ key: 'Delete' }, { collapsed: true }, handleDelete);
} else {
this.addBinding(
{ key: 'Backspace' },
{ collapsed: true, prefix: /^.?$/ },
handleBackspace,
this.handleBackspace,
);
this.addBinding(
{ key: 'Delete' },
{ collapsed: true, suffix: /^.?$/ },
handleDelete,
this.handleDelete,
);
}
this.addBinding(
{ key: 'Backspace' },
{ collapsed: false },
handleDeleteRange,
this.handleDeleteRange,
);
this.addBinding(
{ key: 'Delete' },
{ collapsed: false },
this.handleDeleteRange,
);
this.addBinding({ key: 'Delete' }, { collapsed: false }, handleDeleteRange);
this.addBinding(
{
key: 'Backspace',
Expand All @@ -71,7 +79,7 @@ class Keyboard extends Module {
shiftKey: null,
},
{ collapsed: true, offset: 0 },
handleBackspace,
this.handleBackspace,
);
this.listen();
}
Expand Down Expand Up @@ -173,6 +181,97 @@ class Keyboard extends Module {
}
});
}

handleBackspace(range, context) {
// Check for astral symbols
const length = /[\uD800-\uDBFF][\uDC00-\uDFFF]$/.test(context.prefix)
? 2
: 1;
if (range.index === 0 || this.quill.getLength() <= 1) return;
let formats = {};
const [line] = this.quill.getLine(range.index);
let delta = new Delta().retain(range.index - length).delete(length);
if (context.offset === 0) {
// Always deleting newline here, length always 1
const [prev] = this.quill.getLine(range.index - 1);
if (prev) {
const curFormats = line.formats();
const prevFormats = this.quill.getFormat(range.index - 1, 1);
formats = AttributeMap.diff(curFormats, prevFormats) || {};
if (Object.keys(formats).length > 0) {
// line.length() - 1 targets \n in line, another -1 for newline being deleted
const formatDelta = new Delta()
.retain(range.index + line.length() - 2)
.retain(1, formats);
delta = delta.compose(formatDelta);
}
}
}
this.quill.updateContents(delta, Quill.sources.USER);
this.quill.focus();
}

handleDelete(range, context) {
// Check for astral symbols
const length = /^[\uD800-\uDBFF][\uDC00-\uDFFF]/.test(context.suffix)
? 2
: 1;
if (range.index >= this.quill.getLength() - length) return;
let formats = {};
const [line] = this.quill.getLine(range.index);
let delta = new Delta().retain(range.index).delete(length);
if (context.offset >= line.length() - 1) {
const [next] = this.quill.getLine(range.index + 1);
if (next) {
const curFormats = line.formats();
const nextFormats = this.quill.getFormat(range.index, 1);
formats = AttributeMap.diff(curFormats, nextFormats) || {};
if (Object.keys(formats).length > 0) {
delta = delta.retain(next.length() - 1).retain(1, formats);
}
}
}
this.quill.updateContents(delta, Quill.sources.USER);
this.quill.focus();
}

handleDeleteRange(range) {
const lines = this.quill.getLines(range);
let formats = {};
if (lines.length > 1) {
const firstFormats = lines[0].formats();
const lastFormats = lines[lines.length - 1].formats();
formats = AttributeMap.diff(lastFormats, firstFormats) || {};
}
this.quill.deleteText(range, Quill.sources.USER);
if (Object.keys(formats).length > 0) {
this.quill.formatLine(range.index, 1, formats, Quill.sources.USER);
}
this.quill.setSelection(range.index, Quill.sources.SILENT);
this.quill.focus();
}

handleEnter(range, context) {
const lineFormats = Object.keys(context.format).reduce(
(formats, format) => {
if (
this.quill.scroll.query(format, Scope.BLOCK) &&
!Array.isArray(context.format[format])
) {
formats[format] = context.format[format];
}
return formats;
},
{},
);
const delta = new Delta()
.retain(range.index)
.delete(range.length)
.insert('\n', lineFormats);
this.quill.updateContents(delta, Quill.sources.USER);
this.quill.setSelection(range.index + 1, Quill.sources.SILENT);
this.quill.focus();
}
}

Keyboard.DEFAULTS = {
Expand Down Expand Up @@ -447,90 +546,6 @@ Keyboard.DEFAULTS = {
},
};

function handleBackspace(range, context) {
// Check for astral symbols
const length = /[\uD800-\uDBFF][\uDC00-\uDFFF]$/.test(context.prefix) ? 2 : 1;
if (range.index === 0 || this.quill.getLength() <= 1) return;
let formats = {};
const [line] = this.quill.getLine(range.index);
let delta = new Delta().retain(range.index - length).delete(length);
if (context.offset === 0) {
// Always deleting newline here, length always 1
const [prev] = this.quill.getLine(range.index - 1);
if (prev) {
const curFormats = line.formats();
const prevFormats = this.quill.getFormat(range.index - 1, 1);
formats = AttributeMap.diff(curFormats, prevFormats) || {};
if (Object.keys(formats).length > 0) {
// line.length() - 1 targets \n in line, another -1 for newline being deleted
const formatDelta = new Delta()
.retain(range.index + line.length() - 2)
.retain(1, formats);
delta = delta.compose(formatDelta);
}
}
}
this.quill.updateContents(delta, Quill.sources.USER);
this.quill.focus();
}

function handleDelete(range, context) {
// Check for astral symbols
const length = /^[\uD800-\uDBFF][\uDC00-\uDFFF]/.test(context.suffix) ? 2 : 1;
if (range.index >= this.quill.getLength() - length) return;
let formats = {};
const [line] = this.quill.getLine(range.index);
let delta = new Delta().retain(range.index).delete(length);
if (context.offset >= line.length() - 1) {
const [next] = this.quill.getLine(range.index + 1);
if (next) {
const curFormats = line.formats();
const nextFormats = this.quill.getFormat(range.index, 1);
formats = AttributeMap.diff(curFormats, nextFormats) || {};
if (Object.keys(formats).length > 0) {
delta = delta.retain(next.length() - 1).retain(1, formats);
}
}
}
this.quill.updateContents(delta, Quill.sources.USER);
this.quill.focus();
}

function handleDeleteRange(range) {
const lines = this.quill.getLines(range);
let formats = {};
if (lines.length > 1) {
const firstFormats = lines[0].formats();
const lastFormats = lines[lines.length - 1].formats();
formats = AttributeMap.diff(lastFormats, firstFormats) || {};
}
this.quill.deleteText(range, Quill.sources.USER);
if (Object.keys(formats).length > 0) {
this.quill.formatLine(range.index, 1, formats, Quill.sources.USER);
}
this.quill.setSelection(range.index, Quill.sources.SILENT);
this.quill.focus();
}

function handleEnter(range, context) {
const lineFormats = Object.keys(context.format).reduce((formats, format) => {
if (
this.quill.scroll.query(format, Scope.BLOCK) &&
!Array.isArray(context.format[format])
) {
formats[format] = context.format[format];
}
return formats;
}, {});
const delta = new Delta()
.retain(range.index)
.delete(range.length)
.insert('\n', lineFormats);
this.quill.updateContents(delta, Quill.sources.USER);
this.quill.setSelection(range.index + 1, Quill.sources.SILENT);
this.quill.focus();
}

function makeCodeBlockHandler(indent) {
return {
key: 'Tab',
Expand Down

0 comments on commit 88f2369

Please sign in to comment.