Skip to content

Commit

Permalink
Live viewer: add escape support
Browse files Browse the repository at this point in the history
Closes #136.
  • Loading branch information
domenic committed Dec 30, 2022
1 parent 2141112 commit 2a1faeb
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 1 deletion.
9 changes: 9 additions & 0 deletions live-viewer/index.html
Expand Up @@ -22,10 +22,19 @@ <h1>Live URL Viewer</h1>
<label for="url">URL:</label>
<input id="url" value="https://example.com/" autofocus>

<label for="url-escaped">URL with escapes:</label>
<input id="url-escaped" value="https://example.com/">

<label for="base">Base URL:</label>
<input id="base" value="about:blank">
</form>

<details>
<summary>How do I use "URL with escapes?"</summary>

<p>Most of the time, you don't need to worry about this. But if you want to test characters outside of the U+0021 (!) through U+007E (~) range, which can be harder to input or to visually distinguish, you can use this field. Any strings of the form <samp>\u{<var>number</var>}</samp> will be decoded to their corresponding Unicode code point. So for example, you could test how null characters are processed by the URL parser by using the input <samp>test:\u{0}</samp>.
</details>

<h2>Browser's URL components</h2>

<table class="output" id="browser-output">
Expand Down
39 changes: 39 additions & 0 deletions live-viewer/live-viewer.mjs
@@ -1,6 +1,7 @@
import whatwgURL from "./whatwg-url.mjs";

const urlInput = document.querySelector("#url");
const urlEscapedInput = document.querySelector("#url-escaped");
const baseInput = document.querySelector("#base");

const te = new TextEncoder();
Expand All @@ -19,8 +20,13 @@ const components = [
"origin"
];

urlInput.addEventListener("input", updateEscaped);
urlEscapedInput.addEventListener("input", updateUnescaped);

urlInput.addEventListener("input", update);
urlEscapedInput.addEventListener("input", update);
baseInput.addEventListener("input", update);

window.addEventListener("hashchange", setFromFragment);
setFromFragment();
update();
Expand Down Expand Up @@ -54,6 +60,14 @@ function setResult(kind, result, mismatchedComponents) {
}
}

function updateEscaped() {
urlEscapedInput.value = escape(urlInput.value);
}

function updateUnescaped() {
urlInput.value = unescape(urlEscapedInput.value);
}

function setComponentElValue(componentEl, value) {
const isEmptyString = value === "";

Expand Down Expand Up @@ -120,6 +134,7 @@ function setFromFragment() {
console.warn("base hash parameter was not deserializable.");
}

updateEscaped();
update();
}

Expand All @@ -139,3 +154,27 @@ function decodeFromBase64(encoded) {
const originalString = td.decode(bytes);
return originalString;
}

function escape(rawString) {
return rawString
.replaceAll(
"\\u",
"\\\\u"
)
.replaceAll(
/[^\u{0021}-\u{007E}]/ug,
c => `\\u{${c.codePointAt(0).toString(16).padStart(4, "0")}}`
);
}

function unescape(escapedString) {
return escapedString
.replaceAll(
/(?<!\\)\\u\{([0-9a-fA-F]+)\}/ug,
(_, c) => String.fromCodePoint(Number.parseInt(c, 16))
)
.replaceAll(
"\\\\u",
"\\u"
);
}
10 changes: 9 additions & 1 deletion live-viewer/style.css
@@ -1,9 +1,9 @@
* {
font-family: Georgia;
box-sizing: border-box;
}

body {
font-family: Georgia;
max-width: 70em;
margin: 12px;
}
Expand Down Expand Up @@ -88,3 +88,11 @@ form input {
.output td.empty-string:not(.fail) {
color: #CCC;
}

summary {
cursor: pointer;
}

samp {
font-family: monospace;
}

0 comments on commit 2a1faeb

Please sign in to comment.