diff --git a/examples/html-editor/index.js b/examples/html-editor/index.js
index 80623031..a13010a4 100644
--- a/examples/html-editor/index.js
+++ b/examples/html-editor/index.js
@@ -1,7 +1,7 @@
/* global Y */
window.onload = function () {
- window.domBinding = new Y.DomBinding(window.yXmlType, document.body)
+ window.domBinding = new Y.DomBinding(window.yXmlType, document.body, { scrollingElement: document.scrollingElement })
}
let y = new Y('htmleditor', {
diff --git a/src/Bindings/DomBinding/DomBinding.js b/src/Bindings/DomBinding/DomBinding.js
index 1568f08d..b3ecb625 100644
--- a/src/Bindings/DomBinding/DomBinding.js
+++ b/src/Bindings/DomBinding/DomBinding.js
@@ -33,6 +33,7 @@ export default class DomBinding extends Binding {
this.opts = opts
opts.document = opts.document || document
opts.hooks = opts.hooks || {}
+ this.scrollingElement = opts.scrollingElement || null
/**
* Maps each DOM element to the type that it is associated with.
* @type {Map}
@@ -105,17 +106,6 @@ export default class DomBinding extends Binding {
createAssociation(this, target, type)
}
- /**
- * Enables the smart scrolling functionality for a Dom Binding.
- * This is useful when YXml is bound to a shared editor. When activated,
- * the viewport will be changed to accommodate remote changes.
- *
- * @param {Element} scrollElement The node that is
- */
- enableSmartScrolling (scrollElement) {
- // @TODO: implement smart scrolling
- }
-
/**
* NOTE: currently does not apply filter to existing elements!
* @param {FilterFunction} filter The filter function to use from now on.
diff --git a/src/Bindings/DomBinding/domObserver.js b/src/Bindings/DomBinding/domObserver.js
index 8304c079..593510a5 100644
--- a/src/Bindings/DomBinding/domObserver.js
+++ b/src/Bindings/DomBinding/domObserver.js
@@ -125,9 +125,6 @@ export default function domObserver (mutations, _document) {
}
})
for (let dom of diffChildren) {
- if (dom.yOnChildrenChanged !== undefined) {
- dom.yOnChildrenChanged()
- }
const yxml = this.domToType.get(dom)
applyChangesFromDom(this, dom, yxml, _document)
}
diff --git a/src/Bindings/DomBinding/typeObserver.js b/src/Bindings/DomBinding/typeObserver.js
index 1417cc4e..6b193159 100644
--- a/src/Bindings/DomBinding/typeObserver.js
+++ b/src/Bindings/DomBinding/typeObserver.js
@@ -1,13 +1,49 @@
+/* global getSelection */
import YXmlText from '../../Types/YXml/YXmlText.js'
import YXmlHook from '../../Types/YXml/YXmlHook.js'
import { removeDomChildrenUntilElementFound } from './util.js'
+function findScrollReference (scrollingElement) {
+ if (scrollingElement !== null) {
+ let anchor = getSelection().anchorNode
+ if (anchor == null) {
+ let children = scrollingElement.children
+ for (let i = 0; i < children.length; i++) {
+ const elem = children[i]
+ const rect = elem.getBoundingClientRect()
+ if (rect.top >= 0) {
+ return { elem, top: rect.top }
+ }
+ }
+ } else {
+ if (anchor.nodeType === document.TEXT_NODE) {
+ anchor = anchor.parentElement
+ }
+ const top = anchor.getBoundingClientRect().top
+ return { elem: anchor, top: top }
+ }
+ }
+ return null
+}
+
+function fixScroll (scrollingElement, ref) {
+ if (ref !== null) {
+ const { elem, top } = ref
+ const currentTop = elem.getBoundingClientRect().top
+ const newScroll = scrollingElement.scrollTop + currentTop - top
+ if (newScroll >= 0) {
+ scrollingElement.scrollTop = newScroll
+ }
+ }
+}
+
/**
* @private
*/
export default function typeObserver (events) {
this._mutualExclude(() => {
+ const scrollRef = findScrollReference(this.scrollingElement)
events.forEach(event => {
const yxml = event.target
const dom = this.typeToDom.get(yxml)
@@ -59,5 +95,6 @@ export default function typeObserver (events) {
}
}
})
+ fixScroll(this.scrollingElement, scrollRef)
})
}