2014年5月9日金曜日

ChromeAppsでWebViewのDOM操作

Chrome packaged apps からWebView内に表示されたWebページのDOMを操作する方法です。

manifest.json
{
  "name": "webview example app",
  "description": "webview example app",
  "version": "0.1",
  "app": {
    "background": {
      "scripts": ["background.js"]
    }
  },
  "icons": { "128": "128.png" },
  "permissions": [
    "webview"
  ]
}

main.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
</head>
<body>
  <input id="txtUrl" type="text" value="http://www.google.com">
  <button id="btn">Go</button>
  <hr>
  <div id="indicator"></div>
  <webview id="myWebview" style="width:620px; height:460px"></webview>
</body>
<script src="app.js"></script>
</html>

background.js
chrome.app.runtime.onLaunched.addListener(function() {
  chrome.app.window.create('main.html', {
    'bounds': {
      'width': 640,
      'height': 480
    }
  });
});

app.js
/*
  Fetch the page title on webview from parent window
*/

var indicator = document.getElementById("indicator");
var wv = document.getElementById("myWebview");

document.getElementById("btn").onclick = function(e){
  var url = document.getElementById("txtUrl").value;
  wv.src = url;
  
  wv.addEventListener("loadstart", function() {
    indicator.innerText = "loading...";
  });
  wv.addEventListener("loadstop", function() {
    indicator.innerText = "";
  });
  wv.addEventListener('contentload', function() {
    execScripts(wv);
    // postMessage to webview
    console.log("Requesting title...");
    wv.contentWindow.postMessage({
      command: 'getTitle'
    }, '*');
  });
}

// onMessage from webview
window.addEventListener('message', function(e){
  console.log("Received title:", e.data.title);
});


function execScripts(wv) {
  console.log("execScripts");
  // change styles
  wv.insertCSS({
    code: "body { background-color: black; }"
  });
  // execute script
  wv.executeScript({
    code:
        "window.addEventListener('message', function(e){"
      + "  console.log('Received command:', e.data.command);"
      + "  if(e.data.command == 'getTitle'){"
      + "    console.log('Sending title...');"
      + "    e.source.postMessage({ title: document.title }, e.origin);"
      + "  }"
      + "});"
  });
}

Log

app.js:
execScripts
Requesting title...
Received title: Google 

webview:
Received command: getTitle
Sending title... 

<webview>.executeScript({code:...}) でwebviewに表示されているページにJSコードを送り込んでいるのがポイント。
webviewがページロードを完了したら('contentload')、親ウィンドウ側からexecuteScriptでJSコードを送り込み、'getTitle'コマンドをwebview側へpostMessage()。
webview側は親ウィンドウからのコマンドを受け取ってwebview上のWebページのタイトルを親に返しています。

0 件のコメント:

コメントを投稿