Полезная информация

Хотите узнать больше о расширениях? Посмотрите ролики, рассказывающие о работе с расширениями Firefox.

№1437603-03-2020 13:28:57

solombala
Забанен
 
Группа: Members
Зарегистрирован: 20-07-2019
Сообщений: 652
UA: Firefox 73.0

Re: Custom Buttons

Dumby
Вроде - гуд ! Только наоборот..

скрытый текст

Выделить код

Код:

((id, g) => {
    addDestructor(r => r[5] == "e" && id in g && g[id].destroy());
    if (g[id]) return;
    var topic = "quit-application-granted", {obs} = Services;
    obs.addObserver(g[id] = {
        // true - disable, false - enable
        states: {
            "addon_to@disable": true,
            "{6acd0f4d-ab79-4b79-9b28-8bde65ae355c}": false,

            "addon_to@enable": true,
            "@hoxx-vpn": true,
            "vkomforte-we@vkomforte": true,
        },
        filter(addon) {
            var state = this.states[addon.id];
            if (
                state !== undefined && addon.userDisabled != state
                && addon.type.endsWith("extension")
                && addon.location.name != "app-builtin"
            ) {
                addon.active = addon.location.get(addon.id).enabled
                    = !(addon.userDisabled = state);
                return true;
            }
        },
        observe() {
            this.destroy();
            if (g.XPIDatabase.getAddons().filter(this.filter, this).length)
                g.XPIDatabase.saveChanges(), g.XPIStates.save();
        },
        destroy() {
            delete g[id];
            obs.removeObserver(this, topic);
        }
    }, topic, false);
})(
    "CBQuitApplicationExtensionsSwitcher",
    Cu.import("resource://gre/modules/addons/XPIDatabase.jsm", {})
);


ДА, а продолжить  здесь можно? В смысле, еще какой аддон добавиться...
"addon_to@disable": true,
            "{6acd0f4d-ab79-4b79-9b28-8bde65ae355c}": false,

Отредактировано solombala (03-03-2020 13:30:47)

Отсутствует

 

№1437703-03-2020 17:32:10

dezhnev
Участник
 
Группа: Members
Зарегистрирован: 21-04-2016
Сообщений: 72
UA: Firefox 73.0

Re: Custom Buttons

Dumby
Снимаю шляпу, все как обычно, ничего лишнего.

Может пока посмотрел, глянешь, если время будет, возможно ли уменьшить эти 3 расстояния,
которые изобразил на картинке?
dumby_bm.png

Добавлено 03-03-2020 17:35:16
что-то не редактируется сообщение или забыл уже как :)
вобщем через attributesInspector.js ничего найти не могу, где ужать, где уменьшить, где убрать

Отредактировано dezhnev (03-03-2020 17:35:16)

Отсутствует

 

№1437804-03-2020 09:31:59

Dumby
Участник
 
Группа: Members
Зарегистрирован: 12-08-2012
Сообщений: 2254
UA: Firefox 52.0

Re: Custom Buttons

solombala пишет

ДА, а продолжить  здесь можно? В смысле, еще какой аддон добавиться...

Конечно можно. Даже непонятно откуда могло взяться сомнение.

dezhnev пишет

через attributesInspector.js ничего найти не могу, где ужать, где уменьшить, где убрать

Деревья. Вот такой, например, стиль вроде соответствует.
Сверху — предположительно твои один, два, три,
снизу — попытка симуляции того, что уже есть на картинке.

скрытый текст

Выделить код

Код:

@-moz-document url(chrome://browser/content/places/bookmarksSidebar.xhtml) {

    treechildren {
        margin-left: -2px !important;
    }
    treechildren::-moz-tree-indentation {
        width: 2px !important;
    }
    treechildren::-moz-tree-image {
        margin-right: -1px !important;
    }

    /************************************************/

    treechildren::-moz-tree-row {
        min-height: 18px !important;
    }
    treechildren::-moz-tree-twisty {
        width: 0 !important;
        padding: 0 !important;
    }
}

Отсутствует

 

№1437904-03-2020 10:46:03

_backup
Участник
 
Группа: Members
Зарегистрирован: 12-02-2007
Сообщений: 25
UA: unknown 0.0

Re: Custom Buttons

Есть код, который сохраняет выделенный текст в файл:

Выделить код

Код:

// Сохранить выделенный текст в один файл из контекстного меню

