implement attributes on Y.Text
This commit is contained in:
		
							parent
							
								
									e1f0324840
								
							
						
					
					
						commit
						0aca7bbefa
					
				@ -21,6 +21,10 @@ import {
 | 
			
		||||
  iterateDeletedStructs,
 | 
			
		||||
  iterateStructs,
 | 
			
		||||
  findMarker,
 | 
			
		||||
  typeMapDelete,
 | 
			
		||||
  typeMapSet,
 | 
			
		||||
  typeMapGet,
 | 
			
		||||
  typeMapGetAll,
 | 
			
		||||
  updateMarkerChanges,
 | 
			
		||||
  ArraySearchMarker, AbstractUpdateDecoder, AbstractUpdateEncoder, ID, Doc, Item, Snapshot, Transaction // eslint-disable-line
 | 
			
		||||
} from '../internals.js'
 | 
			
		||||
@ -512,13 +516,32 @@ export class YTextEvent extends YEvent {
 | 
			
		||||
  /**
 | 
			
		||||
   * @param {YText} ytext
 | 
			
		||||
   * @param {Transaction} transaction
 | 
			
		||||
   * @param {Set<any>} subs The keys that changed
 | 
			
		||||
   */
 | 
			
		||||
  constructor (ytext, transaction) {
 | 
			
		||||
  constructor (ytext, transaction, subs) {
 | 
			
		||||
    super(ytext, transaction)
 | 
			
		||||
    /**
 | 
			
		||||
     * @type {Array<DeltaItem>|null}
 | 
			
		||||
     */
 | 
			
		||||
    this._delta = null
 | 
			
		||||
    /**
 | 
			
		||||
     * Whether the children changed.
 | 
			
		||||
     * @type {Boolean}
 | 
			
		||||
     * @private
 | 
			
		||||
     */
 | 
			
		||||
    this.childListChanged = false
 | 
			
		||||
    /**
 | 
			
		||||
     * Set of all changed attributes.
 | 
			
		||||
     * @type {Set<string>}
 | 
			
		||||
     */
 | 
			
		||||
    this.keysChanged = new Set()
 | 
			
		||||
    subs.forEach((sub) => {
 | 
			
		||||
      if (sub === null) {
 | 
			
		||||
        this.childListChanged = true
 | 
			
		||||
      } else {
 | 
			
		||||
        this.keysChanged.add(sub)
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
@ -779,7 +802,7 @@ export class YText extends AbstractType {
 | 
			
		||||
   */
 | 
			
		||||
  _callObserver (transaction, parentSubs) {
 | 
			
		||||
    super._callObserver(transaction, parentSubs)
 | 
			
		||||
    const event = new YTextEvent(this, transaction)
 | 
			
		||||
    const event = new YTextEvent(this, transaction, parentSubs)
 | 
			
		||||
    const doc = transaction.doc
 | 
			
		||||
    // If a remote change happened, we try to cleanup potential formatting duplicates.
 | 
			
		||||
    if (!transaction.local) {
 | 
			
		||||
@ -1111,6 +1134,74 @@ export class YText extends AbstractType {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Removes an attribute.
 | 
			
		||||
   *
 | 
			
		||||
   * @note Xml-Text nodes don't have attributes. You can use this feature to assign properties to complete text-blocks.
 | 
			
		||||
   *
 | 
			
		||||
   * @param {String} attributeName The attribute name that is to be removed.
 | 
			
		||||
   *
 | 
			
		||||
   * @public
 | 
			
		||||
   */
 | 
			
		||||
  removeAttribute (attributeName) {
 | 
			
		||||
    if (this.doc !== null) {
 | 
			
		||||
      transact(this.doc, transaction => {
 | 
			
		||||
        typeMapDelete(transaction, this, attributeName)
 | 
			
		||||
      })
 | 
			
		||||
    } else {
 | 
			
		||||
      /** @type {Array<function>} */ (this._pending).push(() => this.removeAttribute(attributeName))
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Sets or updates an attribute.
 | 
			
		||||
   *
 | 
			
		||||
   * @note Xml-Text nodes don't have attributes. You can use this feature to assign properties to complete text-blocks.
 | 
			
		||||
   *
 | 
			
		||||
   * @param {String} attributeName The attribute name that is to be set.
 | 
			
		||||
   * @param {any} attributeValue The attribute value that is to be set.
 | 
			
		||||
   *
 | 
			
		||||
   * @public
 | 
			
		||||
   */
 | 
			
		||||
  setAttribute (attributeName, attributeValue) {
 | 
			
		||||
    if (this.doc !== null) {
 | 
			
		||||
      transact(this.doc, transaction => {
 | 
			
		||||
        typeMapSet(transaction, this, attributeName, attributeValue)
 | 
			
		||||
      })
 | 
			
		||||
    } else {
 | 
			
		||||
      /** @type {Array<function>} */ (this._pending).push(() => this.setAttribute(attributeName, attributeValue))
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns an attribute value that belongs to the attribute name.
 | 
			
		||||
   *
 | 
			
		||||
   * @note Xml-Text nodes don't have attributes. You can use this feature to assign properties to complete text-blocks.
 | 
			
		||||
   *
 | 
			
		||||
   * @param {String} attributeName The attribute name that identifies the
 | 
			
		||||
   *                               queried value.
 | 
			
		||||
   * @return {any} The queried attribute value.
 | 
			
		||||
   *
 | 
			
		||||
   * @public
 | 
			
		||||
   */
 | 
			
		||||
  getAttribute (attributeName) {
 | 
			
		||||
    return /** @type {any} */ (typeMapGet(this, attributeName))
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns all attribute name/value pairs in a JSON Object.
 | 
			
		||||
   *
 | 
			
		||||
   * @note Xml-Text nodes don't have attributes. You can use this feature to assign properties to complete text-blocks.
 | 
			
		||||
   *
 | 
			
		||||
   * @param {Snapshot} [snapshot]
 | 
			
		||||
   * @return {Object<string, any>} A JSON Object that describes the attributes.
 | 
			
		||||
   *
 | 
			
		||||
   * @public
 | 
			
		||||
   */
 | 
			
		||||
  getAttributes (snapshot) {
 | 
			
		||||
    return typeMapGetAll(this)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @param {AbstractUpdateEncoder} encoder
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
 | 
			
		||||
import {
 | 
			
		||||
  YEvent,
 | 
			
		||||
  YXmlElement, YXmlFragment, Transaction // eslint-disable-line
 | 
			
		||||
  YXmlText, YXmlElement, YXmlFragment, Transaction // eslint-disable-line
 | 
			
		||||
} from '../internals.js'
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -9,7 +9,7 @@ import {
 | 
			
		||||
 */
 | 
			
		||||
export class YXmlEvent extends YEvent {
 | 
			
		||||
  /**
 | 
			
		||||
   * @param {YXmlElement|YXmlFragment} target The target on which the event is created.
 | 
			
		||||
   * @param {YXmlElement|YXmlText|YXmlFragment} target The target on which the event is created.
 | 
			
		||||
   * @param {Set<string|null>} subs The set of changed attributes. `null` is included if the
 | 
			
		||||
   *                   child list changed.
 | 
			
		||||
   * @param {Transaction} transaction The transaction instance with wich the
 | 
			
		||||
@ -25,7 +25,7 @@ export class YXmlEvent extends YEvent {
 | 
			
		||||
    this.childListChanged = false
 | 
			
		||||
    /**
 | 
			
		||||
     * Set of all changed attributes.
 | 
			
		||||
     * @type {Set<string|null>}
 | 
			
		||||
     * @type {Set<string>}
 | 
			
		||||
     */
 | 
			
		||||
    this.attributesChanged = new Set()
 | 
			
		||||
    subs.forEach((sub) => {
 | 
			
		||||
 | 
			
		||||
@ -73,3 +73,17 @@ export const testTreewalker = tc => {
 | 
			
		||||
  t.assert(xml0.querySelector('p') === paragraph1, 'querySelector found paragraph1')
 | 
			
		||||
  compare(users)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @param {t.TestCase} tc
 | 
			
		||||
 */
 | 
			
		||||
export const testYtextAttributes = tc => {
 | 
			
		||||
  const ydoc = new Y.Doc()
 | 
			
		||||
  const ytext = /** @type {Y.XmlText} */ (ydoc.get('', Y.XmlText))
 | 
			
		||||
  ytext.observe(event => {
 | 
			
		||||
    t.compare(event.changes.keys.get('test'), { action: 'add', oldValue: undefined })
 | 
			
		||||
  })
 | 
			
		||||
  ytext.setAttribute('test', 42)
 | 
			
		||||
  t.compare(ytext.getAttribute('test'), 42)
 | 
			
		||||
  t.compare(ytext.getAttributes(), { test: 42 })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user