1import { FilePanelElement } from "./UI/FilePanelElement.js"; 2import { DriveService } from "./Services/DriveService.js"; 3; 4export class MainApp extends HTMLElement { 5 #pnlFile = this.querySelector(".file-panel"); 6 #xmlString = this.querySelector("#xmlString"); 7 #formatBtn = this.querySelector("#formatBtn"); 8 #outputXML = this.querySelector("#outputXML"); 9 #indentation = this.querySelector("#indentation"); 10 #errorInfo = this.querySelector("#error-info"); 11 #resultPanel = this.querySelector("#result-panel"); 12 #sampleBtn = this.querySelector("#sampleBtn"); 13 #folderId = undefined; 14 constructor() { 15 super(); 16 this.#pnlFile.addEventListener("change", () => void this.#onFilePicked()); 17 this.addDelegate("click", "[data-save]", (_, el) => void this.#onSave(el)); 18 this.#formatBtn.addEventListener("click", () => void this.#onFormat()); 19 this.#xmlString.addEventListener("change", () => void this.#onInput()); 20 this.#sampleBtn.addEventListener("click", () => void this.#onSample()); 21 if (this.#isOpenFromDrive()) { 22 this.#readFromDrive(); 23 } 24 else { 25 this.#checkCreateFromDrive(); 26 } 27 } 28 async #onSave(el) { 29 const type = el.getAttribute("data-save"); 30 const result = await this.#outputXML.value; 31 const blob = new Blob([result], { 32 type: "text/xml", 33 }); 34 const fileName = "formatted.xml"; 35 switch (type) { 36 case "drive": 37 await this.#pnlFile.drive.saveFileAsync(blob, fileName, this.#folderId); 38 alert("Saved".loc()); 39 break; 40 case "file": 41 { 42 const url = URL.createObjectURL(blob); 43 const a = document.createElement("a"); 44 a.href = url; 45 a.download = fileName; 46 a.click(); 47 URL.revokeObjectURL(url); 48 } 49 break; 50 case "copy": 51 this.#outputXML.select(); 52 document.execCommand('copy'); 53 break; 54 default: 55 throw new Error("Unknown type: " + type); 56 } 57 } 58 async #processAsync() { 59 const files = this.#pnlFile.files; 60 if (!files || !files.length) { 61 throw new Error("NoFile".loc()); 62 } 63 const texts = []; 64 for (const file of files) { 65 let content; 66 switch (file.type) { 67 case "drive": 68 { 69 // This could be improved by running in parallel instead 70 const arr = await this.#pnlFile.drive.downloadFileAsync(file.drive.id); 71 const dec = new TextDecoder(); 72 content = dec.decode(arr); 73 } 74 break; 75 case "file": 76 content = await file.file.text(); 77 break; 78 default: 79 throw new Error("Unknown type: " + file.type); 80 } 81 texts.push(content); 82 } 83 return texts.join(""); 84 } 85 async #onFilePicked() { 86 const result = await this.#processAsync(); 87 this.#xmlString.value = result; 88 } 89 async #onFormat() { 90 let indentation = this.#indentation.value; 91 let resultXmlText = new XmlBeautify().beautify(this.#xmlString.value, { 92 'indent_size': indentation === "TWO_SPACES" ? 2 : (indentation === "THREE_SPACES" ? 3 : 4) 93 }); 94 if (resultXmlText.indexOf("<parsererror") >= 0) { 95 this.#errorInfo.innerText = `<code>${resultXmlText}</code>`; 96 this.#errorInfo.style.display = "block"; 97 return; 98 } 99 this.#outputXML.value = resultXmlText; 100 this.#resultPanel.style.display = "block"; 101 } 102 async #onInput() { 103 this.#errorInfo.style.display = "none"; 104 this.#resultPanel.style.display = "none"; 105 } 106 async #onSample() { 107 this.#xmlString.value = `<?xml version="1.0"?><catalog><book id="bk101"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><genre>Computer</genre><price>44.95</price><publish_date>2000-10-01</publish_date><description>An in-depth look at creating applications 108 with XML.</description></book><book id="bk102"><author>Ralls, Kim</author><title>Midnight Rain</title><genre>Fantasy</genre><price>5.95</price><publish_date>2000-12-16</publish_date><description>A former architect battles corporate zombies, 109 an evil sorceress, and her own childhood to become queen 110 of the world.</description></book><book id="bk103"><author>Corets, Eva</author><title>Maeve Ascendant</title><genre>Fantasy</genre><price>5.95</price><publish_date>2000-11-17</publish_date><description>After the collapse of a nanotechnology
111 society in England, the young survivors lay the 112 foundation for a new society.</description></book><book id="bk104"><author>Corets, Eva</author><title>Oberon's Legacy</title><genre>Fantasy</genre><price>5.95</price><publish_date>2001-03-10</publish_date><description>In post-apocalypse England, the mysterious 113 agent known only as Oberon helps to create a new life 114 for the inhabitants of London. Sequel to Maeve 115 Ascendant.</description></book><book id="bk105"><author>Corets, Eva</author><title>The Sundered Grail</title><genre>Fantasy</genre><price>5.95</price><publish_date>2001-09-10</publish_date><description>The two daughters of Maeve, half-sisters, 116 battle one another for control of England. Sequel to 117 Oberon's Legacy.</description></book><book id="bk106"><author>Randall, Cynthia</author><title>Lover Birds</title><genre>Romance</genre><price>4.95</price><publish_date>2000-09-02</publish_date><description>When Carla meets Paul at an ornithology 118 conference, tempers fly as feathers get ruffled.</description></book><book id="bk107"><author>Thurman, Paula</author><title>Splish Splash</title><genre>Romance</genre><price>4.95</price><publish_date>2000-11-02</publish_date><description>A deep sea diver finds true love twenty 119 thousand leagues beneath the sea.</description></book><book id="bk108"><author>Knorr, Stefan</author><title>Creepy Crawlies</title><genre>Horror</genre><price>4.95</price><publish_date>2000-12-06</publish_date><description>An anthology of horror stories about roaches, 120 centipedes, scorpions and other insects.</description></book><book id="bk109"><author>Kress, Peter</author><title>Paradox Lost</title><genre>Science Fiction</genre><price>6.95</price><publish_date>2000-11-02</publish_date><description>After an inadvertant trip through a Heisenberg 121 Uncertainty Device, James Salway discovers the problems 122 of being quantum.</description></book><book id="bk110"><author>O'Brien, Tim</author><title>Microsoft .NET: The Programming Bible</title><genre>Computer</genre><price>36.95</price><publish_date>2000-12-09</publish_date><description>Microsoft's .NET initiative is explored in 123 detail in this deep programmer's reference.</description></book><book id="bk111"><author>O'Brien, Tim</author><title>MSXML3: A Comprehensive Guide</title><genre>Computer</genre><price>36.95</price><publish_date>2000-12-01</publish_date><description>The Microsoft MSXML3 parser is covered in 124 detail, with attention to XML DOM interfaces, XSLT processing, 125 SAX and more.</description></book><book id="bk112"><author>Galos, Mike</author><title>Visual Studio 7: A Comprehensive Guide</title><genre>Computer</genre><price>49.95</price><publish_date>2001-04-16</publish_date><description>Microsoft Visual Studio 7 is explored in depth, 126 looking at how Visual Basic, Visual C++, C#, and ASP+ are 127 integrated into a comprehensive development 128 environment.</description></book></catalog>`; 129 } 130 #isOpenFromDrive() { 131 const params = new URLSearchParams(document.location.search); 132 let state = JSON.parse(params.get("state")); 133 return !!state 134 && state.action === "open" 135 && !!state.ids 136 && !!state.ids[0]; 137 } 138 #checkCreateFromDrive() { 139 const params = new URLSearchParams(document.location.search); 140 let state = JSON.parse(params.get("state")); 141 if (!!state 142 && state.action === "create" 143 && !!state.folderId) { 144 this.#folderId = state.folderId; 145 } 146 } 147 async #readFromDrive() { 148 const params = new URLSearchParams(document.location.search); 149 let state = JSON.parse(params.get("state")); 150 const fileId = state.ids[0]; 151 let drive = this.#pnlFile.drive; 152 if (drive === undefined) { 153 drive = await this.initDrive(); 154 } 155 const file = await drive.downloadFileAsync(fileId); 156 var dec = new TextDecoder("utf-8"); 157 this.#xmlString.value = dec.decode(file); 158 } 159 async initDrive() { 160 const infoEl = document.querySelector("#loader"); 161 if (!infoEl) { 162 throw new Error("Missing OAuth2 information"); 163 } 164 let OAuth = { 165 clientId: infoEl.getAttribute("data-client-id"), 166 scope: infoEl.getAttribute("data-scope"), 167 apiKey: infoEl.getAttribute("data-api-key"), 168 projectNumber: infoEl.getAttribute("data-project-number") 169 }; 170 return await DriveService.createAsync(OAuth, true); 171 } 172 static register() { 173 FilePanelElement.register(); 174 customElements.define("main-app", this); 175 } 176} 177//# sourceMappingURL=MainApp.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.