((contextMenu, el)=> {
   var menuitem = contextMenu.insertBefore(document.createElement("menuitem"), el);
   menuitem.id = "content-saveTextItem";
   menuitem.setAttribute("label", "Сохранить выделенный текст в файл");
   addDestructor(()=> menuitem.remove());
   addEventListener('popupshowing', e=> menuitem.hidden = !gContextMenu.isTextSelected, false, contextMenu); 
   menuitem.onclick =e=> e.button ? setPathToFile() : saveSelectionToFile();
   
   function saveSelectionToFile() {
      try { var pathToFile = gPrefService.getComplexValue("CB.saveSelectionToFile", Ci.nsISupportsString).data }
      catch(e) { setPathToFile() };
      var title = convertFromUnicode("UTF-8", getTabLabel());
      var selection = gBrowser.contentDocument.defaultView.getSelection().toString();
      var text = convertFromUnicode("UTF-8", selection) + "\n\n\n\n\n";
      
      var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
      file.initWithPath(pathToFile);
      
      var foStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
      file.exists() ? foStream.init(file, 0x02 | 0x10, 0664, 0) : foStream.init(file, 0x02|0x08|0x20, 0666, 0);
      foStream.write(text, text.length);
      foStream.close();
      
      document.activeElement.blur();  
      setTimeout(()=> window.content.focus(), 300);
   };
   
   function setPathToFile() {     
      var fp = window.makeFilePicker();
      fp.init(window, "Создайте текстовой файл для сохранения текста!", fp.modeSave);
      fp.appendFilters(fp.filterText);
      fp.defaultString = getTabLabel();
      fp.open(result => result == fp.returnOK && cbu.setPrefs("CB.saveSelectionToFile", convertFromUnicode("UTF-8", fp.file.path) + ".txt"));
   };
   
   function convertFromUnicode(charset, str) {
      var converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter);
      converter.charset = charset;
      str = converter.ConvertFromUnicode(str);
      return str + converter.Finish();
   };
   
   function getTabLabel() { 
      var label = gBrowser.mCurrentTab.label;      
      var label = label.replace(/[:+.\\\/<>?*|"]+/g, " ").replace(/\s\s+/g, " ");
      return label.substring(0, 50);
   };
})(document.getElementById("contentAreaContextMenu"), document.getElementById("context-sep-open"));

Можно ли сделать так, что бы он вначале добавлял url той страницы из которой был сохранен?

Отредактировано _backup (04-03-2020 10:52:46)

Отсутствует

 

№1438004-03-2020 11:56:30

solombala
Забанен
 
Группа: Members
Зарегистрирован: 20-07-2019
Сообщений: 652
UA: Firefox 73.0

Re: Custom Buttons

Dumby
От теперь полный фарш ...Тем более под аэро запросто подстраиваю . Последние коды - это нечто , столько проблем и сразу...Класс!

Отсутствует

 

№1438104-03-2020 12:15:17

ALEX_45_ORP
Участник
 
Группа: Members
Зарегистрирован: 18-01-2018
Сообщений: 162
UA: Firefox 73.0

Re: Custom Buttons

solombala

solombala пишет

Тем более под аэро запросто подстраиваю . Последние коды - это нечто , столько проблем и сразу...Класс!

просто уже не терпится увидеть 74 в твоем исполнении, а релиз выйдет только 10 марта ...

Отредактировано ALEX_45_ORP (04-03-2020 13:15:54)


Win 10х64

Отсутствует

 

№1438204-03-2020 19:18:35

unter_officer
Участник
 
Группа: Members
Откуда: Санкт-Петербург
Зарегистрирован: 27-03-2011
Сообщений: 604
UA: Firefox 48.0

Re: Custom Buttons

_backup пишет

Можно ли сделать так, что бы он вначале добавлял url той страницы из которой был сохранен?

скрытый текст

Выделить код

Код:

/*Initialization Code*/

// Сохранить выделенный текст в один файл из контекстного меню

((contextMenu, el)=> {
   var menuitem = contextMenu.insertBefore(document.createElement("menuitem"), el);
   menuitem.id = "content-saveTextItem";
   menuitem.setAttribute("label", "Сохранить выделенный текст в файл");
   addDestructor(()=> menuitem.remove());
   addEventListener('popupshowing', e=> menuitem.hidden = !gContextMenu.isTextSelected, false, contextMenu); 
   menuitem.onclick =e=> e.button ? setPathToFile() : saveSelectionToFile();
   
   function saveSelectionToFile() {
      try { var pathToFile = gPrefService.getComplexValue("CB.saveSelectionToFile", Ci.nsISupportsString).data }
      catch(e) { setPathToFile() };
      var title = convertFromUnicode("UTF-8", getTabLabel());
      var selection = gBrowser.contentDocument.defaultView.getSelection().toString();
      var url = gBrowser.currentURI.spec;
      var text = convertFromUnicode("UTF-8", url + "\n" + selection) + "\n\n\n\n\n";
      
      var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
      file.initWithPath(pathToFile);
      
      var foStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
      file.exists() ? foStream.init(file, 0x02 | 0x10, 0664, 0) : foStream.init(file, 0x02|0x08|0x20, 0666, 0);
      foStream.write(text, text.length);
      foStream.close();
      
      document.activeElement.blur();  
      setTimeout(()=> window.content.focus(), 300);
   };
   
   function setPathToFile() {     
      var fp = window.makeFilePicker();
      fp.init(window, "Создайте текстовой файл для сохранения текста!", fp.modeSave);
      fp.appendFilters(fp.filterText);
      fp.defaultString = getTabLabel();
      fp.open(result => result == fp.returnOK && cbu.setPrefs("CB.saveSelectionToFile", convertFromUnicode("UTF-8", fp.file.path) + ".txt"));
   };
   
   function convertFromUnicode(charset, str) {
      var converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter);
      converter.charset = charset;
      str = converter.ConvertFromUnicode(str);
      return str + converter.Finish();
   };
   
   function getTabLabel() { 
      var label = gBrowser.selectedTab.label;      
      var label = label.replace(/[:+.\\\/<>?*|"]+/g, " ").replace(/\s\s+/g, " ");
      return label.substring(0, 50);
   };
})(document.getElementById("contentAreaContextMenu"), document.getElementById("context-sep-open"));


«The Truth Is Out There»

Отсутствует

 

№1438304-03-2020 20:51:05

func4ptch4
Участник
 
Группа: Members
Зарегистрирован: 03-05-2018
Сообщений: 220
UA: Firefox 75.0

Re: Custom Buttons

Dumby, №14402
Если я правильно понял, он при выходе вкл-откл заданные аддоны? А можно его совместить с этим кодом?

скрытый текст

Выделить код

Код:

self.label="ToggleAddons[Fx]";self.image="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABy0lEQVQ4jbWTz2sUMRiGn2Qmmewy47LLzir0D1BaQYUea/EwBQ9OFNuoFF2x0kHwoKgnLwYsXr0LHvQgKhbBivSk0n8sXjYlXdijuX3J+7xf3vyA/zCuAB+Brq7rM13XKe99HkIQieYysJFCfeAB8Bq4CvwdDAarRVE8Vkq9zbKsBWpgF3gGXAJupKZPgArAey+Vyv8sLdUXrbWV914Cz4EjYBiBLMtuee/zWN+NsLW2Kgp9OJlMLsxggC3gfRR776UxZtp1nYpzt0MIwlpbNU0z0FofFkVxNom4CXxImxhjdtIdbDvnek3TDKy1lRDiF3AuMbgGfIlw0zQDY8zO8RkopXbbtu0nmX8Ay4lBK4T4HmFrbZVl2fR4VSnVOed6SeZPwEpyYK3W+iDCM9291OD+3D3vA+dj5rIsN4tCHyQwJwyAbU6Ob8BKzFyW5ZbWej+BAaYpMG/wWWu9HDNXVXVdSvl1TjNdVNRCiKOyLO/EzHmerwM/E80IeJrGfgisAq+klC/H4/HqcDhcM8bsSSlfzBr8Bm4Cb4BHo9HoVPoONoA17710zvXatu0753qzDqeBPeAdsA4QQhDOuV76EgkhCO99vuD3LdT9A4TPkK2vNlObAAAAAElFTkSuQmCC";
 this.onclick=e=>
{if(e.button==0&&!e.ctrlKey)AddP();                                                                                                      //L
//if(e.button==0&& e.ctrlKey)f();                                                                                                            //Ctrl+L
//if(e.button==2&& e.ctrlKey){e.preventDefault();f();};                                                                         //Ctrl+R
 if(e.button==2&&!e.ctrlKey&&!e.shiftKey&&!e.altKey&&!e.metaKey){e.preventDefault();AddO();}};  //R
 this.tooltipText=self.label+"\nL: On/Off ProxyAddons\nR: On/Off OtherAddons";
//------------------------------------------------------------------------------------------
//forum.mozilla-russia.org/viewtopic.php?pid=777986#p777986
function AddP(){var args=[addon=>addon[addon.userDisabled?"enable":"disable"]({allowSystemAddons:true}),Cu.reportError];
for(var id of["....","...."])AddonManager.getAddonByID(id).then(...args);};
function AddO(){var args=[addon=>addon[addon.userDisabled?"enable":"disable"]({allowSystemAddons:true}),Cu.reportError];
for(var id of["bookmarksorganizer@agenedia.com","webscrapbook@danny0838.addons.mozilla.org","....","...."])AddonManager.getAddonByID(id).then(...args);};

Отсутствует

 

№1438404-03-2020 23:05:13

voqabuhe
Участник
 
Группа: Members
Зарегистрирован: 06-12-2011
Сообщений: 3231
UA: Firefox 73.0

Re: Custom Buttons

unter_officer пишет

// Сохранить выделенный текст в один файл из контекстного меню

Так и должно быть, что после установки кнопки, контекстное меню на выделенном тексте стало в одну строчку из четырёх пунктов?

Отсутствует

 

№1438505-03-2020 01:51:05

unter_officer
Участник
 
Группа: Members
Откуда: Санкт-Петербург
Зарегистрирован: 27-03-2011
Сообщений: 604
UA: Firefox 48.0

Re: Custom Buttons

voqabuhe пишет

Так и должно быть, что после установки кнопки, контекстное меню на выделенном тексте стало в одну строчку из четырёх пунктов?

Так быть не должно. И скорее всего эта кнопка не работает на последних версиях [firefox], мне не на чем проверить.

Отредактировано unter_officer (05-03-2020 01:52:46)


«The Truth Is Out There»

Отсутствует

 

№1438605-03-2020 10:55:31

_backup
Участник
 
Группа: Members
Зарегистрирован: 12-02-2007
Сообщений: 25
UA: unknown 0.0

Re: Custom Buttons

unter_officer, огромное спасибо за код. На FF 56 работает.

Отсутствует

 

№1438705-03-2020 14:03:55

Andrey_Krropotkin
Участник
 
Группа: Members
Зарегистрирован: 11-11-2011
Сообщений: 484
UA: Firefox 73.0

Re: Custom Buttons

Dumby вот добавил в твой код

скрытый текст

Выделить код

Код:

// Добавить кнопки в диалог сохранения файла..........................................................................................
((id, g) => {
    addDestructor(r => r[5] == "e" && id in g && g[id].destroy(true));
    if (g[id]) return;
    var topics = ["widget-first-paint", "quit-application-granted"], {nsIFile} = Ci;
    var {obs, wm, dirsvc} = Services, uct = "unknownContentType", ends = `/${uct}.xhtml`;
    (g[id] = {
        init() {
            for(var topic of topics) obs.addObserver(g[id], topic, false);
            this.wins();
        },
        destroy(wins) {
            delete g[id];
            for(var topic of topics) obs.removeObserver(this, topic);
            wins && this.wins("removeBtn");
        },
        btn(win, method = "addBtn") {
            win.location.href.endsWith(ends) && this[method](win.document);
        },
        wins(method) {
            for(var win of wm.getEnumerator(null)) this.btn(win, method);
        },
        observe(win, topic) {
            topic[0] == "q" ? this.destroy() : this.btn(win);
        },
        get data() {
            var o = g.Object, d = key => dirsvc.get(key, nsIFile).path;
            delete this.data;
            return this.data = o.assign(o.create(null), {

                "Рабочий стол": d("Desk"),
                "chrome": d("UChrm"),
                "chrome\\CSS": d("UChrm") + "\\CSS",
                "C:": "C:\\",
                "E:": "E:\\",
                "F:": "F:\\",
                "G:": "G:\\",
            });
        },
        addBtn(doc) {
            var df = doc.createDocumentFragment();

            var btn1 = doc.cbSaveToButton = df.appendChild(doc.createXULElement("button"));
            btn1.label = "Сохранить как";
            btn1.className = "dialog-button";
            btn1.setAttribute("oncommand", "handleCommand(event.target)");
            btn1.handleCommand = this.cmdf;
            doc.getElementById(uct).getButton("extra1").before(df);

            var btn = doc.cbSaveToButton = df.appendChild(doc.createXULElement("button"));
            btn.label = "Сохранить в";
            btn.className = "dialog-button";

            var popup = btn.appendChild(doc.createXULElement("menupopup"));
            popup.setAttribute("oncommand", "handleCommand(event.target)");
            popup.handleCommand = this.cmd;

            for(var lab in this.data) {
                var menuitem = popup.appendChild(doc.createXULElement("menuitem"));
                menuitem.label = lab;
                menuitem.dir = this.data[lab];
                menuitem.className = "menuitem-iconic";
                menuitem.image = "moz-icon:file:///" + menuitem.dir;
            }
            doc.getElementById(uct).getButton("cancel").before(df);
            btn.type = "menu";
        },
        removeBtn(doc) {
            if (doc.cbSaveToButton) doc.cbSaveToButton.remove(), delete doc.cbSaveToButton;
        },
        cmdf(trg) {
         var win = trg.ownerGlobal;
         var file = (win.dialog.promptForSaveToFileAsync || win.dialog.promptForSaveToFile).call(win.dialog, win.dialog.mLauncher, window, win.dialog.mLauncher.suggestedFileName, "", true);
                    if (file) {
                        win.dialog.mLauncher.saveToDisk(file, 1);
                        win.dialog.onCancel = function() {};
                        win.close();
                    }
        },
        cmd(trg) {
            var file = h.Components.Constructor(
                "@mozilla.org/file/local;1", nsIFile, "initWithPath"
            )(trg.dir);
            var win = trg.ownerGlobal;
            file.append(win.document.getElementById("location").getAttribute("realname"));
            win.dialog.mLauncher.saveToDisk(file, 1);
            win.dialog.onCancel = function() {};
            win.close();
        }
    }).init();
})("CBUnknownContentTypeSaveToButtonizer", Cu.getGlobalForObject(Cu));


Вроде как работает нормально, но нет ли тут ошибок и второе при выборе кнопки "сохранить как" в диалоге сохранения - диалог выбора пути открывается, файл сохраняется, диалог выбора пути закрывается, но окно диалога сохранения само не хочет закрываться, приходится вручную. Можно ли это подправить?

Отсутствует

 

№1438805-03-2020 15:09:05

xrun1
Участник
 
Группа: Members
Зарегистрирован: 12-12-2013
Сообщений: 1227
UA: Firefox 73.0

Re: Custom Buttons

На 73.0.1 вдруг заглючил профиль, на странице введения пароля почты Google/Youtube экран серый. Ну и так по мелочи. Решил переустановить, но нарисовалась проблемка. После добавления в новый профиль файла search.json.mozlz4 не показываются иконки у двух поисков и Яндекса. Это стандартные поиски, Google и Википедия (ru). Старый профиль показывал иконки.

скрытый текст
opol3xH.png

Наверное, всё было прописано в prefs.js, но где искать? Где-то на форуме было... Подскажите, как распотрошить search.json.mozlz4 и прописать туда иконки. Кажется, похожий вопрос был у solombala.
Извините, если не в ту тему.

Отсутствует

 

№1438905-03-2020 16:07:32

solombala
Забанен
 
Группа: Members
Зарегистрирован: 20-07-2019
Сообщений: 652
UA: Firefox 73.0

Re: Custom Buttons

xrun1
https://www.upload.ee/files/11225480/______.rar.html

Отредактировано solombala (05-03-2020 16:09:20)

Отсутствует

 

№1439005-03-2020 16:49:13

unter_officer
Участник
 
Группа: Members
Откуда: Санкт-Петербург
Зарегистрирован: 27-03-2011
Сообщений: 604
UA: Firefox 48.0

Re: Custom Buttons

Подскажите, как распотрошить search.json.mozlz4

Есть кнопка для СВ, то ли turbot делал, то ли yup, сейчас уже не вспомню. Но эта кнопка вроде выше 52-ой версии FF не работает.
Может кто переделает под последние версии FF?

скрытый текст

Выделить код

Код:

/*CODE*/

// Mozilla's Lz4 files format Compressor/Decompresser. ..........
var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(Components.interfaces.nsIFilePicker);
fp.displayDirectory = FileUtils.getDir("ProfD", []);
fp.init(window, "Open File", Components.interfaces.nsIFilePicker.modeOpen);
fp.appendFilter("Mozilla's Lz4 and json files format", "*.jsonlz4; *.mozlz4; *.json");
if (fp.show() == Components.interfaces.nsIFilePicker.returnOK) {
  var file = fp.file;
  if (file.exists() && file.isFile() && file.isReadable()) {
    Components.utils.import("resource://gre/modules/Task.jsm");
    Components.utils.import("resource://gre/modules/osfile.jsm");
    var oldFile = fp.file.path;
    if (oldFile.endsWith(".json")) {
      var newFile = oldFile.replace(/(\.json)$/, ".mozlz4");
      function compress(oFilePath,nFilePath){
        return Task.spawn(function* () {
          var jsonString = yield OS.File.read(oFilePath);
          yield OS.File.writeAtomic(nFilePath, jsonString, {compression: "lz4"});
          LOG("Saved as: " + newFile);
        })
      }
      compress(oldFile,newFile);
      
    }
    else {
      var newFile = (oldFile.replace(".mozlz4", ".json") || oldFile.replace(".jsonlz4", ".json"));
      function decompress(oFilePath,nFilePath){
        return Task.spawn(function* () {
          var jsonString = yield OS.File.read(oFilePath, {encoding: "utf-8", compression: "lz4"});
          yield OS.File.writeAtomic(nFilePath, JSON.stringify(JSON.parse(jsonString), null, '  '), {encoding: "utf-8"});
        })
      }
      decompress(oldFile,newFile);
      LOG("Saved as: " + newFile);
      custombuttons.alertSlide("Saved as: " + newFile);
    }
  }
};

Отредактировано unter_officer (05-03-2020 18:33:54)


«The Truth Is Out There»

Отсутствует

 

№1439105-03-2020 17:13:08

solombala
Забанен
 
Группа: Members
Зарегистрирован: 20-07-2019
Сообщений: 652
UA: Firefox 73.0

Re: Custom Buttons

unter_officer
Не актуально... Или здесь search-extensions лепишь любой поиск или через СВ , к примеру seasonvar

скрытый текст

Выделить код

Код:

Services.search.addEngine("data:text/xml," + encodeURIComponent(`

    <SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
        <ShortName>Seasonvar.ru</ShortName>
        <Description>Сериалы ТУТ! Сериалы онлайн смотреть бесплатно. Смотреть онлайн.</Description>
        <InputEncoding>UTF-8</InputEncoding>
        <Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAADvklEQVRYhb1XTYgcRRR+JtNVr0ail0gUPLkehBwEVwgakMHNdr1XKwQ8RFQwF39uOXnxtkIwieAhetWLeoh7VVBE3IPgYY1gCIFA0OzOdL0aMYoH4y5xZsrDdjUzk91sz8BsQTFU09Pfz3uvXhXAjEax2FjoWP34MsCBWWHsDm7VKWGMwrh+7SiofScQnAlC+j9xeHvfwQvSbwnpO4FxIKTveKs+2TcXCsKF4EwMjINqOhODM1Fs9tRMwX9fgCPCGIX0oLvUjNV0ZhCciZ7wh5stwJkR6OTq1aR+hMBSs3LEW/3tzAh4q04OExj+DYwDYYxi8fWZgLcXG7kwbg6rT2S2y1H3hPRXMwEHABBnLgeH/cA46DozSLEvc+LrmQGn4UlfGY99cuD6cTg0U/B23nhOGO9OvtKB4PD7iT/qc/PsXu8I45vC2E3gaQ470HVmIKT/XgE4WAt4I89OF6S2PKnPA+ON3xbgyPg7geGhwPidMMauM4NU5+Oll1zwpLc6z4Cpp5zwlif9MwDAagsaweEXI6pz9YQn1R9Rm5Juh7ldBbp3JYf7axEorLoa2HwEALACcLCwahMA7gMA2DiBjw3bvRvoeAg84a3aIbg8D9ly2b9XW9DwrP8FAFi38Ig47EsqtaGNZjflVRISnq4FPj6uH4dDnvESAIA4c7FUFMO9Yj629QpjmAocAKCTq/eFtF0GODCJ9SkptxuQvjg1AWGMNxgeEMazeyneKfbBmbg+bQsubPakt7oLACCEa7XVjzlwswUPT6ee8LOCcAEAILCRWolXKq+2YWeitODw5ODz0PSkN9M6LDX/qhuC6gRUdsGC4dEp1OszwmatWrP5sxaBdPKx+K6w7gVnYnsxe3oKAihC+oO09ozFXvYPh6G92MiFUIQxetZvTwTeZj3nScci1y8MEVqrcuAeTlSll6uXOqReFMZYkFqZiMC2fRglz+bTs8KqT9PH99r3gzOxsOoUAIA4vO1J/zIZAdIfCmP0uV5Mzzp5dqzqfLspT1sv6UEnz44BAHjGS5701kQEpLTO8+jptTxY9HcsvSo/TN9b9U/6T5vUy9v3AfXKZC6w/rK81/306wl4sHTm4+FsHwF3JnaXTF8YY/t5mFttQWO5bGjCGAurrso8NKHsqjWd0Gc84x/pRBsc9kZuPCknqqOX7gVnup5xQxi3POGPJfFvSjEjeVVrXDsKqs16zlt1smOzN4TUO8J41hOe86wveNYXvFXnPalzBeF7aXqL54s8q1qwkLaFzV5Lbo6P/wEF7JeDr5SEggAAAABJRU5ErkJggg==</Image>
        <Url type="text/html" method="GET" template="http://seasonvar.ru/search">
            <Param name="q" value="{searchTerms}"/>
        </Url>
        <SearchForm>http://seasonvar.ru/</SearchForm>
    </SearchPlugin>

`), null, null);

Отсутствует

 

№1439205-03-2020 20:34:41

Dumby
Участник
 
Группа: Members
Зарегистрирован: 12-08-2012
Сообщений: 2254
UA: Firefox 52.0

Re: Custom Buttons

Andrey_Krropotkin пишет

вот добавил в твой код

А g на h зачем заменил?
Вобщем, чуть переписал, вроде работает, на первый взгляд.

скрытый текст

Выделить код

Код:

addBtn(doc) {
            var btns = doc.cbSaveButtons = doc.createXULElement("box");

            var btn = btns.appendChild(doc.createXULElement("button"));
            btn.className = "dialog-button";

            var btn1 = btn.cloneNode(false);
            btn1.label = "Сохранить как";
            btn1.setAttribute("oncommand", "handleCommand(window)");
            btn1.handleCommand = this.cmdf;
            btn.before(btn1);

            btn.label = "Сохранить в";
            var popup = btn.appendChild(doc.createXULElement("menupopup"));
            popup.setAttribute("oncommand", "handleCommand(event.target)");
            popup.handleCommand = this.cmd;

            for(var lab in this.data) {
                var menuitem = popup.appendChild(doc.createXULElement("menuitem"));
                menuitem.label = lab;
                menuitem.dir = this.data[lab];
                menuitem.className = "menuitem-iconic";
                menuitem.image = "moz-icon:file:///" + menuitem.dir;
            }
            doc.getElementById(uct).getButton("cancel").before(btns);
            btn.type = "menu";
        },
        removeBtn(doc) {
            if (doc.cbSaveButtons) doc.cbSaveButtons.remove(), delete doc.cbSaveButtons;
        },
        close(win, dlg = win.dialog) {
            dlg.onCancel = dlg.onUnload;
            win.close();
        },
        cmdf(win) {
            var dlg = win.dialog, launcher = dlg.mLauncher;
            win.Object.defineProperty(dlg, "mLauncher", {configurable: true, set() {
                delete dlg.mLauncher; dlg.mLauncher = launcher;
            }});
            var argLauncher = {source: launcher.source, saveDestinationAvailable(file) {
                if (file)
                    launcher.saveDestinationAvailable(file),
                    g[id].close(win, dlg);
            }};
            dlg.promptForSaveToFileAsync(argLauncher, win.opener, launcher.suggestedFileName, "", true);
        },
        cmd(trg) {
            var file = g.Components.Constructor(
                "@mozilla.org/file/local;1", nsIFile, "initWithPath"
            )(trg.dir);
            var win = trg.ownerGlobal;
            file.append(win.document.getElementById("location").getAttribute("realname"));
            win.dialog.mLauncher.saveToDisk(file, 1);
            g[id].close(win);
        }

xrun1 пишет

как распотрошить search.json.mozlz4

Говорят, людям mozlz4-edit нравится.

Отсутствует

 

№1439305-03-2020 21:12:06

Andrey_Krropotkin
Участник
 
Группа: Members
Зарегистрирован: 11-11-2011
Сообщений: 484
UA: Firefox 73.0

Re: Custom Buttons

Dumby спасибо, сначала 2 кода делал и вместо g  вставлял h и т.д., потом объединил и просто невнимательность, забыл заменить.
У меня есть такой код для загрузки CSS

скрытый текст

Выделить код

Код:

/*Initialization Code*/
var idb=this.id;
var button = document.getElementById(idb);

(function(){

var editor = "C:\\Program Files\\AkelPad\\AkelPad.exe";

let { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
if (!window.Services)
    Cu.import("resource://gre/modules/Services.jsm");
let list = Services.wm.getEnumerator("navigator:browser");
while(list.hasMoreElements()){ if(list.getNext() != window) return; }

if (window.UCL) {
    window.UCL.destroy();
    delete window.UCL;
}

window.UCL = {
    USE_UC: "UC" in window,
    AGENT_SHEET: Ci.nsIStyleSheetService.AGENT_SHEET,
    USER_SHEET : Ci.nsIStyleSheetService.USER_SHEET,
    readCSS    : {},
    get disabled_list() {
        let obj = [];
        try {
            obj = this.prefs.getCharPref("disabled_list").split("|");
        } catch(e) {}
        delete this.disabled_list;
        return this.disabled_list = obj;
    },
    get prefs() {
        delete this.prefs;
        return this.prefs = Services.prefs.getBranch("UserCSSLoader.")
    },
    get styleSheetServices(){
        delete this.styleSheetServices;
        return this.styleSheetServices = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
    },
    get FOLDER() {
        let aFolder;
        try {
            let folderPath = this.prefs.getCharPref("FOLDER");
            aFolder = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile)
            aFolder.initWithPath(folderPath);
        } catch (e) {
            aFolder = Services.dirsvc.get("UChrm", Ci.nsIFile);
            aFolder.appendRelativePath("CSS");
        }
        if (!aFolder.exists() || !aFolder.isDirectory()) {
            aFolder.create(Ci.nsIFile.DIRECTORY_TYPE, 0o664);
        }
        delete this.FOLDER;
        return this.FOLDER = aFolder;
    },
    getFocusedWindow: function() {
        let win = document.commandDispatcher.focusedWindow;
        if (!win || win == window) win = content;
        return win;
    },



    init: function() {
const xulNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
const  cbNS = "http://xsms.nm.ru/custombuttons/";
var menupopup = document.createElementNS(xulNS, "menupopup");
menupopup.onclick =  function (event) {
  button.menuClick(event);
}
menupopup.addEventListener("popupshowing", function (event) {
  self.menuPopupShowing(event);
}, false);
button.appendChild(menupopup);
button.type = "menu";
button.orient = "horizontal";
button.menuClick = function (event) {
  event.preventDefault();
  event.stopPropagation();
  button.open = false;
}
button.menuPopupShowing = function (event) {
    var nodeList = event.target.childNodes;
  for (var i = nodeList.length - 1; i >= 0; i--)
    if (nodeList[i].hasAttributeNS(cbNS, "flag"))
      nodeList[i].parentNode.removeChild(nodeList[i]);

}

            let cssmenu = $C("menu", {
            id: "usercssloader-menu",
            label: "CSS",
        });
        menupopup.appendChild(cssmenu);

        let menupop = $C("menupopup", {
         id: "usercssloader-menupopup"
        });
        cssmenu.appendChild(menupop);

                let menu = $C("menu", {
                label: "Инструменты",
            });    
                menupopup.appendChild(menu);

        let mp = $C("menupopup", { id: "usercssloader-submenupopup" });
        menu.appendChild(mp);
        mp.appendChild($C("menuitem", {
            label: "Обновить список файлов-стилей",
            accesskey: "R",
            acceltext: "Alt + R",
            oncommand: "UCL.rebuild();"
        }));
        mp.appendChild($C("menuseparator"));
        mp.appendChild($C("menuitem", {
            label: "Создать файл CSS",
            accesskey: "D",
            oncommand: "UCL.create();"
        }));
        mp.appendChild($C("menuitem", {
            label: "Открыть папку CSS",
            accesskey: "O",
            oncommand: "UCL.openFolder();"
        }));
        mp.appendChild($C("menuitem", {
            label: "Редактировать userChrome.css",
            hidden: false,
            oncommand: "UCL.editUserCSS(\'userChrome.css\');"
        }));
        mp.appendChild($C("menuitem", {
            label: "Редактировать userContent.css",
            hidden: false,
            oncommand: "UCL.editUserCSS(\'userContent.css\');"
        }));
        mp.appendChild($C("menuseparator"));
        mp.appendChild($C("menuitem", {
            label: "Тест стиля (Chrome)",
            id: "usercssloader-test-chrome",
            //hidden: true,
            accesskey: "C",
            oncommand: "UCL.styleTest(window);"
        }));
        mp.appendChild($C("menuitem", {
            label: "Тест стиля (Web)",
            id: "usercssloader-test-content",
            //hidden: true,
            accesskey: "W",
            oncommand: "UCL.styleTest();"
        }));
        mp.appendChild($C("menuitem", {
            label: "Поиск стиля на userstyles.org",
            accesskey: "S",
            oncommand: "UCL.searchStyle();"
        }));

        menu = $C("menu", {
            label: ".uc.css",
            accesskey: "U",
            hidden: !UCL.USE_UC
        });


        mp = $C("menupopup", { id: "usercssloader-ucmenupopup" });
        menu.appendChild(mp);
        mp.appendChild($C("menuitem", {
            label: "Importieren(.uc.js)",
            oncommand: "UCL.UCrebuild();"
        }));
        mp.appendChild($C("menuseparator", { id: "usercssloader-ucsepalator" }));

        $("mainKeyset").appendChild($C("key", {
            id: "usercssloader-rebuild-key",
            oncommand: "UCL.rebuild();",
            key: "R",
            modifiers: "alt",
        }));


        this.rebuild();
        this.initialized = true;
        if (UCL.USE_UC) {
            setTimeout(function() {
                UCL.UCcreateMenuitem();
            }, 1000);
        }
        window.addEventListener("unload", this, false);
    },
    uninit: function() {
        const dis = [];
        for (let x of Object.keys(this.readCSS)) {
            if (!this.readCSS[x].enabled)
                dis.push(x);
        }
        this.prefs.setCharPref("disabled_list", dis.join("|"));
        window.removeEventListener("unload", this, false);
    },
    destroy: function() {
        var i = document.getElementById("usercssloader-menu");
        if (i) i.parentNode.removeChild(i);
        var i = document.getElementById("usercssloader-rebuild-key");
        if (i) i.parentNode.removeChild(i);
        this.uninit();
    },
    handleEvent: function(event) {
        switch(event.type){
            case "unload": this.uninit(); break;
        }
    },
    rebuild: function() {
        let ext = /\.css$/i;
        let not = /\.uc\.css/i;
        let files = this.FOLDER.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator);

        while (files.hasMoreElements()) {
            let file = files.getNext().QueryInterface(Ci.nsIFile);
            if (!ext.test(file.leafName) || not.test(file.leafName)) continue;
            let CSS = this.loadCSS(file);
            CSS.flag = true;
        }
        for (let leafName of Object.keys(this.readCSS)) {
            const CSS = this.readCSS[leafName];
            if (!CSS.flag) {
                CSS.enabled = false;
                delete this.readCSS[leafName];
            }
            delete CSS.flag;
            this.rebuildMenu(leafName);
        }
        if (this.initialized) {
            if (typeof(StatusPanel) !== "undefined")
                StatusPanel._label = "Style importiert";
            else
                XULBrowserWindow.statusTextField.label = "Styles importieren";
        }
    },
    loadCSS: function(aFile) {
        var CSS = this.readCSS[aFile.leafName];
        if (!CSS) {
            CSS = this.readCSS[aFile.leafName] = new CSSEntry(aFile);
            if (this.disabled_list.indexOf(CSS.leafName) === -1) {
                CSS.enabled = true;
            }
        } else if (CSS.enabled) {
            CSS.enabled = true;
        }
        return CSS;
    },
    rebuildMenu: function(aLeafName) {
        var CSS = this.readCSS[aLeafName];
        var menuitem = document.getElementById("usercssloader-" + aLeafName);
        if (!CSS) {
            if (menuitem)
                menuitem.parentNode.removeChild(menuitem);
            return;
        }

        if (!menuitem) {
            menuitem = document.createXULElement("menuitem");
            menuitem.setAttribute("label", aLeafName);
             menuitem.setAttribute("id", "usercssloader-" + aLeafName);
            menuitem.setAttribute("class", "usercssloader-item " + (CSS.SHEET == this.AGENT_SHEET? "AGENT_SHEET" : "USER_SHEET"));
            menuitem.setAttribute("type", "checkbox");
            menuitem.setAttribute("autocheck", "false");
            menuitem.setAttribute("oncommand", "UCL.toggle('"+ aLeafName +"');");
            menuitem.setAttribute("onclick", "UCL.itemClick(event);");
            document.getElementById("usercssloader-menupopup").appendChild(menuitem);
        }
        menuitem.setAttribute("checked", CSS.enabled);
    },
    toggle: function(aLeafName) {
        var CSS = this.readCSS[aLeafName];
        if (!CSS) return;
        CSS.enabled = !CSS.enabled;
        this.rebuildMenu(aLeafName);
    },
    itemClick: function(event) {
        if (event.button == 0) return;

        event.preventDefault();
        event.stopPropagation();
        let label = event.currentTarget.getAttribute("label");

        if (event.button == 1) {
            this.toggle(label);
        }
        else if (event.button == 2) {
            closeMenus(event.target);
            this.edit(this.getFileFromLeafName(label));
        }
    },
    getFileFromLeafName: function(aLeafName) {
        let f = this.FOLDER.clone();
        f.QueryInterface(Ci.nsIFile); // use appendRelativePath
        f.appendRelativePath(aLeafName);
        return f;
    },
    styleTest: function(aWindow) {
        aWindow || (aWindow = this.getFocusedWindow());
        new CSSTester(aWindow, function(tester){
            if (tester.saved)
                UCL.rebuild();
        });
    },
    searchStyle: function() {
        let word;
        try {
            word = gBrowser.currentURI.host;
        } catch {
            word = gBrowser.currentURI.spec;
        }
        
        var ctabpos = gBrowser.selectedTab._tPos +1;
                gBrowser.moveTabTo(gBrowser.selectedTab = gBrowser.addWebTab("https://userstyles.org/styles/search/" + word), ctabpos);
    },
    openFolder: function() {
        this.FOLDER.launch();
    },
    editUserCSS: function(aLeafName) {
        let file = Services.dirsvc.get("UChrm", Ci.nsIFile);
        file.appendRelativePath(aLeafName);
        this.edit(file);
    },
    edit: function(aFile) {
        try {
            var UI = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter);
            UI.charset = window.navigator.platform.toLowerCase().indexOf("win") >= 0? "Shift_JIS": "UTF-8";
            var path = UI.ConvertFromUnicode(aFile.path);
            var app = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
            app.initWithPath(editor);
            var process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);
            process.init(app);
            process.run(false, [path], 1);
        } catch (e) {}
    },
    create: function(aLeafName) {
        if (!aLeafName) aLeafName = prompt("Имя файла", dateFormat(new Date(), "%Y_%m%d_%H%M%S"));
        if (aLeafName) aLeafName = aLeafName.replace(/\s+/g, " ").replace(/[\\/:*?\"<>|]/g, "");
        if (!aLeafName || !/\S/.test(aLeafName)) return;
        if (!/\.css$/.test(aLeafName)) aLeafName += ".css";
        let file = this.getFileFromLeafName(aLeafName);
        this.edit(file);
    },
    UCrebuild: function() {
        let re = /^file:.*\.uc\.css(?:\?\d+)?$/i;
        let query = "?" + new Date().getTime();
        Array.slice(document.styleSheets).forEach(function(css){
            if (!re.test(css.href)) return;
            if (css.ownerNode) {
                css.ownerNode.parentNode.removeChild(css.ownerNode);
            }
            let pi = document.createProcessingInstruction('xml-stylesheet','type="text/css" href="'+ css.href.replace(/\?.*/, '') + query +'"');
            document.insertBefore(pi, document.documentElement);
        });
        UCL.UCcreateMenuitem();
    },
    UCcreateMenuitem: function() {
        let sep = $("usercssloader-ucsepalator");
        let popup = sep.parentNode;
        if (sep.nextSibling) {
            let range = document.createRange();
            range.setStartAfter(sep);
            range.setEndAfter(popup.lastChild);
            range.deleteContents();
            range.detach();
        }

        let re = /^file:.*\.uc\.css(?:\?\d+)?$/i;
        Array.slice(document.styleSheets).forEach(function(css) {
            if (!re.test(css.href)) return;
            let fileURL = decodeURIComponent(css.href).split("?")[0];
            let aLeafName = fileURL.split("/").pop();
            let m = document.createXULElement("menuitem");
            m.setAttribute("label", aLeafName);
            m.setAttribute("tooltiptext", fileURL);
            m.setAttribute("id", "usercssloader-" + aLeafName);
            m.setAttribute("type", "checkbox");
            m.setAttribute("autocheck", "false");
            m.setAttribute("checked", "true");
            m.setAttribute("oncommand", "this.setAttribute('checked', !(this.css.disabled = !this.css.disabled));");
            m.setAttribute("onclick", "UCL.UCItemClick(event);");
            m.css = css;
            popup.appendChild(m);
        });
    },
    UCItemClick: function(event) {
        if (event.button == 0) return;
        event.preventDefault();
        event.stopPropagation();

        if (event.button == 1) {
            event.target.doCommand();
        }
        else if (event.button == 2) {
            closeMenus(event.target);
            let fileURL = event.currentTarget.getAttribute("tooltiptext");
            let file = Services.io.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler).getFileFromURLSpec(fileURL);
            this.edit(file);
        }
    },
};

function CSSEntry(aFile) {
    this.path = aFile.path;
    this.leafName = aFile.leafName;
    this.lastModifiedTime = 1;
    this.SHEET = /^xul-|\.as\.css$/i.test(this.leafName) ? 
        Ci.nsIStyleSheetService.AGENT_SHEET: 
        Ci.nsIStyleSheetService.USER_SHEET;
}
CSSEntry.prototype = {
    sss: Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService),
    _enabled: false,
    get enabled() {
        return this._enabled;
    },
    set enabled(isEnable) {
        var aFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile)
        aFile.initWithPath(this.path);
    
        var isExists = aFile.exists(); // Wenn die Datei existiert true
        var lastModifiedTime = isExists ? aFile.lastModifiedTime : 0;
        var isForced = this.lastModifiedTime != lastModifiedTime; 

        var fileURL = Services.io.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler).getURLSpecFromFile(aFile);
        var uri = Services.io.newURI(fileURL, null, null);

        if (this.sss.sheetRegistered(uri, this.SHEET)) {
            if (!isEnable || !isExists) {
                this.sss.unregisterSheet(uri, this.SHEET);
            }
            else if (isForced) {
                // Nach Stornierung erneut einlesen
                this.sss.unregisterSheet(uri, this.SHEET);
                this.sss.loadAndRegisterSheet(uri, this.SHEET);
            }
        } else {
            if (isEnable && isExists) {
                this.sss.loadAndRegisterSheet(uri, this.SHEET);
            }
        }
        if (this.lastModifiedTime !== 1 && isEnable && isForced) {
            log(this.leafName + " wurde aktualisiert");
        }
        this.lastModifiedTime = lastModifiedTime;
        return this._enabled = isEnable;
    },
};

