Эта тема создана для продолжения дискуссии, завязавшейся при обсуждении одноименного расширения.

Dark-Demon

... много хочешь от расширения, которое даже не пре-альфа :dumb: я говорю, что в будущем пользователи будут править только то, что находится внутри <binding> и ничего более...

Я уже раньше говорил, что принципиально против xbl ничего не имею, всё зависит от конкретной реализации. Пока же получается, что хоть сам код кнопок и выглядит аккуратно, но как это будет выглядеть на практике - неизвестно... Так что IMHO тебе стоит всё-таки попробовать выпустить что-нибудь типа пре-альфы, обладающей базовым функционалом (например, редактирование кнопки без перезагрузки браузера, и т.п.).  Тогда наверняка всплывут и основные проблемы, связанные с этим способом.
А пока у меня еще один вопрос возник. Что будет, если пользователь некорректно напишет кнопку на xbl? Не отразится ли это на других кнопках? В общем, опять приходим к вопросу конкретной реализации.
В общем, если удастся разрешить все эти вопросы, то в расширении можно будет совместить оба формата (и нынешний, и xbl). А может и 3 (если делать что-нибудь типа wizard'а, как я хотел). В любом случае, от нынешнего формата отказываться нет смысла, т.к. под него уже написано много работающих кнопок.

Пока же получается, что хоть сам код кнопок и выглядит аккуратно, но как это будет выглядеть на практике - неизвестно...

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

Так что IMHO тебе стоит всё-таки попробовать выпустить что-нибудь типа пре-альфы, обладающей базовым функционалом

охъ... не обещаю, что это будет скоро...

Что будет, если пользователь некорректно напишет кнопку на xbl? Не отразится ли это на других кнопках?

ничего страшного не случится. единственное, что - надо при сохранении проверять на валидность, как например это сделано в stylish.

Dark-Demon
Попробую переубедить в последний раз.
Проведём аналогию между объектами JavaScript и xbl-привязками в твоём расширении на примере bb-кнопок.
Для имитации UI будем использовать функцию

Выделить код

Код:

function sumAndPrint (a, b)
{
    print (a. getValue () + b. getValue ());
}

Итак, пусть перед нами стоит простая задача сложения двух чисел: 1+2.
Мы принципиально против литерального представления чисел ("ужасы DOM"), поэтому будем создавать объекты.
Вот твой подход:

Выделить код

Код:

// xbl:
// создаём класс-объект '1'
function numberOne () // '<binding id="cb2-bb-code"...'
{
    this. value = 1; // <opener> '[CODE]' </opener>
}
numberOne. prototype =
{
    getValue: function () // методы
    {
        return this. value;
    }
}
// Теперь нам нужно иметь число '2', создаём класс-объект
function numberTwo () // '<binding id="cb2-bb-quote"...'
{
    this. value = 2; // <opener> '[quote]' </opener>
}
numberTwo. prototype = numberOne. prototype; // применяем "наследование"

// xul:
var one = new numberOne (); // '<toolbaritem id="cb2-bb-code"...'
var two = new numberTwo (); // '<toolbaritem id="cb2-bb-quote"...'
// используем
sumAndPrint (one, two);

Мой подход, тобою с негодованием отвергнутый:

Выделить код

Код:

// xbl:
// создаём общий класс 'number'
function number (value)
{
    this. value = value; // нет аналога, это делает платформа (атрибуты)
}
number. prototype =
{
    getValue: function () // методы
    {
        return this. value; // ... this. getAttribute ("attr") ...
    }
}

// xul:
var one = new number (1); // '<toolbarbutton opener="[CODE]"...'
var two = new number (2); // '<toolbarbutton opener="[quote]"...'
// используем
sumAndPrint (one, two);

Dark-Demon

ты о том, как будут программировать сторонние разработчики?

Ага.

Anton, глупость какая-то... я тоже так умею:
в моём случае, например, можно сделать так:

Выделить код

Код:

class code: allbuttons
{
  string code= 'code';
  function onmouseleft() {...}
}
class quote: public code
{
  string code= 'quote';
  inherit function onmouseleft();
  function onmouseright() {...}
}

и это будет актуально, так как, например, можно написать [uri]http://...[/uri], а можно [uri=http://..]ссылка[/uri]
фишка в том, что каждая кнопка наследует всё необходимое из исходной кнопки и доопределяет, что требуется, а в твоём случае, что не предусмотрел в базовом классе, то хрен реализуешь в конкретной кнопке.

Dark-Demon пишет

Anton, глупость какая-то... я тоже так умею:
в моём случае, например, можно сделать так:

и это будет актуально, так как, например, можно написать [uri]http://...[/uri], а можно [uri=http://..]ссылка[/uri]

Да, можно. Но как:

Выделить код

Код:

class uritag: public quote
{
  string code = 'uri';
}

Т. е., каждому отдельному объекту - отдельный класс. Вернёмся к примеру с суммированием. Отметим для начала, что проще было бы написать

Выделить код

Код:

print (1 + 2);

Это тот случай, когда в кнопке пишут что-нибудь уж совсем простое, да хотя бы банальное getBrowser().reloadAllTabs(). В твоём случае обязательно придётся писать новый класс. Несмотря на то,

что

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

...
фишка в том, что каждая кнопка наследует всё необходимое из исходной кнопки и доопределяет, что требуется,...

(читаем: каждый объект доопределяет что ему надо)
Вот в задаче с суммированием для степеней двойки понадобился метод, возвращающий показатель этой самой степени. И что изменится в твоём случае ? Ничего. Как была пропорция 1 объект : 1 класс, так и осталась. Сто чисел - сто классов.

... а в твоём случае, что не предусмотрел в базовом классе, то хрен реализуешь в конкретной кнопке.

В моём случае добавится второй класс. Сто чисел - два класса. Что до бибикодов - мою реализацию ты видел, там даже второй класс не понадобился, модель изначально предусматривала наличие случаев [uri]...[/uri] / [uri=...]...[/uri].

Теперь более близкая к реальности задача. Не будем суммировать числа, будем делать бб-кнопки динамически. На каждом форуме свой набор кодов, где-то в гробу видели '[ code]', где-то разрешены html. Допустим, есть панелька, на неё нужно помещать нужные кнопки в зависимости от того, на каком мы форуме. Не мудрствуя лукаво напишем набор оверлеев, каждый из которых описывает набор кнопок для какого-то конкретного форума. И твоём случае придётся в xbl прописать все возможные теги. И, поскольку таблицы стилей тебя тоже чем-то не устраивают, тебе придётся ещё писать в xul километры 'style="-moz-binding:url..."'.

Что в моём случае ? Одна привязка в xbl, одна строчка в css типа '.bbcodebutton { -moz-binding:url... }' и те же самые оверлеи, только без длинных style="-moz-binding:url..." а все с одинаковым значением атрибута class: class="bbcodebutton".

А то и вовсе без атрибута 'class': в css строчка 'bbbutton { -moz-binding:url ... }, а в xul - '<bbbutton opener="..." closer="..."/>.
Если ты захочешь сделать так

же, тебе придётся вспомнить о css, писать туда километры -moz-binding'ов, для каждого возможного тега. В оверлеях будет что нибудь вроде

Выделить код

Код:

<bbtagcode/>
<bbtagquote/>
<bburiquote/>

Как будто бы всё замечательно, но только на первый взгляд. Потом выяснится, что какой-либо форум не поддерживает альтернативный текст в [uri], т. е., только [uri]...[/uri]. Придётся писать новую привязку в xbl, новый тег <bbtagnoalternatetexturi> какой-нибудь (Кстати, какую привязку он будет, как ты выражаешься, "наследовать" ? Базовую для '[ code]' ? Вроде нелогично. Или переписывать последовательность "наследования": code->noalternatetexturi->uri

?

) и пополнять css.

А между тем, всё вышеописанное можно сделать и вовсе без xbl. Для bb-кнопок сойдёт стандартный класс toolbarbutton.

Т. е., каждому отдельному объекту - отдельный класс.

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

Вернёмся к примеру с суммированием.

не вернёмся. кнопки - это полностью автономные элементы. ни о каком суммировании и речи быть не может.

модель изначально предусматривала наличие случаев [uri]...[/uri] / [uri=...]...[/uri]

это в каком это месте?

И твоём случае придётся в xbl прописать все возможные теги.

да, имено так, неактуальные кнопки будут просто прятаться.

тебе придётся ещё писать в xul километры 'style="-moz-binding:url..."'.

Выделить код

Код:

style="-moz-binding:url(cb2.xbl#bb-code-12)"

не назвал бы это "километрами". кстати, это тебя почему-то не смущает:

Выделить код

Код:

class="toolbarbutton-1 chromeclass-toolbar-additional custombutton-bbbutton"

Что в моём случае ? Одна привязка в xbl, одна строчка в css типа '.bbcodebutton { -moz-binding:url... }' и те же самые оверлеи, только без длинных style="-moz-binding:url..." а все с одинаковым значением атрибута class: class="bbcodebutton".

угу, и с фиксированным числом кнопок. а если хочется динамического числа, то либо опять же прописываем в xul все кнопки и прячем лишние, либо в xul не пишем ничего и генерим их через dom, что впрочем не лишено смысла.

А между тем, всё вышеописанное можно сделать и вовсе без xbl.

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

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

Я всё же надеялся вывести спор в конструктивное русло. Но

Dark-Demon пишет

...для меня остаётся загадкой, на кой в интерпретируемые языки суют классы...

это в каком это месте?

...насчёт тегов я не понял...

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

"не понимаю, не разобрался в чужом коде, не знаю, не понял о чём речь - ну то есть вообще" и, судя по всему, можно добавить "и знать не хочу".

Действительно, бесполезно. А и ладно.

p.s. кстати

...угу, и с фиксированным числом кнопок. а если хочется динамического числа...

спасибо, повеселил

Мда.. это диагноз...

Anton
Твоя критика относительно того, что предлагает Dark-Demon, понятна. Но я никак не могу понять, что конкретно ты хочешь предложить взамен. То есть отдельные-то куски понятны, но какая из них должна получиться итоговая картина - неизвестно. Какова должна быть внутренняя структура расширения в твоём понимании, и как будет выглядеть написание кнопки для конечного пользователя?

Антон предлагает что-то вроде этого: http://forum.mozilla-russia.org/uploaded/ta8v51c4.design_mode.zip

то есть делать объекты на XUL и к ним создавать классы на XBL.
а я предлагаю делать объектоклассы на XBL. а их массив в XUL будет создаваться автоматом.

Yan пишет

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

1. Не надо отказываться от нынешнего формата кнопки. Нужны обработчики экзотических событий или кнопки-меню ? Сделать один-два поддерживаемых расширением xbl, расширяющих функционал всех простых кнопок, создаваемых расширением.
2. Для простых кнопок надо бы предусмотреть возможность указания разработчиком кнопки атрибутов кнопки, доступных для изменения через интерфейс расширения. Допустим, пишет разработчик кнопку типа launchApplication, указывает, что атрибут "path" у кнопки является изменяемым - пользователь через интерфейс расширения (не редактор кода) указать нужный путь.
3. Кнопки и прочие элементы управления хранить в xul - их можно перезаписывать во время работы браузера и динамически подгружать (loadOverlay/DOM).
4. Сложные элементы управления делать непосредственно в xul. Возможно, удобней будет соорудить аналог тега <toolbaritem> - контейнер с поддержкой настраиваемых атрибутов и обработчиков событий.
5. Нужна поддержка скриптов, не привязанных к каким-то кнопкам. Т. е., "API" для сокращения размеров распространяемого кода.
6. Пакеты для распространения наборов кнопок и/или скриптов.
7. xbl использовать только там, где без него действительно не обойтись, или где это значительно сократит размеры кода - например, пакеты однотипных кнопок.

Примерно так.

Anton, тебя, наверно, xbl в детстве укусил :)

