瀏覽代碼

Merge pull request #1057 from ckeditor/t/660

Feature: Implemented `view.Document#scrollToTheSelection()` method. Closes #660.
Piotrek Koszuliński 8 年之前
父節點
當前提交
2b04f05104

+ 16 - 0
packages/ckeditor5-engine/src/view/document.js

@@ -21,6 +21,7 @@ import KeyObserver from './observer/keyobserver';
 import FakeSelectionObserver from './observer/fakeselectionobserver';
 import mix from '@ckeditor/ckeditor5-utils/src/mix';
 import ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';
+import { scrollViewportToShowTarget } from '@ckeditor/ckeditor5-utils/src/dom/scroll';
 
 /**
  * Document class creates an abstract layer over the content editable area.
@@ -302,6 +303,21 @@ export default class Document {
 	}
 
 	/**
+	 * Scrolls the page viewport and {@link #domRoots} with their ancestors to reveal the
+	 * caret, if not already visible to the user.
+	 */
+	scrollToTheSelection() {
+		const range = this.selection.getFirstRange();
+
+		if ( range ) {
+			scrollViewportToShowTarget( {
+				target: this.domConverter.viewRangeToDom( range ),
+				viewportOffset: 20
+			} );
+		}
+	}
+
+	/**
 	 * Disables all added observers.
 	 */
 	disableObservers() {

+ 21 - 0
packages/ckeditor5-engine/tests/view/document/document.js

@@ -19,6 +19,7 @@ import DomConverter from '../../../src/view/domconverter';
 import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils';
 import count from '@ckeditor/ckeditor5-utils/src/count';
 import log from '@ckeditor/ckeditor5-utils/src/log';
+import global from '@ckeditor/ckeditor5-utils/src/dom/global';
 
 testUtils.createSinonSandbox();
 
@@ -323,6 +324,26 @@ describe( 'Document', () => {
 		} );
 	} );
 
+	describe( 'scrollToTheSelection()', () => {
+		it( 'does nothing when there are no ranges in the selection', () => {
+			const stub = testUtils.sinon.stub( global.window, 'scrollTo' );
+
+			viewDocument.scrollToTheSelection();
+			sinon.assert.notCalled( stub );
+		} );
+
+		it( 'scrolls to the first range in selection with an offset', () => {
+			const stub = testUtils.sinon.stub( global.window, 'scrollTo' );
+			const root = viewDocument.createRoot( document.createElement( 'div' ) );
+			const range = ViewRange.createIn( root );
+
+			viewDocument.selection.addRange( range );
+
+			viewDocument.scrollToTheSelection();
+			sinon.assert.calledWithMatch( stub, sinon.match.number, sinon.match.number );
+		} );
+	} );
+
 	describe( 'disableObservers()', () => {
 		it( 'should disable observers', () => {
 			const addedObserverMock = viewDocument.addObserver( ObserverMock );