function CSSTester(aWindow, aCallback) {
    this.win = aWindow || window;
    this.doc = this.win.document;
    this.callback = aCallback;
    this.init();
}
CSSTester.prototype = {
    sss: Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService),
    preview_code: "",
    saved: false,
    init: function() {
        var url = "data:text/html;charset=utf8,"+encodeURIComponent('<!DOCTYPE HTML><html lang="ja"><head><title>CSSTester</title></head><body></body></html>');
        if (parseInt(Services.appinfo.platformVersion) >= 69 && Services.appinfo.browserTabsRemoteAutostart) {
    var chromeURL = `chrome://custombuttons/content/cbdialog${Date.now()}.xul`;
    Cc["@mozilla.org/addons/addon-manager-startup;1"].getService(Ci.amIAddonManagerStartup).registerChrome(
        Services.io.newFileURI(Services.dirsvc.get("ProfD", Ci.nsIFile)), [["override", chromeURL, url]]
    );
    url = chromeURL;
}
        this.dialog = openDialog(url,    "",    "width=550,height=400,dialog=no");
        this.dialog.addEventListener("load", this, false);
    },
    destroy: function() {
        this.preview_end();
        this.dialog.removeEventListener("unload", this, false);
        this.previewButton.removeEventListener("click", this, false);
        this.saveButton.removeEventListener("click", this, false);
        this.closeButton.removeEventListener("click", this, false);
    },
    handleEvent: function(event) {
        switch(event.type) {
            case "click":
                if (event.button != 0) return;
                if (this.previewButton == event.currentTarget) {
                    this.preview();
                }
                else if (this.saveButton == event.currentTarget) {
                    this.save();
                }
                else if (this.closeButton == event.currentTarget) {
                    this.dialog.close();
                }
                break;
            case "load":
                var doc = this.dialog.document;
                doc.body.innerHTML = '\
                    <style type="text/css">\
                        :not(input):not(select) { padding: 0px; margin: 0px; }\
                        table { border-spacing: 0px; }\
                        body, html, #main, #textarea { width: 100%; height: 100%; }\
                        #textarea { font-family: monospace; }\
                    </style>\
                    <table id="main">\
                        <tr height="100%">\
                            <td colspan="4"><textarea id="textarea"></textarea></td>\
                        </tr>\
                        <tr height="40">\
                            <td><input type="button" value="Vorschau" id="Vorschau"/></td>\
                            <td><input type="button" value="Speichern" id="Speichern"/></td>\
                            <td width="80%"><span class="log"></span></td>\
                            <td><input type="button" value="Schließen" id="Schliessen"/></td>\
                        </tr>\
                    </table>\
                ';
                this.textbox = doc.querySelector("textarea");
                this.previewButton = doc.querySelector('input[value="Vorschau"]');
                this.saveButton = doc.querySelector('input[value="Speichern"]');
                this.closeButton = doc.querySelector('input[value="Schließen"]');
                this.logField = doc.querySelector('.log');

                var code = "@namespace url(" + this.doc.documentElement.namespaceURI + ");\n";
                code += this.win.location.protocol.indexOf("http") === 0?
                    "@-moz-document domain(" + this.win.location.host + ") {\n\n\n\n}":
                    "@-moz-document url(" + this.win.location.href + ") {\n\n\n\n}";

                this.textbox.value = code;
                this.dialog.addEventListener("unload", this, false);
                this.previewButton.addEventListener("click", this, false);
                this.saveButton.addEventListener("click", this, false);
                this.closeButton.addEventListener("click", this, false);

                this.textbox.focus();
                let p = this.textbox.value.length - 3;
                this.textbox.setSelectionRange(p, p);

                break;
              case "unload":
                this.destroy();
                this.callback(this);
                break;
        }
    },
    preview: function() {
        var code = this.textbox.value;
        if (!code || !/\:/.test(code))
            return;
        code = "data:text/css;charset=utf-8," + encodeURIComponent(this.textbox.value);
        if (code == this.preview_code)
            return;
        this.preview_end();
        var uri = Services.io.newURI(code, null, null);
        this.sss.loadAndRegisterSheet(uri, Ci.nsIStyleSheetService.AGENT_SHEET);
        this.preview_code = code;
        this.log("Preview");
    },
    preview_end: function() {
        if (this.preview_code) {
            let uri = Services.io.newURI(this.preview_code, null, null);
            this.sss.unregisterSheet(uri, Ci.nsIStyleSheetService.AGENT_SHEET);
            this.preview_code = "";
        }
    },
    save: function() {
        var data = this.textbox.value;
        if (!data) return;

        var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
        fp.init(window, "", Ci.nsIFilePicker.modeSave);
        fp.appendFilter("CSS Files","*.css");
        fp.defaultExtension = "css";
        if (window.UCL)
            fp.displayDirectory = UCL.FOLDER;
        var res = fp.show();
        if (res != fp.returnOK && res != fp.returnReplace) return;

        var suConverter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter);
        suConverter.charset = "UTF-8";
        data = suConverter.ConvertFromUnicode(data);
        var foStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
        foStream.init(fp.file, 0x02 | 0x08 | 0x20, 0o664, 0);
        foStream.write(data, data.length);
        foStream.close();
        this.saved = true;
    },
    log: function() {
        this.logField.textContent = dateFormat(new Date(), "%H:%M:%S") + ": " + $A(arguments);
    }
};

