0

如何将文本添加到您的加载项的浏览器工具栏按钮?
在Firefox非叠加扩展中,如何向浏览器工具栏图标添加文本?

我感兴趣的东西完全一样,下载管理器按钮如何显示上方的进度条“2h”的文字,当两个小时剩余下载所需的文件(S)。

甚至有可能做到这一点,而不诉诸于包括文字在内的大量预制图像?

+0

你可以尝试生成有用的图像住在javscript写他们到一个文件并相应地更新图标,但由于你没有在main.js中的DOM,这可能是不可能的,没有一个画布元素。 – 2014-10-10 12:59:55

回答

2

当你有一个已知的工作示例时,一种方法来弄清楚如何在DOM中实现这种类型的东西(整个浏览器窗口是一个DOM)是安装add-onDOM Inspector并用它来调查内容的DOM看起来像。你可能也想要,Element Inspector加载项,这是一个非常有用的添加到DOM Inspector(shift-right-click打开DOM Inspector到单击的元素)。您也许会发现Stacked Inspector有帮助。

在这种情况下,下载按钮从<toolbarbutton/>开始。具体做法是:

<toolbarbutton id="downloads-button" 
    class="toolbarbutton-1 chromeclass-toolbar-additional" 
    key="key_openDownloads" oncommand="DownloadsIndicatorView.onCommand(event);" 
    ondrop="DownloadsIndicatorView.onDrop(event);" 
    ondragover="DownloadsIndicatorView.onDragOver(event);" 
    ondragenter="DownloadsIndicatorView.onDragOver(event);" 
    label="Downloads" removable="true" cui-areatype="toolbar" 
    tooltip="dynamic-shortcut-tooltip"/> 

Download Button prior to downloading

一旦下载开始结构被改变为:

<toolbarbutton id="downloads-button" 
    class="toolbarbutton-1 chromeclass-toolbar-additional" 
    key="key_openDownloads" oncommand="DownloadsIndicatorView.onCommand(event);" 
    ondrop="DownloadsIndicatorView.onDrop(event);" 
    ondragover="DownloadsIndicatorView.onDragOver(event);" 
    ondragenter="DownloadsIndicatorView.onDragOver(event);" 
    label="Downloads" removable="true" cui-areatype="toolbar" 
    tooltip="dynamic-shortcut-tooltip" 
    indicator="true" progress="true" counter="true"> 
     <stack id="downloads-indicator-anchor" class="toolbarbutton-icon"> 
      <vbox id="downloads-indicator-progress-area" pack="center"> 
       <description id="downloads-indicator-counter" value="6h"/> 
       <progressmeter id="downloads-indicator-progress" class="plain" 
        min="0" max="100" value="3.484329371737533"/> 
      </vbox> 
      <vbox id="downloads-indicator-icon"/> 
     </stack> 
</toolbarbutton> 

Download button while downloading

上述结构变化被包含在chrome://browser/content/downloads/indicatorOverlay.xul其上装载作为覆盖到主浏览器文档上。

控制指标的代码是chrome://browser/content/downloads/indicator.js。实际加载覆盖图的代码是ensureOverlayLoaded(),其格式为chrome://browser/content/downloads/downloads.js

使不使用XUL覆盖
既然你是想这是一个覆盖扩展的变化,你可能不希望使用一个XUL Overlay。因此,您需要遍历按钮所在的所有位置,并对每个结构进行更改。但是,此时您可能正在处理通过CustomizableUI添加的按钮。通过CustomizableUI,您不会通过打开的窗口运行,而是通过它提供给您的节点运行。有必要这样做,因为用户许多人已将自己感兴趣的按钮放在自定义托盘中,而不是放在工具栏中。如果是这种情况,试图通过使用浏览器窗口document找到document.getElementById()的按钮将失败。通过这些使用CustomizableUI界面运行,你可以使用类似以下内容:

function loadUi() { 
    if (window === null || typeof window !== "object") { 
     //If you do not already have a window reference, you need to obtain one: 
     // Add a "/" to un-comment the code appropriate for your add-on type. 
     /* Add-on SDK: 
     var window = require('sdk/window/utils').getMostRecentBrowserWindow(); 
     //*/ 
     /* Overlay and bootstrap (from almost any context/scope): 
     var window=Components.classes["@mozilla.org/appshell/window-mediator;1"] 
          .getService(Components.interfaces.nsIWindowMediator) 
          .getMostRecentWindow("navigator:browser"); 
     //*/ 
    } 

    forEachCustomizableUiById("downloads-button", loadIntoButton, window); 
} 

function forEachCustomizableUiById(buttonId ,func, myWindow) { 
    let groupWidgetWrap = myWindow.CustomizableUI.getWidget(buttonId); 
    groupWidgetWrap.instances.forEach(function(perWindowUiWidget) { 
     //For each button do the load task. 
     func(perWindowUiWidget.node); 
    }); 
} 

function loadIntoButton(buttonElement) { 
    //Make whatever changes to the button you want to here. 
    //You may need to save some information about the original state 
    // of the button. 
} 

显然,卸载只是装载的反向:

function unloadUi() { 
    if (window === null || typeof window !== "object") { 
     //If you do not already have a window reference, you need to obtain one: 
     // Add a "/" to un-comment the code appropriate for your add-on type. 
     /* Add-on SDK: 
     var window = require('sdk/window/utils').getMostRecentBrowserWindow(); 
     //*/ 
     /* Overlay and bootstrap (from almost any context/scope): 
     var window=Components.classes["@mozilla.org/appshell/window-mediator;1"] 
          .getService(Components.interfaces.nsIWindowMediator) 
          .getMostRecentWindow("navigator:browser"); 
     //*/ 
    } 

    forEachCustomizableUiById("downloads-button", unloadFromButton, window); 
} 

function unloadFromButton(buttonElement) { 
    //Return the button to its original state 
} 

在改变按钮的具体实例其下载状态你可能可以做到以下几点:

function loadIntoButton(buttonElement) { 
    buttonElement.setAttribute("indicator","true"); 
    buttonElement.setAttribute("progress","true"); 
    buttonElement.setAttribute("counter","true"); 
    let additional = '' 
     + '<stack id="downloads-indicator-anchor" class="toolbarbutton-icon">' 
     + ' <vbox id="downloads-indicator-progress-area" pack="center">' 
     + '  <description id="downloads-indicator-counter" value="6h"/>' 
     + '  <progressmeter id="downloads-indicator-progress" class="plain"' 
     + '   min="0" max="100" value="3.484329371737533"/>' 
     + ' </vbox>' 
     + ' <vbox id="downloads-indicator-icon"/>' 
     + '</stack>'; 
    buttonElement.insertAdjacentHTML("beforeend",additional); 
} 

function unloadFromButton(buttonElement) { 
    buttonElement.removeAttribute("indicator","true"); 
    buttonElement.removeAttribute("progress","true"); 
    buttonElement.removeAttribute("counter","true"); 
    buttonElement.removeChild(buttonElement.getElementsByTagName("stack")[0]); 
} 

我还没有机会测试上面的代码,所以可能会有一些问题UE的。

从头开始创建一个复杂CustomizableUI部件:
如果你是想从一开始就创建更复杂的东西,那么你应该使用CustomizableUI并创建一个custom部件。该CustomizableUI.jsm page at MDN有一个"simple" example of a complex widget是:

CustomizableUI.createWidget({ 
    //Must run createWidget before windowListener.register because the register 
    // function needs the button added first. 
     id: 'navigator-throbber', 
     type: 'custom', 
     defaultArea: CustomizableUI.AREA_NAVBAR, 
     onBuild: function(aDocument) { 
      var toolbaritem = aDocument.createElementNS(
       'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul', 
       'toolbaritem'); 
      var image = aDocument.createElementNS(
       'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul', 
       'image'); 
      var props = { 
       id: 'navigator-throbber', 
       title: 'Activity Indicator', 
       align: 'center', 
       pack: 'center', 
       mousethrough: 'always', 
       removable: 'true', 
       sdkstylewidget: 'true', 
       overflows: false 
      }; 
      for (var p in props) { 
       toolbaritem.setAttribute(p, props[p]); 
      } 

      toolbaritem.appendChild(image); 
      return toolbaritem; 
     } 
    }); 

