Skip to content

Commit

Permalink
fixes #1361, fixes #1276
Browse files Browse the repository at this point in the history
  • Loading branch information
jhchen committed Mar 29, 2017
1 parent 03eeedd commit 9570a64
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 39 deletions.
1 change: 1 addition & 0 deletions blots/scroll.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class Scroll extends Parchment.Scroll {
constructor(domNode, config) {
super(domNode);
this.emitter = config.emitter;
this.scrollingContainer = config.scrollingContainer;
if (Array.isArray(config.whitelist)) {
this.whitelist = config.whitelist.reduce(function(whitelist, format) {
whitelist[format] = true;
Expand Down
17 changes: 14 additions & 3 deletions core/quill.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ class Quill {
constructor(container, options = {}) {
this.options = expandConfig(container, options);
this.container = this.options.container;
this.scrollingContainer = this.options.scrollingContainer || document.body;
if (this.container == null) {
return debug.error('Invalid Quill container', container);
}
Expand All @@ -72,9 +71,11 @@ class Quill {
this.container.__quill = this;
this.root = this.addContainer('ql-editor');
this.root.classList.add('ql-blank');
this.scrollingContainer = this.options.scrollingContainer || this.root;
this.emitter = new Emitter();
this.scroll = Parchment.create(this.root, {
emitter: this.emitter,
scrollingContainer: this.scrollingContainer,
whitelist: this.options.formats
});
this.editor = new Editor(this.scroll);
Expand Down Expand Up @@ -180,11 +181,21 @@ class Quill {
}

getBounds(index, length = 0) {
let bounds;
if (typeof index === 'number') {
return this.selection.getBounds(index, length);
bounds = this.selection.getBounds(index, length);
} else {
return this.selection.getBounds(index.index, index.length);
bounds = this.selection.getBounds(index.index, index.length);
}
let containerBounds = this.container.getBoundingClientRect();
return {
bottom: bounds.bottom - containerBounds.top,
height: bounds.height,
left: bounds.left - containerBounds.left,
right: bounds.right - containerBounds.left,
top: bounds.top - containerBounds.top,
width: bounds.width
};
}

getContents(index = 0, length = this.getLength() - index) {
Expand Down
40 changes: 20 additions & 20 deletions core/selection.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class Selection {
let scrollLength = this.scroll.length();
index = Math.min(index, scrollLength - 1);
length = Math.min(index + length, scrollLength - 1) - index;
let bounds, node, [leaf, offset] = this.scroll.leaf(index);
let node, [leaf, offset] = this.scroll.leaf(index);
if (leaf == null) return null;
[node, offset] = leaf.position(offset, true);
let range = document.createRange();
Expand All @@ -99,7 +99,7 @@ class Selection {
if (leaf == null) return null;
[node, offset] = leaf.position(offset, true);
range.setEnd(node, offset);
bounds = range.getBoundingClientRect();
return range.getBoundingClientRect();
} else {
let side = 'left';
let rect;
Expand All @@ -117,22 +117,15 @@ class Selection {
rect = leaf.domNode.getBoundingClientRect();
if (offset > 0) side = 'right';
}
bounds = {
return {
bottom: rect.top + rect.height,
height: rect.height,
left: rect[side],
width: 0,
top: rect.top
right: rect[side],
top: rect.top,
width: 0
};
}
let containerBounds = this.root.parentNode.getBoundingClientRect();
return {
left: bounds.left - containerBounds.left,
right: bounds.left + bounds.width - containerBounds.left,
top: bounds.top - containerBounds.top,
bottom: bounds.top + bounds.height - containerBounds.top,
height: bounds.height,
width: bounds.width
};
}

getNativeRange() {
Expand Down Expand Up @@ -200,12 +193,19 @@ class Selection {
if (range == null) return;
let bounds = this.getBounds(range.index, range.length);
if (bounds == null) return;
if (this.root.offsetHeight < bounds.bottom) {
let [line, ] = this.scroll.line(Math.min(range.index + range.length, this.scroll.length()-1));
this.root.scrollTop = line.domNode.offsetTop + line.domNode.offsetHeight - this.root.offsetHeight;
} else if (bounds.top < 0) {
let [line, ] = this.scroll.line(Math.min(range.index, this.scroll.length()-1));
this.root.scrollTop = line.domNode.offsetTop;
let limit = this.scroll.length()-1;
let [first, ] = this.scroll.line(Math.min(range.index, limit));
let last = first;
if (range.length > 0) {
[last, ] = this.scroll.line(Math.min(range.index + range.length, limit));
}
if (first == null || last == null) return;
let scroller = this.scroll.scrollingContainer;
let scrollBounds = scroller.getBoundingClientRect();
if (bounds.top < scrollBounds.top) {
scroller.scrollTop -= (scrollBounds.top - bounds.top);
} else if (bounds.bottom > scrollBounds.bottom) {
scroller.scrollTop += (bounds.bottom - scrollBounds.bottom);
}
}

Expand Down
6 changes: 2 additions & 4 deletions test/unit/core/quill.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,11 @@ describe('Quill', function() {
});

it('getBounds() index', function() {
let bounds = this.quill.selection.getBounds(1);
expect(this.quill.getBounds(1)).toEqual(bounds);
expect(this.quill.getBounds(1)).toBeTruthy();
});

it('getBounds() range', function() {
let bounds = this.quill.selection.getBounds(3, 4);
expect(this.quill.getBounds(new Range(3, 4))).toEqual(bounds);
expect(this.quill.getBounds(new Range(3, 4))).toBeTruthy();
});

it('getFormat()', function() {
Expand Down
10 changes: 5 additions & 5 deletions test/unit/core/selection.js
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,6 @@ describe('Selection', function() {
this.container.classList.add('ql-editor');
this.container.style.fontFamily = 'monospace';
this.container.style.lineHeight = /Trident/i.test(navigator.userAgent) ? '18px' : 'initial';
this.container.style.position = 'relative';
this.initialize(HTMLElement, '<div></div><div>&nbsp;</div>');
this.div = this.container.firstChild;
this.div.style.border = '1px solid #777';
Expand All @@ -367,12 +366,13 @@ describe('Selection', function() {
this.initialize(HTMLElement, '<p><span>0</span></p>', this.div);
let span = this.div.firstChild.firstChild;
span.style.display = 'inline-block'; // IE11 needs this to respect line height
let bounds = span.getBoundingClientRect();
this.reference = {
height: span.offsetHeight,
left: span.offsetLeft,
height: bounds.height,
left: bounds.left,
lineHeight: span.parentNode.offsetHeight,
width: span.offsetWidth,
top: span.offsetTop,
width: bounds.width,
top: bounds.top
};
this.initialize(HTMLElement, '', this.div);
});
Expand Down
4 changes: 2 additions & 2 deletions themes/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,9 @@ class BaseTooltip extends Tooltip {
}

restoreFocus() {
let scrollTop = this.quill.root.scrollTop;
let scrollTop = this.quill.scrollingContainer.scrollTop;
this.quill.focus();
this.quill.root.scrollTop = scrollTop;
this.quill.scrollingContainer.scrollTop = scrollTop;
}

save() {
Expand Down
13 changes: 8 additions & 5 deletions ui/tooltip.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ class Tooltip {
this.boundsContainer = boundsContainer || document.body;
this.root = quill.addContainer('ql-tooltip');
this.root.innerHTML = this.constructor.TEMPLATE;
this.quill.root.addEventListener('scroll', () => {
this.root.style.marginTop = (-1*this.quill.root.scrollTop) + 'px';
});
if (this.quill.root === this.quill.scrollingContainer) {
this.quill.root.addEventListener('scroll', () => {
this.root.style.marginTop = (-1*this.quill.root.scrollTop) + 'px';
});
}
this.hide();
}

Expand All @@ -16,6 +18,7 @@ class Tooltip {

position(reference) {
let left = reference.left + reference.width/2 - this.root.offsetWidth/2;
// root.scrollTop should be 0 if scrollContainer !== root
let top = reference.bottom + this.quill.root.scrollTop;
this.root.style.left = left + 'px';
this.root.style.top = top + 'px';
Expand All @@ -33,8 +36,8 @@ class Tooltip {
}
if (rootBounds.bottom > containerBounds.bottom) {
let height = rootBounds.bottom - rootBounds.top;
let verticalShift = containerBounds.bottom - rootBounds.bottom - height;
this.root.style.top = (top + verticalShift) + 'px';
let verticalShift = reference.bottom - reference.top + height;
this.root.style.top = (top - verticalShift) + 'px';
this.root.classList.add('ql-flip');
}
return shift;
Expand Down

0 comments on commit 9570a64

Please sign in to comment.