Skip to content

Commit

Permalink
Update <a>/<area> API to match current specs
Browse files Browse the repository at this point in the history
This fixes several issues:

- Changing the pathname should update the href
- Empty string host values should be treated like null
- Setting username/password/port of a file: URL should not work
- Setting the port to an empty string should remove the port
- Setting the fragment of javascript: URLs should work
  • Loading branch information
rklfss authored and domenic committed Apr 24, 2017
1 parent fa74ef9 commit 3aca01a
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 24 deletions.
69 changes: 45 additions & 24 deletions lib/jsdom/living/nodes/HTMLHyperlinkElementUtils-impl.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ exports.implementation = class HTMLHyperlinkElementUtilsImpl {
}

get href() {
setTheURL(this);
reinitializeURL(this);
const url = this.url;

if (url === null) {
Expand All @@ -28,7 +28,7 @@ exports.implementation = class HTMLHyperlinkElementUtilsImpl {
}

get origin() {
setTheURL(this);
reinitializeURL(this);

if (this.url === null) {
return "";
Expand All @@ -38,7 +38,7 @@ exports.implementation = class HTMLHyperlinkElementUtilsImpl {
}

get protocol() {
setTheURL(this);
reinitializeURL(this);

if (this.url === null) {
return ":";
Expand All @@ -48,6 +48,8 @@ exports.implementation = class HTMLHyperlinkElementUtilsImpl {
}

set protocol(v) {
reinitializeURL(this);

if (this.url === null) {
return;
}
Expand All @@ -57,7 +59,7 @@ exports.implementation = class HTMLHyperlinkElementUtilsImpl {
}

get username() {
setTheURL(this);
reinitializeURL(this);

if (this.url === null) {
return "";
Expand All @@ -67,9 +69,10 @@ exports.implementation = class HTMLHyperlinkElementUtilsImpl {
}

set username(v) {
reinitializeURL(this);
const url = this.url;

if (url === null || url.host === null || url.cannotBeABaseURL) {
if (url === null || url.host === null || url.host === "" || url.cannotBeABaseURL || url.scheme === "file") {
return;
}

Expand All @@ -78,20 +81,21 @@ exports.implementation = class HTMLHyperlinkElementUtilsImpl {
}

get password() {
setTheURL(this);
reinitializeURL(this);
const url = this.url;

if (url === null || url.password === null) {
if (url === null) {
return "";
}

return url.password;
}

set password(v) {
reinitializeURL(this);
const url = this.url;

if (url === null || url.host === null || url.cannotBeABaseURL) {
if (url === null || url.host === null || url.host === "" || url.cannotBeABaseURL || url.scheme === "file") {
return;
}

Expand All @@ -100,7 +104,7 @@ exports.implementation = class HTMLHyperlinkElementUtilsImpl {
}

get host() {
setTheURL(this);
reinitializeURL(this);
const url = this.url;

if (url === null || url.host === null) {
Expand All @@ -115,7 +119,7 @@ exports.implementation = class HTMLHyperlinkElementUtilsImpl {
}

set host(v) {
setTheURL(this);
reinitializeURL(this);
const url = this.url;

if (url === null || url.cannotBeABaseURL) {
Expand All @@ -127,7 +131,7 @@ exports.implementation = class HTMLHyperlinkElementUtilsImpl {
}

get hostname() {
setTheURL(this);
reinitializeURL(this);
const url = this.url;

if (url === null || url.host === null) {
Expand All @@ -138,7 +142,7 @@ exports.implementation = class HTMLHyperlinkElementUtilsImpl {
}

set hostname(v) {
setTheURL(this);
reinitializeURL(this);
const url = this.url;

if (url === null || url.cannotBeABaseURL) {
Expand All @@ -150,7 +154,7 @@ exports.implementation = class HTMLHyperlinkElementUtilsImpl {
}

get port() {
setTheURL(this);
reinitializeURL(this);
const url = this.url;

if (url === null || url.port === null) {
Expand All @@ -161,19 +165,23 @@ exports.implementation = class HTMLHyperlinkElementUtilsImpl {
}

set port(v) {
setTheURL(this);
reinitializeURL(this);
const url = this.url;

if (url === null || url.host === null || url.cannotBeABaseURL || url.scheme === "file") {
if (url === null || url.host === null || url.host === "" || url.cannotBeABaseURL || url.scheme === "file") {
return;
}

whatwgURL.basicURLParse(v, { url, stateOverride: "port" });
if (v === "") {
url.port = null;
} else {
whatwgURL.basicURLParse(v, { url, stateOverride: "port" });
}
updateHref(this);
}

get pathname() {
setTheURL(this);
reinitializeURL(this);
const url = this.url;

if (url === null) {
Expand All @@ -188,7 +196,7 @@ exports.implementation = class HTMLHyperlinkElementUtilsImpl {
}

set pathname(v) {
setTheURL(this);
reinitializeURL(this);
const url = this.url;

if (url === null || url.cannotBeABaseURL) {
Expand All @@ -197,10 +205,11 @@ exports.implementation = class HTMLHyperlinkElementUtilsImpl {

url.path = [];
whatwgURL.basicURLParse(v, { url, stateOverride: "path start" });
updateHref(this);
}

get search() {
setTheURL(this);
reinitializeURL(this);
const url = this.url;

if (url === null || url.query === null || url.query === "") {
Expand All @@ -211,7 +220,7 @@ exports.implementation = class HTMLHyperlinkElementUtilsImpl {
}

set search(v) {
setTheURL(this);
reinitializeURL(this);
const url = this.url;

if (url === null) {
Expand All @@ -223,13 +232,17 @@ exports.implementation = class HTMLHyperlinkElementUtilsImpl {
} else {
const input = v[0] === "?" ? v.substring(1) : v;
url.query = "";
whatwgURL.basicURLParse(input, { url, stateOverride: "query" });
whatwgURL.basicURLParse(input, {
url,
stateOverride: "query",
encodingOverride: this._ownerDocument.charset
});
}
updateHref(this);
}

get hash() {
setTheURL(this);
reinitializeURL(this);
const url = this.url;

if (url === null || url.fragment === null || url.fragment === "") {
Expand All @@ -240,10 +253,10 @@ exports.implementation = class HTMLHyperlinkElementUtilsImpl {
}

set hash(v) {
setTheURL(this);
reinitializeURL(this);
const url = this.url;

if (url === null || url.scheme === "javascript") {
if (url === null) {
return;
}

Expand All @@ -258,6 +271,14 @@ exports.implementation = class HTMLHyperlinkElementUtilsImpl {
}
};

function reinitializeURL(hheu) {
if (hheu.url !== null && hheu.url.scheme === "blob" && hheu.url.cannotBeABaseURL) {
return;
}

setTheURL(hheu);
}

function setTheURL(hheu) {
const href = hheu.getAttribute("href");
if (href === null) {
Expand Down
2 changes: 2 additions & 0 deletions test/web-platform-tests/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@ describe("Web Platform Tests", () => {
// "dom/events/EventTarget-dispatchEvent.html", // we don't support every event interface yet
"dom/events/EventTarget-removeEventListener.html",

"url/url-setters.html",

"FileAPI/fileReader.html",
"FileAPI/historical.html",
// "FileAPI/idlharness.html", // idl should be used here
Expand Down

0 comments on commit 3aca01a

Please sign in to comment.