y-rb 0.3.2-x64-mingw32

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