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

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

№435109-07-2012 07:52:04

skynet281978
Участник
 
Группа: Members
Зарегистрирован: 09-03-2011
Сообщений: 507
UA: Firefox 13.0

Re: Custom Buttons

Kamui
брал у bunda1 08-05-2011 18:52:05
открываю http://forum.mozilla-russia.org/img/browsers/firefox35.png
нажимаю 3й пункт и ничего. фавиконы на сайтах копирует в base64, а картинки не хочет
в чём может быть причина?
проверил на фаерфокс в которой установлены только два дополнения CB и стайлишь. тоже самое

Отредактировано skynet281978 (09-07-2012 08:57:27)

Отсутствует

 

№435209-07-2012 09:14:36

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

Re: Custom Buttons

skynet281978 пишет

Kamui
брал у bunda1 08-05-2011 18:52:05
открываю http://forum.mozilla-russia.org/img/browsers/firefox35.png
нажимаю 3й пункт и ничего. фавиконы на сайтах копирует в base64, а картинки не хочет

Дополнительные возможности;
Если нажать правой клавишей мыши пункт Сохранить изображение как… в контекстном меню изображений на странице, изображение будет сохранено как base64 код в буфере обмена.

Отсутствует

 

№435309-07-2012 11:10:40

skynet281978
Участник
 
Группа: Members
Зарегистрирован: 09-03-2011
Сообщений: 507
UA: Firefox 13.0

Re: Custom Buttons

bunda1 да, теперь копируется, спасибо.
Мемори монитор: как варьировать расстояние между букв MB и разделителем справа? в кнопке или стилем?

Отсутствует

 

№435409-07-2012 11:12:23

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

Re: Custom Buttons

Kamui пишет

выделено красным

Спасибо, теперь въехал :)

Отсутствует

 

№435509-07-2012 15:14:22

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

Re: Custom Buttons

bunda1 пишет

Да большие страницы не сохраняет выбрасывает эту ошибку, интересно с в чем тут проблема.

Ай, только там return нельзя делать, надо еще mainWindow.removeChild(scrollbox); сделать. :)

Есть вот такое:
Canvas fails with a width > 65535, unconfirmed
google maps webgl broken: "Component returned failure code: 0x8007000e (NS_ERROR_OUT_OF_MEMORY) [nsIDOMHTMLCanvasElement.width]

okkamas_knife пишет

скорее всего в таймаутах - попробуй в конфиге выставить ожидание для скриптов побольше.

Да нет там никакого ожидания, тупо сразу ошибка:

Выделить код

Код:

var width = 10;
var height = 33000;
var canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
canvas.style.display = "none";
canvas.width = width;
canvas.height = height;
document.documentElement.appendChild(canvas);

try {
    var ctx = canvas.getContext("2d");
    //ctx.clearRect(0, 0, width, height);
    var url = canvas.toDataURL("image/png"); // Error: Component returned failure code: 0x80004005 (NS_ERROR_FAILURE)
    alert("Ok");
}
catch(e) {
    Components.utils.reportError(e);
}
document.documentElement.removeChild(canvas);

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

Отсутствует

 

№435609-07-2012 17:46:21

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

Re: Custom Buttons

Придумалось извращение для скриншотов больших страниц:

Выделить код

Код:

saveScreenshot(content || window);

