@@ -55,14 +55,28 @@ abstract class Document implements Iterable<DocumentNode> {
55
55
/// given [node] in this [Document] , or null if the given [node]
56
56
/// is the first node, or the given [node] does not exist in this
57
57
/// [Document] .
58
+ @Deprecated ("Use getNodeBeforeById() instead" )
58
59
DocumentNode ? getNodeBefore (DocumentNode node);
59
60
61
+ /// Returns the [DocumentNode] that appears immediately before the
62
+ /// node with the given [nodeId] in this [Document] , or `null` if
63
+ /// the matching node is the first node in the document, or no such
64
+ /// node exists.
65
+ DocumentNode ? getNodeBeforeById (String nodeId);
66
+
60
67
/// Returns the [DocumentNode] that appears immediately after the
61
68
/// given [node] in this [Document] , or null if the given [node]
62
69
/// is the last node, or the given [node] does not exist in this
63
70
/// [Document] .
71
+ @Deprecated ("Use getNodeAfterById() instead" )
64
72
DocumentNode ? getNodeAfter (DocumentNode node);
65
73
74
+ /// Returns the [DocumentNode] that appears immediately after the
75
+ /// node with the given [nodeId] in this [Document] , or `null` if
76
+ /// the matching node is the last node in the document, or no such
77
+ /// node exists.
78
+ DocumentNode ? getNodeAfterById (String nodeId);
79
+
66
80
/// Returns the [DocumentNode] at the given [position] , or [null] if
67
81
/// no such node exists in this [Document] .
68
82
DocumentNode ? getNode (DocumentPosition position);
@@ -308,14 +322,43 @@ class DocumentPosition {
308
322
}
309
323
310
324
/// A single content node within a [Document] .
311
- abstract class DocumentNode implements ChangeNotifier {
325
+ @immutable
326
+ abstract class DocumentNode {
312
327
DocumentNode ({
313
328
Map <String , dynamic >? metadata,
314
329
}) : _metadata = metadata ?? {};
315
330
331
+ /// Adds [addedMetadata] to this nodes [metadata] .
332
+ ///
333
+ /// This protected method is intended to be used only during constructor
334
+ /// initialization by subclasses, so that subclasses can inject needed metadata
335
+ /// during construction time. This special method is provided because [DocumentNode] s
336
+ /// are otherwise immutable.
337
+ ///
338
+ /// For example, a `ParagraphNode` might need to ensure that its block type
339
+ /// metadata is set to `paragraphAttribution` :
340
+ ///
341
+ /// ParagraphNode({
342
+ /// required super.id,
343
+ /// required super.text,
344
+ /// this.indent = 0,
345
+ /// super.metadata,
346
+ /// }) {
347
+ /// if (getMetadataValue("blockType") == null) {
348
+ /// initAddToMetadata({"blockType": paragraphAttribution});
349
+ /// }
350
+ /// }
351
+ ///
352
+ @protected
353
+ void initAddToMetadata (Map <String , dynamic > addedMetadata) {
354
+ _metadata.addAll (addedMetadata);
355
+ }
356
+
316
357
/// ID that is unique within a [Document] .
317
358
String get id;
318
359
360
+ bool get isDeletable => _metadata[NodeMetadata .isDeletable] != false ;
361
+
319
362
/// Returns the [NodePosition] that corresponds to the beginning
320
363
/// of content in this node.
321
364
///
@@ -380,49 +423,31 @@ abstract class DocumentNode implements ChangeNotifier {
380
423
}
381
424
382
425
/// Returns all metadata attached to this [DocumentNode] .
383
- Map <String , dynamic > get metadata => _metadata;
426
+ Map <String , dynamic > get metadata => Map . from ( _metadata) ;
384
427
385
428
final Map <String , dynamic > _metadata;
386
429
387
- /// Sets all metadata for this [DocumentNode] , removing all
388
- /// existing values.
389
- set metadata (Map <String , dynamic >? newMetadata) {
390
- if (const DeepCollectionEquality ().equals (_metadata, newMetadata)) {
391
- return ;
392
- }
393
-
394
- _metadata.clear ();
395
- if (newMetadata != null ) {
396
- _metadata.addAll (newMetadata);
397
- }
398
- notifyListeners ();
399
- }
400
-
401
430
/// Returns `true` if this node has a non-null metadata value for
402
431
/// the given metadata [key] , and returns `false` , otherwise.
403
432
bool hasMetadataValue (String key) => _metadata[key] != null ;
404
433
405
434
/// Returns this node's metadata value for the given [key] .
406
435
dynamic getMetadataValue (String key) => _metadata[key];
407
436
408
- /// Sets this node's metadata value for the given [key] to the given
409
- /// [value] , and notifies node listeners that a change has occurred .
410
- void putMetadataValue ( String key, dynamic value) {
411
- if (_metadata[key] == value) {
412
- return ;
413
- }
437
+ /// Returns a copy of this [DocumentNode] with [newProperties] added to
438
+ /// the node's metadata .
439
+ ///
440
+ /// If [newProperties] contains keys that already exist in this node's
441
+ /// metadata, the existing properties are overwritten by [newProperties] .
442
+ DocumentNode copyWithAddedMetadata ( Map < String , dynamic > newProperties);
414
443
415
- _metadata[key] = value;
416
- notifyListeners ();
417
- }
444
+ /// Returns a copy of this [DocumentNode] , replacing its existing
445
+ /// metadata with [newMetadata] .
446
+ DocumentNode copyAndReplaceMetadata ( Map < String , dynamic > newMetadata);
418
447
419
448
/// Returns a copy of this node's metadata.
420
449
Map <String , dynamic > copyMetadata () => Map .from (_metadata);
421
450
422
- DocumentNode copy ();
423
-
424
- bool get isDeletable => _metadata[NodeMetadata .isDeletable] != false ;
425
-
426
451
@override
427
452
bool operator == (Object other) =>
428
453
identical (this , other) ||
0 commit comments