yjs/types/YXmlHook.mjs
2018-11-25 22:39:50 +01:00

118 lines
3.2 KiB
JavaScript

/**
* @module types
*/
import { YMap } from './YMap.mjs'
import { createAssociation } from '../bindings/dom/util.mjs'
import * as encoding from '../lib/encoding.mjs'
import * as decoding from '../lib/decoding.mjs'
import { DomBinding } from '../bindings/dom/DomBinding.mjs' // eslint-disable-line
import { Y } from '../utils/Y.mjs' // eslint-disable-line
/**
* You can manage binding to a custom type with YXmlHook.
*
* @public
*/
export class YXmlHook extends YMap {
/**
* @param {String} hookName nodeName of the Dom Node.
*/
constructor (hookName) {
super()
this.hookName = null
if (hookName !== undefined) {
this.hookName = hookName
}
}
/**
* Creates an Item with the same effect as this Item (without position effect)
*
* @private
*/
_copy () {
const struct = super._copy()
struct.hookName = this.hookName
return struct
}
/**
* Creates a Dom Element that mirrors this YXmlElement.
*
* @param {Document} [_document=document] The document object (you must define
* this when calling this method in
* nodejs)
* @param {Object.<string, any>} [hooks] Optional property to customize how hooks
* are presented in the DOM
* @param {DomBinding} [binding] You should not set this property. This is
* used if DomBinding wants to create a
* association to the created DOM type
* @return {Element} The {@link https://developer.mozilla.org/en-US/docs/Web/API/Element|Dom Element}
*
* @public
*/
toDom (_document = document, hooks = {}, binding) {
const hook = hooks[this.hookName]
let dom
if (hook !== undefined) {
dom = hook.createDom(this)
} else {
dom = document.createElement(this.hookName)
}
dom.setAttribute('data-yjs-hook', this.hookName)
createAssociation(binding, dom, this)
return dom
}
/**
* Read the next Item in a Decoder and fill this Item with the read data.
*
* This is called when data is received from a remote peer.
*
* @param {Y} y The Yjs instance that this Item belongs to.
* @param {decoding.Decoder} decoder The decoder object to read data from.
*
* @private
*/
_fromBinary (y, decoder) {
const missing = super._fromBinary(y, decoder)
this.hookName = decoding.readVarString(decoder)
return missing
}
/**
* Transform the properties of this type to binary and write it to an
* BinaryEncoder.
*
* This is called when this Item is sent to a remote peer.
*
* @param {encoding.Encoder} encoder The encoder to write data to.
*
* @private
*/
_toBinary (encoder) {
super._toBinary(encoder)
encoding.writeVarString(encoder, this.hookName)
}
/**
* Integrate this type into the Yjs instance.
*
* * Save this struct in the os
* * This type is sent to other client
* * Observer functions are fired
*
* @param {Y} y The Yjs instance
*
* @private
*/
_integrate (y) {
if (this.hookName === null) {
throw new Error('hookName must be defined!')
}
super._integrate(y)
}
}