Active theme observer (Firefox 4.0 и выше)
Автор: hydrolizer
Описание: добавляет атрибут activetheme с id и версией активной темы к корневым элементам xul-разметки окон для последующего использования атрибута в селекторах CSS-стилей. Таким образом, позволяет сделать привязку стиля оформления к активной теме оформления. Содержимое атрибута формируется из id+версии темы (между id и версией символов-разделителей нет, никакие символы из строк id и версии не удаляются, и не заменяются - т.е. строки берутся, как есть). Весь код кнопки состоит из кода инициализации, однако сама кнопка по нажатию на неё убирает со всех открытых на момент нажатия окон атрибут темы, и выключает слежение за открывающимися окнами - т.е. окна, открытые после нажатия кнопки, атрибута темы иметь не будут. Для повторного навешивания атрибута необходим рестарт FF. Содержимое атрибута темы при его навешивании выводится в консоль.

Кнопка:

Выделить код

Код:

custombutton://%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%0D%0A%3Ccustombutton%20xmlns%3Acb%3D%22http%3A//xsms.nm.ru/custombuttons/%22%3E%0A%20%20%3Cname%3EActive%20Theme%20Observer%3C/name%3E%0A%20%20%3Cimage%3E%3C%21%5BCDATA%5Bcustombuttons-stdicon-1%5D%5D%3E%3C/image%3E%0A%20%20%3Cmode%3E0%3C/mode%3E%0A%20%20%3Cinitcode%3E%3C%21%5BCDATA%5B/*Initialization%20Code*/%0AComponents.utils.import%28%22resource%3A//gre/modules/Services.jsm%22%29%3B%0Avar%20themesObserver%3D%0A%7B%0A%09init%3A%20function%28%29%0A%09%7B%0A%09%09Components.utils.import%28%22resource%3A//gre/modules/AddonManager.jsm%22%29%3B%0A%09%09AddonManager.getAddonsByTypes%28%5B%22theme%22%5D%2C%28function%28addons%29%0A%09%09%7B%0A%09%09%09var%20activeTheme%3Daddons.filter%28function%28elem%29%7B%20return%20elem.isActive%3B%20%7D%29%5B0%5D%3B%0A%09%09%09if%20%28activeTheme%29%0A%09%09%09%7B%0A%09%09%09%09Object.defineProperty%28this%2C%22activeTheme%22%2C%7Bget%3A%20function%28%29%7B%20return%20activeTheme.id+activeTheme.version%3B%20%7D%7D%29%3B%0A%09%09%09%09Services.obs.addObserver%28this%2C%22domwindowopened%22%2Cfalse%29%3B%0A%09%09%09%09var%20enumerator%20%3D%20Services.wm.getEnumerator%28null%29%3B%0A%09%09%09%09while%20%28enumerator.hasMoreElements%28%29%29%0A%09%09%09%09%7B%0A%09%09%09%09%09var%20wnd%3Denumerator.getNext%28%29%3B%0A%09%09%09%09%09wnd.document.documentElement.setAttribute%28%22activetheme%22%2Cthis.activeTheme%29%3B%0A%09%09%09%09%7D%0A%09%09%09%09Services.console.logStringMessage%28%22Active%20theme%3A%20%22+this.activeTheme%29%3B%0A%09%09%09%7D%0A%09%09%09else%0A%09%09%09%09Services.console.logStringMessage%28%22Active%20theme%20has%20not%20been%20found.%22%29%3B%0A%09%09%7D%29.bind%28this%29%29%3B%0A%09%7D%2C%0A%0A%09observe%3A%20function%28aSubject%2CaTopic%2CaData%29%0A%09%7B%0A%09%09if%28aTopic%3D%3D%22domwindowopened%22%29%0A%09%09%09aSubject.addEventListener%28%22load%22%2Cthis.load%2Ctrue%29%3B%0A%09%7D%2C%0A%0A%09load%3A%20function%28event%29%0A%09%7B%0A%09%09this.removeEventListener%28%22load%22%2CthemesObserver.load%2Ctrue%29%3B%0A%09%09event.target.documentElement.setAttribute%28%22activetheme%22%2CthemesObserver.activeTheme%29%3B%0A%09%09Services.console.logStringMessage%28event.target.location+%22%3A%20%22+themesObserver.activeTheme%29%3B%0A%09%7D%0A%7D%3B%0AthemesObserver.init%28%29%3B%0Athis.addEventListener%28%22click%22%2Cfunction%28e%29%0A%7B%0A%09if%20%28%21%28e.button%3D%3D0%20%26%26%20e.type%3D%3D%22click%22%29%29%20return%3B%0A%09Services.obs.removeObserver%28themesObserver%2C%22domwindowopened%22%2Cfalse%29%3B%0A%09var%20enumerator%20%3D%20Services.wm.getEnumerator%28null%29%3B%0A%09while%20%28enumerator.hasMoreElements%28%29%29%0A%09%7B%0A%09%09var%20wnd%3Denumerator.getNext%28%29%3B%0A%09%09wnd.document.documentElement.removeAttribute%28%22activetheme%22%29%3B%0A%09%7D%0A%09Services.console.logStringMessage%28%22removing%20theme%20attributes%3A%20done%22%29%3B%0A%7D%2C%20false%29%3B%0A%5D%5D%3E%3C/initcode%3E%0A%20%20%3Ccode%3E%3C%21%5BCDATA%5B/*CODE*/%5D%5D%3E%3C/code%3E%0A%20%20%3Caccelkey%3E%3C%21%5BCDATA%5B%5D%5D%3E%3C/accelkey%3E%0A%20%20%3Chelp%3E%3C%21%5BCDATA%5B%5D%5D%3E%3C/help%3E%0A%20%20%3Cattributes/%3E%0A%3C/custombutton%3E
Выделить код

