New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.
Starred by 4 users

Issue metadata

Status: Duplicate
Merged: issue 58007
Owner: ----
Closed: Nov 2014
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 3
Type: Feature



Sign in to add a comment

Support optional_content_scripts, similar to optional_permissions and content_scripts

Reported by robwu...@gmail.com, Jul 26 2013

Issue description

Feature request: Allow developers to declare optional content scripts via the manifest file. The optional content scripts can be enabled by requesting the host permissions for the chrome.permissions API.

Use case: The Chrome Web Store disables extensions whenever new permissions/content scripts are added. This is a terrible experience for developers, because we loose users whenever this happens. Whenever we want to add a new site for a content script, we have to use the tabs API to dynamically inject the content script as a response to the chrome.onUpdated event. An alternative is to use the webNavigation API, but this requires yet another scary permission ("Access your tabs and browsing activity"). Either method is sub-optimal, because it requires the use of a permanent background page.

Example of requested API:

    // manifest.json
    ...
    "optional_content_scripts": [{
        "matches": ["*://stackoverflow.com/*"],
        "js": ["contentscript.js"]
    }],
    "options_page": "options.html"
    ...

The optional_content_scripts API follows the same semantics as the existing content_scripts key. To enable the content script, the developer should request the host permissions:

    // options.js
    document.querySelector('grant-extra-permissions').onclick = function() {
        // This API already exists:
        chrome.permissions.request({
            origins: ['*://stackoverflow.com/*']
        });
    };

If a developer wants to disable the content script, they either have to add a check in the content script, or revoke the permission. This is consistent with the current situation.

When the developer has already access to the given host (via another content_scripts entry or via the "permissions" manifest field), the optional content script is enabled by default.


labels: Cr-Platform-Extensions
 

Comment 1 by robwu...@gmail.com, Aug 16 2013

Another accepted way of supporting this feature is to add a chrome.declarativeWebRequest.ExecuteScript action that works like the chrome.tabs.executeScript API. This is also a great way to conditionally enable/disable content scripts, depending on whether they're load in the context of main frames.

A possible problem with implementing this is that web requests are not necessarily tied to a final navigation. At least the current semi-declarative implementation of content scripts (using chrome.declarativeWebRequest.SendMessageToExtension + chrome.tabs.executeScript) suffers from the issue - see issue 257956.

Comment 2 by kgra...@gmail.com, Aug 17 2013

I think another solution would be to expose a new method to chrome.tabs: chrome.tabs.queryTabMatchesOrigin that would allow you to bind to tabs that match a given origin string that you have explicit permission for, then you would be able to manually do the content script injection yourself.

You could implement this in a background page using polling, simply chrome.tabs.query repeatedly with your host match (does not even require chrome.tabs permission), but an edge triggered version would be nicer.

Comment 3 by robwu...@gmail.com, Aug 18 2013

@2
Your "chrome.tabs.queryTabMatchesOrigin" can easily be implemented in JavaScript, without significant performance hits: http://stackoverflow.com/a/12436854/938089

And using chrome.tabs.query repeatedly (I assume you meant in setInterval or something similar) is a terrible solution in terms of performance. The `chrome.tabs.onUpdated` and/or chrome.webNavigation.onCommitted events can already be used to conditionally execute scripts.
However, these methods are non-declarative. The pattern matching has to be done in JavaScript, and since these events are triggered quite often, the event page is revived too often, almost to the point that using a background page is better.

Comment 4 by kgra...@gmail.com, Aug 18 2013

#3, Thanks for the link. I ended up implementing something similar, only I don't want to request access to "tabs" (a very scary looking permission prompt) which would let me check the url matches like you suggest. I instead on EVERY onUpdated I try to run executeScript with inline code that returns a result (window.location.origin) to the executeScript result callback. If it fails (returns undefined), I know I didn't have access to that tab, otherwise, it sends window.location.origin to the executeScript callback, and I can then run my actual content script.
Perhaps it would make most sense to expose the URL for onUpdated for tabs that match current permission set, even without "tabs" permission.
Labels: -Type-Bug Type-Feature
Cc: ranjitkan@chromium.org
Labels: Cr-Webstore
Status: Untriaged

Comment 8 by robwu...@gmail.com, Sep 2 2013

@manoranj...@chromium.org

I see that there is a small error in my initial post.
If you're able to, please edit my initial post as follows:

" Use case: The Chrome Web Store disables extension ... "
" Use case: Chrome disables extension ... "

The limitation that drivers this feature request is not related to the Chrome Web store, but Chromium / Google Chrome.
And change Cr-Webstore to Cr-Platform-Extensions
Labels: -Cr-Webstore Cr-Platform-Extensions
[Updated as per comment#8]: 

Use case: Chrome disables extensions whenever new permissions/content scripts are added. This is a terrible experience for developers, because we loose users whenever this happens. Whenever we want to add a new site for a content script, we have to use the tabs API to dynamically inject the content script as a response to the chrome.onUpdated event. An alternative is to use the webNavigation API, but this requires yet another scary permission ("Access your tabs and browsing activity"). Either method is sub-optimal, because it requires the use of a permanent background page.

Example of requested API:

    // manifest.json
    ...
    "optional_content_scripts": [{
        "matches": ["*://stackoverflow.com/*"],
        "js": ["contentscript.js"]
    }],
    "options_page": "options.html"
    ...

The optional_content_scripts API follows the same semantics as the existing content_scripts key. To enable the content script, the developer should request the host permissions:

    // options.js
    document.querySelector('grant-extra-permissions').onclick = function() {
        // This API already exists:
        chrome.permissions.request({
            origins: ['*://stackoverflow.com/*']
        });
    };

If a developer wants to disable the content script, they either have to add a check in the content script, or revoke the permission. This is consistent with the current situation.

When the developer has already access to the given host (via another content_scripts entry or via the "permissions" manifest field), the optional content script is enabled by default.

Thank you.

Cc: yoz@chromium.org mpcomplete@chromium.org
Labels: -Pri-2 Pri-3
Status: Available
[extensions triage] Setting appropriate flags for feature request, +permissions

Comment 11 by rob@robwu.nl, Nov 23 2014

Mergedinto: 58007
Status: Duplicate

Sign in to add a comment