Compare commits
12 Commits
v13.0.0-60
...
v13.0.0-61
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d50d408cdd | ||
|
|
db5312443e | ||
|
|
dbda07424b | ||
|
|
684d38d6c8 | ||
|
|
44fa064eb2 | ||
|
|
9b6fffd880 | ||
|
|
e9993b2643 | ||
|
|
762e9e8a3a | ||
|
|
6ddeb788c7 | ||
|
|
b9245f323c | ||
|
|
c0e630b635 | ||
|
|
ed2273e2ed |
@@ -70,7 +70,6 @@ missing modules.
|
||||
<script src="https://cdn.jsdelivr.net/npm/y-array@10/dist/y-array.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/y-websockets-client@8/dist/y-websockets-client.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/y-memory@8/dist/y-memory.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/y-array@10/dist/y-array.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/y-map@10/dist/y-map.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/y-text@9/dist/y-text.js"></script>
|
||||
// ..
|
||||
@@ -89,7 +88,6 @@ var Y = require('yjs')
|
||||
require('y-array')(Y) // add the y-array type to Yjs
|
||||
require('y-websockets-client')(Y)
|
||||
require('y-memory')(Y)
|
||||
require('y-array')(Y)
|
||||
require('y-map')(Y)
|
||||
require('y-text')(Y)
|
||||
// ..
|
||||
@@ -102,7 +100,6 @@ import Y from 'yjs'
|
||||
import yArray from 'y-array'
|
||||
import yWebsocketsClient from 'y-webrtc'
|
||||
import yMemory from 'y-memory'
|
||||
import yArray from 'y-array'
|
||||
import yMap from 'y-map'
|
||||
import yText from 'y-text'
|
||||
// ..
|
||||
|
||||
28
package-lock.json
generated
28
package-lock.json
generated
@@ -1,9 +1,21 @@
|
||||
{
|
||||
"name": "yjs",
|
||||
"version": "13.0.0-60",
|
||||
"version": "13.0.0-61",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@types/estree": {
|
||||
"version": "0.0.38",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.38.tgz",
|
||||
"integrity": "sha512-F/v7t1LwS4vnXuPooJQGBRKRGIoxWUTmA4VHfqjOccFsNDThD5bfUNpITive6s352O7o384wcpEaDV8rHCehDA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "6.0.110",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-6.0.110.tgz",
|
||||
"integrity": "sha512-LiaH3mF+OAqR+9Wo1OTJDbZDtCewAVjTbMhF1ZgUJ3fc8xqOJq6VqbpBh9dJVCVzByGmYIg2fREbuXNX0TKiJA==",
|
||||
"dev": true
|
||||
},
|
||||
"abab": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz",
|
||||
@@ -1498,6 +1510,7 @@
|
||||
"version": "2.6.8",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
|
||||
"integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
@@ -4806,7 +4819,8 @@
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
|
||||
"dev": true
|
||||
},
|
||||
"mute-stream": {
|
||||
"version": "0.0.5",
|
||||
@@ -5629,6 +5643,16 @@
|
||||
"glob": "7.1.2"
|
||||
}
|
||||
},
|
||||
"rollup": {
|
||||
"version": "0.58.2",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-0.58.2.tgz",
|
||||
"integrity": "sha512-RZVvCWm9BHOYloaE6LLiE/ibpjv1CmI8F8k0B0Cp+q1eezo3cswszJH1DN0djgzSlo0hjuuCmyeI+1XOYLl4wg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/estree": "0.0.38",
|
||||
"@types/node": "6.0.110"
|
||||
}
|
||||
},
|
||||
"rollup-plugin-babel": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/rollup-plugin-babel/-/rollup-plugin-babel-2.7.1.tgz",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "yjs",
|
||||
"version": "13.0.0-60",
|
||||
"version": "13.0.0-61",
|
||||
"description": "A framework for real-time p2p shared editing on any data",
|
||||
"main": "./y.node.js",
|
||||
"browser": "./y.js",
|
||||
@@ -61,6 +61,7 @@
|
||||
"esdoc-standard-plugin": "^1.0.0",
|
||||
"quill": "^1.3.5",
|
||||
"quill-cursors": "^1.0.2",
|
||||
"rollup": "^0.58.2",
|
||||
"rollup-plugin-babel": "^2.7.1",
|
||||
"rollup-plugin-commonjs": "^8.0.2",
|
||||
"rollup-plugin-inject": "^2.0.0",
|
||||
|
||||
@@ -121,12 +121,11 @@ export default class DomBinding extends Binding {
|
||||
destroy () {
|
||||
this.domToType = null
|
||||
this.typeToDom = null
|
||||
this.type.unobserve(this._typeObserver)
|
||||
this.type.unobserveDeep(this._typeObserver)
|
||||
this._mutationObserver.disconnect()
|
||||
const y = this.type._y
|
||||
y.off('beforeTransaction', this._beforeTransactionHandler)
|
||||
y.off('beforeObserverCalls', this._beforeObserverCallsHandler)
|
||||
y.off('afterObserverCalls', this._afterObserverCallsHandler)
|
||||
y.off('afterTransaction', this._afterTransactionHandler)
|
||||
super.destroy()
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ export default function domObserver (mutations, _document) {
|
||||
let parent = dom
|
||||
let yParent
|
||||
do {
|
||||
parent = parent.parentNode
|
||||
parent = parent.parentElement
|
||||
yParent = this.domToType.get(parent)
|
||||
} while (yParent === undefined && parent !== null)
|
||||
if (yParent !== false && yParent !== undefined && yParent.constructor !== YXmlHook) {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
|
||||
import { YXmlText, YXmlElement, YXmlHook } from '../../Types/YXml/YXml.js'
|
||||
import YXmlText from '../../Types/YXml/YXmlText.js'
|
||||
import YXmlHook from '../../Types/YXml/YXmlHook.js'
|
||||
import YXmlElement from '../../Types/YXml/YXmlElement.js'
|
||||
import { createAssociation, domsToTypes } from './util.js'
|
||||
import { filterDomAttributes, defaultFilter } from './filter.js'
|
||||
|
||||
|
||||
@@ -50,7 +50,6 @@ export default function typeObserver (events) {
|
||||
if (dom !== undefined && dom !== false) {
|
||||
if (yxml.constructor === YXmlText) {
|
||||
dom.nodeValue = yxml.toString()
|
||||
// TODO: use hasOwnProperty instead of === undefined check
|
||||
} else if (event.attributesChanged !== undefined) {
|
||||
// update attributes
|
||||
event.attributesChanged.forEach(attributeName => {
|
||||
|
||||
@@ -61,5 +61,5 @@ export function logID (id) {
|
||||
export function logItemHelper (name, item, append) {
|
||||
const left = item._left !== null ? item._left._lastId : null
|
||||
const origin = item._origin !== null ? item._origin._lastId : null
|
||||
return `${name}(id:${logID(item._id)},start:${logID(item._start)},left:${logID(left)},origin:${logID(origin)},right:${logID(item._right)},parent:${logID(item._parent)},parentSub:${item._parentSub}${append !== undefined ? ' - ' + append : ''})`
|
||||
return `${name}(id:${logID(item._id)},left:${logID(left)},origin:${logID(origin)},right:${logID(item._right)},parent:${logID(item._parent)},parentSub:${item._parentSub}${append !== undefined ? ' - ' + append : ''})`
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ function insertAttributes (y, parent, left, right, attributes, currentAttributes
|
||||
*/
|
||||
function insertText (y, text, parent, left, right, currentAttributes, attributes) {
|
||||
for (let [key] of currentAttributes) {
|
||||
if (attributes.hasOwnProperty(key) === false) {
|
||||
if (attributes[key] === undefined) {
|
||||
attributes[key] = null
|
||||
}
|
||||
}
|
||||
@@ -189,8 +189,9 @@ function formatText (y, length, parent, left, right, currentAttributes, attribut
|
||||
if (right._deleted === false) {
|
||||
switch (right.constructor) {
|
||||
case ItemFormat:
|
||||
if (attributes.hasOwnProperty(right.key)) {
|
||||
if (attributes[right.key] === right.value) {
|
||||
const attr = attributes[right.key]
|
||||
if (attr !== undefined) {
|
||||
if (attr === right.value) {
|
||||
negatedAttributes.delete(right.key)
|
||||
} else {
|
||||
negatedAttributes.set(right.key, right.value)
|
||||
@@ -405,8 +406,9 @@ class YTextEvent extends YArrayEvent {
|
||||
}
|
||||
} else if (item._deleted === false) {
|
||||
oldAttributes.set(item.key, item.value)
|
||||
if (attributes.hasOwnProperty(item.key)) {
|
||||
if (attributes[item.key] !== item.value) {
|
||||
const attr = attributes[item.key]
|
||||
if (attr !== undefined) {
|
||||
if (attr !== item.value) {
|
||||
if (action === 'retain') {
|
||||
addOp()
|
||||
}
|
||||
@@ -433,7 +435,7 @@ class YTextEvent extends YArrayEvent {
|
||||
addOp()
|
||||
while (this._delta.length > 0) {
|
||||
let lastOp = this._delta[this._delta.length - 1]
|
||||
if (lastOp.hasOwnProperty('retain') && !lastOp.hasOwnProperty('attributes')) {
|
||||
if (lastOp.retain !== undefined && lastOp.attributes === undefined) {
|
||||
// retain delta's if they don't assign attributes
|
||||
this._delta.pop()
|
||||
} else {
|
||||
@@ -505,11 +507,11 @@ export default class YText extends YArray {
|
||||
const currentAttributes = new Map()
|
||||
for (let i = 0; i < delta.length; i++) {
|
||||
let op = delta[i]
|
||||
if (op.hasOwnProperty('insert')) {
|
||||
if (op.insert !== undefined) {
|
||||
;[left, right] = insertText(y, op.insert, this, left, right, currentAttributes, op.attributes || {})
|
||||
} else if (op.hasOwnProperty('retain')) {
|
||||
} else if (op.retain !== undefined) {
|
||||
;[left, right] = formatText(y, op.retain, this, left, right, currentAttributes, op.attributes || {})
|
||||
} else if (op.hasOwnProperty('delete')) {
|
||||
} else if (op.delete !== undefined) {
|
||||
;[left, right] = deleteText(y, op.delete, this, left, right, currentAttributes)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
|
||||
import YXmlFragment from './YXmlFragment.js'
|
||||
import YXmlElement from './YXmlElement.js'
|
||||
import YXmlHook from './YXmlHook.js'
|
||||
|
||||
export { default as YXmlFragment } from './YXmlFragment.js'
|
||||
export { default as YXmlElement } from './YXmlElement.js'
|
||||
export { default as YXmlText } from './YXmlText.js'
|
||||
export { default as YXmlHook } from './YXmlHook.js'
|
||||
|
||||
YXmlFragment._YXmlElement = YXmlElement
|
||||
YXmlFragment._YXmlHook = YXmlHook
|
||||
@@ -1,5 +1,5 @@
|
||||
import YMap from '../YMap/YMap.js'
|
||||
import { YXmlFragment } from './YXml.js'
|
||||
import YXmlFragment from './YXmlFragment.js'
|
||||
import { createAssociation } from '../../Bindings/DomBinding/util.js'
|
||||
|
||||
/**
|
||||
@@ -186,3 +186,5 @@ export default class YXmlElement extends YXmlFragment {
|
||||
return dom
|
||||
}
|
||||
}
|
||||
|
||||
YXmlFragment._YXmlElement = YXmlElement
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import YArray from '../Types/YArray/YArray.js'
|
||||
import YMap from '../Types/YMap/YMap.js'
|
||||
import YText from '../Types/YText/YText.js'
|
||||
import { YXmlFragment, YXmlElement, YXmlText, YXmlHook } from '../Types/YXml/YXml.js'
|
||||
import YXmlText from '../Types/YXml/YXmlText.js'
|
||||
import YXmlHook from '../Types/YXml/YXmlHook.js'
|
||||
import YXmlFragment from '../Types/YXml/YXmlFragment.js'
|
||||
import YXmlElement from '../Types/YXml/YXmlElement.js'
|
||||
|
||||
import Delete from '../Struct/Delete.js'
|
||||
import ItemJSON from '../Struct/ItemJSON.js'
|
||||
|
||||
@@ -10,7 +10,10 @@ import Persistence from './Persistence.js'
|
||||
import YArray from './Types/YArray/YArray.js'
|
||||
import YMap from './Types/YMap/YMap.js'
|
||||
import YText from './Types/YText/YText.js'
|
||||
import { YXmlFragment, YXmlElement, YXmlText, YXmlHook } from './Types/YXml/YXml.js'
|
||||
import YXmlText from './Types/YXml/YXmlText.js'
|
||||
import YXmlHook from './Types/YXml/YXmlHook.js'
|
||||
import YXmlFragment from './Types/YXml/YXmlFragment.js'
|
||||
import YXmlElement from './Types/YXml/YXmlElement.js'
|
||||
import BinaryDecoder from './Util/Binary/Decoder.js'
|
||||
import { getRelativePosition, fromRelativePosition } from './Util/relativePosition.js'
|
||||
import { registerStruct } from './Util/structReferences.js'
|
||||
|
||||
779
y.node.js
779
y.node.js
@@ -1,7 +1,7 @@
|
||||
|
||||
/**
|
||||
* yjs - A framework for real-time p2p shared editing on any data
|
||||
* @version v13.0.0-60
|
||||
* @version v13.0.0-61
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
@@ -1341,7 +1341,7 @@ function logID (id) {
|
||||
return `(${id.user},${id.clock})`
|
||||
} else if (id instanceof RootID) {
|
||||
return `(${id.name},${id.type})`
|
||||
} else if (id.constructor === Y$1) {
|
||||
} else if (id.constructor === Y) {
|
||||
return `y`
|
||||
} else {
|
||||
throw new Error('This is not a valid ID!')
|
||||
@@ -1362,7 +1362,7 @@ function logID (id) {
|
||||
function logItemHelper (name, item, append) {
|
||||
const left = item._left !== null ? item._left._lastId : null;
|
||||
const origin = item._origin !== null ? item._origin._lastId : null;
|
||||
return `${name}(id:${logID(item._id)},start:${logID(item._start)},left:${logID(left)},origin:${logID(origin)},right:${logID(item._right)},parent:${logID(item._parent)},parentSub:${item._parentSub}${append !== undefined ? ' - ' + append : ''})`
|
||||
return `${name}(id:${logID(item._id)},left:${logID(left)},origin:${logID(origin)},right:${logID(item._right)},parent:${logID(item._parent)},parentSub:${item._parentSub}${append !== undefined ? ' - ' + append : ''})`
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1835,9 +1835,7 @@ class Item {
|
||||
const userState = y.ss.getState(user);
|
||||
if (selfID === null) {
|
||||
this._id = y.ss.getNextID(this._length);
|
||||
} else if (selfID.user === RootFakeUserID) {
|
||||
// nop
|
||||
} else if (selfID.clock < userState) {
|
||||
} else if (selfID.user === RootFakeUserID) ; else if (selfID.clock < userState) {
|
||||
// already applied..
|
||||
return []
|
||||
} else if (selfID.clock === userState) {
|
||||
@@ -2165,8 +2163,6 @@ function integrateChildren (y, start) {
|
||||
} while (right !== null)
|
||||
}
|
||||
|
||||
|
||||
|
||||
function gcChildren (y, item) {
|
||||
while (item !== null) {
|
||||
item._delete(y, false, true);
|
||||
@@ -3252,9 +3248,7 @@ function minimizeAttributeChanges (left, right, currentAttributes, attributes) {
|
||||
while (true) {
|
||||
if (right === null) {
|
||||
break
|
||||
} else if (right._deleted === true) {
|
||||
// continue
|
||||
} else if (right.constructor === ItemFormat && (attributes[right.key] || null) === right.value) {
|
||||
} else if (right._deleted === true) ; else if (right.constructor === ItemFormat && (attributes[right.key] || null) === right.value) {
|
||||
// found a format, update currentAttributes and continue
|
||||
updateCurrentAttributes(currentAttributes, right);
|
||||
} else {
|
||||
@@ -3293,7 +3287,7 @@ function insertAttributes (y, parent, left, right, attributes, currentAttributes
|
||||
*/
|
||||
function insertText (y, text, parent, left, right, currentAttributes, attributes) {
|
||||
for (let [key] of currentAttributes) {
|
||||
if (attributes.hasOwnProperty(key) === false) {
|
||||
if (attributes[key] === undefined) {
|
||||
attributes[key] = null;
|
||||
}
|
||||
}
|
||||
@@ -3327,8 +3321,9 @@ function formatText (y, length, parent, left, right, currentAttributes, attribut
|
||||
if (right._deleted === false) {
|
||||
switch (right.constructor) {
|
||||
case ItemFormat:
|
||||
if (attributes.hasOwnProperty(right.key)) {
|
||||
if (attributes[right.key] === right.value) {
|
||||
const attr = attributes[right.key];
|
||||
if (attr !== undefined) {
|
||||
if (attr === right.value) {
|
||||
negatedAttributes.delete(right.key);
|
||||
} else {
|
||||
negatedAttributes.set(right.key, right.value);
|
||||
@@ -3543,8 +3538,9 @@ class YTextEvent extends YArrayEvent {
|
||||
}
|
||||
} else if (item._deleted === false) {
|
||||
oldAttributes.set(item.key, item.value);
|
||||
if (attributes.hasOwnProperty(item.key)) {
|
||||
if (attributes[item.key] !== item.value) {
|
||||
const attr = attributes[item.key];
|
||||
if (attr !== undefined) {
|
||||
if (attr !== item.value) {
|
||||
if (action === 'retain') {
|
||||
addOp();
|
||||
}
|
||||
@@ -3571,7 +3567,7 @@ class YTextEvent extends YArrayEvent {
|
||||
addOp();
|
||||
while (this._delta.length > 0) {
|
||||
let lastOp = this._delta[this._delta.length - 1];
|
||||
if (lastOp.hasOwnProperty('retain') && !lastOp.hasOwnProperty('attributes')) {
|
||||
if (lastOp.retain !== undefined && lastOp.attributes === undefined) {
|
||||
// retain delta's if they don't assign attributes
|
||||
this._delta.pop();
|
||||
} else {
|
||||
@@ -3643,12 +3639,12 @@ class YText extends YArray {
|
||||
const currentAttributes = new Map();
|
||||
for (let i = 0; i < delta.length; i++) {
|
||||
let op = delta[i];
|
||||
if (op.hasOwnProperty('insert')) {
|
||||
[left, right] = insertText(y, op.insert, this, left, right, currentAttributes, op.attributes || {});
|
||||
} else if (op.hasOwnProperty('retain')) {
|
||||
[left, right] = formatText(y, op.retain, this, left, right, currentAttributes, op.attributes || {});
|
||||
} else if (op.hasOwnProperty('delete')) {
|
||||
[left, right] = deleteText(y, op.delete, this, left, right, currentAttributes);
|
||||
if (op.insert !== undefined) {
|
||||
[left, right] = insertText(y, op.insert, this, left, right, currentAttributes, op.attributes || {});
|
||||
} else if (op.retain !== undefined) {
|
||||
[left, right] = formatText(y, op.retain, this, left, right, currentAttributes, op.attributes || {});
|
||||
} else if (op.delete !== undefined) {
|
||||
[left, right] = deleteText(y, op.delete, this, left, right, currentAttributes);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -3792,258 +3788,108 @@ class YText extends YArray {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if `parent` is a parent of `child`.
|
||||
*
|
||||
* @param {Type} parent
|
||||
* @param {Type} child
|
||||
* @return {Boolean} Whether `parent` is a parent of `child`.
|
||||
* You can manage binding to a custom type with YXmlHook.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
function isParentOf (parent, child) {
|
||||
child = child._parent;
|
||||
while (child !== null) {
|
||||
if (child === parent) {
|
||||
return true
|
||||
class YXmlHook extends YMap {
|
||||
/**
|
||||
* @param {String} hookName nodeName of the Dom Node.
|
||||
*/
|
||||
constructor (hookName) {
|
||||
super();
|
||||
this.hookName = null;
|
||||
if (hookName !== undefined) {
|
||||
this.hookName = hookName;
|
||||
}
|
||||
child = child._parent;
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Default filter method (does nothing).
|
||||
*
|
||||
* @param {String} nodeName The nodeName of the element
|
||||
* @param {Map} attrs Map of key-value pairs that are attributes of the node.
|
||||
* @return {Map | null} The allowed attributes or null, if the element should be
|
||||
* filtered.
|
||||
*/
|
||||
function defaultFilter (nodeName, attrs) {
|
||||
// TODO: implement basic filter that filters out dangerous properties!
|
||||
return attrs
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function filterDomAttributes (dom, filter) {
|
||||
const attrs = new Map();
|
||||
for (let i = dom.attributes.length - 1; i >= 0; i--) {
|
||||
const attr = dom.attributes[i];
|
||||
attrs.set(attr.name, attr.value);
|
||||
/**
|
||||
* 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
|
||||
}
|
||||
return filter(dom.nodeName, attrs)
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a filter on a type.
|
||||
*
|
||||
* @param {Y} y The Yjs instance.
|
||||
* @param {DomBinding} binding The DOM binding instance that has the dom filter.
|
||||
* @param {YXmlElement | YXmlFragment } type The type to apply the filter to.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
function applyFilterOnType (y, binding, type) {
|
||||
if (isParentOf(binding.type, type)) {
|
||||
const nodeName = type.nodeName;
|
||||
let attributes = new Map();
|
||||
if (type.getAttributes !== undefined) {
|
||||
let attrs = type.getAttributes();
|
||||
for (let key in attrs) {
|
||||
attributes.set(key, attrs[key]);
|
||||
}
|
||||
}
|
||||
const filteredAttributes = binding.filter(nodeName, new Map(attributes));
|
||||
if (filteredAttributes === null) {
|
||||
type._delete(y);
|
||||
/**
|
||||
* 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<key:hookDefinition>} [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 {
|
||||
// iterate original attributes
|
||||
attributes.forEach((value, key) => {
|
||||
// delete all attributes that are not in filteredAttributes
|
||||
if (filteredAttributes.has(key) === false) {
|
||||
type.removeAttribute(key);
|
||||
}
|
||||
});
|
||||
dom = document.createElement(this.hookName);
|
||||
}
|
||||
dom.setAttribute('data-yjs-hook', this.hookName);
|
||||
createAssociation(binding, dom, this);
|
||||
return dom
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Yjs type (YXml) based on the contents of a DOM Element.
|
||||
*
|
||||
* @param {Element|TextNode} element The DOM Element
|
||||
* @param {?Document} _document Optional. Provide the global document object
|
||||
* @param {Hooks} [hooks = {}] Optional. Set of Yjs Hooks
|
||||
* @param {Filter} [filter=defaultFilter] Optional. Dom element filter
|
||||
* @param {?DomBinding} binding Warning: This property is for internal use only!
|
||||
* @return {YXmlElement | YXmlText}
|
||||
*/
|
||||
function domToType (element, _document = document, hooks = {}, filter = defaultFilter, binding) {
|
||||
let type;
|
||||
switch (element.nodeType) {
|
||||
case _document.ELEMENT_NODE:
|
||||
let hookName = null;
|
||||
let hook;
|
||||
// configure `hookName !== undefined` if element is a hook.
|
||||
if (element.hasAttribute('data-yjs-hook')) {
|
||||
hookName = element.getAttribute('data-yjs-hook');
|
||||
hook = hooks[hookName];
|
||||
if (hook === undefined) {
|
||||
console.error(`Unknown hook "${hookName}". Deleting yjsHook dataset property.`);
|
||||
delete element.removeAttribute('data-yjs-hook');
|
||||
hookName = null;
|
||||
}
|
||||
}
|
||||
if (hookName === null) {
|
||||
// Not a hook
|
||||
const attrs = filterDomAttributes(element, filter);
|
||||
if (attrs === null) {
|
||||
type = false;
|
||||
} else {
|
||||
type = new YXmlElement(element.nodeName);
|
||||
attrs.forEach((val, key) => {
|
||||
type.setAttribute(key, val);
|
||||
});
|
||||
type.insert(0, domsToTypes(element.childNodes, document, hooks, filter, binding));
|
||||
}
|
||||
} else {
|
||||
// Is a hook
|
||||
type = new YXmlHook(hookName);
|
||||
hook.fillType(element, type);
|
||||
}
|
||||
break
|
||||
case _document.TEXT_NODE:
|
||||
type = new YXmlText();
|
||||
type.insert(0, element.nodeValue);
|
||||
break
|
||||
default:
|
||||
throw new Error('Can\'t transform this node type to a YXml type!')
|
||||
/**
|
||||
* 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 {BinaryDecoder} decoder The decoder object to read data from.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_fromBinary (y, decoder) {
|
||||
const missing = super._fromBinary(y, decoder);
|
||||
this.hookName = decoder.readVarString();
|
||||
return missing
|
||||
}
|
||||
createAssociation(binding, element, type);
|
||||
return type
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates items until an undeleted item is found.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
function iterateUntilUndeleted (item) {
|
||||
while (item !== null && item._deleted) {
|
||||
item = item._right;
|
||||
/**
|
||||
* 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 {BinaryEncoder} encoder The encoder to write data to.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_toBinary (encoder) {
|
||||
super._toBinary(encoder);
|
||||
encoder.writeVarString(this.hookName);
|
||||
}
|
||||
return item
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an association (the information that a DOM element belongs to a
|
||||
* type).
|
||||
*
|
||||
* @param {DomBinding} domBinding The binding object
|
||||
* @param {Element} dom The dom that is to be associated with type
|
||||
* @param {YXmlElement|YXmlHook} type The type that is to be associated with dom
|
||||
*
|
||||
*/
|
||||
function removeAssociation (domBinding, dom, type) {
|
||||
domBinding.domToType.delete(dom);
|
||||
domBinding.typeToDom.delete(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an association (the information that a DOM element belongs to a
|
||||
* type).
|
||||
*
|
||||
* @param {DomBinding} domBinding The binding object
|
||||
* @param {Element} dom The dom that is to be associated with type
|
||||
* @param {YXmlElement|YXmlHook} type The type that is to be associated with dom
|
||||
*
|
||||
*/
|
||||
function createAssociation (domBinding, dom, type) {
|
||||
if (domBinding !== undefined) {
|
||||
domBinding.domToType.set(dom, type);
|
||||
domBinding.typeToDom.set(type, dom);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If oldDom is associated with a type, associate newDom with the type and
|
||||
* forget about oldDom. If oldDom is not associated with any type, nothing happens.
|
||||
*
|
||||
* @param {DomBinding} domBinding The binding object
|
||||
* @param {Element} oldDom The existing dom
|
||||
* @param {Element} newDom The new dom object
|
||||
*/
|
||||
function switchAssociation (domBinding, oldDom, newDom) {
|
||||
if (domBinding !== undefined) {
|
||||
const type = domBinding.domToType.get(oldDom);
|
||||
if (type !== undefined) {
|
||||
removeAssociation(domBinding, oldDom, type);
|
||||
createAssociation(domBinding, newDom, type);
|
||||
/**
|
||||
* 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!')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert Dom Elements after one of the children of this YXmlFragment.
|
||||
* The Dom elements will be bound to a new YXmlElement and inserted at the
|
||||
* specified position.
|
||||
*
|
||||
* @param {YXmlElement} type The type in which to insert DOM elements.
|
||||
* @param {YXmlElement|null} prev The reference node. New YxmlElements are
|
||||
* inserted after this node. Set null to insert at
|
||||
* the beginning.
|
||||
* @param {Array<Element>} doms The Dom elements to insert.
|
||||
* @param {?Document} _document Optional. Provide the global document object.
|
||||
* @param {DomBinding} binding The dom binding
|
||||
* @return {Array<YXmlElement>} The YxmlElements that are inserted.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
function insertDomElementsAfter (type, prev, doms, _document, binding) {
|
||||
const types = domsToTypes(doms, _document, binding.opts.hooks, binding.filter, binding);
|
||||
return type.insertAfter(prev, types)
|
||||
}
|
||||
|
||||
function domsToTypes (doms, _document, hooks, filter, binding) {
|
||||
const types = [];
|
||||
for (let dom of doms) {
|
||||
const t = domToType(dom, _document, hooks, filter, binding);
|
||||
if (t !== false) {
|
||||
types.push(t);
|
||||
}
|
||||
}
|
||||
return types
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
function insertNodeHelper (yxml, prevExpectedNode, child, _document, binding) {
|
||||
let insertedNodes = insertDomElementsAfter(yxml, prevExpectedNode, [child], _document, binding);
|
||||
if (insertedNodes.length > 0) {
|
||||
return insertedNodes[0]
|
||||
} else {
|
||||
return prevExpectedNode
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove children until `elem` is found.
|
||||
*
|
||||
* @param {Element} parent The parent of `elem` and `currentChild`.
|
||||
* @param {Element} currentChild Start removing elements with `currentChild`. If
|
||||
* `currentChild` is `elem` it won't be removed.
|
||||
* @param {Element|null} elem The elemnt to look for.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
function removeDomChildrenUntilElementFound (parent, currentChild, elem) {
|
||||
while (currentChild !== elem) {
|
||||
const del = currentChild;
|
||||
currentChild = currentChild.nextSibling;
|
||||
parent.removeChild(del);
|
||||
super._integrate(y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4514,109 +4360,261 @@ class YXmlElement extends YXmlFragment {
|
||||
}
|
||||
}
|
||||
|
||||
YXmlFragment._YXmlElement = YXmlElement;
|
||||
|
||||
/**
|
||||
* You can manage binding to a custom type with YXmlHook.
|
||||
* Check if `parent` is a parent of `child`.
|
||||
*
|
||||
* @param {Type} parent
|
||||
* @param {Type} child
|
||||
* @return {Boolean} Whether `parent` is a parent of `child`.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
class YXmlHook extends YMap {
|
||||
/**
|
||||
* @param {String} hookName nodeName of the Dom Node.
|
||||
*/
|
||||
constructor (hookName) {
|
||||
super();
|
||||
this.hookName = null;
|
||||
if (hookName !== undefined) {
|
||||
this.hookName = hookName;
|
||||
function isParentOf (parent, child) {
|
||||
child = child._parent;
|
||||
while (child !== null) {
|
||||
if (child === parent) {
|
||||
return true
|
||||
}
|
||||
child = child._parent;
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
/**
|
||||
* Default filter method (does nothing).
|
||||
*
|
||||
* @param {String} nodeName The nodeName of the element
|
||||
* @param {Map} attrs Map of key-value pairs that are attributes of the node.
|
||||
* @return {Map | null} The allowed attributes or null, if the element should be
|
||||
* filtered.
|
||||
*/
|
||||
function defaultFilter (nodeName, attrs) {
|
||||
// TODO: implement basic filter that filters out dangerous properties!
|
||||
return attrs
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function filterDomAttributes (dom, filter) {
|
||||
const attrs = new Map();
|
||||
for (let i = dom.attributes.length - 1; i >= 0; i--) {
|
||||
const attr = dom.attributes[i];
|
||||
attrs.set(attr.name, attr.value);
|
||||
}
|
||||
return filter(dom.nodeName, attrs)
|
||||
}
|
||||
|
||||
/**
|
||||
* 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<key:hookDefinition>} [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);
|
||||
/**
|
||||
* Applies a filter on a type.
|
||||
*
|
||||
* @param {Y} y The Yjs instance.
|
||||
* @param {DomBinding} binding The DOM binding instance that has the dom filter.
|
||||
* @param {YXmlElement | YXmlFragment } type The type to apply the filter to.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
function applyFilterOnType (y, binding, type) {
|
||||
if (isParentOf(binding.type, type)) {
|
||||
const nodeName = type.nodeName;
|
||||
let attributes = new Map();
|
||||
if (type.getAttributes !== undefined) {
|
||||
let attrs = type.getAttributes();
|
||||
for (let key in attrs) {
|
||||
attributes.set(key, attrs[key]);
|
||||
}
|
||||
}
|
||||
const filteredAttributes = binding.filter(nodeName, new Map(attributes));
|
||||
if (filteredAttributes === null) {
|
||||
type._delete(y);
|
||||
} else {
|
||||
dom = document.createElement(this.hookName);
|
||||
// iterate original attributes
|
||||
attributes.forEach((value, key) => {
|
||||
// delete all attributes that are not in filteredAttributes
|
||||
if (filteredAttributes.has(key) === false) {
|
||||
type.removeAttribute(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
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 {BinaryDecoder} decoder The decoder object to read data from.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_fromBinary (y, decoder) {
|
||||
const missing = super._fromBinary(y, decoder);
|
||||
this.hookName = decoder.readVarString();
|
||||
return missing
|
||||
/**
|
||||
* Creates a Yjs type (YXml) based on the contents of a DOM Element.
|
||||
*
|
||||
* @param {Element|TextNode} element The DOM Element
|
||||
* @param {?Document} _document Optional. Provide the global document object
|
||||
* @param {Hooks} [hooks = {}] Optional. Set of Yjs Hooks
|
||||
* @param {Filter} [filter=defaultFilter] Optional. Dom element filter
|
||||
* @param {?DomBinding} binding Warning: This property is for internal use only!
|
||||
* @return {YXmlElement | YXmlText}
|
||||
*/
|
||||
function domToType (element, _document = document, hooks = {}, filter = defaultFilter, binding) {
|
||||
let type;
|
||||
switch (element.nodeType) {
|
||||
case _document.ELEMENT_NODE:
|
||||
let hookName = null;
|
||||
let hook;
|
||||
// configure `hookName !== undefined` if element is a hook.
|
||||
if (element.hasAttribute('data-yjs-hook')) {
|
||||
hookName = element.getAttribute('data-yjs-hook');
|
||||
hook = hooks[hookName];
|
||||
if (hook === undefined) {
|
||||
console.error(`Unknown hook "${hookName}". Deleting yjsHook dataset property.`);
|
||||
delete element.removeAttribute('data-yjs-hook');
|
||||
hookName = null;
|
||||
}
|
||||
}
|
||||
if (hookName === null) {
|
||||
// Not a hook
|
||||
const attrs = filterDomAttributes(element, filter);
|
||||
if (attrs === null) {
|
||||
type = false;
|
||||
} else {
|
||||
type = new YXmlElement(element.nodeName);
|
||||
attrs.forEach((val, key) => {
|
||||
type.setAttribute(key, val);
|
||||
});
|
||||
type.insert(0, domsToTypes(element.childNodes, document, hooks, filter, binding));
|
||||
}
|
||||
} else {
|
||||
// Is a hook
|
||||
type = new YXmlHook(hookName);
|
||||
hook.fillType(element, type);
|
||||
}
|
||||
break
|
||||
case _document.TEXT_NODE:
|
||||
type = new YXmlText();
|
||||
type.insert(0, element.nodeValue);
|
||||
break
|
||||
default:
|
||||
throw new Error('Can\'t transform this node type to a YXml type!')
|
||||
}
|
||||
createAssociation(binding, element, type);
|
||||
return type
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 {BinaryEncoder} encoder The encoder to write data to.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_toBinary (encoder) {
|
||||
super._toBinary(encoder);
|
||||
encoder.writeVarString(this.hookName);
|
||||
/**
|
||||
* Iterates items until an undeleted item is found.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
function iterateUntilUndeleted (item) {
|
||||
while (item !== null && item._deleted) {
|
||||
item = item._right;
|
||||
}
|
||||
return item
|
||||
}
|
||||
|
||||
/**
|
||||
* 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!')
|
||||
/**
|
||||
* Removes an association (the information that a DOM element belongs to a
|
||||
* type).
|
||||
*
|
||||
* @param {DomBinding} domBinding The binding object
|
||||
* @param {Element} dom The dom that is to be associated with type
|
||||
* @param {YXmlElement|YXmlHook} type The type that is to be associated with dom
|
||||
*
|
||||
*/
|
||||
function removeAssociation (domBinding, dom, type) {
|
||||
domBinding.domToType.delete(dom);
|
||||
domBinding.typeToDom.delete(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an association (the information that a DOM element belongs to a
|
||||
* type).
|
||||
*
|
||||
* @param {DomBinding} domBinding The binding object
|
||||
* @param {Element} dom The dom that is to be associated with type
|
||||
* @param {YXmlElement|YXmlHook} type The type that is to be associated with dom
|
||||
*
|
||||
*/
|
||||
function createAssociation (domBinding, dom, type) {
|
||||
if (domBinding !== undefined) {
|
||||
domBinding.domToType.set(dom, type);
|
||||
domBinding.typeToDom.set(type, dom);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If oldDom is associated with a type, associate newDom with the type and
|
||||
* forget about oldDom. If oldDom is not associated with any type, nothing happens.
|
||||
*
|
||||
* @param {DomBinding} domBinding The binding object
|
||||
* @param {Element} oldDom The existing dom
|
||||
* @param {Element} newDom The new dom object
|
||||
*/
|
||||
function switchAssociation (domBinding, oldDom, newDom) {
|
||||
if (domBinding !== undefined) {
|
||||
const type = domBinding.domToType.get(oldDom);
|
||||
if (type !== undefined) {
|
||||
removeAssociation(domBinding, oldDom, type);
|
||||
createAssociation(domBinding, newDom, type);
|
||||
}
|
||||
super._integrate(y);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert Dom Elements after one of the children of this YXmlFragment.
|
||||
* The Dom elements will be bound to a new YXmlElement and inserted at the
|
||||
* specified position.
|
||||
*
|
||||
* @param {YXmlElement} type The type in which to insert DOM elements.
|
||||
* @param {YXmlElement|null} prev The reference node. New YxmlElements are
|
||||
* inserted after this node. Set null to insert at
|
||||
* the beginning.
|
||||
* @param {Array<Element>} doms The Dom elements to insert.
|
||||
* @param {?Document} _document Optional. Provide the global document object.
|
||||
* @param {DomBinding} binding The dom binding
|
||||
* @return {Array<YXmlElement>} The YxmlElements that are inserted.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
function insertDomElementsAfter (type, prev, doms, _document, binding) {
|
||||
const types = domsToTypes(doms, _document, binding.opts.hooks, binding.filter, binding);
|
||||
return type.insertAfter(prev, types)
|
||||
}
|
||||
|
||||
function domsToTypes (doms, _document, hooks, filter, binding) {
|
||||
const types = [];
|
||||
for (let dom of doms) {
|
||||
const t = domToType(dom, _document, hooks, filter, binding);
|
||||
if (t !== false) {
|
||||
types.push(t);
|
||||
}
|
||||
}
|
||||
return types
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
function insertNodeHelper (yxml, prevExpectedNode, child, _document, binding) {
|
||||
let insertedNodes = insertDomElementsAfter(yxml, prevExpectedNode, [child], _document, binding);
|
||||
if (insertedNodes.length > 0) {
|
||||
return insertedNodes[0]
|
||||
} else {
|
||||
return prevExpectedNode
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove children until `elem` is found.
|
||||
*
|
||||
* @param {Element} parent The parent of `elem` and `currentChild`.
|
||||
* @param {Element} currentChild Start removing elements with `currentChild`. If
|
||||
* `currentChild` is `elem` it won't be removed.
|
||||
* @param {Element|null} elem The elemnt to look for.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
function removeDomChildrenUntilElementFound (parent, currentChild, elem) {
|
||||
while (currentChild !== elem) {
|
||||
const del = currentChild;
|
||||
currentChild = currentChild.nextSibling;
|
||||
parent.removeChild(del);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4664,9 +4662,6 @@ class YXmlText extends YText {
|
||||
}
|
||||
}
|
||||
|
||||
YXmlFragment._YXmlElement = YXmlElement;
|
||||
YXmlFragment._YXmlHook = YXmlHook;
|
||||
|
||||
const structs = new Map();
|
||||
const references = new Map();
|
||||
|
||||
@@ -5315,7 +5310,6 @@ function typeObserver (events) {
|
||||
if (dom !== undefined && dom !== false) {
|
||||
if (yxml.constructor === YXmlText) {
|
||||
dom.nodeValue = yxml.toString();
|
||||
// TODO: use hasOwnProperty instead of === undefined check
|
||||
} else if (event.attributesChanged !== undefined) {
|
||||
// update attributes
|
||||
event.attributesChanged.forEach(attributeName => {
|
||||
@@ -5498,7 +5492,7 @@ function domObserver (mutations, _document) {
|
||||
let parent = dom;
|
||||
let yParent;
|
||||
do {
|
||||
parent = parent.parentNode;
|
||||
parent = parent.parentElement;
|
||||
yParent = this.domToType.get(parent);
|
||||
} while (yParent === undefined && parent !== null)
|
||||
if (yParent !== false && yParent !== undefined && yParent.constructor !== YXmlHook) {
|
||||
@@ -5663,12 +5657,11 @@ class DomBinding extends Binding {
|
||||
destroy () {
|
||||
this.domToType = null;
|
||||
this.typeToDom = null;
|
||||
this.type.unobserve(this._typeObserver);
|
||||
this.type.unobserveDeep(this._typeObserver);
|
||||
this._mutationObserver.disconnect();
|
||||
const y = this.type._y;
|
||||
y.off('beforeTransaction', this._beforeTransactionHandler);
|
||||
y.off('beforeObserverCalls', this._beforeObserverCallsHandler);
|
||||
y.off('afterObserverCalls', this._afterObserverCallsHandler);
|
||||
y.off('afterTransaction', this._afterTransactionHandler);
|
||||
super.destroy();
|
||||
}
|
||||
@@ -5701,7 +5694,7 @@ class DomBinding extends Binding {
|
||||
* @param {Object} opts Connector definition
|
||||
* @param {AbstractPersistence} persistence Persistence adapter instance
|
||||
*/
|
||||
class Y$1 extends NamedEventHandler {
|
||||
class Y extends NamedEventHandler {
|
||||
constructor (room, opts, persistence, conf = {}) {
|
||||
super();
|
||||
this.gcEnabled = conf.gc || false;
|
||||
@@ -5736,7 +5729,7 @@ class Y$1 extends NamedEventHandler {
|
||||
this.connected = false;
|
||||
let initConnection = () => {
|
||||
if (opts != null) {
|
||||
this.connector = new Y$1[opts.connector.name](this, opts.connector);
|
||||
this.connector = new Y[opts.connector.name](this, opts.connector);
|
||||
this.connected = true;
|
||||
this.emit('connectorReady');
|
||||
}
|
||||
@@ -5944,11 +5937,11 @@ class Y$1 extends NamedEventHandler {
|
||||
}
|
||||
}
|
||||
|
||||
Y$1.extend = function extendYjs () {
|
||||
Y.extend = function extendYjs () {
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
var f = arguments[i];
|
||||
if (typeof f === 'function') {
|
||||
f(Y$1);
|
||||
f(Y);
|
||||
} else {
|
||||
throw new Error('Expected a function!')
|
||||
}
|
||||
@@ -6242,7 +6235,14 @@ function plural(ms, n, name) {
|
||||
return Math.ceil(ms / n) + ' ' + name + 's';
|
||||
}
|
||||
|
||||
var debug$1 = createCommonjsModule(function (module, exports) {
|
||||
var ms$1 = /*#__PURE__*/Object.freeze({
|
||||
default: ms,
|
||||
__moduleExports: ms
|
||||
});
|
||||
|
||||
var require$$0 = ( ms$1 && ms ) || ms$1;
|
||||
|
||||
var debug = createCommonjsModule(function (module, exports) {
|
||||
/**
|
||||
* This is the common logic for both the Node.js and web browser
|
||||
* implementations of `debug()`.
|
||||
@@ -6255,7 +6255,7 @@ exports.coerce = coerce;
|
||||
exports.disable = disable;
|
||||
exports.enable = enable;
|
||||
exports.enabled = enabled;
|
||||
exports.humanize = ms;
|
||||
exports.humanize = require$$0;
|
||||
|
||||
/**
|
||||
* The currently active debug mode names, and names to skip.
|
||||
@@ -6314,8 +6314,8 @@ function createDebug(namespace) {
|
||||
|
||||
// set `diff` timestamp
|
||||
var curr = +new Date();
|
||||
var ms$$1 = curr - (prevTime || curr);
|
||||
self.diff = ms$$1;
|
||||
var ms = curr - (prevTime || curr);
|
||||
self.diff = ms;
|
||||
self.prev = prevTime;
|
||||
self.curr = curr;
|
||||
prevTime = curr;
|
||||
@@ -6445,15 +6445,29 @@ function coerce(val) {
|
||||
return val;
|
||||
}
|
||||
});
|
||||
var debug_1 = debug.coerce;
|
||||
var debug_2 = debug.disable;
|
||||
var debug_3 = debug.enable;
|
||||
var debug_4 = debug.enabled;
|
||||
var debug_5 = debug.humanize;
|
||||
var debug_6 = debug.names;
|
||||
var debug_7 = debug.skips;
|
||||
var debug_8 = debug.formatters;
|
||||
|
||||
var debug_1 = debug$1.coerce;
|
||||
var debug_2 = debug$1.disable;
|
||||
var debug_3 = debug$1.enable;
|
||||
var debug_4 = debug$1.enabled;
|
||||
var debug_5 = debug$1.humanize;
|
||||
var debug_6 = debug$1.names;
|
||||
var debug_7 = debug$1.skips;
|
||||
var debug_8 = debug$1.formatters;
|
||||
var debug$1 = /*#__PURE__*/Object.freeze({
|
||||
default: debug,
|
||||
__moduleExports: debug,
|
||||
coerce: debug_1,
|
||||
disable: debug_2,
|
||||
enable: debug_3,
|
||||
enabled: debug_4,
|
||||
humanize: debug_5,
|
||||
names: debug_6,
|
||||
skips: debug_7,
|
||||
formatters: debug_8
|
||||
});
|
||||
|
||||
var require$$0$1 = ( debug$1 && debug ) || debug$1;
|
||||
|
||||
var browser = createCommonjsModule(function (module, exports) {
|
||||
/**
|
||||
@@ -6462,7 +6476,7 @@ var browser = createCommonjsModule(function (module, exports) {
|
||||
* Expose `debug()` as the module.
|
||||
*/
|
||||
|
||||
exports = module.exports = debug$1;
|
||||
exports = module.exports = require$$0$1;
|
||||
exports.log = log;
|
||||
exports.formatArgs = formatArgs;
|
||||
exports.save = save;
|
||||
@@ -6642,7 +6656,6 @@ function localstorage() {
|
||||
} catch (e) {}
|
||||
}
|
||||
});
|
||||
|
||||
var browser_1 = browser.log;
|
||||
var browser_2 = browser.formatArgs;
|
||||
var browser_3 = browser.save;
|
||||
@@ -7189,25 +7202,25 @@ class QuillBinding extends Binding {
|
||||
}
|
||||
|
||||
// TODO: The following assignments should be moved to yjs-dist
|
||||
Y$1.AbstractConnector = AbstractConnector;
|
||||
Y$1.AbstractPersistence = AbstractPersistence;
|
||||
Y$1.Array = YArray;
|
||||
Y$1.Map = YMap;
|
||||
Y$1.Text = YText;
|
||||
Y$1.XmlElement = YXmlElement;
|
||||
Y$1.XmlFragment = YXmlFragment;
|
||||
Y$1.XmlText = YXmlText;
|
||||
Y$1.XmlHook = YXmlHook;
|
||||
Y.AbstractConnector = AbstractConnector;
|
||||
Y.AbstractPersistence = AbstractPersistence;
|
||||
Y.Array = YArray;
|
||||
Y.Map = YMap;
|
||||
Y.Text = YText;
|
||||
Y.XmlElement = YXmlElement;
|
||||
Y.XmlFragment = YXmlFragment;
|
||||
Y.XmlText = YXmlText;
|
||||
Y.XmlHook = YXmlHook;
|
||||
|
||||
Y$1.TextareaBinding = TextareaBinding;
|
||||
Y$1.QuillBinding = QuillBinding;
|
||||
Y$1.DomBinding = DomBinding;
|
||||
Y.TextareaBinding = TextareaBinding;
|
||||
Y.QuillBinding = QuillBinding;
|
||||
Y.DomBinding = DomBinding;
|
||||
|
||||
DomBinding.domToType = domToType;
|
||||
DomBinding.domsToTypes = domsToTypes;
|
||||
DomBinding.switchAssociation = switchAssociation;
|
||||
|
||||
Y$1.utils = {
|
||||
Y.utils = {
|
||||
BinaryDecoder,
|
||||
UndoManager,
|
||||
getRelativePosition,
|
||||
@@ -7218,9 +7231,9 @@ Y$1.utils = {
|
||||
fromBinary
|
||||
};
|
||||
|
||||
Y$1.debug = browser;
|
||||
Y.debug = browser;
|
||||
browser.formatters.Y = messageToString;
|
||||
browser.formatters.y = messageToRoomname;
|
||||
|
||||
module.exports = Y$1;
|
||||
module.exports = Y;
|
||||
//# sourceMappingURL=y.node.js.map
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user