|
|
Defining browser-like user interfaces for HTML content
JavaScript provides several APIs for controlling the window
displaying the HTML content. In AIR, these APIs can be overridden
by implementing a custom HTMLHost class.
About extending the HTMLHost classIf,
for example, your application presents multiple HTMLLoader objects
in a tabbed interface, you may want title changes made by the loaded
HTML pages to change the label of the tab, not the title of the
main window. Similarly, your code could respond to a window.moveTo() call
by repositioning the HTMLLoader object in its parent display object
container, by moving the window that contains the HTMLLoader object,
by doing nothing at all, or by doing something else entirely.
The AIR HTMLHost class controls the following JavaScript properties
and methods:
window.status
window.document.title
window.location
window.blur()
window.close()
window.focus()
window.moveBy()
window.moveTo()
window.open()
window.resizeBy()
window.resizeTo()
When you create an HTMLLoader object using new HTMLLoader(),
the listed JavaScript properties or methods are not enabled. The
HTMLHost class provides a default, browser-like implementation of
these JavaScript APIs. You can also extend the HTMLHost class to
customize the behavior. To create an HTMLHost object supporting
the default behavior, set the defaultBehaviors parameter
to true in the HTMLHost constructor:
var defaultHost:HTMLHost = new HTMLHost(true);
When you create an HTML window in AIR with the HTMLLoader class createRootWindow() method,
an HTMLHost instance supporting the default behaviors is assigned
automatically. You can change the host object behavior by assigning
a different HTMLHost implementation to the htmlHost property
of the HTMLLoader, or you can assign null to disable
the features entirely.
Note: AIR assigns a default HTMLHost object to the
initial window created for an HTML-based AIR application and any
windows created by the default implementation of the JavaScript window.open() method.
Example: Extending the HTMLHost classThe following example shows how to customize the way that
an HTMLLoader object affects the user interface, by extending the
HTMLHost class:
Create a class
that extends the HTMLHost class (a subclass).
Override methods of the new class to
handle changes in the user interface-related settings. For example,
the following class, CustomHost, defines behaviors for calls to window.open() and
changes to window.document.title. Calls to window.open() open
the HTML page in a new window, and changes to window.document.title (including
the setting of the <title> element of an
HTML page) set the title of that window.
package
{
import flash.html.*;
import flash.display.StageScaleMode;
import flash.display.NativeWindow;
import flash.display.NativeWindowInitOptions;
public class CustomHost extends HTMLHost
{
import flash.html.*;
override public function
createWindow(windowCreateOptions:HTMLWindowCreateOptions):HTMLLoader
{
var initOptions:NativeWindowInitOptions = new NativeWindowInitOptions();
var bounds:Rectangle = new Rectangle(windowCreateOptions.x,
windowCreateOptions.y,
windowCreateOptions.width,
windowCreateOptions.height);
var htmlControl:HTMLLoader = HTMLLoader.createRootWindow(true, initOptions,
windowCreateOptions.scrollBarsVisible, bounds);
htmlControl.htmlHost = new HTMLHostImplementation();
if(windowCreateOptions.fullscreen){
htmlControl.stage.displayState =
StageDisplayState.FULL_SCREEN_INTERACTIVE;
}
return htmlControl;
}
override public function updateTitle(title:String):void
{
htmlLoader.stage.nativeWindow.title = title;
}
}
}
In the code that contains the HTMLLoader
(not the code of the new subclass of HTMLHost), create an object
of the new class. Assign the new object to the htmlHost property
of the HTMLLoader. The following Flex code uses the CustomHost class
defined in the previous step:
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical"
applicationComplete="init()">
<mx:Script>
<![CDATA[
import flash.html.HTMLLoader;
import CustomHost;
private function init():void
{
var html:HTMLLoader = new HTMLLoader();
html.width = container.width;
html.height = container.height;
var urlReq:URLRequest = new URLRequest("Test.html");
html.htmlHost = new CustomHost();
html.load(urlReq);
container.addChild(html);
}
]]>
</mx:Script>
<mx:UIComponent id="container" width="100%" height="100%"/>
</mx:WindowedApplication>
To test the code described
here, include an HTML file with the following content in the application
directory:
<html>
<head>
<title>Test</title>
</head>
<script>
function openWindow()
{
window.runtime.trace("in");
document.title = "foo"
window.open('Test.html');
window.runtime.trace("out");
}
</script>
<body>
<a href="#" onclick="openWindow()">window.open('Test.html')</a>
</body>
</html>
Handling changes to the window.location propertyOverride the locationChange() method to
handle changes of the URL of the HTML page. The locationChange() method
is called when JavaScript in a page changes the value of window.location.
The following example simply loads the requested URL:
override public function updateLocation(locationURL:String):void
{
htmlLoader.load(new URLRequest(locationURL));
}
Note: You can use the htmlLoader property of the HTMLHost
object to reference the current HTMLLoader object.
Handling JavaScript calls to window.moveBy(), window.moveTo(), window.resizeTo(), window.resizeBy()Override the set windowRect() method to
handle changes in the bounds of the HTML content. The set windowRect() method
is called when JavaScript in a page calls window.moveBy(), window.moveTo(), window.resizeTo(),
or window.resizeBy(). The following example simply
updates the bounds of the desktop window:
override public function set windowRect(value:Rectangle):void
{
htmlLoader.stage.nativeWindow.bounds = value;
}
Handling JavaScript calls to window.open()Override the createWindow() method to
handle JavaScript calls to window.open(). Implementations
of the createWindow() method are responsible for
creating and returning a new HTMLLoader object. Typically, you would
display the HTMLLoader in a new window, but creating a window is
not required.
The following example illustrates how to implement the createWindow() function
using the HTMLLoader.createRootWindow() to create
both the window and the HTMLLoader object. You can also create a
NativeWindow object separately and add the HTMLLoader to the window
stage.
override public function createWindow(windowCreateOptions:HTMLWindowCreateOptions):HTMLLoader{
var initOptions:NativeWindowInitOptions = new NativeWindowInitOptions();
var bounds:Rectangle = new Rectangle(windowCreateOptions.x, windowCreateOptions.y,
windowCreateOptions.width, windowCreateOptions.height);
var htmlControl:HTMLLoader = HTMLLoader.createRootWindow(true, initOptions,
windowCreateOptions.scrollBarsVisible, bounds);
htmlControl.htmlHost = new HTMLHostImplementation();
if(windowCreateOptions.fullscreen){
htmlControl.stage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE;
}
return htmlControl;
}
Note: This example assigns the custom HTMLHost implementation
to any new windows created with window.open().
You can also use a different implementation or set the htmlHost property
to null for new windows, if desired.
The object passed as a parameter to the createWindow() method
is an HTMLWindowCreateOptions object. The HTMLWindowCreateOptions
class includes properties that report the values set in the features parameter
string in the call to window.open():
HTMLWindowCreateOptions property
|
Corresponding setting in the features string
in the JavaScript call to window.open()
|
fullscreen
|
fullscreen
|
height
|
height
|
locationBarVisible
|
location
|
menuBarVisible
|
menubar
|
resizeable
|
resizable
|
scrollBarsVisible
|
scrollbars
|
statusBarVisible
|
status
|
toolBarVisible
|
toolbar
|
width
|
width
|
x
|
left or screenX
|
y
|
top or screenY
|
The HTMLLoader class does not implement all the features that
can be specified in the feature string. Your application must provide
scroll bars, location bars, menu bars, status bars, and toolbars
when appropriate.
The other arguments to the JavaScript window.open() method
are handled by the system. A createWindow() implementation
should not load content in the HTMLLoader object, or set the window
title.
Handling JavaScript calls to window.close()Override the windowClose() to handle JavaScript
calls to window.close() method. The following example
closes the desktop window when the window.close() method
is called:
override public function windowClose():void
{
htmlLoader.stage.nativeWindow.close();
}
JavaScript calls to window.close() do not have
to close the containing window. You could, for example, remove the
HTMLLoader from the display list, leaving the window (which may
have other content) open, as in the following code:
override public function windowClose():void
{
htmlLoader.parent.removeChild(htmlLoader);
}
Handling changes of the window.status propertyOverride the updateStatus() method to
handle JavaScript changes to the value of window.status.
The following example traces the status value:
override public function updateStatus(status:String):void
{
trace(status);
}
The requested status is passed as a string to the updateStatus() method.
The HTMLLoader object does not provide a status bar.
Handling changes of the window.document.title propertyoverride the updateTitle() method to handle
JavaScript changes to the value of window.document.title.
The following example changes the window title and appends the string,
"Sample," to the title:
override public function updateTitle(title:String):void
{
htmlLoader.stage.nativeWindow.title = title + " - Sample";
}
When document.title is set on an HTML page,
the requested title is passed as a string to the updateTitle() method.
Changes to document.title do not have to change
the title of the window containing the HTMLLoader object. You could,
for example, change another interface element, such as a text field.
Handling JavaScript calls to window.blur() and window.focus()Override the windowBlur() and windowFocus() methods
to handle JavaScript calls to window.blur() and window.focus(),
as shown in the following example:
override public function windowBlur():void
{
htmlLoader.alpha = 0.5;
}
override public function windowFocus():void
{
htmlLoader.alpha = 1.0;
NativeApplication.nativeApplication.activate(htmlLoader.stage.nativeWindow);
}
Note: AIR does not provide an API for deactivating
a window or application.
Creating windows with scrolling HTML contentThe HTMLLoader class includes a static method, HTMLLoader.createRootWindow(),
which lets you open a new window (represented by a NativeWindow
object) that contains an HTMLLoader object and define some user
interface settings for that window. The method takes four parameters,
which let you define the user interface:
Parameter
|
Description
|
visible
|
A Boolean value that specifies whether the
window is initially visible (true) or not (false).
|
windowInitOptions
|
A NativeWindowInitOptions object. The NativeWindowInitOptions
class defines initialization options for a NativeWindow object,
including the following: whether the window is minimizable, maximizable,
or resizable, whether the window has system chrome or custom chrome,
whether the window is transparent or not (for windows that do not
use system chrome), and the type of window.
|
scrollBarsVisible
|
Whether there are scroll bars (true)
or not (false).
|
bounds
|
A Rectangle object defining the position
and size of the new window.
|
For example, the following code uses the HTMLLoader.createRootWindow() method
to create a window with HTMLLoader content that uses scrollbars:
var initOptions:NativeWindowInitOptions = new NativeWindowInitOptions();
var bounds:Rectangle = new Rectangle(10, 10, 600, 400);
var html2:HTMLLoader = HTMLLoader.createRootWindow(true, initOptions, true, bounds);
var urlReq2:URLRequest = new URLRequest("http://www.example.com");
html2.load(urlReq2);
html2.stage.nativeWindow.activate();
Note: Windows created by calling createRootWindow() directly
in JavaScript remain independent from the opening HTML window. The
JavaScript Window opener and parent properties,
for example, are null. However, if you call createRootWindow() indirectly
by overriding the HTMLHost createWindow() method
to call createRootWindow(), then opener and parent do
reference the opening HTML window.
|