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

Список ответов на каверзные вопросы можно получить в FAQ-разделе форума.

№10124-01-2020 20:48:58

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

Re: [CB]Attributes Inspector (для разработчиков)

Какой-то обложенный распорками Check for Addons Updates:
https://github.com/Infocatcher/Custom_B … Updates.js (изменения)


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

Отсутствует

 

№10224-01-2020 22:05:56

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

Re: [CB]Attributes Inspector (для разработчиков)

Infocatcher пишет

Check for Addons Updates

А почему в этой теме, а не в [CB]Check for Addons Updates | Форум Mozilla Россия ?

Отсутствует

 

№10324-01-2020 22:09:24

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

Re: [CB]Attributes Inspector (для разработчиков)

voqabuhe
Хм, да, там будет уместнее. Просто изначальный вопрос оказался в этой теме.


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

Отсутствует

 

№10420-03-2020 23:30:52

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

Re: [CB]Attributes Inspector (для разработчиков)

Infocatcher что то я не нашел тему про "Edit_Custom_Button_in_Tab" у меня на 74 она до сих пор работает. Поэтому задам здесь. Если есть отдельная тема - то покажите. Вопрос в следующем. Код работает нормально, но выскивает ошибка в консоли не на что не влияющая -
[Exception... "Component returned failure code: 0x805e0006 [nsIWebNavigation.loadURI]"  nsresult: "0x805e0006 (<unknown>)"  location: "JS frame :: chrome://browser/content/browser.js :: _loadURI :: line 1513"  data: no]  - browser.js:1513:29 при редактировании во вкладке. Может посмотрите? Сейчас код у меня такой

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

Выделить код

Код:

// http://infocatcher.ucoz.net/js/cb/editCustomButtonInTab.js
// https://github.com/Infocatcher/Custom_Buttons/tree/master/Edit_Custom_Button_in_Tab

// Edit Custom Button in Tab button for Custom Buttons
// (code for "initialization" section)

// (c) Infocatcher 2012-2014
// version 0.1.8.3 - 2014-01-12

// Note:
// In Firefox 3.6 and older:
// - Force enables "Save size and position of editor windows separately for each custom button"
//   option for editor in tab (because doesn't work without this)
// - tab with editor can't be closed sometimes using OK/Cancel buttons

var editInTabLabel = (function() {
    var locale = (function() {
        if("Services" in window && "locale" in Services) {
            var locales = Services.locale.requestedLocales // Firefox 64+
                || Services.locale.getRequestedLocales && Services.locale.getRequestedLocales();
            if(locales)
                return locales[0];
        }
        var prefs = "Services" in window && Services.prefs
            || Components.classes["@mozilla.org/preferences-service;1"]
                .getService(Components.interfaces.nsIPrefBranch);
        function pref(name, type) {
            return prefs.getPrefType(name) != prefs.PREF_INVALID ? prefs["get" + type + "Pref"](name) : undefined;
        }
        if(!pref("intl.locale.matchOS", "Bool")) { // Also see https://bugzilla.mozilla.org/show_bug.cgi?id=1414390
            var locale = pref("general.useragent.locale", "Char");
            if(locale && locale.substr(0, 9) != "chrome://")
                return locale;
        }
        return Components.classes["@mozilla.org/chrome/chrome-registry;1"]
            .getService(Components.interfaces.nsIXULChromeRegistry)
            .getSelectedLocale("global");
    })().match(/^[a-z]*/)[0];
    if(locale == "ru")
        return "Редактировать во вкладке…";
    return "Edit button in tab…";
})();

const editorBaseUri = "chrome://custombuttons/content/editor.xul";
const cbIdTabAttr = "custombuttons-editInTab-id";

const editId = "custombuttons-contextpopup-edit";
const editInTabId = editId + "InTab";
var editInTab = document.getElementById(editInTabId);
if(editInTab)
    editInTab.parentNode.removeChild(editInTab);