作为一个更复杂的例子,Noitidart提供了浏览器使用的用于它的自定义插件的代码的总结的变焦控制和编辑控制面板英寸它可在此要点:https://gist.github.com/Noitidart/10902477








自定义CSS和XML绑定Firefox的下载按钮: 要充分实现自己的下载按钮,你还需要的版本CSS和由Mozilla使用的自定义XML绑定。

CSS的下载按钮(从chrome://browser/content/browser.css

#downloads-button { 
    -moz-binding: url("chrome://browser/content/downloads/download.xml#download-toolbarbutton"); 
} 

/*** Visibility of downloads indicator controls ***/ 

/* Bug 924050: If we've loaded the indicator, for now we hide it in the menu panel, 
    and just show the icon. This is a hack to side-step very weird layout bugs that 
    seem to be caused by the indicator stack interacting with the menu panel. */ 
#downloads-button[indicator]:not([cui-areatype="menu-panel"]) > image.toolbarbutton-icon, 
#downloads-button[indicator][cui-areatype="menu-panel"] > #downloads-indicator-anchor { 
    display: none; 
} 

toolbarpaletteitem[place="palette"] > #downloads-button[indicator] > image.toolbarbutton-icon { 
    display: -moz-box; 
} 

toolbarpaletteitem[place="palette"] > #downloads-button[indicator] > stack.toolbarbutton-icon { 
    display: none; 
} 

#downloads-button:-moz-any([progress], [counter], [paused]) #downloads-indicator-icon, 
#downloads-button:not(:-moz-any([progress], [counter], [paused])) 
                #downloads-indicator-progress-area 
{ 
    visibility: hidden; 
} 

/* Hacks for toolbar full and text modes, until bug 573329 removes them */ 

toolbar[mode="text"] > #downloads-button { 
    display: -moz-box; 
    -moz-box-orient: vertical; 
    -moz-box-pack: center; 
} 

toolbar[mode="text"] > #downloads-button > .toolbarbutton-text { 
    -moz-box-ordinal-group: 1; 
} 

toolbar[mode="text"] > #downloads-button > .toolbarbutton-icon { 
    display: -moz-box; 
    -moz-box-ordinal-group: 2; 
    visibility: collapse; 
} 

