Skip to content

Commit 927948b

Browse files
committed
Updating live-viewer
1 parent fe8983e commit 927948b

File tree

2 files changed

+47
-148
lines changed

2 files changed

+47
-148
lines changed

live-viewer/index.html

Lines changed: 10 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -19,50 +19,19 @@ <h1>Live Encoding Viewer</h1>
1919
<span class="fail">red</span>.
2020

2121
<form>
22-
<label for="url">Encoding:</label>
23-
<input id="url" value="https://example.com/" autofocus>
24-
25-
<label for="base">Base Encoding:</label>
26-
<input id="base" value="about:blank">
22+
<label for="message">Message:</label>
23+
<input id="message" value="Hello, World" autofocus>
2724
</form>
2825

2926
<h2>Browser's Encoding components</h2>
3027

3128
<table class="output" id="browser-output">
32-
<tr id="href">
33-
<th>href</th>
34-
<td></td>
35-
</tr>
36-
<tr id="protocol">
37-
<th>protocol</th>
38-
<td></td>
39-
</tr>
40-
<tr id="username">
41-
<th>username</th>
42-
<td></td>
43-
</tr>
44-
<tr id="password">
45-
<th>password</th>
46-
<td></td>
47-
</tr>
48-
<tr id="port">
49-
<th>port</th>
50-
<td></td>
51-
</tr>
52-
<tr id="hostname">
53-
<th>hostname</th>
54-
<td></td>
55-
</tr>
56-
<tr id="pathname">
57-
<th>pathname</th>
58-
<td></td>
59-
</tr>
60-
<tr id="search">
61-
<th>search</th>
29+
<tr id="encoded">
30+
<th>encoded</th>
6231
<td></td>
6332
</tr>
64-
<tr id="hash">
65-
<th>hash</th>
33+
<tr id="decoded">
34+
<th>decoded</th>
6635
<td></td>
6736
</tr>
6837
</table>
@@ -72,40 +41,12 @@ <h2>Browser's Encoding components</h2>
7241
<h2>jsdom/whatwg-encoding's components</h2>
7342

7443
<table class="output" id="jsdom-output">
75-
<tr id="href">
76-
<th>href</th>
44+
<tr id="encoded">
45+
<th>encoded</th>
7746
<td></td>
7847
</tr>
79-
<tr id="protocol">
80-
<th>protocol</th>
81-
<td></td>
82-
</tr>
83-
<tr id="username">
84-
<th>username</th>
85-
<td></td>
86-
</tr>
87-
<tr id="password">
88-
<th>password</th>
89-
<td></td>
90-
</tr>
91-
<tr id="port">
92-
<th>port</th>
93-
<td></td>
94-
</tr>
95-
<tr id="hostname">
96-
<th>hostname</th>
97-
<td></td>
98-
</tr>
99-
<tr id="pathname">
100-
<th>pathname</th>
101-
<td></td>
102-
</tr>
103-
<tr id="search">
104-
<th>search</th>
105-
<td></td>
106-
</tr>
107-
<tr id="hash">
108-
<th>hash</th>
48+
<tr id="decoded">
49+
<th>decoded</th>
10950
<td></td>
11051
</tr>
11152
</table>
@@ -116,6 +57,4 @@ <h2>jsdom/whatwg-encoding's components</h2>
11657
<a href="https://github.com/jsdom/whatwg-encoding/tree/master/live-viewer">Fork me on GitHub!</a>
11758
</footer>
11859

119-
<iframe hidden id="browser-iframe"></iframe>
120-
12160
<script src="live-viewer.js"></script>

live-viewer/live-viewer.js

