34

Introduction
Google chrome has a feature that allows you to create shortcuts to web pages and make them appear like traditional desktop applications.

For example, a shortcut to twitter mobile might be

C:\Users\<username>\AppData\Local\Google\Chrome\Application\chrome.exe  --app=https://mobile.twitter.com/

The file icon for this app is stored in

C:\Users\<username>\AppData\Local\Google\Chrome\User Data\Default\Web Applications\mobile.twitter.com\https_80

My Question
It's been a while since I've used this feature and I seem to remember that you could add your own JavaScript files to the app folder which were included when the application was loaded. However, I cannot find any documentation that discusses this feature but I'm 99% certain it exists.

Does anyone have any details if this feature is available and what files I need to create?

Clarification

I'm basically opening a webpage using Chrome's "Application Shortcut" and I want this webpage to refresh every x seconds. However, I do not have control over this webpage.

I'm sure in older versions of Chrome this used to be possible... unless I'm going mad.

Cœur
  • 37,241
  • 25
  • 195
  • 267
GateKiller
  • 74,180
  • 73
  • 171
  • 204
  • Can you clarify what exactly you want to do with your javascript file? When you say ***included when the application was loading***, what do you exactly mean? Since I assume you want a link to a website, what is the purpose of the javascript file? – agarcian Feb 16 '12 at 09:38
  • @GGG I don't see what is the problem of asking that. There might be other ways to do what he is intending to do. knowing the ultimate purpose might help people answer in a better way rather than guessing. Some people might answer like this: *I'm not sure if this is exactly what you're after* indicating that they are not sure exactly what the original purpose of the question is. – agarcian Feb 16 '12 at 10:03
  • @agarcian fair enough. I assumed he wanted full user script capabilities, I didn't even think about cases like this. – Dagg Nabbit Feb 16 '12 at 10:10
  • Just for reference I wrote an answer suggesting to set it up as a hosted app and including content scripts, but I just tried it and apparently chrome doesn't allow content scripts in hosted apps, so I'm deleting the answer. – Dagg Nabbit Feb 16 '12 at 10:24

2 Answers2

103

Chrome extensions and their content scripts are also loaded when Chrome starts in the App mode.

So, you can create a simple extension, which injects JavaScript code in the page as follows:

1. Create a manifest.json file

{
  "name": "Run code on twitter mobile",
  "version": "1.0",
  "manifest_version": 2,
  "content_scripts": [
    {
      "js": [
        "contentscript.js"
      ],
      "matches": [
        "https://mobile.twitter.com/*"
      ]
    }
  ],
  "web_accessible_resources": [
    {
      "resources": [
        "script.js"
      ],
      "matches": [
        "https://mobile.twitter.com/*"
      ]
    }
  ]
}

2. The content script

Then, create a file called contentscript.js, and add the desired JavaScript code.
This script is included at every load of the matched page. All DOM methods, via the document object is directly available. However, window and document.defaultView do not point to the window object in the page [source].

If you want to access global methods or properties, you have to dynamically create a <script>, and inject it in the page (see Building a Chrome Extension - Inject code in a page using a Content script).

contentscript.js

var s = document.createElement('script');
s.src = chrome.extension.getURL('script.js');
(document.head||document.documentElement).appendChild(s);
s.onload = function() {
    s.parentNode.removeChild(s);
};

3. The script which will be injected

Then, create a file called script.js, and place it in the same folder as manifest.json and contentscript.js. The code in script.js executes as if it was a true part of the affected page.

Reference for content scripts.

Reference for web accessible resources.

xingming2020
  • 5
  • 1
  • 2