UCL.init();

function $(id) { return document.getElementById(id); }
function $A(arr) { return Array.slice(arr); }
function $C(name, attr) {
    var el = document.createXULElement(name);
    if (attr) Object.keys(attr).forEach(function(n) { el.setAttribute(n, attr[n]) });
    return el;
}
function dateFormat(date, format) {
    format = format.replace("%Y", ("000" + date.getFullYear()).substr(-4));
    format = format.replace("%m", ("0" + (date.getMonth()+1)).substr(-2));
    format = format.replace("%d", ("0" + date.getDay()).substr(-2));
    format = format.replace("%H", ("0" + date.getHours()).substr(-2));
    format = format.replace("%M", ("0" + date.getMinutes()).substr(-2));
    format = format.replace("%S", ("0" + date.getSeconds()).substr(-2));
    return format;
}
function log() { Application.console.log(Array.from(arguments)); }
})();


Я хочу туда добить AUTHOR_SHEET
Тут в window.UCL я добавляю - AUTHOR_SHEET : Ci.nsIStyleSheetService.AUTHOR_SHEET
Теперь надо еще исправить строчку menuitem.setAttribute("class", "usercssloader-item " + (CSS.SHEET == this.AGENT_SHEET? "AGENT_SHEET" : "USER_SHEET"));
и строчку this.SHEET = /^xul-|\.as\.css$/i.test(this.leafName) ?  Ci.nsIStyleSheetService.AGENT_SHEET: Ci.nsIStyleSheetService.USER_SHEET; 
Как лучше это сделать?

Отсутствует

 

№1439405-03-2020 23:27:27

Dumby
Участник
 
Группа: Members
Зарегистрирован: 12-08-2012
Сообщений: 2254
UA: Firefox 52.0

Re: Custom Buttons

Andrey_Krropotkin пишет

Тут в window.UCL я добавляю - AUTHOR_SHEET : Ci.nsIStyleSheetService.AUTHOR_SHEET
Теперь надо еще исправить строчку menuitem.setAttribute("class", "usercssloader-item " + (CSS.SHEET == this.AGENT_SHEET? "AGENT_SHEET" : "USER_SHEET"));

Ну, например

скрытый текст

Выделить код

Код:

//menuitem.setAttribute("class", "usercssloader-item " + (CSS.SHEET == this.AGENT_SHEET? "AGENT_SHEET" : "USER_SHEET"));

            menuitem.setAttribute("class", "usercssloader-item " + (
                CSS.SHEET == this.AGENT_SHEET ? "AGENT"
                    : CSS.SHEET == this.AUTHOR_SHEET ? "AUTHOR" : "USER"
            ) + "_SHEET");

и строчку this.SHEET = /^xul-|\.as\.css$/i.test(this.leafName) ?  Ci.nsIStyleSheetService.AGENT_SHEET: Ci.nsIStyleSheetService.USER_SHEET;

А метку перед расширением для AUTHOR_SHEET
я что ли должен придумать вместо тебя?
Ладно, допустим blabla.au.css, тогда, опять же, например

скрытый текст

Выделить код

Код:

//this.SHEET = /^xul-|\.as\.css$/i.test(this.leafName) ? 
    //    Ci.nsIStyleSheetService.AGENT_SHEET: 
    //    Ci.nsIStyleSheetService.USER_SHEET;

    var prfx = /^xul-|\.a(s|u)\.css$/i.test(this.leafName)
        ? RegExp.$1 == "u" ? "AUTHOR" : "AGENT" : "USER";
    this.SHEET = Ci.nsIStyleSheetService[prfx + "_SHEET"];

Отсутствует

 

№1439505-03-2020 23:58:31

Andrey_Krropotkin
Участник
 
Группа: Members
Зарегистрирован: 11-11-2011
Сообщений: 484
UA: Firefox 73.0

Re: Custom Buttons

Dumby cпасибо, а в этом же коде можешь посмотреть функцию CSSTester.prototype (необязательная можно и скрыть) - там выдает ошибки на кнопки при открытии окна.
да еще одна незначительная, не влияющая ни на что ошибка (TypeError: e.target.closest(...) is null), которая вылазит в консоли при нажатии на "Инструменты для всех дополнений" в этом коде

скрытый текст

Выделить код

Код:

//Дополнительные пункты контекстного меню на странице about:addons для аддонов, плагинов, тем, CB.....................................................................................
((id, g, iconizer) => addDestructor(r => r[5] == "e" && id in g && g[id].destroy()) + addEventListener("shown", {
    //------------------------------------------------------------------
    "Копировать имя_i": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAByUlEQVQ4jY2TTUhUURiGn5tD0Sp00iAwXM1iFu4kWkUZg/9MoZQhdoUCV7ooItq4atFORRGkuLMwoc0kNBGKDLSwFpEIQgspqGUUNsjI3HvPX4s7I3Nn7oW+1fn5vvd8z3vOsYiIgXuPneFMr21ZVmh9+m7GisoPxcTsM2d46on5c1gy9bHgvDVR+afqJzNzy870xIgNUJGGkqf4XVEAuJ4XeWCiNpibX3MGr/XYPd0pADxlOK0MQgf7Xw++sfJq0zRiJQAWcgWndHRkr28UWcrlAfCVwa8KrK4XOPxbYqz/MsnWcyfFi7lCIPD9x0/70YNRykKz+eELQkny74sIJbnQmqQ71UVhe+cES2hoP9uC63mBgO/7dF7s4NexZPRmBqlBaMPHnc+kL7UTh1VxqwKuGxjkaUP+zRZCSVqwKJeP2dvdj8SqGZuod9hXhr6hGwgNL5ZfEoc1PnaL2sFNAlvvthFKxmJJbfCUqXbghhHSyTOkJwcBmHr4vAnLVwKhJEPZbLgDXwh678yG7rfjfLIJS2qD0IEP9R6kiq8XrzS+sOz9p5+asKodXB0YCQkcNBbHYUXlxP6u67dnIj9PY8QJpIC2/6iX/wDxeTOAfNDrywAAAABJRU5ErkJggg==",
    "Копировать имя"(addon, hideOn) {
        if (hideOn) return false;

        gClipboard.write(addon.name);
    },
    //------------------------------------------------------------------
    "Копировать ID_i": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAByUlEQVQ4jY2TTUhUURiGn5tD0Sp00iAwXM1iFu4kWkUZg/9MoZQhdoUCV7ooItq4atFORRGkuLMwoc0kNBGKDLSwFpEIQgspqGUUNsjI3HvPX4s7I3Nn7oW+1fn5vvd8z3vOsYiIgXuPneFMr21ZVmh9+m7GisoPxcTsM2d46on5c1gy9bHgvDVR+afqJzNzy870xIgNUJGGkqf4XVEAuJ4XeWCiNpibX3MGr/XYPd0pADxlOK0MQgf7Xw++sfJq0zRiJQAWcgWndHRkr28UWcrlAfCVwa8KrK4XOPxbYqz/MsnWcyfFi7lCIPD9x0/70YNRykKz+eELQkny74sIJbnQmqQ71UVhe+cES2hoP9uC63mBgO/7dF7s4NexZPRmBqlBaMPHnc+kL7UTh1VxqwKuGxjkaUP+zRZCSVqwKJeP2dvdj8SqGZuod9hXhr6hGwgNL5ZfEoc1PnaL2sFNAlvvthFKxmJJbfCUqXbghhHSyTOkJwcBmHr4vAnLVwKhJEPZbLgDXwh678yG7rfjfLIJS2qD0IEP9R6kiq8XrzS+sOz9p5+asKodXB0YCQkcNBbHYUXlxP6u67dnIj9PY8QJpIC2/6iX/wDxeTOAfNDrywAAAABJRU5ErkJggg==",
    "Копировать ID"(addon, hideOn) {
        if (hideOn) return false;

        gClipboard.write(addon.id);
    },
    //------------------------------------------------------------------
    "Копировать версию_i": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAByUlEQVQ4jY2TTUhUURiGn5tD0Sp00iAwXM1iFu4kWkUZg/9MoZQhdoUCV7ooItq4atFORRGkuLMwoc0kNBGKDLSwFpEIQgspqGUUNsjI3HvPX4s7I3Nn7oW+1fn5vvd8z3vOsYiIgXuPneFMr21ZVmh9+m7GisoPxcTsM2d46on5c1gy9bHgvDVR+afqJzNzy870xIgNUJGGkqf4XVEAuJ4XeWCiNpibX3MGr/XYPd0pADxlOK0MQgf7Xw++sfJq0zRiJQAWcgWndHRkr28UWcrlAfCVwa8KrK4XOPxbYqz/MsnWcyfFi7lCIPD9x0/70YNRykKz+eELQkny74sIJbnQmqQ71UVhe+cES2hoP9uC63mBgO/7dF7s4NexZPRmBqlBaMPHnc+kL7UTh1VxqwKuGxjkaUP+zRZCSVqwKJeP2dvdj8SqGZuod9hXhr6hGwgNL5ZfEoc1PnaL2sFNAlvvthFKxmJJbfCUqXbghhHSyTOkJwcBmHr4vAnLVwKhJEPZbLgDXwh678yG7rfjfLIJS2qD0IEP9R6kiq8XrzS+sOz9p5+asKodXB0YCQkcNBbHYUXlxP6u67dnIj9PY8QJpIC2/6iX/wDxeTOAfNDrywAAAABJRU5ErkJggg==",
    "Копировать версию"(addon, hideOn) {
        if (hideOn) return ["custombuttons"];

        gClipboard.write(addon.version);
    },
    //------------------------------------------------------------------
    "Копировать имя и версию_i": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAByUlEQVQ4jY2TTUhUURiGn5tD0Sp00iAwXM1iFu4kWkUZg/9MoZQhdoUCV7ooItq4atFORRGkuLMwoc0kNBGKDLSwFpEIQgspqGUUNsjI3HvPX4s7I3Nn7oW+1fn5vvd8z3vOsYiIgXuPneFMr21ZVmh9+m7GisoPxcTsM2d46on5c1gy9bHgvDVR+afqJzNzy870xIgNUJGGkqf4XVEAuJ4XeWCiNpibX3MGr/XYPd0pADxlOK0MQgf7Xw++sfJq0zRiJQAWcgWndHRkr28UWcrlAfCVwa8KrK4XOPxbYqz/MsnWcyfFi7lCIPD9x0/70YNRykKz+eELQkny74sIJbnQmqQ71UVhe+cES2hoP9uC63mBgO/7dF7s4NexZPRmBqlBaMPHnc+kL7UTh1VxqwKuGxjkaUP+zRZCSVqwKJeP2dvdj8SqGZuod9hXhr6hGwgNL5ZfEoc1PnaL2sFNAlvvthFKxmJJbfCUqXbghhHSyTOkJwcBmHr4vAnLVwKhJEPZbLgDXwh678yG7rfjfLIJS2qD0IEP9R6kiq8XrzS+sOz9p5+asKodXB0YCQkcNBbHYUXlxP6u67dnIj9PY8QJpIC2/6iX/wDxeTOAfNDrywAAAABJRU5ErkJggg==",
    "Копировать имя и версию"(addon, hideOn) {
        if (hideOn) return ["custombuttons"];

        gClipboard.write(addon.name + " " + addon.version);
    },
    //------------------------------------------------------------------
    "Домашняя страница_i": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAC4jAAAuIwF4pT92AAAIIklEQVRYR61Xa1CU1xlGUNTpr/7rdNr+sCbt2DrRphPb0VZnWtsYhk5tNWnaaHHaVJsoWgWVNlRbMQoaE6poQATkLpdlWVAzLusqLgioi9xEdkGIIJdd9vLt5dvbd76n7/ncdaxigLbvzDNnYc6e5znP+55z3o2KeibmzZsXNX/+/KhYwvz/M/ja08VXCN8mvEx4KTz+r3gpjG8RvkqYGzVVzJkzJ5qGH+3Zs+diUVGxMTc393Zefr4xn6OgwFgQwfnzxvMRFBY+QWEERUXPfabv3S4vL29PTk7OI475xPW8gOjoaK5sTf3Fi8OgcHs88Pn98AcCCISCCIZCCEkSJMYUMFmGjJlFZN4VrbadOGKJ63kBpCqGhtVl5eV9gsvFHg4Ph0bHxtjY+Dgbn5hgExwWi4Jxi5VZrJPMOslhY1abnVlotNntzM7hcChwhDFpswVJPKuurm6Kms6BiooKs1cUwcktViuIBLSAAiKC2+VEUBTgdTng87rgF10I0N9ykBzzuuEUXHC53HC53XCH4RQECeSYuqbmJhcwpQNPBFRWmkWfD+O08wg57RJOp4OInTAPW1FmeIjTegu2fGpEwulOpNePotzwOR6M2UmIF16vlwR44PESKJUul0viaVCr1dMLqCQBPO/c8gi51+0EWY6shhEk5D7A91Nv4Y1jXViZ2oR1Gb1IrAghIWcMm7O6kasfgUC7Dvp9JECESG6SCxKvAXVt7fQCqqqqzIFgEBbKNbfcQ5YPjFjwx3MD2FLixHf3NmJlih7xaQZsy+7Gscs2nNCKyLwK7C624O3MXhxUj2PU5kIo6CcBPnLEowionakAXvGUf8Ztn7Tb8bdaO9K1AdR1BLEq1YC3jt/Ce9md2F/Sj8o7Iq71yShplXHsCrAzfxDb8kZx5JIAF6UiGAyAakoRoNFoZiCgutockriASRbwOlB0U1B2d80EpF+ZxC/T27DjbCfOUjpO1D9Ck0lEozmEXIOIQxoBf84fQWJeP94vFZGlHSHaEKXCqwioq6ubXkC1IkCC02FjD8YcSLssIbsxgB8evIlXknTYkN6KxNweHK8bwflGJ3pGQ3hoZ7jZ78fZay7sr/JgU5YJKSofXs/oocJ0QgoFZu7AYwEMotvGtD0iDtQz/PhQO6LerMJr+69h47E27Dz3WEChQUD/RAjEgfaHMloHgdIWCX/KNuEDtRcr03qQ2zBE1NIsHFCpzBKTSYCDFRh82K0KYFlKK6LfUmFZ0lWsP9qC93K6cLBiCFVtDrolZQxYGK7eZ8hrkpHZEMTRmkF8og3iB4f6sLvoPl0BjwXU19dPL0BVU2OmO4Oq38HO6EUkVYtIqZ7AkiQ9vrb1EtYdasbvM43kQi/OXHkEhxe4Nwpo7wF5zUBSuYCt2X1IuyhhyT4jtuaaZudADTnAb28uIEvnxbZiAUkVNuwoHsSXNqmxZJcW8YdbsDnzDv6Q1YF/XRrGZx0e5DSM4UONFbsKR/B+3hD+WQ/86vQj/J2OJFhw9g74vQL7VOckBwI4chnI0ss4XGfFig8asZyK8Q1yYsfZDqSW3sO+wm5syGjB6tRGbD7Vhb9SIXIB79K9UdDipRSEZi6ghgTwyZLfzWpvT2JrkYB/UCEe1IBOA+i8Syiho7k1pwO/PtaC19Oa8WqynpxpwJcT1PjFifuK4AN1DG/nWHG9L8CP4iwEqNWKAL/oZoNU3m9mDiG52otUjYQDGllZ/BS58c3EBkRtqMLCd9SUmloaCZvq8ErKHWXuPirefZUiHHQLhwI+SSZbwzUw9XMcEaAOC6BXjQEBfKQZovt+iFLhxF8qPUipkbCnwoVl+9uwaOcNfH37NXyD8PLuZryW2o6fHunDtiIndpT6ob4tkpWiLAjuEF+T1m6OmqkD9KSyQMAPwSPiNx934+cZJiSqRrBPY6FLRsDvzoxi/SdDiPvoAeIJG04+xJZzVtq1F9tLfDhU44DN7oBLcMo2m12iYOHXMPYL+4GIAx6Pm/GHhNG1PDLpwfqMdvzk4x7sqBhGRr0HJ3UBHP8sgLQ6Pz0+fqp2brkP72TbkVw6hs/paXYLDtlisWJ4eCRIAlBcXNxAHHO+OAW1tYoAasmYn1oyn8+viHC4fThM9bn+TB9WpfWR1YPYeHIMvz1jwcZTE4g7Pox4cildNQBT/yB6ujtlQ9NNNN64IZlMZrm1tdW6ePHiFZxrzlQWRATUPnHAQykIKO/5+PgE+vvN6Ll7CyWqS3j3wwtYlViOV7fXYMVODX62V41tR1UoU1/BndYbuFBeJtdqNDAYDKy3t5fdvXvXv3Tp0rgw+XPc/ykg7AB1NYoA7oIgCBgdHYXJ3I/7PV3oNrbgVvN13LiuQ1OjHrdbGpX/3evuQIPuqkxtHV+C8UZkYGAAa9asSQhzvIB9CgGecAqC1JyEqD9g1AlH4ulumNG7wdPEe0G73SHTrqHX66mXcEq0e8TFxe2aljw8QemKSYDpaQc4uIiIEA5eUFwQH7lI3njabDaZu3Tp8mWpq6tL5juPj49XyKfM+bNBc7gDq1UqVR+RSNRIBin/ks/nk4hEAYl5AhKkjCRU4ru1Wq2S2WwOGo1GdHZ2+teuXbuFrzvtziMRdmCNTqd7hP8iuCO8YNva2izLly9fF15zivP2ggj/NPvO3r178y9cuKCjM6stLS3VlZWVPQH9vHoONKeBn2/6qabNyclRLVq06Ht8vRiKaSinjNgw5s4CMU99VmJWO382YmNjoxcuXBizYMGCuYSYFyE859l588KpnHH8G9SEW7QrlTX7AAAAAElFTkSuQmCC",
    "Домашняя страница"(addon, hideOn) {
        if (hideOn) return !addon.homepageURL;

        var url = addon.homepageURL;
        if (!url) {
        if (addon.reviewURL) {
        url = addon.reviewURL.replace(/\/reviews\/.*$/, "/");
        }
        }
       openURL(url);
    },
    //------------------------------------------------------------------
    "Поиск на АМО_i": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJGSURBVDjLjdJLSNRBHMDx78yqLZaKS75DPdgDDaFDbdJmde5QlhCJGxgpRJfqEEKnIsJLB7skQYQKZaSmdLaopPCgEvSCShCMzR5a7oq7/3l12RVtjfzBMA/4fWZ+MyOccwBM3g8HEbIdfCEhfAFnLVapOa28Uevpjrqz/WOsERJgsu9Uq5CZQzgqrJfo9BajNd5irEYn4p3OUiFExtCLmw2tawFi4l5zUMjMIau9u7K+qxeoAcoAA0wDb2OPwmfA16LiiaOHLj1edRLpkO3WmIis7+oBDgJbgQ2AH6gC6jY19N62RkcctKeVIJAhp9QgUA3kJXdONZVcq9JxPSgQoXRAyIDRth8oAXQyKdWnoCKrTD9CBv4GMqx1WGNZkeRWJKbG2hiD1Cb9FbTnzWFdY/LCdLKlgNQ84gyNKqHm0gDjqVHnxDHgA/B9RQkpaB6YklkZl62np9KBhOqwjpKFgeY2YAz4BESBWHI8Hhs6PVVSvc3v98ye4fP7T676B845nt040ip98qpWJmI9PWiU6bfWgXGN2YHcKwU7tsuc4kpUPMbU0+f8+vKt+Pitl7PLAMDI9cNBoB0hQwICzjqUp6MZvsy8yvp95BRuQUjJ75mPvH4wYo1NlJ64Mza7DPwrhi8cCOeXl/aUB4P4c/NJxKLMvpngycCrzxVFG2v/CwAMnguF80oLe8p27cQh+fnpPV/fTc95S6piXQDAw7a9YbWkezZXFbAwMx/xPFXb1D3+Y90AQF/L7kAsri9mZ4lrTd0TcYA/Kakr+x2JSPUAAAAASUVORK5CYII=",
    "Поиск на АМО"(addon, hideOn) {
        if (hideOn) return ["custombuttons","theme","plugin"];

        var url = addon.homepageURL;
        if (!url) {
        url = "https://addons.mozilla.org/search/?q="
            + encodeURIComponent(addon.name);
        }
       openURL(url);
    },
    //------------------------------------------------------------------
    "Папка установки_i": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABAklEQVR42mNkoBAwAjEXEAcCMTsW+U9AvB6I/+I0gJ2Noe3QJoZKASEgjwkq+h+C795lYPCKZMgC8mZg0fsfbICIIMOcF6cZkrGZ/v8fA0PndIa/7z8BXfAPqgVKv//A8GPeZoYERmE+hjmP1+AwAOgiTjOIP7HZLyjLMJNRmB/ogjMMyYzsUC8wIhQwsgCFWHAHoKAy0AARIYY5r69idwEhIKgBMgAYBq8vkGmALsyAU2QaYAwz4CiZBliADBAAGnCATANsYQbsJtMAJ5ABwGh8uZE8A4R9gAYwMzHkT8hl6Bfgxp5ecIH3Xxj+F05hyIdpUmXAnpnwge9AfJckW7EBAC/gSzisxsnmAAAAAElFTkSuQmCC",
        "Папка установки"(addon, hideOn) {
        if (hideOn) return ["custombuttons","theme","plugin"];

                    switch (addon.type) {
                    case "plugin":
                    var pathes = addon.pluginFullpath;
                    for (var i = 0; i < pathes.length; i++) {
                        this.revealPath(pathes[i]);
                    }
                    return;
                case "userchromejs":
                    var file = addon._script.file;
                    if (file.exists())
                        file.reveal();
                    return;
            }

            var gecko = parseInt(Services.appinfo.platformVersion);
            var nsLocalFile = Components.Constructor("@mozilla.org/file/local;1", (gecko >= 14) ? "nsIFile" : "nsILocalFile",
                "initWithPath");

            var dir = Services.dirsvc.get("ProfD", Ci.nsIFile);
            dir.append("extensions");
            dir.append(addon.id);
            var fileOrDir = dir.path + (dir.exists() ? "" : ".xpi");

            try {
                (new nsLocalFile(fileOrDir)).reveal();
            } catch (ex) {
                var addonDir = /.xpi$/.test(fileOrDir) ? dir.parent : dir;
                try {
                    if (addonDir.exists()) {
                        addonDir.launch();
                    }
                } catch (ex) {
                    var uri = Services.io.newFileURI(addonDir);
                    var protSvc = Cc["@mozilla.org/uriloader/external-protocol-service;1"].
                    getService(Ci.nsIExternalProtocolService);
                    protSvc.loadUrl(uri);
                }
            }
    },
    //------------------------------------------------------------------
    "Файл установки_i": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAA51AAAOdQG5Y1EyAAAAhklEQVQ4y6WT0QnAIAxE78Bt2v1cod3PznP9kVLTRKUGBD+Sd5eQUBJWggCWCAkAJPGXOqlUPyVKkrSPQIoCQJGE6AF4HFyGuBmrR3cGQX8Wmp2cL8Cqv5JPD5Zm1D0nFZjTjHpQ7DuI1L3iBjBS9/pvhtjr21OukVkXiX/ug6SWj4mr53wDMz1vldHlLJkAAAAASUVORK5CYII=",
        "Файл установки"(addon, hideOn) {
        if (hideOn) return ["custombuttons","theme","plugin"];

            var gecko = parseInt(Services.appinfo.platformVersion);
            var nsLocalFile = Components.Constructor("@mozilla.org/file/local;1", (gecko >= 14) ? "nsIFile" : "nsILocalFile",
                "initWithPath");
            var dir = Services.dirsvc.get("ProfD", Ci.nsIFile); 
                        dir.append('extensions');
                        dir.append(addon.id);
                            if ( dir.exists() ) dir.launch();
                            var file = Components.classes['@mozilla.org/file/directory_service;1']
                                      .getService(Components.interfaces.nsIProperties)
                                     .get('ProfD', Components.interfaces.nsIFile);
                            file.append('extensions');
                            file.append( addon.id + '.xpi' )
                            if ( file.exists() ) file.launch(); 
                            return;
    },
    //------------------------------------------------------------------
    url: "chrome://mozapps/content/extensions/aboutaddons.html",
    handleEvent(e) {
        if (e.target.baseURI != this.url) return;
        var item = this.getItem(e.target.ownerDocument);
        var addon = item.addon = e.target.closest("addon-card").addon;

        for(var child of item.children) {
            var res = this[child.textContent](addon, true);
            child.hidden = Array.isArray(res)
                ? res.includes(addon.type) : res;
        }
        e.target.contains(item) || requestAnimationFrame(
            () => e.target.prepend(item)
        );
    },
    click(e) {
        e.stopPropagation();
        iconizer.item.parentNode.hide();
        this[e.target.textContent](iconizer.item.addon);
    },
    getItem(doc) {
        if (iconizer.item) {
            if (iconizer.item.ownerDocument == doc) return iconizer.item;
            iconizer.handleEvent();
        }
        var item = doc.createElement("div");
        item.id = id;
        for(var lab of this.labels) item.appendChild(
            doc.createElement("panel-item")
        ).append(lab);

        item.onclick = this.click;
        doc.ownerGlobal.addEventListener("unload", iconizer);
        return iconizer.item = item;
    },
    get labels() {
        delete this.labels;
        this.click = this.click.bind(this);
        if (id in g) return this.labels = (iconizer = g[id]).labs;

        g[id] = iconizer;
        var css = "", ind = 0, arr = [];
        var push = (ind, icon) => {
            var chromeImg = `chrome://custombuttons/content/${id + ind}`;
            arr.push(["override", chromeImg, icon]);
            return chromeImg;
        }
        var labs = iconizer.labs = Object.keys(this).filter(key => {
            var res = String(this[key]).startsWith('"');
            if (!res) return false;
            ind++;
            var icon = this[key + "_i"];
            if (icon) css += `\n\t#${
                id
            } > panel-item:nth-child(${ind}) {\n\t\t--icon: url(${
                push(ind, icon)
            }) !important;\n\t}`;
            return true;
        });
        var ams = Cc["@mozilla.org/addons/addon-manager-startup;1"].getService(Ci.amIAddonManagerStartup);
        var mUri = Services.io.getProtocolHandler("resource").getSubstitution("custombuttons-modules");
        iconizer.iconHelper = ams.registerChrome(mUri, arr);

        var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
        var md = "@-moz-document url(chrome://mozapps/content/extensions/aboutaddons.html) {";
        var uri = Services.io.newURI("data:text/css;charset=utf-8," + encodeURIComponent(md + css + "\n}"));
        var args = [uri, sss.USER_SHEET];
        sss.loadAndRegisterSheet(...args);

        iconizer.handleEvent = function() {
            if (!this.item) return;
            this.item.ownerGlobal.removeEventListener("unload", this);
            this.item.remove();
            this.item = null;
        }
        iconizer.destroy = function() {
            delete g[id];
            this.handleEvent();
            sss.unregisterSheet(...args);
            this.iconHelper.destruct();
        }
        return this.labels = labs;
    },
    revealPath: function(path){
            var file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
            file.initWithPath(path);
            if(file.exists())
                file.reveal();
        }
}, true, gBrowser.tabpanels || 1))("CBAddonsMenuExt", Cu.import("resource://gre/modules/Services.jsm", {}), {});