Код:

/*Initialization Code*/
Components.utils.import("resource://gre/modules/Services.jsm");
var themesObserver=
{
  init: function()
  {
    Components.utils.import("resource://gre/modules/AddonManager.jsm");
    AddonManager.getAddonsByTypes(["theme"],(function(addons)
    {
      var activeTheme=addons.filter(function(elem){ return elem.isActive; })[0];
      if (activeTheme)
      {
        Object.defineProperty(this,"activeTheme",{get: function(){ return activeTheme.id+activeTheme.version; }});
        Services.obs.addObserver(this,"domwindowopened",false);
        var enumerator = Services.wm.getEnumerator(null);
        while (enumerator.hasMoreElements())
        {
          var wnd=enumerator.getNext();
          wnd.document.documentElement.setAttribute("activetheme",this.activeTheme);
        }
        Services.console.logStringMessage("Active theme: "+this.activeTheme);
      }
      else
        Services.console.logStringMessage("Active theme has not been found.");
    }).bind(this));
  },

  observe: function(aSubject,aTopic,aData)
  {
    if(aTopic=="domwindowopened")
      aSubject.addEventListener("load",this.load,true);
  },

  load: function(event)
  {
    this.removeEventListener("load",themesObserver.load,true);
    event.target.documentElement.setAttribute("activetheme",themesObserver.activeTheme);
    Services.console.logStringMessage(event.target.location+": "+themesObserver.activeTheme);
  }
};
themesObserver.init();
this.addEventListener("click",function(e)
{
  if (!(e.button==0 && e.type=="click")) return;
  Services.obs.removeObserver(themesObserver,"domwindowopened",false);
  var enumerator = Services.wm.getEnumerator(null);
  while (enumerator.hasMoreElements())
  {
    var wnd=enumerator.getNext();
    wnd.document.documentElement.removeAttribute("activetheme");
  }
  Services.console.logStringMessage("removing theme attributes: done");
}, false);

Стиль для проверки:

Выделить код

Код:

@-moz-document url("chrome://custombuttons/content/editor.xul") {
    #custombuttonsEditor[activetheme="{014fe8e0-6553-11e0-ae3e-0800200c9a66}2.1.1.1"] {
        background-color: red !important;
    }
}

(использовался для проверки установленной у меня на данный момент темы FT SilverGlow).
Отдельное расширение с данной функциональностью можно взять здесь

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

bunda1 пишет

может  можно с этим что то сделать, убрать там версию темы

Разумеется, можно -  строчку кода

Object.defineProperty(this,"activeTheme",{get: function(){ return activeTheme.id+activeTheme.version; }});

заменяете на

Object.defineProperty(this,"activeTheme",{get: function(){ return activeTheme.id; }});

Просто когда я полгода назад писал этот код для расширения, то тема, под которую это тестировалось, и которая была у меня установлена (всё тот же Bloomind FT, но только Graphite Glow) достаточно сильно изменялась от версии к версии - поэтому я и ввел в атрибут еще и версию темы.

