1 /*
2 * Copyright (c) 2002-2026 Gargoyle Software Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 * https://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 package org.htmlunit.javascript.host.dom;
16
17 import org.htmlunit.corejs.javascript.Context;
18 import org.htmlunit.corejs.javascript.Function;
19 import org.htmlunit.corejs.javascript.Scriptable;
20 import org.htmlunit.corejs.javascript.VarScope;
21 import org.htmlunit.html.DomCharacterData;
22 import org.htmlunit.html.DomElement;
23 import org.htmlunit.javascript.JavaScriptEngine;
24 import org.htmlunit.javascript.configuration.JsxClass;
25 import org.htmlunit.javascript.configuration.JsxConstructor;
26 import org.htmlunit.javascript.configuration.JsxFunction;
27 import org.htmlunit.javascript.configuration.JsxGetter;
28 import org.htmlunit.javascript.configuration.JsxSetter;
29 import org.htmlunit.javascript.host.Element;
30
31 /**
32 * A JavaScript object for {@code CharacterData}.
33 *
34 * @author David K. Taylor
35 * @author Chris Erskine
36 * @author Ahmed Ashour
37 * @author Ronald Brill
38 *
39 * @see <a href="https://developer.mozilla.org/en-US/docs/Web/API/CharacterData">MDN Documentation</a>
40 */
41 @JsxClass
42 public class CharacterData extends Node {
43
44 /**
45 * JavaScript constructor.
46 */
47 @Override
48 @JsxConstructor
49 public void jsConstructor() {
50 super.jsConstructor();
51 }
52
53 /**
54 * Gets the JavaScript property {@code data} for this character data.
55 * @return the String of data
56 */
57 @JsxGetter
58 public String getData() {
59 return getDomCharacterDataOrDie().getData();
60 }
61
62 /**
63 * Sets the JavaScript property {@code data} for this character data.
64 * @param newValue the new String of data
65 */
66 @JsxSetter
67 public void setData(final String newValue) {
68 getDomCharacterDataOrDie().setData(newValue);
69 }
70
71 /**
72 * Gets the number of character in the character data.
73 * @return the number of characters
74 */
75 @JsxGetter
76 public int getLength() {
77 return getDomCharacterDataOrDie().getLength();
78 }
79
80 /**
81 * Appends a string to character data.
82 * @param arg the string to be appended to the character data
83 */
84 @JsxFunction
85 public void appendData(final String arg) {
86 getDomCharacterDataOrDie().appendData(arg);
87 }
88
89 /**
90 * Deletes characters from character data.
91 * @param offset the position of the first character to be deleted
92 * @param count the number of characters to be deleted
93 */
94 @JsxFunction
95 public void deleteData(final int offset, final int count) {
96 if (offset < 0) {
97 throw JavaScriptEngine.asJavaScriptException(
98 getWindow(),
99 "Provided offset: " + offset + " is less than zero.",
100 DOMException.INDEX_SIZE_ERR);
101 }
102
103 final DomCharacterData domCharacterData = getDomCharacterDataOrDie();
104 if (offset > domCharacterData.getLength()) {
105 throw JavaScriptEngine.asJavaScriptException(
106 getWindow(),
107 "Provided offset: " + offset + " is greater than length.",
108 DOMException.INDEX_SIZE_ERR);
109 }
110
111 domCharacterData.deleteData(offset, count);
112 }
113
114 /**
115 * Inserts a string into character data.
116 * @param offset the position within the first character at which
117 * the string is to be inserted.
118 * @param arg the string to insert
119 */
120 @JsxFunction
121 public void insertData(final int offset, final String arg) {
122 getDomCharacterDataOrDie().insertData(offset, arg);
123 }
124
125 /**
126 * Replaces characters of character data with a string.
127 * @param offset the position within the first character at which
128 * the string is to be replaced.
129 * @param count the number of characters to be replaced
130 * @param arg the string that replaces the count characters beginning at
131 * the character at offset.
132 */
133 @JsxFunction
134 public void replaceData(final int offset, final int count, final String arg) {
135 getDomCharacterDataOrDie().replaceData(offset, count, arg);
136 }
137
138 /**
139 * Extracts a substring from character data.
140 * @param offset the position of the first character to be extracted
141 * @param count the number of characters to be extracted
142 * @return a string that consists of the count characters of the character
143 * data starting from the character at position offset
144 */
145 @JsxFunction
146 public String substringData(final int offset, final int count) {
147 return getDomCharacterDataOrDie().substringData(offset, count);
148 }
149
150 private DomCharacterData getDomCharacterDataOrDie() {
151 return (DomCharacterData) super.getDomNodeOrDie();
152 }
153
154 /**
155 * Returns the next element sibling.
156 * @return the next element sibling
157 */
158 @JsxGetter
159 public Element getNextElementSibling() {
160 final DomElement child = getDomNodeOrDie().getNextElementSibling();
161 if (child != null) {
162 return child.getScriptableObject();
163 }
164 return null;
165 }
166
167 /**
168 * Returns the previous element sibling.
169 * @return the previous element sibling
170 */
171 @JsxGetter
172 public Element getPreviousElementSibling() {
173 final DomElement child = getDomNodeOrDie().getPreviousElementSibling();
174 if (child != null) {
175 return child.getScriptableObject();
176 }
177 return null;
178 }
179
180 /**
181 * {@inheritDoc}
182 */
183 @Override
184 @JsxFunction
185 public void remove() {
186 super.remove();
187 }
188
189 /**
190 * Inserts a set of Node or DOMString objects in the children list of this ChildNode's parent,
191 * just before this ChildNode.
192 * @param context the context
193 * @param scope the scope
194 * @param thisObj this object
195 * @param args the arguments
196 * @param function the function
197 */
198 @JsxFunction
199 public static void before(final Context context, final VarScope scope,
200 final Scriptable thisObj, final Object[] args, final Function function) {
201 Node.before(context, thisObj, args, function);
202 }
203
204 /**
205 * Inserts a set of Node or DOMString objects in the children list of this ChildNode's parent,
206 * just after this ChildNode.
207 * @param context the context
208 * @param scope the scope
209 * @param thisObj this object
210 * @param args the arguments
211 * @param function the function
212 */
213 @JsxFunction
214 public static void after(final Context context, final VarScope scope,
215 final Scriptable thisObj, final Object[] args, final Function function) {
216 Node.after(context, thisObj, args, function);
217 }
218
219 /**
220 * Replaces the node with a set of Node or DOMString objects.
221 * @param context the context
222 * @param scope the scope
223 * @param thisObj this object
224 * @param args the arguments
225 * @param function the function
226 */
227 @JsxFunction
228 public static void replaceWith(final Context context, final VarScope scope,
229 final Scriptable thisObj, final Object[] args, final Function function) {
230 Node.replaceWith(context, thisObj, args, function);
231 }
232 }