danf
danf

Reputation: 293

Call function in a webview from the main page

I'm attempting to embed a webview in a packaged app, and in that webview I will display a local page containing results from Google Custom Search, obtained via their javascript API. In order to do that I need to be able to call a function in the webview from the main page of the packaged app.

I could not get the function call from the main page to the webview to work however. I then made a bare bones example, and the function call still would not work. I've included those files below.

I am trying two methods - to inject code, and to pass a message. While I can inject code to set the content of a div, and it works (#1 below), injecting code to call a function does not work (#2), and listening for a message and then calling a function also does not work (#3).

I'm assuming from what I've seen online that this should be possible, so I'm not sure why the function calling cases are not working. If anyone can give me some direction as to why it is not working, I would much appreciate it. Thanks!

index.html

<html>
<head>
  <title>Test</title>
  <script type="text/javascript" src="scripts.js"></script>
</head>

<body>
    <input type="text" id="query1" value="test1" /><input type="button" id="submit1" value="Submit #1" />
    <input type="text" id="query2" value="test2" /><input type="button" id="submit2" value="Submit #2" />
    <input type="text" id="query3" value="test3" /><input type="button" id="submit3" value="Submit #3" />

    <webview src="wv.html" id="wv" partition="wv"></webview>
</body>
</html>

wv.html

<html>
<head>
    <script>
        function testCall(mesg) {
            document.getElementById('showtext').textContent = mesg;
        }

        document.addEventListener('DOMContentLoaded', function() {
            // Set up message event handler:
            window.addEventListener('message', function(event) {
                // call function to display the data
                testCall(event.data);
            });
        });
    </script>
</head>

<body>

<h3>Webview:</h3>

<div id="showtext"></div>

</body>
</html>

scripts.js

function submit1ButtonClicked() {
    document.getElementById('wv').executeScript({ code: "document.getElementById('showtext').textContent = '" + document.getElementById('query1').value + "';" });
}

function submit2ButtonClicked() {
    document.getElementById('wv').executeScript({ code: "testCall('" + document.getElementById('query2').value + "');" });
}

function submit3ButtonClicked() {
    document.getElementById('wv').contentWindow.postMessage(document.getElementById('query3').value, '*');
}

// Initialize the listeners
function initListeners() {
    document.getElementById("submit1").onclick = submit1ButtonClicked;
    document.getElementById("submit2").onclick = submit2ButtonClicked;
    document.getElementById("submit3").onclick = submit3ButtonClicked;

    document.getElementById('wv').addEventListener('message', function(event) {
        document.getElementById('showtext').textContent = event.data;
    });
}

window.onload = initListeners;

main.js

chrome.app.runtime.onLaunched.addListener(function() {
  // Center window on screen.
  var screenWidth = screen.availWidth;
  var screenHeight = screen.availHeight;
  var width = 300;
  var height = 300;

  chrome.app.window.create('index.html', {
    id: "TestWebviewID",
    bounds: {
      width: width,
      height: height,
      left: Math.round((screenWidth-width)/2),
      top: Math.round((screenHeight-height)/2)
    }
  });
});

manifest.json

{
    "manifest_version": 2,
    "name": "TestWebview",
    "version": "1",
    "minimum_chrome_version": "25",
    "app": {
        "background": {
            "scripts": ["main.js"]
        }
    },
    "permissions": [
        "webview"
    ],
    "webview": {
        "partitions": [
            {
                "name": "wv",
                "accessible_resources": ["wv.html"]
            }
        ]
    }
}

Upvotes: 0

Views: 1153

Answers (2)

danf
danf

Reputation: 293

In regards to getting the injected function call method (#2) to work, Fady Samuel on the Chromium Apps discussion list said:

Script injected into a <webview> lives in an "isolated world". See here for a description of what isolated worlds are: https://developer.chrome.com/extensions/content_scripts#execution-environment

A work around is to instead inject a script tag. Script within a script tag will run in the same world as the script in the guest content.

Upvotes: 1

danf
danf

Reputation: 293

I found that if I added the following to manifest.json then the message passing (method #3) would work:

"sandbox": {
  "pages": ["wv.html"]
}

Upvotes: 0

Related Questions