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

Будьте в курсе последних изменений в мире Mozilla, следя за нашим микроблогом в Twitter.

№1312620-02-2019 17:55:12

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

Re: Custom Buttons

func4ptch4 пишет

Dumby
W7RdlAY.png
У всех так? и вообще у меня все время удаляются еще 10 расширений, может кастыли не
правильно поставил на [firefox] 65.0.1? ну которые дают работать с bootstrap и CB...

На чистом профиле тоже самое, CB пашет, зато расширения отваливаются.
Причина только в костылях config.js но что я не так сделал?

Да, подтверждаю, удалось воспроизвести.
Например:
Textmarker — устанавливается (есть id в манифесте),
а Sticky Notes — не устанавливается (нет id в манифесте).

Пока, на скорую руку, добавил такое. Спасибо.

Выделить код

Код:

Cu.import("resource://gre/modules/addons/XPIInstall.jsm", {})
        .shouldVerifySignedState = addon => !addon.id;

Отсутствует

 

№1312720-02-2019 19:27:07

Stkvsky
Участник
 
Группа: Members
Зарегистрирован: 26-06-2012
Сообщений: 1699
UA: Firefox 55.0

Re: Custom Buttons

Подскажите пожалуйста, есть ли кнопка перемещающая вкладку в конец списка вкладок, чтобы не тянуть ее руками через все открытые вкладки

Отсутствует

 

№1312820-02-2019 21:53:43

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

Re: Custom Buttons

Dumby
Спасибо вам! я просто голову ломал пару дней и думал как с АМО не устанавливаются... так и сяк что только не делал)
Я читал про манифест, но у меня урезанный фф и где этот манифест должен быть я не понял... да и вообще как с АМО устанавливать? сперва надо ид узнавать.
Так что еще раз спасибо что без манифеста, это в 100 раз удобнее.
Хочу отдельно сказать спасибо что делайте для нас конфиг и поддерживайте(хотя сидите на 52?).

Отсутствует

 

№1312921-02-2019 21:49:31

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

Re: Custom Buttons

Отвалилась кнопка, если кто может посмотрите там он не вставляет куда надо!)
Осторожно в коде много мусора.

Insert special symbol

Выделить код

Код:

//forum.mozilla-russia.org/viewtopic.php?pid=760489#p760489
this.type != "menu" ? this.type = "menu" : (popup => {

    var columns=["¤ ¦ § © « » ¬ ® ° ± µ ¶ — ‘ ’ “ ” • ‰ ‹ › ™",
                 "… ≈ ≠ × ✓ ✗ ⊞ ⊞ ⊞ ⊞ ⊞ ⊞ ⊞ ⊞ ⊞ ⊞ ⊞",
                 "\uD83E\uDD8A \uD83D\uDE0E ⊞ ⊞ ⊞ ⊞ ⊞ ⊞ ⊞"];

  //var css = //0&&
    `   #${_id} menuitem > .menu-text{
            font-size:22px;
            font-family:Consolas,Rockwell,Verdana;
            text-align:center;
            -moz-appearance:none;
            margin:0;
            padding:0 14px;}
        #${_id} menuitem > :not(.menu-text){display:none;}
        #${_id} > menupopup > arrowscrollbox{background-color:menu;}
    `.replace(/;/g, " !important;");

    var inserter={
        get docShell() {
            delete this.docShell;
            return this.docShell = "docShell" in document
                && document.docShell instanceof Ci.nsIDocShell
                ? document.docShell : window.docShell;},
        insertText: function(text) {
            if (!this.docShell.isCommandEnabled("cmd_insertText")) return;
            var params = Components.classes["@mozilla.org/embedcomp/command-params;1"]
                .createInstance(Components.interfaces.nsICommandParams);
            params.setStringValue("state_data", text);
            this.docShell.doCommandWithParams("cmd_insertText", params);},
        insert(text) {
            var br = document.activeElement;
            !br || br.localName != "browser" || !br.isRemoteBrowser
            ? this.insertText(text) : br.messageManager.loadFrameScript(
                `data:,(${this.insertText})${encodeURIComponent(text.toSource())}`
            , false);}
    };
    this.onmousedown = e => {
        if (e.button) return;
        popup.addEventListener("popupshowing", e => popup.firstChild
            .boxObject.parentBox.setAttribute("orient", "horizontal")
        , {once: true});
        popup.setAttribute("context", "");
        popup.setAttribute("oncommand", "inserter.insert(event.target.label);");
        popup.onauxclick = e => {
            var sym = e.target.label;
            sym && inserter.insert(sym);}
        popup.inserter = inserter;
        var df = document.createDocumentFragment();
        for(var symbols of columns) {
            var menugroup = popup.appendChild(document.createElement("menugroup"));
            menugroup.setAttribute("orient", "vertical");
            for(var sym of symbols.split(" ")) menugroup.appendChild(
                document.createElement("menuitem")
            ).setAttribute("label", sym);}
        popup.append(df);
        this.onmousedown = null;
        if (!css) return;
        var dwu = "windowUtils" in window && windowUtils instanceof Ci.nsIDOMWindowUtils
            ? windowUtils : window.QueryInterface(Ci.nsIInterfaceRequestor)
                .getInterface(Ci.nsIDOMWindowUtils);
        var type = dwu.AGENT_SHEET;
        var url = "data:text/css," + encodeURIComponent(css);
        dwu.loadSheetUsingURIString(url, type);
        addDestructor(() => dwu.removeSheetUsingURIString(url, type));}
})(this.appendChild(document.createElement("menupopup")));





// Indomito и Difabor-версия от 27.05.2014
// За основу взят код-Вставка символа в текстовое поле(Firefox) от11.05.2013 автор bunda1
///var delay=600,array=[],symbList,myID=_id,symbName=myID+".symbols",mynum=0;
///var symbListOrig="¤,¦,§,@,©,«,»,¬,®,°,±,µ,¶,—,‘,’,“,”,•,‰,‹,›,™";

//this.onmousedown=function(e){this._mouseDownTime=Date.now();};
    //if(e.button!=0)return;
    //if(e.button==2)this._mouseDownTime=Date.now();};

this.tooltipText=
"                    Вставить специальный символ\n—————————————————————————\n"+
"Left               —   Вставка символа из списка\n"+
"Left Long     —   Редактирование списка символов\n"+
"Middle         —   Возврат к исходному списку символов\n"+
"Right            —   Запуск таблицы символов Windows\n"+
"Right Long  —   Стандартное Меню Кнопки";

