~testplan-team/testplan/source-collection

« back to all changes in this revision

Viewing changes to htmlunit-2.4/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/HTMLFormElement.java

  • Committer: edA-qa mort-ora-y
  • Date: 2010-04-07 10:54:57 UTC
  • Revision ID: eda-qa@disemia.com-20100407105457-g46bvbsrjqtjujab
updating hmltunit src

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (c) 2002-2008 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
 
 * http://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 com.gargoylesoftware.htmlunit.javascript.host;
16
 
 
17
 
import java.io.IOException;
18
 
import java.util.List;
19
 
 
20
 
import org.mozilla.javascript.Scriptable;
21
 
 
22
 
import com.gargoylesoftware.htmlunit.Page;
23
 
import com.gargoylesoftware.htmlunit.WebAssert;
24
 
import com.gargoylesoftware.htmlunit.html.HtmlButton;
25
 
import com.gargoylesoftware.htmlunit.html.HtmlElement;
26
 
import com.gargoylesoftware.htmlunit.html.HtmlForm;
27
 
import com.gargoylesoftware.htmlunit.html.HtmlImage;
28
 
import com.gargoylesoftware.htmlunit.html.HtmlInput;
29
 
import com.gargoylesoftware.htmlunit.html.HtmlPage;
30
 
import com.gargoylesoftware.htmlunit.html.HtmlSelect;
31
 
import com.gargoylesoftware.htmlunit.html.HtmlTextArea;
32
 
import com.gargoylesoftware.htmlunit.html.SubmittableElement;
33
 
 
34
 
/**
35
 
 * A JavaScript object for a Form.
36
 
 *
37
 
 * @version $Revision: 3969 $
38
 
 * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
39
 
 * @author Daniel Gredler
40
 
 * @author Kent Tong
41
 
 * @author Chris Erskine
42
 
 * @author Marc Guillemot
43
 
 * @author Ahmed Ashour
44
 
 * @author Sudhan Moghe
45
 
 *
46
 
 * @see <a href="http://msdn.microsoft.com/en-us/library/ms535249.aspx">MSDN documentation</a>
47
 
 */
48
 
public class HTMLFormElement extends HTMLElement {
49
 
 
50
 
    private static final long serialVersionUID = -1860993922147246513L;
51
 
    private HTMLCollection elements_; // has to be a member to have equality (==) working
52
 
 
53
 
    /**
54
 
     * Creates an instance. A default constructor is required for all JavaScript objects.
55
 
     */
56
 
    public HTMLFormElement() { }
57
 
 
58
 
    /**
59
 
     * JavaScript constructor. This must be declared in every JavaScript file because
60
 
     * the rhino engine won't walk up the hierarchy looking for constructors.
61
 
     */
62
 
    public final void jsConstructor() {
63
 
    }
64
 
 
65
 
    /**
66
 
     * {@inheritDoc}
67
 
     */
68
 
    @Override
69
 
    public void setHtmlElement(final HtmlElement htmlElement) {
70
 
        super.setHtmlElement(htmlElement);
71
 
        final HtmlForm htmlForm = getHtmlForm();
72
 
        htmlForm.setScriptObject(this);
73
 
    }
74
 
 
75
 
    /**
76
 
     * Returns the value of the JavaScript attribute "name".
77
 
     * @return the value of this attribute
78
 
     */
79
 
    public String jsxGet_name() {
80
 
        return getHtmlForm().getNameAttribute();
81
 
    }
82
 
 
83
 
    /**
84
 
     * Sets the value of the JavaScript attribute "name".
85
 
     * @param name the new value
86
 
     */
87
 
    public void jsxSet_name(final String name) {
88
 
        WebAssert.notNull("name", name);
89
 
        getHtmlForm().setNameAttribute(name);
90
 
    }
91
 
 
92
 
    /**
93
 
     * Returns the value of the JavaScript attribute "elements".
94
 
     * @return the value of this attribute
95
 
     */
96
 
    public HTMLCollection jsxGet_elements() {
97
 
        if (elements_ == null) {
98
 
            final HtmlForm htmlForm = getHtmlForm();
99
 
 
100
 
            elements_ = new HTMLCollection(this) {
101
 
                private static final long serialVersionUID = -2554743215194459203L;
102
 
 
103
 
                @Override
104
 
                protected List<Object> computeElements() {
105
 
                    final List<Object> response = super.computeElements();
106
 
                    response.addAll(htmlForm.getLostChildren());
107
 
                    return response;
108
 
                }
109
 
            };
110
 
            final String xpath = ".//*[(name() = 'input' or name() = 'button'"
111
 
                    + " or name() = 'select' or name() = 'textarea')]";
112
 
            elements_.init(htmlForm, xpath);
113
 
 
114
 
        }
115
 
        return elements_;
116
 
    }
117
 
 
118
 