16-10-2011 16:37:11
А еще можно сделать так:

Object.defineProperty(this,"activeTheme",{get: function(){ return activeTheme.id

+" "+

activeTheme.version; }});


и в стилях, которые не предполагается делать зависимыми от версии темы, использовать вот такой селектор:

Выделить код

Код:

@-moz-document url("chrome://custombuttons/content/editor.xul") {
    #custombuttonsEditor[activetheme~="{014fe8e0-6553-11e0-ae3e-0800200c9a66}"] {
        background-color: red !important;
    }
}
hydrolizer пишет

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

:( у меня не выводится в консоль - FF 7.01

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

Выделить код

Код:

/*Initialization Code*/
Components.utils.import("resource://gre/modules/Services.jsm");
var themesObserver=
{
  init: function()
  {
    Components.utils.import("resource://gre/modules/AddonManager.jsm");
    AddonManager.getAddonsByTypes(["theme"],(function(addons)
    {
      var activeTheme=addons.filter(function(elem){ return elem.isActive; })[0];
      if (activeTheme)
      {
        Object.defineProperty(this,"activeTheme",{get: function(){ return activeTheme.id+" "+activeTheme.version; }});
        Services.obs.addObserver(this,"domwindowopened",false);
        var enumerator = Services.wm.getEnumerator(null);
        while (enumerator.hasMoreElements())
        {
          var wnd=enumerator.getNext();
          wnd.document.documentElement.setAttribute("activetheme",this.activeTheme);
        }
        Services.console.logStringMessage("Active theme: "+this.activeTheme);
      }
      else
        Services.console.logStringMessage("Active theme has not been found.");
    }).bind(this));
  },

  observe: function(aSubject,aTopic,aData)
  {
    if(aTopic=="domwindowopened")
      aSubject.addEventListener("load",this.load,true);
  },

  load: function(event)
  {
    this.removeEventListener("load",themesObserver.load,true);
    event.target.documentElement.setAttribute("activetheme",themesObserver.activeTheme);
    Services.console.logStringMessage(event.target.location+": "+themesObserver.activeTheme);
  }
};
themesObserver.init();
this.addEventListener("click",function(e)
{
  if (!(e.button==0 && e.type=="click")) return;
  Services.obs.removeObserver(themesObserver,"domwindowopened",false);
  var enumerator = Services.wm.getEnumerator(null);
  while (enumerator.hasMoreElements())
  {
    var wnd=enumerator.getNext();
    wnd.document.documentElement.removeAttribute("activetheme");
  }
  Services.console.logStringMessage("removing theme attributes: done");

и не работает :(

Выделить код

Код:

#search-container[activetheme~="{-972ce4c6-7e08-4474-a285-3208198ce6fd-}"]
    {display: none !important; }

я установил Bloomind FT SilverGlow, но все равно не работает

Выделить код

Код:

#search-container[activetheme~="{014fe8e0-6553-11e0-ae3e-0800200c9a66}"]
    {display: none !important; }
bunda1 пишет

у меня не выводится в консоль - FF 7.01

Проверьте в самой консоли, какой тип вывода задан - должен быть All или Messages. И еще проверьте значение настройки devtools.errorconsole.enabled - должно быть true.

bunda1 пишет

я установил Bloomind FT SilverGlow, но все равно не работает

А с приведенным выше кодом для окошка редактора редактора кнопок - работает?

hydrolizer пишет

devtools.errorconsole.enabled - должно быть true.
А с приведенным выше кодом для окошка редактора редактора кнопок - работает?

Tеперь выводится в консоль.
С приведенным выше кодом для окошка редактора редактора кнопок - работает а вот все остальное нет.
пример;

Выделить код

Код:

#titlebar [activetheme~="{014fe8e0-6553-11e0-ae3e-0800200c9a66}"]
    {display: none !important; }
bunda1 пишет

пример

Так атрибут темы же навешивается не на каждый элемент окна, а на корневой элемент окна. Т.е. вам нужен такой стиль:

Выделить код

Код:

#main-window[activetheme~="{014fe8e0-6553-11e0-ae3e-0800200c9a66}"] #titlebar {
    display: none !important;
}

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

hydrolizer
Ну спасибо, теперь все работает.