5 - каким боком это относится к сабжу? давай не будем создавать очередной кухонный комбайн...

Dark-Demon пишет

Anton

А ? Что такое ? В других разделах не флеймится ?

давай не будем создавать очередной кухонный комбайн...

А-а, ладно, не создавай, разрешаю.

foxuser
Для обсуждения этого расширения есть специальная тема. Эта тема только для обсуждения разработки.

Ну что ж, встречайте tp4 :)
http://dark-demon.nm.ru/etc/files/customitems.tp4.rar
реализовал добавление, редактирование и переименовывание кнопок. рантайм изменения ещё не реализовал.
нажмите ctrl+правую кнопку мыши на каком-нибудь кастомайтеме и в меню будут два пункта: new и edit

Ян, на мой взгляд, так редактировать кнопки много удобнее.

ps. я сменил название, так что предыдущую версию надо удалить.

http://dark-demon.nm.ru/etc/files/customitems.v.3.rar

новая версия customitems - 0.3
в интерфейсе редактирования добавилась ссылка на редактирование родительской кнопки.

ещё добавил две весьма полезные кнопки (Л,С,П - соответствено, левая, средняя и правая кнопки мыши).

первая:
Л - создаёт новую пустую вкладку
С - восстанавливает последнюю закрытую
П - выдаёт контекстное меню выбора какую закрытую вкладку восстанавливать.

вторая:
Л - создаёт новое окно
С - восстанавливает последнюю сохранённую сессию.
П - выдаёт контектное меню выбора между последними четырьмя сохранёнными сессиями.

ещё у меня вопросик возник: я открываю xul-файлы в отдельных табах. как из этих xul-ов получить доступ к основному окну браузера?

благодаря Антону исправил багу с sessionstore, теперь она работает и в многооконном режиме.
если есть желающие сделать аналогичные кастомкнопки, выкладываю исходники кастомайтемов sessionstore и tabber...

ci-sessiostore:

Выделить код

Код:

<content context="_child">
	<xul:toolbarbutton label="Session Restore" tooltiptext="New Window | Restore Browser State" image="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAK8AAACvABQqw0mAAAACB0RVh0U29mdHdhcmUATWFjcm9tZWRpYSBGaXJld29ya3MgTVi7kSokAAABb0lEQVR4nKWSv0tCURTHP9ceJaYU5lBBDZlUkw1FLQ2GELS2NoXiEP2YCgrCIipCIYkCERrcmqI/oBocais3sd7UUFARFS9JkdtgPqR8WvaFL/ecc7/nnO9whJSS/0AMLe3PNnjHN//aqCj1HycjbXbhPrnTko+t8KAaii88TobPVP2Vx90In8TtuEcQT2scJGvzP+VGASunG11VtZ7DuKUYe8f63pebBxm9saLwlqXdYfvdxkiEMNAzuUV7kw0usyjUNeJyduiaa1Wlx+WqOGdvYLEQnD6i8FJwFgjuEQ1O6yL/yi6xV9VSbgDz8xaAwgGsPmv5fF5nKp3WpJQFzs1JCYYMgTSRedcdlMK/sgtAuITlcvAnjB2U8stNCGSxhj+hmfg65XIOijSElCiYBADR4DRCCP0vtjbzQx/+XjAJBL5zLbXQYrylAnq3nxBM7NxS12knm4NMBswNkMtVaRVgkXC0HhBAP2CuyQJcfQKFzMLCQlddPgAAAABJRU5ErkJggg=="/>
	<xul:menupopup anonid="contextmenu" onclick="event.stopPropagation()">
		<xul:menuitem label="last" oncommand="parentNode.parentNode.restore(1, this.label)"/>
		<xul:menuitem label="more last" oncommand="parentNode.parentNode.restore(2, this.label)"/>
		<xul:menuitem label="very last" oncommand="parentNode.parentNode.restore(3, this.label)"/>
		<xul:menuitem label="lastest" oncommand="parentNode.parentNode.restore(4, this.label)"/>
	</xul:menupopup>
</content>

<implementation>
	<constructor>
		<![CDATA[
			if (typeof (hiddenwindow.customitems_last_session_stored) == 'undefined')
			{
				if (!this.storedir.exists()) this.storedir.create(0x01, 0755);
				if (this.curstate.exists()) this.curstate.copyTo(this.storedir,"sessionstore.0");
				for (var i=4; i>0; i--)
				{
					if (this.states[i].exists()) this.states[i].remove(false);
					if (this.states[i-1].exists()) this.states[i-1].copyTo(this.storedir,"sessionstore."+i);
				}
				hiddenwindow.customitems_last_session_stored = true;
			};
		]]>
	</constructor>
	<destructor>
		<![CDATA[
			if (this.curstate.exists()) 
			{
				if (states[0].exists()) states[0].remove(false);
				this.curstate.copyTo(this.storedir,"sessionstore.0"); 
			};
		]]>
	</destructor>
	<method name="restore">
		<parameter name="num"/>
		<parameter name="name"/>
		<body>
			<![CDATA[
				if (confirm('restore '+name+' browser state?'))
				{
					this.ifstream.init (this.states[num], 0x01, 0, 0);
					var lifstream= this.ifstream.QueryInterface(Components.interfaces.nsILineInputStream);
					var line = {};
					lifstream.readLine(line);
					this.seserv.setBrowserState(line.value);
					this.ifstream.close();
				};
			]]>
		</body>
	</method>
	<field name="appshell"> Components.classes ["@mozilla.org/appshell/appShellService;1"]. getService(Components.interfaces.nsIAppShellService) </field>
	<field name="seserv"> Components.classes['@mozilla.org/browser/sessionstore;1'].getService(Components.interfaces.nsISessionStore) </field>
	<field name="profdir"> Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("ProfD", Components.interfaces.nsIFile) 	</field>
	<field name="ifstream"> Components.classes['@mozilla.org/network/file-input-stream;1'].getService(Components.interfaces.nsIFileInputStream) </field>
	<field name="hiddenwindow"> appshell.hiddenDOMWindow </field>
	<field name="storedir">
		<![CDATA[
			var storedir= profdir.clone();
			storedir.append("sessionstore");
			storedir
		]]>
	</field>
	<field name="curstate">
		<![CDATA[
			var curstate= this.profdir.clone();
			curstate.append("sessionstore.js");
			curstate
		]]>
	</field>
	<field name="states">
		<![CDATA[
			var states= new Array(); 
			for (var i=4; i>=0; i--)
			{
				states[i]= this.storedir.clone();
				states[i].append("sessionstore."+i);
			};
			states
		]]>
	</field>
</implementation>

<handlers>
	<handler event="click" button="0" modifiers="any"> OpenBrowserWindow(); </handler>
	<handler event="click" button="1" modifiers="any"> this.restore(1, 'last'); </handler>
</handlers>

ci-tabber:

Выделить код

Код:

<content context="_child">
	<xul:toolbarbutton label="Tabber" tooltiptext="New Tab | Undo Close Tab" image="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAK8AAACvABQqw0mAAAACB0RVh0U29mdHdhcmUATWFjcm9tZWRpYSBGaXJld29ya3MgTVi7kSokAAABKElEQVR4nKWSsUrDcBDGfykRpIMiWFCpbiL4BJZSsKNDC+ripg51cezcgs1qQXyATk4KllZfQEqp4OALuAhObakuyeLwuaQhNkkN9YODO+6+7+7+9zck8R+YY+f2rmnPm+a0Wg/fYvvwoPAOgCRa921bUmxz65FEwq+81eqz9tgP7fpxcsrncSl6BYCVBYOjzVSQXa0m0xvr48jxpxKNxs0bIICnfIqLdMTilkXdsryw3Xz4AjCXlxZXM7ksg+Eoggn+mQbDEZlcll6nO+et0Ot0A6Ti60syVOz6KglQBNgvwN55Lfy1KxUJIu0SJImph6/7/PJE7GG3VPn79u40bldbku3yfv+DWRBbIHT82AK1mlOWnLLkTKZMgPxZNe4gARjAzqxkSc8/PUraALhZmswAAAAASUVORK5CYII="/>
	<xul:menupopup anonid="contextmenu" onclick="event.stopPropagation()" onpopupshowing="parentNode.updatemenu(this)"/>
