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.html.impl;
16  
17  import org.htmlunit.html.DomNode;
18  
19  /**
20   * Contains standard selection-related functionality used by various input elements.
21   *
22   * <p>From <a href="http://www.whatwg.org/specs/web-apps/current-work/#selection">the HTML5 spec</a>:
23   *
24   * <blockquote>Mostly for historical reasons, in addition to the browsing context's selection, each
25   * textarea and input element has an independent selection. These are the text field selections.</blockquote>
26   *
27   * @author Daniel Gredler
28   * @author Ronald Brill
29   * @author Ahmed Ashour
30   */
31  public class SelectableTextSelectionDelegate implements SelectionDelegate {
32  
33      /** The owner element. */
34      private final SelectableTextInput element_;
35  
36      /** The field selection, which is independent of the browsing context's selection. */
37      private final SimpleRange selection_;
38  
39      /**
40       * Creates a new instance for the specified element.
41       * @param element the owner element
42       */
43      public SelectableTextSelectionDelegate(final SelectableTextInput element) {
44          element_ = element;
45          selection_ = new SimpleRange((DomNode) element, 0);
46      }
47  
48      /**
49       * Focuses the owner element and selects all of its text.
50       */
51      public void select() {
52          element_.focus();
53          setSelectionStart(0);
54          setSelectionEnd(element_.getText().length());
55      }
56  
57      /**
58       * Returns the selected text in the owner element, or {@code null} if there is no selected text.
59       * @return the selected text in the owner element, or {@code null} if there is no selected text
60       */
61      public String getSelectedText() {
62          return selection_.toString();
63      }
64  
65      /**
66       * {@inheritDoc}
67       */
68      @Override
69      public int getSelectionStart() {
70          return selection_.getStartOffset();
71      }
72  
73      /**
74       * {@inheritDoc}
75       */
76      @Override
77      public void setSelectionStart(int selectionStart) {
78          if (selectionStart < 0) {
79              return;
80          }
81  
82          final int length = element_.getText().length();
83          selectionStart = Math.max(0, Math.min(selectionStart, length));
84          selection_.setStart((DomNode) element_, selectionStart);
85          if (selection_.getEndOffset() < selectionStart) {
86              selection_.setEnd((DomNode) element_, selectionStart);
87          }
88      }
89  
90      /**
91       * {@inheritDoc}
92       */
93      @Override
94      public int getSelectionEnd() {
95          return selection_.getEndOffset();
96      }
97  
98      /**
99       * {@inheritDoc}
100      */
101     @Override
102     public void setSelectionEnd(int selectionEnd) {
103         final int length = element_.getText().length();
104         selectionEnd = Math.min(length, Math.max(selectionEnd, 0));
105         selection_.setEnd((DomNode) element_, selectionEnd);
106         if (selection_.getStartOffset() > selectionEnd) {
107             selection_.setStart((DomNode) element_, selectionEnd);
108         }
109     }
110 }