mirror of
https://github.com/yjs/yjs.git
synced 2025-12-16 19:57:45 +01:00
[suggested formatting] implement previousUnattributedAttributes approach
This commit is contained in:
@@ -935,6 +935,16 @@ export class YText extends AbstractType {
|
|||||||
*/
|
*/
|
||||||
let changedAttributes = {} // saves changed attributes for retain
|
let changedAttributes = {} // saves changed attributes for retain
|
||||||
let usingChangedAttributes = false
|
let usingChangedAttributes = false
|
||||||
|
/**
|
||||||
|
* Logic for formatting attribute attribution
|
||||||
|
* Everything that comes after an formatting attribute is formatted by the user that created it.
|
||||||
|
* Two exceptions:
|
||||||
|
* - the user resets formatting to the previously known formatting that is not attributed
|
||||||
|
* - the user deletes a formatting attribute and hence restores the previously known formatting
|
||||||
|
* that is not attributed.
|
||||||
|
* @type {import('../utils/Delta.js').FormattingAttributes}
|
||||||
|
*/
|
||||||
|
let previousUnattributedAttributes = {} // contains previously known unattributed formatting
|
||||||
/**
|
/**
|
||||||
* @type {import('../utils/Delta.js').FormattingAttributes}
|
* @type {import('../utils/Delta.js').FormattingAttributes}
|
||||||
*/
|
*/
|
||||||
@@ -1016,6 +1026,9 @@ export class YText extends AbstractType {
|
|||||||
case ContentFormat: {
|
case ContentFormat: {
|
||||||
const { key, value } = /** @type {ContentFormat} */ (c.content)
|
const { key, value } = /** @type {ContentFormat} */ (c.content)
|
||||||
const currAttrVal = currentAttributes[key] ?? null
|
const currAttrVal = currentAttributes[key] ?? null
|
||||||
|
if (attribution != null && (c.deleted || !previousUnattributedAttributes.hasOwnProperty(key))) {
|
||||||
|
previousUnattributedAttributes[key] = c.deleted ? value : currAttrVal
|
||||||
|
}
|
||||||
// @todo write a function "updateCurrentAttributes" and "updateChangedAttributes"
|
// @todo write a function "updateCurrentAttributes" and "updateChangedAttributes"
|
||||||
// # Update Attributes
|
// # Update Attributes
|
||||||
if (renderContent || renderDelete) {
|
if (renderContent || renderDelete) {
|
||||||
@@ -1075,28 +1088,30 @@ export class YText extends AbstractType {
|
|||||||
previousAttributes[key] = value
|
previousAttributes[key] = value
|
||||||
}
|
}
|
||||||
// # Update Attributions
|
// # Update Attributions
|
||||||
if (attribution != null || d.usedAttribution?.attributes?.[key] != null) {
|
if (attribution != null || previousUnattributedAttributes.hasOwnProperty(key)) {
|
||||||
/**
|
/**
|
||||||
* @type {import('../utils/Delta.js').Attribution}
|
* @type {import('../utils/Delta.js').Attribution}
|
||||||
*/
|
*/
|
||||||
const formattingAttribution = object.assign({}, d.usedAttribution)
|
const formattingAttribution = object.assign({}, d.usedAttribution)
|
||||||
const attributesChanged = /** @type {{ [key: string]: Array<any> }} */ (formattingAttribution.attributes = object.assign({}, formattingAttribution.attributes ?? {}))
|
const changedAttributedAttributes = /** @type {{ [key: string]: Array<any> }} */ (formattingAttribution.attributes = object.assign({}, formattingAttribution.attributes ?? {}))
|
||||||
if (value === null || attribution == null) {
|
|
||||||
delete attributesChanged[key]
|
if (attribution == null || equalAttrs(previousUnattributedAttributes[key], currentAttributes[key] ?? null)) {
|
||||||
|
// an unattributed formatting attribute was found or an attributed formatting
|
||||||
|
// attribute was found that resets to the previous status
|
||||||
|
delete changedAttributedAttributes[key]
|
||||||
|
delete previousUnattributedAttributes[key]
|
||||||
} else {
|
} else {
|
||||||
const by = attributesChanged[key] = (attributesChanged[key]?.slice() ?? [])
|
const by = changedAttributedAttributes[key] = (changedAttributedAttributes[key]?.slice() ?? [])
|
||||||
by.push(...((c.deleted ? attribution.delete : attribution.insert) ?? []))
|
by.push(...((c.deleted ? attribution.delete : attribution.insert) ?? []))
|
||||||
const attributedAt = (c.deleted ? attribution.deletedAt : attribution.insertedAt)
|
const attributedAt = (c.deleted ? attribution.deletedAt : attribution.insertedAt)
|
||||||
if (attributedAt) formattingAttribution.attributedAt = attributedAt
|
if (attributedAt) formattingAttribution.attributedAt = attributedAt
|
||||||
}
|
}
|
||||||
if (attribution != null) {
|
if (object.isEmpty(changedAttributedAttributes)) {
|
||||||
if (object.isEmpty(attributesChanged)) {
|
d.useAttribution(null)
|
||||||
d.useAttribution(null)
|
} else if (attribution != null) {
|
||||||
} else {
|
const attributedAt = (c.deleted ? attribution.deletedAt : attribution.insertedAt)
|
||||||
const attributedAt = (c.deleted ? attribution.deletedAt : attribution.insertedAt)
|
if (attributedAt != null) formattingAttribution.attributedAt = attributedAt
|
||||||
if (attributedAt != null) formattingAttribution.attributedAt = attributedAt
|
d.useAttribution(formattingAttribution)
|
||||||
d.useAttribution(formattingAttribution)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
|||||||
Reference in New Issue
Block a user