サイドバーガジェット内にウェブページを表示する方法を調べてみた


ガジェット内にウェブページを表示するというのは,
一言で言えばガジェットとして動くウェブブラウザを作れないかな?ということに.
多分COMコンポーネントか何かを使えば簡単にできるんだろうなあ…….
今の私には,そこまでの技術が無いのでHTML+JavaScriptでできそうな範囲で.

目次

どうやって実現するか

ガジェットで簡易ブラウザを実現するといっても,
ガジェット自体がブラウザの上で動いています.
なので,問題はウェブページ内部にどうやって
任意のウェブページを表示させるかということになります.
ウェブページの中にウェブページを埋め込む…….
となれば,<frameset>,<iframe>,<object>が候補に上がります.
実際のところどれを使っても実現できそうな雰囲気ですね.
それぞれ試してみます.

今回は,実現方法を検証するためなのでDock/Undockの機能は付けず,
常にある程度の大きさを持った状態にします.

問題点

今まで色々試したところによると,
ガジェット内で新たなウェブページを開こうとするとIEを開いてしまいます.
例えば,アンカータグでウェブページを開くだけのガジェットを作って動かしてみて下さい.
つまり,次のようなガジェットです.

<html>
<head>
<title>Anchor test</title>
</head>
<body style="width: 600px; height: 600px;">
<a href="http://www.google.co.jp/" target="_self">リンクを開く</a>
</body>
</html>

動かしてみるとわかりますが,あえてtargetを_selfにしているのにGoogleが開かれるのはIEです.
まあ,これは考えてみれば当然で,HTMLを使って表示させているとはいえ,
あくまでこれはガジェットであってウェブページでは無いわけですから,
逆に言えばウェブページをそのまま表示できてしまってはおかしいとも言えます.

この制約により,今回紹介するあらゆる方法では,
ウェブページをガジェット内で表示することができるのは直接URLを指定した1階層までになります.
つまり,ガジェット内で開いたウェブページ内のリンクをクリックするとIEが起動するってことですね.

ひな形

3種類の方法は,どれも一部が異なるだけで基本機能は同じです.
そのひな形を記します.

ちなみにこのひな形をガジェットとして動かすと,
次の画像のようなガジェットになります.
(黒い枠線は後から描き足しました)

(2008/11/01追記: サンプルにGoogleの検索ページを表示したスクリーンショットを掲載していましたが,Googleのウェブページのスクリーンショットを勝手に掲載してはいけないらしいので,一旦画像を削除しました)

このガジェットは,何もしません.

gadget.xml

いつも通りです

<?xml version="1.0" encoding="utf-8" ?>
<gadget>
<name>Mini Browser</name>
<namespace>mitc.xrea.jp</namespace>
<version>1.0.0.0</version>
<author name="miff">
<info url="mitc.xrea.jp" />
</author>
<copyright>&#169; 2007</copyright>
<description>Tiny Browser</description>
<hosts>
<host name="sidebar">
<base type="HTML" apiVersion="1.0.0" src="MiniBrowser.html" />
<permissions>Full</permissions>
<platform minPlatformVersion="1.0" />
</host>
</hosts>
</gadget>

MiniBrowser.html

URL入力欄と移動ボタンを配置.
移動ボタンは,JavaScriptの関数と結び付けておく.

<html>
<head>
<link href="./default.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="main.js"></script>
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<title>Mini Browser</title>
</head>
<body>
<!-- URL入力欄 -->
<!-- テスト用にgoogleのURLを入れておく -->
<input type="text" id="navigateBox" value="http://www.google.co.jp/" />
<!-- 移動ボタン -->
<input type="button" id="action" value="移動" onclick="navigateBoxSubmit()" />
</body>
</html>

main.js

この関数にURLを開く動作を記述していきます.

function navigateBoxSubmit() {
}

default.css

bodyの大きさを大きめに取って後はブラウザっぽくURL入力欄と移動ボタンを配置.