Отредактировано Andrey_Krropotkin (06-03-2020 00:29:33)

Отсутствует

 

№1439606-03-2020 19:37:28

xrun1
Участник
 
Группа: Members
Зарегистрирован: 12-12-2013
Сообщений: 1227
UA: Firefox 73.0

Re: Custom Buttons

solombala
Dumby
Спасибо, всё получилось.

Отредактировано xrun1 (07-03-2020 01:36:21)

Отсутствует

 

№1439707-03-2020 11:16:59

Dumby
Участник
 
Группа: Members
Зарегистрирован: 12-08-2012
Сообщений: 2254
UA: Firefox 52.0

Re: Custom Buttons

Andrey_Krropotkin пишет

можешь посмотреть функцию CSSTester.prototype (необязательная можно и скрыть) - там выдает ошибки на кнопки при открытии окна.

Объект же, а не функция.
Если имеется в виду установка doc.body.innerHTML в CSSTester.prototype.handleEvent()
то да, это не будет нормально работать для нас, так они решили, типа небезопасно.
Можно воспользоваться DOMParser'ом, тогда не будет ошибок при открытии окна,
но сам CSSTester от этого, разумеется, лучше не станет.

скрытый текст

Выделить код

Код:

//doc.body.innerHTML = '\

                doc.body.append(...new doc.ownerGlobal.DOMParser().parseFromSafeString('\
                    <style type="text/css">\
                        :not(input):not(select) { padding: 0px; margin: 0px; }\
                        table { border-spacing: 0px; }\
                        body, html, #main, #textarea { width: 100%; height: 100%; }\
                        #textarea { font-family: monospace; }\
                    </style>\
                    <table id="main">\
                        <tr height="100%">\
                            <td colspan="4"><textarea id="textarea"></textarea></td>\
                        </tr>\
                        <tr height="40">\
                            <td><input type="button" value="Vorschau" id="Vorschau"/></td>\
                            <td><input type="button" value="Speichern" id="Speichern"/></td>\
                            <td width="80%"><span class="log"></span></td>\
                            <td><input type="button" value="Schließen" id="Schliessen"/></td>\
                        </tr>\
                    </table>\
                ', "text/html").querySelectorAll("style,table"));

одна незначительная, не влияющая ни на что ошибка (TypeError: e.target.closest(...) is null), которая вылазит в консоли при нажатии на "Инструменты для всех дополнений"

Да, шестерёнку втащили в aboutaddons.html и её менюшка
расположилась там на общих основаниях. Так, навскидку

скрытый текст

Выделить код

Код:

handleEvent(e) {
        //if (e.target.baseURI != this.url) return;
        if (e.target.baseURI != this.url || e.target.parentNode.id) return;

Отредактировано Dumby (07-03-2020 11:18:57)

Отсутствует

 

№1439807-03-2020 17:48:14

Andrey_Krropotkin
Участник
 
Группа: Members
Зарегистрирован: 11-11-2011
Сообщений: 484
UA: Firefox 73.0

Re: Custom Buttons

Dumby спасибо. Чуть подпраил, вот что получилось

скрытый текст

Выделить код

Код:

/*Initialization Code*/

var idb=this.id;
var button = document.getElementById(idb);

(function(){

var editor = "C:\\Program Files\\AkelPad\\AkelPad.exe";

let { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
if (!window.Services)
    Cu.import("resource://gre/modules/Services.jsm");
let list = Services.wm.getEnumerator("navigator:browser");
while(list.hasMoreElements()){ if(list.getNext() != window) return; }

if (window.UCL) {
    window.UCL.destroy();
    delete window.UCL;
}

window.UCL = {
    USE_UC: "UC" in window,
    AGENT_SHEET: Ci.nsIStyleSheetService.AGENT_SHEET,
    USER_SHEET : Ci.nsIStyleSheetService.USER_SHEET,
    AUTHOR_SHEET : Ci.nsIStyleSheetService.AUTHOR_SHEET,
    readCSS    : {},
    get disabled_list() {
        let obj = [];
        try {
            obj = this.prefs.getCharPref("disabled_list").split("|");
        } catch(e) {}
        delete this.disabled_list;
        return this.disabled_list = obj;
    },
    get prefs() {
        delete this.prefs;
        return this.prefs = Services.prefs.getBranch("UserCSSLoader.")
    },
    get styleSheetServices(){
        delete this.styleSheetServices;
        return this.styleSheetServices = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
    },
    get FOLDER() {
        let aFolder;
        try {
            let folderPath = this.prefs.getCharPref("FOLDER");
            aFolder = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile)
            aFolder.initWithPath(folderPath);
        } catch (e) {
            aFolder = Services.dirsvc.get("UChrm", Ci.nsIFile);
            aFolder.appendRelativePath("CSS");
        }
        if (!aFolder.exists() || !aFolder.isDirectory()) {
            aFolder.create(Ci.nsIFile.DIRECTORY_TYPE, 0o664);
        }
        delete this.FOLDER;
        return this.FOLDER = aFolder;
    },
    getFocusedWindow: function() {
        let win = document.commandDispatcher.focusedWindow;
        if (!win || win == window) win = content;
        return win;
    },



    init: function() {
const xulNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
const  cbNS = "http://xsms.nm.ru/custombuttons/";
var menupopup = document.createElementNS(xulNS, "menupopup");
menupopup.onclick =  function (event) {
  button.menuClick(event);
}
menupopup.addEventListener("popupshowing", function (event) {
  self.menuPopupShowing(event);
}, false);
button.appendChild(menupopup);
button.type = "menu";
button.orient = "horizontal";
button.menuClick = function (event) {
  event.preventDefault();
  event.stopPropagation();
  button.open = false;
}
button.menuPopupShowing = function (event) {
    var nodeList = event.target.childNodes;
  for (var i = nodeList.length - 1; i >= 0; i--)
    if (nodeList[i].hasAttributeNS(cbNS, "flag"))
      nodeList[i].parentNode.removeChild(nodeList[i]);

}

            let cssmenu = $C("menu", {
            id: "usercssloader-menu",
            label: "CSS",
        });
        menupopup.appendChild(cssmenu);

        let menupop = $C("menupopup", {
         id: "usercssloader-menupopup"
        });
        cssmenu.appendChild(menupop);

                let menu = $C("menu", {
                label: "Инструменты",
            });    
                menupopup.appendChild(menu);

        let mp = $C("menupopup", { id: "usercssloader-submenupopup" });
        menu.appendChild(mp);
        mp.appendChild($C("menuitem", {
            label: "Обновить список файлов-стилей",
            accesskey: "R",
            acceltext: "Alt + R",
            oncommand: "UCL.rebuild();"
        }));
        mp.appendChild($C("menuseparator"));
        mp.appendChild($C("menuitem", {
            label: "Создать файл CSS",
            accesskey: "D",
            oncommand: "UCL.create();"
        }));
        mp.appendChild($C("menuitem", {
            label: "Открыть папку CSS",
            accesskey: "O",
            oncommand: "UCL.openFolder();"
        }));
        mp.appendChild($C("menuitem", {
            label: "Редактировать userChrome.css",
            hidden: false,
            oncommand: "UCL.editUserCSS(\'userChrome.css\');"
        }));
        mp.appendChild($C("menuitem", {
            label: "Редактировать userContent.css",
            hidden: false,
            oncommand: "UCL.editUserCSS(\'userContent.css\');"
        }));
        mp.appendChild($C("menuseparator"));
        mp.appendChild($C("menuitem", {
            label: "Тест стиля",
            id: "usercssloader-test-chrome",
            accesskey: "C",
            oncommand: "UCL.styleTest(window);"
        }));
        mp.appendChild($C("menuitem", {
            label: "Поиск стиля на userstyles.org",
            accesskey: "S",
            oncommand: "UCL.searchStyle();"
        }));

        menu = $C("menu", {
            label: ".uc.css",
            accesskey: "U",
            hidden: !UCL.USE_UC
        });


        mp = $C("menupopup", { id: "usercssloader-ucmenupopup" });
        menu.appendChild(mp);
        mp.appendChild($C("menuitem", {
            label: "Importieren(.uc.js)",
            oncommand: "UCL.UCrebuild();"
        }));
        mp.appendChild($C("menuseparator", { id: "usercssloader-ucsepalator" }));

        $("mainKeyset").appendChild($C("key", {
            id: "usercssloader-rebuild-key",
            oncommand: "UCL.rebuild();",
            key: "R",
            modifiers: "alt",
        }));


        this.rebuild();
        this.initialized = true;
        if (UCL.USE_UC) {
            setTimeout(function() {
                UCL.UCcreateMenuitem();
            }, 1000);
        }
        window.addEventListener("unload", this, false);
    },
    uninit: function() {
        const dis = [];
        for (let x of Object.keys(this.readCSS)) {
            if (!this.readCSS[x].enabled)
                dis.push(x);
        }
        this.prefs.setCharPref("disabled_list", dis.join("|"));
        window.removeEventListener("unload", this, false);
    },
    destroy: function() {
        var i = document.getElementById("usercssloader-menu");
        if (i) i.parentNode.removeChild(i);
        var i = document.getElementById("usercssloader-rebuild-key");
        if (i) i.parentNode.removeChild(i);
        this.uninit();
    },
    handleEvent: function(event) {
        switch(event.type){
            case "unload": this.uninit(); break;
        }
    },
    rebuild: function() {
        let ext = /\.css$/i;
        let not = /\.uc\.css/i;
        let files = this.FOLDER.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator);

        while (files.hasMoreElements()) {
            let file = files.getNext().QueryInterface(Ci.nsIFile);
            if (!ext.test(file.leafName) || not.test(file.leafName)) continue;
            let CSS = this.loadCSS(file);
            CSS.flag = true;
        }
        for (let leafName of Object.keys(this.readCSS)) {
            const CSS = this.readCSS[leafName];
            if (!CSS.flag) {
                CSS.enabled = false;
                delete this.readCSS[leafName];
            }
            delete CSS.flag;
            this.rebuildMenu(leafName);
        }
        if (this.initialized) {
            if (typeof(StatusPanel) !== "undefined")
                StatusPanel._label = "Style importiert";
            else
                XULBrowserWindow.statusTextField.label = "Styles importieren";
        }
    },
    loadCSS: function(aFile) {
        var CSS = this.readCSS[aFile.leafName];
        if (!CSS) {
            CSS = this.readCSS[aFile.leafName] = new CSSEntry(aFile);
            if (this.disabled_list.indexOf(CSS.leafName) === -1) {
                CSS.enabled = true;
            }
        } else if (CSS.enabled) {
            CSS.enabled = true;
        }
        return CSS;
    },
    rebuildMenu: function(aLeafName) {
        var CSS = this.readCSS[aLeafName];
        var menuitem = document.getElementById("usercssloader-" + aLeafName);
        if (!CSS) {
            if (menuitem)
                menuitem.parentNode.removeChild(menuitem);
            return;
        }

        if (!menuitem) {
            menuitem = document.createXULElement("menuitem");
            menuitem.setAttribute("label", aLeafName);
             menuitem.setAttribute("id", "usercssloader-" + aLeafName);
            menuitem.setAttribute("class", "usercssloader-item " + (
                CSS.SHEET == this.AGENT_SHEET ? "AGENT"
                    : CSS.SHEET == this.AUTHOR_SHEET ? "AUTHOR" : "USER"
            ) + "_SHEET");
            menuitem.setAttribute("type", "checkbox");
            menuitem.setAttribute("autocheck", "false");
            menuitem.setAttribute("oncommand", "UCL.toggle('"+ aLeafName +"');");
            menuitem.setAttribute("onclick", "UCL.itemClick(event);");
            document.getElementById("usercssloader-menupopup").appendChild(menuitem);
        }
        menuitem.setAttribute("checked", CSS.enabled);
    },
    toggle: function(aLeafName) {
        var CSS = this.readCSS[aLeafName];
        if (!CSS) return;
        CSS.enabled = !CSS.enabled;
        this.rebuildMenu(aLeafName);
    },
    itemClick: function(event) {
        if (event.button == 0) return;

        event.preventDefault();
        event.stopPropagation();
        let label = event.currentTarget.getAttribute("label");

        if (event.button == 1) {
            this.toggle(label);
        }
        else if (event.button == 2) {
            closeMenus(event.target);
            this.edit(this.getFileFromLeafName(label));
        }
    },
    getFileFromLeafName: function(aLeafName) {
        let f = this.FOLDER.clone();
        f.QueryInterface(Ci.nsIFile); // use appendRelativePath
        f.appendRelativePath(aLeafName);
        return f;
    },
    styleTest: function(aWindow) {
        aWindow || (aWindow = this.getFocusedWindow());
        new CSSTester(aWindow, function(tester){
            if (tester.saved)
                UCL.rebuild();
        });
    },
    searchStyle: function() {
        let word;
        try {
            word = gBrowser.currentURI.host;
        } catch {
            word = gBrowser.currentURI.spec;
        }
        
        var ctabpos = gBrowser.selectedTab._tPos +1;
                gBrowser.moveTabTo(gBrowser.selectedTab = gBrowser.addWebTab("https://userstyles.org/styles/search/" + word), ctabpos);
    },
    openFolder: function() {
        this.FOLDER.launch();
    },
    editUserCSS: function(aLeafName) {
        let file = Services.dirsvc.get("UChrm", Ci.nsIFile);
        file.appendRelativePath(aLeafName);
        this.edit(file);
    },
    edit: function(aFile) {
        try {
            var UI = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter);
            UI.charset = window.navigator.platform.toLowerCase().indexOf("win") >= 0? "Shift_JIS": "UTF-8";
            var path = UI.ConvertFromUnicode(aFile.path);
            var app = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
            app.initWithPath(editor);
            var process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);
            process.init(app);
            process.run(false, [path], 1);
        } catch (e) {}
    },
    create: function(aLeafName) {
        if (!aLeafName) aLeafName = prompt("Имя файла", dateFormat(new Date(), "%Y_%m%d_%H%M%S"));
        if (aLeafName) aLeafName = aLeafName.replace(/\s+/g, " ").replace(/[\\/:*?\"<>|]/g, "");
        if (!aLeafName || !/\S/.test(aLeafName)) return;
        if (!/\.css$/.test(aLeafName)) aLeafName += ".css";
        let file = this.getFileFromLeafName(aLeafName);
        this.edit(file);
    },
    UCrebuild: function() {
        let re = /^file:.*\.uc\.css(?:\?\d+)?$/i;
        let query = "?" + new Date().getTime();
        Array.slice(document.styleSheets).forEach(function(css){
            if (!re.test(css.href)) return;
            if (css.ownerNode) {
                css.ownerNode.parentNode.removeChild(css.ownerNode);
            }
            let pi = document.createProcessingInstruction('xml-stylesheet','type="text/css" href="'+ css.href.replace(/\?.*/, '') + query +'"');
            document.insertBefore(pi, document.documentElement);
        });
        UCL.UCcreateMenuitem();
    },
    UCcreateMenuitem: function() {
        let sep = $("usercssloader-ucsepalator");
        let popup = sep.parentNode;
        if (sep.nextSibling) {
            let range = document.createRange();
            range.setStartAfter(sep);
            range.setEndAfter(popup.lastChild);
            range.deleteContents();
            range.detach();
        }

        let re = /^file:.*\.uc\.css(?:\?\d+)?$/i;
        Array.slice(document.styleSheets).forEach(function(css) {
            if (!re.test(css.href)) return;
            let fileURL = decodeURIComponent(css.href).split("?")[0];
            let aLeafName = fileURL.split("/").pop();
            let m = document.createXULElement("menuitem");
            m.setAttribute("label", aLeafName);
            m.setAttribute("tooltiptext", fileURL);
            m.setAttribute("id", "usercssloader-" + aLeafName);
            m.setAttribute("type", "checkbox");
            m.setAttribute("autocheck", "false");
            m.setAttribute("checked", "true");
            m.setAttribute("oncommand", "this.setAttribute('checked', !(this.css.disabled = !this.css.disabled));");
            m.setAttribute("onclick", "UCL.UCItemClick(event);");
            m.css = css;
            popup.appendChild(m);
        });
    },
    UCItemClick: function(event) {
        if (event.button == 0) return;
        event.preventDefault();
        event.stopPropagation();

        if (event.button == 1) {
            event.target.doCommand();
        }
        else if (event.button == 2) {
            closeMenus(event.target);
            let fileURL = event.currentTarget.getAttribute("tooltiptext");
            let file = Services.io.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler).getFileFromURLSpec(fileURL);
            this.edit(file);
        }
    },
};

function CSSEntry(aFile) {
    this.path = aFile.path;
    this.leafName = aFile.leafName;
    this.lastModifiedTime = 1;
    var prfx = /^xul-|\.a(s|u)\.css$/i.test(this.leafName)
        ? RegExp.$1 == "u" ? "AUTHOR" : "AGENT" : "USER";
    this.SHEET = Ci.nsIStyleSheetService[prfx + "_SHEET"];
}
CSSEntry.prototype = {
    sss: Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService),
    _enabled: false,
    get enabled() {
        return this._enabled;
    },
    set enabled(isEnable) {
        var aFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile)
        aFile.initWithPath(this.path);
    
        var isExists = aFile.exists(); // Wenn die Datei existiert true
        var lastModifiedTime = isExists ? aFile.lastModifiedTime : 0;
        var isForced = this.lastModifiedTime != lastModifiedTime; 

        var fileURL = Services.io.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler).getURLSpecFromFile(aFile);
        var uri = Services.io.newURI(fileURL, null, null);

        if (this.sss.sheetRegistered(uri, this.SHEET)) {
            if (!isEnable || !isExists) {
                this.sss.unregisterSheet(uri, this.SHEET);
            }
            else if (isForced) {
                // Nach Stornierung erneut einlesen
                this.sss.unregisterSheet(uri, this.SHEET);
                this.sss.loadAndRegisterSheet(uri, this.SHEET);
            }
        } else {
            if (isEnable && isExists) {
                this.sss.loadAndRegisterSheet(uri, this.SHEET);
            }
        }
        if (this.lastModifiedTime !== 1 && isEnable && isForced) {
            log(this.leafName + " wurde aktualisiert");
        }
        this.lastModifiedTime = lastModifiedTime;
        return this._enabled = isEnable;
    },
};