var editItem = document.getElementById(editId);
editInTab = editItem.cloneNode(true);
editInTab.id = editInTabId;
editInTab.setAttribute("cb_id", editInTabId);
editInTab.setAttribute("label", editInTabLabel);
editInTab.setAttribute("oncommand", "editCustomButtonInTab();");
if(!Object.create) // Firefox 3.6 and older
    editInTab.removeAttribute("observes");
editInTab.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAitJREFUeNrEk0tIVVEUhr99zrnHc1+SkYQVFWo20G6SgkFRDorEILFJDoogkoLoXfOopEZCYIFlIITlRIUiC5UmFZVk1igwCAozfD9uat17z97tc5XK0pGDFiz289/rXz//FkopFhMGiwyr5GoHHgkpZUnCde9LqXwwHyuR3HVNIzZpGrubbLtjfHwYyzvywIYpHp0o386ajAAD3/R1MRfugZeFoGcgbm9pedo+7VVVCMvTwKt8tGwrfXGb5mfRJFj8VV0Ki7hpk9t5gW35lYx9GcSZGFOGSjJQvuXpYd4PTLPUYU6m+Q1SgzbBkEPey0tUHjlJfU8j0c8j+Aa/ahFn2x2cdknVgLBfpx5DyTQIBGx8+oHjras4vX8DtfWNFG0q4gmPyas9VqgZqEbNAEvPUnW1sCMI+QVBPXc02Ar5ONiURW55NsHus1TkjNDW2srHdYcormo/Z2kG+0p35BPTfaaHrVnBBAmt75QwKK3LYuPetdDbDxMTdHc2ELn4gfWj32l+MFQhdla1KVdKpCvxBPXAcWUSlQEaYgeIlK2GvmENHuHOmxVcW3mLoDuqn09gGjNiF8xnEPWw+DUFpTA0BS+uc/tdDodrnhf+445dV9p/LaQw+SH8nBfVRBMpKi0zm5LIEupq7lF541Vhy6lIV3XGTRw5qdWXM078bRSBK3zs6b3MWxEgplxSPnWS2e8kwXfPbO4SanIefy4cf7bWtdAl8d9/408BBgBVmNFVzOyEfgAAAABJRU5ErkJggg==");
editItem.parentNode.insertBefore(editInTab, editItem.nextSibling);

Array.prototype.filter.call( // Process already cloned menu items
    document.getElementsByAttribute("observes", editItem.getAttribute("observes")),
    function(mi) {
        var id = mi.id || "";
        return mi != editItem
            && id.substr(0, editId.length) == editId
            && id.substr(0, editInTabId.length) != editInTabId;
    }
).forEach(function(editItem, i) {
    var clone = editInTab.cloneNode(true);
    clone.id += "-cloned-" + i;
    editItem.parentNode.insertBefore(clone, editItem.nextSibling);
});

// Process #custombuttons-contextpopup-sub
const editIdSub = editId + "-sub";
var editItemSub = document.getElementById(editIdSub);
if(editItemSub) {
    var clone = editInTab.cloneNode(true);
    if(editItemSub.hasAttribute("observes"))
        clone.setAttribute("observes", editItemSub.getAttribute("observes"));
    else
        clone.removeAttribute("observes");
    clone.id += "-sub";
    editItemSub.parentNode.insertBefore(clone, editItemSub.nextSibling);
}

