mirror of
https://github.com/mdn/webextensions-examples.git
synced 2026-04-17 06:48:37 +02:00
By using the URL interface, the user is ascertained that the piece of code does not manipulate the DOM. Keeping them in the right mental context for the example. The apply-css example uses the protocol of the URL of the tab to determine if a pageAction should be shown. Any page that is hosted over http or https will receive the page action. The former implementation creates an anchor tag, assigns the URL to that, and fetches the protocol from there. This PR alters that to using the URL interface. This makes it clear to the user that we're staying in JavaScript land and will not start manipulating the visible DOM. I would argue this is cleaner all together, but I'm very open to learning about a different opinion. The URL interface is more broadly supported than the pageAction.setIcon which this example is also dependent on, so this change should not change compatibility of this Browser Extension.
69 lines
1.9 KiB
JavaScript
69 lines
1.9 KiB
JavaScript
const CSS = "body { border: 20px solid red; }";
|
|
const TITLE_APPLY = "Apply CSS";
|
|
const TITLE_REMOVE = "Remove CSS";
|
|
const APPLICABLE_PROTOCOLS = ["http:", "https:"];
|
|
|
|
/*
|
|
Toggle CSS: based on the current title, insert or remove the CSS.
|
|
Update the page action's title and icon to reflect its state.
|
|
*/
|
|
function toggleCSS(tab) {
|
|
|
|
function gotTitle(title) {
|
|
if (title === TITLE_APPLY) {
|
|
browser.pageAction.setIcon({tabId: tab.id, path: "icons/on.svg"});
|
|
browser.pageAction.setTitle({tabId: tab.id, title: TITLE_REMOVE});
|
|
browser.tabs.insertCSS({code: CSS});
|
|
} else {
|
|
browser.pageAction.setIcon({tabId: tab.id, path: "icons/off.svg"});
|
|
browser.pageAction.setTitle({tabId: tab.id, title: TITLE_APPLY});
|
|
browser.tabs.removeCSS({code: CSS});
|
|
}
|
|
}
|
|
|
|
var gettingTitle = browser.pageAction.getTitle({tabId: tab.id});
|
|
gettingTitle.then(gotTitle);
|
|
}
|
|
|
|
/*
|
|
Returns true only if the URL's protocol is in APPLICABLE_PROTOCOLS.
|
|
*/
|
|
function protocolIsApplicable(url) {
|
|
const protocol = (new URL(url)).protocol;
|
|
return APPLICABLE_PROTOCOLS.includes(protocol);
|
|
}
|
|
|
|
/*
|
|
Initialize the page action: set icon and title, then show.
|
|
Only operates on tabs whose URL's protocol is applicable.
|
|
*/
|
|
function initializePageAction(tab) {
|
|
if (protocolIsApplicable(tab.url)) {
|
|
browser.pageAction.setIcon({tabId: tab.id, path: "icons/off.svg"});
|
|
browser.pageAction.setTitle({tabId: tab.id, title: TITLE_APPLY});
|
|
browser.pageAction.show(tab.id);
|
|
}
|
|
}
|
|
|
|
/*
|
|
When first loaded, initialize the page action for all tabs.
|
|
*/
|
|
var gettingAllTabs = browser.tabs.query({});
|
|
gettingAllTabs.then((tabs) => {
|
|
for (let tab of tabs) {
|
|
initializePageAction(tab);
|
|
}
|
|
});
|
|
|
|
/*
|
|
Each time a tab is updated, reset the page action for that tab.
|
|
*/
|
|
browser.tabs.onUpdated.addListener((id, changeInfo, tab) => {
|
|
initializePageAction(tab);
|
|
});
|
|
|
|
/*
|
|
Toggle CSS when the page action is clicked.
|
|
*/
|
|
browser.pageAction.onClicked.addListener(toggleCSS);
|