Javascript 引导添加按钮到BrowserPalette并使其持久化

Javascript 引导添加按钮到BrowserPalette并使其持久化,javascript,firefox-addon,firefox-addon-restartless,Javascript,Firefox Addon,Firefox Addon Restartless,我有点好奇。我能够添加一个按钮到浏览器调色板,然后将其移动到一个工具栏与此代码,可以复制粘贴到scratchpad和运行 var doc = document; var win = doc.defaultView; var toolbox = doc.querySelector('#navigator-toolbox'); var buttonId = 'bpMyBtn'; var button = doc.getElementById(buttonId); if (!button) {

我有点好奇。我能够添加一个按钮到浏览器调色板,然后将其移动到一个工具栏与此代码,可以复制粘贴到scratchpad和运行

var doc = document;
var win = doc.defaultView;

var toolbox = doc.querySelector('#navigator-toolbox');

var buttonId = 'bpMyBtn';
var button = doc.getElementById(buttonId);
if (!button) {
    button = doc.createElementNS('http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul', 'toolbarbutton');
    button.setAttribute('id', buttonId);
    button.setAttribute('label', 'My Button');
    button.setAttribute('tooltiptext', 'My buttons tool tip if you want one');
    button.setAttribute('class', 'toolbarbutton-1 chromeclass-toolbar-additional');
    button.style.listStyleImage = 'url("https://gist.githubusercontent.com/Noitidart/9266173/raw/06464af2965cb5968248b764b4669da1287730f3/my-urlbar-icon-image.png")';
    button.addEventListener('command', function() {
        alert('you clicked my button')
    }, false);

    toolbox.palette.appendChild(button);
}

var targetToolbar = doc.querySelector('#nav-bar');
//move button into last postion in targetToolbar
targetToolbar.insertItem(buttonId); //if you want it in first position in targetToolbar do: targetToolbar.insertItem(buttonId, navBar.firstChild);
targetToolbar.setAttribute('currentset', targetToolbar.currentSet);
doc.persist(targetToolbar.id, 'currentset');
但是,
doc.persist
不起作用,一旦我重新启动浏览器,按钮就不见了。是否可以使用persist在引导加载项的第一次添加一个按钮并将其持久化

这也引出了一个问题:如何删除按钮并保持它?(ie在卸载时完全从调色板中删除,另一个ie:只从工具栏中删除,因此换句话说,只需将其发送回调色板并保持)

我从这里获得了持久化代码:

我使用的库最初是在who的一篇文章中找到的,它是我引导开发的主要知识来源。它工作得非常好:

(为了便于测试,您可以通过以下方式将其添加到启动功能中:

最后,要添加按钮本身,请在窗口加载的函数中使用如下内容:


(unload()也是Erik Vold的另一个库函数)

在设置
currentset
属性之前,请检查
targetToolbar.currentset
属性是否确实包含按钮的id。运行上述代码后,我检查了currentset,按钮id确实存在。重新启动浏览器后,我只运行代码:
console.log('targetToolbar.currentset',targetToolbar.currentset)
它给了我
“targetToolbar.currentset”未定义的
真的很奇怪。我在australis使用FF 29他们停止了currentset吗?自我提示:在australis,我认为它在做
CustomizeLeUI.AddWidgeToArea
然后
CustomizeLeUIInternal.saveState
我不确定要传递的参数,就像我不知道如何获取区域id一样。看看它是如何传递的r搜索它,我会看一看。哦,非常感谢。这不是真正的持久化,虽然,嗯?那么,在启动插件时,如果原因是没有安装,我必须运行恢复功能?我现在肯定接受这个答案,但是,如果一个真正的持久化解决方案来了,我更愿意,我想研究新的
定制ableUIInternal
stuff for Austrail是真正持久的。要检查localstore.rdf currentset中的find,您应该找到按钮的ID。由于引导扩展没有(不应该)留下任何东西,因此每次启动按钮时,我们都必须还原按钮。
/* ***** BEGIN LICENSE BLOCK *****
* Version: MIT/X11 License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* Contributor(s):
* Dmitry Gutov <dgutov@yandex.ru> (Original Author)
* Erik Vold <erikvvold@gmail.com>
*
* ***** END LICENSE BLOCK ***** */

(function(global) {
  let positions = {};

  /*
   * Assigns position that will be used by `restorePosition`
   * if the button is not found on any toolbar's current set.
   * If `beforeID` is null, or no such item is found on the toolbar,
   * the button will be added to the end.
   * @param beforeID ID of the element before which the button will be inserted.
   */
  global.setDefaultPosition = function(buttonID, toolbarID, beforeID) {
    positions[buttonID] = [toolbarID, beforeID];
  };

  /*
   * Restores the button's saved position.
   * @param {XULDocument} doc XUL window document.
   * @param {XULElement} button button element.
   */
  global.restorePosition = function(doc, button, toolbox) {
    function $(sel, all)
      doc[all ? "querySelectorAll" : "getElementById"](sel);
    ($(toolbox) || $("header-view-toolbox") || $("navigator-toolbox") || $("mail-toolbox")).palette.appendChild(button);

    let toolbar, currentset, idx,
        toolbars = $("toolbar", true);
    for (let i = 0; i < toolbars.length; ++i) {
      let tb = toolbars[i];
      currentset = tb.getAttribute("currentset").split(","),
      idx = currentset.indexOf(button.id);
      if (idx != -1) {
        toolbar = tb;
        break;
      }
    }

    // saved position not found, using the default one, if any
    if (!toolbar && (button.id in positions)) {
      let [tbID, beforeID] = positions[button.id];
      toolbar = $(tbID);
      [currentset, idx] = persist(doc, toolbar, button.id, beforeID);
    }

    if (toolbar) {
      if (idx != -1) {
        // inserting the button before the first item in `currentset`
        // after `idx` that is present in the document
        for (let i = idx + 1; i < currentset.length; ++i) {
          let before = $(currentset[i]);
          if (before) {
            toolbar.insertItem(button.id, before);
            return;
          }
        }
      }
      toolbar.insertItem(button.id);
    }
  };

  function persist(document, toolbar, buttonID, beforeID) {
    let currentset = toolbar.getAttribute("currentset").split(","),
        idx = (beforeID && currentset.indexOf(beforeID)) || -1;
    if (idx != -1) {
      currentset.splice(idx, 0, buttonID);
    } else {
      currentset.push(buttonID);
    }
    toolbar.setAttribute("currentset", currentset.join(","));
    document.persist(toolbar.id, "currentset");
    return [currentset, idx];
  }
})(this);
setDefaultPosition("my_button_id", "navigator-toolbox", null);
if (reason == ADDON_INSTALL)
{
    setDefaultPosition("my_button_id", "navigator-toolbox", null);
}
let toolbarbutton = document.createElement("toolbarbutton"),
toolbarbutton.id = "my_button_id";
toolbarbutton.setAttribute("label", "My toolbar button");
restorePosition(document, toolbarbutton, "navigator-toolbox");
unload(function()
{
    toolbarbutton.parentNode.removeChild(toolbarbutton);
});