Skip to content

Commit

Permalink
fix: switching to ww cause scrolling (close #194) (#269)
Browse files Browse the repository at this point in the history
* fix: switching to ww cause scrolling (close #194)

* refactor: apply code review (ref #269)
  • Loading branch information
kyuwoo-choi committed Jul 20, 2018
1 parent 4e1d034 commit b87c338
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 26 deletions.
57 changes: 31 additions & 26 deletions src/js/wysiwygEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class WysiwygEditor {
_initEvent() {
this.eventManager.listen('wysiwygSetValueBefore', html => this._preprocessForInlineElement(html));
this.eventManager.listen('wysiwygKeyEvent', ev => this._runKeyEventHandlers(ev.data, ev.keyMap));
this.eventManager.listen('wysiwygRangeChangeAfter', () => this._scrollToRangeIfNeed());
this.eventManager.listen('wysiwygRangeChangeAfter', () => this.scrollIntoCursor());
}

/**
Expand Down Expand Up @@ -489,9 +489,7 @@ class WysiwygEditor {
});
}

this.defer(() => {
this._scrollToRangeIfNeed();
});
this.defer(() => this.scrollIntoCursor());
});

this.addKeyEventHandler('TAB', ev => {
Expand Down Expand Up @@ -523,24 +521,6 @@ class WysiwygEditor {
});
}

/**
* Scroll editor area to current cursor position if need
* @private
*/
_scrollToRangeIfNeed() {
const $editorContainerEl = this.$editorContainerEl;
const range = this.getRange();
const cursorTop = this.getEditor().getCursorPosition(range).top - $editorContainerEl.offset().top;

if (cursorTop >= $editorContainerEl.height()) {
let target = range.endContainer;
if (!(target instanceof Element)) {
target = target.parentNode;
}
target.scrollIntoView(false);
}
}

/**
* _isInOrphanText
* check if range is orphan text
Expand Down Expand Up @@ -1009,16 +989,41 @@ class WysiwygEditor {
this.eventManager.emit('wysiwygRangeChangeAfter', this);
}

/**
* move scroll to cursor
* scrollIntoView browser function may cause scrolling on document.
* this function aims to replace scrollIntoView function to prevent that.
* it will move the scroll of squire only.
* @memberof SquireExt
*/
scrollIntoCursor() {
const scrollTop = this.scrollTop();
const {
top: cursorTop,
height: cursorHeight
} = this.getEditor().getCursorPosition();
const {
top: editorTop,
height: editorHeight
} = this.$editorContainerEl.get(0).getBoundingClientRect();

const cursorAboveEditor = cursorTop - editorTop;
const cursorBelowEditor = (cursorTop + cursorHeight) - (editorTop + editorHeight);

if (cursorAboveEditor < 0) {
this.scrollTop(scrollTop + cursorAboveEditor);
} else if (cursorBelowEditor > 0) {
this.scrollTop(scrollTop + cursorBelowEditor);
}
}

/**
* Set cursor position to end
* @memberof WysiwygEditor
*/
moveCursorToEnd() {
this.getEditor().moveCursorToEnd();
const contentNodes = this.get$Body().get(0).childNodes;
if (contentNodes.length > 0) {
contentNodes[contentNodes.length - 1].scrollIntoView(false);
}
this.scrollIntoCursor();
this._correctRangeAfterMoveCursor('end');
}

Expand Down
34 changes: 34 additions & 0 deletions test/unit/wysiwygEditor.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -564,4 +564,38 @@ describe('WysiwygEditor', () => {
expect(spyOriginal).not.toHaveBeenCalled();
}, 1);
});

describe('scrollIntoCursor', () => {
it('should scroll to cursor at the end', () => {
wwe.setHeight(50);
const sqe = wwe.getEditor();
sqe.setHTML('<div>a</div><div>a</div><div>a</div><div>a</div><div>a</div><div>a</div><div>a</div><div>a</div>');
sqe.moveCursorToEnd();

wwe.scrollIntoCursor();

const {top: cursorTop, height: cursorHeight} = sqe.getCursorPosition();
const {top: editorTop, height: editorHeight} = wwe.$editorContainerEl.get(0).getBoundingClientRect();
expect(cursorTop >= 0).toBe(true);
expect(cursorTop + cursorHeight <= editorTop + editorHeight).toBe(true);
});

it('should scroll to cursor at the first', () => {
wwe.setHeight(50);
const sqe = wwe.getEditor();
sqe.setHTML('a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>');

// scroll to bottom
wwe.scrollTop(99999);

sqe.moveCursorToStart();
wwe.scrollIntoCursor();

const {top: cursorTop, height: cursorHeight} = sqe.getCursorPosition();
const {top: editorTop, height: editorHeight} = wwe.$editorContainerEl.get(0).getBoundingClientRect();

expect(cursorTop - editorTop >= 0).toBe(true);
expect(cursorTop + cursorHeight <= editorTop + editorHeight).toBe(true);
});
});
});

0 comments on commit b87c338

Please sign in to comment.