(() => { "use strict"; const prompt = Services.prompt, prefs = Services.prefs, startup = Services.startup, indent = prefs.getIntPref("devtools.editor.tabsize") || 4, url = "chrome://devtools/content/scratchpad/scratchpad.xul", menuPopup = this.appendChild(document.createElement("menupopup")), isRu = (() => {try {return prefs.getCharPref("general.useragent.locale").toLowerCase().match(/^[\w]+/)[0] == "ru"} catch(ex) {return false}})(), loc = isRu ? { s1: "Распаковать файл...", s2: "Запаковать файл...", s3: "Редактировать кнопку", s4: "Несохраненные изменения", s5: "Вы хотите сохранить изменения?", s6: "Сохранить и упаковать обратно", s7: "Не сохранять", s8: "Сохранить только в распакованном файле", s9: "Перезапустить браузер?", s10: "Вы должны перезапустить браузер для применения изменений.\n(Предупреждение: Все изменения в запакованном файле могут быть потеряны,\nесли не перезапустить браузер сейчас!)", s11: "Выбрать файл", s12: "Mozilla Lz4 и json файлы" } : { s1: "Decompress File...", s2: "Compress File...", s3: "Edit Button", s4: "Unsaved Changes", s5: "Do you want to save the changes?", s6: "Save and compress back", s7: "Don't Save", s8: "Save only to decompressed file", s9: "Restart Browser?", s10: "You need restart browser to apply changes.\n(Warning: You may loose all your changes in compressed file if does not restart now!)", s11: "Open File", s12: "Mozilla's Lz4 and json files format" }, compress = ([cfp, dcfp]) => { if (cfp && dcfp) return Task.spawn(function* () { const jsonString = yield OS.File.read(dcfp); yield OS.File.writeAtomic(cfp, jsonString, {compression: "lz4"}); }); }, decompress = ([cfp, dcfp]) => { if (cfp && dcfp) return Task.spawn(function* () { const jsonString = yield OS.File.read(cfp, {encoding: "utf-8", compression: "lz4"}); yield OS.File.writeAtomic(dcfp, JSON.stringify(JSON.parse(jsonString), null, indent), {encoding: "utf-8"}); }); }, restDlg = () => prompt.confirm(null, loc.s9, loc.s10) && startup.quit(startup.eAttemptQuit | startup.eRestart), savetDlg = (scratchpad, [cfp, dcfp]) => { const button = prompt.confirmEx(null, loc.s4, loc.s5, prompt.BUTTON_POS_0 * prompt.BUTTON_TITLE_IS_STRING + prompt.BUTTON_POS_1 * prompt.BUTTON_TITLE_IS_STRING + prompt.BUTTON_POS_2 * prompt.BUTTON_TITLE_IS_STRING, loc.s6, loc.s7, loc.s8, null, {value: false}); switch (button) { case 0: scratchpad.saveFile(() => compress([cfp, dcfp]).then(restDlg())); break; case 2: scratchpad.saveFile(); break; default: return; } }, filePicker = isDec => { const fpc = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); fpc.displayDirectory = FileUtils.getDir("ProfD", []); fpc.init(window, loc.s11, Ci.nsIFilePicker.modeOpen); fpc.appendFilter(loc.s12, isDec ? "*.jsonlz4; *.mozlz4;" : "*.json"); if (fpc.show() != Ci.nsIFilePicker.returnOK) return []; const file = fpc.file; if (!(file.exists() && file.isFile() && file.isReadable())) return []; const fp = file.path; return isDec ? [fp, fp + ".json"] : [/\.jsonlz4|\.mozlz4/i.test(fp) ? fp.split(/\.json$/i)[0] : fp + ".mozlz4", fp]; }; for (const [type, lbl, cmd] of [ ['menuitem', loc.s1, () => {const [cfp,dcfp] = filePicker(true); decompress([cfp,dcfp])}], ['menuitem', loc.s2, () => {const [cfp,dcfp] = filePicker(); compress([cfp,dcfp])}], ['menuseparator'], ['menuitem', loc.s3, () => custombuttons.editButton(this)] ]) { const node = menuPopup.appendChild(document.createElement(type)); lbl && node.setAttribute("label", lbl); cmd && (node.onclick = () => cmd()); }; this.onclick = this.oncontextmenu = e => { if (e.target != this) return; switch (e.button) { case 0: const [cfp,dcfp] = filePicker(true); if (!(cfp && dcfp)) return; decompress([cfp,dcfp]).then(() => { let scratchpad; const tab = gBrowser.selectedTab = gBrowser.addTab(url), br = tab.linkedBrowser, onPageShow = e => { const win = e.target.defaultView, {top} = win, doc = win.content.document; if (top.location.href == url && win.location.href.startsWith("data:")) { scratchpad = top.Scratchpad; scratchpad.hideMenu(); doc.getElementById("sp-toolbar").collapsed = true; const mItems = [...doc.getElementById("scratchpad-text-popup").children] mItems.slice(mItems.findIndex(el => el.id == "cMenu_selectAll") + 1).map(el => el.hidden = true) scratchpad.importFromFile(FileUtils.File(dcfp), false); } }; br.addEventListener("pageshow", onPageShow, false); tab.addEventListener("TabClose", function TabClose(e) { tab.removeEventListener("TabClose", TabClose, false); br.removeEventListener("pageshow", onPageShow, false); scratchpad.dirty && savetDlg(scratchpad, [cfp, dcfp]); }, false) }); break; case 1: document.popupNode = this; document.getElementById("custombuttons-contextpopup").openPopup(this, "after_start"); break; case 2: if (e.shiftKey || e.ctrlKey || e.altKey || e.metaKey) return; e.preventDefault(); e.stopPropagation(); menuPopup.openPopup(this, "after_start"); break; default: return } } })(); |