Skip to content

Commit

Permalink
Construct URLSearchParams from sequence initializer.
Browse files Browse the repository at this point in the history
Follow up recent spec addition[1,2] and support sequence<sequence<USVString>>
initializers for URLSearchParams.

1 - whatwg/url#27
2 - whatwg/url#175

R=tyoshino,haraken
BUG=680531

Review-Url: https://codereview.chromium.org/2725593003
Cr-Commit-Position: refs/heads/master@{#453903}
  • Loading branch information
sigbjornf authored and Commit bot committed Mar 1, 2017
1 parent 9d86f02 commit 4c9507d
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,17 @@
}, 'Parse =');

test(function() {
var params = new URLSearchParams('foobar=a\nb');
assert_equals(params.toString(), 'foobar=a%0Ab');
}, 'Parse \\n');
let params = new URLSearchParams([]);
assert_true(params !== null, 'Empty sequence');
assert_equals(params.toString(), '');

params = new URLSearchParams([[1, 2], ['a', 'b']]);
assert_equals(params.toString(), '1=2&a=b');

assert_type_error(() => { new URLSearchParams([[1, 2, 3]]) },
"Sequence elements must be pairs");
}, 'sequence initializer');

</script>
</head>
</html>
4 changes: 2 additions & 2 deletions third_party/WebKit/Source/bindings/core/v8/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,8 @@ bindings_core_generated_union_type_files = [
"$bindings_core_v8_output_dir/StringOrDictionary.h",
"$bindings_core_v8_output_dir/StringOrFloat.cpp",
"$bindings_core_v8_output_dir/StringOrFloat.h",
"$bindings_core_v8_output_dir/USVStringOrURLSearchParams.cpp",
"$bindings_core_v8_output_dir/USVStringOrURLSearchParams.h",
"$bindings_core_v8_output_dir/USVStringSequenceSequenceOrUSVStringOrURLSearchParams.cpp",
"$bindings_core_v8_output_dir/USVStringSequenceSequenceOrUSVStringOrURLSearchParams.h",
"$bindings_core_v8_output_dir/UnrestrictedDoubleOrString.cpp",
"$bindings_core_v8_output_dir/UnrestrictedDoubleOrString.h",
"$bindings_core_v8_output_dir/VideoTrackOrAudioTrackOrTextTrack.cpp",
Expand Down
39 changes: 36 additions & 3 deletions third_party/WebKit/Source/core/dom/URLSearchParams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "core/dom/URLSearchParams.h"

#include <utility>
#include "core/dom/DOMURL.h"
#include "platform/network/FormDataEncoder.h"
#include "platform/weborigin/KURL.h"
Expand Down Expand Up @@ -39,20 +40,47 @@ class URLSearchParamsIterationSource final

} // namespace

URLSearchParams* URLSearchParams::create(const URLSearchParamsInit& init) {
URLSearchParams* URLSearchParams::create(const URLSearchParamsInit& init,
ExceptionState& exceptionState) {
if (init.isUSVString()) {
const String& queryString = init.getAsUSVString();
if (queryString.startsWith('?'))
return new URLSearchParams(queryString.substring(1));
return new URLSearchParams(queryString);
}
// TODO(sof): copy constructor no longer in the spec,
// consider removing.
if (init.isURLSearchParams())
return new URLSearchParams(init.getAsURLSearchParams());

if (init.isUSVStringSequenceSequence()) {
return URLSearchParams::create(init.getAsUSVStringSequenceSequence(),
exceptionState);
}

DCHECK(init.isNull());
return new URLSearchParams(String());
}

URLSearchParams* URLSearchParams::create(const Vector<Vector<String>>& init,
ExceptionState& exceptionState) {
URLSearchParams* instance = new URLSearchParams(String());
if (!init.size())
return instance;
for (unsigned i = 0; i < init.size(); ++i) {
const Vector<String>& pair = init[i];
if (pair.size() != 2) {
exceptionState.throwTypeError(ExceptionMessages::failedToConstruct(
"URLSearchParams",
"Sequence initializer must only contain pair elements"));
return nullptr;
}
instance->appendWithoutUpdate(pair[0], pair[1]);
}
instance->runUpdateSteps();
return instance;
}

URLSearchParams::URLSearchParams(const String& queryString, DOMURL* urlObject)
: m_urlObject(urlObject) {
if (!queryString.isEmpty())
Expand Down Expand Up @@ -112,7 +140,7 @@ void URLSearchParams::setInput(const String& queryString) {
queryString.substring(endOfName + 1, nameValueEnd - endOfName - 1));
if (value.isNull())
value = "";
m_params.push_back(std::make_pair(name, value));
appendWithoutUpdate(name, value);
}
start = nameValueEnd + 1;
}
Expand All @@ -125,8 +153,13 @@ String URLSearchParams::toString() const {
return String(encodedData.data(), encodedData.size());
}