function CSSTester(aWindow, aCallback) {
    this.win = aWindow || window;
    this.doc = this.win.document;
    this.callback = aCallback;
    this.init();
}
CSSTester.prototype = {
    sss: Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService),
    preview_code: "",
    saved: false,
    init: function() {
        var url = "data:text/html;charset=utf8,"+encodeURIComponent('<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>CSSTester</title></head><body></body></html>');
        if (parseInt(Services.appinfo.platformVersion) >= 69 && Services.appinfo.browserTabsRemoteAutostart) {
    var chromeURL = `chrome://custombuttons/content/cbdialog${Date.now()}.xul`;
    Cc["@mozilla.org/addons/addon-manager-startup;1"].getService(Ci.amIAddonManagerStartup).registerChrome(
        Services.io.newFileURI(Services.dirsvc.get("ProfD", Ci.nsIFile)), [["override", chromeURL, url]]
    );
    url = chromeURL;
}
        this.dialog = openDialog(url, "", "width=850,height=600,dialog=no");
        this.dialog.addEventListener("load", this, false);
    },
    destroy: function() {
        this.preview_end();
        this.dialog.removeEventListener("unload", this, false);
        this.previewButton.removeEventListener("click", this, false);
        this.saveButton.removeEventListener("click", this, false);
        this.closeButton.removeEventListener("click", this, false);
    },
    handleEvent: function(event) {
        switch(event.type) {
            case "click":
                if (event.button != 0) return;
                if (this.previewButton == event.currentTarget) {
                    this.preview();
                }
                else if (this.saveButton == event.currentTarget) {
                    this.save();
                }
                else if (this.closeButton == event.currentTarget) {
                    this.dialog.close();
                }
                break;
            case "load":
                var doc = this.dialog.document;
                doc.body.append(...new doc.ownerGlobal.DOMParser().parseFromSafeString('\
                    <style>\
                        :not(input):not(select) { padding: 0px; margin: 0px; }\
                        table { border-spacing: 0px; }\
                        body, html, #main, #textarea { width: 100%; height: 100%; }\
                        #textarea { font-family: monospace; }\
                    </style>\
                    <table id="main">\
                        <tr height="100%">\
                            <td colspan="4"><textarea contentEditable="true" id="textarea"></textarea></td>\
                        </tr>\
                        <tr height="40">\
                            <td><input type="button" value="Просмотр" id="Vorschau"/></td>\
                            <td><input type="button" value="Сохранить" id="Speichern"/></td>\
                            <td width="80%"><span class="log"></span></td>\
                            <td><input type="button" value="Закрыть" id="Schliessen"/></td>\
                        </tr>\
                    </table>\
                ', "text/html").querySelectorAll("style,table"));
                this.textbox = doc.querySelector("textarea");
                this.previewButton = doc.querySelector('input[value="Просмотр"]');
                this.saveButton = doc.querySelector('input[value="Сохранить"]');
                this.closeButton = doc.querySelector('input[value="Закрыть"]');
                this.logField = doc.querySelector('.log');

        var eTLDsvc = Cc["@mozilla.org/network/effective-tld-service;1"].getService(Ci.nsIEffectiveTLDService);
        var eTLD;
        var uri = gBrowser.currentURI;
        try {
        eTLD = eTLDsvc.getBaseDomain(uri);
            } catch (e) {
         eTLD = uri.asciiHost;
        }

                var code = "@namespace url(" + this.doc.documentElement.namespaceURI + ");\n";
                if (gBrowser.currentURI.spec.slice(0, 4) === "http") {code +="@-moz-document domain(" + eTLD + ") {\n\n\n\n}";}
                if (gBrowser.currentURI.spec.slice(0, 4) != "http") {
                code +="@-moz-document url(" + this.win.location.href + ") {\n\n\n\n}";}

                this.textbox.value = code;
                this.dialog.addEventListener("unload", this, false);
                this.previewButton.addEventListener("click", this, false);
                this.saveButton.addEventListener("click", this, false);
                this.closeButton.addEventListener("click", this, false);

                this.textbox.focus();
                let p = this.textbox.value.length - 3;
                this.textbox.setSelectionRange(p, p);

                break;
              case "unload":
                this.destroy();
                this.callback(this);
                break;
        }
    },
    preview: function() {
        var code = this.textbox.value;
        if (!code || !/\:/.test(code))
            return;
        code = "data:text/css;charset=utf-8," + encodeURIComponent(this.textbox.value);
        if (code == this.preview_code)
            return;
        this.preview_end();
        var uri = Services.io.newURI(code, null, null);
        this.sss.loadAndRegisterSheet(uri, (Ci.nsIStyleSheetService.AGENT_SHEET || Ci.nsIStyleSheetService.USER_SHEET));
        this.preview_code = code;
        this.log("Preview");
    },
    preview_end: function() {
        if (this.preview_code) {
            let uri = Services.io.newURI(this.preview_code, null, null);
            this.sss.unregisterSheet(uri, (Ci.nsIStyleSheetService.AGENT_SHEET || Ci.nsIStyleSheetService.USER_SHEET));
            this.preview_code = "";
        }
    },
    save: function() {
        var data = this.textbox.value;
        if (!data) return;
        var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
        fp.init(window, "", Ci.nsIFilePicker.modeSave);
        fp.appendFilter("CSS Files","*.css");
        fp.defaultExtension = "css";
        if (window.UCL)
        fp.displayDirectory = UCL.FOLDER;
        var suConverter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter);
        suConverter.charset = "UTF-8";
        data = suConverter.ConvertFromUnicode(data);
        var nsIFilePicker = Components.interfaces.nsIFilePicker;
        fp.open(function (rv) {
                if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {
                var foStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
                foStream.init(fp.file, 0x02|0x20|0x08, 0666, 0);
                foStream.write(data, data.length);
                foStream.close();
             }
         });
        this.saved = true;
    },
    log: function() {
        this.logField.textContent = dateFormat(new Date(), "%H:%M:%S") + ": " + $A(arguments);
    }
};

UCL.init();

function $(id) { return document.getElementById(id); }
function $A(arr) { return Array.from(arr); }
function $C(name, attr) {
    var el = document.createXULElement(name);
    if (attr) Object.keys(attr).forEach(function(n) { el.setAttribute(n, attr[n]) });
    return el;
}
function dateFormat(date, format) {
    format = format.replace("%Y", ("000" + date.getFullYear()).substr(-4));
    format = format.replace("%m", ("0" + (date.getMonth()+1)).substr(-2));
    format = format.replace("%d", ("0" + date.getDay()).substr(-2));
    format = format.replace("%H", ("0" + date.getHours()).substr(-2));
    format = format.replace("%M", ("0" + date.getMinutes()).substr(-2));
    format = format.replace("%S", ("0" + date.getSeconds()).substr(-2));
    return format;
}

function log() { Application.console.log(Array.from(arguments)); }

})();


не решенным осталось - добавить контестное меню в окно (но что-то все перепробовал и не получается) и второе не знаю в preview: function() и в preview_end: function()  добавил USER_SHEET и не уверен правильно или нет, но вроде работает.
И подскажи пожайлуста чем можно заменить
скрытый текст

Выделить код

Код:

getBrowserForContentWindow: function(aContentWindow) {
      return aContentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
          .getInterface(Ci.nsIWebNavigation)
          .QueryInterface(Ci.nsIDocShellTreeItem)
          .rootTreeItem
          .QueryInterface(Ci.nsIInterfaceRequestor)
          .getInterface(Ci.nsIDOMWindow)
          .QueryInterface(Ci.nsIDOMChromeWindow);
    },

Отредактировано Andrey_Krropotkin (07-03-2020 17:55:21)

Отсутствует

 

№1439908-03-2020 10:33:33

Dumby
Участник
 
Группа: Members
Зарегистрирован: 12-08-2012
Сообщений: 2254
UA: Firefox 52.0

Re: Custom Buttons

Andrey_Krropotkin пишет

добавить контестное меню в окно

Для этого нужны обеспечительные скрипты и стили.
Можно заменить CSSTester.prototype.init()

скрытый текст

Выделить код

Код:

init() {
        var url = "data:application/xhtml+xml;charset=utf8," + encodeURIComponent(
            `<?xml version="1.0"?>
            <?xml-stylesheet href="chrome://global/skin/menu.css" type="text/css"?>
            <?xml-stylesheet href="chrome://global/skin/popup.css" type="text/css"?>
            <html xmlns="${xhtmlns}">
                <head>
                    <title>CSSTester</title>
                    <script src="chrome://global/content/globalOverlay.js"/>
                    <script src="chrome://global/content/editMenuOverlay.js"/>
                    <style>#textarea{width:calc(100% - 2px)!important;}</style>
                </head>
                <body></body>
            </html>`
        );
        var proto = CSSTester.prototype;
        var uri = Services.io.newFileURI(Services.dirsvc.get("ProfD", Ci.nsIFile));
        var chromeURL = `chrome://custombuttons/content/cbdialog${Date.now()}.xhtml`;
        var ams = Cc["@mozilla.org/addons/addon-manager-startup;1"].getService(Ci.amIAddonManagerStartup);
        proto.CSSTesterHelper = ams.registerChrome(uri, [["override", chromeURL, url]]);
        addDestructor(proto.CSSTesterHelper.destruct);

        (proto.init = function() {
            (this.dialog = openDialog(chromeURL, "", "width=850,height=600,dialog=no"))
                .addEventListener("load", this, false);
        }).call(this);
    },

в preview: function() и в preview_end: function()  добавил USER_SHEET и не уверен правильно или нет

Замысел непонятен, AGENT_SHEET имеет значение ноль,
таким образом запись (Ci.nsIStyleSheetService.AGENT_SHEET || Ci.nsIStyleSheetService.USER_SHEET)
эквивалентна просто Ci.nsIStyleSheetService.USER_SHEET

подскажи пожайлуста чем можно заменить

Хорошо бы посмотреть где и как это используется.
Вот, парочка вариантов, может подойдёт

скрытый текст

Выделить код

Код:

getBrowserForContentWindow: aContentWindow => aContentWindow.docShell.rootTreeItem.domWindow,

getBrowserForContentWindow: aContentWindow => aContentWindow.windowRoot.ownerGlobal,

Отсутствует

 