</content>

<implementation>
	<field name="seserv"> Components.classes['@mozilla.org/browser/sessionstore;1'].getService(Components.interfaces.nsISessionStore) </field>
	<method name="updatemenu">
		<parameter name="popup"/>
		<body>
			<![CDATA[
				var c;	while (c= popup.firstChild) popup.removeChild(c);
				var tabs = eval(this.seserv.getClosedTabData(window));
				for (var i = 0; i < tabs.length; i++) 
				{
					var mi = popup.appendChild(document.createElement("menuitem"));
					mi.setAttribute("label", i+": "+tabs[i].title);
					mi.setAttribute("oncommand", "undoCloseTab("+i+")");
				};
			]]>
		</body>
	</method>
</implementation>

<handlers>
	<handler event="click" button="0" modifiers="any"> BrowserOpenTab(); </handler>
	<handler event="click" button="1" modifiers="any"> undoCloseTab(); </handler>
</handlers>

в sessionstore была ошибка, из-за чего сессии не сохранялись. подправил предыдущее сообщение.

http://dark-demon.nm.ru/etc/files/customitems.v.4.rar

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

Yan, не подскажешь, как динамически добавлять кнопки в палитру? а то я в твоём расширении не понял как это делается...

Dark-Demon
А что конкретно не понятно?
Это делает функция addToPalette(button):

Выделить код

Код:

...
	addToPalette:function(button){
		this.gToolbox.palette.appendChild(button);
	},
...

Где:
this.gToolbox=document.getElementById("navigator-toolbox");//Firefox
button - созданный через DOM элемент <toolbarbutton>.

ясненько, попробуем...

Блин, сделал, все работало, запаковал в расширение, установил и опять не пошет %-\ пока выложил с этим багом ибо весь остальной функционал готов к использованию: http://dark-demon.nm.ru/etc/files/customitems.v.5.xpi
кнопки не прилагаются, установить их можно отсюда:
http://dark-demon.nm.ru/soft/customitems/
ещё попробовал реализовать обратную совместимость с custombuttons. вставляют в начало инициализационного кода определение функции bind(), но когда она используется вылетает ошибка мол нет такой функции... в общем мрак...

Dark-Demon

ещё попробовал реализовать обратную совместимость с custombuttons. вставляют в начало инициализационного кода определение функции bind(), но когда она используется вылетает ошибка мол нет такой функции...

Это баг во второй версии Firefox: https://bugzilla.mozilla.org/show_bug.cgi?id=355161
Исправят в 2.0.1

Yan, дык если эти кнопки установить твоим расширением, то они работают нормально....

В версии 0.0.1.3 я сделал, чтобы при нажатии на кнопку проверялось, есть ли метод bind у Function, и если нет -- то он заново инициализируется.

Yan, вотъ! я тоже так делаю. я просто добавляю твой код в начало инициализации.

например:

Выделить код

Код:

<content label="Image show-hide" image="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAA3NCSVQICAjb4U/gAAAAD1BMVEUfact50/fF+v/M//////8mt18DAAAABXRSTlP/////APu2DlMAAAAJcEhZcwAACvAAAArwAUKsNJgAAAAgdEVYdFNvZnR3YXJlAE1hY3JvbWVkaWEgRmlyZXdvcmtzIE1Yu5EqJAAAADhJREFUeJxjcHFgAAIXFwYXB2NjYwYWEMNQUJCZAcYwYIEwGBigDEFhDIYQ+QygpUZKIAbIGQwsANX+EGaBLn8yAAAAAElFTkSuQmCC">
	<xul:toolbarbutton xbl:inherits="label,image" />
</content>

<implementation>
	<constructor>
		<![CDATA[

if ((typeof Function.prototype.bind)=="undefined")
{
	Function.prototype.bind= function(object)
	{
		var method = this;
		return function()
		{
			return method.apply(object, arguments);
		};
	};
};

this.pref='permissions.default.image';
this.setState=function(){
	switch(this.PS.getIntPref(this.pref))
	{
	case 1:
		this.image= 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAFo9M/3AAAACXBIWXMAAAsSAAALEgHS3X78AAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAACp0lEQVR42mL4//8/g3zm6f8AAcQAYvz4uuc/QACBeSAOQAAx/P75/X/ukY//AQIILHXhz///lZe//wfJAgQQWOBui9D/P78t/6ftffcfIIAYYKbA9AIEEIjDWnPtx3+YIEAAMXz7/P7/75+v/mcADQQJAAQQ0HTt/y9nqv73W/caLAAQQDAzWC8CbWq89et//fWf/5HNBAgguIJzIKdc+v6/7Py3/8Wnv/wvPPkZrAgggMAKfv+c8P/f+8r//x+mAZ03/X/g5nf/sw68BysACCCIH78p///zSeb/n4ci/39d4P+/4+f//0d//QcrAAggFH8gY5A4CAMEEFxB0+1f/xtu/vxfc+X7f5CDYYoAAgiuoP7Gz//VV378r7j4HdkkVoAAgisA6Sy/8O1/ydmvYB+c+g02hRUggBgaw6T+g4Iegq//B/Fzj376fwLiSFaAAAIr+HI17f//l4X//9+JAyvIPPjh/3GoAoAAAit4MEns/71Gof+f1hmCFaQCownqTVaAAAIr+PNb4f+fFxL//9wUACsAScIUAAQQA8y/IA7IsSAvgvAFKD4PxdjCCIQBAgjDgAvQSK0DRmrtNWDQXAUFzTewxjNAn5/8/R/FIIAAwjAAZFsdMEFVAcMUFPkgzaAEUAoKvlOfkYMQ7AWAAAJrBvmLEC4Aasw/DsTHPiG7ghUggOAG/PkFTCG/p/3//6P///+PLf//vwamrsc5///+WQc2IHLX+//Zhz/+zz4EjwKwAQABBDfg90/d/w+mSvx/DEztPy+G//9/K/r//6vBwBhoBhvgv/HN//T97/9n7Hv//xiSAQABhDDgl8b/B33C/++3C/6/38T//34d7//7Vdz//0Kjzm/dq/9pe979T939Fp6UQQYABBDRYSAZdghrkgcIMAD5xMj+kGsEXgAAAABJRU5ErkJggg==';
		this.tooltipText= 'load all images';
	 	break;
	case 2:
		this.image=
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAA3NCSVQICAjb4U/gAAAAD1BMVEUfact50/fF+v/M//////8mt18DAAAABXRSTlP/////APu2DlMAAAAJcEhZcwAACvAAAArwAUKsNJgAAAAgdEVYdFNvZnR3YXJlAE1hY3JvbWVkaWEgRmlyZXdvcmtzIE1Yu5EqJAAAADhJREFUeJxjcHFgAAIXFwYXB2NjYwYWEMNQUJCZAcYwYIEwGBigDEFhDIYQ+QygpUZKIAbIGQwsANX+EGaBLn8yAAAAAElFTkSuQmCC';
		this.tooltipText= 'don\'t load any images';
		break;
	case 3: 
		this.image=
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAFo9M/3AAAACXBIWXMAAAsSAAALEgHS3X78AAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAACdklEQVR42mL4//8/g3zm6f8AAcQAYvz69es/QACBeSAOQAAx/Pnz5//Z20/+AwQQWOrHv///n7x89R8kCxBAYIEuXdb/f//+/X/w8oP/AAHEADMFphcggEAc1pdv3vyHCQIEEMPPnz//gwy8dPcpWAAggMCmnzp16v+Rqw/BAgABBDOD9RfQpncf3v1/9RahHSQHEEBwBd+BCh4DnXLv6Yv/Nx89/3/l/jOwIoAAAisAGXv9+vX/MOedvvn4//Frj8AKAAII7keQBAj//v37//M///8/+/0frAAggFD8gYxB4iAMEEBwBR8+vvv/5v1bYJC8/v/733+4IoAAgit4/e7t/+evX/9/9OIVskmsAAEEV/D01ev/D56//H/78Yv/1x48+//uD9gUVoAAYlizZg04pGAYxD8PjIbXUAUAAQRWMMmA9f+VK1f+dwK9CeKfuP7o/0uoAoAAAivo02f9f+7cuf9tOhAFh4DR9BziTVaAAAIrgIUBCIP4IEloOLACBBADzL8gDsixIC+C4uUnFP+AYmxhBMIAAYRhwE9wpL79/wYYLKCIfQEMmofPIUHz6e///2///EcxCCCAMAwA2fYCmKCeATWC0uFDYNDdf/by/50nL/5fBQbf5ftP/7//CzeEFSCAwJpB/iKErwJTz6V7T/9fBCZMJFewAgQQ3ABQAE0BBjcoyCcAQxUUsj16rP///fsHNuAcMG7OAFPZqRuP/79CMgAggOAGgCIRpBEUX6BkCYqWDh1WeMiD4u4oMBeAcsILJAMAAgjFgF6gjSDNII2gOG3RRhhw+MrD/wcvPfi//+J9eFIGGQAQQESHAa4kDxBgAMjdAQviliYiAAAAAElFTkSuQmCC';
		this.tooltipText= 'load images only from this domain';
		break;
	}
}

this.PS=
 Components.classes['@mozilla.org/preferences-service;1']
 .getService(Components.interfaces.nsIPrefBranch);
this.ob={};
this.ob.observe=this.setState.bind(this);
this.PS.addObserver(this.pref,this.ob,false);
this.setState();

		]]>
	</constructor>
