-
-
Notifications
You must be signed in to change notification settings - Fork 94
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Meant to be an always-updating version of https://quuz.org/url/liveview2.html. Much code, especially styling, copied from https://github.com/annevk/live-url-viewer. Closes #106.
- Loading branch information
Showing
10 changed files
with
8,913 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,3 +5,4 @@ lib/URLSearchParams.js | |
lib/url-state-machine.js | ||
lib/urlencoded.js | ||
lib/utils.js | ||
live-viewer/whatwg-url.js |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,3 +11,4 @@ lib/URLSearchParams.js | |
lib/url-state-machine.js | ||
lib/urlencoded.js | ||
lib/utils.js | ||
out/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,22 @@ | ||
language: node_js | ||
sudo: false | ||
|
||
language: node_js | ||
node_js: stable | ||
sudo: false | ||
|
||
install: | ||
- yarn | ||
|
||
script: | ||
- yarn lint | ||
- yarn test | ||
|
||
before_deploy: | ||
- bash scripts/deploy-live-viewer.sh | ||
|
||
deploy: | ||
provider: pages | ||
local-dir: out | ||
committer-from-gh: true | ||
skip-cleanup: true | ||
keep-history: true | ||
github-token: $GH_TOKEN |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"env": { | ||
"browser": true | ||
}, | ||
"globals": { | ||
"whatwgURL": false | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
<!doctype html> | ||
<meta charset="utf-8"> | ||
<title>Live URL Viewer</title> | ||
<link rel="stylesheet" href="style.css"> | ||
<script src="whatwg-url.js"></script> | ||
|
||
<h1>Live URL Viewer</h1> | ||
|
||
<p>The output below will display a URL's parsed components from the browser versus those given by | ||
<a href="https://github.com/jsdom/whatwg-url">jsdom/whatwg-url</a>. | ||
|
||
<p>jsdom/whatwg-url closely follows the <a href="http://url.spec.whatwg.org/">URL Standard</a> and | ||
the associated | ||
<a href="https://github.com/w3c/web-platform-tests/tree/master/url">web-platform-tests</a>, so this | ||
serves as a good comparison versus the standard itself. | ||
|
||
<p>The output will be colored <span class="pass">dark green</span> unless a difference occurs | ||
between the two parsers in which case the affected URL component will be colored | ||
<span class="fail">red</span>. | ||
|
||
<form> | ||
<label for="url">URL:</label> | ||
<input id="url" value="https://example.com/" autofocus> | ||
|
||
<label for="base">Base URL:</label> | ||
<input id="base" value="about:blank"> | ||
</form> | ||
|
||
<h2>Browser's URL components</h2> | ||
|
||
<table class="output" id="browser-output"> | ||
<tr id="href"><th>href</th><td></td></tr> | ||
<tr id="protocol"><th>protocol</th><td></td></tr> | ||
<tr id="username"><th>username</th><td></td></tr> | ||
<tr id="password"><th>password</th><td></td></tr> | ||
<tr id="port"><th>port</th><td></td></tr> | ||
<tr id="hostname"><th>hostname</th><td></td></tr> | ||
<tr id="pathname"><th>pathname</th><td></td></tr> | ||
<tr id="search"><th>search</th><td></td></tr> | ||
<tr id="hash"><th>hash</th><td></td></tr> | ||
</table> | ||
|
||
<p class="output error" id="browser-error"></p> | ||
|
||
<h2>jsdom/whatwg-url's components</h2> | ||
|
||
<table class="output" id="jsdom-output"> | ||
<tr id="href"><th>href</th><td></td></tr> | ||
<tr id="protocol"><th>protocol</th><td></td></tr> | ||
<tr id="username"><th>username</th><td></td></tr> | ||
<tr id="password"><th>password</th><td></td></tr> | ||
<tr id="port"><th>port</th><td></td></tr> | ||
<tr id="hostname"><th>hostname</th><td></td></tr> | ||
<tr id="pathname"><th>pathname</th><td></td></tr> | ||
<tr id="search"><th>search</th><td></td></tr> | ||
<tr id="hash"><th>hash</th><td></td></tr> | ||
</table> | ||
|
||
<p class="output error" id="jsdom-error"></p> | ||
|
||
<footer> | ||
<a href="https://github.com/jsdom/whatwg-url/tree/master/live-viewer">Fork me on GitHub!</a> | ||
</footer> | ||
|
||
<iframe hidden id="browser-iframe"></iframe> | ||
|
||
<script src="live-viewer.js"></script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
"use strict"; | ||
(() => { | ||
const urlInput = document.querySelector("#url"); | ||
const baseInput = document.querySelector("#base"); | ||
|
||
// Use an iframe to avoid <base> affecting the main page. This is especially bad in Edge where it | ||
// appears to break Edge's DevTools. | ||
const browserIframeDocument = document.querySelector("#browser-iframe").contentDocument; | ||
const browserAnchor = browserIframeDocument.createElement("a"); | ||
const browserBase = browserIframeDocument.createElement("base"); | ||
browserIframeDocument.head.appendChild(browserBase); | ||
browserIframeDocument.body.appendChild(browserAnchor); | ||
|
||
const components = [ | ||
"href", "protocol", "username", | ||
"password", "port", "hostname", | ||
"pathname", "search", "hash" | ||
]; | ||
|
||
urlInput.addEventListener("input", update); | ||
baseInput.addEventListener("input", update); | ||
setFromFragment(); | ||
update(); | ||
|
||
function update() { | ||
const browserResult = getBrowserResult(); | ||
const jsdomResult = getJsdomResult(); | ||
const mismatchedComponents = getMismatchedComponents(browserResult, jsdomResult); | ||
|
||
setResult("browser", browserResult, mismatchedComponents); | ||
setResult("jsdom", jsdomResult, mismatchedComponents); | ||
updateFragmentForSharing(); | ||
} | ||
|
||
function setResult(kind, result, mismatchedComponents) { | ||
const output = document.querySelector(`#${kind}-output`); | ||
const error = document.querySelector(`#${kind}-error`); | ||
|
||
if (result instanceof Error) { | ||
output.hidden = true; | ||
error.hidden = false; | ||
error.textContent = result.toString(); | ||
} else { | ||
output.hidden = false; | ||
error.hidden = true; | ||
for (const component of components) { | ||
const componentEl = output.querySelector(`#${component}`).querySelector("td"); | ||
setComponentElValue(componentEl, result[component]); | ||
setComponentElMismatch(componentEl, mismatchedComponents.has(component)); | ||
} | ||
} | ||
} | ||
|
||
function setComponentElValue(componentEl, value) { | ||
const isEmptyString = value === ""; | ||
componentEl.textContent = isEmptyString ? "(empty string)" : value; | ||
componentEl.classList.toggle("empty-string", isEmptyString); | ||
} | ||
|
||
function setComponentElMismatch(componentEl, isMismatched) { | ||
componentEl.classList.toggle("pass", !isMismatched); | ||
componentEl.classList.toggle("fail", isMismatched); | ||
} | ||
|
||
function getMismatchedComponents(result1, result2) { | ||
const mismatched = new Set(); | ||
for (const component of components) { | ||
if (result1[component] !== result2[component]) { | ||
mismatched.add(component); | ||
} | ||
} | ||
return mismatched; | ||
} | ||
|
||
function getBrowserResult() { | ||
// First make sure the base is not invalid by testing it against an about:blank base. | ||
browserBase.href = "about:blank"; | ||
browserAnchor.href = baseInput.value; | ||
if (browserAnchor.protocol === ":") { | ||
return new Error("Browser could not parse the base URL"); | ||
} | ||
|
||
// Now actually parse the URL against the base. | ||
browserAnchor.href = urlInput.value; | ||
browserBase.href = baseInput.value; | ||
if (browserAnchor.protocol === ":") { | ||
return new Error("Browser could not parse the input"); | ||
} | ||
|
||
return browserAnchor; | ||
} | ||
|
||
function getJsdomResult() { | ||
try { | ||
return new whatwgURL.URL(urlInput.value, baseInput.value); | ||
} catch (e) { | ||
return e; | ||
} | ||
} | ||
|
||
function updateFragmentForSharing() { | ||
location.hash = `url=${btoa(urlInput.value)}&base=${btoa(baseInput.value)}`; | ||
} | ||
|
||
function setFromFragment() { | ||
const pieces = /#url=([^&]+)&base=(.*)/.exec(location.hash); | ||
if (!pieces) { | ||
return; | ||
} | ||
const [, urlEncoded, baseEncoded] = pieces; | ||
urlInput.value = atob(urlEncoded); | ||
baseInput.value = atob(baseEncoded); | ||
} | ||
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
* { | ||
font-family: Georgia; | ||
box-sizing: border-box; | ||
} | ||
|
||
body { | ||
max-width: 70em; | ||
margin: 12px; | ||
} | ||
|
||
h1, h2, h3, h4, h5, h6 { | ||
font-style: italic; | ||
color: DarkBlue; | ||
margin-bottom: 0.2em; | ||
} | ||
|
||
h1 { | ||
margin-top: 0; | ||
} | ||
|
||
h2, h3, h4, h5, h6 { | ||
margin-top: 1em; | ||
} | ||
|
||
h2 { | ||
font-size: 1.5em; | ||
font-weight: bold; | ||
} | ||
|
||
p { | ||
margin-top: 0.5em; | ||
word-spacing: 0.3ex; | ||
} | ||
|
||
footer { | ||
position: absolute; | ||
top: 1em; | ||
right: 1em; | ||
} | ||
|
||
form label { | ||
display: block; | ||
margin-bottom: 6px; | ||
} | ||
|
||
form input { | ||
width: 90%; | ||
margin-bottom: 20px; | ||
padding: 3px; | ||
} | ||
|
||
.output { | ||
background-color: whitesmoke; | ||
border: 1px dashed crimson; | ||
width: 95%; | ||
padding: 1em; | ||
margin: 0; | ||
} | ||
|
||
.output.error { | ||
color: Crimson; | ||
} | ||
|
||
.output th { | ||
width: 100px; | ||
text-align: right; | ||
padding-right: 20px; | ||
} | ||
|
||
.output td { | ||
font-family: 'Bitstream Vera Sans Mono', 'Andale Mono', 'Lucida Console', monospace, fixed; | ||
} | ||
|
||
.pass { | ||
color: green; | ||
} | ||
|
||
.fail { | ||
color: red; | ||
} | ||
|
||
.output td.empty-string { | ||
font-family: inherit; | ||
font-size: smaller; | ||
font-style: italic; | ||
color: #CCC; | ||
} |
Oops, something went wrong.