- Revision
- 202176
- Author
- [email protected]
- Date
- 2016-06-17 13:18:54 -0700 (Fri, 17 Jun 2016)
Log Message
URL hash setter does not remove fragment identifier if argument is an empty string
https://bugs.webkit.org/show_bug.cgi?id=158869
<rdar://problem/26863430>
Reviewed by Darin Adler.
Source/WebCore:
URL hash setter and URLUtils hash setter should remove the fragment identifier
if set to "#" or "":
- https://url.spec.whatwg.org/#dom-url-hash
- https://html.spec.whatwg.org/multipage/semantics.html#dom-hyperlink-hash
This patch aligns our behavior with the specification and with other browsers
(tested Firefox and Chrome).
This patch also updates HTMLAnchorElement to inherit URLUtils to avoid code
duplication. HTMLAnchorElement already implements URLUtils in the IDL, as per
the specification:
- https://html.spec.whatwg.org/multipage/semantics.html#htmlanchorelement
No new tests, rebaselined existing tests.
* html/HTMLAnchorElement.cpp:
(WebCore::HTMLAnchorElement::origin): Deleted.
(WebCore::HTMLAnchorElement::text): Deleted.
(WebCore::HTMLAnchorElement::setText): Deleted.
(WebCore::HTMLAnchorElement::toString): Deleted.
(WebCore::HTMLAnchorElement::isLiveLink): Deleted.
(WebCore::HTMLAnchorElement::sendPings): Deleted.
(WebCore::HTMLAnchorElement::handleClick): Deleted.
(WebCore::HTMLAnchorElement::eventType): Deleted.
(WebCore::HTMLAnchorElement::treatLinkAsLiveForEventType): Deleted.
(WebCore::isEnterKeyKeydownEvent): Deleted.
(WebCore::shouldProhibitLinks): Deleted.
(WebCore::HTMLAnchorElement::willRespondToMouseClickEvents): Deleted.
(WebCore::rootEditableElementMap): Deleted.
(WebCore::HTMLAnchorElement::rootEditableElementForSelectionOnMouseDown): Deleted.
(WebCore::HTMLAnchorElement::clearRootEditableElementForSelectionOnMouseDown): Deleted.
(WebCore::HTMLAnchorElement::setRootEditableElementForSelectionOnMouseDown): Deleted.
* html/HTMLAnchorElement.h:
(WebCore::HTMLAnchorElement::invalidateCachedVisitedLinkHash): Deleted.
* html/URLUtils.h:
(WebCore::URLUtils<T>::setHash):
LayoutTests:
Update existing layout tests now that setting hash to "" or "#" clears
the fragment identifier.
* fast/dom/DOMURL/set-href-attribute-hash-expected.txt:
* fast/dom/DOMURL/set-href-attribute-hash.html:
* fast/dom/HTMLAnchorElement/script-tests/set-href-attribute-hash.js:
* fast/dom/HTMLAnchorElement/set-href-attribute-hash-expected.txt:
Modified Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (202175 => 202176)
--- trunk/LayoutTests/ChangeLog 2016-06-17 19:51:33 UTC (rev 202175)
+++ trunk/LayoutTests/ChangeLog 2016-06-17 20:18:54 UTC (rev 202176)
@@ -1,3 +1,19 @@
+2016-06-17 Chris Dumez <[email protected]>
+
+ URL hash setter does not remove fragment identifier if argument is an empty string
+ https://bugs.webkit.org/show_bug.cgi?id=158869
+ <rdar://problem/26863430>
+
+ Reviewed by Darin Adler.
+
+ Update existing layout tests now that setting hash to "" or "#" clears
+ the fragment identifier.
+
+ * fast/dom/DOMURL/set-href-attribute-hash-expected.txt:
+ * fast/dom/DOMURL/set-href-attribute-hash.html:
+ * fast/dom/HTMLAnchorElement/script-tests/set-href-attribute-hash.js:
+ * fast/dom/HTMLAnchorElement/set-href-attribute-hash-expected.txt:
+
2016-06-17 John Wilander <[email protected]>
Ignore case in the check for security origin inheritance
Modified: trunk/LayoutTests/fast/dom/DOMURL/set-href-attribute-hash-expected.txt (202175 => 202176)
--- trunk/LayoutTests/fast/dom/DOMURL/set-href-attribute-hash-expected.txt 2016-06-17 19:51:33 UTC (rev 202175)
+++ trunk/LayoutTests/fast/dom/DOMURL/set-href-attribute-hash-expected.txt 2016-06-17 20:18:54 UTC (rev 202176)
@@ -15,13 +15,13 @@
Set hash to null
PASS a.href is 'https://www.mydomain.com/path/testurl.html#null'
Set hash to empty string
-PASS a.href is 'https://www.mydomain.com/path/testurl.html#'
+PASS a.href is 'https://www.mydomain.com/path/testurl.html'
Add hash to mailto: protocol
PASS a.href is 'mailto:e-mail_address@goes_here#hash-value'
Add hash to file: protocol
PASS a.href is 'file:///some%20path#hash value'
Set hash to '#'
-PASS a.href is 'http://mydomain.com/#'
+PASS a.href is 'http://mydomain.com/'
Add hash to non-standard protocol
PASS a.href is 'foo:bar#hash'
PASS successfullyParsed is true
Modified: trunk/LayoutTests/fast/dom/DOMURL/set-href-attribute-hash.html (202175 => 202176)
--- trunk/LayoutTests/fast/dom/DOMURL/set-href-attribute-hash.html 2016-06-17 19:51:33 UTC (rev 202175)
+++ trunk/LayoutTests/fast/dom/DOMURL/set-href-attribute-hash.html 2016-06-17 20:18:54 UTC (rev 202176)
@@ -44,7 +44,7 @@
debug("Set hash to empty string");
a.href = ""
a.hash = "";
-shouldBe("a.href", "'https://www.mydomain.com/path/testurl.html#'");
+shouldBe("a.href", "'https://www.mydomain.com/path/testurl.html'");
// Firefox 3.5.2 does not allow setting hash to mailto: scheme, and it should.
debug("Add hash to mailto: protocol");
@@ -62,7 +62,7 @@
debug("Set hash to '#'");
a.href = ""
a.hash = "#";
-shouldBe("a.href", "'http://mydomain.com/#'");
+shouldBe("a.href", "'http://mydomain.com/'");
// Firefox 3.5.2 does not allow setting hash to foo: scheme, and it should.
debug("Add hash to non-standard protocol");
Modified: trunk/LayoutTests/fast/dom/HTMLAnchorElement/script-tests/set-href-attribute-hash.js (202175 => 202176)
--- trunk/LayoutTests/fast/dom/HTMLAnchorElement/script-tests/set-href-attribute-hash.js 2016-06-17 19:51:33 UTC (rev 202175)
+++ trunk/LayoutTests/fast/dom/HTMLAnchorElement/script-tests/set-href-attribute-hash.js 2016-06-17 20:18:54 UTC (rev 202176)
@@ -34,7 +34,7 @@
debug("Set hash to empty string");
a.href = ""
a.hash = "";
-shouldBe("a.href", "'https://www.mydomain.com/path/testurl.html#'");
+shouldBe("a.href", "'https://www.mydomain.com/path/testurl.html'");
// Firefox 3.5.2 does not allow setting hash to mailto: scheme, and it should.
debug("Add hash to mailto: protocol");
@@ -52,7 +52,7 @@
debug("Set hash to '#'");
a.href = ""
a.hash = "#";
-shouldBe("a.href", "'http://mydomain.com/#'");
+shouldBe("a.href", "'http://mydomain.com/'");
// Firefox 3.5.2 does not allow setting hash to foo: scheme, and it should.
debug("Add hash to non-standard protocol");
Modified: trunk/LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-hash-expected.txt (202175 => 202176)
--- trunk/LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-hash-expected.txt 2016-06-17 19:51:33 UTC (rev 202175)
+++ trunk/LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-hash-expected.txt 2016-06-17 20:18:54 UTC (rev 202176)
@@ -14,13 +14,13 @@
Set hash to null
PASS a.href is 'https://www.mydomain.com/path/testurl.html#null'
Set hash to empty string
-PASS a.href is 'https://www.mydomain.com/path/testurl.html#'
+PASS a.href is 'https://www.mydomain.com/path/testurl.html'
Add hash to mailto: protocol
PASS a.href is 'mailto:e-mail_address@goes_here#hash-value'
Add hash to file: protocol
PASS a.href is 'file:///some%20path#hash value'
Set hash to '#'
-PASS a.href is 'http://mydomain.com/#'
+PASS a.href is 'http://mydomain.com/'
Add hash to non-standard protocol
PASS a.href is 'foo:bar#hash'
PASS successfullyParsed is true
Modified: trunk/Source/WebCore/ChangeLog (202175 => 202176)
--- trunk/Source/WebCore/ChangeLog 2016-06-17 19:51:33 UTC (rev 202175)
+++ trunk/Source/WebCore/ChangeLog 2016-06-17 20:18:54 UTC (rev 202176)
@@ -1,3 +1,48 @@
+2016-06-17 Chris Dumez <[email protected]>
+
+ URL hash setter does not remove fragment identifier if argument is an empty string
+ https://bugs.webkit.org/show_bug.cgi?id=158869
+ <rdar://problem/26863430>
+
+ Reviewed by Darin Adler.
+
+ URL hash setter and URLUtils hash setter should remove the fragment identifier
+ if set to "#" or "":
+ - https://url.spec.whatwg.org/#dom-url-hash
+ - https://html.spec.whatwg.org/multipage/semantics.html#dom-hyperlink-hash
+
+ This patch aligns our behavior with the specification and with other browsers
+ (tested Firefox and Chrome).
+
+ This patch also updates HTMLAnchorElement to inherit URLUtils to avoid code
+ duplication. HTMLAnchorElement already implements URLUtils in the IDL, as per
+ the specification:
+ - https://html.spec.whatwg.org/multipage/semantics.html#htmlanchorelement
+
+ No new tests, rebaselined existing tests.
+
+ * html/HTMLAnchorElement.cpp:
+ (WebCore::HTMLAnchorElement::origin): Deleted.
+ (WebCore::HTMLAnchorElement::text): Deleted.
+ (WebCore::HTMLAnchorElement::setText): Deleted.
+ (WebCore::HTMLAnchorElement::toString): Deleted.
+ (WebCore::HTMLAnchorElement::isLiveLink): Deleted.
+ (WebCore::HTMLAnchorElement::sendPings): Deleted.
+ (WebCore::HTMLAnchorElement::handleClick): Deleted.
+ (WebCore::HTMLAnchorElement::eventType): Deleted.
+ (WebCore::HTMLAnchorElement::treatLinkAsLiveForEventType): Deleted.
+ (WebCore::isEnterKeyKeydownEvent): Deleted.
+ (WebCore::shouldProhibitLinks): Deleted.
+ (WebCore::HTMLAnchorElement::willRespondToMouseClickEvents): Deleted.
+ (WebCore::rootEditableElementMap): Deleted.
+ (WebCore::HTMLAnchorElement::rootEditableElementForSelectionOnMouseDown): Deleted.
+ (WebCore::HTMLAnchorElement::clearRootEditableElementForSelectionOnMouseDown): Deleted.
+ (WebCore::HTMLAnchorElement::setRootEditableElementForSelectionOnMouseDown): Deleted.
+ * html/HTMLAnchorElement.h:
+ (WebCore::HTMLAnchorElement::invalidateCachedVisitedLinkHash): Deleted.
+ * html/URLUtils.h:
+ (WebCore::URLUtils<T>::setHash):
+
2016-06-17 John Wilander <[email protected]>
Ignore case in the check for security origin inheritance
Modified: trunk/Source/WebCore/html/HTMLAnchorElement.cpp (202175 => 202176)
--- trunk/Source/WebCore/html/HTMLAnchorElement.cpp 2016-06-17 19:51:33 UTC (rev 202175)
+++ trunk/Source/WebCore/html/HTMLAnchorElement.cpp 2016-06-17 20:18:54 UTC (rev 202176)
@@ -322,193 +322,11 @@
return getAttribute(targetAttr);
}
-String HTMLAnchorElement::hash() const
-{
- String fragmentIdentifier = href().fragmentIdentifier();
- if (fragmentIdentifier.isEmpty())
- return emptyString();
- return AtomicString(String("#" + fragmentIdentifier));
-}
-
-void HTMLAnchorElement::setHash(const String& value)
-{
- URL url = ""
- if (value[0] == '#')
- url.setFragmentIdentifier(value.substring(1));
- else
- url.setFragmentIdentifier(value);
- setHref(url.string());
-}
-
-String HTMLAnchorElement::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());
-}
-
-void HTMLAnchorElement::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 HTMLAnchorElement::username() const
-{
- return href().encodedUser();
-}
-
-void HTMLAnchorElement::setUsername(const String& value)
-{
- URL url = ""
- url.setUser(value);
- setHref(url.string());
-}
-
-String HTMLAnchorElement::password() const
-{
- return href().encodedPass();
-}
-
-void HTMLAnchorElement::setPassword(const String& value)
-{
- URL url = ""
- url.setPass(value);
- setHref(url.string());
-}
-
-String HTMLAnchorElement::hostname() const
-{
- return href().host();
-}
-
-void HTMLAnchorElement::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 HTMLAnchorElement::pathname() const
-{
- return href().path();
-}
-
-void HTMLAnchorElement::setPathname(const String& value)
-{
- URL url = ""
- if (!url.canSetPathname())
- return;
-
- if (value[0] == '/')
- url.setPath(value);
- else
- url.setPath("/" + value);
-
- setHref(url.string());
-}
-
-String HTMLAnchorElement::port() const
-{
- if (href().hasPort())
- return String::number(href().port());
-
- return emptyString();
-}
-
-void HTMLAnchorElement::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.
- unsigned port = value.toUInt();
- if (isDefaultPortForProtocol(port, url.protocol()))
- url.removePort();
- else
- url.setPort(port);
-
- setHref(url.string());
-}
-
-String HTMLAnchorElement::protocol() const
-{
- return href().protocol() + ":";
-}
-
-void HTMLAnchorElement::setProtocol(const String& value)
-{
- URL url = ""
- url.setProtocol(value);
- setHref(url.string());
-}
-
-String HTMLAnchorElement::search() const
-{
- String query = href().query();
- return query.isEmpty() ? emptyString() : "?" + query;
-}
-
String HTMLAnchorElement::origin() const
{
return SecurityOrigin::create(href()).get().toString();
}
-void HTMLAnchorElement::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 HTMLAnchorElement::text()
{
return textContent();
Modified: trunk/Source/WebCore/html/HTMLAnchorElement.h (202175 => 202176)
--- trunk/Source/WebCore/html/HTMLAnchorElement.h 2016-06-17 19:51:33 UTC (rev 202175)
+++ trunk/Source/WebCore/html/HTMLAnchorElement.h 2016-06-17 20:18:54 UTC (rev 202176)
@@ -27,6 +27,7 @@
#include "HTMLElement.h"
#include "HTMLNames.h"
#include "LinkHash.h"
+#include "URLUtils.h"
namespace WebCore {
@@ -55,7 +56,7 @@
// RelationUp = 0x00020000,
};
-class HTMLAnchorElement : public HTMLElement {
+class HTMLAnchorElement : public HTMLElement, public URLUtils<HTMLAnchorElement> {
public:
static Ref<HTMLAnchorElement> create(Document&);
static Ref<HTMLAnchorElement> create(const QualifiedName&, Document&);
@@ -67,33 +68,6 @@
const AtomicString& name() const;
- String hash() const;
- void setHash(const String&);
-
- String host() const;
- void setHost(const String&);
-
- String username() const;
- void setUsername(const String&);
-
- String password() const;
- void setPassword(const String&);
-
- String hostname() const;
- void setHostname(const String&);
-
- String pathname() const;
- void setPathname(const String&);
-
- String port() const;
- void setPort(const String&);
-
- String protocol() const;
- void setProtocol(const String&);
-
- String search() const;
- void setSearch(const String&);
-
String origin() const;
String text();
Modified: trunk/Source/WebCore/html/URLUtils.h (202175 => 202176)
--- trunk/Source/WebCore/html/URLUtils.h 2016-06-17 19:51:33 UTC (rev 202175)
+++ trunk/Source/WebCore/html/URLUtils.h 2016-06-17 20:18:54 UTC (rev 202176)
@@ -284,10 +284,11 @@
void URLUtils<T>::setHash(const String& value)
{
URL url = ""
- if (value[0U] == '#')
- url.setFragmentIdentifier(value.substring(1));
+ String newFragment = value[0U] == '#' ? value.substring(1) : value;
+ if (newFragment.isEmpty())
+ url.removeFragmentIdentifier();
else
- url.setFragmentIdentifier(value);
+ url.setFragmentIdentifier(newFragment);
setHref(url.string());
}