自定义下载按钮XML绑定(从chrome://browser/content/downloads/download.xml):

<?xml version="1.0"?> 
<!-- -*- Mode: HTML; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- --> 
<!-- vim: set ts=2 et sw=2 tw=80: --> 

<!-- This Source Code Form is subject to the terms of the Mozilla Public 
    - License, v. 2.0. If a copy of the MPL was not distributed with this file, 
    - You can obtain one at http://mozilla.org/MPL/2.0/. --> 

<!DOCTYPE bindings SYSTEM "chrome://browser/locale/downloads/downloads.dtd"> 

<bindings id="downloadBindings" 
      xmlns="http://www.mozilla.org/xbl" 
      xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" 
      xmlns:xbl="http://www.mozilla.org/xbl"> 

    <binding id="download" 
      extends="chrome://global/content/bindings/richlistbox.xml#richlistitem"> 
    <content orient="horizontal" 
      align="center" 
      onclick="DownloadsView.onDownloadClick(event);"> 
     <xul:image class="downloadTypeIcon" 
       validate="always" 
       xbl:inherits="src=image"/> 
     <xul:image class="downloadTypeIcon blockedIcon"/> 
     <xul:vbox pack="center" 
       flex="1" 
       class="downloadContainer" 
       style="width: &downloadDetails.width;"> 
     <!-- We're letting localizers put a min-width in here primarily 
      because of the downloads summary at the bottom of the list of 
      download items. An element in the summary has the same min-width 
      on a description, and we don't want the panel to change size if the 
      summary isn't being displayed, so we ensure that items share the 
      same minimum width. 
      --> 
     <xul:description class="downloadTarget" 
         crop="center" 
         style="min-width: &downloadsSummary.minWidth2;" 
         xbl:inherits="value=target,tooltiptext=target"/> 
     <xul:progressmeter anonid="progressmeter" 
          class="downloadProgress" 
          min="0" 
          max="100" 
          xbl:inherits="mode=progressmode,value=progress"/> 
     <xul:description class="downloadDetails" 
         crop="end" 
         xbl:inherits="value=status,tooltiptext=statusTip"/> 
     </xul:vbox> 
     <xul:stack> 
     <xul:button class="downloadButton downloadCancel" 
        tooltiptext="&cmd.cancel.label;" 
        oncommand="DownloadsView.onDownloadCommand(event, 'downloadsCmd_cancel');"/> 
     <xul:button class="downloadButton downloadRetry" 
        tooltiptext="&cmd.retry.label;" 
        oncommand="DownloadsView.onDownloadCommand(event, 'downloadsCmd_retry');"/> 
     <xul:button class="downloadButton downloadShow" 
        tooltiptext="&cmd.show.label;" 
        oncommand="DownloadsView.onDownloadCommand(event, 'downloadsCmd_show');"/> 
     </xul:stack> 
    </content> 
    </binding> 

    <binding id="download-full-ui" 
      extends="chrome://global/content/bindings/richlistbox.xml#richlistitem"> 
    <resources> 
     <stylesheet src="chrome://browser/content/downloads/download.css"/> 
    </resources> 

    <content orient="horizontal" align="center"> 
     <xul:image class="downloadTypeIcon" 
       validate="always" 
       xbl:inherits="src=image"/> 
     <xul:image class="downloadTypeIcon blockedIcon"/> 
     <xul:vbox pack="center" flex="1"> 
     <xul:description class="downloadTarget" 
         crop="center" 
         xbl:inherits="value=displayName,tooltiptext=displayName"/> 
     <xul:progressmeter anonid="progressmeter" 
          class="downloadProgress" 
          min="0" 
          max="100" 
          xbl:inherits="mode=progressmode,value=progress"/> 
     <xul:description class="downloadDetails" 
         style="width: &downloadDetails.width;" 
         crop="end" 
         xbl:inherits="value=status,tooltiptext=statusTip"/> 
     </xul:vbox> 

     <xul:button class="downloadButton downloadCancel" 
        tooltiptext="&cmd.cancel.label;" 
        oncommand="goDoCommand('downloadsCmd_cancel')"/> 
     <xul:button class="downloadButton downloadRetry" 
        tooltiptext="&cmd.retry.label;" 
        oncommand="goDoCommand('downloadsCmd_retry')"/> 
     <xul:button class="downloadButton downloadShow" 
        tooltiptext="&cmd.show.label;" 
        oncommand="goDoCommand('downloadsCmd_show')"/> 

    </content> 
    </binding> 

    <binding id="download-toolbarbutton" 
      extends="chrome://global/content/bindings/toolbarbutton.xml#toolbarbutton"> 
    <content> 
     <children /> 
     <xul:image class="toolbarbutton-icon" xbl:inherits="validate,src=image,label"/> 
     <xul:label class="toolbarbutton-text" crop="right" flex="1" 
       xbl:inherits="value=label,accesskey,crop,wrap"/> 
     <xul:label class="toolbarbutton-multiline-text" flex="1" 
       xbl:inherits="xbl:text=label,accesskey,wrap"/> 
    </content> 
    </binding> 
</bindings> 
+0

真棒的回答! – canuckistani 2014-10-12 18:08:40

+0

谢谢!完美的回答。添加“6h”的拉贝尔l和进度条就在所需的工具栏按钮旁边。 – 2014-10-13 13:36:30

+0

@Makyen Followup:你如何使它通过我的toolbarbutton而不是旁边呢?我尝试从我的toolbarbutton中删除'图像'标签,使其移动过来,但它只留下一个空白区域 – 2014-10-14 09:22:42

相关问题