void URLSearchParams::append(const String& name, const String& value) {
void URLSearchParams::appendWithoutUpdate(const String& name,
const String& value) {
m_params.push_back(std::make_pair(name, value));
}

void URLSearchParams::append(const String& name, const String& value) {
appendWithoutUpdate(name, value);
runUpdateSteps();
}

Expand Down
15 changes: 10 additions & 5 deletions third_party/WebKit/Source/core/dom/URLSearchParams.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,23 @@
#ifndef URLSearchParams_h
#define URLSearchParams_h

#include <base/gtest_prod_util.h>
#include <utility>
#include "bindings/core/v8/Iterable.h"
#include "bindings/core/v8/ScriptWrappable.h"
#include "bindings/core/v8/USVStringOrURLSearchParams.h"
#include "bindings/core/v8/USVStringSequenceSequenceOrUSVStringOrURLSearchParams.h"
#include "platform/heap/Handle.h"
#include "platform/network/EncodedFormData.h"
#include "wtf/Forward.h"
#include "wtf/text/WTFString.h"
#include <base/gtest_prod_util.h>
#include <utility>

namespace blink {

class ExceptionState;
class DOMURL;

typedef USVStringOrURLSearchParams URLSearchParamsInit;
typedef USVStringSequenceSequenceOrUSVStringOrURLSearchParams
URLSearchParamsInit;

class CORE_EXPORT URLSearchParams final
: public GarbageCollectedFinalized<URLSearchParams>,
Expand All @@ -29,7 +30,9 @@ class CORE_EXPORT URLSearchParams final
DEFINE_WRAPPERTYPEINFO();

public:
static URLSearchParams* create(const URLSearchParamsInit&);
static URLSearchParams* create(const URLSearchParamsInit&, ExceptionState&);
static URLSearchParams* create(const Vector<Vector<String>>&,
ExceptionState&);

static URLSearchParams* create(const String& queryString,
DOMURL* urlObject = nullptr) {
Expand Down Expand Up @@ -68,6 +71,8 @@ class CORE_EXPORT URLSearchParams final
IterationSource* startIteration(ScriptState*, ExceptionState&) override;
void encodeAsFormData(Vector<char>&) const;

void appendWithoutUpdate(const String& name, const String& value);

Vector<std::pair<String, String>> m_params;

WeakMember<DOMURL> m_urlObject;
Expand Down
5 changes: 3 additions & 2 deletions third_party/WebKit/Source/core/dom/URLSearchParams.idl
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
// https://url.spec.whatwg.org/#interface-urlsearchparams

[
Constructor(optional (USVString or URLSearchParams) init = ""),
Exposed=(Window,Worker)
Constructor(optional (sequence<sequence<USVString>> or USVString or URLSearchParams) init = ""),
Exposed=(Window,Worker),
RaisesException=Constructor,
] interface URLSearchParams {
void append(USVString name, USVString value);
[ImplementedAs=deleteAllWithName] void delete(USVString name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ PasswordCredential* PasswordCredential::create(HTMLFormElement* form,
if (form->enctype() == "multipart/form-data") {
additionalData.setFormData(formData);
} else {
URLSearchParams* params = URLSearchParams::create(URLSearchParamsInit());
URLSearchParams* params = URLSearchParams::create(String());
for (const FormData::Entry* entry : formData->entries()) {
if (entry->isString())
params->append(entry->name().data(), entry->value().data());
Expand Down Expand Up @@ -135,7 +135,7 @@ PassRefPtr<EncodedFormData> PasswordCredential::encodeFormData(
if (m_additionalData.isURLSearchParams()) {
// If |additionalData| is a 'URLSearchParams' object, build a urlencoded
// response.
URLSearchParams* params = URLSearchParams::create(URLSearchParamsInit());
URLSearchParams* params = URLSearchParams::create(String());
URLSearchParams* additionalData = m_additionalData.getAsURLSearchParams();
for (const auto& param : additionalData->params()) {
const String& name = param.first;
Expand Down

0 comments on commit 4c9507d

Please sign in to comment.