Skip to content

Commit

Permalink
Save selection on api change methods
Browse files Browse the repository at this point in the history
Includes insertText, insertEmbed, deleteText, formatText, formatLine,
removeformat, updateContents

Closes #731
  • Loading branch information
jhchen committed Jul 12, 2016
1 parent 9ea959d commit 7f1fa0d
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 39 deletions.
15 changes: 8 additions & 7 deletions core/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,12 @@ class Editor {
return index + length;
}, 0);
this.updating = false;
this.update(delta, source);
return this.update(delta, source);
}

deleteText(index, length, source = Emitter.sources.API) {
this.scroll.deleteAt(index, length);
this.update(new Delta().retain(index).delete(length), source);
return this.update(new Delta().retain(index).delete(length), source);
}

enable(enabled = true) {
Expand All @@ -90,14 +90,14 @@ class Editor {
});
});
this.scroll.optimize();
this.update(new Delta().retain(index).retain(length, clone(formats)), source);
return this.update(new Delta().retain(index).retain(length, clone(formats)), source);
}

formatText(index, length, formats = {}, source = Emitter.sources.API) {
Object.keys(formats).forEach((format) => {
this.scroll.formatAt(index, length, format, formats[format]);
});
this.update(new Delta().retain(index).retain(length, clone(formats)), source);
return this.update(new Delta().retain(index).retain(length, clone(formats)), source);
}

