Rewild Your Web
18
fork

Configure Feed

Select the types of activity you want to include in your feed.

json viewer

Signed-off-by: webbeef <me@webbeef.org>

webbeef 67847948 2e13d6ad

+325
+32
patches/components/script/dom/servoparser/mod.rs.patch
··· 1 + --- original 2 + +++ modified 3 + @@ -1055,9 +1055,10 @@ 4 + // Return the result of loading an XML document given navigationParams and type. 5 + MediaType::Xml => self.load_xml_document(parser), 6 + // Return the result of loading a text document given navigationParams and type. 7 + - MediaType::JavaScript | MediaType::Json | MediaType::Text | MediaType::Css => { 8 + + MediaType::JavaScript | MediaType::Text | MediaType::Css => { 9 + self.load_text_document(parser, cx) 10 + }, 11 + + MediaType::Json => self.load_json_document(parser, cx), 12 + // Return the result of loading a media document given navigationParams and type. 13 + MediaType::Image | MediaType::AudioVideo => { 14 + self.load_media_document(parser, media_type, &mime_type, cx); 15 + @@ -1125,6 +1126,17 @@ 16 + self.process_link_headers_in_media_phase_with_task(&parser.document); 17 + } 18 + 19 + + /// Load a JSON document with a pretty-printed, interactive viewer. 20 + + fn load_json_document(&mut self, parser: &ServoParser, cx: &mut js::context::JSContext) { 21 + + self.initialize_document_object(&parser.document); 22 + + let template = resources::read_string(Resource::JsonViewerHTML); 23 + + let page = format!("<html><head>{template}</head><body><pre id=\"json-raw\">",); 24 + + parser.push_string_input_chunk(page); 25 + + parser.parse_sync(cx); 26 + + parser.tokenizer.set_plaintext_state(); 27 + + self.process_link_headers_in_media_phase_with_task(&parser.document); 28 + + } 29 + + 30 + /// <https://html.spec.whatwg.org/multipage/#navigate-media> 31 + fn load_media_document( 32 + &mut self,
+21
patches/components/shared/embedder/resources.rs.patch
··· 1 + --- original 2 + +++ modified 3 + @@ -109,6 +109,10 @@ 4 + DirectoryListingHTML, 5 + /// A HTML page that is used for the about:memory url. 6 + AboutMemoryHTML, 7 + + /// A HTML page with CSS and JS for rendering JSON documents with syntax highlighting 8 + + /// and collapsible tree view. The template contains `<style>` and `<script>` blocks 9 + + /// that are injected into the `<head>` of the JSON document page. 10 + + JsonViewerHTML, 11 + /// RPC script for the Debugger API on behalf of devtools. 12 + DebuggerJS, 13 + } 14 + @@ -125,6 +129,7 @@ 15 + Resource::CrashHTML => "crash.html", 16 + Resource::DirectoryListingHTML => "directory-listing.html", 17 + Resource::AboutMemoryHTML => "about-memory.html", 18 + + Resource::JsonViewerHTML => "json-viewer.html", 19 + Resource::DebuggerJS => "debugger.js", 20 + } 21 + }
+272
resources/json-viewer.html
··· 1 + <style> 2 + body { 3 + font-family: monospace; 4 + margin: 0; 5 + padding: 0; 6 + background: #fff; 7 + color: #333; 8 + } 9 + 10 + #json-raw { 11 + display: none; 12 + } 13 + 14 + #viewer { 15 + padding: 0.5em 1em; 16 + line-height: 1.5; 17 + } 18 + 19 + #toolbar { 20 + display: flex; 21 + gap: 1em; 22 + padding: 0.5em; 23 + align-items: center; 24 + background: #f5f5f5; 25 + border-bottom: 1px solid #ddd; 26 + } 27 + 28 + #toolbar button { 29 + min-width: 5em; 30 + } 31 + 32 + #toolbar button.active { 33 + background: #ddd; 34 + font-weight: bold; 35 + } 36 + 37 + #raw-view { 38 + display: none; 39 + padding: 0.5em 1em; 40 + white-space: pre-wrap; 41 + word-break: break-all; 42 + } 43 + 44 + .json-error { 45 + padding: 0.5em 1em; 46 + color: #c00; 47 + font-weight: bold; 48 + } 49 + 50 + /* Syntax highlighting for Json data types */ 51 + .json-key { 52 + color: #881391; 53 + } 54 + 55 + .json-string { 56 + color: #1a1aa6; 57 + } 58 + 59 + .json-number { 60 + color: #1c00cf; 61 + } 62 + 63 + .json-boolean { 64 + color: #0d22aa; 65 + } 66 + 67 + .json-null { 68 + color: #808080; 69 + } 70 + 71 + /* Collapsible tree */ 72 + .toggle { 73 + cursor: pointer; 74 + user-select: none; 75 + } 76 + 77 + .toggle::before { 78 + content: "\25BC"; 79 + display: inline-block; 80 + width: 1em; 81 + transition: transform 0.1s; 82 + } 83 + 84 + .toggle.collapsed::before { 85 + transform: rotate(-90deg); 86 + } 87 + 88 + .collapsible { 89 + margin-left: 1.5em; 90 + } 91 + 92 + .collapsible.hidden { 93 + display: none; 94 + } 95 + 96 + .bracket { 97 + color: #333; 98 + } 99 + 100 + .comma { 101 + color: #333; 102 + } 103 + 104 + .line { 105 + padding-left: 0; 106 + } 107 + </style> 108 + <script> 109 + // Shortcut to create an element with an optional class and text content. 110 + function createElement(name, classes = null, textContent = null) { 111 + let node = document.createElement(name); 112 + if (classes) { 113 + node.className = classes; 114 + } 115 + if (textContent) { 116 + node.textContent = textContent; 117 + } 118 + return node; 119 + } 120 + 121 + document.addEventListener("DOMContentLoaded", function () { 122 + let rawEl = document.getElementById("json-raw"); 123 + if (!rawEl) { 124 + return; 125 + } 126 + let rawText = rawEl.textContent; 127 + 128 + let data; 129 + let parseError = null; 130 + try { 131 + data = JSON.parse(rawText); 132 + } catch (e) { 133 + parseError = e; 134 + } 135 + 136 + // Build the page structure 137 + document.body.innerHTML = ""; 138 + 139 + // Toolbar 140 + let toolbar = createElement("div"); 141 + toolbar.id = "toolbar"; 142 + let prettyBtn = createElement("button", "active", "Pretty"); 143 + let rawBtn = createElement("button", null, "Raw"); 144 + toolbar.append(prettyBtn); 145 + toolbar.append(rawBtn); 146 + document.body.append(toolbar); 147 + 148 + // Pretty view 149 + let viewer = createElement("div"); 150 + viewer.id = "viewer"; 151 + document.body.append(viewer); 152 + 153 + // Raw view 154 + let rawView = createElement("pre"); 155 + rawView.id = "raw-view"; 156 + document.body.append(rawView); 157 + 158 + if (parseError) { 159 + let errDiv = createElement( 160 + "div", 161 + "json-error", 162 + "Invalid JSON: " + parseError.message, 163 + ); 164 + viewer.append(errDiv); 165 + let pre = createElement("pre", null, rawText); 166 + viewer.append(pre); 167 + rawView.textContent = rawText; 168 + } else { 169 + renderNode(data, viewer); 170 + rawView.textContent = JSON.stringify(data, null, 2); 171 + } 172 + 173 + // Toggle buttons 174 + prettyBtn.onclick = function () { 175 + viewer.style.display = ""; 176 + rawView.style.display = "none"; 177 + prettyBtn.className = "active"; 178 + rawBtn.className = ""; 179 + }; 180 + rawBtn.onclick = function () { 181 + viewer.style.display = "none"; 182 + rawView.style.display = "block"; 183 + rawBtn.className = "active"; 184 + prettyBtn.className = ""; 185 + }; 186 + 187 + function renderNode(value, container) { 188 + if (value === null) { 189 + let s = createElement("span", "json-null", "null"); 190 + container.append(s); 191 + } else if (typeof value === "boolean") { 192 + let s = createElement("span", "json-boolean", String(value)); 193 + container.append(s); 194 + } else if (typeof value === "number") { 195 + let s = createElement("span", "json-number", String(value)); 196 + container.append(s); 197 + } else if (typeof value === "string") { 198 + let s = createElement("span", "json-string", JSON.stringify(value)); 199 + container.append(s); 200 + } else if (Array.isArray(value)) { 201 + renderArray(value, container); 202 + } else if (typeof value === "object") { 203 + renderObject(value, container); 204 + } 205 + } 206 + 207 + function renderObject(obj, container) { 208 + let keys = Object.keys(obj); 209 + if (keys.length === 0) { 210 + container.append(createElement("span", "bracket", "{}")); 211 + return; 212 + } 213 + 214 + let toggle = createElement("span", "toggle"); 215 + container.append(toggle); 216 + 217 + container.append(createElement("span", "bracket", "{")); 218 + 219 + let inner = createElement("div", "collapsible"); 220 + container.append(inner); 221 + 222 + keys.forEach((key, i) => { 223 + let line = createElement("div", "line"); 224 + line.append(createElement("span", "json-key", JSON.stringify(key))); 225 + line.append(document.createTextNode(": ")); 226 + renderNode(obj[key], line); 227 + if (i < keys.length - 1) { 228 + line.append(createElement("span", "comma", ",")); 229 + } 230 + inner.append(line); 231 + }); 232 + 233 + container.append(createElement("span", "bracket", "}")); 234 + 235 + toggle.onclick = function () { 236 + toggle.classList.toggle("collapsed"); 237 + inner.classList.toggle("hidden"); 238 + }; 239 + } 240 + 241 + function renderArray(arr, container) { 242 + if (arr.length === 0) { 243 + container.append(createElement("span", "bracket", "[]")); 244 + return; 245 + } 246 + 247 + let toggle = createElement("span", "toggle"); 248 + container.append(toggle); 249 + 250 + container.append(createElement("span", "bracket", "[")); 251 + 252 + let inner = createElement("div", "collapsible"); 253 + container.append(inner); 254 + 255 + arr.forEach((item, i) => { 256 + let line = createElement("div", "line"); 257 + renderNode(item, line); 258 + if (i < arr.length - 1) { 259 + line.append(createElement("span", "comma", ",")); 260 + } 261 + inner.append(line); 262 + }); 263 + 264 + container.append(createElement("span", "bracket", "]")); 265 + 266 + toggle.onclick = function () { 267 + toggle.classList.toggle("collapsed"); 268 + inner.classList.toggle("hidden"); 269 + }; 270 + } 271 + }); 272 + </script>