//this.onclick=function(e){
//    symbList=(custombuttons.isPref(symbName))? unescape(custombuttons.getPrefs(symbName)): symbListOrig;
//    if(e.button==0 && ((Date.now() - this._mouseDownTime) < delay) &&!e.ctrlKey&&!e.shiftKey&&!e.altKey&&!e.metaKey){
//      array=symbList.split(",");
//      var node=document.getElementById(this.id + "-menuPopup");
//      if(node && node.parentNode) node.parentNode.removeChild(node); //блокировать дублирование меню
//
//      var menuPopup=document.getElementById("mainPopupSet").appendChild(document.createElement("menupopup"));
//      menuPopup.id=this.id+"-menuPopup";
//
//      array.forEach(function(symbol){
//         var menuItem=document.createElement("menuitem");
//         menuItem.setAttribute("label",symbol);
//         menuItem.style.fontSize="12px"; //размер шрифта
//         menuItem.addEventListener("command",insertText,false);
//         menuPopup.appendChild(menuItem);});
//
//      menuPopup.openPopup(this,-1,-1,"popup","bottomleft","topleft");}
//    else if(e.button==0 && (((Date.now() - this._mouseDownTime) >= delay)||(!e.ctrlKey && e.shiftKey&&!e.altKey&&!e.metaKey))){
//    var a=prompt("Рредактировать эту строку, вставляя символы или группы символов через запятую:",symbList);if (a) custombuttons.setPrefs(symbName,escape(a));}
//
//    else if((e.button==1 || (e.button==0&&e.ctrlKey)) &&(!e.shiftKey&&!e.altKey&&!e.metaKey)){custombuttons.clearPrefs(symbName);}   //Действие при клике СКМ//mbMouse();
//    else if((e.button==1 || (e.button==0&&e.ctrlKey)) && (e.shiftKey&&!e.altKey&&!e.metaKey)){alert("Длительность: "+(Date.now() - this._mouseDownTime)+ "мс " + mynum);}
//
//    else if(e.button==2 && !e.ctrlKey&&!e.shiftKey&&!e.altKey&&!e.metaKey&& ((Date.now() - this._mouseDownTime) < delay)){startProcess("C:\\Windows\\system32\\charmap.exe",[]);}    };
//    //Действие при клике ПКМ без модификаторов//if ((Date.now() - this._mouseDownTime) < delay) startProcess("C:\\Windows\\system32\\charmap.exe",[]);
//this.oncontextmenu=function(e){
//    if(e.button==2 && ((Date.now() - this._mouseDownTime) < delay) &&!e.ctrlKey&&!e.shiftKey&&!e.altKey&&!e.metaKey){e.preventDefault();e.stopPropagation();}};
//    //Блокируем контекстное меню при клике ПКМ без модификаторов
//
//
//function startProcess(path,args){var file=Components.classes["@mozilla.org/file/local;1"] .createInstance(Components.interfaces.nsILocalFile);
//     file.initWithPath(path);
//            if(file.exists()){var process=Components.classes["@mozilla.org/process/util;1"] .createInstance(Components.interfaces.nsIProcess);
//      process.init(file);process.run(false,args,args.length);} else custombuttons. alertBox("Файл не найден",path);};
//
////this.type="menu";
//
// Вставить текст в текстовое поле ............
//function insertText(){ 
//   var text=this.label;
//   var cmd="cmd_insertText";
//   var controller=document.commandDispatcher.getControllerForCommand(cmd);
//   if(controller && controller.isCommandEnabled(cmd)){
//        var controller=controller.QueryInterface(Components.interfaces.nsICommandController);
//        var params=Components.classes["@mozilla.org/embedcomp/command-params;1"].createInstance(Components.interfaces.nsICommandParams);
//        params.setStringValue("state_data",text);
//        controller.doCommandWithParams(cmd,params);}};

Отредактировано func4ptch4 (21-02-2019 21:52:00)

Отсутствует

 

№1313021-02-2019 23:04:17

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

Re: Custom Buttons

func4ptch4
Зачем закомментировал css?
Если css не нужен, то лучше убрать две косые перед нулём.

Вообще, я, иногда, приглядываю за ней в ночнушке, на интерес.
Если хочешь попробовать — могу процитировать

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

Выделить код

Код:

this.type != "menu" ? this.type = "menu" : (popup => {

    var columns = [
        "¤ ¦ § © « » ¬ ® ° ± µ ¶ — ‘ ’ “ ” • ‰ ‹ › ™",
        "… ≈ ≠ × ✓ ✗ ⊞ ⊞ ⊞ ⊞ ⊞ ⊞ ⊞ ⊞ ⊞ ⊞ ⊞",
        "\uD83E\uDD8A \uD83D\uDE0E ⊞ ⊞ ⊞ ⊞ ⊞ ⊞ ⊞"
    ];
    var css = //0&&
    `
        #${_id} menuitem > .menu-text {
            font-size: 22px;
            font-family: Consolas, Rockwell, Verdana;
            text-align: center;
            -moz-appearance: none;
            margin: 0;
            padding: 0 14px;
        }
        #${_id} menuitem > :not(.menu-text) {
            display: none;
        }
        #${_id} > menupopup > arrowscrollbox {
            background-color: menu;
        }
    `.replace(/;/g, " !important;");

    var inserter = {
        get docShell() {
            delete this.docShell;
            return this.docShell = "docShell" in document
                && document.docShell instanceof Ci.nsIDocShell
                ? document.docShell : window.docShell;
        },
        get insertText() {
            delete this.insertText;
            return this.insertText = text => {
                if (!this.docShell.isCommandEnabled("cmd_insertText")) return;
                var params = "createCommandParams" in Components.utils
                    ? Cu.createCommandParams()
                    : Components.classes["@mozilla.org/embedcomp/command-params;1"]
                        .createInstance(Components.interfaces.nsICommandParams);
                params.setStringValue("state_data", text);
                this.docShell.doCommandWithParams("cmd_insertText", params);
            }
        },
        insert(text) {
            var br = document.activeElement;
            !br || br.localName != "browser" || !br.isRemoteBrowser
            ? this.insertText(text) : br.messageManager.loadFrameScript(
                `data:,(${this.insertText})${encodeURIComponent(text.toSource())}`
            , false, true);
        }
    };
    this.onmousedown = e => {
        if (e.button) return;
        /*
        popup.addEventListener("popupshowing", e => popup.firstChild
            .boxObject.parentBox.setAttribute("orient", "horizontal")
        , {once: true});
        */
        popup.addEventListener("popupshowing", e => {
            var menugroup = popup.firstChild;

            // Bug 1519948 - Remove box objects (Firefox ??+)
            // https://bugzilla.mozilla.org/show_bug.cgi?id=1519948
            var parent = "boxObject" in menugroup
                ? menugroup.boxObject.parentBox
                : menugroup.flattenedTreeParentNode;

            parent.setAttribute("orient", "horizontal");

            // Bug 1454357 - Remove scrollbox binding (Firefox 66+)
            // https://bugzilla.mozilla.org/show_bug.cgi?id=1454357
            if (parent.localName == "scrollbox")
                parent.style.setProperty("-moz-box-orient", "horizontal", "important");

        }, {once: true});

        popup.setAttribute("context", "");
        popup.setAttribute("oncommand", "inserter.insert(event.target.label);");
        popup.onauxclick = e => {
            var sym = e.target.label;
            sym && inserter.insert(sym);
        }
        popup.inserter = inserter;
        var df = document.createDocumentFragment();
        for(var symbols of columns) {
            var menugroup = popup.appendChild(document.createElement("menugroup"));
            menugroup.setAttribute("orient", "vertical");
            for(var sym of symbols.split(" ")) menugroup.appendChild(
                document.createElement("menuitem")
            ).setAttribute("label", sym);
        }
        popup.append(df);
        this.onmousedown = null;
        if (!css) return;
        var dwu = "windowUtils" in window && windowUtils instanceof Ci.nsIDOMWindowUtils
            ? windowUtils : window.QueryInterface(Ci.nsIInterfaceRequestor)
                .getInterface(Ci.nsIDOMWindowUtils);
        var type = dwu.AGENT_SHEET;
        var url = "data:text/css," + encodeURIComponent(css);
        dwu.loadSheetUsingURIString(url, type);
        addDestructor(() => dwu.removeSheetUsingURIString(url, type));
    }
})(this.appendChild(document.createElement("menupopup")));