Rob W
  • 341,306
  • 83
  • 791
  • 678
  • 4
    To load an extension, navigate to `chrome://extensions/`, activate `Developer mode`, and click on the `Load unpacked extension` button. Then, select the directory which contains your `manifest.json` (and `contentscript.js`, `script.js`) file, then confirm. If you want to test the extension in the Private browsing mode, expand the description, and check the box. When you update your script, you **have to** click on `Reload extension`, to see the changes. – Rob W Feb 17 '12 at 13:29
  • Because all I wanted to do was refresh the page every 30 seconds, all I had to insert into contentscript.js was: setTimeout( "location.reload(true);", 30 * 1000 ); – GateKiller Feb 20 '12 at 10:19
  • 2
    @GateKiller You'd better use `setInterval(function(){location.reload(true);}, 30000);` Using a string as an argument for `setTimeout` is discouraged. I replaced `setTimeout` with `setInterval`, to deal with accidental navigation cancelling (which could break your script). If you actually like this feature, use `setTimeout(function(){location.reload(true);},3000);`. – Rob W Feb 20 '12 at 10:24
  • @RobW: What are differences between `window object of page` and `window object of content script`, i have taken a cursory look most of features looked similar barring few page related prototypes, any information on differences? – Sudarshan Dec 25 '12 at 07:35
  • @Sudarshan Content scripts run in an own execution context. Most of the DOM methods (eg `appendChild`) are available to both contexts (page and content scripts), but at the same time, they're different. For instance, if you use `document.appendChild = null;` in the page, the content script will still see an unmodified method when it accesses `document.appendChild`. This separation/proxying of context exists for all objects -including `window`- in the page and content script. – Rob W Dec 25 '12 at 09:52
  • @RobW: Please Correct me if i am wrong, does this mean they make a copy of original page window and give it to content script `document.defaultview` ? – Sudarshan Dec 25 '12 at 10:04
  • 1
    @Sudarshan It's not copied (that'd be expensive), but accessed via a proxy. To get it clear, the `window`, `parent`, `top`, `frames`, `document.defaultView`, etc. all refer to the global object in a content script, which is completely different from the page's one. – Rob W Dec 25 '12 at 10:37
  • @RobW: Absolutely stellar tutorials - thanks! But the Chrome documentation indicates that content scripts must have both "tab" and "host" permissions in order to inject code. You may wish to include a permissions section in your `manifest.json` file. – Dave Jan 05 '14 at 19:24
  • @Dave The `tabs` permission is [only needed under a few circumstances](https://developer.chrome.com/extensions/tabs.html#manifest), programmatic script execution is not one of them. Further, the host permissions are not needed, because they are implied by the `"matches"` key of the content script declaration in the manifest file. – Rob W Jan 05 '14 at 19:49
  • Thanks - the documentation https://developer.chrome.com/extensions/declare_permissions.html and https://developer.chrome.com/extensions/content_scripts.html#pi could be clearer on that point, both by mentioning that host permissions are NOT needed, and that `web_accessible_resources:` IS. – Dave Jan 05 '14 at 20:47
  • Is there any way to send message back to the background script using the second (2. The content script) option? – Rod Lima Mar 07 '19 at 23:11
  • 1
    I got an error using this because the format for "web_accessible_resources" changed, see https://developer.chrome.com/docs/extensions/mv3/manifest/web_accessible_resources/ . One should do something like: ```"web_accessible_resources": [ {"matches": ["http://mobile.twitter.com/*"], "resources":["script.js"] } ]``` – Maarten Derickx Apr 27 '21 at 14:07
  • s.src = chrome.extension.getURL('script.js'); //deprecated should be replaced with s.src = chrome.runtime.getURL('script.js'); – ezhupa99 Sep 04 '22 at 13:38
-5

I assume you want to include a javascript to do some 'launching' of the application, perhaps to resize the window when loading your target url?

Here is something you could do, as suggested in this post

Create an Html page locally that contains the javascript that you need to run.

Change this: C:\Users\<username>\AppData\Local\Google\Chrome\Application\chrome.exe --app=https://mobile.twitter.com/

to this:

C:\Documents and Settings\<username>\Local Settings\Application Data\Google\Chrome\Application\chrome.exe” –app=file:///C:/Documents%20and%20Settings/<username>/My%20Documents/My %20Custom%20Shortcuts/twitter_mobile_launcher.html

and your twitter_mobile_launcher.html file would look like this:

<html>  
 <head>  
  <script type="text/javascript">  
   // Do what you need with your javascript, for example, resizing your window...
   window.resizeTo(300,400);  
   window.moveTo(300,0);  
   window.location = "https://mobile.twitter.com/";  
  </script>  
 </head>  
 <body>  
  <h1>If you see this, the redirect did not work properly.</h1>  
 </body>  
</html>  
agarcian
  • 3,909
  • 3
  • 33
  • 55