window.editCustomButtonInTab = function(btn, newTab) { // Should be global to work in cloned menus
    if(!btn)
        btn = custombuttons.popupNode;
    if(!btn)
        return;
    var btnId = btn.id;
    var link = custombuttons.makeButtonLink("edit", btnId);
    var cbService = "cbICustomButtonsService" in Components.interfaces
        ? Components.classes["@xsms.nm.ru/custombuttons/cbservice;1"]
            .getService(Components.interfaces.cbICustomButtonsService)
        : Components.classes["@xsms.nm.ru/custombuttons/cbservice;1"] // Custom Buttons 0.0.5.9+
            .getService(Components.interfaces.nsISupports)
            .wrappedJSObject;
    var param = cbService.getButtonParameters(link);
    var editorUriFull = editorBaseUri
        + "?window=" + cbService.getWindowId(document.documentURI)
        + "&id=" + btnId;
    var editorUri = cbService.mode & 64 /*CB_MODE_SAVE_EDITOR_SIZE_SEPARATELY*/
        || !Object.create // Firefox 3.6 and older
        ? editorUriFull
        : editorBaseUri;

    // Search for already opened tab
    var rawParam = unwrap(param);
    var isSeaMonkey = "Services" in window && Services.appinfo.name == "SeaMonkey";
    var ws = Components.classes["@mozilla.org/appshell/window-mediator;1"]
        .getService(Components.interfaces.nsIWindowMediator)
        .getEnumerator(isSeaMonkey ? null : "navigator:browser");
    while(ws.hasMoreElements()) {
        let win = ws.getNext();
        if(isSeaMonkey && win.location.href != "chrome://navigator/content/navigator.xul")
            continue;
        let gBrowser = win.gBrowser;
        let tabs = gBrowser.tabs || gBrowser.tabContainer.childNodes;
        for(let i = 0, l = tabs.length; i < l; ++i) {
            let tab = tabs[i];
            if(tab == newTab)
                continue;
            let browser = tab.linkedBrowser;
            if(!browser)
                continue;
            let loc = browser.currentURI.spec;
            if(loc.substr(0, editorBaseUriLength) != editorBaseUri)
                continue;
            let isSameEditor = loc == editorUriFull
                || tab.getAttribute(cbIdTabAttr) == btnId;
            let win = browser.contentWindow; // Will be null for unloaded tab
            if(!isSameEditor && win) {
                let rawWin = unwrap(win);
                let winParam = "arguments" in rawWin && rawWin.arguments.length
                    ? unwrap(rawWin.arguments[0])
                    : rawWin.editor && rawWin.editor.param;
                isSameEditor = winParam && winParam.buttonLink == link;
            }
            if(isSameEditor) {
                gBrowser.selectedTab = tab;
                win && win.focus();
                newTab && setTimeout(function() {
                    gBrowser.removeTab(newTab);
                }, 0);
                return;
            }
        }
    }

    // Or open new tab
    var tab = newTab;
    if(!tab) {
        tab = gBrowser.selectedTab = gBrowser.addTab(editorUri, {
            triggeringPrincipal: "Services" in window // Firefox 63+
                && Services.scriptSecurityManager
                && Services.scriptSecurityManager.getSystemPrincipal()
        });
        initSessionStore();
        tab.setAttribute(cbIdTabAttr, btn.id);
    }

    var browser = tab.linkedBrowser;
    browser.addEventListener("DOMContentLoaded", function load(e) {
        var doc = e.target;
        if(doc.location != editorUri)
            return;
        browser.removeEventListener(e.type, load, false);

        var win = doc.defaultView;
        win.arguments = [param];

        var iconLink = doc.createElementNS("http://www.w3.org/1999/xhtml", "link");
        iconLink.rel = "shortcut icon";
        //iconLink.href = "chrome://custombuttons-context/content/icons/default/custombuttonsEditor.ico";
        iconLink.href = getStdImage(rawParam.image);
        iconLink.style.display = "none";
        doc.documentElement.insertBefore(iconLink, doc.documentElement.firstChild);

        var alreadyAsked = false;
        function checkUnsaved(e) {
            if(alreadyAsked)
                return;
            var dlg = unwrap(doc).documentElement;
            if(
                "_fireButtonEvent" in dlg
                    ? !dlg._fireButtonEvent("cancel")
                    : !dlg.cancelDialog()
            )
                e.preventDefault();
        }
        function onDialogCancel(e) {
            alreadyAsked = true;
            // win.setTimeout shouldn't fire while confirmation dialog from the same window are opened
            win.setTimeout(function() {
                alreadyAsked = false;
            }, 100);
        }
        function destroy(e) {
            win.removeEventListener("dialogcancel", onDialogCancel, false);
            win.removeEventListener("beforeunload", checkUnsaved, false);
            win.removeEventListener("unload", destroy, false);
        }
        win.addEventListener("dialogcancel", onDialogCancel, false);
        win.addEventListener("beforeunload", checkUnsaved, false);
        win.addEventListener("unload", destroy, false);
    }, false);
};
function unwrap(o) {
    return o.wrappedJSObject || o; // Firefox 3.6 and older
}
function getStdImage(iid) {
    if(/^custombuttons-stdicon-(\d)$/.test(iid)) switch(+RegExp.$1) {
        // chrome://custombuttons/skin/custombuttons.css
        // toolbarbutton[cb-stdicon="custombuttons-stdicon-*"] { ... }
        case 1: return "chrome://custombuttons/skin/button.png";
        case 2: return "chrome://custombuttons/skin/stdicons/rbutton.png";
        case 3: return "chrome://custombuttons/skin/stdicons/gbutton.png";
        case 4: return "chrome://custombuttons/skin/stdicons/bbutton.png";
    }
    return iid || "chrome://custombuttons/skin/button.png";
}