</implementation>

<handlers>
	<handler event="click" button="0" modifiers="any">
		<![CDATA[

switch(this.PS.getIntPref(this.pref)){
	case 1: this.PS.setIntPref(this.pref,2);break;
	case 2: this.PS.setIntPref(this.pref,3);break;
	case 3: this.PS.setIntPref(this.pref,1);break;
}

		]]>
	</handler>
</handlers>

Dark-Demon
Если честно -- влом даже разбираться, т.к. в 2.0.0.1 всё равно поправят, и я этот хак из след. версий уберу.
Ты бы лучше другие баги ковырял, коих немало. Например, добавил я в user.js:

user_pref("nglayout.debug.disable_xul_cache",true);
user_pref("javascript.options.showInConsole", true);
user_pref("javascript.options.strict", true);
user_pref("browser.dom.window.dump.enabled", true);

И при последующем запуске все твои кнопки перестали инициализироваться. В панели они есть (проверил через DOM-инспектор), а их не видно. (После этого мне и стало влом разбираться, куда bind пропал.)
И перезапускать браузер при каждом изменении кнопки -- это никуда не годится.
С юзабилити проблемы большие..

В панели они есть (проверил через DOM-инспектор), а их не видно.

ты ставил кнопки с моего сайта? или кастомкнопки?

И перезапускать браузер при каждом изменении кнопки -- это никуда не годится.

изменять можно не перезагружая, удалять уже тоже, но я эту версию ещё не выложил. вот с добавление - коряга. :(

Ты бы лучше другие баги ковырял, коих немало.

а ты strict отруби и ни одного не останется ;)

что-то addons.mozilla.org не хочет кушать моё расширение :(
а когда выходит версия 2.0.0.1?

Чёрт, опять не заметил твоё сообщение от 6 декабря.

ты ставил кнопки с моего сайта? или кастомкнопки?

С твоего сайта.

...вот с добавление - коряга.

Это вроде как основная функция. :)

а ты strict отруби и ни одного не останется wink

Не понял. Как strict мешает работе расширения?

что-то addons.mozilla.org не хочет кушать моё расширение sad
а когда выходит версия 2.0.0.1?

Не знаю.

Yan, strict никак не мешает работе, просто засоряет консоль.

ввиду того, что старое моё расширение под третьей лисицей не заработало, да и редактор давно уже хотел дописать сделал новую версию:
http://dark-demon.nm.ru/soft/customitem … ems3a1.xpi
тестировал под фф 3.0а6
после установки расширения в палитре можно найти демонстрационную кнопку. другие адаптированные под новую версию расширения кнопки можно найти тут: http://dark-demon.nm.ru/soft/customitems3/

из нововведений:
возможность перегружать стандартные кнопки
новый редактор с разделением всех xbl сущностей

особенности:
после добавления новой кнопки требуется перезагрузка %-\
убрал наследование, возможно потом верну

скриншот

Подниму-ка я тему. =)

Во-первых, нужна ли вообще настройка на скрытие кнопки «применить» в редакторе? Пусть она всегда видна будет, не мешает же.
Во-вторых, чисто визуально лучше смотрится, когда после нажатия видно, что «сохранилось» – т.е. кнопка становится неактивной.

Относительно универсальная схема примерно такая:

Выделить код

Код:

<dialog
onchange="changed(event);"
oncommand="changed(event);"
oninput="changed(event);"
ondragexit="changed(event);"

С ondragexit не совсем хорошо, я пару раз пытался выявлять факт перетаскивания текста иначе, но результатов не добился. :sick:

Далее два варианта.
1. Просто проверять event.target.localName и если, например, это не "tab", включать кнопку.
2. При каждой загрузке настроек и при каждом сохранении пробегать по всем (сохраняемым) элементам, и записывать их состояние (которое уже сохранено) в атрибут:
checked="true" -> saved_checked="true"
value="qqq" (точнее, свойство value) -> saved_value="qqq"
А в changed(event), соответственно, проверять, изменилось ли.

Самый точный вариант, но и самый медленный, если может быть большой текст (а он может).


Ну, и преимущество в том, что код мало зависит от структуры XUL и от того, как реализовано чтение/сохранение настроек.

P.S. И все же «Показывать кнопку "Применить" в редакторе кода», а не «Отобразить кнопку "Применить" в редакторе кода». Последнее больше применимо к однократному действию.

Во-первых, нужна ли вообще настройка на скрытие кнопки «применить» в редакторе? Пусть она всегда видна будет, не мешает же.

Если писать сразу в кнопку, то она будет пересоздаваться и инициализироваться при каждой записи.
А для отложенной записи нет инфраструктуры.

Во-вторых, чисто визуально лучше смотрится, когда после нажатия видно, что «сохранилось» – т.е. кнопка становится неактивной.

Относительно универсальная схема примерно такая:

Кажется, есть вариант попроще. nsIEditorObserver на редактор + анализ transactionManager. numberOfUndoItems

Anton пишет

Если писать сразу в кнопку, то она будет пересоздаваться и инициализироваться при каждой записи.

В основном сохранение нужно на случай, если выполненный по F9 код тем или иным образом не даст сохраниться.
А инициализацию можно запускать только если окно редактора теряет фокус.

Anton пишет

Кажется, есть вариант попроще. nsIEditorObserver на редактор + анализ transactionManager. numberOfUndoItems

Три редактора, два текстовых поля + хоткей, два чекбокса. И это после не особо внимательного осмотра.
Хотя если хочется точно знать, сохранено ли текущее состояние (скажем, если пользователь отменил все изменения), может, и проще.
И то наличие отмен не сильно связано с сохраненностью текста.

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

Выделить код

Код:

function x() {
    // some comment
    ...

Методика лечения примерно такая:

Выделить код

Код:

if(/^\s*\/\//m.test(block))
	block = block.replace(/^(\s*)\/\//mg, "$1");
else
	block = block.replace(/^/mg, "//");
Infocatcher пишет

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

Это не баг.
Ответственная за это функция предназначена для установки комментариев в начало строки и снятия их оттуда же.
Комментарии внутри строки имеют приоритет.

Удобнее, что ли, хм. Надо будет последить, что нужно чаще.
Разве что снимать «внутренние» комментарии при таком подходе неудобно.

http://forum.mozilla-russia.org/viewtop … 82#p364082
https://www.mozdev.org/bugs/show_bug.cgi?id=21391

Что вообще дает добавление оверлея через свой протокол кроме запрета кэширования?
Вроде как, там проблема в том, что компонента запускается позже, чем читается chrome.manifest. Так вот, может, есть смысл делать document.loadOverlay() после load/DOMContentLoaded окна или просто из подключенного к обычному оверлею скрипта?

13-08-2009 23:09:01
Хм, как-то странно оно себя ведет. По-моему, что-то не так с компонентой, реализующей протокол.

Что вообще дает добавление оверлея через свой протокол кроме запрета кэширования?

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

Так вот, может, есть смысл делать document.loadOverlay() после load/DOMContentLoaded окна или просто из подключенного к обычному оверлею скрипта?

Если надо "перекрывать" toolbarpalette это не будет работать.

Хм, как-то странно оно себя ведет. По-моему, что-то не так с компонентой, реализующей протокол.

И что же с ней "не так" ?

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

Кроме версий js это сейчас для чего-нибудь используется?

Если надо "перекрывать" toolbarpalette это не будет работать.

А когда подключается toolbarpalette?

И что же с ней "не так" ?

Ммм... она не работает. :D
А если серьезно, не знаю. Или что-то глобально не так с оверлеями по своему протоколу, раз идут глюки из-за того, что другое расширение меняет момент загрузки своих скриптов, или что-то не так в реализации протокола. Или баг в Firefox, наконец.
И можно ведь у автора ABP спросить, глядишь, присоветует чего.

Кроме версий js это сейчас для чего-нибудь используется?

Пока нет.

А когда подключается toolbarpalette?

Конструктор toolbox'а его удаляет из документа.

Ммм... она не работает. :D

Она-то как раз работает. Не работает chrome.manifest.

или что-то не так в реализации протокола.

Всё так.

И можно ведь у автора ABP спросить, глядишь, присоветует чего.

Уже посоветовал, за что я ему весьма благодарен. Оверлей с кнопками будет загружаться из resource://, селектор версий js - по-прежнему из custtombuttons://, но через loadOverlay (...)

Пока нет.

В том смысле, что есть планы использовать изменение контента, загружаемого по своему протоколу, для чего-то еще или просто может пригодиться?
И я не совсем понял, как проявляется баг, из-за которого нужно «руками» указывать версию js. Т.е. нельзя ли решить эту проблему не через одно место?

Конструктор toolbox'а его удаляет из документа.

До того, как запустятся скрипты расширений, так?
Тут, по идее, может помочь компонента навроде userChromeJS, если, конечно, есть подходящее событие, по которому можно запускаться.

Она-то как раз работает. Не работает chrome.manifest.

Т.е. это баг в реализации chrome.manifest?

или что-то не так в реализации протокола.

Всё так.

Тебе видней. =) Тем не менее, не стоило это исключать без веских оснований, а у меня их не было.

Уже посоветовал, за что я ему весьма благодарен. Оверлей с кнопками будет загружаться из resource://, селектор версий js - по-прежнему из custtombuttons://, но через loadOverlay (...)

Не совсем понимаю, что дает resource://, он что, тоже не кэшируется или можно сделать, чтобы не кэшировался?

Т.е. нельзя ли решить эту проблему не через одно место?

Без динамической подмены версии js как раз и будет "через одно место" - лишние записи в chrome.manifest, несколько оверлеев, слегка отличающихся только значением атрибута type. Это при том, что в chrome.manifest нет флага для platformversion.

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

Это значит, надо поставить observer на domwindowopened, когда он "поймает" окно, проверить, нужное ли это окно, поставить на окно обработчик некоего события, дождаться срабатывания обработчика и загрузить оверлей.
И ещё неизвестно, решит это проблему, или нет.

Т.е. это баг в реализации chrome.manifest?

Я разве что-нибудь говорил про "баг в реализации chrome.manifest" ?

Тебе видней. =) Тем не менее, не стоило это исключать без веских оснований, а у меня их не было.

Мдя... Ну я то ведь думал, что у тебя есть какие-то веские основания, раз ты это озвучиваешь.

что дает resource://, он что, тоже не кэшируется

Да, оверлеи через resource:// не кэшируются.

Anton пишет

Без динамической подмены версии js как раз и будет "через одно место" - лишние записи в chrome.manifest, несколько оверлеев, слегка отличающихся только значением атрибута type. Это при том, что в chrome.manifest нет флага для platformversion.

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

Выделить код

Код:

let x = 5;
alert(x);

, и он будет работать.
И

Выделить код

Код:

new Function("let x = 5; alert(x);")();

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

И ещё неизвестно, решит это проблему, или нет.

Если оверлей через resource:// решает проблему, нет смысла и проверять, понятно, что так сложнее.
Только можно ли при этом будет поставить CB в виде глобального расширения? Или будет использоваться что-то хитрее, чем
resource custombuttons-profile ../../custombuttons/
?

Хотя нет, еще же где-то должна определиться версия js. =/

Я разве что-нибудь говорил про "баг в реализации chrome.manifest" ?

А я и не утверждаю, что ты говорил. Но ведь баг есть. И он где-то находится. Так вот, где баг?

Мдя... Ну я то ведь думал, что у тебя есть какие-то веские основания, раз ты это озвучиваешь.

Я сказал, что «по-моему». К тому же, проявлялось все это довольно-таки странно. Например, у меня почему-то вываливалось исключение на document.loadOverlay() при использовании custombutton-протокола и при том, что в chrome.manifest все строки с custombutton:// были закомментированы.

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

2.0, xbl вызывает что-нибудь из скрипта, загруженного без указания версии.

А я и не утверждаю, что ты говорил. Но ведь баг есть. И он где-то находится. Так вот, где баг?

Я же сказал: не работает chrome.manifest

Infocatcher пишет

Например, у меня почему-то вываливалось исключение на document.loadOverlay() при использовании custombutton-протокола и при том, что в chrome.manifest все строки с custombutton:// были закомментированы.

При каких условиях ?

2.0, xbl вызывает что-нибудь из скрипта, загруженного без указания версии.

Н-ну, пусть xbl оповещает наблюдателя, что нужно выполнить код такой-то кнопки.

Я же сказал: не работает chrome.manifest

Это уже вопрос терминологии. Если что-то не работает, то или так и задумано, или это баг.

При каких условиях ?

Тот код не сохранился, потому как не давал нужного результата... =(
И еще может влиять наличие/отсутствие/установка ABP.

Пока пытался воспроизвести, убил все расширения:

Выделить код

Код:

## Firefox

overlay chrome://browser/content/browser.xul chrome://custombuttons/content/test.xul

overlay chrome://browser/content/browser.xul chrome://custombuttons/content/overlay.xul
#   overlay chrome://browser/content/browser.xul custombuttons://content/buttonsoverlay.xul

## Browser
#   overlay chrome://browser/content/browser.xul custombuttons://content/cbbutton.xul
overlay chrome://global/content/customizeToolbar.xul custombuttons://content/cbbutton.xul

test.xul:

Выделить код

Код:

<?xml version="1.0"?>
<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
	<script type="application/x-javascript">
	<![CDATA[

	document.loadOverlay("custombuttons://content/buttonsoverlay.xul", null);
	document.loadOverlay("custombuttons://content/cbbutton.xul", null);

	]]>
	</script>
</overlay>

А

Выделить код

Код:

window.addEventListener("load", function(e) {
	document.loadOverlay("custombuttons://content/buttonsoverlay.xul", null);
	document.loadOverlay("custombuttons://content/cbbutton.xul", null);
}, false);

тупо не дает никакого эффекта.

Правда, это все без установленного ABP.

А при установке ABP плюс

Выделить код

Код:

setTimeout(function() {
	document.loadOverlay("custombuttons://content/buttonsoverlay.xul", null);
	document.loadOverlay("custombuttons://content/cbbutton.xul", null);
}, 1000);

Firefox вообще падает при запуске. о_О
Закомментировал setTimeout и далее, тогда запустился.

Заодно нашел в userChromeJS коммент про https://bugzilla.mozilla.org/show_bug.cgi?id=330458.

Н-ну, пусть xbl оповещает наблюдателя, что нужно выполнить код такой-то кнопки.

Эта идея требует тщательного обдумывания.
Может быть, когда-нибудь потом, но не сейчас.

Это уже вопрос терминологии.

Первоначальный вопрос, напомню, был "Что не так с компонентой" : )

Firefox вообще падает при запуске. о_О

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

Эта идея требует тщательного обдумывания.
Может быть, когда-нибудь потом, но не сейчас.

Если уже все починилось, то это не приоритетно, разумеется. Однако это мне видится несколько более простым подходом, чем правка оверлея «на лету».

Первоначальный вопрос, напомню, был "Что не так с компонентой" : )

Бррр... так я совсем запутаюсь.
Итого: компонента работает, chrome.manifest – нет.
А я имел в виду, что раз проблема в chrome.manifest, в нем и баг, точнее, в том, как этот файл обрабатывается при запуске приложения.
В общем, проехали.

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

Вполне возможно, там в комментах к багу есть хитрый код для загрузки нескольких оверлеев (var overlay_loader= ...) и, вроде как, с observer'ом тоже баг:

Выделить код

Код:

observe: function(subject,topic,data)
    {
    // don't bother to do anything because we cannot
    // guarantee that this observer will be called anyway
    }

Однако это мне видится несколько более простым подходом, чем правка оверлея «на лету».

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

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

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

А биндинги нельзя повесить вручную

Уже не надо. Вот так: http://www.mozdev.org/source/browse/custombuttons/src/chrome/custombuttons/content/custombuttons/tcbbutton.xul?rev=1.1.8.2;content-type=text%2Fplain;f=h работает.
Не нравится, правда, что в некоторых случаях (http://forum.mozilla-russia.org/viewtopic.php?pid=282054#p282054) это может зависеть от порядка следования элементов <script>

А если как-то так:

Выделить код

Код:

<script type="application/x-javascript;version=1.8" src="chrome://custombuttons/content/cbbutton-loader.js"/>
<script type="application/x-javascript;version=1.7" src="chrome://custombuttons/content/cbbutton-loader.js"/>
<script type="application/x-javascript;version=1.6" src="chrome://custombuttons/content/cbbutton-loader.js"/>
<script type="application/x-javascript" src="chrome://custombuttons/content/cbbutton-loader.js"/>

cbbutton-loader.js:

Выделить код

Код:

if(!("custombuttonsLoaded" in window)) {
	Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
		.getService(Components.interfaces.mozIJSSubScriptLoader)
		.loadSubScript("chrome://custombuttons/content/cbbutton.js");
	window.custombuttonsLoaded = true;
}

?
(И перечислять версии от новых к старым.)

Infocatcher пишет

А если как-то так:

Выделить код

Код:

<script type="application/x-javascript;version=1.8" src="chrome://custombuttons/content/cbbutton-loader.js"/>
<script type="application/x-javascript;version=1.7" src="chrome://custombuttons/content/cbbutton-loader.js"/>
<script type="application/x-javascript;version=1.6" src="chrome://custombuttons/content/cbbutton-loader.js"/>
<script type="application/x-javascript" src="chrome://custombuttons/content/cbbutton-loader.js"/>

cbbutton-loader.js:

Выделить код

Код:

if(!("custombuttonsLoaded" in window)) {
	Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
		.getService(Components.interfaces.mozIJSSubScriptLoader)
		.loadSubScript("chrome://custombuttons/content/cbbutton.js");
	window.custombuttonsLoaded = true;
}

?
(И перечислять версии от новых к старым.)

Не пойму, в чём суть.

Не пойму, в чём суть.

Суть в том, что скрипты из chrome://custombuttons/content/cbbutton.js гарантированно выполнятся только один раз и с наибольшей версией js. Ну, в теории. =)

Суть в том, что скрипты из chrome://custombuttons/content/cbbutton.js гарантированно выполнятся только один раз и с наибольшей версией js. Ну, в теории.

Ну, может быть.

Anton пишет

Впрочем, можешь пировать победу над селектором версий

Какая фраза!

Прошу пардона, а с селектором стиль-тема все глухо пока?

Al_H
http://forum.mozilla-russia.org/viewtopic.php?pid=359992#p359992

Размышляю по поводу http://forum.mozilla-russia.org/viewtopic.php?pid=365834#p365834
Стоит или не стоит добавлять в "api" что-нибудь вроде sendKey, и если стоит, какая у этой функции должна быть сигнатура ?

Anton пишет

Стоит или не стоит добавлять в "api" что-нибудь вроде sendKey

Ну, самый удобный вариант – это как в Mouse Gestures Redox, чтобы с диалогом. Но количество кода для реализации плохо соотносится с получаемой пользой, по-моему. А в противном случае не особо ясно, куда там сокращать код – и так не много, а тем, кто «в курсе» – наоборот труднее будет, с нестандартной функцией-то (а в код расширения лезть, разумеется, лень :D).
К тому же, вроде бы, что-то может реагировать на keyup. Или тогда всю последовательность keydown -> keypress -> keyup эмулировать.
Вот как-то так:

Выделить код

Код:

custombuttons.dispatchKeyEvent(
	["keydown", "keypress", "keyup"],
	true /*ctrlKey*/, false /*altKey*/, false /*shiftKey*/, false /*metaKey*/,
    "VK_SPACE"
);

20-08-2009 20:30:06
А, может, custombuttons.sendKey и лучше будет.
При желании можно и просто sendKey, если передавать эту функцию в виде аргумента.

Ну, я предполагал по типу ms wsh object. sendKeys (string)
Примерно sendKey (key[, object])
Но, наверное, не такая уж востребованная функция.

startProcess часто используется, как будто бы, но не знаю, как она работает в не-windows системах.

Мне тут про деструкторы кнопок подумалось.
А не достаточно ли просто перед каждым вызовом инициализации проверять, есть ли у кнопки метод destroy, и запускать его при наличии. Ну, а при unload окна пусть этот метод вызывается из XBL-деструктора.

Примерно в таком духе:

Выделить код

Код:

var button = ...;
if("destroy" in button && (!("hasOwnProperty" in button) || button.hasOwnProperty("destroy")))
	button.destroy.call(button); // Кнопка уже была инициализирована и определила метод "destroy"
try {
	new Function("arg0,arg1", button.getAttribute("cb-init")).call(button, arg0, arg1);
}
...

(А destroy может всплыть от Object.prototype, а также можно сделать this.__proto__ = null; в инициализации кнопки.)

перед каждым вызовом инициализации проверять, есть ли у кнопки метод destroy

В конструкторе такая проверка есть давно.

а также можно сделать this.__proto__ = null; в инициализации кнопки.

: )
И как потом быть с интерфейсом nsIDOMNode ?

