y-rb 0.1.4.alpha.1-arm64-darwin

Sign up to get free protection for your applications and to get access to all the features.
data/lib/y/xml.rb ADDED
@@ -0,0 +1,846 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Y
4
+ # rubocop:disable Metrics/ClassLength
5
+
6
+ # A XMLElement
7
+ #
8
+ # Someone should not instantiate an element directly, but use
9
+ # {Y::Doc#get_xml_element} instead
10
+ #
11
+ # @example
12
+ # doc = Y::Doc.new
13
+ # xml_element = doc.get_xml_element("my xml")
14
+ #
15
+ # puts xml_element.to_s
16
+ class XMLElement
17
+ # @!attribute [r] document
18
+ #
19
+ # @return [Y::Doc] The document this array belongs to
20
+ attr_accessor :document
21
+
22
+ # Create a new XMLElement instance
23
+ #
24
+ # @param [Y::Doc] doc
25
+ def initialize(doc = nil)
26
+ @document = doc || Y::Doc.new
27
+
28
+ super()
29
+ end
30
+
31
+ # Retrieve node at index
32
+ #
33
+ # @param [Integer] index
34
+ # @return [Y::XMLElement|nil]
35
+ def [](index)
36
+ yxml_element_get(index)
37
+ end
38
+
39
+ # Create a node at index
40
+ #
41
+ # @param [Integer] index
42
+ # @param [String] name Name of node, e.g. `<p />`
43
+ # @return [Y::XMLElement]
44
+ def []=(index, name)
45
+ yxml_element_insert_element(transaction, index, name)
46
+ end
47
+
48
+ # Returns first child in list or nil if no child exists
49
+ #
50
+ # @return [Hash]
51
+ def attrs
52
+ yxml_element_attributes
53
+ end
54
+
55
+ alias attributes attrs
56
+
57
+ # Returns first child in list or nil if no child exists
58
+ #
59
+ # @return [Y::XMLElement]
60
+ def first_child
61
+ yxml_element_first_child
62
+ end
63
+
64
+ # Insert text into element at given index
65
+ #
66
+ # Optional input is pushed to the text if provided
67
+ #
68
+ # @param [Integer] index
69
+ # @param [String|nil] input
70
+ # @return [Y::XMLText]
71
+ def insert_text(index, input = nil)
72
+ text = yxml_element_insert_text(transaction, index)
73
+ text << input unless input.nil?
74
+ text
75
+ end
76
+
77
+ # Retrieve element or text adjacent (next) to this element
78
+ #
79
+ # @return [Y::XMLElement|Y::XMLText|nil]
80
+ def next_sibling
81
+ yxml_element_next_sibling
82
+ end
83
+
84
+ # Attach listener to get notified about changes to the element
85
+ #
86
+ # This supports either a `Proc` or a `Block`.
87
+ #
88
+ # @example Receive changes via Proc
89
+ # doc = Y::Doc.new
90
+ # xml_element = doc.get_xml_element("my xml element")
91
+ # xml_element.attach ->(changes) { … }
92
+ #
93
+ # @example Receive changes via Block
94
+ # doc = Y::Doc.new
95
+ # xml_element = doc.get_xml_element("my xml element")
96
+ # xml_element.attach { |changes| … }
97
+ #
98
+ # @param [Proc] callback
99
+ # @param [Block] block
100
+ # @return [Integer] The subscription ID
101
+ def attach(callback = nil, &block)
102
+ return yxml_element_observe(callback) unless callback.nil?
103
+
104
+ yxml_element_observe(block.to_proc) unless block.nil?
105
+ end
106
+
107
+ # Retrieve parent element
108
+ #
109
+ # @return [Y::XMLElement|nil]
110
+ def parent
111
+ yxml_element_parent
112
+ end
113
+
114
+ # Retrieve element or text adjacent (previous) to this element
115
+ #
116
+ # @return [Y::XMLElement|Y::XMLText|nil]
117
+ def prev_sibling
118
+ yxml_element_prev_sibling
119
+ end
120
+
121
+ # Creates a new child an inserts at the end of the children list
122
+ #
123
+ # @param [String] name
124
+ # @return [Y::XMLElement]
125
+ def <<(name)
126
+ xml_element = yxml_element_push_elem_back(transaction, name)
127
+ xml_element.document = document
128
+ xml_element
129
+ end
130
+
131
+ alias push_child <<
132
+
133
+ # Insert new text at the end of this elements child list
134
+ #
135
+ # The optional str argument initializes the text node with its value
136
+ #
137
+ # @param [String] str
138
+ # @return [Y::XMLText]
139
+ def push_text(str = nil)
140
+ text = yxml_element_push_text_back(transaction)
141
+ text.document = document
142
+ text << str unless str.nil?
143
+ text
144
+ end
145
+
146
+ # Number of children
147
+ #
148
+ # @return [Integer]
149
+ def size
150
+ yxml_element_size
151
+ end
152
+
153
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
154
+
155
+ # Removes one or more children from XML Element
156
+ #
157
+ # @example Removes a single element
158
+ # doc = Y::Doc.new
159
+ #
160
+ # xml_element = doc.get_xml_element("my xml")
161
+ # xml_element << "A"
162
+ # xml_element << "B"
163
+ # xml_element << "C"
164
+ #
165
+ # xml_element.slice!(1)
166
+ #
167
+ # xml_element.to_s # <UNDEFINED><A></A><C></C></UNDEFINED>
168
+ #
169
+ # @overload slice!(n)
170
+ # Removes nth node from child list
171
+ #
172
+ # @overload slice!(start, length)
173
+ # Removes a range of nodes
174
+ #
175
+ # @overload slice!(range)
176
+ # Removes a range of nodes
177
+ #
178
+ # @return [void]
179
+ def slice!(*args)
180
+ if args.size.zero?
181
+ raise ArgumentError,
182
+ "Provide one of `index`, `range`, `start, length` as arguments"
183
+ end
184
+
185
+ if args.size == 1
186
+ arg = args.first
187
+
188
+ if arg.is_a?(Range)
189
+ if arg.exclude_end?
190
+ yxml_element_remove_range(transaction, arg.first,
191
+ arg.last - arg.first)
192
+ end
193
+ unless arg.exclude_end?
194
+ yxml_element_remove_range(transaction, arg.first,
195
+ arg.last + 1 - arg.first)
196
+ end
197
+ return nil
198
+ end
199
+
200
+ if arg.is_a?(Numeric)
201
+ yxml_element_remove_range(transaction, arg.to_int, 1)
202
+ return nil
203
+ end
204
+ end
205
+
206
+ if args.size == 2
207
+ first, second = args
208
+
209
+ if first.is_a?(Numeric) && second.is_a?(Numeric)
210
+ yxml_element_remove_range(transaction, first, second)
211
+ return nil
212
+ end
213
+ end
214
+
215
+ raise ArgumentError, "Please check your arguments, can't slice."
216
+ end
217
+
218
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
219
+
220
+ # Tag name
221
+ #
222
+ # @return [String]
223
+ def tag
224
+ yxml_element_tag
225
+ end
226
+
227
+ # String representation of this node and all its children
228
+ #
229
+ # @return [String]
230
+ def to_s
231
+ yxml_element_to_s
232
+ end
233
+
234
+ # Detach a listener
235
+ #
236
+ # @param [Integer] subscription_id
237
+ # @return [void]
238
+ def detach(subscription_id)
239
+ yxml_element_unobserve(subscription_id)
240
+ end
241
+
242
+ # Creates a new node and puts it in front of the child list
243
+ #
244
+ # @param [String] name
245
+ # @return [Y::XMLElement]
246
+ def unshift_child(name)
247
+ xml_element = yxml_element_push_elem_front(transaction, name)
248
+ xml_element.document = document
249
+ xml_element
250
+ end
251
+
252
+ # Insert new text at the front of this elements child list
253
+ #
254
+ # The optional str argument initializes the text node with its value
255
+ #
256
+ # @param [String] str
257
+ # @return [Y::XMLText]
258
+ def unshift_text(str = nil)
259
+ text = yxml_element_push_text_front(transaction)
260
+ text.document = document
261
+ text << args.first unless str.nil?
262
+ text
263
+ end
264
+
265
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
266
+
267
+ # make attributes just work on an element in the form of `attr_name` and
268
+ # `attr_name=`
269
+ #
270
+ # @example Set and get an attribute
271
+ # doc = Y::Doc.new
272
+ # xml_element = doc.get_xml_element("my xml")
273
+ # xml_element.attr_name = "Hello"
274
+ #
275
+ # puts xml_element.attr_name # "Hello"
276
+ #
277
+ # @!visibility private
278
+ def method_missing(method_name, *args, &block)
279
+ is_setter = method_name.to_s.end_with?("=")
280
+
281
+ setter = method_name
282
+ setter += "=" unless is_setter
283
+ getter = method_name
284
+ getter = getter.to_s.slice(0...-1).to_sym if is_setter
285
+
286
+ define_singleton_method(setter.to_sym) do |new_val|
287
+ yxml_element_insert_attribute(transaction,
288
+ method_name.to_s
289
+ .delete_suffix("=")
290
+ .delete_prefix("attr_"),
291
+ new_val)
292
+ end
293
+
294
+ define_singleton_method(getter) do
295
+ yxml_element_get_attribute(method_name.to_s.delete_prefix("attr_"))
296
+ end
297
+
298
+ if is_setter
299
+ value = args[0]
300
+ send(setter, value)
301
+ end
302
+ rescue StandardError
303
+ super(method_name, *args, &block)
304
+ end
305
+
306
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
307
+
308
+ # Make sure we only respond to attributes
309
+ # @!visibility private
310
+ def respond_to_missing?(method_name, include_private = false)
311
+ method_name.to_s.start_with?("attr_") || super
312
+ end
313
+
314
+ private
315
+
316
+ # @!method yxml_element_attributes
317
+ #
318
+ # @return [Hash]
319
+
320
+ # @!method yxml_element_first_child
321
+ #
322
+ # @return [Y::XMLElement|Y::XMLText]
323
+
324
+ # @!method yxml_element_get_attribute(name)
325
+ #
326
+ # @param [String] name
327
+ # @return [String|nil]
328
+
329
+ # @!method yxml_element_get(index)
330
+ #
331
+ # @param [Integer] index
332
+ # @return [Y::XMLElement|Y::XMLText|nil]
333
+
334
+ # @!method yxml_element_insert_attribute(transaction, name, value)
335
+ #
336
+ # @param [Y::Transaction] transaction
337
+ # @param [String] name
338
+ # @param [String] value
339
+ # @return [String|nil]
340
+
341
+ # @!method yxml_element_insert_element(transaction, index, name)
342
+ #
343
+ # @param [Y::Transaction] transaction
344
+ # @param [Integer] index
345
+ # @param [String] name
346
+ # @return [Y::XMLElement]
347
+
348
+ # @!method yxml_element_insert_text(transaction, index)
349
+ #
350
+ # @param [Y::Transaction] transaction
351
+ # @param [Integer] index
352
+ # @return [Y::XMLText]
353
+
354
+ # @!method yxml_element_next_sibling()
355
+ #
356
+ # @return [Y::XMLElement|XMLText|nil]
357
+
358
+ # @!method yxml_element_observe(callback)
359
+ #
360
+ # @param [Proc] callback
361
+ # @return [Integer] The subscription ID
362
+
363
+ # @!method yxml_element_parent()
364
+ #
365
+ # @return [Y::XMLElement|nil]
366
+
367
+ # @!method yxml_element_prev_sibling()
368
+ #
369
+ # @return [Y::XMLElement|XMLText|nil]
370
+
371
+ # @!method yxml_element_push_elem_back(transaction, name)
372
+ #
373
+ # @param [Y::Transaction] transaction
374
+ # @param [String] name
375
+ # @return [Y::XMLElement]
376
+
377
+ # @!method yxml_element_push_elem_front(transaction, name)
378
+ #
379
+ # @param [Y::Transaction] transaction
380
+ # @param [String] name
381
+ # @return [Y::XMLElement]
382
+
383
+ # @!method yxml_element_push_text_back(transaction)
384
+ #
385
+ # @param [Y::Transaction] transaction
386
+ # @return [Y::XMLText]
387
+
388
+ # @!method yxml_element_push_text_front(transaction)
389
+ #
390
+ # @param [Y::Transaction] transaction
391
+ # @return [Y::XMLText]
392
+
393
+ # @!method yxml_element_remove_attribute(transaction, name)
394
+ #
395
+ # @param [Y::Transaction] transaction
396
+ # @param [String] name
397
+ #
398
+ # @return [void]
399
+
400
+ # @!method yxml_element_remove_range(transaction, index, length)
401
+ #
402
+ # @param [Y::Transaction] transaction
403
+ # @param [Integer] index
404
+ # @param [Integer] length
405
+ #
406
+ # @return [void]
407
+
408
+ # @!method yxml_element_size()
409
+ #
410
+ # @return [Integer]
411
+
412
+ # @!method yxml_element_tag()
413
+ #
414
+ # @return [String]
415
+
416
+ # @!method yxml_element_to_s()
417
+ #
418
+ # @return [String]
419
+
420
+ # @!method yxml_element_unobserve(subscription_id)
421
+ #
422
+ # @param [Integer] subscription_id
423
+ # @return [void]
424
+
425
+ # A reference to the current active transaction of the document this element
426
+ # belongs to.
427
+ #
428
+ # @return [Y::Transaction] A transaction object
429
+ def transaction
430
+ document.current_transaction
431
+ end
432
+ end
433
+
434
+ # A XMLText
435
+ #
436
+ # Someone should not instantiate a text directly, but use
437
+ # {Y::Doc#get_text_element}, {Y::XMLElement#insert_text},
438
+ # {Y::XMLElement#push_text}, {Y::XMLElement#unshift_text} instead.
439
+ #
440
+ # The XMLText API is similar to {Y::Text}, but adds a few methods to make it
441
+ # easier to work in structured XML documents.
442
+ #
443
+ # @example
444
+ # doc = Y::Doc.new
445
+ # xml_text = doc.get_xml_text("my xml text")
446
+ #
447
+ # puts xml_text.to_s
448
+ class XMLText
449
+ # @!attribute [r] document
450
+ #
451
+ # @return [Y::Doc] The document this array belongs to
452
+ attr_accessor :document
453
+
454
+ # Create a new XMLText instance
455
+ #
456
+ # @param [Y::Doc] doc
457
+ def initialize(doc = nil)
458
+ @document = doc || Y::Doc.new
459
+
460
+ super()
461
+ end
462
+
463
+ # Push a string to the end of the text node
464
+ #
465
+ # @param [String] str
466
+ # @return {void}
467
+ def <<(str)
468
+ yxml_text_push(transaction, str)
469
+ end
470
+
471
+ alias push <<
472
+
473
+ # Attach a listener to get notified about changes
474
+ #
475
+ # @param [Proc] callback
476
+ # @return [Integer] subscription_id
477
+ def attach(callback = nil, &block)
478
+ yxml_text_observe(callback) unless callback.nil?
479
+ yxml_text_observe(block.to_proc) unless block.nil?
480
+ end
481
+
482
+ # Return text attributes
483
+ #
484
+ # @return [Hash]
485
+ def attrs
486
+ yxml_text_attributes
487
+ end
488
+
489
+ # Detach a listener
490
+ #
491
+ # @param [Integer] subscription_id
492
+ # @return [void]
493
+ def detach(subscription_id)
494
+ yxml_text_unobserve(subscription_id)
495
+ end
496
+
497
+ # Format text
498
+ #
499
+ # @param [Integer] index
500
+ # @param [Integer] length
501
+ # @param [Hash] attrs
502
+ # @return [void]
503
+ def format(index, length, attrs)
504
+ yxml_text_format(transaction, index, length, attrs)
505
+ end
506
+
507
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
508
+
509
+ # Insert a value at position and with optional attributes. This method is
510
+ # similar to [String#insert](https://ruby-doc.org/core-3.1.2/String.html),
511
+ # except for the optional third `attrs` argument.
512
+ #
513
+ # @example Insert a string at position
514
+ # doc = Y::Doc.new
515
+ # text = doc.get_text("my text")
516
+ # text << "Hello, "
517
+ #
518
+ # text.insert(7, "World!")
519
+ #
520
+ # puts text.to_s == "Hello, World!" # true
521
+ #
522
+ # The value can be any of the supported types:
523
+ # - Boolean
524
+ # - String
525
+ # - Numeric
526
+ # - Array (where element types must be supported)
527
+ # - Hash (where the the types of key and values must be supported)
528
+ #
529
+ # @param [Integer] index
530
+ # @param [String, Float, Array, Hash] value
531
+ # @param [Hash|nil] attrs
532
+ # @return [void]
533
+ def insert(index, value, attrs = nil)
534
+ if value.is_a?(String)
535
+ yxml_text_insert(transaction, index, value) if attrs.nil?
536
+ unless attrs.nil?
537
+ yxml_text_insert_with_attrs(transaction, index, value,
538
+ attrs)
539
+ end
540
+ return nil
541
+ end
542
+
543
+ if can_insert?(value)
544
+ yxml_text_insert_embed(transaction, index, value) if attrs.nil?
545
+ unless attrs.nil?
546
+ yxml_text_insert_embed_with_attrs(transaction, index, value,
547
+ attrs)
548
+ end
549
+ return nil
550
+ end
551
+
552
+ raise ArgumentError,
553
+ "Can't insert value. `#{value.class.name}` isn't supported."
554
+ end
555
+
556
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
557
+
558
+ # Return length of string
559
+ #
560
+ # @return [void]
561
+ def length
562
+ yxml_text_length
563
+ end
564
+
565
+ alias size length
566
+
567
+ # Return adjacent XMLElement or XMLText node (next)
568
+ #
569
+ # @return [Y::XMLElement|Y::XMLText|nil]
570
+ def next_sibling
571
+ yxml_text_next_sibling
572
+ end
573
+
574
+ # Return parent XMLElement
575
+ #
576
+ # @return [Y::XMLElement|nil]
577
+ def parent
578
+ yxml_text_parent
579
+ end
580
+
581
+ # Return adjacent XMLElement or XMLText node (prev)
582
+ #
583
+ # @return [Y::XMLElement|Y::XMLText|nil]
584
+ def prev_sibling
585
+ yxml_text_prev_sibling
586
+ end
587
+
588
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
589
+
590
+ # Removes a part from text
591
+ #
592
+ # **Attention:** In comparison to String#slice, {XMLText#slice!} will not
593
+ # return the substring that gets removed. Even this being technically
594
+ # possible, it requires us to read the substring before removing it, which
595
+ # is not desirable in most situations.
596
+ #
597
+ # @example Removes a single character
598
+ # doc = Y::Doc.new
599
+ #
600
+ # text = doc.get_xml_text("my xml text")
601
+ # text << "Hello"
602
+ #
603
+ # text.slice!(0)
604
+ #
605
+ # text.to_s == "ello" # true
606
+ #
607
+ # @example Removes a range of characters
608
+ # doc = Y::Doc.new
609
+ #
610
+ # text = doc.get_xml_text("my xml text")
611
+ # text << "Hello"
612
+ #
613
+ # text.slice!(1..2)
614
+ # text.to_s == "Hlo" # true
615
+ #
616
+ # text.slice!(1...2)
617
+ # text.to_s == "Ho" # true
618
+ #
619
+ # @example Removes a range of chars from start and for given length
620
+ # doc = Y::Doc.new
621
+ #
622
+ # text = doc.get_xml_text("my xml text")
623
+ # text << "Hello"
624
+ #
625
+ # text.slice!(0, 3)
626
+ #
627
+ # text.to_s == "lo" # true
628
+ #
629
+ # @overload slice!(index)
630
+ # Removes a single character at index
631
+ #
632
+ # @overload slice!(start, length)
633
+ # Removes a range of characters
634
+ #
635
+ # @overload slice!(range)
636
+ # Removes a range of characters
637
+ #
638
+ # @return [void]
639
+ def slice!(*args)
640
+ if args.size.zero?
641
+ raise ArgumentError,
642
+ "Provide one of `index`, `range`, `start, length` as arguments"
643
+ end
644
+
645
+ if args.size == 1
646
+ arg = args.first
647
+
648
+ if arg.is_a?(Range)
649
+ yxml_text_remove_range(transaction, arg.first, arg.last - arg.first)
650
+ return nil
651
+ end
652
+
653
+ if arg.is_a?(Numeric)
654
+ yxml_text_remove_range(transaction, arg.to_int, 1)
655
+ return nil
656
+ end
657
+ end
658
+
659
+ if args.size == 2
660
+ first, second = args
661
+
662
+ if first.is_a?(Numeric) && second.is_a?(Numeric)
663
+ yxml_text_remove_range(transaction, first, second)
664
+ return nil
665
+ end
666
+ end
667
+
668
+ raise ArgumentError, "Please check your arguments, can't slice."
669
+ end
670
+
671
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
672
+
673
+ # Returns string representation of XMLText
674
+ #
675
+ # @return [String]
676
+ def to_s
677
+ yxml_text_to_s
678
+ end
679
+
680
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
681
+
682
+ # make attributes just work on an element in the form of `attr_name` and
683
+ # `attr_name=`
684
+ #
685
+ # @example Set and get an attribute
686
+ # doc = Y::Doc.new
687
+ # xml_element = doc.get_xml_element("my xml")
688
+ # xml_element.attr_name = "Hello"
689
+ #
690
+ # puts xml_element.attr_name # "Hello"
691
+ #
692
+ # @!visibility private
693
+ def method_missing(method_name, *args, &block)
694
+ is_setter = method_name.to_s.end_with?("=")
695
+
696
+ setter = method_name
697
+ setter += "=" unless is_setter
698
+ getter = method_name
699
+ getter = getter.to_s.slice(0...-1).to_sym if is_setter
700
+
701
+ define_singleton_method(setter.to_sym) do |new_val|
702
+ yxml_text_insert_attribute(transaction,
703
+ method_name.to_s
704
+ .delete_suffix("=")
705
+ .delete_prefix("attr_"),
706
+ new_val)
707
+ end
708
+
709
+ define_singleton_method(getter) do
710
+ yxml_text_get_attribute(method_name.to_s.delete_prefix("attr_"))
711
+ end
712
+
713
+ if is_setter
714
+ value = args[0]
715
+ send(setter, value)
716
+ end
717
+ rescue StandardError
718
+ super(method_name, *args, &block)
719
+ end
720
+
721
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
722
+
723
+ # Make sure we only respond to attributes
724
+ # @!visibility private
725
+ def respond_to_missing?(method_name, include_private = false)
726
+ method_name.to_s.start_with?("attr_") || super
727
+ end
728
+
729
+ private
730
+
731
+ def can_insert?(value)
732
+ value.is_a?(NilClass) ||
733
+ value.is_a?(Symbol) ||
734
+ [true, false].include?(value) ||
735
+ value.is_a?(Numeric) ||
736
+ value.is_a?(Enumerable) ||
737
+ value.is_a?(Hash)
738
+ end
739
+
740
+ # @!method yxml_text_attributes
741
+ #
742
+ # @return [Hash]
743
+
744
+ # @!method yxml_text_format(transaction, index, length, attrs)
745
+ #
746
+ # @param [Integer] index
747
+ # @param [Integer] length
748
+ # @param [Hash] attrs
749
+ # @return [void]
750
+
751
+ # @!method yxml_text_get_attribute(name)
752
+ #
753
+ # @param [String] name
754
+ # @return [String|nil]
755
+
756
+ # @!method yxml_text_insert(transaction, index, str)
757
+ #
758
+ # @param [Y::Transaction] transaction
759
+ # @param [Integer] index
760
+ # @param [String] str
761
+ # @return [void]
762
+
763
+ # @!method yxml_text_insert_attribute(transaction, name, value)
764
+ #
765
+ # @param [Y::Transaction] transaction
766
+ # @param [String] name
767
+ # @param [String] value
768
+ # @return [void]
769
+
770
+ # @!method yxml_text_insert_with_attrs(transaction, index, value, attrs)
771
+ #
772
+ # @param [Y::Transaction] transaction
773
+ # @param [Integer] index
774
+ # @param [String] value
775
+ # @param [Hash] attrs
776
+ # @return [void]
777
+
778
+ # @!method yxml_text_insert_embed(transaction, index, value)
779
+ #
780
+ # @param [Y::Transaction] transaction
781
+ # @param [Integer] index
782
+ # @param [String] value
783
+ # @return [void]
784
+
785
+ # @!method yxml_text_insert_embed_with_attrs(txn, index, value, attrs)
786
+ #
787
+ # @param [Y::Transaction] txn
788
+ # @param [Integer] index
789
+ # @param [true|false|Float|Integer|Array|Hash] value
790
+ # @param [Hash] attrs
791
+ # @return [void]
792
+
793
+ # @!method yxml_text_length
794
+ #
795
+ # @return [Integer]
796
+
797
+ # @!method yxml_text_next_sibling
798
+ #
799
+ # @return [Y::XMLElement|Y::XMLText|nil]
800
+
801
+ # @!method yxml_text_observe(callback)
802
+ #
803
+ # @param [Proc] callback
804
+ # @return [Integer] A subscription ID
805
+
806
+ # @!method yxml_text_parent
807
+ #
808
+ # @return [Y::XMLElement|nil]
809
+
810
+ # @!method yxml_text_prev_sibling
811
+ #
812
+ # @return [Y::XMLElement|Y::XMLText|nil]
813
+
814
+ # @!method yxml_text_push(transaction, str)
815
+ #
816
+ # @param [Y::Transaction] transaction
817
+ # @param [String] str
818
+ # @return [void]
819
+
820
+ # @!method yxml_text_remove_range(transaction, index, length)
821
+ #
822
+ # @param [Y::Transaction] transaction
823
+ # @param [Integer] index
824
+ # @param [Integer] length
825
+ # @return [void]
826
+
827
+ # @!method yxml_text_to_s()
828
+ #
829
+ # @return [void]
830
+
831
+ # @!method yxml_text_unobserve(subscription_id)
832
+ #
833
+ # @param [Integer] subscription_id
834
+ # @return [void]
835
+
836
+ # A reference to the current active transaction of the document this text
837
+ # belongs to.
838
+ #
839
+ # @return [Y::Transaction] A transaction object
840
+ def transaction
841
+ document.current_transaction
842
+ end
843
+ end
844
+
845
+ # rubocop:enable Metrics/ClassLength
846
+ end