№1440008-03-2020 13:43:29

Andrey_Krropotkin
Участник
 
Группа: Members
Зарегистрирован: 11-11-2011
Сообщений: 484
UA: Firefox 73.0

Re: Custom Buttons

Dumby пишет

Замысел непонятен

Если тестирую браузер нужен AGENT_SHEET, если сайт - USER_SHEET (как то так, а с этим вроде бы все тестируется)

Dumby пишет

Хорошо бы посмотреть

Исправляю очень старый скрипт, пока на полпути

скрытый текст

Выделить код

Код:

// ==UserScript==
// @name           SaveUserChromeJS.uc.js
// @author         ywzhaiqi
// @description    установка контекстного меню кнопок на github для скачивания скриптов
// @include        main
// @charset        UTF-8
// @version        0.4b
// @homepageURL    https://github.com/ywzhaiqi/userChromeJS/tree/master/SaveUserChromeJS
// @reviewURL      http://bbs.kafan.cn/thread-1590873-1-1.html
// ==/UserScript==

(function() {

// Включены ли уведомления после сохранения?
var notificationsAfterInstall = true;

// Загружается ли скрипт после сохранения (запускать не нужно)? Поддерживается только .uc.js, некоторые скрипты проблематичны.
var runWithoutRestart = false;


let { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
if (!window.Services) Cu.import("resource://gre/modules/Services.jsm");

if(typeof window.saveUserChromeJS != "undefined"){
    window.saveUserChromeJS.uninit();
    delete window.saveUserChromeJS;
}

const RE_USERCHROME_JS = /\.uc(?:-\d+)?\.(?:js|xul)$|userChrome\.js$/i;
const RE_CONTENTTYPE = /text\/html/i;

var ns = window.saveUserChromeJS = {
    

    init: function() {
           // добавить в contentAreaContextMenu
              if ( document.getElementById("uc-install-menu") ) return; 
              var xulns = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
              var icon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAAICAAP//AICAgMDAwP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcj7VkAAABfdFJOU/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8Ak5pfLAAAAAlwSFlzAAAOwwAADsMBx2+oZAAAAFxJREFUKFNljgEOwCAIAwuF/395RWXMrDExHLQA3gKYpVXojwPo6SpewDSzAHGAXvWpkQYagNSWN2EyfGUM+G/RQWZFOnSt9AZMR3nGwggivqF1Q12xQVzavRHwALQIAv2bDRzYAAAAAElFTkSuQmCC";
        var contextMenu = document.getElementById("contentAreaContextMenu");
        var menuitem = document.createElementNS(xulns, "menuitem");
        menuitem.setAttribute("id", "uc-install-menu");
        menuitem.setAttribute("label", "Установить для userChromeJS");
        menuitem.setAttribute("class", "menuitem-iconic");
        menuitem.setAttribute("image", icon);
        menuitem.setAttribute("accessKey", "I");
        menuitem.setAttribute("oncommand", "saveUserChromeJS.saveScript(gContextMenu.linkURL)");

        contextMenu.insertBefore(menuitem, contextMenu.firstChild);
        contextMenu.addEventListener("popupshowing", this, false);
        this._menuitem = menuitem;
    },
    handleEvent: function(event){
        switch(event.type){
            case "popupshowing":
                if (event.target != event.currentTarget) return;
                if(gContextMenu.onLink){
                    this._menuitem.hidden = !RE_USERCHROME_JS.test(gContextMenu.linkURL);
                }else{
                    this._menuitem.hidden = true;
                }
                break;
        }
    },
    
    observe: function(aSubject, aTopic, aData) {
        switch (aTopic) {
            case "content-document-global-created":
                let safeWin = aSubject;
                let chromeWin = this.getBrowserForContentWindow(safeWin).wrappedJSObject;
                if (!chromeWin) return;

                let gBrowser = chromeWin.gBrowser;
                if (!gBrowser) return;

                let lhref = safeWin.location.href;
                if(lhref.startsWith("view-source")) return;

                // Показать баннер установки scriptish, если пользователь переходит к .user.js
                // файл в top-level tab.
                if (safeWin === safeWin.top && RE_USERCHROME_JS.test(lhref) && !RE_CONTENTTYPE.test(safeWin.document.contentType)) {
                    safeWin.setTimeout(function(){
                        ns.showInstallBanner(gBrowser.getBrowserForDocument(safeWin.document));
                    }, 500);
                }

                if(safeWin.location.hostname == 'github.com'){
                    safeWin.addEventListener("DOMContentLoaded", function(){
                        ns.github_addButton(safeWin.document);

                        // github с history.pushstate, нужно добавить кнопку еще раз после загрузки страницы
                        // 2014-7-15:firefox 33(nightly)если цитируется unsafeWindow.$ это потерпит крах
                        if (Services.appinfo.version < 33) {
                            ns.github_addListener(safeWin);
                        }                    
                        var sWBrowser = gBrowser.getBrowserForContentWindow(safeWin);
                        if (!sWBrowser.ProgListener) {
                           sWBrowser.ProgListener = {
                              QueryInterface: XPCOMUtils.generateQI(["nsIWebProgressListener", "nsISupportsWeakReference"]),
                              onLocationChange: function() {
                                 safeWin.setTimeout(function() {
                                    ns.github_addButton(safeWin.document);
                                 }, 0);
                              }
                           };
                        };
                        try {
                           sWBrowser.addProgressListener(sWBrowser.ProgListener, Ci.nsIWebProgress.NOTIFY_LOCATION);
                           safeWin.addEventListener('beforeunload', function() {
                              sWBrowser.removeProgressListener(sWBrowser.ProgListener);
                           });
                        } catch(e) { };
                    }, false);
                }

                break;
        }
    },
    

    showInstallBanner: function(browser) {
        var notificationBox = gBrowser.getNotificationBox(browser);
        var greeting = "Das ist ein userChrome Script. Klicken Sie auf Installieren, um es zu verwenden. Nach dem Speichern im Chrome Ordner bitte einen Neustart durchführen.";
        var btnLabel = "Installieren";

        // Удалить существующие уведомления. Уведомления удаляются
        // автоматически по клику и по странице навигации, но нам нужно удалить
        // их самим в случае перезагрузки, или они складываются.
        for (var i = 0, child; child = notificationBox.childNodes[i]; i++)
            if (child.getAttribute("value") == "install-userChromeJS")
                notificationBox.removeNotification(child);

        var notification = notificationBox.appendNotification(
            greeting,
            "install-userChromeJS",
            null,
            notificationBox.PRIORITY_WARNING_MEDIUM, [{
                label: btnLabel,
                accessKey: "I",
                popup: null,
                callback: this.saveCurrentScript
            }
        ]);
    },
    github_addButton: function(doc){
        if(doc.getElementById("uc-install-button")) return;

        var rawBtn = doc.getElementById("raw-url");
        if(!rawBtn) return;

        var downURL = rawBtn.href;
        if(!RE_USERCHROME_JS.test(downURL)) return;

        var installBtn = doc.createXULElement("a");
        installBtn.setAttribute("id", "uc-install-button");
        installBtn.setAttribute("class", "btn btn-sm");
        installBtn.setAttribute("href", downURL);
        installBtn.innerHTML = "Installieren";
        installBtn.addEventListener("click", function(event){
            event.preventDefault();
            ns.saveScript(downURL);
        }, false);

        rawBtn.parentNode.insertBefore(installBtn, rawBtn);
    },
    github_addListener: function(win){
        var script = '\
            (function(){\
                var $ = unsafeWindow.jQuery;\
                if(!$) return;\
                $(document).on("pjax:success", function(){\
                    github_addButton(document);\
                });\
            })();\
        ';
        let sandbox = new Cu.Sandbox(win, {sandboxPrototype: win});
        sandbox.unsafeWindow = win.wrappedJSObject;
        sandbox.document     = win.document;
        sandbox.window       = win;
        sandbox.github_addButton = ns.github_addButton;
        Cu.evalInSandbox(script, sandbox);
    },
    saveCurrentScript: function(event){
        ns.saveScript();
    },
    saveScript: function(url) {
        var win = ns.getFocusedWindow();

        var doc, name, fileName, fileExt, charset;
        if(!url){
            url = win.location.href;
            doc = win.document;
            name = doc.body.textContent.match(/\/\/\s*@name\s+(.*)/i);
            charset = doc.body.textContent.match(/\/\/\s*@charset\s+(.*)/i);
        }

        name = name && name[1] ? name[1] : decodeURIComponent(url.split("/").pop());
        fileName = name.replace(/\.uc\.(js|xul)$|$/i, ".uc.$1").replace(/\s/g, '_');
        if (fileName.match(/\.uc\.$/i)) {  // Исправить имя
            var m = url.match(/\.(js|xul)$/);
            if (m)
                fileName += m[1];
        }
  
        fileExt = name.match(/\.uc\.(js|xul)$/i);
        fileExt = fileExt && fileExt[1] ? fileExt[1] : "js";
        charset = charset && charset[1] ? charset[1] : "UTF-8";

        // https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XUL/Tutorial/Open_and_Save_Dialogs
        var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
        var err = false;
          try {
             fp.init(window, "", Ci.nsIFilePicker.modeSave);
          } catch(e) {
             fp.init(ns.getMostRecentWindow(), "", Ci.nsIFilePicker.modeSave);
             err = true;
             Application.console.log('SaveUserChromeJS.uc.js - error catched (A)');
          };
        var SCRIPTS_FOLDER = Services.dirsvc.get("UChrm", Ci.nsIFile);
        fp.appendFilter("*." + fileExt, "*.uc.js;*.uc.xul");
        fp.appendFilters(Ci.nsIFilePicker.filterAll);
        fp.displayDirectory = SCRIPTS_FOLDER; 
        fp.defaultExtension = fileExt;
        fp.defaultString = fileName;
        var nsIFilePicker = Components.interfaces.nsIFilePicker;
        fp.open(function (rv) {
        if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {
              var persist = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"].createInstance(Ci.nsIWebBrowserPersist);
                persist.persistFlags = persist.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
                var url2 = url.replace("github", "raw.githubusercontent").replace("\/blob", " ");
                var obj_URI;
                if(doc && fileExt != 'xul'){
                    obj_URI = doc.documentURIObject;
                }else{
                    obj_URI = Services.io.newURI(url2, null, null);
                }
                    if(notificationsAfterInstall){
                    persist.progressListener = {
                    onProgressChange: function(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress) {
                            if(aCurSelfProgress == aMaxSelfProgress){
                                    var win = err ? ns.getMostRecentWindow() : window;
                                    win.setTimeout(function(){
                                    ns.showInstallMessage({
                                        fileExt: fileExt,
                                        fileName: fileName,
                                        file: fp.file,
                                        charset: charset
                                    });
                                }, 100);
                            }
                        },
                        onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus) { }
                    };
                }
                
                persist.saveURI(obj_URI, document.nodePrincipal, null, null, null, null, fp.file, null);
             }
         });
    },
    showInstallMessage: function(info){
        var isRun = (info.fileExt == "js");

        var mainAction, secondActions;
        if(runWithoutRestart && isRun){
            mainAction = {
                label: "Выполнить немедленно (без перезапуска).",
                accessKey: "a",
                callback: function(){
                    ns.runScript(info.file, info.charset);
                }
            };
            secondActions = [{
                label: "Перезагрузите сейчас",
                accessKey: "s",
                callback: ns.restartApp
            }];
        }else{
            mainAction = {
                label: "Перезагрузите сейчас",
                accessKey: "s",
                callback: ns.restartApp
            };
            secondActions = null;
        }

        var showedMsg = ns.popupNotification({
            id: "userchromejs-install-popup-notification",
            message: "'" + info.fileName + "' Установка завершена.",
            mainAction: mainAction,
            secondActions: secondActions,
            options: {
                removeOnDismissal: true,
                persistWhileVisible: true
            }
        });
    },
    popupNotification: function(details){
        var win = ns.getMostRecentWindow();
        if (win && win.PopupNotifications) {
            win.PopupNotifications.show(
                win.gBrowser.selectedBrowser,
                details.id,
                details.message,
                "",
                details.mainAction,
                details.secondActions,
                details.options);
            return true;
        }

        return false;
    },
    // Только поддержка us.js
        runScript: function(file, charset){
        window.userChrome_js.getScripts();
        if(window.userChromeManager){
            window.userChromeManager.rebuildScripts();
        }

        var dir = file.parent.leafName;
        if(dir.toLowerCase() == 'chrome' || (dir in window.userChrome_js.arrSubdir)){

            let context = {};
            Services.scriptloader.loadSubScript( "file:" + file.path, context, charset || "UTF-8");
        }
    },
    flushCache: function (file) {
        if (file)
             Services.obs.notifyObservers(file, "flush-cache-entry", "");
        else
             Services.obs.notifyObservers(null, "startupcache-invalidate", "");
    },
    getFocusedWindow: function() {
        var win = document.commandDispatcher.focusedWindow;
        try {
         return (!win || win == window) ? content : win;
      } catch(e) {
         Application.console.log('SaveUserChromeJS.uc.js - error catched (B)');
         return (!win || win == window) ? null : win;
      };
    },
    getMostRecentWindow: function(){
        return Services.wm.getMostRecentWindow("navigator:browser")
    },
    getBrowserForContentWindow: function(aContentWindow) {
      return aContentWindow.docShell.rootTreeItem.domWindow;
    },
    restartApp: function() {
        const appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"].getService(Components.interfaces.nsIAppStartup);

        // Уведомить все окна о том, что приложение было запрошено.
        var os = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
        var cancelQuit = Components.classes["@mozilla.org/supports-PRBool;1"].createInstance(Components.interfaces.nsISupportsPRBool);
        os.notifyObservers(cancelQuit, "quit-application-requested", null);

        // Что-то прервало процесс выхода.
        if (cancelQuit.data) return;

        // Уведомить все окна о том, что приложение завершено.
        os.notifyObservers(null, "quit-application-granted", null);

        // Перечислить все окна и обработчики вызовов
        var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator);
        var windows = wm.getEnumerator(null);
        var win;
        while (windows.hasMoreElements()) {
            win = windows.getNext();
            if (("tryToClose" in win) && !win.tryToClose()) return;
        }
        let XRE = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime);
        if (typeof XRE.invalidateCachesOnRestart == "function") XRE.invalidateCachesOnRestart();
        appStartup.quit(appStartup.eRestart | appStartup.eAttemptQuit);
    }
};


function log(arg){ Application.console.log("[SaveUserChromeJS]" + arg);}

function checkDoc(doc) {
    if (!(doc instanceof HTMLDocument)) return false;
    if (!window.mimeTypeIsTextBased(doc.contentType)) return false;
    if (!doc.body || !doc.body.hasChildNodes()) return false;
    if (doc.body instanceof HTMLFrameSetElement) return false;
    return true;
}

})();

window.saveUserChromeJS.init();


Что то с кодировкой в UTF-8 выходного файла не получается, не пойму где ее поменять можно ( в persist, saveURI или еще где-то)

Отредактировано Andrey_Krropotkin (09-03-2020 01:33:21)

Отсутствует

 

Board footer

Powered by PunBB
Modified by Mozilla Russia
Copyright © 2004–2020 Mozilla Russia GitHub mark
Язык отображения форума: [Русский] [English]