The Declarative Content API allows you to show your extension's $(ref:pageAction page action) depending on the URL of a web page and the CSS selectors its content matches, without needing to take a host permission or inject a content script. Use the activeTab permission in order to be able to interact with a page after the user clicks on your page action.
If you need more precise control over when your page action appears or you need to change its appearance to match the current tab before the user clicks on it, you'll have to keep using the $(ref:pageAction) API.
As a declarative API, this
API lets you register rules on the
$(ref:onPageChanged)
$(ref:events.Event event) object which
take an action (currently just $(ref:ShowPageAction)
) when
a set of conditions, represented as a
$(ref:PageStateMatcher)
, are met.
The $(ref:PageStateMatcher)
matches web pages if and only
if all listed criteria are met. The following rule would show a page
action for pages on https://www.google.com/
when a
password field is present on it:
var rule1 = { conditions: [ new $(ref:PageStateMatcher chrome.declarativeContent.PageStateMatcher)({ $(ref:PageStateMatcher.pageUrl pageUrl): { $(ref:events.UrlFilter.hostEquals hostEquals): 'www.google.com', $(ref:events.UrlFilter.schemes schemes): ['https'] }, $(ref:PageStateMatcher.css css): ["input[type='password']"] }) ], actions: [ new $(ref:ShowPageAction chrome.declarativeContent.ShowPageAction)() ] };
Note: All conditions and actions are created via a constructor as shown in the example above.
In order to also show a page action for sites with a video, you can add a second condition, as each condition is sufficient to trigger all specified actions:
var rule2 = { conditions: [ new $(ref:PageStateMatcher chrome.declarativeContent.PageStateMatcher)({ $(ref:PageStateMatcher.pageUrl pageUrl): { $(ref:events.UrlFilter.hostEquals hostEquals): 'www.google.com', $(ref:events.UrlFilter.schemes schemes): ['https'] }, $(ref:PageStateMatcher.css css): ["input[type='password']"] }), new $(ref:PageStateMatcher chrome.declarativeContent.PageStateMatcher)({ $(ref:PageStateMatcher.css css): ["video"] }) ], actions: [ new $(ref:ShowPageAction chrome.declarativeContent.ShowPageAction)() ] };
Added rules are saved across browser restarts, so register them as follows:
$(ref:runtime.onInstalled chrome.runtime.onInstalled).addListener(function(details) { $(ref:onPageChanged chrome.declarativeContent.onPageChanged).removeRules(undefined, function() { $(ref:onPageChanged chrome.declarativeContent.onPageChanged).addRules([rule2]); }); });
Note: You should always register or unregister rules in bulk rather than individually because each of these operations recreates internal data structures. This re-creation is computationally expensive but facilitates a faster matching algorithm.
Combine the above rule with the activeTab permission to create an extension that doesn't need any install-time permissions but can invite the user to click its page action on relevant pages and can run on those pages when the user clicks the page action.
$(ref:PageStateMatcher.css) conditions must be
compound selectors,
meaning that you can't
include combinators
like whitespace or ">
" in your selectors. This helps Chrome
match the selectors more efficiently.
Compound Selectors (OK) | Complex Selectors (Not OK) |
---|---|
a | div p |
iframe.special[src^='http'] | p>span.highlight |
ns|* | p + ol |
#abcd:checked | p::first-line |
CSS conditions only match displayed elements: if an element that matches your
selector is display:none
or one of its parent elements
is display:none
, it doesn't cause the condition to match. Elements
styled with visibility:hidden
, positioned off-screen, or hidden by
other elements can still make your condition match.