Отсутствует

 

№1313125-02-2019 10:29:37

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

Re: Custom Buttons

Dumby Спасибо, а так на ночнушках не сижу.

Отсутствует

 

№1313208-03-2019 15:11:01

leex
Участник
 
Группа: Members
Зарегистрирован: 24-03-2011
Сообщений: 319
UA: Firefox 50.0

Re: Custom Buttons

Можно ли в СВ добавить имитацию сочетания клавиш ctrl+F5 ?
дело в том что в последние время стало проблематично зайти на  Gmail
При входе появляется надпись ошибка искажения содержимого  и если не нажать ctrl+F5 то страница остается недоступной

У меня есть кнопка с таким кодом, можно ли в нее добавить ctrl+F5?

Выделить код

Код:

gBrowser.selectedTab = gBrowser.addTab('http://mail.google.com/mail/#i');

Отредактировано leex (08-03-2019 15:12:19)

Отсутствует

 

№1313308-03-2019 16:16:19

Infocatcher
Not found
 
Группа: Extensions
Зарегистрирован: 24-05-2007
Сообщений: 4339
UA: Firefox 56.0

Re: Custom Buttons

leex пишет

добавить ctrl+F5?

Можно попробовать вот так:

Выделить код

Код:

var tab = gBrowser.selectedTab = gBrowser.addTab("http://mail.google.com/mail/#i", {
    triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()
});
setTimeout(function() {
    tab.linkedBrowser.reloadWithFlags(nsIWebNavigation.LOAD_FLAGS_BYPASS_PROXY | nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE);
}, 1000);

Вместо 1000 надо подобрать подходящую задержку, это проще, чем отлавливать начало загрузки в случае обмазывания браузера мультипроцессностью.

Впрочем, можно воткнуть еще больше волшебных таймеров, вот так должно работать без подгонки:

Выделить код

Код:

var tab = gBrowser.selectedTab = gBrowser.addTab("http://mail.google.com/mail/#i", {
    triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()
});
var browser = tab.linkedBrowser;
setTimeout(function wait() {
    if(browser.currentURI.spec == "about:blank" || browser.webProgress.isLoadingDocument)
        setTimeout(wait, 25);
    else {
        var wn = Components.interfaces.nsIWebNavigation;
        browser.reloadWithFlags(wn.LOAD_FLAGS_BYPASS_PROXY | wn.LOAD_FLAGS_BYPASS_CACHE);
    }
}, 0);

Прошлое – это локомотив, который тянет за собой будущее. Бывает, что это прошлое вдобавок чужое. Ты едешь спиной вперед и видишь только то, что уже исчезло. А чтобы сойти с поезда, нужен билет. Ты держишь его в руках. Но кому ты его предъявишь?
Виктор Пелевин. Желтая стрела

Отсутствует

 

№1313409-03-2019 17:03:39

leex
Участник
 
Группа: Members
Зарегистрирован: 24-03-2011
Сообщений: 319
UA: Firefox 50.0

Re: Custom Buttons

Благодарю!
Использую второй код

Отсутствует

 

№1313510-03-2019 10:14:08

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

Re: Custom Buttons

leex вопрос а что делает сочетание Ctrl+F5 обновление страницы? если да то F5 тоже самое? Ctrl+R тоже что и F5.

Отсутствует

 

№1313610-03-2019 10:31:50

leex
Участник
 
Группа: Members
Зарегистрирован: 24-03-2011
Сообщений: 319
UA: Firefox 50.0

Re: Custom Buttons

func4ptch4 пишет

leex вопрос а что делает сочетание Ctrl+F5 обновление страницы? если да то F5 тоже самое? Ctrl+R тоже что и F5.

Ctrl+F5 обновляет страницу без кэша, вернее старый кэш не использует а создает новый
а F5 просто обновляет используя старый кэш для данной страницы

Отредактировано leex (10-03-2019 10:32:55)

Отсутствует

 

№1313712-03-2019 08:36:33

Rag
Участник
 
Группа: Members
Откуда: Краснодон
Зарегистрирован: 06-03-2017
Сообщений: 247
UA: Firefox 60.0

Re: Custom Buttons

Доброго дня всем.
Может кто нибудь поправить две кнопки для PaleMoon-28.4.0?
1.Проверка орфографии (на некоторых сайтах слетает галка в меню страницы на пункте “Проверка орфографии”)

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

Выделить код

Код:

//Проверка орфографии
 addEventListener('focus', function(e){
  if (e.target.tagName && (e.target.tagName == 'TEXTAREA'|| e.target.tagName == 'INPUT'))
       e.target.setAttribute('spellcheck', 'true')
 }, content.document.body);


2.Автоматически добавлять выделенный текст
скрытый текст

Выделить код

Код:

//Автоматически добавлять выделенный текст в SearchBar
 this._handleClick =()=> cbu.setPrefs(s, !cbu.getPrefs(s));

var s = 'CB.pasteIntoSearchBar';
cbu.isPref(s, true);

toggleImage();
function toggleImage() self.checked = cbu.getPrefs(s);           
gPrefService.addObserver(s, toggleImage, false);
addDestructor(()=> gPrefService.removeObserver(s, toggleImage) );

function pasteIntoSearchBar(e) {
   if ( e.button || !cbu.getPrefs(s) ) return;
      
   var sel = document.commandDispatcher.focusedWindow.getSelection();    
   if ( !sel.isCollapsed ) BrowserSearch.searchBar._textbox.value = sel;
};
addEventListener('mouseup', pasteIntoSearchBar, false, gBrowser);

Отсутствует

 

№1313812-03-2019 11:00:15

bunda1
Moderator
 
Группа: Moderators
Откуда: Латвия
Зарегистрирован: 09-02-2010
Сообщений: 4811
UA: Firefox 60.0

Re: Custom Buttons

А что за проблемы с 2.Автоматически добавлять выделенный текст, у меня вроде всё работает?

Отсутствует

 

№1313912-03-2019 11:46:44

Rag
Участник
 
