1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.html;
16
17 import org.htmlunit.SgmlPage;
18 import org.w3c.dom.CharacterData;
19
20
21
22
23
24
25
26
27
28
29
30 public abstract class DomCharacterData extends DomNode implements CharacterData {
31
32
33 private String data_;
34
35
36
37
38
39
40
41 public DomCharacterData(final SgmlPage page, final String data) {
42 super(page);
43 setData(data);
44 }
45
46
47
48
49
50 @Override
51 public String getData() {
52 return data_;
53 }
54
55
56
57
58
59 @Override
60 public void setData(final String data) {
61 final String oldData = data_;
62 data_ = data;
63
64 final SgmlPage page = getPage();
65 if (page == null || page.isCharacterDataChangeListenerInUse()) {
66 fireCharacterDataChanged(this, oldData);
67 }
68 }
69
70
71
72
73
74 @Override
75 public void setNodeValue(final String newValue) {
76 setData(newValue);
77 }
78
79
80
81
82 @Override
83 public void setTextContent(final String textContent) {
84 setData(textContent);
85 }
86
87
88
89
90
91 @Override
92 public int getLength() {
93 return data_.length();
94 }
95
96
97
98
99
100 @Override
101 public void appendData(final String newData) {
102 data_ += newData;
103 }
104
105
106
107
108
109
110
111
112 @Override
113 public void deleteData(final int offset, final int count) {
114 if (offset < 0) {
115 throw new IllegalArgumentException("Provided offset: " + offset + " is less than zero.");
116 }
117
118 final String data = data_.substring(0, offset);
119 if (count >= 0) {
120 final int fromLeft = offset + count;
121 if (fromLeft < data_.length()) {
122 setData(data + data_.substring(fromLeft));
123 return;
124 }
125 }
126 setData(data);
127 }
128
129
130
131
132
133
134 @Override
135 public void insertData(final int offset, final String arg) {
136 setData(new StringBuilder(data_).insert(offset, arg).toString());
137 }
138
139
140
141
142
143
144
145 @Override
146 public void replaceData(final int offset, final int count, final String arg) {
147 deleteData(offset, count);
148 insertData(offset, arg);
149 }
150
151
152
153
154
155
156
157
158 @Override
159 public String substringData(final int offset, final int count) {
160 final int length = data_.length();
161 if (count < 0 || offset < 0 || offset > length - 1) {
162 throw new IllegalArgumentException("offset: " + offset + " count: " + count);
163 }
164
165 final int tailIndex = Math.min(offset + count, length);
166 return data_.substring(offset, tailIndex);
167 }
168
169
170
171
172
173 @Override
174 public String getNodeValue() {
175 return data_;
176 }
177
178
179
180
181 @Override
182 public String getCanonicalXPath() {
183 return getParentNode().getCanonicalXPath() + '/' + getXPathToken();
184 }
185
186
187
188
189 private String getXPathToken() {
190 final DomNode parent = getParentNode();
191
192
193
194 int siblingsOfSameType = 0;
195 int nodeIndex = 0;
196 for (final DomNode child : parent.getChildren()) {
197 if (child == this) {
198 nodeIndex = ++siblingsOfSameType;
199 if (nodeIndex > 1) {
200
201
202 break;
203 }
204 }
205 else if (child.getNodeType() == getNodeType()) {
206 siblingsOfSameType++;
207 if (nodeIndex > 0) {
208
209
210 break;
211 }
212 }
213 }
214
215 final String nodeName = getNodeName().substring(1) + "()";
216 if (siblingsOfSameType == 1) {
217 return nodeName;
218 }
219 return nodeName + '[' + nodeIndex + ']';
220 }
221 }