org.htmlunit.javascript.host.xml.FormData Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of xlt Show documentation
Show all versions of xlt Show documentation
XLT (Xceptance LoadTest) is an extensive load and performance test tool developed and maintained by Xceptance.
/*
* Copyright (c) 2002-2024 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.htmlunit.javascript.host.xml;
import static org.htmlunit.BrowserVersionFeatures.JS_FORM_DATA_CONTENT_TYPE_PLAIN_IF_FILE_TYPE_UNKNOWN;
import static org.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
import static org.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static org.htmlunit.javascript.configuration.SupportedBrowser.FF;
import static org.htmlunit.javascript.configuration.SupportedBrowser.FF_ESR;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.htmlunit.FormEncodingType;
import org.htmlunit.WebRequest;
import org.htmlunit.corejs.javascript.Context;
import org.htmlunit.corejs.javascript.ES6Iterator;
import org.htmlunit.corejs.javascript.Function;
import org.htmlunit.corejs.javascript.Scriptable;
import org.htmlunit.corejs.javascript.ScriptableObject;
import org.htmlunit.javascript.HtmlUnitScriptable;
import org.htmlunit.javascript.JavaScriptEngine;
import org.htmlunit.javascript.configuration.JsxClass;
import org.htmlunit.javascript.configuration.JsxConstructor;
import org.htmlunit.javascript.configuration.JsxFunction;
import org.htmlunit.javascript.configuration.JsxSymbol;
import org.htmlunit.javascript.host.file.File;
import org.htmlunit.javascript.host.html.HTMLFormElement;
import org.htmlunit.util.KeyDataPair;
import org.htmlunit.util.MimeType;
import org.htmlunit.util.NameValuePair;
/**
* A JavaScript object for {@code FormData}.
*
* @author Ahmed Ashour
* @author Ronald Brill
* @author Thorsten Wendelmuth
*/
@JsxClass
public class FormData extends HtmlUnitScriptable {
/** Constant used to register the prototype in the context. */
public static final String FORM_DATA_TAG = "FormData";
private final List requestParameters_ = new ArrayList<>();
public static final class FormDataIterator extends ES6Iterator {
enum Type { KEYS, VALUES, BOTH }
private final Type type_;
private final String className_;
private final List nameValuePairList_;
private int index_;
public static void init(final ScriptableObject scope, final String className) {
ES6Iterator.init(scope, false, new FormDataIterator(className), FORM_DATA_TAG);
}
public FormDataIterator(final String className) {
type_ = Type.BOTH;
index_ = 0;
nameValuePairList_ = Collections.emptyList();
className_ = className;
}
public FormDataIterator(final Scriptable scope, final String className, final Type type,
final List nameValuePairList) {
super(scope, FORM_DATA_TAG);
type_ = type;
index_ = 0;
nameValuePairList_ = nameValuePairList;
className_ = className;
}
/**
* {@inheritDoc}
*/
@Override
public String getClassName() {
return className_;
}
/**
* {@inheritDoc}
*/
@Override
protected boolean isDone(final Context cx, final Scriptable scope) {
return index_ >= nameValuePairList_.size();
}
/**
* {@inheritDoc}
*/
@Override
protected Object nextValue(final Context cx, final Scriptable scope) {
if (isDone(cx, scope)) {
return Context.getUndefinedValue();
}
final NameValuePair nextNameValuePair = nameValuePairList_.get(index_++);
switch (type_) {
case KEYS:
return nextNameValuePair.getName();
case VALUES:
return nextNameValuePair.getValue();
case BOTH:
return cx.newArray(scope, new Object[] {nextNameValuePair.getName(), nextNameValuePair.getValue()});
default:
throw new AssertionError();
}
}
}
/**
* Default constructor.
*/
public FormData() {
}
/**
* Constructor.
* @param formObj a form
*/
@JsxConstructor
public void jsConstructor(final Object formObj) {
if (formObj instanceof HTMLFormElement) {
final HTMLFormElement form = (HTMLFormElement) formObj;
requestParameters_.addAll(form.getHtmlForm().getParameterListForSubmit(null));
}
}
/**
* Appends a new value onto an existing key inside a {@code FormData} object,
* or adds the key if it does not already exist.
* @param name the name of the field whose data is contained in {@code value}
* @param value the field's value
* @param filename the filename reported to the server (optional)
*/
@JsxFunction
public void append(final String name, final Object value, final Object filename) {
if (value instanceof File) {
final File file = (File) value;
String fileName = null;
String contentType;
if (filename instanceof String) {
fileName = (String) filename;
}
contentType = file.getType();
if (StringUtils.isEmpty(contentType)) {
if (getBrowserVersion().hasFeature(JS_FORM_DATA_CONTENT_TYPE_PLAIN_IF_FILE_TYPE_UNKNOWN)) {
contentType = MimeType.TEXT_PLAIN;
}
else {
contentType = MimeType.APPLICATION_OCTET_STREAM;
}
}
requestParameters_.add(new KeyDataPair(name, file.getFile(), fileName, contentType, (Charset) null));
}
else {
requestParameters_.add(new NameValuePair(name, JavaScriptEngine.toString(value)));
}
}
/**
* Removes the entry (if exists).
* @param name the name of the field to remove
*/
@JsxFunction(functionName = "delete", value = {CHROME, EDGE, FF, FF_ESR})
public void delete_js(final String name) {
if (StringUtils.isEmpty(name)) {
return;
}
requestParameters_.removeIf(pair -> name.equals(pair.getName()));
}
/**
* @param name the name of the field to check
* @return the first value found for the give name
*/
@JsxFunction({CHROME, EDGE, FF, FF_ESR})
public String get(final String name) {
if (StringUtils.isEmpty(name)) {
return null;
}
for (final NameValuePair pair : requestParameters_) {
if (name.equals(pair.getName())) {
return pair.getValue();
}
}
return null;
}
/**
* @param name the name of the field to check
* @return the values found for the give name
*/
@JsxFunction({CHROME, EDGE, FF, FF_ESR})
public Scriptable getAll(final String name) {
if (StringUtils.isEmpty(name)) {
return JavaScriptEngine.newArray(this, 0);
}
final List