问题
Currently I am building a webextension on firefox 47.
When you click a webextension button, a drop-down menu appears, from there I can navigate to other websites.
The button that is appearing is the icon I specified in manifest.json
. I wonder if there is any way to change the icon of the extension to a text-string containing the URL I am currently visiting, and changes every time I visit a new URL.
回答1:
No, you can not directly change a browser action or page action icon into some long string of text. You can:
- Browser Actions:
- Change the icon using browserAction.setIcon(). This changes the image which is displayed. It will always be the same normal icon size. You could include a very limited amount of text in the icon image. However, it would be complex to do this dynamically, but switching between a limited set might not be that bad.
- Change the badge text using browserAction.setBadgeText(). The amount of text is limited to about four characters.
- Change the background color of the badge text using browserAction.setBadgeBackgroundColor()
- Change the icon's title using browserAction.setTitle(). This is displayed as a tooltip. The text is not inherently restricted in length. However, there are reasonable limitations on what will actually be displayed to the user.
- Change from sending an event to your background page, for which you can listen with a browserAction.onClicked listener, to displaying an HTML popup by supplying the popup's URL with browserAction.setPopup(). You can change back to the click event by specifying
''
as the URL for the popup. - Enable or disable the button with browserAction.enable() and browserAction.disable().
- Page Actions:
- Change the icon using pageAction.setIcon(). This changes the image which is displayed. It will always be the same normal icon size. You could include a very limited amount of text in the icon image. However, it would be complex to do this dynamically, but switching between a limited set might not be that bad.
- Change the icon's title using pageAction.setTitle(). This is displayed as a tooltip. The text is not inherently restricted in length. However, there are reasonable limitations on what will actually be displayed to the user.
- Change from sending an event to your background page, for which you can listen with a pageAction.onClicked listener, to displaying an HTML popup by supplying the popup's URL with pageAction.setPopup(). You can change back to the click event by specifying
''
as the URL for the popup. - Show or hide the button with pageAction.show() and pageAction.hide().
Example of changing the icon badge and badge color:
The code used to create the on/off states for the button is:
background.js
//The browserButtonStates Object describes the states the button can be in and the
// 'action' function to be called when the button is clicked when in that state.
// In this case, we have two states 'on' and 'off'.
// You could expand this to as many states as you desire.
//icon is a string, or details Object for browserAction.setIcon()
//title must be unique for each state. It is used to track the state.
// It indicates to the user what will happen when the button is clicked.
// In other words, it reflects what the _next_ state is, from the user's
// perspective.
//action is the function to call when the button is clicked in this state.
var browserButtonStates = {
defaultState: 'off',
on: {
//icon : '/ui/is-on.png'
badgeText : 'On',
badgeColor : 'green',
title : 'Turn Off',
action : function(tab) {
chrome.webNavigation.onCommitted.removeListener(onTabLoad);
},
nextState : 'off'
},
off: {
//icon : '/ui/is-off.png'
badgeText : 'Off',
badgeColor : 'red',
title : 'Turn On',
action : function(tab) {
chrome.webNavigation.onCommitted.addListener(onTabLoad);
},
nextState : 'on'
}
}
//This moves the Browser Action button between states and executes the action
// when the button is clicked. With two states, this toggles between them.
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.browserAction.getTitle({tabId:tab.id},function(title){
//After checking for errors, the title is used to determine
// if this is going to turn On, or Off.
if(chrome.runtime.lastError){
console.log('browserAction:getTitle: Encountered an error: '
+ chrome.runtime.lastError);
return;
}
//Check to see if the current button title matches a button state
let newState = browserButtonStates.defaultState;
Object.keys(browserButtonStates).some(key=> {
if(key === 'defaultState') {
return false;
}
let state = browserButtonStates[key];
if(title === state.title) {
newState = state.nextState;
setBrowserActionButton(browserButtonStates[newState]);
if(typeof state.action === 'function') {
//Do the action of the matching state
state.action(tab);
}
//Stop looking
return true;
}
});
setBrowserActionButton(browserButtonStates[newState]);
});
});
function setBrowserActionButton(tabId,details){
if(typeof tabId === 'object' && tabId !== null){
//If the tabId parameter is an object, then no tabId was passed.
details = tabId;
tabId = null;
}
let icon = details.icon;
let title = details.title;
let text = details.badgeText;
let color = details.badgeColor;
//Supplying a tabId is optional. If not provided, changes are to all tabs.
let tabIdObject = {};
if(tabId !== null && typeof tabId !== 'undefined'){
tabIdObject.tabId = tabId;
}
if(typeof icon === 'string'){
//Assume a string is the path to a file
// If not a string, then it needs to be a full Object as is to be passed to
// setIcon().
icon = {path:icon};
}
if(icon) {
Object.assign(icon,tabIdObject);
chrome.browserAction.setIcon(icon);
}
if(title) {
let detailsObject = {title};
Object.assign(detailsObject,tabIdObject);
chrome.browserAction.setTitle(detailsObject);
}
if(text) {
let detailsObject = {text};
Object.assign(detailsObject,tabIdObject);
chrome.browserAction.setBadgeText(detailsObject);
}
if(color) {
let detailsObject = {color};
Object.assign(detailsObject,tabIdObject);
chrome.browserAction.setBadgeBackgroundColor(detailsObject);
}
}
//Set the starting button state to the default state
setBrowserActionButton(browserButtonStates[browserButtonStates.defaultState]);
manifest.json:
{
"description": "Demo Button toggle",
"manifest_version": 2,
"name": "Demo Button toggle",
"version": "0.1",
"background": {
"scripts": [
"background.js"
]
},
"browser_action": {
"default_icon": {
"32": "myIcon.png"
},
"default_title": "Turn On",
"browser_style": true
}
}
The code in this answer was originally posted in my answer to In a Firefox WebExtension, how I can make a button that looks and acts like a toggle.
来源:https://stackoverflow.com/questions/41869497/change-the-button-of-a-firefox-webextension-into-a-textstring