function saveScreenshot(win) {
    var ww = win.innerWidth + win.scrollMaxX;
    var wh = win.innerHeight + win.scrollMaxY;

    var canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");

    var maxIterations = 500;
    var stopTime = Date.now() + 10000;

    var w = ww;
    var h = wh;
    var dw = ww;
    var dh = wh;

    function canNext() {
        return i < maxIterations && Date.now() < stopTime && (dw >= 2 || dh >= 2);
    }
    function message(title, s) {
        Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
            .getService(Components.interfaces.nsIPromptService)
            .alert(window, "Save Screenshot :: " + title, s);
    }

    var lastErr;
    for(var i = 0; ; ++i) {
        try {
            canvas.width = w;
            canvas.height = h;
            var context = canvas.getContext("2d");

            context.drawWindow(win, 0, 0, w, h, "rgb(255, 255, 255)");
            var url = canvas.toDataURL("image/png");

            if(i && canNext()) {
                if(h > w && h < wh && dh >= 2) h += (dh /= 2);
                else if(w < ww)                w += (dw /= 2);
                continue;
            }

            i && setTimeout(function() {
                message(
                    "Warning",
                    "Can't save entire page: "
                        + ww + "x" + wh
                        + " => " + Math.round(w) + "x" + Math.round(h)
                        + "\nLast error:\n" + lastErr
                );
            }, 0);

            var fileName = win.document.title
                .replace(/[\\\/:*?"<>|\s]+/g, "_");
            if("saveImageURL" in window)
                saveImageURL(url, fileName + ".png");
            else {
                Components.classes["@mozilla.org/appshell/window-mediator;1"]
                    .getService(Components.interfaces.nsIWindowMediator)
                    .getMostRecentWindow("navigator:browser")
                    .saveImageURL(url, fileName + ".png");
            }
            return true;
        }
        catch(e) {
            lastErr = e;
            if(!canNext()) {
                Components.utils.reportError(e);
                message("Error", "Iteration: " + i + "\nError:\n" + e);
                break;
            }
            if(h > w && dh >= 2) h -= (dh /= 2);
            else                 w -= (dw /= 2);
        }
    }
    return false;
}

При возникновении ошибок уменьшает высоту/ширину с ограничением времени и количества итераций.

Добавлено 09-07-2012 18:05:11
Обновил, теперь можно вызывать с помощью Mouse Gestures в любом окне.

Отредактировано Infocatcher (09-07-2012 18:05:11)


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

Отсутствует

 

№435709-07-2012 21:42:14

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

Re: Custom Buttons

Infocatcher
Ты реально крут, такой полезный код сделал.
Я сейчас ради эксперимента сохранил как PNG целый роман из lib.rus.ec на 1,76 МБ. При этом почему то выскакивает alert с ошибкой :/

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

Выделить код

Код:

Can't save entire page: 1024x104216 => 1024x32568
Last error:
[Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIDOMCanvasRenderingContext2D.drawWindow]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: chrome://custombuttons-context/content/button.js?windowId=Firefox&id=custombuttons-button13@code :: saveScreenshot :: line 33"  data: no]


но страницу все равно сохраняет.

Отсутствует

 

№435809-07-2012 21:55:20

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

Re: Custom Buttons

bunda1
Не всю.
С ошибками при больших размерах ничего не сделать, разве что разделить на части и сохранить в несколько файлов.

1024x104216 => 1024x32568

Ну вот страничка и урезалась до 1024x32568. :)


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

Отсутствует

 

№435909-07-2012 22:10:45

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

Re: Custom Buttons

Было бы не плохо если страница после сохранения сама прокрутилас до => 1024x32568.:blush:
Типа намёк на продолжение.

Отредактировано bunda1 (09-07-2012 22:17:52)

Отсутствует

 

№436009-07-2012 23:55:48

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

Re: Custom Buttons

bunda1 пишет

Было бы не плохо если страница после сохранения сама прокрутилас до => 1024x32568.:blush:
Типа намёк на продолжение.

Да какой-то это не намек, а дразнилка. :)

Можно вот так:

Выделить код

Код:

saveScreenshot(content || window);

