Adobe AIRで作るデスクトップアプリケーション

第12回HTMLコンテンツの利用

HTMLの表示

Adobe AIRにはSafari等のブラウザで採用されているWebKitエンジンが実装されており、HTMLのレンダリングやJavaScriptの実行が可能です。これはAIRの大きな特長の一つと言えるでしょう。今回はAIRアプリケーションにHTMLコンテンツを追加する方法について解説します。

HTMLの表示方法はとても簡単です。まずはFlashでの実装方法から見てみましょう。次のサンプルはステージにgihyo.jpのトップページを表示します。

import flash.html.HTMLControl;
var html:HTMLControl = new HTMLControl();
html.width = stage.stageWidth;
html.height = stage.stageHeight;
html.load(new URLRequest("http://gihyo.jp/"));
addChild(html);
HTMLの表示を簡単に行える
HTMLの表示を簡単に行える

AIR APIでHTMLコンテンツの処理を担当するのはHTMLControlクラス(flash.htmlパッケージ)です。このクラスはDisplayObjectの一つで、Spriteクラスのサブクラスです。したがって、インスタンスを作成して任意の表示リストに加えればステージ上に表示されます。回転したりフィルタを掛けることも可能です。もちろん、具体的なコンテンツを読み込まなければ何も表示されません。コンテンツを読み込むには、URLを指定したURLRequestオブジェクトを作成してload()メソッドに渡します。また、HTMLControlオブジェクトの幅(widthプロパティ)と高さ(heightプロパティ)のデフォルト値は0なので、ここではステージと同じサイズに変更しています。

なお、デフォルトの状態でウィンドウをリサイズすると、それに合わせてコンテンツも拡大/縮小されてしまいます。コンテンツのスケールを変えずに表示領域の広さが変わるようにするには、次のようなコードを追加すればよいでしょう。

stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.addEventListener(Event.RESIZE, stageResizeHandler);
function stageResizeHandler(e:Event):void {
  html.width = stage.stageWidth;
  html.height = stage.stageHeight;
}

続いてFlex Builderでの実装方法です。Flex BuilderにはHTMLコンテンツを表示するためのHTMLコンポーネントがあるので、それを使います。

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
  <mx:HTML x="0" y="0" width="100%" height="100%" location="http://gihyo.jp/"/>
</mx:WindowedApplication>

このようにHTMLコンポーネントを配置して、locationプロパティにURLを指定するだけです。width/heightプロパティを100%にしておけばウィンドウサイズに合わせて表示領域も変わりますし、スクロールバーまで付いています。

Flashでのスクロールバー

Flex BuilderのHTMLコンポーネントにはもともとスクロールバーが付いていますが、Flashでは独自にスクロール処理を組み込む必要があります。スクロールの実装にはHTMLControlクラスの下記のプロパティを使います。

プロパティ
width:NumberHTMLControlオブジェクトの幅
height:NumberHTMLControlオブジェクトの高さ
htmlWidth:NumberHTMLコンテンツの幅
htmlHeight:NumberHTMLコンテンツの高さ
scrollH:Number水平方向のスクロール位置
scrollV:Number垂直方向のスクロール位置

