Skip to content

Commit 8283935

Browse files
committed
Simplify json global value
1 parent 87a4bff commit 8283935

File tree

2 files changed

+61
-56
lines changed

2 files changed

+61
-56
lines changed

src/content.ts

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,16 @@ import { errorPage, jsonToHTML } from "./jsonformatter";
33
import { installCollapseEventListeners } from "./collapse";
44
import { safeStringEncodeNums } from "./safe-encode-numbers";
55

6-
function setJsonAsGlobalVariable(jsonObj: JSON) {
6+
function setJsonAsGlobalVariable(this: any, jsonObj: any) {
77
const script = document.createElement("script");
8-
const jsonStr = JSON.stringify(jsonObj).replace(/\\/g, "\\\\");
9-
script.text = `window.data=JSON.parse('${jsonStr}');`;
8+
script.text = `Object.defineProperty(window, 'data', { value: ${JSON.stringify(
9+
jsonObj
10+
)}, writable: false, configurable: false });`;
1011
document.documentElement.appendChild(script);
1112

1213
// log info message
1314
// with this queueMicrotask user can not see source file information in log
14-
queueMicrotask(() =>
15-
console.log(
16-
"%c%s%c%s",
17-
"color: green; font-size: 16px;",
18-
"JSON is exposed as variable called ",
19-
"background-color: rgba(175, 184, 193, 0.2); font-size: 16px; margin: 0; padding: 0.2em 0.4em; border-radius: 6px",
20-
"data"
21-
)
22-
);
15+
queueMicrotask(() => console.log('JSON is exposed as a global variable called "data"'));
2316
}
2417

2518
/**
@@ -34,15 +27,14 @@ chrome.runtime.sendMessage({}, (response: boolean) => {
3427
// At least in chrome, the JSON is wrapped in a pre tag.
3528
const content = document.getElementsByTagName("pre")[0].textContent;
3629
let outputDoc = "";
30+
let jsonObj = null;
3731

3832
if (content === null) {
3933
outputDoc = errorPage(new Error("No content"), "", document.URL);
4034
} else {
4135
try {
42-
const jsonObj = JSON.parse(safeStringEncodeNums(content));
36+
jsonObj = JSON.parse(safeStringEncodeNums(content));
4337
outputDoc = jsonToHTML(jsonObj, document.URL);
44-
45-
setJsonAsGlobalVariable(jsonObj);
4638
} catch (e: any) {
4739
outputDoc = errorPage(
4840
e instanceof Error ? e : new Error(e.toString()),
@@ -54,4 +46,5 @@ chrome.runtime.sendMessage({}, (response: boolean) => {
5446

5547
document.documentElement.innerHTML = outputDoc;
5648
installCollapseEventListeners();
49+
setJsonAsGlobalVariable(jsonObj);
5750
});

src/jsonformatter.ts

Lines changed: 53 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ export function jsonToHTML(json: any, uri: string) {
1010

1111
/** Convert a whole JSON value / JSONP response into an HTML body, without title and scripts */
1212
function jsonToHTMLBody(json: any) {
13-
return `<div id="json">${valueToHTML(json, '<root>')}</div>`;
13+
return `<div id="json">${valueToHTML(json, "<root>")}</div>`;
1414
}
1515

1616
/** Produce an error document for when parsing fails. */
1717
export function errorPage(error: Error, data: string, uri: string) {
18-
return toHTML(errorPageBody(error, data), uri + ' - Error');
18+
return toHTML(errorPageBody(error, data), uri + " - Error");
1919
}
2020

2121
/** Produce an error content for when parsing fails. */
@@ -25,7 +25,7 @@ function errorPageBody(error: Error, data: string) {
2525

2626
const errorInfo = massageError(error);
2727

28-
let output = `<div id="error">${chrome.i18n.getMessage('errorParsing')}`;
28+
let output = `<div id="error">${chrome.i18n.getMessage("errorParsing")}`;
2929
if (errorInfo.message) {
3030
output += `<div class="errormessage">${errorInfo.message}</div>`;
3131
}
@@ -37,13 +37,15 @@ function errorPageBody(error: Error, data: string) {
3737
* Encode a string to be used in HTML
3838
*/
3939
function htmlEncode(t: any): string {
40-
return (typeof t !== "undefined" && t !== null) ? t.toString()
41-
.replace(/&/g, "&amp;")
42-
.replace(/"/g, "&quot;")
43-
.replace(/'/g, "&apos;")
44-
.replace(/</g, "&lt;")
45-
.replace(/>/g, "&gt;")
46-
: '';
40+
return typeof t !== "undefined" && t !== null
41+
? t
42+
.toString()
43+
.replace(/&/g, "&amp;")
44+
.replace(/"/g, "&quot;")
45+
.replace(/'/g, "&apos;")
46+
.replace(/</g, "&lt;")
47+
.replace(/>/g, "&gt;")
48+
: "";
4749
}
4850

4951
/**
@@ -74,71 +76,77 @@ function valueToHTML(value: any, path: string) {
7476
const valueType = typeof value;
7577

7678
if (value === null) {
77-
return decorateWithSpan('null', 'null');
79+
return decorateWithSpan("null", "null");
7880
} else if (Array.isArray(value)) {
7981
return arrayToHTML(value, path);
80-
} else if (valueType === 'object') {
82+
} else if (valueType === "object") {
8183
return objectToHTML(value, path);
82-
} else if (valueType === 'number') {
83-
return decorateWithSpan(value, 'num');
84-
} else if (valueType === 'string' &&
85-
value.charCodeAt(0) === 8203 &&
86-
!isNaN(value.slice(1))) {
87-
return decorateWithSpan(value.slice(1), 'num');
88-
} else if (valueType === 'string') {
84+
} else if (valueType === "number") {
85+
return decorateWithSpan(value, "num");
86+
} else if (valueType === "string" && value.charCodeAt(0) === 8203 && !isNaN(value.slice(1))) {
87+
return decorateWithSpan(value.slice(1), "num");
88+
} else if (valueType === "string") {
8989
if (/^(http|https|file):\/\/[^\s]+$/i.test(value)) {
90-
return `<a href="${htmlEncode(value)}"><span class="q">&quot;</span>${jsString(value)}<span class="q">&quot;</span></a>`;
90+
return `<a href="${htmlEncode(value)}"><span class="q">&quot;</span>${jsString(
91+
value
92+
)}<span class="q">&quot;</span></a>`;
9193
} else {
9294
return `<span class="string">&quot;${jsString(value)}&quot;</span>`;
9395
}
94-
} else if (valueType === 'boolean') {
95-
return decorateWithSpan(value, 'bool');
96+
} else if (valueType === "boolean") {
97+
return decorateWithSpan(value, "bool");
9698
}
9799

98-
return '';
100+
return "";
99101
}
100102

101103
// Convert an array into an HTML fragment
102104
function arrayToHTML(json: any, path: string) {
103105
if (json.length === 0) {
104-
return '[ ]';
106+
return "[ ]";
105107
}
106108

107-
let output = '';
109+
let output = "";
108110
for (let i = 0; i < json.length; i++) {
109111
const subPath = `${path}[${i}]`;
110-
output += '<li>' + valueToHTML(json[i], subPath);
112+
output += "<li>" + valueToHTML(json[i], subPath);
111113
if (i < json.length - 1) {
112-
output += ',';
114+
output += ",";
113115
}
114-
output += '</li>';
116+
output += "</li>";
115117
}
116-
return (json.length === 0 ? '' : '<span class="collapser"></span>') +
117-
`[<ul class="array collapsible">${output}</ul>]`;
118+
return (
119+
(json.length === 0 ? "" : '<span class="collapser"></span>') +
120+
`[<ul class="array collapsible">${output}</ul>]`
121+
);
118122
}
119123

120124
// Convert a JSON object to an HTML fragment
121125
function objectToHTML(json: any, path: string) {
122126
let numProps = Object.keys(json).length;
123127
if (numProps === 0) {
124-
return '{ }';
128+
return "{ }";
125129
}
126130

127-
let output = '';
131+
let output = "";
128132
for (const prop in json) {
129-
let subPath = '';
133+
let subPath = "";
130134
let escapedProp = JSON.stringify(prop).slice(1, -1);
131135
const bare = isBareProp(prop);
132136
if (bare) {
133137
subPath = `${path}.${escapedProp}`;
134138
} else {
135139
escapedProp = `"${escapedProp}"`;
136140
}
137-
output += `<li><span class="prop${(bare ? '' : ' quoted')}" title="${htmlEncode(subPath)}"><span class="q">&quot;</span>${jsString(prop)}<span class="q">&quot;</span></span>: ${valueToHTML(json[prop], subPath)}`;
141+
output += `<li><span class="prop${bare ? "" : " quoted"}" title="${htmlEncode(
142+
subPath
143+
)}"><span class="q">&quot;</span>${jsString(
144+
prop
145+
)}<span class="q">&quot;</span></span>: ${valueToHTML(json[prop], subPath)}`;
138146
if (numProps > 1) {
139-
output += ',';
147+
output += ",";
140148
}
141-
output += '</li>';
149+
output += "</li>";
142150
numProps--;
143151
}
144152

@@ -155,7 +163,7 @@ function massageError(error: Error): {
155163
return error;
156164
}
157165

158-
const message = error.message.replace(/^JSON.parse: /, '').replace(/of the JSON data/, '');
166+
const message = error.message.replace(/^JSON.parse: /, "").replace(/of the JSON data/, "");
159167
const parts = /line (\d+) column (\d+)/.exec(message);
160168
if (!parts || parts.length !== 3) {
161169
return error;
@@ -164,7 +172,7 @@ function massageError(error: Error): {
164172
return {
165173
message: htmlEncode(message),
166174
line: Number(parts[1]),
167-
column: Number(parts[2])
175+
column: Number(parts[2]),
168176
};
169177
}
170178

@@ -175,14 +183,18 @@ function highlightError(data: string, lineNum?: number, columnNum?: number) {
175183

176184
const lines = data.match(/^.*((\r\n|\n|\r)|$)/gm)!;
177185

178-
let output = '';
186+
let output = "";
179187
for (let i = 0; i < lines.length; i++) {
180188
const line = lines[i];
181189

182190
if (i === lineNum - 1) {
183191
output += '<span class="errorline">';
184-
output += `${htmlEncode(line.substring(0, columnNum - 1))}<span class="errorcolumn">${htmlEncode(line[columnNum - 1])}</span>${htmlEncode(line.substring(columnNum))}`;
185-
output += '</span>';
192+
output += `${htmlEncode(
193+
line.substring(0, columnNum - 1)
194+
)}<span class="errorcolumn">${htmlEncode(line[columnNum - 1])}</span>${htmlEncode(
195+
line.substring(columnNum)
196+
)}`;
197+
output += "</span>";
186198
} else {
187199
output += htmlEncode(line);
188200
}

0 commit comments

Comments
 (0)