function initSessionStore() {
    initSessionStore = function() {};
    var ss = "nsISessionStore" in Components.interfaces
        ? (
            Components.classes["@mozilla.org/browser/sessionstore;1"]
            || Components.classes["@mozilla.org/suite/sessionstore;1"]
        ).getService(Components.interfaces.nsISessionStore)
        : SessionStore; // Firefox 61+ https://bugzilla.mozilla.org/show_bug.cgi?id=1450559
    ss.persistTabAttribute(cbIdTabAttr);
}
function checkTab(tab) {
    var cbId = tab.getAttribute(cbIdTabAttr);
    if(!cbId)
        return;
    initSessionStore();
    let btn = document.getElementById(cbId);
    if(btn)
        editCustomButtonInTab(btn, tab);
}
const editorBaseUriLength = editorBaseUri.length;
// We can't use only SSTabRestoring: user can reload tab with editor
addEventListener("DOMContentLoaded", function(e) {
    var doc = e.target;
    if(doc.location.href.substr(0, editorBaseUriLength) != editorBaseUri)
        return;
    var tabs = gBrowser.tabs || gBrowser.tabContainer.childNodes;
    for(var i = 0, l = tabs.length; i < l; ++i) {
        let tab = tabs[i];
        let browser = tab.linkedBrowser;
        if(browser && browser.contentDocument == doc) {
            checkTab(tab);
            break;
        }
    }
}, true, document.getElementById("appcontent")); // Firefox 60+, gBrowser isn't a DOM node anymore 
checkTab(gBrowser.selectedTab);

function destructor(reason) {
    if(reason == "update" || reason == "delete") {
        Array.prototype.slice.call(document.getElementsByAttribute("cb_id", editInTabId)).forEach(function(btn) {
            btn.parentNode.removeChild(btn);
        });
        delete window.editCustomButtonInTab;
    }
}
if(
    typeof addDestructor == "function" // Custom Buttons 0.0.5.6pre4+
    && addDestructor != ("addDestructor" in window && window.addDestructor)
)
    addDestructor(destructor, this);
else
    this.onDestroy = destructor;

Отредактировано Andrey_Krropotkin (20-03-2020 23:39:08)

Отсутствует

 

№10521-03-2020 14:07:22

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

Re: [CB]Attributes Inspector (для разработчиков)

Andrey_Krropotkin
Edit_Custom_Button_in_Tab здесь совершенно нипричём.

Это из-за Custom Buttons в моём исполнении.
По совершенно посторонним groupbox'ным причинам
захотелось посмотреть, насколько плохо это смотрится на Linux.

С превеликим трудом и приключениями поставил в виртуалку
Mint 19.3 Mate, и оказалось(!), что там, в отличие от Windows,
.xul адреса не просто грузятся ущербно, а вообще не грузятся.
Вместо загрузки выскакивает знаменитый диалог unknownContentType.xhtml