function saveScreenshot(win) {
    var ww = win.innerWidth + win.scrollMaxX;
    var wh = win.innerHeight + win.scrollMaxY;

    var canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");

    var maxIterations = 200;
    var stopTime = Date.now() + 12000;

    var w = ww;
    var h = wh;
    var dw = ww;
    var dh = wh;

    function canNext() {
        return i < maxIterations && Date.now() < stopTime && (dw >= 2 || dh >= 2);
    }
    function message(title, s) {
        Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
            .getService(Components.interfaces.nsIPromptService)
            .alert(window, "Save Screenshot :: " + title, s);
    }
    function getFileName(iw, ih) {
        return fileName
            + (cw > 1 || ch > 1 ? "-part" : "")
            + (ch > 1 ? "-" + ih : "")
            + (cw > 1 ? "-" + iw : "")
            + ".png";
    }

    var lastErr;
    for(var i = 0; ; ++i) {
        try {
            canvas.width = w;
            canvas.height = h;
            var context = canvas.getContext("2d");

            context.drawWindow(win, 0, 0, w, h, "rgb(255, 255, 255)");
            var url = canvas.toDataURL("image/png");

            if(i && canNext()) {
                if(h > w && h < wh && dh >= 2) h += (dh /= 2);
                else if(w < ww)                w += (dw /= 2);
                continue;
            }

            if(i) {
                var cw = Math.ceil(ww/w);
                var ch = Math.ceil(wh/h);
                setTimeout(function() {
                    message(
                        "Warning",
                        "Can't save entire page: "
                            + ww + " x " + wh
                            + " => " + Math.round(w) + " x " + Math.round(h)
                            + "\nParts: " + cw + " x " + ch + " = " + cw*ch
                            + "\n\nLast error:\n" + lastErr
                    );
                }, 0);
            }

            var fileName = win.document.title
                .replace(/[\\\/:*?"<>|\s]+/g, "_");

            var saveImageURL = "saveImageURL" in window
                ? window.saveImageURL // See chrome://global/content/contentAreaUtils.js
                : Components.classes["@mozilla.org/appshell/window-mediator;1"]
                    .getService(Components.interfaces.nsIWindowMediator)
                    .getMostRecentWindow("navigator:browser")
                    .saveImageURL;
            saveImageURL(url, getFileName(1, 1));

            if(i) { // Try save page parts...
                for(var ih = 1; ih <= ch; ++ih) {
                    for(var iw = 1; iw <= cw; ++iw) {
                        var x = w*(iw - 1);
                        var y = h*(ih - 1);
                        if(!x && !y) // This is initial part, already saved
                            continue;
                        var _w = iw < cw ? w : ww - x;
                        var _h = ih < ch ? h : wh - y;

                        setTimeout(function(x, y, w, h, iw, ih) {
                            canvas.width = w;
                            canvas.height = h;
                            context = canvas.getContext("2d");

                            context.drawWindow(win, x, y, w, h, "rgb(255, 255, 255)");
                            url = canvas.toDataURL("image/png");

                            saveImageURL(url, getFileName(iw, ih));
                        }, 0, x, y, _w, _h, iw, ih);
                    }
                }
            }
            return true;
        }
        catch(e) {
            lastErr = e;
            if(!canNext()) {
                Components.utils.reportError(e);
                message("Error", "Iteration: " + i + "\nError:\n" + e);
                break;
            }
            if(h > w && dh >= 2) h -= (dh /= 2);
            else                 w -= (dw /= 2);
        }
    }
    return false;
}

Будет сохранять частями в отдельные файлы.
Только saveImageURL() не позволяет обработать отмену.
И можно получить NS_ERROR_OUT_OF_MEMORY для только что сработавшего размера.


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

Отсутствует

 

№436110-07-2012 00:45:16

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

Re: Custom Buttons

Infocatcher пишет

Только saveImageURL() не позволяет обработать отмену.
И можно получить NS_ERROR_OUT_OF_MEMORY для только что сработавшего размера.

Попробовал, грузит браузер не по детски. И saveImageURL() пока не сохранит все не останавливается. Эх.

Отсутствует

 

№436210-07-2012 01:09:41

Крошка Ру
Участник
 
Группа: Extensions
Зарегистрирован: 19-10-2008
Сообщений: 8718
UA: Firefox 16.0

Re: Custom Buttons

bunda1, а если для сохранения тяжёлых страниц внешний скриншотер припахать? :)

Отсутствует

 

№436310-07-2012 01:45:50

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

Re: Custom Buttons

Крошка Ру пишет

bunda1, а если для сохранения тяжёлых страниц внешний скриншотер припахать? :)

