5

I am trying to make a Chrome extension, which will monitor GMail and do something when user starts to write a message. After some study of examples and documentation I have figured out that I should do it with declarativeContent, which reacts on page change.

This is what I have done by now.

manifest.json:

{
  "manifest_version": 2,
  "name": "Gmail helper",
  "version": "0.1",
  "permissions": [ "declarativeContent" ],
  "background": {
    "scripts": ["background.js"],
    "persistent": false
  }
}

background.js:

chrome.runtime.onInstalled.addListener (function (details) {
  chrome.declarativeContent.onPageChanged.removeRules (undefined, function () {
    chrome.declarativeContent.onPageChanged.addRules ([{
      conditions: [
        new chrome.declarativeContent.PageStateMatcher({
          pageUrl: { hostEquals: 'mail.google.com', schemes: ['https'] },
          css: ["div"]
//          css: ["div[aria-label='Message Body']"]
        })
      ],
      actions: [ new chrome.declarativeContent.RequestContentScript({js: ["content.js"]}) ]
    }]);
  });
});

content.js:

alert ("Test");

My plan was to declare a content script that would trigger on page changes in GMail. I have added a declarative rule, which has pageURL, css and actions defined. According to my understanding content.js should be executed when pageUrl and css content match. However, content.js is not executed.

What am I doing wrong?

Thanks.

nobody
  • 64
  • 5
  • 15

3 Answers3

11

Running a content script on a site requires permissions for the site, which isn't stated explicitly in the documentation of declarativeContent API, but is deduced by the lack of "This action can be used without host permissions" note, which is present in other actions. The purpose of declarativeContent API is to install extensions from the WebStore without any permission confirmation warning so naturally this API can't grant you access to mail.google.com unless you add it explicitly in your manifest:

"permissions": ["declarativeContent", "https://mail.google.com/"]
wOxxOm
  • 65,848
  • 11
  • 132
  • 136
  • Thanks. I found something about permissions but was unable to find any reference or example showing what you wrote. As you can see I have added permissions for declarativeContent but dit not add the URL. This is a great answer. – nobody Sep 14 '17 at 10:29
8

From description of your task it looks like you don't need declarativeContent.

You need to add a content script to page if GMail page is open and in content script you need to add a listener to message editor DOM element (or whatever another element you need to track).

Assuming that you know how to do the second, to add content script to GMail page you need to add the following into manifest:

  "content_scripts": [
    {
      "matches": [
        "https://mail.google.com/*"
      ],
      "js": ["content.js"]
    }

You also don't need background script and permissions in this case.

Note: Although you don't need to specify permissions, your extension will require to ask them from the user. During installation, Chrome will warn the user that your extension will have access to all user data on the page to make the user able to cancel installation if he or she does not agree.

  • Thanks. I like the other answer better, because I think it is a more proper way to do it. I tried it your way at first, but I didn't know how to react on page changes. I had problems because the elements I was looking for were not available right at the beginning. Maybe I should have used `"run_a": "document_end"`. I tried to add a listener, but the elements were simply not available. – nobody Sep 14 '17 at 10:34
  • You're welcome. Sure it is up to you. I just think that adding tracking of page changes to extension is overkill. If you change mind, you may use mutation observers to get notification about added DOM object (https://stackoverflow.com/questions/16618876/determining-if-a-html-element-has-been-added-to-the-dom-dynamically). I played a bit with GMail page, it seems that message editor always appears as child of this element
    . So you may track just children inside probably (I did not investigate carefully so may be wrong).
    – Victor Portnov Sep 14 '17 at 11:42
  • @VictorPortnov is there any way to ask for content script permissions later? – sheriff_paul Oct 15 '19 at 19:00
  • @Goehybrid no, I don't think so. It is not a permission in fact, it is kind of a filter used by browser to decide if content script should be injected to the page or not. – Victor Portnov Oct 18 '19 at 08:15
0

In the document description, RequestContentScript is experimental, but it is not. In my test, Chrome version >= 60 is available, but allFrames does not seem to work.

Before using "RequestContentScript", you need to declare host permissions in "permissions".

https://developer.chrome.com/extensions/declarativeContent#type-RequestContentScript

enter image description here

weiya ou
  • 2,730
  • 1
  • 16
  • 24