Страницы: 1
Недавно мне понадобилась возможность экспорта стилей Stylish - всех - в один текстовый файл. Я её реализовал в своем расширении-сборнике кода, если кому понадобится - ниже кнопка, делающая то же самое.
Экспортировать стили Stylish в текстовый файл. (Firefox 12+)
Автор: hydrolizer.
Описание: Kод добавляет в меню кнопки Stylish пункт "Экспортировать стили"; при выборе пункта предлагается указать файл экспорта, в который будут выгружены все имеющиеся стили Stylish.
Использование: положите код в любую Custom Buttons кнопку, в инициализацию. Не обязательно создавать новую CB кнопку, можно использовать уже существующую.
(function() { if (document.getElementById("stylish-export-styles-to-file")) return; let sn = document.evaluate("//xul:popupset[@id='mainPopupSet']/descendant::xul:menuitem[@id='stylish-manage']/following-sibling::node()[position()=1]", document, function() { return "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; }, Ci.nsIDOMXPathResult.ANY_UNORDERED_NODE_TYPE, null); var menuitem = document.createElement("menuitem"); menuitem.id = "stylish-export-styles"; menuitem.setAttribute("label", "Экспортировать стили"); sn.singleNodeValue.parentNode.insertBefore(menuitem, sn.singleNodeValue); menuitem.addEventListener("click", function(event) { var fp=Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); fp.init(window, "Укажите файл экспорта", Ci.nsIFilePicker.modeSave); fp.appendFilter("Каскадные таблицы стилей (css)","*.css"); var res = fp.show(); if (res == Ci.nsIFilePicker.returnCancel) return null; var cssFile = fp.file; if (!/\.css/i.test(cssFile.path)) cssFile.initWithPath(cssFile.path+".css"); Components.utils.import("resource://gre/modules/Services.jsm"); var dbFile = Services.dirsvc.get("ProfD", Ci.nsIFile); dbFile.append("stylish.sqlite"); var ssvc=Cc["@mozilla.org/storage/service;1"].getService(Ci.mozIStorageService); var mDBConn = ssvc.openDatabase(dbFile); var stmt = mDBConn.createStatement("SELECT name, code from styles"); stmt.executeAsync( { results: [], handleResult: function(aResultSet) { for (let row = aResultSet.getNextRow(); row; row = aResultSet.getNextRow()) this.results = this.results.concat( ["/*", row.getResultByName("name"),"*/",row.getResultByName("code"),""]); }, handleError: function(aError) { Services.prompt.alert(null, "Ошибка выполнения запроса", aError.message); }, handleCompletion: function(aReason) { mDBConn.asyncClose(); Cu.import("resource://gre/modules/FileUtils.jsm"); Cu.import("resource://gre/modules/NetUtil.jsm"); var ostream = FileUtils.openSafeFileOutputStream(cssFile) var converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter); converter.charset = "UTF-8"; var istream = converter.convertToInputStream(this.results.join("\n")); NetUtil.asyncCopy(istream, ostream, (function(status) { if (!Components.isSuccessCode(status)) Services.prompt.alert(null, "Ошибка","Ошибка сохранения стилей (код: "+status+")"); else custombuttons.alertSlide("Экспорт стилей Stylish", "Стили успешно экспортированы."); }).bind(this)); } }); }, false); })();
Отредактировано hydrolizer (02-06-2012 15:17:24)
Отсутствует
iDev.Pi
По отдельности - т.е. все стили, и отдельный файл для каждого стиля?
Отсутствует
iDev.Pi
вот:
function Exporter(toFileSet) { Object.defineProperty(this, "toFileSet", {get: function(){ return toFileSet; }}); var converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter); converter.charset = "UTF-8"; Object.defineProperty(this, "converter", {get: function(){ return converter; }}); }; Exporter.prototype= { styles: null, mDBConn: null, exportFile: null, toString: function() { return "[custombuttons.stylish-exporter]"; }, handleEvent: function(event) { this.exportFile = this.toFileSet ? this.pickDirectory() : this.pickFile(); if (!this.exportFile) return; this.getStyles(); }, pickFile: function() { var fp=Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); fp.init(window, "Укажите файл экспорта", Ci.nsIFilePicker.modeSave); fp.appendFilter("Каскадные таблицы стилей (css)","*.css"); var res = fp.show(); if (res == Ci.nsIFilePicker.returnCancel) return null; var cssFile = fp.file; if (!/\.css$/i.test(cssFile.path)) cssFile.initWithPath(cssFile.path+".css"); return cssFile; }, pickDirectory: function() { var fp=Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); fp.init(window, "Укажите папку для экспорта", Ci.nsIFilePicker.modeGetFolder); return fp.show()==Ci.nsIFilePicker.returnOK ? fp.file : null; }, getStyles: function() { var dbFile = Services.dirsvc.get("ProfD", Ci.nsIFile); dbFile.append("stylish.sqlite"); var ssvc=Cc["@mozilla.org/storage/service;1"].getService(Ci.mozIStorageService); this.mDBConn = ssvc.openDatabase(dbFile); var stmt = this.mDBConn.createStatement("SELECT name, code from styles"); this.styles=[]; stmt.executeAsync(this); }, prepareStyles: function() { var data; if (!this.toFileSet) { var content = []; this.styles.forEach(function(elem) { content = content.concat(["/*", elem.name,"*/", elem.style, ""]); }); data=[{file: this.exportFile, content: content.join("\n")}]; } else { data=this.styles.map((function(elem) { var file = this.exportFile.clone(); file.append(elem.name.replace(/[\\\/\:\*\?"<>\|]/g,"-").replace(/^\.|\.$/g,"_")+".css"); return {file: file, content: ["/*", elem.name,"*/", elem.style].join("\n")}; }).bind(this)); } this.saveStyles(data); }, saveStyles: function(data) { if (data.length==0) { custombuttons.alertSlide("Экспорт стилей Stylish", "Стили успешно экспортированы."); return; } Cu.import("resource://gre/modules/FileUtils.jsm"); Cu.import("resource://gre/modules/NetUtil.jsm"); var style = data.shift(); var ostream = FileUtils.openSafeFileOutputStream(style.file) var istream = this.converter.convertToInputStream(style.content); NetUtil.asyncCopy(istream, ostream, (function(status) { if (!Components.isSuccessCode(status)) Services.prompt.alert(null, "Ошибка","Ошибка сохранения стилей (код: "+status+")"); else this.saveStyles(data); }).bind(this)); }, handleResult: function(aResultSet) { for (let row = aResultSet.getNextRow(); row; row = aResultSet.getNextRow()) this.styles.push({name: row.getResultByName("name"), style: row.getResultByName("code")}); }, handleError: function(aError) { Services.prompt.alert(null, "Ошибка выполнения запроса", aError.message); }, handleCompletion: function(aReason) { this.mDBConn.asyncClose((function() { delete this.mDBConn; }).bind(this)); this.prepareStyles(); } }; (function() { if (document.getElementById("stylish-export-styles-to-file")) return; var miToSingleFile = document.createElement("menuitem"); miToSingleFile.id = "stylish-export-styles-to-file"; miToSingleFile.setAttribute("label", "в файл"); var miToSetFiles = document.createElement("menuitem"); miToSetFiles.id = "stylish-export-styles-to-set-files"; miToSetFiles.setAttribute("label", "в набор файлов"); var popup = document.createElement("menupopup"); popup.appendChild(miToSingleFile); popup.appendChild(miToSetFiles); var menu = document.createElement("menu"); menu.id="stylish-export-styles"; menu.setAttribute("label","Экспортировать стили"); menu.appendChild(popup); let sn = document.evaluate("//xul:popupset[@id='mainPopupSet']/descendant::xul:menuitem[@id='stylish-manage']/following-sibling::node()[position()=1]", document, function() { return "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; }, Ci.nsIDOMXPathResult.ANY_UNORDERED_NODE_TYPE, null); sn.singleNodeValue.parentNode.insertBefore(menu, sn.singleNodeValue); miToSingleFile.addEventListener("click", new Exporter(false), false); miToSetFiles.addEventListener("click", new Exporter(true), false); })();
Добавляется уже не пункт меню, а подменю экспорта с двумя пунктами: экспорт в файл, и экспорт в набор файлов. Во втором случае имя файла определяется названием стиля.
Отредактировано hydrolizer (02-06-2012 15:17:00)
Отсутствует
Советую заменить
на
иначе после открытия настройки панелей будет так:
Отредактировано bunda1 (02-06-2012 14:37:49)
Отсутствует
bunda1
Заменил. Но, надо сказать, этот кусок кода был полностью скопипащен из кода вот этой кнопки - у меня же это не кнопка; пункты меню вставляются совсем другим образом, и этих проверок не требуется.
Отсутствует
hydrolizer
Это такой баг Сustom Buttons, при открытия настройки панелей код из вкладки инициализации кнопки инициализируется повторно и это надо блокировать иначе твой код добавит новый пункт меню и так каждый раз.
Но блок if (stop) return; не сработал, не знаю почему.
Отредактировано bunda1 (02-06-2012 16:13:09)
Отсутствует
Можно использовать расширение Stylish Sync >
https://addons.mozilla.org/ru/firefox/a … ylishsync/
Лично я выключаю синхронизацию и делаю вручную через бэкапы.
Отсутствует
почему то кнопка на мозиле 31 1 1 не работает... CB 0058
еле нашёл))
Отредактировано mahtanoronra (27-02-2015 06:15:18)
Отсутствует
а для кнопок нечто подобное?
Отсутствует
а для кнопок нечто подобное?
Отсутствует
Не совсем в тему, но пригодится тем кто ищет. Есть такое расширение Stylish-Custom, помимо прочих удобств добавляемых в Stylish, добавляет возможность бекапа стилей, каждый стиль в отдельный .css файл, плюс позволяет выбрать активные или неактивные стили для бэкапа, или вообще самостоятельно выбрать, что бэкапить.
Отсутствует
Создать кнопку или положить в инициализацию другой
//Экспорт стилей Stylish в меню кнопки ................................................................................................................. function Exporter(toFileSet) { Object.defineProperty(this, "toFileSet", {get: function(){ return toFileSet; }}); var converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter); converter.charset = "UTF-8"; Object.defineProperty(this, "converter", {get: function(){ return converter; }}); }; Exporter.prototype= { styles: null, mDBConn: null, exportFile: null, toString: function() { return "[custombuttons.stylish-exporter]"; }, handleEvent: function(event) { this.exportFile = this.toFileSet ? this.pickDirectory() : this.pickFile(); if (!this.exportFile) return; this.getStyles(); }, pickFile: function() { var fp=Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); fp.init(window, "Укажите файл экспорта", Ci.nsIFilePicker.modeSave); fp.appendFilter("Каскадные таблицы стилей (css)","*.css"); var res = fp.show(); if (res == Ci.nsIFilePicker.returnCancel) return null; var cssFile = fp.file; if (!/\.css$/i.test(cssFile.path)) cssFile.initWithPath(cssFile.path+".css"); return cssFile; }, pickDirectory: function() { var fp=Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); fp.init(window, "Укажите папку для экспорта", Ci.nsIFilePicker.modeGetFolder); return fp.show()==Ci.nsIFilePicker.returnOK ? fp.file : null; }, getStyles: function() { var dbFile = Services.dirsvc.get("ProfD", Ci.nsIFile); dbFile.append("stylish.sqlite"); var ssvc=Cc["@mozilla.org/storage/service;1"].getService(Ci.mozIStorageService); this.mDBConn = ssvc.openDatabase(dbFile); var stmt = this.mDBConn.createStatement("SELECT name, code from styles"); this.styles=[]; stmt.executeAsync(this); }, prepareStyles: function() { var data; if (!this.toFileSet) { var content = []; this.styles.forEach(function(elem) { content = content.concat(["/*", elem.name,"*/", elem.style, ""]); }); data=[{file: this.exportFile, content: content.join("\n")}]; } else { data=this.styles.map((function(elem) { var file = this.exportFile.clone(); file.append(elem.name.replace(/[\\\/\:\*\?"<>\|]/g,"-").replace(/^\.|\.$/g,"_")+".css"); return {file: file, content: ["/*", elem.name,"*/", elem.style].join("\n")}; }).bind(this)); } this.saveStyles(data); }, saveStyles: function(data) { if (data.length==0) { custombuttons.alertSlide("Экспорт стилей Stylish", "Стили успешно экспортированы."); return; } Cu.import("resource://gre/modules/FileUtils.jsm"); Cu.import("resource://gre/modules/NetUtil.jsm"); var style = data.shift(); var ostream = FileUtils.openSafeFileOutputStream(style.file) var istream = this.converter.convertToInputStream(style.content); NetUtil.asyncCopy(istream, ostream, (function(status) { if (!Components.isSuccessCode(status)) Services.prompt.alert(null, "Ошибка","Ошибка сохранения стилей (код: "+status+")"); else this.saveStyles(data); }).bind(this)); }, handleResult: function(aResultSet) { for (let row = aResultSet.getNextRow(); row; row = aResultSet.getNextRow()) this.styles.push({name: row.getResultByName("name"), style: row.getResultByName("code")}); }, handleError: function(aError) { Services.prompt.alert(null, "Ошибка выполнения запроса", aError.message); }, handleCompletion: function(aReason) { this.mDBConn.asyncClose((function() { delete this.mDBConn; }).bind(this)); this.prepareStyles(); } }; (function() { if (document.getElementById("stylish-export-styles-to-file")) return; var miToSingleFile = document.createElement("menuitem"); miToSingleFile.id = "stylish-export-styles-to-file"; miToSingleFile.setAttribute("label", "В файл"); var miToSetFiles = document.createElement("menuitem"); miToSetFiles.id = "stylish-export-styles-to-set-files"; miToSetFiles.setAttribute("label", "В набор файлов"); var popup = document.createElement("menupopup"); popup.appendChild(miToSingleFile); popup.appendChild(miToSetFiles); var menu = document.createElement("menu"); menu.id="stylish-export-styles"; menu.setAttribute("label","Экспортировать стили"); menu.appendChild(popup); let sn = document.evaluate("//xul:popupset[@id='mainPopupSet']/descendant::xul:menuitem[@id='stylish-manage']/following-sibling::node()[position()=1]", document, function() { return "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; }, Ci.nsIDOMXPathResult.ANY_UNORDERED_NODE_TYPE, null); sn.singleNodeValue.parentNode.insertBefore(menu, sn.singleNodeValue); miToSingleFile.addEventListener("click", new Exporter(false), false); miToSetFiles.addEventListener("click", new Exporter(true), false); })();
Отсутствует
Страницы: 1