Lines changed: 37 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,14 @@
11
"use strict";
22
(() => {
3-
const urlInput = document.querySelector("#url");
4-
const baseInput = document.querySelector("#base");
5-
6-
const te = new TextEncoder();
7-
const td = new TextDecoder();
8-
9-
// Use an iframe to avoid <base> affecting the main page. This is especially bad in Edge where it
10-
// appears to break Edge's DevTools.
11-
const browserIframeDocument = document.querySelector("#browser-iframe").contentDocument;
12-
const browserAnchor = browserIframeDocument.createElement("a");
13-
const browserBase = browserIframeDocument.createElement("base");
14-
browserIframeDocument.head.appendChild(browserBase);
15-
browserIframeDocument.body.appendChild(browserAnchor);
3+
const messageInput = document.querySelector("#message");
164

175
const components = [
18-
"href", "protocol", "username",
19-
"password", "port", "hostname",
20-
"pathname", "search", "hash"
6+
"encoded",
7+
"decoded"
218
];
229

23-
urlInput.addEventListener("input", update);
24-
baseInput.addEventListener("input", update);
25-
window.addEventListener("hashchange", setFromFragment);
26-
setFromFragment();
10+
messageInput.addEventListener("input", update);
11+
update();
2712

2813
function update() {
2914
const browserResult = getBrowserResult();
@@ -32,7 +17,6 @@
3217

3318
setResult("browser", browserResult, mismatchedComponents);
3419
setResult("jsdom", jsdomResult, mismatchedComponents);
35-
updateFragmentForSharing();
3620
}
3721

3822
function setResult(kind, result, mismatchedComponents) {
@@ -72,80 +56,56 @@
7256
function getMismatchedComponents(result1, result2) {
7357
const mismatched = new Set();
7458
for (const component of components) {
75-
if (result1[component] !== result2[component]) {
76-
mismatched.add(component);
59+
if (typeof result1[component] === "string") {
60+
if (result1[component] !== result2[component]) {
61+
mismatched.add(component);
62+
}
63+
}
64+
if (result1[component] instanceof Uint8Array) {
65+
if (equalBuffer(result1[component], result2[component]) === false) {
66+
mismatched.add(component);
67+
}
7768
}
7869
}
7970
return mismatched;
8071
}
8172

8273
function getBrowserResult() {
83-
// First make sure the base is not invalid by testing it against an about:blank base.
84-
browserBase.href = "about:blank";
85-
browserAnchor.href = baseInput.value;
86-
if (browserAnchor.protocol === ":") {
87-
return new Error("Browser could not parse the base URL");
88-
}
89-
90-
// Now actually parse the URL against the base.
91-
browserAnchor.href = urlInput.value;
92-
browserBase.href = baseInput.value;
93-
if (browserAnchor.protocol === ":") {
94-
return new Error("Browser could not parse the input");
74+
try {
75+
const encoder = new TextEncoder();
76+
const decoder = new TextDecoder();
77+
return {
78+
encoded: encoder.encode(messageInput.value),
79+
decoded: decoder.decode(encoder.encode(messageInput.value))
80+
};
81+
} catch (e) {
82+
return e;
9583
}
96-
97-
return browserAnchor;
9884
}
9985

10086
function getJsdomResult() {
10187
try {
102-
return new whatwgEncoding.TextEncoder();
88+
const encoder = new whatwgEncoding.TextEncoder();
89+
const decoder = new whatwgEncoding.TextDecoder();
90+
return {
91+
encoded: encoder.encode(messageInput.value),
92+
decoded: decoder.decode(encoder.encode(messageInput.value))
93+
};
10394
} catch (e) {
10495
return e;
10596
}
10697
}
10798

108-
function updateFragmentForSharing() {
109-
location.hash = `url=${encodeToBase64(urlInput.value)}&base=${encodeToBase64(baseInput.value)}`;
110-
}
111-
112-
function setFromFragment() {
113-
const pieces = /#url=([^&]+)&base=(.*)/.exec(location.hash);
114-
if (!pieces) {
115-
return;
99+
function equalBuffer(buf1, buf2) {
100+
if (buf1.byteLength !== buf2.byteLength) {
101+
return false;
116102
}
117-
const [, urlEncoded, baseEncoded] = pieces;
118-
try {
119-
urlInput.value = decodeFromBase64(urlEncoded);
120-
} catch (e) {
121-
// eslint-disable-next-line no-console
122-
console.warn("url hash parameter was not deserializable.");
123-
}
124-
125-
try {
126-
baseInput.value = decodeFromBase64(baseEncoded);
127-
} catch (e) {
128-
// eslint-disable-next-line no-console
129-
console.warn("base hash parameter was not deserializable.");
103+
for (let i = 0; i !== buf1.byteLength; i++) {
104+
if (buf1[i] !== buf2[i]) {
105+
return false;
106+
}
130107
}
131-
132-
update();
108+
return true;
133109
}
134110

135-
// btoa / atob don't work on Unicode.
136-
// This version is a superset of btoa / atob, so it maintains compatibility with older versions of
137-
// the live viewer which used btoa / atob directly.
138-
function encodeToBase64(originalString) {
139-
const bytes = te.encode(originalString);
140-
const byteString = Array.from(bytes, byte => String.fromCharCode(byte)).join("");
141-
const encoded = btoa(byteString);
142-
return encoded;
143-
}
144-
145-
function decodeFromBase64(encoded) {
146-
const byteString = atob(encoded);
147-
const bytes = Uint8Array.from(byteString, char => char.charCodeAt(0));
148-
const originalString = td.decode(bytes);
149-
return originalString;
150-
}
151111
})();

0 commit comments

Comments
 (0)