Да это возможно, запустить скриншотер с какими то параметрами. Я что то такое выдел в сборке Oперы страница сохранялась скриншотером SiteShoter специальной кнопкой на подобие CB. Но не все скриншотеры это поддерживают и я не знаю как это сделать.

Отсутствует

 

№436410-07-2012 02:41:12

Крошка Ру
Участник
 
Группа: Extensions
Зарегистрирован: 19-10-2008
Сообщений: 8718
UA: Firefox 16.0

Re: Custom Buttons

bunda1, Для K-Meleon есть CapturePlus  , правда это расширение , но может можно сам принцип реализации посмотреть ? :angel: Там PicPick используется.

Отсутствует

 

№436510-07-2012 04:48:32

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

Re: Custom Buttons

okkamas_knife пишет

2 сделать такой вариант - смотрим размеры и если они слишком большие то предупреждаем пользователя что страница будет обрезана и сохраняем обрезанный вариант без всякого гимора.

Никто не гарантирует, что добавление ограничения уберет ошибки.
И уже есть: http://forum.mozilla-russia.org/viewtop … 25#p571425

Еще можно добавить начальное предположение, тогда, пока там ничего не починят/поломают, подбор наибольшего допустимого размера будет быстрее:

Выделить код

Код:

saveScreenshot(content || window);