Группа: Members
Откуда: Краснодон
Зарегистрирован: 06-03-2017
Сообщений: 247
UA: Firefox 60.0

Re: Custom Buttons

bunda1 пишет

А что за проблемы

Спасибо за желание помочь.С этой кнопкой я сам разобрался.Просто установил другую версию Custom Buttons.А вот с первой кнопкой это не прокатило.
Ответьте пожалуйста,какая версия CB наиболее оптимально подходит к PaleMoon-28*?

Отсутствует

 

№1314012-03-2019 12:02:41

bunda1
Moderator
 
Группа: Moderators
Откуда: Латвия
Зарегистрирован: 09-02-2010
Сообщений: 4811
UA: Firefox 60.0

Re: Custom Buttons

У меня Custom Buttons 0.0.5.8.9.5 нормально работает на последнем PaleMoon28, но мне кажется эта какая то исправленная версия которую я скачал не помню где, может тут 19-09-2017 13:46:15. Насчёт Проверка орфографии напиши на каком сайте глючит, я посмотрю.

Отсутствует

 

№1314112-03-2019 12:37:36

Rag
Участник
 
Группа: Members
Откуда: Краснодон
Зарегистрирован: 06-03-2017
Сообщений: 247
UA: Firefox 60.0

Re: Custom Buttons

bunda1 пишет

напиши на каком сайте глючит

google.ru,google.com,yandex.ua ставлю галку перезагружаю страницу и всё галки нет.А вот на duckduckgo.com галка не слетает.

Отсутствует

 

№1314212-03-2019 13:01:18

bunda1
Moderator
 
Группа: Moderators
Откуда: Латвия
Зарегистрирован: 09-02-2010
Сообщений: 4811
UA: Firefox 60.0

Re: Custom Buttons

Выделить код

Код:

// Проверка орфографии 
addEventListener('click', e=> {
   if ( e.target.tagName && (e.target.tagName == 'TEXTAREA'|| e.target.tagName == 'INPUT'))
        e.target.setAttribute('spellcheck', 'true');
}, content.document.body);

Отсутствует

 

№1314312-03-2019 13:38:39

Rag
Участник
 
Группа: Members
Откуда: Краснодон
Зарегистрирован: 06-03-2017
Сообщений: 247
UA: Firefox 60.0

Re: Custom Buttons

bunda1
Большое спасибо.Кнопка работает.

Отсутствует

 

№1314417-03-2019 05:04:15

Dobrov
Участник
 
Группа: Members
Зарегистрирован: 04-10-2011
Сообщений: 388
UA: Firefox 60.0

Re: Custom Buttons

Подскажите, как заменить/запретить стандартный MiddleClick мыши на urlbar-go-button. У меня выполняется моя функция, затем ненужная стандартная: Middle-click the Reload button to duplicate the current tab to a new tab
addEventListener("click", function(event) go_button_click(event), false, document.getElementById("urlbar-go-button"));

Отсутствует

 

№1314517-03-2019 14:06:06

leex
Участник
 
Группа: Members
Зарегистрирован: 24-03-2011
Сообщений: 319
UA: Firefox 50.0

Re: Custom Buttons

Ребята, помогите пожалуйста назначить на ПКМ открытие ссылки https://mail.google.com/mail/u/0/#sent  (с Ctrl+F5)
Но так чтобы остался этот код на ЛКМ

скрытый текст
var tab = gBrowser.selectedTab = gBrowser.addTab("http://mail.google.com/mail/#i", {
var tab = gBrowser.selectedTab = gBrowser.addTab("http://mail.google.com/mail/#i", {
    triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()
});
var browser = tab.linkedBrowser;
setTimeout(function wait() {
    if(browser.currentURI.spec == "about:blank" || browser.webProgress.isLoadingDocument)
        setTimeout(wait, 25);
    else {
        var wn = Components.interfaces.nsIWebNavigation;
        browser.reloadWithFlags(wn.LOAD_FLAGS_BYPASS_PROXY | wn.LOAD_FLAGS_BYPASS_CACHE);
    }
}, 0);

Отредактировано leex (17-03-2019 14:29:45)

Отсутствует

 

№1314617-03-2019 18:53:06

drage2
Забанен
 
Группа: Members
Откуда: Донецк
Зарегистрирован: 23-11-2017
Сообщений: 392
UA: Firefox 66.0

Re: Custom Buttons

Dumby
Привет! Хотел 67 попробовать , в ручную BOOTSTRAP рихтануть не получилось..Костыли странно работают, аддонны с BOOTSTRAP устанавливаться  , но как-то не работают толком...В  67 в ручную , без костылей сделал, а тут...Что они опять наваяли?

Отсутствует

 

№1314717-03-2019 20:39:39

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

Re: Custom Buttons

Dobrov пишет

Подскажите, как заменить/запретить стандартный MiddleClick мыши на urlbar-go-button.

Вариант

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

Выделить код

Код:

addEventListener("click", e => {
    if (e.button == 1 && e.target.id == "urlbar-go-button") {
        e.stopPropagation();

        custombuttons.editButton(self);
    }
}, true, gURLBar);

leex пишет

Ребята, помогите пожалуйста назначить на ПКМ открытие ссылки https://mail.google.com/mail/u/0/#sent  (с Ctrl+F5)
Но так чтобы остался этот код на ЛКМ

В Инициализацию попробуй

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

Выделить код

Код:

(addTab => {
    this._handleClick = () => addTab("http://mail.google.com/mail/#i");
    this.oncontextmenu = e => e.ctrlKey || e.shiftKey || !!addTab("https://mail.google.com/mail/u/0/#sent");
})(url => {
    var tab = gBrowser.selectedTab = gBrowser.addTab(url, {
        triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()
    });
    var browser = tab.linkedBrowser;
    setTimeout(function wait() {
        if(browser.currentURI.spec == "about:blank" || browser.webProgress.isLoadingDocument)
            setTimeout(wait, 25);
        else {
            var wn = Components.interfaces.nsIWebNavigation;
            browser.reloadWithFlags(wn.LOAD_FLAGS_BYPASS_PROXY | wn.LOAD_FLAGS_BYPASS_CACHE);
        }
    }, 0);
});

drage2 пишет

Хотел 67 попробовать

Странный выбор времени — за день до смены циклов.
Завтра надеюсь выложить, если ничего не случится.

Отсутствует

 

№1314818-03-2019 00:09:02

drage2
Забанен
 
Группа: Members
Откуда: Донецк
Зарегистрирован: 23-11-2017
Сообщений: 392
UA: Firefox 67.0

Re: Custom Buttons

Dumby
CB -  в аддонах не видно , кнопки, в смысле....Само СВ устанавливается...
Custom Buttons 0.0.7.0.0.2

Отредактировано drage2 (18-03-2019 11:57:38)

Отсутствует

 

№1314918-03-2019 13:11:56

leex
Участник
 
Группа: Members
Зарегистрирован: 24-03-2011
Сообщений: 319
UA: Firefox 50.0

Re: Custom Buttons

Dumby
Большое спасибо!
Код прекрасно работает  :)
Но идет двойная загрузка. Сначала загружается страница, а потом идет ее обновление
Это поведение связано со основным кодом (Сtrl+F5) Видимо влияет "плавающая" скорость интернета или скорость "запрос\ответ" с сервера.
На это только сейчас обратил внимание, так как скорость сегодня маленькая и загрузка с обновлением идет долго.

добавлено

По идее это правильная работа кода . Я хотел чтобы открылась ссылка а потом обновление с  Сtrl+F5
и Infocatcher помог реализовать это.
Если открывать gmail.com обычным способом то "Ошибка искажения содержимого" появляется не всегда.
Можно ли сделать одну загрузку без Сtrl+F5 если  "Ошибка искажения содержимого" не обнаружена?
А если обнаружена то подключить Сtrl+F5
Или как то отменить вторую загрузку (обновление) Первая загрузка то с этим кодом всегда идет хорошо, без ошибок.

Вообще, реально ли отследить эту ошибку в СВ?

Отредактировано leex (18-03-2019 15:55:09)

Отсутствует

 

№1315018-03-2019 16:58:50

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

Re: Custom Buttons

«Merge Date»

custom_buttons-0.0.7.0.0.3-fx-paxmod.xpi

config.js

Выделить код

Код:

//
try {(nsvo => {
    var o = Cu.getGlobalForObject(nsvo).Object, {freeze} = o;
    o.freeze = obj => {
        if (Components.stack.caller.filename != "resource://gre/modules/AppConstants.jsm")
            return freeze(obj);
        obj.MOZ_REQUIRE_SIGNING = false;
        obj.MOZ_ALLOW_LEGACY_EXTENSIONS = true;
        return (o.freeze = freeze)(obj);
    }
    lockPref("extensions.legacy.enabled", true);
    lockPref("xpinstall.signatures.required", false);
    lockPref("extensions.langpacks.signatures.required", false);

    nsvo = Cu.import("resource://gre/modules/addons/XPIInstall.jsm", {});
    var shouldVerify = nsvo.shouldVerifySignedState;
    nsvo.shouldVerifySignedState = addon => !addon.id && shouldVerify(addon);
    
})(Cu.import("resource://gre/modules/WebRequestCommon.jsm", {}));}
catch(ex) {Cu.reportError(ex);}

//
try {({
    ids: [
        "custombuttons@xsms.org",
    ],
    init(xrt) {
        if (xrt.inSafeMode) return;
        Cu.import("resource://gre/modules/addons/XPIProvider.jsm", this);
        var load = async file => {
            var rootURI = this.XPIInternal.getURIForResourceInFile(file, "");
            Cu.import(rootURI.resolve("startup.jsm"), {}).start(rootURI);
        }
        var proto = this.XPIInternal.BootstrapScope.prototype;
        var func = proto._beforeCallBootstrapMethod;

        proto._beforeCallBootstrapMethod = () => {
            proto._beforeCallBootstrapMethod = func;
            for(var addon of this.XPIInternal.XPIStates.enabledAddons())
                this.ids.includes(addon.id) && !addon.loader && load(addon.file);
        }
    }
}).init(Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime));}
catch(ex) {Cu.reportError(ex);}


