Yjs Docs
  • Introduction
  • Yjs in the Wild
  • License ❤️
  • 🚲Getting Started
    • A Collaborative Editor
    • Awareness & Presence
    • Offline Support
    • Shared Types
  • 🔥Ecosystem
    • Editor Bindings
      • ProseMirror
      • TipTap
      • Monaco
      • Quill
      • CodeMirror
      • Remirror
      • Milkdown
      • Slate
    • Connection Provider
      • y-websocket
      • y-webrtc
      • y-webxdc
      • y-dat
      • y-sweet
      • Liveblocks
      • SuperViz
    • Database Provider
      • y-indexeddb
      • y-leveldb
      • y-redis
    • Other
      • y-protocols
    • Ports to other languages
  • 🔧API
    • Y.Doc
    • Shared Types
      • Y.Map
      • Y.Array
      • Y.Text
      • Y.XmlFragment
      • Y.XmlElement
      • Y.XmlText
    • Y.UndoManager
    • Y.Event
    • Delta Format
    • Document Updates
    • Y.RelativePosition
    • Awareness
    • Subdocuments
    • Internals
    • FAQ
  • 🧪Tutorials
    • Meshing Providers
    • Persisting the Document to a Central Database
    • Indefinite Scaling with y-redis
    • Lessons Learned
    • Custom Provider
  • 🌎External Resources
    • Talks, Podcasts, and Blogs
    • About CRDTs
    • CRDT Benchmarks
    • Yjs Discussion Board
    • Yjs Chat
    • Kevin's Blog
    • Awesome People ⭐
Powered by GitBook
On this page
  • API
  • Observing changes: Y.XmlEvent
  • Y.XmlEvent API

Was this helpful?

Edit on Git
  1. API
  2. Shared Types

Y.XmlElement

A shared type that represents an XML node

import * as Y from 'yjs'

const ydoc = new Y.Doc()

// You can define a Y.XmlElement as a top-level type or a nested type

// Method 1: Define a top-level type
// Note that the nodeName is always "undefined"
// when defining an XmlElement as a top-level type.
const yxmlElement = ydoc.get('prop-name', Y.XmlElement)
// Method 2: Define Y.XmlFragment that can be included into the Yjs document
const yxmlNested = new Y.XmlElement('node-name')

// Common methods
const yxmlText = new Y.XmlText()
yxmlFragment.insert(0, [yxmlText])
yxmlFragment.firstChild === yxmlText
yxmlFragment.insertAfter(yxmlText, [new Y.XmlElement('node-name')])
yxmlFragment.get(0) === yxmlText // => true

//show result in dev console
console.log(yxmlFragment.toDOM())

API

const yxmlElement = Y.XmlElement(nodeName: string)

yxmlElement.nodeName: string The name of this Y.XmlElement as a String.

yxmlElement.prevSibling: Y.XmlElement | Y.XmlText | null The previous sibling of this type. Is null if this is the first child of its parent.

yxmlElement.nextSibling: Y.XmlElement | Y.XmlText | null The next sibling of this type. Is null if this is the last child of its parent.

yxmlElement.toString(): string Returns the XML-String representation of this element. E.g. "<div height="30px"></div>"

yxmlElement.setAttribute(name: string, value: string | Y.AbstractType) Set an XML attribute. Technically, the value can only be a string. But we also allow shared types. In this case, the XML type can't be properly converted to a string.

yxmlElement.removeAttribute(name: string) Remove an XML attribute.

yxmlElement.getAttribute(name: string): string | Y.AbstractType Retrieve an XML attribute.

yxmlElement.getAttributes(): Object<string, string | Y.AbstractType> Retrieve all XML attributes.

Observing changes: Y.XmlEvent

yxmlFragment.observe(yxmlEvent => {
  yxmlEvent.target === yarray // => true

  // Observe when child-elements are added or deleted. 
  // Log the Xml-Delta Format to calculate the difference to the last observe-event
  console.log(yxmlEvent.changes.delta)

  // Observe attribute changes.  
  // Option 1: A set of keys that changed
  yxmlEvent.keysChanged // => Set<strings>
  // Option 2: Compute the differences
  yxmlEvent.changes.keys // => Map<string, { action: 'add'|'update'|'delete', oldValue: any}>

  // The change format is equivalent to the Y.MapEvent change format.
  yxmlEvent.changes.keys.forEach((change, key) => {
    if (change.action === 'add') {
      console.log(`Attribute "${key}" was added. Initial value: "${ymap.get(key)}".`)
    } else if (change.action === 'update') {
      console.log(`Attribute "${key}" was updated. New value: "${ymap.get(key)}". Previous value: "${change.oldValue}".`)
    } else if (change.action === 'delete') {
      console.log(`Attribute "${key}" was deleted. New value: undefined. Previous value: "${change.oldValue}".`)
    }
  })
})

yxmlElement.insert(0, [new Y.XmlText()]) // => [{ insert: [yxmlText] }]
yxmlElement.delete(0, 1) // [{ delete: 1 }]

yxmlElement.setAttribute('key', 'value') // Attribute "key" was added. Initial value: "undefined".
yxmlElement.setAttribute('key', 'new value') // Attribute "key" was updated. New value: "new value". Previous value: "value"
yxmlElement.deleteAttribute('key') // Attribute "key" was deleted. New value: undefined. Previous value: "new value"

Y.XmlEvent API

[todo]

describe childListChanged and attributesChanged

PreviousY.XmlFragmentNextY.XmlText

Last updated 1 year ago

Was this helpful?

Inherits from .

The yxmlElement.observe callback fires Y.XmlEvent events that you can use to calculate the changes that happened during a transaction. We use an adaption of the to calculate insertions & deletions of child-elements. Changes on the xml-attributes are expressed using the same API from .

See API. The API is inherited from Y.Event.I'm still in the process of moving the documentation to this place. For now, you can find the API docs in the README:

🔧
Y.XmlFragment
Y.Event
Quill delta format
Y.Map
GitHub - yjs/yjs: Shared data types for building collaborative softwareGitHub
API DOCS
Logo