>Форум Mozilla Россия http://forum.mozilla-russia.org/index.php >Сustom Buttons http://forum.mozilla-russia.org/viewforum.php?id=34 >[CB] Экспорт стилей Stylish http://forum.mozilla-russia.org/viewtopic.php?id=55106 |
hydrolizer > 30-05-2012 07:57:04 |
Недавно мне понадобилась возможность экспорта стилей Stylish - всех - в один текстовый файл. Я её реализовал в своем расширении-сборнике кода, если кому понадобится - ниже кнопка, делающая то же самое. Выделить код Код:(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); })(); |
iDev.Pi > 31-05-2012 02:08:25 |
удобно для миграции на User Style Manager |
hydrolizer > 31-05-2012 03:32:29 |
iDev.Pi |
iDev.Pi > 31-05-2012 13:29:01 |
hydrolizer |
hydrolizer > 01-06-2012 12:41:29 |
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); })(); Добавляется уже не пункт меню, а подменю экспорта с двумя пунктами: экспорт в файл, и экспорт в набор файлов. Во втором случае имя файла определяется названием стиля. |
iDev.Pi > 02-06-2012 01:17:51 |
hydrolizer |
bunda1 > 02-06-2012 13:49:01 |
Советую заменить на иначе после открытия настройки панелей будет так: скрытый текст |
LongLogin > 02-06-2012 14:02:36 |
bunda1 |
hydrolizer > 02-06-2012 15:25:54 |
bunda1 |
bunda1 > 02-06-2012 16:07:42 |
hydrolizer |
Redee > 02-09-2014 21:22:42 |
Можно использовать расширение Stylish Sync > Лично я выключаю синхронизацию и делаю вручную через бэкапы. |
mahtanoronra > 27-02-2015 05:37:53 |
почему то кнопка на мозиле 31 1 1 не работает... CB 0058 еле нашёл)) |
difabor > 28-02-2015 00:50:02 |
Спасибо! Очень удобная штука! |
oleg953 > 02-02-2016 13:24:33 |
жаль что позно нашёл! Класс! 02-02-2016 13:43:30 |
voqabuhe > 02-02-2016 15:02:53 |
oleg953 пишет
|
bunda1 > 02-02-2016 15:10:21 |
oleg953 пишет
|
oleg953 > 02-02-2016 15:32:55 |
bunda1 пишет
отлично! спасибо |
_zt > 24-10-2016 21:25:27 |
Не совсем в тему, но пригодится тем кто ищет. Есть такое расширение Stylish-Custom, помимо прочих удобств добавляемых в Stylish, добавляет возможность бекапа стилей, каждый стиль в отдельный .css файл, плюс позволяет выбрать активные или неактивные стили для бэкапа, или вообще самостоятельно выбрать, что бэкапить. |
Ultima2m > 25-10-2016 05:19:09 |
Создать кнопку или положить в инициализацию другой скрытый текст Выделить код Код://Экспорт стилей 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); })(); Код создает подменю бэкапа в кнопке Stylish |