Chromium Code Reviews| Index: Source/core/dom/DOMURLSearchParams.cpp |
| diff --git a/Source/core/dom/DOMURLSearchParams.cpp b/Source/core/dom/DOMURLSearchParams.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..fbfc6f495af6775eb89c78942d82b82d636a969d |
| --- /dev/null |
| +++ b/Source/core/dom/DOMURLSearchParams.cpp |
| @@ -0,0 +1,224 @@ |
| +/* |
| + * Copyright (c) 2014, Opera Software ASA. All rights reserved. |
| + * |
| + * Redistribution and use in source and binary forms, with or without |
| + * modification, are permitted provided that the following conditions |
| + * are met: |
| + * 1. Redistributions of source code must retain the above copyright |
| + * notice, this list of conditions and the following disclaimer. |
| + * 2. Redistributions in binary form must reproduce the above copyright |
| + * notice, this list of conditions and the following disclaimer in the |
| + * documentation and/or other materials provided with the distribution. |
| + * 3. Neither the name of Opera Software ASA nor the names of its |
| + * contributors may be used to endorse or promote products derived |
| + * from this software without specific prior written permission. |
| + * |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
| + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
| + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
| + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
| + * OF THE POSSIBILITY OF SUCH DAMAGE. |
| + */ |
| + |
| +#include "config.h" |
| +#include "core/dom/DOMURLSearchParams.h" |
| + |
| +#include "core/dom/DOMURLUtils.h" |
| +#include "platform/weborigin/KURL.h" |
| +#include "wtf/text/StringBuilder.h" |
| +#include "wtf/text/TextEncoding.h" |
| + |
| +namespace WebCore { |
| + |
| +DOMURLSearchParams::DOMURLSearchParams() |
| + : m_urlObject(0) |
| + , m_isUpdating(false) |
| +{ |
| + ScriptWrappable::init(this); |
| +} |
| + |
| +void DOMURLSearchParams::runUpdateSteps() |
| +{ |
| + if (m_urlObject) { |
| + m_isUpdating = true; |
| + DOMURLUtils::setSearch(m_urlObject, toString()); |
| + m_isUpdating = false; |
| + } |
| +} |
| + |
| +static String decodeString(String input) |
| +{ |
| + return decodeURLEscapeSequences(input.replace('+', ' ')); |
| +} |
| + |
| +void DOMURLSearchParams::setInput(const String& queryString) |
| +{ |
| + if (m_isUpdating) |
| + return; |
| + |
| + m_params.clear(); |
| + unsigned start = 0; |
| + unsigned queryStringLength = queryString.length(); |
| + while (start < queryStringLength) { |
| + size_t nameStart = start; |
| + size_t nameValueEnd = queryString.find('&', start); |
| + if (nameValueEnd == kNotFound) |
| + nameValueEnd = queryStringLength; |
| + |
| + if (nameValueEnd > start) { |
| + size_t endOfName = queryString.find('=', start); |
| + |
| + if (endOfName == kNotFound || endOfName > nameValueEnd) |
| + endOfName = nameValueEnd; |
| + |
| + String name = decodeString(queryString.substring(nameStart, endOfName - nameStart)); |
| + |
| + bool validUTF8 = true; |
| + if (!name.isEmpty()) { |
| + name = name.utf8(StrictUTF8Conversion).data(); |
| + validUTF8 = !name.isEmpty(); |
| + } |
| + |
| + String value; |
| + if (validUTF8 && endOfName != nameValueEnd) { |
| + value = decodeString(queryString.substring(endOfName + 1, nameValueEnd - endOfName - 1)); |
| + if (!value.isEmpty()) { |
| + value = value.utf8(StrictUTF8Conversion).data(); |
| + validUTF8 = !value.isEmpty(); |
| + } |
| + } |
| + if (validUTF8 && value.isNull()) |
| + value = ""; |
| + |
| + if (validUTF8) |
| + m_params.append(std::make_pair(name, value)); |
| + } |
| + start = nameValueEnd + 1; |
| + } |
| +} |
| + |
| +PassRefPtr<DOMURLSearchParams> DOMURLSearchParams::create(const String& queryString) |
| +{ |
| + RefPtr<DOMURLSearchParams> searchParams = adoptRef(new DOMURLSearchParams()); |
| + if (queryString.isEmpty()) |
| + return searchParams; |
| + |
| + searchParams->setInput(queryString); |
| + return searchParams; |
|
Inactive
2014/01/20 22:06:12
.release()
sof
2014/01/21 13:20:11
Done.
|
| +} |
| + |
| +PassRefPtr<DOMURLSearchParams> DOMURLSearchParams::create(DOMURLSearchParams* init) |
| +{ |
| + RefPtr<DOMURLSearchParams> searchParams = adoptRef(new DOMURLSearchParams()); |
| + if (!init) |
| + return searchParams; |
|
Inactive
2014/01/20 22:06:12
.release()
sof
2014/01/21 13:20:11
Done.
|
| + |
| + searchParams->m_params = init->m_params; |
| + return searchParams; |
|
Inactive
2014/01/20 22:06:12
.release()
sof
2014/01/21 13:20:11
Done.
|
| +} |
| + |
| +static String encodeString(const String& input) |
| +{ |
| + String escaped = encodeWithURLEscapeSequences(input); |
| + // Encode "%20" as "*"; as required and much prettier. |
| + escaped.replace("%20", "+"); |
|
Inactive
2014/01/20 22:06:12
nit: Can return here directly.
sof
2014/01/21 13:20:11
Done.
|
| + return escaped; |
| +} |
| + |
| +String DOMURLSearchParams::toString() const |
| +{ |
| + StringBuilder result; |
| + bool isFirst = true; |
| + for (Vector<std::pair<String, String> >::const_iterator it = m_params.begin(); it != m_params.end(); ++it) { |
| + String name = encodeString(it->first); |
| + if (!name.isEmpty()) { |
| + if (!isFirst) |
| + result.append('&'); |
| + else |
| + isFirst = false; |
| + |
| + result.append(name); |
| + String value = encodeString(it->second); |
| + if (!value.isEmpty()) { |
| + result.append('='); |
| + result.append(value); |
| + } |
| + } |
| + } |
| + return result.toString(); |
| +} |
| + |
| +void DOMURLSearchParams::appendNameValue(const String& name, const String& value) |
| +{ |
| + m_params.append(std::make_pair(name, value)); |
| + runUpdateSteps(); |
| +} |
| + |
| +void DOMURLSearchParams::deleteAllWithName(const String& name) |
| +{ |
| + for (unsigned i = 0; i < m_params.size();) { |
| + if (m_params[i].first == name) |
| + m_params.remove(i); |
| + else |
| + i++; |
| + } |
| + runUpdateSteps(); |
| +} |
| + |
| +String DOMURLSearchParams::getFirstValue(const String& name) const |
| +{ |
| + for (Vector<std::pair<String, String> >::const_iterator it = m_params.begin(); it != m_params.end(); ++it) { |
| + if (it->first == name) |
| + return it->second; |
| + } |
| + return String(); |
| +} |
| + |
| +Vector<String> DOMURLSearchParams::getAllValues(const String& name) const |
| +{ |
| + Vector<String> result; |
| + for (Vector<std::pair<String, String> >::const_iterator it = m_params.begin(); it != m_params.end(); ++it) { |
| + if (it->first == name) |
| + result.append(it->second); |
| + } |
| + return result; |
| +} |
| + |
| +bool DOMURLSearchParams::hasName(const String& name) const |
| +{ |
| + for (Vector<std::pair<String, String> >::const_iterator it = m_params.begin(); it != m_params.end(); ++it) { |
| + if (it->first == name) |
| + return true; |
| + } |
| + return false; |
| +} |
| + |
| +void DOMURLSearchParams::setNameValue(const String& name, const String& value) |
| +{ |
| + bool foundMatch = false; |
| + for (unsigned i = 0; i < m_params.size();) { |
| + if (m_params[i].first == name) { |
| + if (!foundMatch) { |
| + m_params[i++].second = value; |
| + foundMatch = true; |
| + } else { |
| + m_params.remove(i); |
| + } |
| + } else { |
| + i++; |
| + } |
| + } |
| + if (!foundMatch) |
| + appendNameValue(name, value); |
| + else |
| + runUpdateSteps(); |
| +} |
| + |
| +} // namespace WebCore |