Chrome apps webview tag - how to quickly inject CSS or JS?

I am writing an application that needs to embed a specific website in <webview>

and inject some CSS and JS codes to adapt that website for viewing on a specific touch device.

The problem is that I can't find a way to inject my code on page load, instead the code is injected AFTER the page is rendered and as a result all changes become visible.

While code injection works fine with chrome extensions and script content (by setting the attribute run_at

to document_end

on manifest.json, this is not the case for webviews.

This is my code:

manifest.json

{
  "name": "App",
  "version": "0.0.1",
  "manifest_version": 2,

  "app": {
    "background": {
      "scripts": [ "main.js" ]
    }
  },

  "permissions": [
    "webview"
  ]
}

      

main.js

chrome.app.runtime.onLaunched.addListener(function() {
  chrome.app.window.create('index.html', { state: "normal" },
    function(win) {
      win.contentWindow.onload = function() {
        var wv = this.document.querySelector('webview');
        wv.addEventListener('contentload', function(e) {
          this.insertCSS({ code: "body { background: red !important; }" });
        });
      }
    }
  );
});

      

index.html

<webview src="https://developer.chrome.com/apps/tags/webview" style="width: 100%; height: 100%;"></webview>

      

Same in the Gist: https://gist.github.com/OnkelTem/ae6877d2d7b2bdfea5ae

If you try this app you will see that only after the webview is loaded and fully rendered, my CSS rule is applied and the page background turns red. In this example I am using the webview contentload event, but I have also tried all other webview events: loadstart , loadstop , loadcommit . > - without any difference.

I also tried using webview.contentWindow, but this is an EMPTY object all the time, despite the documentation it should be used.

Any ideas? Is it even possible?

+3


source to share


1 answer


First of all, use loadcommit

event
instead of contentload

event
.

Second, add runAt: 'document_start'

to the call webview.insertCSS

(this also applies webview.executeScript

if you ever want to use it). The implementation executeScript

is shared with the execute extension implementation, but unfortunately the application documentation is incomplete. Look chrome.tabs.insertCSS

until the application documentation is fixed.

Here's an example that works as desired:

chrome.app.runtime.onLaunched.addListener(function() {
  chrome.app.window.create('index.html', { state: 'normal' },
    function(win) {
      win.contentWindow.onload = function() {
        var wv = this.document.querySelector('webview');
        // loadcommit instead of contentload:
        wv.addEventListener('loadcommit', function(e) {
          this.insertCSS({
            code: 'body { background: red !important; }',
            runAt: 'document_start'  // and added this
          });
        });
      }
    }
  );
});

      



Note. Even though the previous one works, I recommend putting the script that handles the webview in index.html because the resulting code is a lot neat.

// main.js
chrome.app.runtime.onLaunched.addListener(function() {
  chrome.app.window.create('index.html', { state: 'normal' });
});

      

<!-- index.html -->
<webview src="https://developer.chrome.com/apps/tags/webview" style="width: 100%; height: 100%;"></webview>
<script src="index.js"></script>

      

// index.js
var wv = document.querySelector('webview');
wv.addEventListener('loadcommit', function() {
  wv.insertCSS({
    code: 'body { background: red !important; }',
    runAt: 'document_start'
  });
});

      

+4


source







All Articles