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 @JsxClass
40 public class CharacterData extends Node {
41
42 /**
43 * JavaScript constructor.
44 */
45 @Override
46 @JsxConstructor
47 public void jsConstructor() {
48 super.jsConstructor();
49 }
50
51 /**
52 * Gets the JavaScript property {@code data} for this character data.
53 * @return the String of data
54 */
55 @JsxGetter
56 public String getData() {
57 return getDomCharacterDataOrDie().getData();
58 }
59
60 /**
61 * Sets the JavaScript property {@code data} for this character data.
62 * @param newValue the new String of data
63 */
64 @JsxSetter
65 public void setData(final String newValue) {
66 getDomCharacterDataOrDie().setData(newValue);
67 }
68
69 /**
70 * Gets the number of character in the character data.
71 * @return the number of characters
72 */
73 @JsxGetter
74 public int getLength() {
75 return getDomCharacterDataOrDie().getLength();
76 }
77
78 /**
79 * Append a string to character data.
80 * @param arg the string to be appended to the character data
81 */
82 @JsxFunction
83 public void appendData(final String arg) {
84 getDomCharacterDataOrDie().appendData(arg);
85 }
86
87 /**
88 * Delete characters from character data.
89 * @param offset the position of the first character to be deleted
90 * @param count the number of characters to be deleted
91 */
92 @JsxFunction
93 public void deleteData(final int offset, final int count) {
94 if (offset < 0) {
95 throw JavaScriptEngine.asJavaScriptException(
96 getWindow(),
97 "Provided offset: " + offset + " is less than zero.",
98 DOMException.INDEX_SIZE_ERR);
99 }
100
101 final DomCharacterData domCharacterData = getDomCharacterDataOrDie();
102 if (offset > domCharacterData.getLength()) {
103 throw JavaScriptEngine.asJavaScriptException(
104 getWindow(),
105 "Provided offset: " + offset + " is greater than length.",
106 DOMException.INDEX_SIZE_ERR);
107 }
108
109 domCharacterData.deleteData(offset, count);
110 }
111
112 /**
113 * Insert a string into character data.
114 * @param offset the position within the first character at which
115 * the string is to be inserted.
116 * @param arg the string to insert
117 */
118 @JsxFunction
119 public void insertData(final int offset, final String arg) {
120 getDomCharacterDataOrDie().insertData(offset, arg);
121 }
122
123 /**
124 * Replace characters of character data with a string.
125 * @param offset the position within the first character at which
126 * the string is to be replaced.
127 * @param count the number of characters to be replaced
128 * @param arg the string that replaces the count characters beginning at
129 * the character at offset.
130 */
131 @JsxFunction
132 public void replaceData(final int offset, final int count, final String arg) {
133 getDomCharacterDataOrDie().replaceData(offset, count, arg);
134 }
135
136 /**
137 * Extract a substring from character data.
138 * @param offset the position of the first character to be extracted
139 * @param count the number of characters to be extracted
140 * @return a string that consists of the count characters of the character
141 * data starting from the character at position offset
142 */
143 @JsxFunction
144 public String substringData(final int offset, final int count) {
145 return getDomCharacterDataOrDie().substringData(offset, count);
146 }
147
148 private DomCharacterData getDomCharacterDataOrDie() {
149 return (DomCharacterData) super.getDomNodeOrDie();
150 }
151
152 /**
153 * Returns the next element sibling.
154 * @return the next element sibling
155 */
156 @JsxGetter
157 public Element getNextElementSibling() {
158 final DomElement child = getDomNodeOrDie().getNextElementSibling();
159 if (child != null) {
160 return child.getScriptableObject();
161 }
162 return null;
163 }
164
165 /**
166 * Returns the previous element sibling.
167 * @return the previous element sibling
168 */
169 @JsxGetter
170 public Element getPreviousElementSibling() {
171 final DomElement child = getDomNodeOrDie().getPreviousElementSibling();
172 if (child != null) {
173 return child.getScriptableObject();
174 }
175 return null;
176 }
177
178 /**
179 * {@inheritDoc}
180 */
181 @Override
182 @JsxFunction
183 public void remove() {
184 super.remove();
185 }
186
187 /**
188 * Inserts a set of Node or DOMString objects in the children list of this ChildNode's parent,
189 * just before this ChildNode.
190 * @param context the context
191 * @param scope the scope
192 * @param thisObj this object
193 * @param args the arguments
194 * @param function the function
195 */
196 @JsxFunction
197 public static void before(final Context context, final VarScope scope,
198 final Scriptable thisObj, final Object[] args, final Function function) {
199 Node.before(context, thisObj, args, function);
200 }
201
202 /**
203 * Inserts a set of Node or DOMString objects in the children list of this ChildNode's parent,
204 * just after this ChildNode.
205 * @param context the context
206 * @param scope the scope
207 * @param thisObj this object
208 * @param args the arguments
209 * @param function the function
210 */
211 @JsxFunction
212 public static void after(final Context context, final VarScope scope,
213 final Scriptable thisObj, final Object[] args, final Function function) {
214 Node.after(context, thisObj, args, function);
215 }
216
217 /**
218 * Replaces the node wit a set of Node or DOMString objects.
219 * @param context the context
220 * @param scope the scope
221 * @param thisObj this object
222 * @param args the arguments
223 * @param function the function
224 */
225 @JsxFunction
226 public static void replaceWith(final Context context, final VarScope scope,
227 final Scriptable thisObj, final Object[] args, final Function function) {
228 Node.replaceWith(context, thisObj, args, function);
229 }
230 }