Anton пишет

В конструкторе такая проверка есть давно.

Хы, а я как-то только про потерявшиеся XBL-деструкторы осознал, а прочие эффекты или пропустил, или не уловил из пояснений.
А проверить поленился. =)

И как потом быть с интерфейсом nsIDOMNode ?

Туго без него, ага. Пожалуй, все равно без Object.prototype в начале цепочки прототипов ничего полезного не получится.

P.S. Странно, не вызывается this.destroy.
Инициализация:

Выделить код

Код:

this.clickHandler = function() {
	setTimeout(function() { throw "Click"; }, 0);
}
window.addEventListener("click", this.clickHandler, true);
this.destroy = function() {
	alert("destroy");
	window.removeEventListener("click", this.clickHandler, true);
};
var _this = this;
window.addEventListener("dblclick", function f() {
	window.removeEventListener("dblclick", f, true);
	setTimeout(function() { throw "dblclick -> destroy()"; }, 0);
	_this.destroy();
}, true);

Или я снова что-то не учел?

26-08-2009 19:56:44
P.P.S. Увидел, что контекст выполнения в destroy() не передается. Но это в данном случае не важно – alert все равно не выскакивает.

26-08-2009 20:04:18
Ну, и с вот таким кодом – тоже не вызывается:

Выделить код

Код:

this.clickHandler = function() {
	setTimeout(function() { throw "Click"; }, 0);
}
var _this = this;
window.addEventListener("click", this.clickHandler, true);
this.destroy = function() {
	alert("destroy");
	window.removeEventListener("click", _this.clickHandler, true);
};
window.addEventListener("dblclick", function f() {
	window.removeEventListener("dblclick", f, true);
	setTimeout(function() { throw "dblclick -> destroy()"; }, 0);
	_this.destroy();
}, true);
Infocatcher пишет

Странно, не вызывается this.destroy.

Ну так деструктора в toolbarbutton.xml нет - кто его позовёт ? : )

Anton пишет

Ну так деструктора в toolbarbutton.xml нет - кто его позовёт ? : )

Речь шла о пересоздании кнопки aka кнопка Применить в редакторе.
Т.е. destroy средствами CB вообще никогда не вызывается. Или я как-то не так тестирую.

26-08-2009 21:05:46
Это я вот это тестирую:

перед каждым вызовом инициализации проверять, есть ли у кнопки метод destroy

В конструкторе такая проверка есть давно.

Infocatcher пишет

Т.е. destroy средствами CB вообще никогда не вызывается.

Ну почему не вызывается - при удалении кнопки вызывается. При инициализации не вызывается, это верно. Как верно и то, что в конструкторе есть вызов destroy : )

С деструкторами я запамятовал - задумывалось, что штатным обработчиком кнопки будет onDestroy, а destroy - это служебная функция в cbbuttonimpl.js.
Но раз уж это случилось, теперь будут два штатных обработчика - destroy/onDestroy.

А еще может быть ondestroy. =)
А штатный обработчик, по-моему, лучше делать, например, в виде cbDestroy. Впрочем, уже и так весьма разнообразно и нету какого-то особенного отличительного признака у «внутренних» полей.

Кстати, можно еще передавать в функцию-деструктор параметр, определяющий, удаление это или обновление кода.


И несколько идей касательно интерфейса.

1. «Кнопка была успешно создана. Вы можете добавить её на любую панель инструментов через меню "Вид -> Панели инструментов -> Настроить..."»
Можно заменить многоточие одним юникодным символом (…) – по аналогии с надписями в самом Firefox. И остальных местах тогда тоже заменить.

И, мне кажется, удобнее сделать как-то так:
v Больше не показывать это сообщение
[Ok] [Настроить…]

[Настроить…] открывает диалог настройки панелей инструментов.

2. «Обновить кнопку " ... " кодом кнопки " ... " ?»
Аналогично:
[Ok] [Редактировать…] [Отмена]

Собственно, хотя вряд ли кто проверяет, но запускать что-то там, не видя кода, как-то не особо. =)

3. Не прикрутить ли контекстное меню к диалогу настройки панелей инструментов? И там, соответственно, как минимум, «редактировать» и «удалить».


[UPD]
Немного подкорректировал.

Infocatcher
Постараюсь не забыть.

Мне тут подумалось, что хорошо бы сделать возможность редактирования произвольной кнопки (а не той, что видна и с контекстным меню).
А то пару раз уже приходилось делать разные финты ушами из-за неточностей в коде, делавших недоступной или саму кнопку, или контекстное меню.
Тут мне видятся два пути – или «редактор редакторов» со списком всех кнопок, или возможность выбора редактируемой кнопки в уже имеющемся редакторе.

И, пожалуй, не помешает возможность отключения инициализации кнопок при запуске. Мало ли, что там, не руками же из-за этого XML'ку править. Можно и руками, конечно, но только удалять – править уже муторно.
Например, при запуске с неким параметром командной строки (как в Stylish).


Также при поиске по Ctrl+/ хочется навигации по результатам через Enter/Shift+Enter или стрелки вниз/вверх (а то Enter мимо поля закроет диалог).
И, возможно, не стоит закрывать диалог поиска по Ctrl+F (не припомню ни одного примера, чтобы подобные окошки сразу закрывались).

Infocatcher

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

Я помню про контекстное меню в диалоге настройки панелей инструментов.
И не только меню.
В этом году уже вряд ли сделаю, в чём винюсь конечно, но ничего не поделаешь.

возможность отключения инициализации кнопок при запуске. Мало ли, что там, не руками же из-за этого XML'ку править. Можно и руками, конечно, но только удалять – править уже муторно.
Например, при запуске с неким параметром командной строки (как в Stylish).

Если будут предложения по наименованию параметра командной строки - готов рассмотреть, если нет - придумаю сам : )

Также при поиске по Ctrl+/ хочется навигации по результатам через Enter/Shift+Enter или стрелки вниз/вверх (а то Enter мимо поля закроет диалог).
И, возможно, не стоит закрывать диалог поиска по Ctrl+F (не припомню ни одного примера, чтобы подобные окошки сразу закрывались).

Вот насчет первого - не знаю. Есть ведь навигация по F3/Shift+F3. Завершение по Enter - почти как в Emacs, вроде удобно. А "Enter мимо поля закроет диалог" - это как воспроизвести ?
Насчёт второго - может быть, но за пример брал PSPad, там именно так. Дальше можно по F3/Shift+F3.

Я помню про контекстное меню в диалоге настройки панелей инструментов.

И это тоже. Но меня тут угораздило чуть промахнуться с кодом и скрыть кнопку «пользовательским» стилем (да еще и с important-флагом). К счастью, промахнулся я не до конца, и кнопку можно было показать добавлением атрибута.

Если будут предложения по наименованию параметра командной строки - готов рассмотреть, если нет - придумаю сам : )

Ну, «custombuttons» там должно в любом случае присутствовать. =)
Что-то вроде «-custombuttons-disable-initialization», хотя и длинновато.
Или даже «-custombuttons-safe-mode».
Первое лучше отражает суть, второе – понятнее для «непосвященных».
Возможно, второй вариант практичнее – вдруг когда-нибудь потом понадобится отключать что-то еще. Те же хоткеи. Допустим, стороннее расширение устраивает вечный полноэкранный режим, а выход из него – только переназначенным через CB хоткеем. Пример сферичен, конечно (к тому же, встроенный -safe-mode должен позволить все лишнее поотключать), но мало ли.

Есть ведь навигация по F3/Shift+F3.

А тут простой пример в лице поиска в Firefox. (Shift+)F3 есть, но есть и (Shift+)Enter.

А "Enter мимо поля закроет диалог" - это как воспроизвести ?

Там же <dialog>, и если не перехватить нажатие Enter, то он выполнит умолчальное действие (эквивалент нажатия на Ok) и закроется. А разный эффект от одного и того же действия далеко не всегда удобен.

Насчёт второго - может быть, но за пример брал PSPad, там именно так. Дальше можно по F3/Shift+F3.

Тогда не знаю. Или вот настройку добавить – для привыкших к иному поведению или сторонников орудовать мышкой. =)
С тем же успехом можно добавить галочку для учета регистра на панель быстрого поиска.

P.S.

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

Торопиться особо некуда. Было бы определенное сочетание необходимости и наличия свободного времени, сам бы докрутил что-нибудь. =) Но я же ленюсь. :D

15-12-2009 18:21:01
Заодно небольшой баг:
Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.1.5) Gecko/20091204 Thunderbird/3.0
65def966cc61.png