    /**
119
 
     * Returns the value of the JavaScript attribute "length".
120
 
     * Does not count input type=image elements as browsers (IE6, Mozilla 1.7) do
121
 
     * (cf <a href="http://msdn.microsoft.com/en-us/library/ms534101.aspx">MSDN doc</a>)
122
 
     * @return the value of this attribute
123
 
     */
124
 
    public int jsxGet_length() {
125
 
        final int all = jsxGet_elements().jsxGet_length();
126
 
        final int images = getHtmlForm().getElementsByAttribute("input", "type", "image").size();
127
 
        return all - images;
128
 
    }
129
 
 
130
 
    /**
131
 
     * Returns the value of the JavaScript attribute "action".
132
 
     * @return the value of this attribute
133
 
     */
134
 
    public String jsxGet_action() {
135
 
        return getHtmlForm().getActionAttribute();
136
 
    }
137
 
 
138
 
    /**
139
 
     * Sets the value of the JavaScript attribute "action".
140
 
     * @param action the new value
141
 
     */
142
 
    public void jsxSet_action(final String action) {
143
 
        WebAssert.notNull("action", action);
144
 
        getHtmlForm().setActionAttribute(action);
145
 
    }
146
 
 
147
 
    /**
148
 
     * Returns the value of the JavaScript attribute "method".
149
 
     * @return the value of this attribute
150
 
     */
151
 
    public String jsxGet_method() {
152
 
        return getHtmlForm().getMethodAttribute();
153
 
    }
154
 
 
155
 
    /**
156
 
     * Sets the value of the JavaScript attribute "method".
157
 
     * @param method the new value
158
 
     */
159
 
    public void jsxSet_method(final String method) {
160
 
        WebAssert.notNull("method", method);
161
 
        getHtmlForm().setMethodAttribute(method);
162
 
    }
163
 
 
164
 
    /**
165
 
     * Returns the value of the JavaScript attribute "target".
166
 
     * @return the value of this attribute
167
 
     */
168
 
    public String jsxGet_target() {
169
 
        return getHtmlForm().getTargetAttribute();
170
 
    }
171
 
 
172
 
    /**
173
 
     * Returns the <tt>onsubmit</tt> event handler for this element.
174
 
     * @return the <tt>onsubmit</tt> event handler for this element
175
 
     */
176
 
    public Object jsxGet_onsubmit() {
177
 
        return getEventHandlerProp("onsubmit");
178
 
    }
179
 
 
180
 
    /**
181
 
     * Sets the <tt>onsubmit</tt> event handler for this element.
182
 
     * @param onsubmit the <tt>onsubmit</tt> event handler for this element
183
 
     */
184
 
    public void jsxSet_onsubmit(final Object onsubmit) {
185
 
        setEventHandlerProp("onsubmit", onsubmit);
186
 
    }
187
 
 
188
 
    /**
189
 
     * Sets the value of the JavaScript attribute "target".
190
 
     * @param target the new value
191
 
     */
192
 
    public void jsxSet_target(final String target) {
193
 
        WebAssert.notNull("target", target);
194
 
        getHtmlForm().setTargetAttribute(target);
195
 
    }
196
 
 
197
 
    /**
198
 
     * Returns the value of the JavaScript attribute "encoding".
199
 
     * @return the value of this attribute
200
 
     */
201
 
    public String jsxGet_encoding() {
202
 
        return getHtmlForm().getEnctypeAttribute();
203
 
    }
204
 
 
205
 
    /**
206
 
     * Sets the value of the JavaScript attribute "encoding".
207
 
     * @param encoding the new value
208
 
     */
209
 
    public void jsxSet_encoding(final String encoding) {
210
 
        WebAssert.notNull("encoding", encoding);
211
 
        getHtmlForm().setEnctypeAttribute(encoding);
212
 
    }
213
 
 
214
 
    private HtmlForm getHtmlForm() {
215
 
        return (HtmlForm) getHtmlElementOrDie();
216
 
    }
217
 
 
218
 
    /**
219
 
     * Submits the form.
220
 
     *
221
 
     * @throws IOException if an io error occurs
222
 
     */
223
 
    public void jsxFunction_submit() throws IOException {
224
 
        getHtmlForm().submit((SubmittableElement) null);
225
 
    }
226
 
 
227
 
