View Javadoc
1   /*
2    * Copyright (c) 2002-2025 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.WebDriverTestCase;
18  import org.htmlunit.junit.BrowserRunner;
19  import org.htmlunit.junit.annotation.Alerts;
20  import org.junit.Test;
21  import org.junit.runner.RunWith;
22  
23  /**
24   * Tests for {@link TextRange}.
25   *
26   * @author Marc Guillemot
27   * @author Ahmed Ashour
28   * @author David Gileadi
29   * @author Frank Danek
30   */
31  @RunWith(BrowserRunner.class)
32  public class TextRangeTest extends WebDriverTestCase {
33  
34      /**
35       * @throws Exception if the test fails
36       */
37      @Test
38      @Alerts("TypeError")
39      public void text() throws Exception {
40          final String html = DOCTYPE_HTML
41              + "<html>\n"
42              + "<head>\n"
43              + "  <script>\n"
44              + LOG_TITLE_FUNCTION
45              + "    function test() {\n"
46              + "      try {\n"
47              + "        var f = document.getElementById('foo');\n"
48              + "        f.focus();\n"
49              + "        var r = document.selection.createRange();\n"
50              + "        log(f.value);\n"
51              + "        r.text = 'bla bla';\n"
52              + "        log(f.value);\n"
53              + "        r.duplicate().text = 'bli bli';\n"
54              + "        log(f.value);\n"
55              + "      } catch(e) { logEx(e); }\n"
56              + "    }\n"
57              + "  </script>\n"
58              + "</head>\n"
59              + "<body onload='test()'>\n"
60              + "<textarea id='foo'></textarea>\n"
61              + "</body>\n"
62              + "</html>";
63  
64          loadPageVerifyTitle2(html);
65      }
66  
67      /**
68       * @throws Exception if the test fails
69       */
70      @Test
71      @Alerts("TypeError")
72      public void parentElement() throws Exception {
73          final String html = DOCTYPE_HTML
74              + "<html>\n"
75              + "<head>\n"
76              + "  <script>\n"
77              + LOG_TITLE_FUNCTION
78              + "    function test() {\n"
79              + "      try {\n"
80              + "        log(document.body.createTextRange().parentElement().tagName);\n"
81              + "      } catch(e) { logEx(e); }\n"
82              + "    }\n"
83              + "  </script>\n"
84              + "</head>\n"
85              + "<body onload='test()'>\n"
86              + "</body>\n"
87              + "</html>";
88  
89          loadPageVerifyTitle2(html);
90      }
91  
92      /**
93       * @throws Exception if the test fails
94       */
95      @Test
96      @Alerts("TypeError")
97      public void collapse() throws Exception {
98          final String html = DOCTYPE_HTML
99              + "<html>\n"
100             + "<head>\n"
101             + "  <script>\n"
102             + LOG_TITLE_FUNCTION
103             + "    function test() {\n"
104             + "      try {\n"
105             + "        var f = document.getElementById('foo');\n"
106             + "        f.focus();\n"
107             + "        f.select();\n"
108             + "        var r = document.selection.createRange();\n"
109             + "        log(r.text);\n"
110             + "        r.collapse();\n"
111             + "        log(r.text);\n"
112             + "      } catch(e) { logEx(e); }\n"
113             + "    }\n"
114             + "  </script>\n"
115             + "</head>\n"
116             + "<body onload='test()'>\n"
117             + "<textarea id='foo'>hello</textarea>\n"
118             + "</body>\n"
119             + "</html>";
120 
121         loadPageVerifyTitle2(html);
122     }
123 
124     /**
125      * Minimal test: just test that function is available.
126      * @throws Exception if the test fails
127      */
128     @Test
129     @Alerts("TypeError")
130     public void select() throws Exception {
131         final String html = DOCTYPE_HTML
132             + "<html>\n"
133             + "<head>\n"
134             + "  <script>\n"
135             + LOG_TITLE_FUNCTION
136             + "    function test() {\n"
137             + "      try {\n"
138             + "        var r = document.selection.createRange();\n"
139             + "        r.select();\n"
140             + "      } catch(e) { logEx(e); }\n"
141             + "    }\n"
142             + "  </script>\n"
143             + "</head>\n"
144             + "<body onload='test()'>\n"
145             + "<textarea id='foo'>hello</textarea>\n"
146             + "</body>\n"
147             + "</html>";
148 
149         loadPageVerifyTitle2(html);
150     }
151 
152     /**
153      * @throws Exception if the test fails
154      */
155     @Test
156     @Alerts("TypeError")
157     public void moveEnd() throws Exception {
158         final String html = DOCTYPE_HTML
159             + "<html>\n"
160             + "<head>\n"
161             + "  <script>\n"
162             + LOG_TITLE_FUNCTION
163             + "    function test() {\n"
164             + "      try {\n"
165             + "        var f = document.getElementById('foo');\n"
166             + "        f.focus();\n"
167             + "        f.select();\n"
168             + "        var r = document.selection.createRange();\n"
169             + "        log(r.text);\n"
170             + "        r.moveEnd('character', -1);\n"
171             + "        log(r.text);\n"
172             + "        r.moveStart('character');\n"
173             + "        log(r.text);\n"
174             + "      } catch(e) { logEx(e); }\n"
175             + "    }\n"
176             + "  </script>\n"
177             + "</head>\n"
178             + "<body onload='test()'>\n"
179             + "<textarea id='foo'>hello</textarea>\n"
180             + "</body>\n"
181             + "</html>";
182 
183         loadPageVerifyTitle2(html);
184     }
185 
186     /**
187      * @throws Exception if the test fails
188      */
189     @Test
190     @Alerts("TypeError")
191     public void moveOutOfBounds_input() throws Exception {
192         final String html = DOCTYPE_HTML
193             + "<html>\n"
194             + "<head>\n"
195             + "  <script>\n"
196             + LOG_TITLE_FUNCTION
197             + "    function test() {\n"
198             + "      try {\n"
199             + "        var f = document.getElementById('foo');\n"
200             + "        f.focus();\n"
201             + "        f.select();\n"
202             + "        var r = document.selection.createRange();\n"
203             + "        log(r.text);\n"
204             + "        r.moveEnd('character', -1);\n"
205             + "        log(r.text);\n"
206             + "        r.moveStart('character');\n"
207             + "        log(r.text);\n"
208             + "        log(r.moveEnd('character', 100));\n"
209             + "        log(r.moveStart('character', -100));\n"
210             + "        log(r.text);\n"
211             + "      } catch(e) { logEx(e); }\n"
212             + "    }\n"
213             + "  </script>\n"
214             + "</head>\n"
215             + "<body onload='test()'>\n"
216             + "<input id='foo' value='hello'/>\n"
217             + "</body>\n"
218             + "</html>";
219 
220         loadPageVerifyTitle2(html);
221     }
222 
223     /**
224      * @throws Exception if the test fails
225      */
226     @Test
227     @Alerts("TypeError")
228     public void inRange() throws Exception {
229         final String html = DOCTYPE_HTML
230             + "<html>\n"
231             + "<head>\n"
232             + "  <script>\n"
233             + LOG_TITLE_FUNCTION
234             + "    function test() {\n"
235             + "      try {\n"
236             + "        var r1 = document.body.createTextRange();\n"
237             + "        var r2 = r1.duplicate();\n"
238             + "        log(r1.inRange(r2));\n"
239             + "        log(r2.inRange(r1));\n"
240             + "        r1.collapse();\n"
241             + "        log(r1.inRange(r2));\n"
242             + "        log(r2.inRange(r1));\n"
243             + "      } catch(e) { logEx(e); }\n"
244             + "    }\n"
245             + "  </script>\n"
246             + "</head>\n"
247             + "<body onload='test()'>\n"
248             + "<textarea id='foo'>hello</textarea>\n"
249             + "</body>\n"
250             + "</html>";
251 
252         loadPageVerifyTitle2(html);
253     }
254 
255     /**
256      * Regression test for
257      * <a href="http://sourceforge.net/support/tracker.php?aid=2836591">Bug 2836591</a>.
258      * @throws Exception if the test fails
259      */
260     @Test
261     @Alerts("TypeError")
262     public void inRange2() throws Exception {
263         final String html = DOCTYPE_HTML
264             + "<html><body>\n"
265             + "<form name='f'><input name='q' value=''></form>\n"
266             + "<script>\n"
267             + LOG_TITLE_FUNCTION
268             + "  try {\n"
269             + "    var range = document.f.q.createTextRange();\n"
270             + "    var selectionRange = document.selection.createRange();\n"
271             + "    log(range.inRange(selectionRange));\n"
272             + "  } catch(e) { logEx(e); }\n"
273             + "</script>\n"
274             + "</body></html>";
275 
276         loadPageVerifyTitle2(html);
277     }
278 
279     /**
280      * @throws Exception if an error occurs
281      */
282     @Test
283     @Alerts("TypeError")
284     public void moveToElementText() throws Exception {
285         final String html = DOCTYPE_HTML
286             + "<html><body onload='test()'>\n"
287             + "<span id='s1'>abc</span><span id='s2'>xyz</span><span id='s3'>foo</span>\n"
288             + "<script>\n"
289             + LOG_TITLE_FUNCTION
290             + "  function test() {\n"
291             + "    try {\n"
292             + "      var r = document.selection.createRange();\n"
293             + "      r.moveToElementText(document.getElementById('s3'));\n"
294             + "      log(r.parentElement().id + ' ' + r.text + ' ' + r.htmlText);\n"
295             + "    } catch(e) { logEx(e); }\n"
296             + "  }\n"
297             + "</script>\n"
298             + "</body></html>";
299 
300         loadPageVerifyTitle2(html);
301     }
302 
303     /**
304      * @throws Exception if an error occurs
305      */
306     @Test
307     @Alerts("TypeError")
308     public void setEndRange() throws Exception {
309         final String html = DOCTYPE_HTML
310             + "<html><body>\n"
311             + "<form name='f'><input name='q' value='hello world'></form>\n"
312             + "<script>\n"
313             + LOG_TITLE_FUNCTION
314             + "  try {\n"
315             + "    var range1 = document.f.q.createTextRange();\n"
316             + "    var range2 = range1.duplicate();\n"
317             + "    range1.moveEnd('character', -6);\n"
318             + "    log(range1.text);\n"
319             + "    range2.moveStart('character', 6);\n"
320             + "    log(range2.text);\n"
321             + "    var r3 = range1.duplicate();\n"
322             + "    r3.setEndPoint('EndToEnd', range2);\n"
323             + "    log(r3.text);\n"
324             + "  } catch(e) { logEx(e); }\n"
325             + "</script>\n"
326             + "</body></html>";
327         loadPageVerifyTitle2(html);
328     }
329 
330     /**
331      * @throws Exception if an error occurs
332      */
333     @Test
334     @Alerts("TypeError")
335     public void createRangeParentElement() throws Exception {
336         final String html = DOCTYPE_HTML
337             + "<html><body>\n"
338             + "<script>\n"
339             + LOG_TITLE_FUNCTION
340             + "  try {\n"
341             + "    s = document.selection.createRange();\n"
342             + "    p = s.parentElement();\n"
343             + "    log(p.tagName);\n"
344             + "  } catch(e) { logEx(e); }\n"
345             + "</script>\n"
346             + "</body></html>";
347 
348         loadPageVerifyTitle2(html);
349     }
350 
351     /**
352      * @throws Exception if an error occurs
353      */
354     @Test
355     @Alerts("TypeError")
356     public void createRangeHtmlText() throws Exception {
357         final String html = DOCTYPE_HTML
358             + "<html><body>\n"
359             + "<script>\n"
360             + LOG_TITLE_FUNCTION
361             + "  try {\n"
362             + "    s = document.selection.createRange();\n"
363             + "    t = s.htmlText;\n"
364             + "    log(t);\n"
365             + "  } catch(e) { logEx(e); }\n"
366             + "</script>\n"
367             + "</body></html>";
368 
369         loadPageVerifyTitle2(html);
370     }
371 
372     /**
373      * @throws Exception if an error occurs
374      */
375     @Test
376     @Alerts("TypeError")
377     public void moveToBookmark() throws Exception {
378         final String html = DOCTYPE_HTML
379             + "<html><body>\n"
380             + "<script>\n"
381             + LOG_TITLE_FUNCTION
382             + "  try {\n"
383             + "    var rng = document.body.createTextRange();\n"
384             + "    rng.moveToBookmark(rng.getBookmark());\n"
385             + "    log('ok');\n"
386             + "  } catch(e) { logEx(e); }\n"
387             + "</script>\n"
388             + "</body></html>";
389 
390         loadPageVerifyTitle2(html);
391     }
392 
393     /**
394      * @throws Exception if the test fails
395      */
396     @Test
397     public void compareEndPoints() throws Exception {
398         final String html = DOCTYPE_HTML
399             + "<html>\n"
400             + "<head>\n"
401             + "  <script>\n"
402             + LOG_TITLE_FUNCTION
403             + "    function test() {\n"
404             + "      if (document.selection) {\n"
405             + "        var r1 = document.selection.createRange();\n"
406             + "        var r2 = document.selection.createRange();\n"
407             + "        log(r1.compareEndPoints('StartToStart', r2));\n"
408             + "      }\n"
409             + "    }\n"
410             + "  </script>\n"
411             + "</head>\n"
412             + "<body onload='test()'>\n"
413             + "</body>\n"
414             + "</html>";
415 
416         loadPageVerifyTitle2(html);
417     }
418 
419 }