hooks port to domBinding

This commit is contained in:
Kevin Jahns
2018-04-26 13:26:21 +02:00
parent 94933a704d
commit 1fe37c565e
9 changed files with 68 additions and 51 deletions

View File

@@ -30,6 +30,9 @@ export default class DomBinding extends Binding {
constructor (type, target, opts = {}) {
// Binding handles textType as this.type and domTextarea as this.target
super(type, target)
this.opts = opts
opts.document = opts.document || document
opts.hooks = opts.hooks || {}
/**
* Maps each DOM element to the type that it is associated with.
* @type {Map}
@@ -49,11 +52,11 @@ export default class DomBinding extends Binding {
// set initial value
target.innerHTML = ''
for (let child of type) {
target.insertBefore(child.toDom(this.domToType, this.typeToDom), null)
target.insertBefore(child.toDom(opts.document, opts.hooks, this), null)
}
this._typeObserver = typeObserver.bind(this)
this._domObserver = (mutations) => {
domObserver.call(this, mutations, opts._document)
domObserver.call(this, mutations, opts.document)
}
type.observeDeep(this._typeObserver)
this._mutationObserver = new MutationObserver(this._domObserver)

View File

@@ -1,5 +1,5 @@
import { YXmlText, YXmlElement } from '../../Types/YXml/YXml.js'
import { YXmlText, YXmlElement, YXmlHook } from '../../Types/YXml/YXml.js'
import { createAssociation } from './util.js'
/**
@@ -15,14 +15,29 @@ export default function domToType (element, _document = document, binding) {
let type
switch (element.nodeType) {
case _document.ELEMENT_NODE:
type = new YXmlElement(element.nodeName)
const attrs = element.attributes
for (let i = attrs.length - 1; i >= 0; i--) {
const attr = attrs[i]
type.setAttribute(attr.name, attr.value)
let hookName = element.dataset.yjsHook
let hook
if (hookName !== undefined) {
hook = binding.opts.hooks[hookName]
if (hook === undefined) {
console.error(`Unknown hook "${hookName}". Deleting yjsHook dataset property.`)
delete element.dataset.yjsHook
hookName = undefined
}
}
if (hookName === undefined) {
type = new YXmlElement(element.nodeName)
const attrs = element.attributes
for (let i = attrs.length - 1; i >= 0; i--) {
const attr = attrs[i]
type.setAttribute(attr.name, attr.value)
}
const children = Array.from(element.childNodes).map(e => domToType(e, _document, binding))
type.insert(0, children)
} else {
type = new YXmlHook(hookName)
hook.fillType(element, type)
}
const children = Array.from(element.childNodes).map(e => domToType(e, _document, binding))
type.insert(0, children)
break
case _document.TEXT_NODE:
type = new YXmlText()

View File

@@ -6,7 +6,7 @@ import { removeDomChildrenUntilElementFound } from './util.js'
/**
* @private
*/
export default function typeObserver (events, _document) {
export default function typeObserver (events) {
this._mutualExclude(() => {
events.forEach(event => {
const yxml = event.target
@@ -37,11 +37,10 @@ export default function typeObserver (events, _document) {
let currentChild = dom.firstChild
yxml.forEach(childType => {
const childNode = this.typeToDom.get(childType)
const binding = this
switch (childNode) {
case undefined:
// Does not exist. Create it.
const node = childType.toDom(_document, binding)
const node = childType.toDom(this.opts.document, this.opts.hooks, this)
dom.insertBefore(node, currentChild)
break
case false: