Skip to content

Commit

Permalink
unifiy quill and toolbar format implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
jhchen committed Feb 25, 2016
1 parent 3c7c0d8 commit aee9b86
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 49 deletions.
11 changes: 8 additions & 3 deletions core/quill.js
Expand Up @@ -45,7 +45,7 @@ class Quill {
let html = this.container.innerHTML;
this.container.classList.add('ql-container');
this.container.innerHTML = '';
this.controls = {};
this.controls = {}; // TODO make into API
this.modules = {};
// TODO scroll will reset innerHTML as well, do not do twice
this.root = this.addContainer('ql-editor');
Expand Down Expand Up @@ -117,16 +117,17 @@ class Quill {
this.selection.focus();
}

formatCursor(name, value, source = Emitter.sources.API) {
format(name, value, source = Emitter.sources.API) {
let range = this.getSelection();
if (range == null) return;
if (Parchment.query(name, Parchment.Scope.BLOCK)) {
this.formatLine(range, name, value, source);
} else if (range.length === 0) {
this.selection.format(name, value);
return this.selection.format(name, value);
} else {
this.formatText(range, name, value, source);
}
this.setSelection(range, Emitter.sources.SILENT);
}

formatLine(index, length, name, value, source) {
Expand Down Expand Up @@ -181,6 +182,10 @@ class Quill {
return this.editor.getText(index, length);
}

hasFocus() {
return this.selection.hasFocus();
}

insertEmbed(index, embed, value, source) {
this.editor.insertEmbed(index, embed, value, source);
}
Expand Down
14 changes: 7 additions & 7 deletions core/selection.js
Expand Up @@ -38,12 +38,8 @@ class Selection {
this.update(Emitter.sources.SILENT);
}

checkFocus() {
return document.activeElement === this.root;
}

focus() {
if (this.checkFocus()) return;
if (this.hasFocus()) return;
this.root.focus();
this.setRange(this.savedRange);
}
Expand Down Expand Up @@ -155,7 +151,7 @@ class Selection {
}

getRange() {
if (!this.checkFocus()) return [null, null];
if (!this.hasFocus()) return [null, null];
let range = this.getNativeRange();
if (range == null) return [null, null];
let positions = [[range.start.node, range.start.offset]];
Expand All @@ -178,6 +174,10 @@ class Selection {
return [new Range(start, end-start), range];
}

hasFocus() {
return document.activeElement === this.root;
}

scrollIntoView() {
if (this.lastRange == null) return;
let startBounds = this.getBounds(this.lastRange.start);
Expand All @@ -197,7 +197,7 @@ class Selection {
let selection = document.getSelection();
if (selection == null) return;
if (startNode != null) {
if (!this.checkFocus()) this.root.focus();
if (!this.hasFocus()) this.root.focus();
let nativeRange = this.getNativeRange();
if (nativeRange == null ||
startNode !== nativeRange.start.node || startOffset !== nativeRange.start.offset ||
Expand Down
21 changes: 9 additions & 12 deletions modules/keyboard.js
Expand Up @@ -52,9 +52,9 @@ class Keyboard extends Module {

onDelete(backspace, range) {
if (range.length > 0) {
this.quill.deleteText(range, Quill.sources.USER);
this.quill.deleteText(range, Emitter.sources.USER);
} else if (!backspace) {
this.quill.deleteText(range.index, 1, Quill.sources.USER);
this.quill.deleteText(range.index, 1, Emitter.sources.USER);
} else {
let [line, offset] = this.quill.scroll.descendant(Block, range.index);
let formats = this.quill.getFormat(range);
Expand All @@ -65,11 +65,11 @@ class Keyboard extends Module {
line.format('list', false);
}
} else {
this.quill.deleteText(range.index - 1, 1, Quill.sources.USER);
this.quill.deleteText(range.index - 1, 1, Emitter.sources.USER);
range = new Range(Math.max(0, range.index - 1));
}
}
this.quill.setSelection(range.index, Quill.sources.SILENT);
this.quill.setSelection(range.index, Emitter.sources.SILENT);
}

onEnter(range) {
Expand All @@ -84,8 +84,8 @@ class Keyboard extends Module {
.retain(range.index)
.insert('\n', lineFormats)
.delete(range.length);
this.quill.updateContents(delta, Quill.sources.USER);
this.quill.setSelection(range.index + 1, Quill.sources.SILENT);
this.quill.updateContents(delta, Emitter.sources.USER);
this.quill.setSelection(range.index + 1, Emitter.sources.SILENT);
Object.keys(formats).forEach((name) => {
if (lineFormats[name] == null) {
this.quill.formatCursor(name, formats[name]);
Expand All @@ -95,16 +95,13 @@ class Keyboard extends Module {

onFormat(format, range) {
let formats = this.quill.getFormat(range);
this.quill.formatCursor(format, !formats[format], Quill.sources.USER);
if (range.length !== 0) {
this.quill.setSelection(range, Quill.sources.SILENT);
}
this.quill.format(format, formats[format], Emitter.sources.USER);
}

onTab(range, evt) {
if (range.length === 0) {
let delta = new Delta().retain(range.index).insert('\t').delete(range.length);
this.quill.updateContents(delta, Quill.sources.USER);
this.quill.updateContents(delta, Emitter.sources.USER);
this.quill.setSelection(range.index + 1, Emitter.sources.SILENT);
} else {
let modifier = evt.shiftKey ? -1 : 1;
Expand All @@ -113,7 +110,7 @@ class Keyboard extends Module {
let indent = parseInt(format['indent'] || 0);
line.format('indent', Math.max(0, indent + modifier));
});
this.quill.update(Quill.sources.USER);
this.quill.update(Emitter.sources.USER);
this.quill.setSelection(range, Emitter.sources.SILENT);
}
}
Expand Down
24 changes: 7 additions & 17 deletions modules/toolbar.js
@@ -1,4 +1,5 @@
import extend from 'extend';
import Emitter from '../core/emitter';
import Parchment from 'parchment';
import Module from '../core/module';
import logger from '../core/logger';
Expand Down Expand Up @@ -41,34 +42,23 @@ class Toolbar extends Module {
// if (this.quill.options.formats.indexOf(format) < 0) return; // TODO enable
let eventName = input.tagName === 'SELECT' ? 'change' : 'click';
input.addEventListener(eventName, () => {
let range = this.quill.getSelection(true);
if (range == null) return false;
this.quill.focus();
let value;
if (input.tagName === 'SELECT') {
value = input.options[input.selectedIndex].value || false;
} else {
value = input.classList.contains('ql-active') ? false : input.getAttribute('data-value') || true;
}
let handler = this.quill.controls[format] || this.handle.bind(this);
handler(range, format, value);
this.update();
if (this.quill.controls[format]) {
this.quill.controls[format](format, value);
} else {
this.quill.format(format, value, Emitter.sources.USER);
}
});
// TODO use weakmap
this.controls.push([format, input]);
}

handle(range, format, value) {
if (Parchment.query(format, Parchment.Scope.BLOCK)) {
this.quill.formatLine(range, format, value, Quill.sources.USER);
} else if (range.length === 0) {
this.quill.formatCursor(format, value, Quill.sources.USER);
return;
} else {
this.quill.formatText(range, format, value, Quill.sources.USER);
}
this.quill.setSelection(range, Quill.sources.SILENT);
}

update() {
let range = this.quill.getSelection();
if (range == null) return;
Expand Down
20 changes: 10 additions & 10 deletions test/unit/selection.js
Expand Up @@ -21,19 +21,19 @@ describe('Selection', function() {
});

it('initial focus', function() {
expect(this.selection.checkFocus()).toBe(false);
expect(this.selection.hasFocus()).toBe(false);
this.selection.focus();
expect(this.selection.checkFocus()).toBe(true);
expect(this.selection.hasFocus()).toBe(true);
});

it('restore last range', function() {
let range = new Range(1, 2);
this.selection.setRange(range);
this.textarea.focus();
this.textarea.select();
expect(this.selection.checkFocus()).toBe(false);
expect(this.selection.hasFocus()).toBe(false);
this.selection.focus();
expect(this.selection.checkFocus()).toBe(true);
expect(this.selection.hasFocus()).toBe(true);
expect(this.selection.getRange()[0]).toEqual(range);
});
});
Expand Down Expand Up @@ -162,7 +162,7 @@ describe('Selection', function() {
selection.setRange(expected);
let [range, ] = selection.getRange();
expect(range).toEqual(expected);
expect(selection.checkFocus()).toBe(true);
expect(selection.hasFocus()).toBe(true);
});

it('empty lines', function() {
Expand All @@ -176,7 +176,7 @@ describe('Selection', function() {
selection.setRange(expected);
let [range, ] = selection.getRange();
expect(range).toEqual(range);
expect(selection.checkFocus()).toBe(true);
expect(selection.hasFocus()).toBe(true);
});

it('nested text node', function() {
Expand All @@ -190,7 +190,7 @@ describe('Selection', function() {
selection.setRange(expected);
let [range, ] = selection.getRange();
expect(range).toEqual(expected);
expect(selection.checkFocus()).toBe(true);
expect(selection.hasFocus()).toBe(true);
});

it('between inlines', function() {
Expand All @@ -199,7 +199,7 @@ describe('Selection', function() {
selection.setRange(expected);
let [range, ] = selection.getRange();
expect(range).toEqual(expected);
expect(selection.checkFocus()).toBe(true);
expect(selection.hasFocus()).toBe(true);
});

it('between embeds', function() {
Expand All @@ -219,7 +219,7 @@ describe('Selection', function() {
selection.setRange(expected);
let [range, ] = selection.getRange();
expect(range).toEqual(expected);
expect(selection.checkFocus()).toBe(true);
expect(selection.hasFocus()).toBe(true);
});

it('null', function() {
Expand All @@ -230,7 +230,7 @@ describe('Selection', function() {
selection.setRange(null);
[range, ] = selection.getRange();
expect(range).toEqual(null);
expect(selection.checkFocus()).toBe(false);
expect(selection.hasFocus()).toBe(false);
});
});

Expand Down

0 comments on commit aee9b86

Please sign in to comment.