    /**
228
 
     * Resets this form.
229
 
     */
230
 
    public void jsxFunction_reset() {
231
 
        getHtmlForm().reset();
232
 
    }
233
 
 
234
 
    /**
235
 
     * Overridden to allow the retrieval of certain form elements by ID or name.
236
 
     *
237
 
     * @param name {@inheritDoc}
238
 
     * @return {@inheritDoc}
239
 
     */
240
 
    @Override
241
 
    protected Object getWithPreemption(final String name) {
242
 
        final HtmlForm form = getHtmlForm();
243
 
        final Page page = form.getPage();
244
 
        if (page instanceof HtmlPage) {
245
 
            // Try to satisfy this request using a map-backed operation before punting and using XPath.
246
 
            // XPath operations are very expensive, and this method gets invoked quite a bit.
247
 
            // Approach: Try to match the string to a name or ID, accepting only inputs (not type=image),
248
 
            // buttons, selects and textareas that are in this form. We also include img elements
249
 
            // (the second XPath search below) in the search, because any results with more than one element
250
 
            // will end up using the XPath search anyway, so it doesn't hurt when looking for single elements.
251
 
            final List<HtmlElement> elements = ((HtmlPage) page).getElementsByIdAndOrName(name);
252
 
            if (elements.isEmpty()) {
253
 
                return NOT_FOUND;
254
 
            }
255
 
            if (elements.size() == 1) {
256
 
                final HtmlElement element = elements.get(0);
257
 
                final String tagName = element.getTagName();
258
 
                final String type = element.getAttribute("type").toLowerCase();
259
 
                if ((HtmlInput.TAG_NAME.equals(tagName) && !"image".equals(type))
260
 
                        || HtmlButton.TAG_NAME.equals(tagName)
261
 
                        || HtmlSelect.TAG_NAME.equals(tagName)
262
 
                        || HtmlTextArea.TAG_NAME.equals(tagName)
263
 
                        || HtmlImage.TAG_NAME.equals(tagName)) {
264
 
                    if (form.isAncestorOf(element) || form.getLostChildren().contains(element)) {
265
 
                        return getScriptableFor(element);
266
 
                    }
267
 
                }
268
 
                else {
269
 
                    return NOT_FOUND;
270
 
                }
271
 
            }
272
 
        }
273
 
        // The shortcut wasn't enough, which means we probably need to perform the XPath operation anyway.
274
 
        // Note that the XPath expression below HAS TO MATCH the tag name checks performed in the shortcut above.
275
 
        // Approach: Try to match the string to a name or ID, accepting only inputs (not type=image),
276
 
        // buttons, selects and textareas that are in this form. We *don't* include img elements, which will
277
 
        // only be searched if the first search fails.
278
 
        HTMLCollection collection = new HTMLCollection(this);
279
 
        final String xpath = ".//*[(@name = '" + name + "' or @id = '" + name + "')"
280
 
            + " and ((name() = 'input' and translate(@type, 'IMAGE', 'image') != 'image') or name() = 'button'"
281
 
            + " or name() = 'select' or name() = 'textarea')]";
282
 
        collection.init(form, xpath);
283
 
        int length = collection.jsxGet_length();
284
 
        // If no form fields are found, IE and Firefox are able to find img elements by ID or name.
285
 
        if (length == 0) {
286
 
            collection = new HTMLCollection(this);
287
 
            final String xpath2 = ".//*[(@name = '" + name + "' or @id = '" + name + "')"
288
 
                + " and name() = 'img']";
289
 
            collection.init(form, xpath2);
290
 
        }
291
 
        // Return whatever we have at this point.
292
 
        Object result = collection;
293
 
        length = collection.jsxGet_length();
294
 
        if (length == 0) {
295
 
            result = NOT_FOUND;
296
 
        }
297
 
        else if (length == 1) {
298
 
            result = collection.get(0, collection);
299
 
        }
300
 
        return result;
301
 
    }
302
 
 
303
 
    /**
304
 
     * Returns the specified indexed property.
305
 
     * @param index the index of the property
306
 
     * @param start the scriptable object that was originally queried for this property
307
 
     * @return the property
308
 
     */
309
 
    @Override
310
 
    public Object get(final int index, final Scriptable start) {
311
 
        if (getDomNodeOrNull() == null) {
312
 
            return NOT_FOUND; // typically for the prototype
313
 
        }
314
 
        return jsxGet_elements().get(index, ((HTMLFormElement) start).jsxGet_elements());
315
 
    }
316
 
}