custom_buttons-0.0.7.0.0.3-fx-bootstrap.xpi
bootstrap-loader.js

Выделить код

Код:

//
try {
    Cu.createDocumentEncoder && Cc["@mozilla.org/moz/jssubscript-loader;1"]
        .getService(Ci.mozIJSSubScriptLoader).loadSubScript(String.raw`
            data:,var {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");%0Avar {AddonManager} = ChromeUtils.import("resource://gre/modules/AddonManager.jsm");%0A%0Athis.lazyModules = {%0A%09OS: "resource://gre/modules/osfile.jsm",%0A%09Services: "resource://gre/modules/Services.jsm",%0A%09ConsoleAPI: "resource://gre/modules/Console.jsm",%0A%09Blocklist: "resource://gre/modules/Blocklist.jsm",%0A%09AddonInternal: "resource://gre/modules/addons/XPIDatabase.jsm"%0A};%0Aif ("@mozilla.org/intl/domlocalization;1" in Cc)%0A%09this.lazyModules.RDFDataSource = "resource://gre/modules/addons/RDFDataSource.jsm";%0Aelse%0A%09// Firefox 67+%0A%09// Bug 1523194 - Remove XPIDL for DOMLocalization and use do_ImportModule instead%0A%09// https://bugzilla.mozilla.org/show_bug.cgi?id=1523194%0A%09//%0A%09// Bug 857458 - Remove support for update.rdf%0A%09// https://bugzilla.mozilla.org/show_bug.cgi?id=857458%0A%0A%09XPCOMUtils.defineLazyGetter(this, "RDFDataSource", () => {%0A%09%09var obs = {};%0A%09%09var scs = Cc["@mozilla.org/streamConverters;1"].getService(Ci.nsIStreamConverterService);%0A%09%09var sis = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream);%0A%09%09var sl =  Cc["@mozilla.org/network/stream-loader;1"].createInstance(Ci.nsIStreamLoader);%0A%0A%09%09var gzip = "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";%0A%09%09sis.data = atob(gzip);%0A%09%09obs.onStreamComplete = (a, b, c, d, result) => Cu.evalInSandbox(String.fromCharCode(...result), this);%0A%09%09sl.init(obs);%0A%09%09var converter = scs.asyncConvertData("gzip", "uncompressed", sl, null);%0A%09%09converter.onStartRequest(null, null);%0A%0A%09%09var args = [null, null, sis, 0, sis.data.length];%0A%09%09// Bug 1525319 - Investigate if we can remove Context argument from Channel methods (Firefox 67+)%0A%09%09// https://bugzilla.mozilla.org/show_bug.cgi?id=1525319%0A%09%09if (converter.onDataAvailable.length == 4) args.shift();%0A%09%09converter.onDataAvailable(...args);%0A%0A%09%09converter.onStopRequest(null, null, null);%0A%0A%09%09return RDFDataSource;%0A%09});%0AXPCOMUtils.defineLazyModuleGetters(this, this.lazyModules);%0Adelete this.lazyModules;%0A%0AXPCOMUtils.defineLazyGetter(this, "BOOTSTRAP_REASONS", () =>%0A%09ChromeUtils.import("resource://gre/modules/addons/XPIProvider.jsm", {})%0A%09%09.XPIProvider.BOOTSTRAP_REASONS%0A);%0AXPCOMUtils.defineLazyGetter(this, "logger", () =>%0A%09ChromeUtils.import("resource://gre/modules/Log.jsm", {})%0A%09%09.Log.repository.getLogger("addons.bootstrap")%0A);%0A%0A%0A// RDFManifestConverter.jsm%0Aconst RDFURI_INSTALL_MANIFEST_ROOT = "urn:mozilla:install-manifest";%0A%0Afunction EM_R(aProperty) {%0A%09return %60http://www.mozilla.org/2004/em-rdf%23%24{aProperty}%60;%0A}%0Afunction getValue(literal) {%0A%09return literal && literal.getValue();%0A}%0Afunction getProperty(resource, property) {%0A%09return getValue(resource.getProperty(EM_R(property)));%0A}%0A%0Aclass Manifest {%0A%09constructor(ds) {%0A%09%09this.ds = ds;%0A%09}%0A%09static loadFromString(text) {%0A%09%09return new this(RDFDataSource.loadFromString(text));%0A%09}%0A%09static loadFromBuffer(buffer) {%0A%09%09return new this(RDFDataSource.loadFromBuffer(buffer));%0A%09}%0A%09static async loadFromFile(uri) {%0A%09%09return new this(await RDFDataSource.loadFromFile(uri));%0A%09}%0A}%0A%0Aclass InstallRDF extends Manifest {%0A%09_readProps(source, obj, props) {%0A%09%09for (let prop of props) {%0A%09%09%09let val = getProperty(source, prop);%0A%09%09%09if (val != null) {%0A%09%09%09%09obj[prop] = val;%0A%09%09%09}%0A%09%09}%0A%09}%0A%09_readArrayProp(source, obj, prop, target, decode = getValue) {%0A%09%09let result = Array.from(%0A%09%09%09source.getObjects(EM_R(prop)), target => decode(target)%0A%09%09);%0A%09%09if (result.length) {%0A%09%09%09obj[target] = result;%0A%09%09}%0A%09}%0A%09_readArrayProps(source, obj, props, decode = getValue) {%0A%09%09for (let [prop, target] of Object.entries(props)) {%0A%09%09%09this._readArrayProp(source, obj, prop, target, decode);%0A%09%09}%0A%09}%0A%09_readLocaleStrings(source, obj) {%0A%09%09this._readProps(source, obj, ["name", "description", "creator", "homepageURL"]);%0A%09%09this._readArrayProps(source, obj, {%0A%09%09%09locale: "locales",%0A%09%09%09developer: "developers",%0A%09%09%09translator: "translators",%0A%09%09%09contributor: "contributors",%0A%09%09});%0A%09}%0A%09decode() {%0A%09%09let root = this.ds.getResource(RDFURI_INSTALL_MANIFEST_ROOT);%0A%09%09let result = {};%0A%0A%09%09let props = [%0A%09%09%09"id", "version", "type", "updateURL", "optionsURL",%0A%09%09%09"optionsType", "aboutURL", "iconURL",%0A%09%09%09"bootstrap", "unpack", "strictCompatibility"%0A%09%09];%0A%09%09this._readProps(root, result, props);%0A%0A%09%09let decodeTargetApplication = source => {%0A%09%09%09let app = {maxVersion: "*"};%0A%09%09%09this._readProps(source, app, ["id", "minVersion"]);%0A%09%09%09return app;%0A%09%09};%0A%0A%09%09let decodeLocale = source => {%0A%09%09%09let localized = {};%0A%09%09%09this._readLocaleStrings(source, localized);%0A%09%09%09return localized;%0A%09%09};%0A%0A%09%09this._readLocaleStrings(root, result);%0A%0A%09%09this._readArrayProps(%0A%09%09%09root, result, {"targetPlatform": "targetPlatforms"}%0A%09%09);%0A%09%09this._readArrayProps(%0A%09%09%09root, result, {"targetApplication": "targetApplications"}, decodeTargetApplication%0A%09%09);%0A%09%09this._readArrayProps(%0A%09%09%09root, result, {"localized": "localized"}, decodeLocale%0A%09%09);%0A%09%09this._readArrayProps(%0A%09%09%09root, result, {"dependency": "dependencies"}, source => getProperty(source, "id")%0A%09%09);%0A%09%09return result;%0A%09}%0A}%0A// fim RDFManifestConverter.jsm%0A%0A%0A// BootstrapLoader.jsm%0A/**%0A * Valid IDs fit this pattern.%0A */%0Avar gIDTest = /^(\{[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\}|[a-z0-9-\._]*\@[a-z0-9-\._]+)$/i;%0A%0A// Properties that exist in the install manifest%0Aconst PROP_METADATA%09= [%0A%09"id", "version", "type", "internalName", "updateURL",%0A%09"optionsURL", "optionsType", "aboutURL", "iconURL"%0A];%0Aconst PROP_LOCALE_SINGLE = ["name", "description", "creator", "homepageURL"];%0Aconst PROP_LOCALE_MULTI%09= ["developers", "translators", "contributors"];%0A%0A// Map new string type identifiers to old style nsIUpdateItem types.%0A// Retired values:%0A// 32 = multipackage xpi file%0A// 8 = locale%0A// 256 = apiextension%0A// 128 = experiment%0A// theme = 4%0Aconst TYPES = {%0A%09extension: 2,%0A%09dictionary: 64,%0A};%0A%0Aconst COMPATIBLE_BY_DEFAULT_TYPES = {%0A%09extension: true,%0A%09dictionary: true,%0A};%0A%0Aconst hasOwnProperty = Function.call.bind(Object.prototype.hasOwnProperty);%0A%0Afunction isXPI(filename) {%0A%09let ext = filename.slice(-4).toLowerCase();%0A%09return ext === ".xpi" || ext === ".zip";%0A}%0A%0A/**%0A * Gets an nsIURI for a file within another file, either a directory or an XPI%0A * file. If aFile is a directory then this will return a file: URI, if it is an%0A * XPI file then it will return a jar: URI.%0A *%0A * @param {nsIFile} aFile%0A *%09%09The file containing the resources, must be either a directory or an XPI file%0A *%0A * @param {string} aPath%0A *%09%09The path to find the resource at, "/" separated. If aPath is empty%0A *%09%09then the uri to the root of the contained files will be returned%0A *%0A * @returns {nsIURI}%0A *%09%09An nsIURI pointing at the resource%0A */%0Afunction getURIForResourceInFile(aFile, aPath) {%0A%09if (!isXPI(aFile.leafName)) {%0A%09%09let resource = aFile.clone();%0A%09%09if (aPath)%0A%09%09%09aPath.split("/").forEach(part => resource.append(part));%0A%0A%09%09return Services.io.newFileURI(resource);%0A%09}%0A%09return buildJarURI(aFile, aPath);%0A}%0A%0A/**%0A * Creates a jar: URI for a file inside a ZIP file.%0A *%0A * @param {nsIFile} aJarfile%0A *%09%09The ZIP file as an nsIFile%0A *%0A * @param {string} aPath%0A *%09%09The path inside the ZIP file%0A *%0A * @returns {nsIURI}%0A *%09%09An nsIURI for the file%0A */%0Afunction buildJarURI(aJarfile, aPath) {%0A%09let uri = Services.io.newFileURI(aJarfile);%0A%09uri = "jar:" + uri.spec + "!/" + aPath;%0A%09return Services.io.newURI(uri);%0A}%0A%0Avar BootstrapLoader = {%0A%09name: "bootstrap",%0A%09manifestFile: "install.rdf",%0A%09async loadManifest(pkg) {%0A%09%09/**%0A%09%09 * Reads locale properties from either the main install manifest root%0A%09%09 * or an em:localized section in the install manifest.%0A%09%09 *%0A%09%09 * @param {Object} aSource%0A%09%09 *%09%09The resource to read the properties from.%0A%09%09 *%0A%09%09 * @param {boolean} isDefault%0A%09%09 *%09%09True if the locale is to be read from the main install manifest root%0A%09%09 *%0A%09%09 * @param {string[]} aSeenLocales%0A%09%09 *%09%09An array of locale names already seen for this install manifest.%0A%09%09 *%09%09Any locale names seen as a part of this function will be added to this array%0A%09%09 *%0A%09%09 * @returns {Object}%0A%09%09 *%09%09An object containing the locale properties%0A%09%09 */%0A%09%09function readLocale(aSource, isDefault, aSeenLocales) {%0A%09%09%09let locale = {};%0A%09%09%09if (!isDefault) {%0A%09%09%09%09locale.locales = [];%0A%09%09%09%09for (let localeName of aSource.locales || []) {%0A%09%09%09%09%09if (!localeName) {%0A%09%09%09%09%09%09logger.warn("Ignoring empty locale in localized properties");%0A%09%09%09%09%09%09continue;%0A%09%09%09%09%09}%0A%09%09%09%09%09if (aSeenLocales.includes(localeName)) {%0A%09%09%09%09%09%09logger.warn("Ignoring duplicate locale in localized properties");%0A%09%09%09%09%09%09continue;%0A%09%09%09%09%09}%0A%09%09%09%09%09aSeenLocales.push(localeName);%0A%09%09%09%09%09locale.locales.push(localeName);%0A%09%09%09%09}%0A%0A%09%09%09%09if (locale.locales.length == 0) {%0A%09%09%09%09%09logger.warn("Ignoring localized properties with no listed locales");%0A%09%09%09%09%09return null;%0A%09%09%09%09}%0A%09%09%09}%0A%09%09%09for (let prop of [...PROP_LOCALE_SINGLE, ...PROP_LOCALE_MULTI]) {%0A%09%09%09%09if (hasOwnProperty(aSource, prop)) {%0A%09%09%09%09%09locale[prop] = aSource[prop];%0A%09%09%09%09}%0A%09%09%09}%0A%09%09%09return locale;%0A%09%09}%0A%0A%09%09let manifestData = await pkg.readString("install.rdf");%0A%09%09let manifest = InstallRDF.loadFromString(manifestData).decode();%0A%0A%09%09let addon = new AddonInternal();%0A%09%09for (let prop of PROP_METADATA) {%0A%09%09%09if (hasOwnProperty(manifest, prop)) {%0A%09%09%09%09addon[prop] = manifest[prop];%0A%09%09%09}%0A%09%09}%0A%09%09if (!addon.type) {%0A%09%09%09addon.type = "extension";%0A%09%09} else {%0A%09%09%09let type = addon.type;%0A%09%09%09addon.type = null;%0A%09%09%09for (let name in TYPES) {%0A%09%09%09%09if (TYPES[name] == type) {%0A%09%09%09%09%09addon.type = name;%0A%09%09%09%09%09break;%0A%09%09%09%09}%0A%09%09%09}%0A%09%09}%0A%09%09if (!(addon.type in TYPES))%0A%09%09%09throw new Error("Install manifest specifies unknown type: " + addon.type);%0A%0A%09%09if (!addon.id)%0A%09%09%09throw new Error("No ID in install manifest");%0A%09%09if (!gIDTest.test(addon.id))%0A%09%09%09throw new Error("Illegal add-on ID " + addon.id);%0A%09%09if (!addon.version)%0A%09%09%09throw new Error("No version in install manifest");%0A%0A%09%09addon.strictCompatibility =%0A%09%09%09!(addon.type in COMPATIBLE_BY_DEFAULT_TYPES) ||%0A%09%09%09"strictCompatibility" in manifest && manifest.strictCompatibility == "true";%0A%0A%09%09// Only read these properties for extensions.%0A%09%09if (addon.type == "extension") {%0A%09%09%09if (manifest.bootstrap != "true") {%0A%09%09%09%09throw new Error("Non-restartless extensions no longer supported");%0A%09%09%09}%0A%09%09%09if (%0A%09%09%09%09addon.optionsType &&%0A%09%09%09%09addon.optionsType != AddonManager.OPTIONS_TYPE_INLINE_BROWSER &&%0A%09%09%09%09addon.optionsType != AddonManager.OPTIONS_TYPE_TAB%0A%09%09%09) {%0A%09%09%09%09throw new Error("Install manifest specifies unknown optionsType: " + addon.optionsType);%0A%09%09%09}%0A%09%09} else {%0A%09%09%09// Convert legacy dictionaries into a format the WebExtension%0A%09%09%09// dictionary loader can process.%0A%09%09%09if (addon.type === "dictionary") {%0A%09%09%09%09addon.loader = null;%0A%09%09%09%09let dictionaries = {};%0A%09%09%09%09await pkg.iterFiles(({path}) => {%0A%09%09%09%09%09let match = /^dictionaries\/([^\/]+)\.dic$/.exec(path);%0A%09%09%09%09%09if (match) {%0A%09%09%09%09%09%09let lang = match[1].replace(/_/g, "-");%0A%09%09%09%09%09%09dictionaries[lang] = match[0];%0A%09%09%09%09%09}%0A%09%09%09%09});%0A%09%09%09%09addon.startupData = {dictionaries};%0A%09%09%09}%0A%0A%09%09%09// Only extensions are allowed to provide an optionsURL, optionsType,%0A%09%09%09// optionsBrowserStyle, or aboutURL. For all other types they are silently ignored%0A%09%09%09addon.aboutURL = null;%0A%09%09%09addon.optionsBrowserStyle = null;%0A%09%09%09addon.optionsType = null;%0A%09%09%09addon.optionsURL = null;%0A%09%09}%0A%0A%09%09addon.defaultLocale = readLocale(manifest, true);%0A%09%09let defaultLocaleEntries = Object.entries(addon.defaultLocale);%0A%0A%09%09let seenLocales = [];%0A%09%09addon.locales = [];%0A%09%09for (let localeData of manifest.localized || []) {%0A%09%09%09let locale = readLocale(localeData, false, seenLocales);%0A%09%09%09if (locale) {%0A%09%09%09%09for(let [key, val] of defaultLocaleEntries)%0A%09%09%09%09%09key in locale || Reflect.set(locale, key, val);%0A%09%09%09%09addon.locales.push(locale);%0A%09%09%09}%0A%09%09}%0A%0A%09%09addon.dependencies = Object.freeze(%0A%09%09%09"dependencies" in manifest ? Array.from(new Set(manifest.dependencies)) : []%0A%09%09);%0A%0A%09%09let seenApplications = [];%0A%09%09addon.targetApplications = [];%0A%09%09for (let targetApp of manifest.targetApplications || []) {%0A%09%09%09if (!targetApp.id || !targetApp.minVersion || !targetApp.maxVersion) {%0A%09%09%09%09logger.warn("Ignoring invalid targetApplication entry in install manifest");%0A%09%09%09%09continue;%0A%09%09%09}%0A%09%09%09if (seenApplications.includes(targetApp.id)) {%0A%09%09%09%09logger.warn(%0A%09%09%09%09%09"Ignoring duplicate targetApplication entry for " + targetApp.id + " in install manifest"%0A%09%09%09%09);%0A%09%09%09%09continue;%0A%09%09%09}%0A%09%09%09seenApplications.push(targetApp.id);%0A%09%09%09addon.targetApplications.push(targetApp);%0A%09%09}%0A%0A%09%09// Note that we don't need to check for duplicate targetPlatform entries since%0A%09%09// the RDF service coalesces them for us.%0A%09%09addon.targetPlatforms = [];%0A%09%09for (let targetPlatform of manifest.targetPlatforms || []) {%0A%09%09%09let platform = {%0A%09%09%09%09os: null,%0A%09%09%09%09abi: null,%0A%09%09%09};%0A%0A%09%09%09let pos = targetPlatform.indexOf("_");%0A%09%09%09if (pos != -1) {%0A%09%09%09%09platform.os = targetPlatform.substring(0, pos);%0A%09%09%09%09platform.abi = targetPlatform.substring(pos + 1);%0A%09%09%09} else {%0A%09%09%09%09platform.os = targetPlatform;%0A%09%09%09}%0A%09%09%09addon.targetPlatforms.push(platform);%0A%09%09}%0A%0A%09%09addon.userDisabled = false;%0A%09%09addon.softDisabled = addon.blocklistState == Blocklist.STATE_SOFTBLOCKED;%0A%09%09addon.applyBackgroundUpdates = AddonManager.AUTOUPDATE_DEFAULT;%0A%0A%09%09addon.userPermissions = null;%0A%0A%09%09addon.icons = {};%0A%09%09if (await pkg.hasResource("icon.png")) {%0A%09%09%09addon.icons[32] = "icon.png";%0A%09%09%09addon.icons[48] = "icon.png";%0A%09%09}%0A%0A%09%09if (await pkg.hasResource("icon64.png")) {%0A%09%09%09addon.icons[64] = "icon64.png";%0A%09%09}%0A%0A%09%09return addon;%0A%09},%0A%0A%09// Bug 1512436 - Add new install location for built in search web extensions (Firefox 67+)%0A%09// https://bugzilla.mozilla.org/show_bug.cgi?id=1512436%0A%09// https://hg.mozilla.org/mozilla-central/diff/e3e75697e98c/toolkit/mozapps/extensions/internal/XPIProvider.jsm%23l1.396%0A%09//loadScope(addon, file) {%0A%09loadScope(addon, file = addon.file || addon._sourceBundle) {%0A%0A%09%09let uri = getURIForResourceInFile(file, "bootstrap.js").spec;%0A%09%09let principal = Services.scriptSecurityManager.getSystemPrincipal();%0A%0A%09%09let sandbox = new Cu.Sandbox(principal, {%0A%09%09%09sandboxName: uri,%0A%09%09%09addonId: addon.id,%0A%09%09%09wantGlobalProperties: ["ChromeUtils"],%0A%09%09%09metadata: { addonID: addon.id, URI: uri },%0A%09%09});%0A%0A%09%09try {%0A%09%09%09Object.assign(sandbox, BOOTSTRAP_REASONS);%0A%0A%09%09%09XPCOMUtils.defineLazyGetter(%0A%09%09%09%09sandbox, "console", () => new ConsoleAPI({ consoleID: %60addon/%24{addon.id}%60 })%0A%09%09%09);%0A%09%09%09Services.scriptloader.loadSubScript(uri, sandbox);%0A%0A%09%09} catch (e) {%0A%09%09%09logger.warn(%60Error loading bootstrap.js for %24{addon.id}%60, e);%0A%09%09}%0A%0A%09%09function findMethod(name) {%0A%09%09%09if (sandbox.name) {%0A%09%09%09%09return sandbox.name;%0A%09%09%09}%0A%09%09%09try {%0A%09%09%09%09let method = Cu.evalInSandbox(name, sandbox);%0A%09%09%09%09return method;%0A%09%09%09} catch (err) { }%0A%0A%09%09%09return () => {%0A%09%09%09%09logger.warn(%60Add-on %24{addon.id} is missing bootstrap method %24{name}%60);%0A%09%09%09};%0A%09%09}%0A%0A%09%09let install = findMethod("install");%0A%09%09let uninstall = findMethod("uninstall");%0A%09%09let startup = findMethod("startup");%0A%09%09let shutdown = findMethod("shutdown");%0A%0A%09%09return {%0A%09%09%09install: (...args) => install(...args),%0A%09%09%09uninstall: (...args) => uninstall(...args),%0A%0A%09%09%09startup(...args) {%0A%09%09%09%09if (addon.type == "extension") {%0A%09%09%09%09%09logger.debug(%60Registering manifest for %24{file.path}\n%60);%0A%09%09%09%09%09Components.manager.addBootstrappedManifestLocation(file);%0A%09%09%09%09}%0A%09%09%09%09return startup(...args);%0A%09%09%09},%0A%0A%09%09%09shutdown(data, reason) {%0A%09%09%09%09try {%0A%09%09%09%09%09return shutdown(data, reason);%0A%09%09%09%09} catch (err) {%0A%09%09%09%09%09throw err;%0A%09%09%09%09} finally {%0A%09%09%09%09%09if (reason != BOOTSTRAP_REASONS.APP_SHUTDOWN) {%0A%09%09%09%09%09%09logger.debug(%60Removing manifest for %24{file.path}\n%60);%0A%09%09%09%09%09%09Components.manager.removeBootstrappedManifestLocation(file);%0A%09%09%09%09%09}%0A%09%09%09%09}%0A%09%09%09},%0A%09%09};%0A%09},%0A};%0A// fim BootstrapLoader.jsm%0A%0A%0AAddonManager.addExternalExtensionLoader(BootstrapLoader);%0AObject.defineProperty(%0A%09AddonInternal.prototype,%0A%09"providesUpdatesSecurely",%0A%09{enumerable: true, value: true}%0A);%0A
        `.trim(), new Cu.Sandbox(Cu.getObjectPrincipal(this), {wantGlobalProperties: ["ChromeUtils", "atob"]}));
} catch(ex) {Cu.reportError(ex);}


В bootstrap-loader'е, код выброшенного RDFDataSource.jsm,
чтобы занимал меньше места, разместил как base64 gzip,
извиняюсь за образовавшуюся человеконечитаемость.

Отсутствует

 

Board footer

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