24 Understanding Chrome Extensions Declarative Content

The chrome.declarativeContent API is an API use to take specific actions depending on the contents of the page without the use of the host_permissions in the manifest.json file or the help of the content scripts. Due to this the actions that can be trigged are limited;

  1. Show the action icon on the toolbar
  2. Setting another icon on the action icon.
  3. Registering a content script.

You can find documentation of the chrome.declarativeContent API here: https://developer.chrome.com/docs/extensions/reference/api/declarativeContent

How to declare it in the Manifest.json

{
...
"permissions":[
"declarativeContent"
],
...
}

How to use it

To use chrome.declarativeContent will need to define 2 items, conditions and actions. These 2 make up a rule

Conditions

These are the filters that the extensions will be looking for within the page to match. The filter options will

  1. Is the page bookmarked
  2. If the page contents a specific element.
  3. The url pattern of the page.

pageUrlcss and isBookmarked are the only options you have for conditions

Actions

These are a list of declarative content actions that are trigged when the conditions are satisfied.

// This rule tells the extension to show the icon in the toolbar
// when the page is on google.com and there is a password input.

let rule1 = {
id: "my rule 1", // optional, will be generated if not set.
priority: 100, // optional, defaults to 100.
conditions: [
new chrome.declarativeContent.PageStateMatcher({
pageUrl: { hostSuffix: '.google.com', schemes: ['https'] },
css: ["input[type='password']"]
})
],

actions: [ new chrome.declarativeContent.ShowAction() ]

};
// This rule tells the extension to show the icon in the toolbar
// and register a content scripts 'content.js'
// when the page is on google.com and there is a password input.
// or if a video exists on the page

let rule2 = {
id: "my rule 2", // optional, will be generated if not set.
priority: 100, // optional, defaults to 100.
conditions: [
new chrome.declarativeContent.PageStateMatcher({
pageUrl: { hostSuffix: '.google.com', schemes: ['https'] },
css: ["input[type='password']"],
isBookmarked: false,
}),
new chrome.declarativeContent.PageStateMatcher({
css: ["video"]
})
],
actions: [

// show icon
new chrome.declarativeContent.ShowAction(),

// register content scripts
new chrome.declarativeContent.RequestContentScript({
css: [],
js: ["content.js"]
})
]
};

Note: As long as one of the conditions of a rule is met all the actions will fire

CSS Matching

Notice how the css has selectors similar to the ones you would use for document.querySelector however, they are a bit limited. You can use compound selectors like;

a
iframe.special[src^='http']
ns|*
#abcd:checked

But not complex ones like;

div p

p>span.highlight

p + ol

p::first-line

You can read the doc here for more info on the CSS Matching patterns.

Page Filter

As for pageUrl it follows a JSON structure called UrlFilter containing, hostSuffix , schemes and more many. For all the options you can use for it go here: https://developer.chrome.com/docs/extensions/reference/api/events#type-UrlFilter

Adding and Remove Rules

Now that we able to define rules how do we add/remove them? We are able to do so using the event listener chrome.declarativeContent.onPageChanged

// when the extension is installed.
chrome.runtime.onInstalled.addListener(function(details) {

// ...code to define rule1 and rule2

let removeRuleIds = ['my rule 1', 'my rule 2'];

// use undefine to remove all the rules else use an array of rule ids.
chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {

// add rules
chrome.declarativeContent.onPageChanged.addRules([rule1, rule2]);
});

});

Sample Project

We are going to make a chrome extensions that makes use of the declarativeContent API to display the action icon and register a content script that changes the background to gold, when a webpage is from Facebook, Google, Instagram, YouTube or if the webpage as a video element in it.

You can find the source code for the project here: https://github.com/BuildChromeExtensions/chromeDeclarativeContent

We will need 3 files for this one; manifest.jsonbackground.js and content.js

manifest.json

{
"name": "Declarative Content Extension",
"version": "1.0.0.0",
"manifest_version": 3,
"action": {
"default_title": "Actions for Declartive content"
},
"permissions": [
"activeTab",
"declarativeContent"
],
"background": {
"service_worker": "background.js"
}
}

content.js

The content script that will registered

document.body.style.background = 'gold';

background.js

// when the extension is installed.
chrome.runtime.onInstalled.addListener(function (details) {

const rule = {
// id: "myrule", // optional, will be generated if not set.
// priority: 100, // optional, defaults to 100.
conditions: [
new chrome.declarativeContent.PageStateMatcher({
pageUrl: { hostSuffix: '.youtube.com', schemes: ['https'] },
}),
new chrome.declarativeContent.PageStateMatcher({
pageUrl: { hostSuffix: '.facebook.com', schemes: ['https'] },
}),
new chrome.declarativeContent.PageStateMatcher({
pageUrl: { hostSuffix: '.instagram.com', schemes: ['https'] },
}),
new chrome.declarativeContent.PageStateMatcher({
pageUrl: { hostSuffix: '.google.com', schemes: ['https'] },
}),
],
actions: [

// show icon
new chrome.declarativeContent.ShowAction(),

// register content scripts
new chrome.declarativeContent.RequestContentScript({ js: ["content.js"] })
]
};

// use undefine to remove all the rules else use an array of rule ids.
chrome.declarativeContent.onPageChanged.removeRules(undefined, function () {
console.log('Rule Removed');

// add rules
chrome.declarativeContent.onPageChanged.addRules([rule], function (rules) {
console.log('Rule Added', rules)
});
});

});

Chrome Extension

Declarative

Declarative Content

Leave a Reply

Your email address will not be published. Required fields are marked *

More Articles & Posts