Поэтому было принято решение делать так:
nsIContentPolicy.shouldLoad() <— REJECT_REQUEST,
xhtml-override —> browsingContext.loadURI()

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

Отсутствует

 

№10628-04-2022 08:20:18

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

Re: [CB]Attributes Inspector (для разработчиков)

Infocatcher
В Firefox 99 завезли баг:
Bug 1753836 - MouseEvent.screenX/Y coordinate space is weird.


STR:
Открываем about:preferences, меняем зум на больше-меньше 100%,
запускаем AI, наводим на элемент страницы.


AR:
AI-тултип позиционируется не там, где должен, а со смещением.


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


Похоже, себе и нам, навязана необходимость некого перерасчёта.
Вот, такая добавка, вроде, помогает

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

Выделить код

Код:

…
		mousemoveHandler: function(e) {
			var tt = this.context.tt;

			if(!this._hasData) {
				this.mouseoverHandler(e);
				return;
			}

			var x, y;
			if(e) {
				x = e.screenX;
				y = e.screenY;

				// ▼▼▼▼▼
				if(this.fxVersion >= 99) {
					var k = e.view.devicePixelRatio / tt.ownerGlobal.devicePixelRatio;
					x *= k;
					y *= k;
				}

Отсутствует

 

№10703-05-2022 00:06:17

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

Re: [CB]Attributes Inspector (для разработчиков)

Dumby
Не было печали, апдейтов накачали… :sick:
Спасибо, обновил: https://github.com/Infocatcher/Custom_Buttons/commit/0865ba7


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

Отсутствует

 

№10810-01-2023 00:19:02

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

Re: [CB]Attributes Inspector (для разработчиков)

Infocatcher
Для Firefox 109 переключили настройку этого бага.
Теперь это затрагивает и релиз, и пора что-то с этим делать.


Проявляется в том, что Attributes Inspector больше не показывает margin, border, padding,
и, иногда, не показывает размеры (или показывает неправильно).


Такое происходит во всех окнах, кроме того, в котором запущен код,
то есть, контент, сайдбар, любые другие окна брузера и не браузера.


Насколько я вижу, Element и XULElement используются только для оператора instanceof,
поэтому сделал себе так (последняя строка обозначает место, перед которой добавлен остальной код).

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

Выделить код

Код:

//...
	var omit = this.eventHandler.fxVersion < 106;
	var defElm = function(name) {
		var elm = window[name];
		if(omit) return elm;

		var res = {};
		res[Symbol.hasInstance] = elm.isInstance.bind(elm);
		return res;
	}
	var Element = defElm("Element");
	var XULElement = defElm("XULElement");

	this.setAllListeners(ael);


Метод isInstance() довольно старый, Firefox 59+

Отредактировано Dumby (04-02-2023 08:52:30)

Отсутствует

 

№10912-01-2023 12:31:05

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

Re: [CB]Attributes Inspector (для разработчиков)

Infocatcher
Да, ещё упустил упомянуть, что в Firefox 110+
удалили классический contract id для промпт-сервиса.

Отсутствует

 

№11004-02-2023 08:35:59

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

Re: [CB]Attributes Inspector (для разработчиков)

Infocatcher
Ещё, в Firefox 111+, поломали Ctrl+Shift+C копирование с тултипа.
Bug 1776879 - Investigate if we could get rid of text/unicode, but use `text/plain` directly for plain text for Clipboard and DnD

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

Выделить код

Код:

/*
			this.setClipboardData({
				"text/unicode": text.replace(/\r\n?|\n/g, this.lineBreak),
				"text/html":    html.replace(/\r\n?|\n/g, this.lineBreak)
			}, sourceWindow);
*/
			var data = {
				"text/html": html.replace(/\r\n?|\n/g, this.lineBreak)
			};
			data["text/" + (this.fxVersion >= 111 ? "plain" : "unicode")]
				= text.replace(/\r\n?|\n/g, this.lineBreak);
			this.setClipboardData(data, sourceWindow);

Отсутствует

 

Board footer

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