View Javadoc
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 }