Diff
Modified: trunk/Source/WebCore/ChangeLog (163252 => 163253)
--- trunk/Source/WebCore/ChangeLog 2014-02-02 01:58:16 UTC (rev 163252)
+++ trunk/Source/WebCore/ChangeLog 2014-02-02 02:18:09 UTC (rev 163253)
@@ -1,3 +1,47 @@
+2014-02-01 Maciej Stachowiak <[email protected]>
+
+ Factor URL decomposition methods (from URLUtils interface) into a base template
+ https://bugs.webkit.org/show_bug.cgi?id=128052
+
+ Reviewed by Sam Weinig.
+
+ Refactoring only; no new tests.
+
+ * html/DOMURL.cpp:
+ * html/DOMURL.h:
+ (WebCore::DOMURL::href): Moved to header and made inline.
+ * html/URLUtils.h: Added.
+ (WebCore::URLUtils::href): Downcast and call the derived class.
+ (WebCore::URLUtils::setHref): Downcast and call the derived class.
+ Functions below factored out from DOMURL.cpp.
+ (WebCore::URLUtils<T>::toString):
+ (WebCore::URLUtils<T>::origin):
+ (WebCore::URLUtils<T>::protocol):
+ (WebCore::URLUtils<T>::setProtocol):
+ (WebCore::URLUtils<T>::username):
+ (WebCore::URLUtils<T>::setUsername):
+ (WebCore::URLUtils<T>::password):
+ (WebCore::URLUtils<T>::setPassword):
+ (WebCore::URLUtils<T>::host):
+ (WebCore::parsePortFromStringPosition):
+ (WebCore::URLUtils<T>::setHost):
+ (WebCore::URLUtils<T>::hostname):
+ (WebCore::URLUtils<T>::setHostname):
+ (WebCore::URLUtils<T>::port):
+ (WebCore::URLUtils<T>::setPort):
+ (WebCore::URLUtils<T>::pathname):
+ (WebCore::URLUtils<T>::setPathname):
+ (WebCore::URLUtils<T>::search):
+ (WebCore::URLUtils<T>::setSearch):
+ (WebCore::URLUtils<T>::hash):
+ (WebCore::URLUtils<T>::setHash):
+
+ Add mention of new header.
+ * GNUmakefile.list.am:
+ * WebCore.vcxproj/WebCore.vcxproj:
+ * WebCore.vcxproj/WebCore.vcxproj.filters:
+ * WebCore.xcodeproj/project.pbxproj:
+
2014-02-01 Benjamin Poulain <[email protected]>
Improve the _javascript_ bindings of DatasetDOMStringMap
Modified: trunk/Source/WebCore/GNUmakefile.list.am (163252 => 163253)
--- trunk/Source/WebCore/GNUmakefile.list.am 2014-02-02 01:58:16 UTC (rev 163252)
+++ trunk/Source/WebCore/GNUmakefile.list.am 2014-02-02 02:18:09 UTC (rev 163253)
@@ -3716,6 +3716,7 @@
Source/WebCore/html/URLInputType.cpp \
Source/WebCore/html/URLInputType.h \
Source/WebCore/html/URLRegistry.h \
+ Source/WebCore/html/URLUtils.h \
Source/WebCore/html/ValidationMessage.cpp \
Source/WebCore/html/ValidationMessage.h \
Source/WebCore/html/ValidityState.h \
Modified: trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj (163252 => 163253)
--- trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj 2014-02-02 01:58:16 UTC (rev 163252)
+++ trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj 2014-02-02 02:18:09 UTC (rev 163253)
@@ -20444,6 +20444,7 @@
<ClInclude Include="..\html\TimeRanges.h" />
<ClInclude Include="..\html\TypeAhead.h" />
<ClInclude Include="..\html\URLInputType.h" />
+ <ClInclude Include="..\html\URLUtils.h" />
<ClInclude Include="..\html\ValidationMessage.h" />
<ClInclude Include="..\html\ValidityState.h" />
<ClInclude Include="..\html\VoidCallback.h" />
Modified: trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters (163252 => 163253)
--- trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters 2014-02-02 01:58:16 UTC (rev 163252)
+++ trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters 2014-02-02 02:18:09 UTC (rev 163253)
@@ -11081,6 +11081,9 @@
<ClInclude Include="..\html\URLInputType.h">
<Filter>html</Filter>
</ClInclude>
+ <ClCompile Include="..\html\URLUtils.h">
+ <Filter>html</Filter>
+ </ClCompile>
<ClInclude Include="..\html\ValidationMessage.h">
<Filter>html</Filter>
</ClInclude>
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (163252 => 163253)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2014-02-02 01:58:16 UTC (rev 163252)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2014-02-02 02:18:09 UTC (rev 163253)
@@ -8994,6 +8994,7 @@
656581E909D1508D000E61D7 /* SVGNames.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SVGNames.h; sourceTree = "<group>"; };
656581EA09D1508D000E61D7 /* XLinkNames.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = XLinkNames.cpp; sourceTree = "<group>"; };
656581EB09D1508D000E61D7 /* XLinkNames.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = XLinkNames.h; sourceTree = "<group>"; };
+ 656B9DCA189DE10000BB842C /* URLUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = URLUtils.h; sourceTree = "<group>"; };
656D371A0ADBA5DE00A4554D /* LoaderNSURLExtras.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LoaderNSURLExtras.h; sourceTree = "<group>"; };
656D371B0ADBA5DE00A4554D /* LoaderNSURLExtras.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = LoaderNSURLExtras.mm; sourceTree = "<group>"; };
656D371E0ADBA5DE00A4554D /* DocumentLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DocumentLoader.h; sourceTree = "<group>"; };
@@ -17455,6 +17456,7 @@
F55B3DA91251F12D003EF269 /* URLInputType.cpp */,
F55B3DAA1251F12D003EF269 /* URLInputType.h */,
CDEE393817974274001D7580 /* URLRegistry.h */,
+ 656B9DCA189DE10000BB842C /* URLUtils.h */,
F5A154251279534D00D0B0C0 /* ValidationMessage.cpp */,
F5A154261279534D00D0B0C0 /* ValidationMessage.h */,
15C7708A100D3C6A005BA267 /* ValidityState.h */,
Modified: trunk/Source/WebCore/html/DOMURL.cpp (163252 => 163253)
--- trunk/Source/WebCore/html/DOMURL.cpp 2014-02-02 01:58:16 UTC (rev 163252)
+++ trunk/Source/WebCore/html/DOMURL.cpp 2014-02-02 02:18:09 UTC (rev 163253)
@@ -81,11 +81,6 @@
ec = TypeError;
}
-const URL& DOMURL::href() const
-{
- return m_url;
-}
-
void DOMURL::setHref(const String& url)
{
m_url = URL(m_baseURL, url);
@@ -98,209 +93,7 @@
ec = TypeError;
}
-const String& DOMURL::toString() const
-{
- return href().string();
-}
-String DOMURL::origin() const
-{
- RefPtr<SecurityOrigin> origin = SecurityOrigin::create(href());
- return origin->toString();
-}
-
-String DOMURL::protocol() const
-{
- return href().protocol() + ':';
-}
-
-void DOMURL::setProtocol(const String& value)
-{
- URL url = ""
- url.setProtocol(value);
- setHref(url.string());
-}
-
-String DOMURL::username() const
-{
- return href().user();
-}
-
-void DOMURL::setUsername(const String& user)
-{
- URL url = ""
- url.setUser(user);
- setHref(url);
-}
-
-String DOMURL::password() const
-{
- return href().pass();
-}
-
-void DOMURL::setPassword(const String& pass)
-{
- URL url = ""
- url.setPass(pass);
- setHref(url);
-}
-
-String DOMURL::host() const
-{
- const URL& url = ""
- if (url.hostEnd() == url.pathStart())
- return url.host();
- if (isDefaultPortForProtocol(url.port(), url.protocol()))
- return url.host();
- return url.host() + ':' + String::number(url.port());
-}
-
-// This function does not allow leading spaces before the port number.
-static unsigned parsePortFromStringPosition(const String& value, unsigned portStart, unsigned& portEnd)
-{
- portEnd = portStart;
- while (isASCIIDigit(value[portEnd]))
- ++portEnd;
- return value.substring(portStart, portEnd - portStart).toUInt();
-}
-
-void DOMURL::setHost(const String& value)
-{
- if (value.isEmpty())
- return;
- URL url = ""
- if (!url.canSetHostOrPort())
- return;
-
- size_t separator = value.find(':');
- if (!separator)
- return;
-
- if (separator == notFound)
- url.setHostAndPort(value);
- else {
- unsigned portEnd;
- unsigned port = parsePortFromStringPosition(value, separator + 1, portEnd);
- if (!port) {
- // http://dev.w3.org/html5/spec/infrastructure.html#url-decomposition-idl-attributes
- // specifically goes against RFC 3986 (p3.2) and
- // requires setting the port to "0" if it is set to empty string.
- url.setHostAndPort(value.substring(0, separator + 1) + '0');
- } else {
- if (isDefaultPortForProtocol(port, url.protocol()))
- url.setHostAndPort(value.substring(0, separator));
- else
- url.setHostAndPort(value.substring(0, portEnd));
- }
- }
- setHref(url.string());
-}
-
-String DOMURL::hostname() const
-{
- return href().host();
-}
-
-void DOMURL::setHostname(const String& value)
-{
- // Before setting new value:
- // Remove all leading U+002F SOLIDUS ("/") characters.
- unsigned i = 0;
- unsigned hostLength = value.length();
- while (value[i] == '/')
- i++;
-
- if (i == hostLength)
- return;
-
- URL url = ""
- if (!url.canSetHostOrPort())
- return;
-
- url.setHost(value.substring(i));
- setHref(url.string());
-}
-
-String DOMURL::port() const
-{
- if (href().hasPort())
- return String::number(href().port());
-
- return emptyString();
-}
-
-void DOMURL::setPort(const String& value)
-{
- URL url = ""
- if (!url.canSetHostOrPort())
- return;
-
- // http://dev.w3.org/html5/spec/infrastructure.html#url-decomposition-idl-attributes
- // specifically goes against RFC 3986 (p3.2) and
- // requires setting the port to "0" if it is set to empty string.
- // FIXME: http://url.spec.whatwg.org/ doesn't appear to require this; test what browsers do
- unsigned port = value.toUInt();
- if (isDefaultPortForProtocol(port, url.protocol()))
- url.removePort();
- else
- url.setPort(port);
-
- setHref(url.string());
-}
-
-String DOMURL::pathname() const
-{
- return href().path();
-}
-
-void DOMURL::setPathname(const String& value)
-{
- URL url = ""
- if (!url.canSetPathname())
- return;
-
- if (value[0] == '/')
- url.setPath(value);
- else
- url.setPath("/" + value);
-
- setHref(url.string());
-}
-
-String DOMURL::search() const
-{
- String query = href().query();
- return query.isEmpty() ? emptyString() : "?" + query;
-}
-
-void DOMURL::setSearch(const String& value)
-{
- URL url = ""
- String newSearch = (value[0] == '?') ? value.substring(1) : value;
- // Make sure that '#' in the query does not leak to the hash.
- url.setQuery(newSearch.replaceWithLiteral('#', "%23"));
-
- setHref(url.string());
-}
-
-String DOMURL::hash() const
-{
- String fragmentIdentifier = href().fragmentIdentifier();
- if (fragmentIdentifier.isEmpty())
- return emptyString();
- return AtomicString(String("#" + fragmentIdentifier));
-}
-
-void DOMURL::setHash(const String& value)
-{
- URL url = ""
- if (value[0] == '#')
- url.setFragmentIdentifier(value.substring(1));
- else
- url.setFragmentIdentifier(value);
- setHref(url.string());
-}
-
#if ENABLE(BLOB)
String DOMURL::createObjectURL(ScriptExecutionContext* scriptExecutionContext, Blob* blob)
Modified: trunk/Source/WebCore/html/DOMURL.h (163252 => 163253)
--- trunk/Source/WebCore/html/DOMURL.h 2014-02-02 01:58:16 UTC (rev 163252)
+++ trunk/Source/WebCore/html/DOMURL.h 2014-02-02 02:18:09 UTC (rev 163253)
@@ -29,6 +29,7 @@
#include "ExceptionCode.h"
#include "URL.h"
+#include "URLUtils.h"
#include <wtf/HashSet.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
@@ -40,48 +41,17 @@
class ScriptExecutionContext;
class URLRegistrable;
-class DOMURL : public RefCounted<DOMURL> {
+class DOMURL : public RefCounted<DOMURL>, public URLUtils<DOMURL> {
public:
static PassRefPtr<DOMURL> create(const String& url, const String& base, ExceptionCode&);
static PassRefPtr<DOMURL> create(const String& url, const DOMURL* base, ExceptionCode&);
static PassRefPtr<DOMURL> create(const String& url, ExceptionCode&);
- const URL& href() const;
+ URL href() const { return m_url; }
void setHref(const String& url);
void setHref(const String&, ExceptionCode&);
- const String& toString() const;
- String origin() const;
-
- String protocol() const;
- void setProtocol(const String&);
-
- String username() const;
- void setUsername(const String&);
-
- String password() const;
- void setPassword(const String&);
-
- String host() const;
- void setHost(const String&);
-
- String hostname() const;
- void setHostname(const String&);
-
- String port() const;
- void setPort(const String&);
-
- String pathname() const;
- void setPathname(const String&);
-
- String search() const;
- void setSearch(const String&);
-
- String hash() const;
- void setHash(const String&);
-
-
#if ENABLE(BLOB)
static void contextDestroyed(ScriptExecutionContext*);
Added: trunk/Source/WebCore/html/URLUtils.h (0 => 163253)
--- trunk/Source/WebCore/html/URLUtils.h (rev 0)
+++ trunk/Source/WebCore/html/URLUtils.h 2014-02-02 02:18:09 UTC (rev 163253)
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2014 Apple Inc. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS 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 APPLE OR ITS 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.
+ */
+
+#ifndef URLUtils_h
+#define URLUtils_h
+
+#include "SecurityOrigin.h"
+
+namespace WebCore {
+
+template <typename T>
+class URLUtils {
+public:
+ URL href() const { return static_cast<const T*>(this)->href(); }
+ void setHref(const String& url) { static_cast<T*>(this)->setHref(url); }
+
+ String toString() const;
+
+ String origin() const;
+
+ String protocol() const;
+ void setProtocol(const String&);
+
+ String username() const;
+ void setUsername(const String&);
+
+ String password() const;
+ void setPassword(const String&);
+
+ String host() const;
+ void setHost(const String&);
+
+ String hostname() const;
+ void setHostname(const String&);
+
+ String port() const;
+ void setPort(const String&);
+
+ String pathname() const;
+ void setPathname(const String&);
+
+ String search() const;
+ void setSearch(const String&);
+
+ String hash() const;
+ void setHash(const String&);
+};
+
+template <typename T>
+String URLUtils<T>::toString() const
+{
+ return href().string();
+}
+
+template <typename T>
+String URLUtils<T>::origin() const
+{
+ RefPtr<SecurityOrigin> origin = SecurityOrigin::create(href());
+ return origin->toString();
+}
+
+template <typename T>
+String URLUtils<T>::protocol() const
+{
+ return href().protocol() + ':';
+}
+
+template <typename T>
+void URLUtils<T>::setProtocol(const String& value)
+{
+ URL url = ""
+ url.setProtocol(value);
+ setHref(url.string());
+}
+
+template <typename T>
+String URLUtils<T>::username() const
+{
+ return href().user();
+}
+
+template <typename T>
+void URLUtils<T>::setUsername(const String& user)
+{
+ URL url = ""
+ url.setUser(user);
+ setHref(url);
+}
+
+template <typename T>
+String URLUtils<T>::password() const
+{
+ return href().pass();
+}
+
+template <typename T>
+void URLUtils<T>::setPassword(const String& pass)
+{
+ URL url = ""
+ url.setPass(pass);
+ setHref(url);
+}
+
+template <typename T>
+String URLUtils<T>::host() const
+{
+ const URL& url = ""
+ if (url.hostEnd() == url.pathStart())
+ return url.host();
+ if (isDefaultPortForProtocol(url.port(), url.protocol()))
+ return url.host();
+ return url.host() + ':' + String::number(url.port());
+}
+
+// This function does not allow leading spaces before the port number.
+static inline unsigned parsePortFromStringPosition(const String& value, unsigned portStart, unsigned& portEnd)
+{
+ portEnd = portStart;
+ while (isASCIIDigit(value[portEnd]))
+ ++portEnd;
+ return value.substring(portStart, portEnd - portStart).toUInt();
+}
+
+template <typename T>
+void URLUtils<T>::setHost(const String& value)
+{
+ if (value.isEmpty())
+ return;
+ URL url = ""
+ if (!url.canSetHostOrPort())
+ return;
+
+ size_t separator = value.find(':');
+ if (!separator)
+ return;
+
+ if (separator == notFound)
+ url.setHostAndPort(value);
+ else {
+ unsigned portEnd;
+ unsigned port = parsePortFromStringPosition(value, separator + 1, portEnd);
+ if (!port) {
+ // http://dev.w3.org/html5/spec/infrastructure.html#url-decomposition-idl-attributes
+ // specifically goes against RFC 3986 (p3.2) and
+ // requires setting the port to "0" if it is set to empty string.
+ url.setHostAndPort(value.substring(0, separator + 1) + '0');
+ } else {
+ if (isDefaultPortForProtocol(port, url.protocol()))
+ url.setHostAndPort(value.substring(0, separator));
+ else
+ url.setHostAndPort(value.substring(0, portEnd));
+ }
+ }
+ setHref(url.string());
+}
+
+template <typename T>
+String URLUtils<T>::hostname() const
+{
+ return href().host();
+}
+
+template <typename T>
+void URLUtils<T>::setHostname(const String& value)
+{
+ // Before setting new value:
+ // Remove all leading U+002F SOLIDUS ("/") characters.
+ unsigned i = 0;
+ unsigned hostLength = value.length();
+ while (value[i] == '/')
+ i++;
+
+ if (i == hostLength)
+ return;
+
+ URL url = ""
+ if (!url.canSetHostOrPort())
+ return;
+
+ url.setHost(value.substring(i));
+ setHref(url.string());
+}
+
+template <typename T>
+String URLUtils<T>::port() const
+{
+ if (href().hasPort())
+ return String::number(href().port());
+
+ return emptyString();
+}
+
+template <typename T>
+void URLUtils<T>::setPort(const String& value)
+{
+ URL url = ""
+ if (!url.canSetHostOrPort())
+ return;
+
+ // http://dev.w3.org/html5/spec/infrastructure.html#url-decomposition-idl-attributes
+ // specifically goes against RFC 3986 (p3.2) and
+ // requires setting the port to "0" if it is set to empty string.
+ // FIXME: http://url.spec.whatwg.org/ doesn't appear to require this; test what browsers do
+ unsigned port = value.toUInt();
+ if (isDefaultPortForProtocol(port, url.protocol()))
+ url.removePort();
+ else
+ url.setPort(port);
+
+ setHref(url.string());
+}
+
+template <typename T>
+String URLUtils<T>::pathname() const
+{
+ return href().path();
+}
+
+template <typename T>
+void URLUtils<T>::setPathname(const String& value)
+{
+ URL url = ""
+ if (!url.canSetPathname())
+ return;
+
+ if (value[0] == '/')
+ url.setPath(value);
+ else
+ url.setPath("/" + value);
+
+ setHref(url.string());
+}
+
+template <typename T>
+String URLUtils<T>::search() const
+{
+ String query = href().query();
+ return query.isEmpty() ? emptyString() : "?" + query;
+}
+
+template <typename T>
+void URLUtils<T>::setSearch(const String& value)
+{
+ URL url = ""
+ String newSearch = (value[0] == '?') ? value.substring(1) : value;
+ // Make sure that '#' in the query does not leak to the hash.
+ url.setQuery(newSearch.replaceWithLiteral('#', "%23"));
+
+ setHref(url.string());
+}
+
+template <typename T>
+String URLUtils<T>::hash() const
+{
+ String fragmentIdentifier = href().fragmentIdentifier();
+ if (fragmentIdentifier.isEmpty())
+ return emptyString();
+ return AtomicString(String("#" + fragmentIdentifier));
+}
+
+template <typename T>
+void URLUtils<T>::setHash(const String& value)
+{
+ URL url = ""
+ if (value[0] == '#')
+ url.setFragmentIdentifier(value.substring(1));
+ else
+ url.setFragmentIdentifier(value);
+ setHref(url.string());
+}
+
+} // namespace WebCore
+
+#endif // URLUtils_h