body
{
width: 600px;
height: 600px;
}
#navigateBox
{
width: 80%;
}
#action
{
width: 10%;
}

iframe

iframeを使うと,ページ内に別のページを埋め込めます.
互換性の問題などであんまり使わないほうがいいと言われてきましたが,
Tridentで解釈されることが確実なガジェットでは,使っても問題無いでしょう.
(ガジェットが求めるHTML*1の仕様によってはやらない方がいいのかも…….とりあえず動作はします.)

MiniBrowser.html

bodyの中に次のコードを入れる

<div id="browsercontainer">
</div>

これは,iframeのコードを流し込むためのコンテナです.

main.js

function navigateBoxSubmit() {
var url = "";
url = navigateBox.value;
var html = "";
html += '<iframe id="browsermain" src="' + url + '" height="450" width="500">';
html += '</iframe>';
browsercontainer.innerHTML = html;
}

MainBrowser.htmlに追加したdivタグの内側にiframeを流し込みます.
この時にURLを指定しておくことで目的のページを閲覧します.
直接iframeのsrcを変更することを試みてみましたが,それはうまくいきませんでした.

*1 : もしくはXHTML

object

MiniBrowser.html

bodyの中に次のコードを入れる

<div id="browsercontainer">
</div>

これは,objectのコードを流し込むためのコンテナです.

main.js

function navigateBoxSubmit() {
var url = "";
url = navigateBox.value;
var html = "";
html += '<object id="minibrowser" type="text/html" data="' + url + '" style="height: 450px; width: 500px;">';
html += '</object>';
browsercontainer.innerHTML = html;

iframeと同じ要領です.
動作も同じ.

frameset

framesetを使ったやり方は,iframeやobjectを使ったやり方とはかなり異なります.
フレームを使ったウェブページ作成は,今となっては使われることが少なくなってきましたが…….
ところで,結論から書くとこのやり方は失敗でした.
フレームのIDを指定してURLを開こうとしてもIEが開きますし,
ためしに普通にアンカータグで異なるフレームにページをロードしようとしてもIEが開きます.
これは,本エントリーの冒頭で述べた制約があるからです.
そして,objectタグなどで取っているのと同じようにframesetの中身を丸ごと置き換える方法もうまくいきませんでした.
画面は変わるんですが,それはページが開くのではなく真白になってしまうのです.

MiniBrowser.html

<html>
<head>
<link href="./default.css" rel="stylesheet" type="text/css" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<title>Mini Browser</title>
</head>
<frameset id="fundamental" rows="50%,*">
<frame src="./Navigator.html" name="documentNavigator">
<frame src="http://www.google.co.jp/" name="documentMain">
</frameset>
</html>

Navigator.html

このファイルを追加.

<html>
<head>
<script type="text/javascript" src="main.js"></script>
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<title>Navigator</title>
</head>
<body>
<input type="text" id="navigateBox" value="http://www.google.com/search?hl=ja&lr=lang_ja&ie=UTF-8&oe=UTF-8&num=50&q=" />
<input type="button" id="action" value="移動" onclick="navigateBoxSubmit()" />
</body>
</html>

main.js

function navigateBoxSubmit() {
var url = "";
url = navigateBox.value;
var html = "";
html += '<frame src="./Navigator.html" name="documentNavigator">';
html += '<frame src="' + url + '" name="documentMain">';
parent.fundamental.innerHTML = html;
}

default.css

フレームにはbodyがありません.

#fundamental
{
width: 600px;
height: 600px;
}
#navigateBox
{
width: 80%;
}
#action
{
width: 10%;
}

まとめ

フレームを使ったやり方は失敗でしたが,
iframeもobjectもページを開くだけなら普通にできました.
通常のページでやるようなsrcを操作するやり方ではなく,
あらかじめURLを書き込んだタグを新しく流し込んで置き換える点がポイントのようです.
どこかの偉い人は,きっともっとスマートにできる方法を知っているに違いない.
とりあえずこれだけでもある程度は望みがかなったので今回はひとまず良しとしておきます.

Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>