sizeToContent(), что ли, делать...

И, раз уж на то пошло, в заголовке хочется написать «Custom Buttons: ...».

Там же <dialog>, и если не перехватить нажатие Enter, то он выполнит умолчальное действие (эквивалент нажатия на Ok) и закроется. А разный эффект от одного и того же действия далеко не всегда удобен.

Не понимаю.
По Ctrl+/ открывается поле поиска, фокус передается ему.
По Enter поле поиска закрывается.
Без разного эффекта для Enter не обойтись всё равно, потому что в кодовых textbox'ах Enter должен вставлять перевод строки.

sizeToContent(), что ли, делать...

Он там есть, по onload и по oncommand. Правда, почему-то по onload в Thunderbird 3 не срабатывает.
Ладно, разберусь.

Не понимаю.

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

Кстати, еще разумно подхватывать выделенный текст при нажатии Ctrl+/.

15-12-2009 19:12:32

Правда, почему-то по onload в Thunderbird 3 не срабатывает.

Видимо, баг.

Как-то так:

Выделить код

Код:

sizeWindowToContent: function (forced)
 {
  ...
  window. sizeToContent ();
  if (forced)
   setTimeout(window. sizeToContent, 0);
 },


 onLoad: function ()
 {
  ...
  this. sizeWindowToContent (true);
 },

Кривовато (и дергается) :|, но зато работает.

навигация по результатам поиска стрелками (когда фокус на поле для поиска) удобнее – эффект от нажатия стрелок не там, где предполагалось, менее критичен.

Вроде понял.

Как-то так:

Вроде бы когда-то так было, не помню.

Интересно это работает.
Если this. sizeWindowToContent (true); "утащить" в начало onLoad(), то в Thunderbird с размером диалога всё будет в порядке, но в Firefox диалог настроек будет заметно выше, т. к. чекбокс ещё не будет скрыт.
Если поставить два вызова this. sizeWindowToContent (true); - в начале и в конце onLoad(), в Thunderbird будет то же самое, что и с одним в конце.

Вроде понял.

И еще раз про то же, но с другого бока.
Основная мысль: хорошо, когда поиск работает так же, как и в браузере (а там можно перемещаться по результатам по Enter/Shift+Enter).
Однако окно браузера не закроется, если случайно нажать Enter не в поле для поиска.
Ну, и отсюда вывод, что можно и стрелками перемещение делать – все равно ничего дельного при нажатии вниз/вверх не происходит.

Интересно это работает.

Это еще хорошо, что XUL там не сложный. При наличии скроллбоксов бывает интереснее.
Еще можно попробовать показывать/скрывать все, что нужно, по DOMContentLoaded (или добавить вызов функции в самом конце DOM-дерева), а sizeToContent вызывать все так же по load.

Однако окно браузера не закроется, если случайно нажать Enter не в поле для поиска.

Опять двадцать пять : )
Поиск реализует редактор, а не диалог.
В редакторе с Enter'ом всё в порядке, я настаиваю : )

В редакторе с Enter'ом всё в порядке, я настаиваю : )

А я не спорю. Вроде бы. :D
В любом случае фокусы реализует уже пользователь.

Кстати, а как насчет пункта контекстного меню для создания пустой кнопки – как клонирование, только без переноса свойств?

Кстати, а как насчет пункта контекстного меню для создания пустой кнопки – как клонирование, только без переноса свойств?

Не хотелось бы добавлять в контекстное меню. Подумаю.

Не хотелось бы добавлять в контекстное меню. Подумаю.

А если изменить поведение клонирования при клике средней кнопкой мыши?

Infocatcher

А если изменить поведение клонирования при клике средней кнопкой мыши?

Может быть. Или Shift/Ctrl+Left click.

okkamas_knife
Это к автору кнопки.

Anton пишет

Может быть. Или Shift/Ctrl+Left click.

Лучше «и». Кликать без участия клавиатуры удобнее. Но на случай отсутствия средней кнопки лучше предусмотреть запасной вариант.
А правую кнопку для контекстных меню лучше не использовать. Точнее, не получится даже посто так – будет срабатывать oncommand. Ну, и в том же Linux контекстное меню открывается сразу по нажатию на ПКМ (без отпускания), а в таком случае удобно отпускать кнопку уже на нужном пункте внутри меню.

Меня тут попросили реквест передать...

Так сказать, несколько доработанная идея.
Хорошо бы добавить в редактор кнопку «протестировать», которая бы пересоздавала кнопку без сохранения настроек с возможностью отмены.
По идее, с пересозданием кнопки проблем возникнуть не должно – достаточно пропустить сохранение файла (или обновить напрямую на основании данных редактора – лень смотреть, как там сейчас делается). С отменой сложнее. Наверное, считывать параметры из файла (мы же его не сохранили).
Как вариант – две кнопки: «протестировать» и «отменить», причем вторая становится активной только если если есть, что отменять. Разве что нехорошо, что уже есть стандартная кнопка отмены, закрывающая диалог. А две схожих кнопки как-то не особо смотрятся. Впрочем, undo и cancel. =)

И еще один неудобный момент – хорошо бы иметь возможность и отмены, и сохранения на случай вылета программы или каких других сбоев.

Или вот при сохранении во время редактирования сохраняться во временный файл. При нажатии на Ok файл удалять, а изменения записывать в основной файл, а при отмене – тоже удалять и считывать данные из основного файла. Причем даже имена для файлов есть – что-нибудь + номер кнопки.
Но тогда нужно при запуске проверять, нет ли таких временных файлов, а если есть – предлагать открыть их на редактирование.

Вот как-то так. :|

26-01-2010 01:11:04
Мне тут подсказывают, что путано излагаю. :D
Если кратко, то нужна возможность посмотреть, как работает код, а потом, если не понравилось, вернуть всё назад.
Остальное – детали.

Да, а для отмен можно делать один файл, аналогичный по структуре основному файлу настроек. Тогда проще проверять при запуске, не было ли падения – по наличию файла (который удалился бы при успешном закрытии редактора). Ну, и проверять при закрытии, нету ли еще открытых редакторов, и если нет – удалять временный файл. Или уже при закрытии браузера удалять, что проще, наверное – насколько я помню, можно подписаться на оповещение о соответствующем событии.

26-01-2010 01:16:55

правда я ещё вот ругался на то что кнопка "применить" означает "сохранить", и что лучше бы её переименовать в таковую)

okkamas_knife
Очень просто, без создателей кнопок не будет большинства. =) И, думается, некоммерческие вещи пишутся для самих себя, так что тут польза очевидна :D – все упирается в то, насколько сложно реализовать ту или иную идею.

И не все кнопки могут существовать в двух экземплярах одновременно.

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

Infocatcher

Меня тут попросили реквест передать...

Ок, закину в todo.

okkamas_knife пишет

а вот для удобства разработки думаю неплохо былобы добавить к этому редактору возможность висеть поверх окна ФФ чтоб при проверке кнопке окно редактирования не пряталось.

Проще не разворачивать окно на весь экран.

На правах развлекательства: http://forum.mozilla-russia.org/uploade … +tb+sb.xpi
Искать «//~added».

Суть:

Выделить код

Код:

toggleOnTop: function() {
  var ci = Components.interfaces;
  var xulWin = window.QueryInterface(ci.nsIInterfaceRequestor)
   .getInterface(ci.nsIWebNavigation)
   .QueryInterface(ci.nsIDocShellTreeItem)
   .treeOwner
   .QueryInterface(ci.nsIInterfaceRequestor)
   .getInterface(ci.nsIXULWindow);
  var normal = xulWin.zLevel == xulWin.normalZ;
  xulWin.zLevel = normal ? xulWin.highestZ : xulWin.normalZ;
  document.getElementById("toggleOnTop").setAttribute("checked", normal);
 }

Распихивать текст по локалям лениво, ибо это только концепт.
Например, у себя я пробую вот так:

Выделить код

Код:

var s = top.document.documentElement.style;
if(normal) {
    s.outline = "2px groove " + (this.pu.pref("ui.onTopBorderColor") || "orange");
    s.outlineOffset = "-2px";
}
else {
    s.outline = "";
    s.outlineOffset = "";
}

И, увы, это отличается от системного onTop в Windows.

CB 0.0.4.7
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.2pre) Gecko/20100224 Namoroka/3.6.2pre
+ тема по умолчанию

ec504ed9afeb.png

А если добавить class="menuitem-iconic", то уже нормально (добавлено только к первому пункту):
b87977df758d.png

А причина – в

Выделить код

Код:

menuitem[id^="custombuttons-contextpopup-"] {
   -moz-binding: url("chrome://global/content/bindings/menu.xml#menuitem-iconic") !important;
}

и в

Выделить код

Код:

menu.menu-iconic > .menu-iconic-left,
menuitem.menuitem-iconic > .menu-iconic-left {
  -moz-appearance: menuimage;
  padding-top: 2px;
}

из chrome://global/skin/menu.css (берется из firefox/chrome/classic.jar!/skin/classic/aero/global/menu.css)

25-02-2010 02:10:02
И в русской локали вылезают accesskeys (в скобках после названий/меток) на английском...

25-02-2010 02:11:21
Скажем,

Выделить код

Код:

<!ENTITY editor.name "Имя:">
<!ENTITY editor.name.accesskey "N">

выводится как

Имя (N):

Смотрится не особо.

Infocatcher

А если добавить class="menuitem-iconic", то уже нормально

Хорошо, добавлю.

И в русской локали вылезают accesskeys (в скобках после названий/меток) на английском...Смотрится не особо.

Как сделать лучше ?
С одной стороны - единый и независимый от текущей локализации и раскладки интерфейс.
С другой - лишние буквы в скобках.

Anton пишет

С другой - лишние буквы в скобках.