getContents(index, length) {
Expand Down Expand Up @@ -146,7 +146,7 @@ class Editor {

insertEmbed(index, embed, value, source = Emitter.sources.API) {
this.scroll.insertAt(index, embed, value);
this.update(new Delta().retain(index).insert({ [embed]: value }), source);
return this.update(new Delta().retain(index).insert({ [embed]: value }), source);
}

insertText(index, text, formats = {}, source = Emitter.sources.API) {
Expand All @@ -155,7 +155,7 @@ class Editor {
Object.keys(formats).forEach((format) => {
this.scroll.formatAt(index, text.length, format, formats[format]);
});
this.update(new Delta().retain(index).insert(text, clone(formats)), source)
return this.update(new Delta().retain(index).insert(text, clone(formats)), source)
}

isBlank() {
Expand All @@ -176,7 +176,7 @@ class Editor {
let contents = this.getContents(index, length + suffixLength);
let diff = contents.diff(new Delta().insert(text).concat(suffix));
let delta = new Delta().retain(index).concat(diff);
this.applyDelta(delta, source);
return this.applyDelta(delta, source);
}

update(change, source = Emitter.sources.USER) {
Expand All @@ -193,6 +193,7 @@ class Editor {
this.emitter.emit(...args);
}
}
return change;
}
}

Expand Down
87 changes: 68 additions & 19 deletions core/quill.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ let debug = logger('quill');


class Quill {
static debug(limit) {
logger.level(limit);
static debug(limit) {3
}

static import(name) {
Expand Down Expand Up @@ -107,7 +106,11 @@ class Quill {

deleteText(index, length, source) {
[index, length, , source] = overload(index, length, source);
this.editor.deleteText(index, length, source);
let range = this.getSelection();
let change = this.editor.deleteText(index, length, source);
range = shiftRange(range, index, -1*length, source);
this.setSelection(range, Emitter.sources.SILENT);
return change;
}

disable() {
Expand All @@ -125,27 +128,36 @@ class Quill {

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

formatLine(index, length, name, value, source) {
let formats;
[index, length, formats, source] = overload(index, length, name, value, source);
this.editor.formatLine(index, length, formats, source);
let range = this.getSelection();
let change = this.editor.formatLine(index, length, formats, source);
this.setSelection(range, Emitter.sources.SILENT);
return change;
}

formatText(index, length, name, value, source) {
let formats;
[index, length, formats, source] = overload(index, length, name, value, source);
this.editor.formatText(index, length, formats, source);
let range = this.getSelection();
let change = this.editor.formatText(index, length, formats, source);
this.setSelection(range, Emitter.sources.SILENT);
return change;
}

getBounds(index, length = 0) {
Expand Down Expand Up @@ -193,13 +205,20 @@ class Quill {
}

insertEmbed(index, embed, value, source) {
this.editor.insertEmbed(index, embed, value, source);
let range = this.getSelection();
let change = this.editor.insertEmbed(index, embed, value, source);
range = shiftRange(range, change, source);
this.setSelection(range, Emitter.sources.SILENT);
return change;
}

insertText(index, text, name, value, source) {
let formats;
let formats, range = this.getSelection();
[index, , formats, source] = overload(index, 0, name, value, source);
this.editor.insertText(index, text, formats, source);
let change = this.editor.insertText(index, text, formats, source);
range = shiftRange(range, index, text.length, source);
this.setSelection(range, Emitter.sources.SILENT);
return change;
}

off() {
Expand All @@ -216,16 +235,20 @@ class Quill {

pasteHTML(index, html, source = Emitter.sources.API) {
if (typeof index === 'string') {
this.setContents(this.clipboard.convert(index), html);
return this.setContents(this.clipboard.convert(index), html);
} else {
let paste = this.clipboard.convert(html);
this.updateContents(new Delta().retain(index).concat(paste), source);
return this.updateContents(new Delta().retain(index).concat(paste), source);
}
}

removeFormat(index, length, source) {
let range = this.getSelection();
[index, length, , source] = overload(index, length, source);
this.editor.removeFormat(index, length, source);
let change = this.editor.removeFormat(index, length, source);
range = shiftRange(range, index, change.length(), source);
this.setSelection(range, Emitter.sources.SILENT);
return change;
}

setContents(delta, source = Emitter.sources.API) {
Expand All @@ -236,7 +259,7 @@ class Quill {
delta.insert('\n');
}
delta.delete(this.getLength());
this.editor.applyDelta(delta, source);
return this.editor.applyDelta(delta, source);
}

setSelection(index, length, source) {
Expand All @@ -251,19 +274,24 @@ class Quill {

setText(text, source = Emitter.sources.API) {
let delta = new Delta().insert(text);
this.setContents(delta, source);
return this.setContents(delta, source);
}

update(source = Emitter.sources.USER) {
this.scroll.update(source); // Will update selection before selection.update() does if text changes
let change = this.scroll.update(source); // Will update selection before selection.update() does if text changes
this.selection.update(source);
return change;
}

updateContents(delta, source = Emitter.sources.API) {
let range = this.getSelection();
if (Array.isArray(delta)) {
delta = new Delta(delta.slice());
}
this.editor.applyDelta(delta, source);
let change = this.editor.applyDelta(delta, source);
range = shiftRange(range, change, source);
this.setSelection(range, Emitter.sources.SILENT);
return change;
}
}
Quill.DEFAULTS = {
Expand Down Expand Up @@ -314,5 +342,26 @@ function overload(index, length, name, value, source) {
return [index, length, formats, source];
}

function shiftRange(range, index, length, source) {
if (range == null) return null;
let start, end;
if (index instanceof Delta) {
[start, end] = [range.index, range.index + range.length].map(function(pos) {
return index.transformPosition(pos, source === Emitter.sources.USER);
});
} else {
if (source === Emitter.sources.USER) index -= 1;
[start, end] = [range.index, range.index + range.length].map(function(pos) {
if (index > pos) return pos;
if (length >= 0) {
return pos + length;
} else {
return Math.max(index, pos + length);
}
});
}
return new Range(start, end - start);
}


export { overload, Quill as default };
4 changes: 0 additions & 4 deletions modules/keyboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,11 @@ class Keyboard extends Module {
this.addBinding({ key: Keyboard.keys.BACKSPACE }, { collapsed: true, prefix: /^$/ }, function(range) {
if (range.index === 0) return;
this.quill.deleteText(range.index - 1, 1, Quill.sources.USER);
this.quill.setSelection(range.index - 1, Quill.sources.SILENT);
this.quill.selection.scrollIntoView();
});
this.addBinding({ key: Keyboard.keys.DELETE }, { collapsed: true, suffix: /^$/ }, function(range) {
if (range.index >= this.quill.getLength() - 1) return;
this.quill.deleteText(range.index, 1, Quill.sources.USER);
this.quill.setSelection(range.index, Quill.sources.SILENT);
});
this.addBinding({ key: Keyboard.keys.BACKSPACE }, { collapsed: false }, handleDelete);
this.addBinding({ key: Keyboard.keys.DELETE }, { collapsed: false }, handleDelete);
Expand Down Expand Up @@ -181,7 +179,6 @@ Keyboard.DEFAULTS = {
this.quill.scroll.deleteAt(range.index, range.length);
}
this.quill.insertText(range.index, '\t', Quill.sources.USER);
this.quill.setSelection(range.index + 1, Quill.sources.SILENT);
}
],
'list empty enter': [
Expand Down Expand Up @@ -235,7 +232,6 @@ function handleEnter(range, context) {
return lineFormats;
}, {});
this.quill.insertText(range.index, '\n', lineFormats, Quill.sources.USER);
this.quill.setSelection(range.index + 1, Quill.sources.SILENT);
this.quill.selection.scrollIntoView();
Object.keys(context.format).forEach((name) => {
if (lineFormats[name] != null) return;
Expand Down
6 changes: 0 additions & 6 deletions modules/toolbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,6 @@ class Toolbar extends Module {
.delete(range.length)
.insert({ [format]: true })
, Quill.sources.USER);
range = new Range(range.index + 1, 0);
this.quill.setSelection(range, Quill.sources.SILENT);
} else {
this.quill.format(format, value, Quill.sources.USER);
}
Expand Down Expand Up @@ -197,11 +195,7 @@ Toolbar.DEFAULTS = {
}
});
} else {
let startLength = this.quill.getLength();
this.quill.removeFormat(range, Quill.sources.USER);
let endLength = this.quill.getLength();
// account for embed removals
this.quill.setSelection(range.index, range.length - (startLength-endLength), Quill.sources.SILENT);
}
},
direction: function(value) {
Expand Down
1 change: 0 additions & 1 deletion themes/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@ BaseTheme.DEFAULTS = {
.delete(range.length)
.insert({ image: e.target.result })
, Emitter.sources.USER);
quill.setSelection(range.index + 1, Emitter.sources.SILENT);
fileInput.value = "";
}
reader.readAsDataURL(this.files[0]);
Expand Down
2 changes: 0 additions & 2 deletions ui/link-tooltip.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,13 @@ class LinkTooltip {

remove() {
this.quill.formatText(this.range, 'link', false, Quill.sources.USER);
this.quill.setSelection(this.range, Quill.sources.SILENT);
this.hide();
}

save() {
let url = this.textbox.value;
let scrollTop = this.quill.root.scrollTop;
this.quill.formatText(this.range, 'link', url, Quill.sources.USER);
this.quill.setSelection(this.range, Quill.sources.SILENT);
this.quill.root.scrollTop = scrollTop;
this.hide();
}
Expand Down

0 comments on commit 7f1fa0d

Please sign in to comment.