function saveScreenshot(win) {
    var ww = win.innerWidth + win.scrollMaxX;
    var wh = win.innerHeight + win.scrollMaxY;

    var canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");

    var maxIterations = 200;
    var stopTime = Date.now() + 12000;
    var okSize = 32000;

    var w = ww;
    var h = wh;
    var dw = ww;
    var dh = wh;

    function canNext() {
        return i < maxIterations && Date.now() < stopTime && (dw >= 2 || dh >= 2);
    }
    function message(title, s) {
        Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
            .getService(Components.interfaces.nsIPromptService)
            .alert(window, "Save Screenshot :: " + title, s);
    }

    var lastErr;
    for(var i = 0; ; ++i) {
        try {
            canvas.width = w;
            canvas.height = h;
            var context = canvas.getContext("2d");

            context.drawWindow(win, 0, 0, w, h, "rgb(255, 255, 255)");
            var url = canvas.toDataURL("image/png");

            if(i && canNext()) {
                if(h > w && h < wh && dh >= 2) h += (dh /= 2);
                else if(w < ww)                w += (dw /= 2);
                continue;
            }

            i && setTimeout(function() {
                message(
                    "Warning",
                    "Can't save entire page: "
                        + ww + " x " + wh
                        + " => " + Math.round(w) + " x " + Math.round(h)
                        + "\nLast error:\n" + lastErr
                );
            }, 0);

            var fileName = win.document.title
                .replace(/[\\\/:*?"<>|\s]+/g, "_");
            if("saveImageURL" in window)
                saveImageURL(url, fileName + ".png");
            else {
                Components.classes["@mozilla.org/appshell/window-mediator;1"]
                    .getService(Components.interfaces.nsIWindowMediator)
                    .getMostRecentWindow("navigator:browser")
                    .saveImageURL(url, fileName + ".png");
            }
            return true;
        }
        catch(e) {
            lastErr = e;
            if(!i) {
                w = dw = Math.min(w, okSize);
                h = dh = Math.min(h, okSize);
                continue;
            }
            if(!canNext()) {
                Components.utils.reportError(e);
                message("Error", "Iteration: " + i + "\nError:\n" + e);
                break;
            }
            if(h > w && dh >= 2) h -= (dh /= 2);
            else                 w -= (dw /= 2);
        }
    }
    return false;
}
okkamas_knife пишет

хочу воткнуть на таб еще одну кнопку но чтоб отдельным расширением

Расширение, переопределяющее binding для tab'а может быть только одно.
Правда, можно сделать расширяющий binding с наследованием, только для поддержки каждого расширения нужен будет отдельный binding.
Но можно попытаться генерировать нужный binding «на лету», только вот по протоколу file: подключить нельзя из-за ограничений безопасности, неизвестно, можно ли использовать resource:, а chrome: нельзя настраивать программно.

Так что или одно расширение, или при каждом открытии вкладки добавлять на нее кнопки вручную.


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

Отсутствует

 

№436610-07-2012 17:24:50

homo_nudus
Участник
 
Группа: Extensions
Зарегистрирован: 19-02-2007
Сообщений: 193
UA: Firefox 16.0

Re: Custom Buttons

Скажите, пожалуйста, почему при переинициализации всех кнопок (она происходит каждый раз, когда закрывается палитра инструментов при настройке панелей инструментов) обработчики событий, заданные в коде инициализации, дублируются? Однако при редактировании кнопки такого не происходит.

Здесь, например, написано:

If multiple identical EventListeners are registered on the same EventTarget with the same parameters, the duplicate instances are discarded. They do not cause the EventListener to be called twice, and since the duplicates are discarded, they do not need to be removed manually with the removeEventListener method.

Однако для такой тестовой кнопки:

this.clickBtn = function(event) {
    if (event.button == 0) {
        event.preventDefault();
        alert("cb click " + Date.now());
    }
}
this.addEventListener("click", this.clickBtn, true);

каждая переинициализация после закрытия палитры инструментов добавляет по одному alert при нажатии (их на одно нажатие будет столько, сколько раз за сессию вызывалась настройка панелей инструментов). Однако если отредактировать саму кнопку, инициализация после редактирования обнулит все обработчики и alert опять будет один.

Есть ли способ избежать таких наслоений одинаковых обработчиков?

Отредактировано homo_nudus (10-07-2012 17:50:31)

Отсутствует

 

№436710-07-2012 18:00:20

homo_nudus
Участник
 
Группа: Extensions
Зарегистрирован: 19-02-2007
Сообщений: 193
UA: Firefox 16.0

Re: Custom Buttons

okkamas_knife
Какой именно код некорректный и в чём?

Удаление не помогает, этот код ведёт себя точно так же:

this.clickBtn = function(event) {
    if (event.button == 0) {
        event.preventDefault();
        alert("cb click " + Date.now());
    }
}
this.removeEventListener("click", this.clickBtn, true);
this.addEventListener("click", this.clickBtn, true);

В упомянутой цитате сказано, что при добавлении такого же обработчика с теми же параметрами удалять не нужно, дубликаты отбрасываются. Можно предположить, что при переинициализации this.clickBtn — уже другая функция (даже если её код одинаков), поэтому происходит дублирование и поэтому удаление бесполезно. Но почему же при редактировании кнопки такого эффекта нет, хотя и тогда происходит повторная инициализация?

Отредактировано homo_nudus (10-07-2012 18:02:46)

Отсутствует

 

№436810-07-2012 18:42:59

homo_nudus
Участник
 
Группа: Extensions
Зарегистрирован: 19-02-2007
Сообщений: 193
UA: Firefox 16.0

Re: Custom Buttons

okkamas_knife
Проверил на 13.0.1. Та же самая проблема, только при инициализации после закрытия палитры в консоли появляется сообщение об ошибке:

Ошибка: uncaught exception: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIObserverService.removeObserver]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: chrome://browser/content/search/search.xml ::  :: line 90"  data: no]

Однако оно относится не к расширению, а к панели поиска (если его удалить в палитру, при последующих закрытиях палитры этой ошибки не возникает, но обработчики событий всё равно наслаиваются). Так что у меня и на 13.0.1 та же проблема. А вы проверяли на 13.0?

Отсутствует

 

№436910-07-2012 18:56:34

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

Re: Custom Buttons

homo_nudus
Скорее всего, кнопка при сохранении из редактора пересоздается.

Вот так двоится и при сохранении:

Выделить код

Код:

window.addEventListener("click", function(e) {
    if(e.button == 1)
        alert("cb: middle-click");
}, true);

Так что надо или реализовать this.onDestroy() для зачистки, или использовать

Выделить код

Код:

function addEventListener (eventType, eventHandler, captureFlag, eventTarget)

из \chrome\custombuttons.jar\content\custombuttons\contextBuilder.js (chrome://custombuttons/content/contextBuilder.js)

Добавлено 10-07-2012 18:58:43
Да, а функции там каждый раз новые создаются через new Function() для кода, поэтому проще подчищать из того же кода, который «наследил».
Ну, или экспортировать что-нибудь в window, например.

Отредактировано Infocatcher (10-07-2012 18:58:43)


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

Отсутствует

 

№437010-07-2012 19:07:56

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

Re: Custom Buttons

homo_nudus пишет

Скажите, пожалуйста, почему при переинициализации всех кнопок (она происходит каждый раз, когда закрывается палитра инструментов при настройке панелей инструментов) обработчики событий, заданные в коде инициализации, дублируются?

Это баг Custom Buttons, появился на FF4.

Однако для такой тестовой кнопки:

Используй код с которым проблем нет:

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

Выделить код

Код:

this.onclick = function(event) {
    if(event.button == 0) {
        // Действие при клике ЛКМ
    }
    else if(event.button == 1) {
        // Действие при клике СКМ
    }
    else if(event.button == 2 && !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey) {
        // Действие при клике ПКМ без модификаторов
    }
};
this.oncontextmenu = function(event) {
    if(event.button == 2 && !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey) {
        // Блокируем контекстное меню при клике ПКМ без модификаторов
        event.preventDefault();
        event.stopPropagation();
    }
};

Однако если отредактировать саму кнопку, инициализация после редактирования обнулит все обработчики и alert опять будет один.

Если отредактировать кнопку обработчики событий тоже дублируются, это проверено. Но похоже что бывает исключения.

Отредактировано bunda1 (10-07-2012 19:08:58)

Отсутствует

 

№437110-07-2012 19:11:04

homo_nudus
Участник
 
Группа: Extensions
Зарегистрирован: 19-02-2007
Сообщений: 193
UA: Firefox 16.0

Re: Custom Buttons

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

Попробую сейчас помудрить с onDestroy. Тут есть рецепт с window, но он меня немного пугает. Да и неправильное ведь всё равно поведение получается с этими обработчиками.

bunda1
Попробую и так, спасибо.
Может, они дублируются, только если функция анонимна или если она объявлена, но не привязана как свойство к кнопке?

Отредактировано homo_nudus (10-07-2012 19:11:51)

Отсутствует

 

№437210-07-2012 19:27:06

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

Re: Custom Buttons

homo_nudus пишет

Есть ли способ избежать таких наслоений одинаковых обработчиков?

Я это решаю по простому. Не самый лучший метод - для редактирования нужен рестарт и могут быть проблемы с глобальными переменными:

Выделить код

Код:

//Стоп, при открытии настройки панелей....................................................
if (window.qwertyRun == 'stop') return;

this.clickBtn = function(event) {
    if (event.button == 0) {
        event.preventDefault();
        alert("cb click " + Date.now());
    }
}
this.addEventListener("click", this.clickBtn, true); 
window.qwertyRun = 'stop';

Или так, но такой вариант по неизвестным мне причинам не всегда работает:

Выделить код

Код:

// удаление обработчиков для адресной строки, при открытии настройки панелей
this.onDestroy = function() {
document.getElementById("urlbar").removeEventListener("dblclick", mclick, false);
document.getElementById("urlbar").removeEventListener("mousedown", function(e){if(!gURLBar.focused) goDoCommand("cmd_copy");}, false)
};

// добавляем обработчики для адресной строки........ 
document.getElementById("urlbar").addEventListener("dblclick", mclick, false);
//копировать выделенный текст на странице
document.getElementById("urlbar").addEventListener("mousedown", function(e){if(!gURLBar.focused) goDoCommand("cmd_copy");}, false);

И может это будет полезно:

Using onDestroy Method

Выделить код

Код:

/*Initialization code*/
// constructor example - change button type property
// destructor  example - close window
// update      example - edit button
// delete      example - delete button
LOG("test 2");
this.onDestroy = function(reason) {
  LOG("test 1");
  if (reason == "constructor") LOG("constructor");
  if (reason == "destructor")  LOG("destructor");
  if (reason == "update")      LOG("update");
  if (reason == "delete")      LOG("delete");
}

Отредактировано bunda1 (10-07-2012 19:35:39)

Отсутствует

 

№437310-07-2012 19:33:14

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

Re: Custom Buttons

homo_nudus пишет

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

Да все они заново создаются:

Выделить код

Код:

function f0(e) {
    if(e.button == 1)
        alert("cb: middle-click - 0");
}
window.addEventListener("click", f0, true);

var f1 = function _f1(e) {
    if(e.button == 1)
        alert("cb: middle-click - 1");
};
window.addEventListener("click", f1, true);

this.f2 = function(e) {
    if(e.button == 1)
        alert("cb: middle-click - 2");
};
window.addEventListener("click", this.f2, true);

Добавлено 10-07-2012 19:35:02

bunda1 пишет

Или так, но такой вариант по неизвестным мне причинам не всегда работает:

removeEventListener() удалит только ту же функцию, что была добавлена через addEventListener().
А

Выделить код

Код:

addEventListener("mousedown", function(e) ...

создает новую функцию и никуда не сохраняет ссылку на нее.

Отредактировано Infocatcher (10-07-2012 19:35:02)


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

Отсутствует

 

№437410-07-2012 19:36:04

homo_nudus
Участник
 
Группа: Extensions
Зарегистрирован: 19-02-2007
Сообщений: 193
UA: Firefox 16.0

Re: Custom Buttons

Infocatcher, bunda1
Да, любой из этих кодов работает:
-----------------------------------------------------------------
this.clickBtn = function(event) {
    if (event.button == 0) {
        event.preventDefault();
        alert("cb click " + Date.now());
    }
}
this.addEventListener("click", this.clickBtn, true);
this.onDestroy = function() {
    this.removeEventListener("click", this.clickBtn, true);
}
-----------------------------------------------------------------------------
this.clickBtn = function(event) {
    if (event.button == 0) {
        event.preventDefault();
        alert("cb click " + Date.now());
    }
}
this.onclick = this.clickBtn;
---------------------------------------------

Жаль только, что оба не очень красивы (добавления свойств window и подавно хотелось бы избегать). Onclick обычно советуют заменять на addEventListener (гибкий и стандартизированный метод), а вся эта суматоха с onDestroy выглядит костылями.

Большое спасибо всем за помощь.

Отредактировано homo_nudus (10-07-2012 19:37:40)

Отсутствует

 

№437510-07-2012 19:38:11

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

Re: Custom Buttons

А вот так работает:

Выделить код

Код:

function f(e) {
    if(e.button == 1)
        alert("cb: middle-click");
}
window.addEventListener("click", f, true);
this.onDestroy = function() {
    window.removeEventListener("click", f, true);
};

И вот так:

Выделить код

Код:

function f(e) {
    if(e.button == 1)
        alert("cb: middle-click");
}
addEventListener("click", f, true); // Функция addEventListener переопределена, и removeEventListener() вызовется автоматически при пересоздании кнопки

Добавлено 10-07-2012 19:39:34

homo_nudus пишет

Onclick обычно советуют заменять на addEventListener

Отделение разметки от кода ради отделения разметки от кода? :)

Отредактировано Infocatcher (10-07-2012 19:39:34)


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

Отсутствует

 

Board footer

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