С той же стороны еще есть отсутствие прямой связи accesskey с текстом, а также отсутствие подобного в других местах.
А на MDC только про японскую локаль отступление: https://developer.mozilla.org/En/XUL_Tu … sskey_text.
Меня вот больше непривычный вид смущает.

Вроде бы, для всяких там независимостей правильнее использовать «обычные» хоткеи. :|

Может быть, даже есть смысл реагировать на Ctrl+Вниз и Ctrl+Вверх (или что-то вроде того) как на Tab и Shift+Tab, раз уж Tab перехватывается.
Заодно неприятная мелочь: Shift+Tab не позволяет уйти из поля для ввода картинки.

Infocatcher пишет

С той же стороны еще есть отсутствие прямой связи accesskey с текстом, а также отсутствие подобного в других местах.
А на MDC только про японскую локаль отступление: https://developer.mozilla.org/En/XUL_Tu … sskey_text.
Меня вот больше непривычный вид смущает.

Вроде бы, для всяких там независимостей правильнее использовать «обычные» хоткеи. :|

Это ведь редактор кода, а код набирается в en-раскладке. Если локализовать горячие клавиши, то наверняка перед (и после) их использованием потребуется сменить раскладку. Три "распальцовки" -  уже не так быстро как одна.

Может быть, даже есть смысл реагировать на Ctrl+Вниз и Ctrl+Вверх (или что-то вроде того) как на Tab и Shift+Tab, раз уж Tab перехватывается.

Кроме Tab/Ctrl+Tab работает ещё Ctrl+PgUp и Ctrl+PgDn. Но эти сочетания реализуют последовательный доступ к вкладкам, а не произвольный, и работают не из любой точки редактора.

Заодно неприятная мелочь: Shift+Tab не позволяет уйти из поля для ввода картинки.

Понятно, буду разбираться.

Anton пишет

Это ведь редактор кода, а код набирается в en-раскладке. Если локализовать горячие клавиши, то наверняка перед (и после) их использованием потребуется сменить раскладку. Три "распальцовки" -  уже не так быстро как одна.

Если accesskeys на английском работают из любой раскладки, а на русском – только на русской, то это уже баг. =/ Там вообще странно как-то – по-моему, еще есть разница, как идет русификация – изначально или в виде языкового пакета.
Вот, скажем, Alt+Ф (Файл) у меня не работает на английской раскладке. В редакторе, видимо, будет также. Тогда надо бы поискать баг на тему, а accesskeys пока оставить как есть.

Infocatcher пишет

Вот, скажем, Alt+Ф (Файл) у меня не работает на английской раскладке. В редакторе, видимо, будет также.

В редакторе так и есть, о чем я и говорил.
Может быть, сделаю Ctrl+1/2/3/4, хотя это мне кажется менее удобным чем Alt+буква
Или скрою accesskeys из меток.

Anton пишет

Может быть, сделаю Ctrl+1/2/3/4, хотя это мне кажется менее удобным чем Alt+буква

Это и правда менее удобно. И все равно останутся лишние символы в скобках.

Anton пишет

Или скрою accesskeys из меток.

Хм, не знал, что они скрываются.
Есть только кривая идея приписать в редакторе что-нибудь вроде <label cb_accesskey="x" /> и реализовывать фокусирование на контролах самостоятельно. Плюс сделать настройку, чтобы можно было заменить cb_accesskey на accesskey. Но есть большие сомнения в целесообразности таких выкрутасов.

Infocatcher пишет

Хм, не знал, что они скрываются.

Это можно сделать множеством способов. Ну, хотя бы добавив <key> и удалив accesskey.

А как насчет принудительного отображения контекстного меню по (редкоиспользуемые модификаторы)+правоклик?
Что-нибудь вроде вот такого:

Выделить код

Код:

window.addEventListener("click", function(e) {
    if(e.button == 2 && e.ctrlKey && e.shiftKey && e.altKey) {
        var tar = e.originalTarget;
        if(
            "id" in tar && tar.id.indexOf("custombuttons-button") == 0
            && navigator.preference("custombuttons.mode") & 64
        ) {
            e.preventDefault();
            e.stopPropagation();
            var cm = document.getElementById("custombuttons-contextpopup");
            document.popupNode = tar.ownerDocument.popupNode = tar;
            if("openPopupAtScreen" in cm) // Firefox 3.0+
                cm.openPopupAtScreen(e.screenX, e.screenY, true /*isContextMenu*/);
            else
                cm.showPopup(e.target, e.clientX, e.clientY, "context", "none", "none");
        }
    }
}, true);

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

Тестовая кнопка:

Выделить код

Код:

this.oncontextmenu = this.onclick = function(e) {
    e.preventDefault();
    e.stopPropagation();
};

Правда, можно отключить инициализацию, но зато тут без переоткрытия окна получается. И хорошо бы выяснить, как там на Маках с наличием клавиш-модификаторов.

Infocatcher пишет

И хорошо бы выяснить, как там на Маках с наличием клавиш-модификаторов.

http://support.apple.com/kb/HT1343?viewlocale=ru_RU&locale=ru_RU

Как будто бы все в наличии.

Anton
а можно ли как-то твой аддон сделать совместимым с отличным editor-ом Stylish Custom? это аддон-надстройка для основного аддона (Stylish) и в нём всё сделано адски удобно. Велосипед изобретать не за чем и можно было бы конечно даже просто скопировать его функционал, но наилучшим бы вариантом было б просто сделать эти 2 аддона совместимыми.
Вообще, с чьей стороны в данном случае надо прилагать усилия? Со стороны автора Stylish Custom или же можно как-то аддон CustomButtons подправить?
Если идея покажется тебе интересной - я готов посодействовать в разговорах и налаживании связи с автором Stylish Custom.

iDev.Pi пишет

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

Под "совместимостью" понимается возможность использования Custom Buttons для настройки панели инструментов редактора Stylish Custom ?

Пока что Custom Buttons не позволяет настраиваться на использование в произвольных окнах.
Может быть, в будущем этот функционал будет как-нибудь реализован, но не скоро.

Anton пишет

Под "совместимостью" понимается возможность использования Custom Buttons для настройки панели инструментов редактора Stylish Custom ?

iDev.Pi предлагает наоборот — использовать навороченную форму редактирования из Stylish-Custom для правки кода в Custom Buttons.

Anton,
как уже верно подсказали Sid и okkamas_knife - я как раз имел ввиду возможность использования Stylish Custom редактора для редактирования кнопок CustomButtons.
Я подобный вопрос задал и ChoGGi, автору Stylish Custom, и его ответ немного огорчил: он сказал, что очень маловероятно что он сделает такое, вот если бы КБ был больше похож на стайлиш...  тем не менее, я попросил составить примерный список того, что должно быть изменено, может быть всё же окажется это вовсе не таким уж и трудоёмким делом, ведь часть функций вроде экспорта-импорта, по крайней мере на первое время, и не надо, пока больше всего нужны просто удобности того редактора.

Вобщем, ChoGGi хоть и очень неохотно отозвался, но вроде согласился сделать отдельный редактор для КБ на основе функционала Stylish Custom. Подождём - увидим.

iDev.Pi пишет

как уже верно подсказали Sid и okkamas_knife - я как раз имел ввиду возможность использования Stylish Custom редактора для редактирования кнопок CustomButtons.

Если честно, не вижу смысла.

Какой функционал редактора Stylish Custom нужен в Custom Buttons ?

Поиск есть, целых два. Обычный (Ctrl+F) и по мере набора (Ctrl+/).
Поиск уже найденного вперед/назад есть (F3/Shift+F3).
Переход к строке есть (Ctrl+G).
Сворачивание строк есть (Ctrl+W).
Комментирование выделенного участка кода есть (Ctrl+Shift+A).

Есть выравнивание выделенного кода по Tab/Shift+Tab, есть даже замена (Ctrl+H).
По F11 можно свернуть/развернуть окно редактора, по F9 - выполнить код существующей кнопки.

Я Stylish не пользуюсь, поэтому, может быть что-то упустил в сравнении, поправьте если так.

Anton
там сделано:
удобная система сохранения (флэшбэки)
скрэтчпад - пустой текстареа, который можно использовать как что-то типа временного буфера
wrap/unwrap кода - вкл/выкл переноса строк
быстрое закомментирование куска кода
соединение строк разделённых брейком
отображает позицию курсора по оси у (строка) и х (символ)
ну и продуманное (+настраиваемое) поведение диалоговых окон при закрытии основного окна например (если в код с посл. момента сохранения были внесены изменения, то при закрытии он спросит у пользователя что делать - сохранить ли изменения или вернуться к предыдущему изменению, проигнорировав все последовавшие после этого изменения)

вот больше всего в КБ не хватает именно продуманного сохранения и правильного поведения диалоговых окон, остальное - уже мелочи

вообще там ещё много вкусностей вроде грамотного apply-unapply или заливки кода на сайт в 1 клик

и на всякий случай уточню: Stylish и Stylish Custom - это 2 разных дополнения, 2-ое - обвеска для 1-ого.

Совсем забыл.
http://forum.mozilla-russia.org/viewtop … 14#p415514:

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

И далее.

Очень странно реагирует на любые (?) модальные сообщения в инициализации.

Что интересно, вне CB не воспроизводится.

Infocatcher пишет

Совсем забыл.
http://forum.mozilla-russia.org/viewtop … 14#p415514:

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

И далее.

Очень странно реагирует на любые (?) модальные сообщения в инициализации.

Это не проблема CB.

Что интересно, вне CB не воспроизводится.

Конечно.

Anton пишет

Это не проблема CB.

Это понятно. Просто правильнее найти/создать баг в багзилле.

Вроде, недавно появилось: при сохранении сбрасывается позиция прокуртки в редакторе.

Посмотрел, в 0.0.4.8 появилось.

Infocatcher пишет

Вроде, недавно появилось: при сохранении сбрасывается позиция прокуртки в редакторе.

Спасибо, исправил.