スクロールの最大値は、コンテンツとオブジェクトのサイズの差で求められます。次のコードは水平/垂直共に最大までスクロールする例です(htmlはHTMLControlオブジェクト⁠⁠。

var maxScrollH:Number = html.htmlWidth - html.width;
var maxScrollV:Number = html.htmlHeight - html.height;
html.scrollH = maxScrollH;
html.scrollV = maxScrollV;

履歴の移動

ウェブブラウザのようなアプリーケーションを作成する際は、ページの履歴を行き来する機能が必要になるかも知れません。HTMLControlクラスおよびHTMLコンポーネントには、ちょうどJavaScriptのhistoryオブジェクトに相当する機能が用意されています。履歴に関するメソッド/プロパティには次のものがあります。

メソッド/プロパティ命令/
historyBack()戻る
historyForward()進む
historyGo()指定したステップ数移動する(正の値は進む/負の値は戻る)
getHistoryAt()指定した位置のエントリを取得する
historyLength:uint履歴リストの長さ
historyPosition:uint履歴リスト内の現在の位置

次のコードは戻る/進むボタンの実装例です(htmlはHTMLControlオブジェクト⁠⁠。

prev_btn.addEventListener(MouseEvent.CLICK, prevClickHandler);
next_btn.addEventListener(MouseEvent.CLICK, nextClickHandler);
function prevClickHandler(e:MouseEvent):void {
  html.historyBack();
}
function nextClickHandler(e:MouseEvent):void {
  html.historyForward();
}

なお、履歴リスト内の各エントリはページのURLやタイトルを保持したHTMLHistoryItemオブジェクト(flash.htmlパッケージ)です。

動的にHTMLを作成する

外部のHTMLを読み込む以外に、ActionScriptで作成したHTMLを読み込むことも可能です。HTMLは単純にストリングとして用意したものを使います。場合によってはXMLクラスを利用すると記述が楽になるでしょう。次の例では、簡単なJavaScriptを交えたHTMLを作成し、それを読み込んでいます。

import flash.html.HTMLControl;
var js:String = 'function jsFunc() { return "Hell from JS." }';
var xhtml:XML = 
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script>{js}</script>
  </head>
  <body>
    <p id="msg">StringからつくったHTML</p>
  </body>
</html>
var html:HTMLControl = new HTMLControl();
html.width = stage.stageWidth;
html.height = stage.stageHeight;
html.loadString(xhtml.toString());
addChild(html);

Flashでは、上記のコードのようにHTMLControlオブジェクトに対してloadString()メソッドを呼び出すことでストリングのHTMLを表示できます。Flex BuilderでHTMLコンポーネントを使用する場合は、コンポーネントのhtmlTextプロパティにHTMLを割り当てることで表示できます。

DOMへのアクセス

アプリケーションSandBox内のSWFコンテンツは、HTMLControlオブジェクトに読み込まれたページのDOMにアクセスできます。HTMLの読み込み完了後DOMが作成されるとEvent.COMPLETEイベントが通知されるので、それを待って処理を行います。前項のサンプルに次のコードを追加してみましょう。

html.addEventListener(Event.COMPLETE, completeHandler);
function completeHandler(e:Event):void {
  trace(html.window.document.getElementById("msg").innerHTML);
  trace(html.window.jsFunc());
  html.window.document.getElementById("msg").innerHTML = "HTMLを書き換えました";
}

このように、JavaScriptのwindowオブジェクトに相当するwindowプロパティ(HTMLControl.window)を通して、ページの要素やJavaScriptの関数にアクセスします。

HTML関連のイベント

HTMLControlクラスでは、次のようなイベントが発生します(flash.eventsパッケージ⁠⁠。Event.HTML_BOUNDS_CHANGEとEvent.SCROLL以外はHTMLコンポーネントでも共通です。

イベント発生タイミング
Event.COMPLETE読み込み処理が完了してHTMLページのonloadイベントが発生した直後。
Event.DOM_INITIALIZEHTMLドキュメント作成後、DOMノードを実際に作成する前。
Event.HTML_BOUNDS_CHANGEhtmlWidthまたはhtmlHeightプロパティが変わった時。
Event.HTML_RENDERコンテンツの表示内容が更新された時。
Event.LOCATION_CHANGElocationプロパティが変わった時。
Event.SCROLLscrollHまたはscrollVプロパティが変わった時。
HTMLUncaughtJavaScriptExceptionEvent.
UNCAUGHT_JAVASCRIPT_EXCEPTION
⁠※実際は改行しません)
JavaScript側でキャッチしていない例外が発生した時。

PDFの表示

HTMLControlオブジェクトのload()メソッドあるいはHTMLコンポーネントのlocationプロパティにPDFファイルのURLを渡すことで、PDFの表示も可能です。ただし、実行環境にAdobe Reader 8.1以降がインストールされている必要があります。PDFの表示が可能かどうかは、HTMLControl.pdfCapabilityプロパティで確認できます。

import flash.html.HTMLControl;
import flash.html.HTMLPDFCapability;
if (HTMLControl.pdfCapability == HTMLPDFCapability.STATUS_OK) {
  trace("PDFの表示が可能です。");
}

上記コードから分かるように、HTMLControl.pdfCapabilityプロパティの取り得る値は、HTMLPDFCapabilityクラスの定数に定義されています。

定数意味
ERROR_INSTALLED_READER_NOT_FOUNDAdobe Readerが見つかりません。
ERROR_INSTALLED_READER_TOO_OLDAdobe Readerが見つかりましたが、古いバージョンです。
ERROR_PREFERRED_READER_TOO_OLD適したバージョンのAdobe Readerが見つかりましたが、古いバージョンが優先されています。
STATUS_OK適したバージョンのAdobe Readerが見つかりました。

なお、PDF表示に対しては、HTMLControlオブジェクトの拡大/縮小、透過、回転は無効です。そうした操作を行うと、PDFが非表示になるので注意してください。

PDFはAdobe Readerの機能を使って表示される
PDFはAdobe Readerの機能を使って表示される

おすすめ記事

記事・ニュース一覧