Google Chromeを入れたついでにGoogle Gearsを試してみた

ChromeにはGoogle Gearsが組み込まれてます。

Gearsは単なるrdbAPIと思ってたけど、Desktop/LoacalServer/Workerなどいろいろあるようで、順次試してみようと思う。


まずは、databaseだが、ResultSetがnext()でカーソルを進める仕様である。このため、whileループ中にnextを入れ忘れたりすると無限ループに入って、ブラウザを落とさなくてはいけなくなったりするんだけれど、Chromeはタブを落とすだけでいいので、このためだけでも十分いけそうだ。Firefoxでドキュメント見ながらやっちゃうと、ドキュメントも無限ループ状態のテストページと一緒に落とされるのはきついだろうなあ(普通は長時間処理を落とすようなダイアログがでるけれど、出ないことも多々ある)。デフォルト状態でテキストエリアがリサイズ可能なのもいい。

LocalServerはurlに対応するデータをキャッシュするようだけど、caputure系のメソッドだけのようなので、キャッシュしたものは自動で使うのかな。ブラウザで強制更新とは独立してるとなると、GearsベースサイトはLocalServerの更新手段を用意しないと管理画面で消さない限りずっとその時点のキャッシュが使われることになるのか。

gears_init.js

function initFactory() {
  if (window.google && google.gears) return google.gears.factory;

  var factory;
  if (typeof GearsFactory != 'undefined') { // firefox
    factory = new GearsFactory();
  } else if ((typeof navigator.mimeTypes != 'undefined') &&
      navigator.mimeTypes["application/x-googlegears"]) {
    // safari/chrome: hidden object tag
    factory = document.createElement("object");
    factory.style.display = "none";
    factory.width = factory.height = 0;
    factory.type = "application/x-googlegears";
    document.documentElement.appendChild(factory);
  } else if (window.ActiveXObject) { // ie
    try {
      factory = new ActiveXObject('Gears.Factory');
      if (factory.getBuildInfo().indexOf('ie_mobile') != -1) {
        factory.privateSetGlobalObject(this);
      }
    } catch (ex) {}
  } else { // not installed
    throw "Gears Not Found";
  }

  window.google = {}
  window.google.gears = {}
  window.google.gears.factory = factory;
  return factory;
}

Chromeで使うだけならSafari用の部分だけあればいいが、一応全ブラウザ向け

database

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script src="gears_init.js"></script>
<script>//
var db;
function doInit() {
  var factory = initFactory();
  db = factory.create('beta.database');  // arg must be 'beta.database'
}
function doCreateDB() {
  db.open();
  try {
    var rs = db.execute('create table TestData (id int, name text)');
    p(rs);
  } finally {
    db.close();
  }
}
function doInsert() {
  db.open();
  try {
    var rs = db.execute('insert into TestData values (?, ?)', [0, "Taro"]);
    p(rs);
  } finally {
    db.close();
  }
}
function doLoad() {
  db.open();
  try {
    var rs = db.execute('select * from TestData');
    p(rs);
  } finally {
    db.close();
  }
}
function p(rs) {
  if (!rs.isValidRow()) return;
  var result = "";
  for (var i = 0; i < rs.fieldCount(); i += 1) {
    result += "[" + rs.fieldName(i) + "] ";
  }
  var hl = result.length;
  result += "\n";
  for (var i = 0; i < hl; i += 1) result += "-";
  result += "\n";
  while (rs.isValidRow()) {
    for (var i = 0; i < rs.fieldCount(); i += 1) {
      result += "[" + rs.field(i) + "] ";
    }
    result += "\n";
    rs.next();
  }
  rs.close();
  document.getElementById("out").value = result;
}
//</script>
</head>
<body onload="doInit()">
<input type="button" value="create db/table" onclick="doCreateDB()"/>
<input type="button" value="insert" onclick="doInsert()"/>
<input type="button" value="load" onclick="doLoad()"/>
<br/>
<textarea id="out"></textarea>
</body>
</html>

localserver

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script src="gears_init.js"></script>
<script>//

var lserver;
function doInit() {
  var factory = initFactory();
  lserver = factory.create('beta.localserver');  // arg must be 'beta.localserver'
}
function doCapture() {
  var store = lserver.createStore("mystore");
  store.capture("foo.txt"); // update and cache
  // browser cannot update it by reload button or Shift-F5
}

//</script>
</head>
<body onload="doInit()">
<input type="button" value="capture" onclick="doCapture()"/>
<br/>
<textarea id="out"></textarea>
</body>
</html>

一度captureすると、サーバ上のfoo.txtを更新しても、このHTMLからcaptureしなおさない限り、ブラウザでのfoo.txtの表示はShift+F5を押そうが更新されない。

改めてみると、Goelocationといい、Gearsにはハンドヘルド向けの機能に向いたものが多いなあ。