| //////////////////////////////////////////////////////////////////////////////// |
| // |
| // Licensed to the Apache Software Foundation (ASF) under one or more |
| // contributor license agreements. See the NOTICE file distributed with |
| // this work for additional information regarding copyright ownership. |
| // The ASF licenses this file to You under the Apache License, Version 2.0 |
| // (the "License"); you may not use this file except in compliance with |
| // the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| package mx.controls |
| { |
| |
| import flash.events.Event; |
| import flash.events.FocusEvent; |
| import flash.events.HTMLUncaughtScriptExceptionEvent; |
| import flash.events.MouseEvent; |
| import flash.html.HTMLLoader; |
| import flash.html.HTMLHistoryItem; |
| import flash.html.HTMLHost; |
| import flash.net.URLRequest; |
| import flash.system.ApplicationDomain; |
| import flash.system.IME; |
| import flash.system.IMEConversionMode; |
| import mx.controls.listClasses.BaseListData; |
| import mx.controls.listClasses.IDropInListItemRenderer; |
| import mx.controls.listClasses.IListItemRenderer; |
| import mx.core.ClassFactory; |
| import mx.core.EdgeMetrics; |
| import mx.core.IDataRenderer; |
| import mx.core.IFactory; |
| import mx.core.IIMESupport; |
| import mx.core.FlexHTMLLoader; |
| import mx.core.mx_internal; |
| import mx.core.ScrollControlBase; |
| import mx.core.ScrollPolicy; |
| import mx.events.FlexEvent; |
| import mx.events.ScrollEvent; |
| import mx.styles.StyleManager |
| import mx.styles.CSSStyleDeclaration; |
| import mx.managers.IFocusManagerComponent; |
| |
| use namespace mx_internal; |
| |
| //-------------------------------------- |
| // Events |
| //-------------------------------------- |
| |
| /** |
| * Dispatched after the last loading operation caused by |
| * setting the <code>location</code> or <code>htmlText</code> |
| * property has completed. |
| * |
| * <p>This event is always dispatched asynchronously, |
| * after the JavaScript <code>load</code> event |
| * has been dispatched in the HTML DOM.</p> |
| * |
| * <p>An event handler for this event may call any method |
| * or access any property of this control |
| * or its internal <code>htmlLoader</code>.</p> |
| * |
| * @eventType flash.events.Event.COMPLETE |
| * |
| * @see location |
| * @see htmlText |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Event(name="complete", type="flash.events.Event")] |
| |
| /** |
| * Dispatched after the HTML DOM has been initialized |
| * in response to a loading operation caused by |
| * setting the <code>location</code> or <code>htmlText</code> property. |
| * |
| * <p>When this event is dispatched, |
| * no JavaScript methods have yet executed. |
| * The <code>domWindow</code>and <code>domWindow.document</code> |
| * objects exist, but other DOM objects may not. |
| * You can use this event to set properties |
| * onto the <code>domWindow</code> and <code>domWindow.document</code> |
| * objects for JavaScript methods to later access.</p> |
| * |
| * <p>A handler for this event should not set any properties |
| * or call any methods which start another loading operation |
| * or which affect the URL for the current loading operation; |
| * doing so causes either an ActionScript or a JavaScript exception.</p> |
| * |
| * @eventType flash.events.Event.HTML_DOM_INITIALIZE |
| * |
| * @see location |
| * @see htmlText |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Event(name="htmlDOMInitialize", type="flash.events.Event")] |
| |
| /** |
| * Dispatched when this control's HTML content initially renders, |
| * and each time that it re-renders. |
| * |
| * <p>Because an HTML control can dispatch many of these events, |
| * you should avoid significant processing in a <code>render</code> |
| * handler that might negatively impact performance.</p> |
| * |
| * @eventType flash.events.Event.HTML_RENDER |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Event(name="htmlRender", type="flash.events.Event")] |
| |
| /** |
| * Dispatched when the <code>location</code> property changes. |
| * |
| * <p>This event is always dispatched asynchronously. |
| * An event handler for this event may call any method |
| * or access any property of this control |
| * or its internal <code>htmlLoader</code>.</p> |
| * |
| * @eventType flash.events.Event.LOCATION_CHANGE |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Event(name="locationChange", type="flash.events.Event")] |
| |
| /** |
| * Dispatched when an uncaught JavaScript exception occurs. |
| * |
| * <p>This event is always dispatched asynchronously. |
| * An event handler for this event may call any method |
| * or access any property of this control |
| * or its internal <code>htmlLoader</code>.</p> |
| * |
| * @eventType flash.events.HTMLUncaughtScriptExceptionEvent.UNCAUGHT_SCRIPT_EXCEPTION |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Event(name="uncaughtScriptException", type="flash.events.HTMLUncaughtScriptExceptionEvent")] |
| |
| //-------------------------------------- |
| // Styles |
| //-------------------------------------- |
| |
| /** |
| * The number of pixels between the bottom edge of this control |
| * and the bottom edge of its HTML content area. |
| * |
| * @default 0 |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Style(name="paddingBottom", type="Number", format="Length", inherit="no")] |
| |
| /** |
| * The number of pixels between the left edge of this control |
| * and the left edge of its HTML content area. |
| * |
| * @default 0 |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Style(name="paddingLeft", type="Number", format="Length", inherit="no")] |
| |
| /** |
| * The number of pixels between the right edge of this control |
| * and the right edge of its HTML content area. |
| * |
| * @default 0 |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Style(name="paddingRight", type="Number", format="Length", inherit="no")] |
| |
| /** |
| * The number of pixels between the top edge of this control |
| * and the top edge of its HTML content area. |
| * |
| * @default 0 |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Style(name="paddingTop", type="Number", format="Length", inherit="no")] |
| |
| //-------------------------------------- |
| // Other metadata |
| //-------------------------------------- |
| |
| [IconFile("HTML.png")] |
| |
| [ResourceBundle("controls")] |
| |
| /** |
| * The HTML control lets you display HTML content in your application. |
| * |
| * <p>You use the <code>location</code> property to specify the URL |
| * of an HTML page whose content is displayed in the control, or you |
| * can set the <code>htmlText</code> property to specify a String |
| * containing HTML-formatted text that is rendered in the control.</p> |
| * |
| * @mxml |
| * |
| * <p>The <code><mx:HTML></code> tag inherits all of the tag |
| * attributes of its superclass and adds the following tag attributes:</p> |
| * |
| * <pre> |
| * <mx:HTML |
| * <strong>Properties</strong> |
| * data="<i>null</i>" |
| * historyPosition="0" |
| * htmlHost="<i>null</i>" |
| * htmlLoaderFactory="mx.core.ClassFactory" |
| * htmlText="" |
| * listData="<i>null</i>" |
| * location="" |
| * paintsDefaultBackground="false" |
| * runtimeApplicationDomain="<i>null</i>" |
| * userAgent="<i>null</i>" |
| * |
| * <strong>Styles</strong> |
| * paddingBottom="0" |
| * paddingLeft="0" |
| * paddingRight="0" |
| * paddingTop="0" |
| * |
| * <strong>Events</strong> |
| * complete="<i>No default</i>" |
| * htmlDOMInitialize="<i>No default</i>" |
| * htmlRender="<i>No default</i>" |
| * locationChange="<i>No default</i>" |
| * uncaughtScriptException="<i>No default</i>" |
| * /> |
| * </pre> |
| * |
| * @see ../../flash/html/HTMLLoader.html HTMLLoader |
| * |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public class HTML extends ScrollControlBase |
| implements IDataRenderer, IDropInListItemRenderer, |
| IListItemRenderer, IFocusManagerComponent |
| { |
| include "../core/Version.as"; |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Class constants |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| */ |
| private static const MAX_HTML_WIDTH:Number = 2880; |
| |
| /** |
| * @private |
| */ |
| private static const MAX_HTML_HEIGHT:Number = 2880; |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Class properties |
| // |
| //-------------------------------------------------------------------------- |
| |
| //---------------------------------- |
| // pdfCapability |
| //---------------------------------- |
| |
| /** |
| * The type of PDF support on the user's system, |
| * defined as an integer code value. |
| * |
| * <p>An HTML object can display PDF content only if this property |
| * evaluates to <code>PDFCapability.STATUS_OK</code>. |
| * The PDFCapability class defines constants for possible values |
| * of the <code>pdfCapability</code> property, as follows:</p> |
| * |
| * <table class="innertable"> |
| * <tr> |
| * <th>PDFCapability constant</th> |
| * <th>Meaning</th> |
| * </tr> |
| * <tr> |
| * <td><code>STATUS_OK</code></td> |
| * <td>A sufficient version (8.1 or later) of Acrobat Reader |
| * is detected and PDF content can be loaded in an HTML object. |
| * <p><em>Note:</em> On Windows, if a Acrobat Acrobat |
| * or Acrobat Reader version 7.x or above |
| * is currently running on the user's system, |
| * that version is used even if a later version |
| * that supports loading PDF loaded in an HTML object is installed. |
| * In this case, if the the value of the |
| * <code>pdfCampability</code> property is |
| * <code>PDFCapability.STATUS_OK</code>, |
| * when an AIR application attempts to load PDF content |
| * into an HTML object, the older version of Acrobat or Reader |
| * displays an alert, without an error message displayed the AIR runtime. |
| * If this is a possible situation for your end users, |
| * you may consider providing them with instructions to close Acrobat |
| * while running your application. |
| * You may consider displaying these instructions if the PDF |
| * content does not load within an acceptable timeframe.</p></td> |
| * </tr> |
| * <tr> |
| * <td><code>ERROR_INSTALLED_READER_NOT_FOUND</code></td> |
| * <td>No version of Acrobat Reader is detected. |
| * An HTML object cannot display PDF content.</td> |
| * </tr> |
| * <tr> |
| * <td><code>ERROR_INSTALLED_READER_TOO_OLD</code></td> |
| * <td>Acrobat Reader has been detected, but the version is too old. |
| * An HTML object cannot display PDF content.</td> |
| * </tr> |
| * <tr> |
| * <td><code>ERROR_PREFERED_READER_TOO_OLD</code></td> |
| * <td>A sufficient version (8.1 or later) of Acrobat Reader is detected, |
| * but the the version of Acrobat Reader that is setup |
| * to handle PDF content is older than Reader 8.1. |
| * An HTML object cannot display PDF content.</td> |
| * </tr> |
| * </table> |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public static function get pdfCapability():int |
| { |
| return HTMLLoader.pdfCapability; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Constructor |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Constructor. |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function HTML() |
| { |
| super(); |
| |
| _horizontalScrollPolicy = ScrollPolicy.AUTO; |
| _verticalScrollPolicy = ScrollPolicy.AUTO; |
| |
| tabFocusEnabled = false; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Variables |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| * Flag that will block default data/listData behavior. |
| */ |
| private var textSet:Boolean; |
| |
| /** |
| * @private |
| */ |
| private var errorCaught:Boolean = false; |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Overridden properties |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| */ |
| override public function set verticalScrollPosition(value:Number):void |
| { |
| // Clip the vertical scroll position to appropriate min/max bounds. |
| value = Math.max(value,0); |
| if (htmlLoader && (htmlLoader.contentHeight > htmlLoader.height)) |
| value = Math.min(value,htmlLoader.contentHeight - htmlLoader.height) |
| |
| super.verticalScrollPosition = value; |
| |
| if (htmlLoader) |
| htmlLoader.scrollV = value; |
| else |
| invalidateProperties(); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Properties |
| // |
| //-------------------------------------------------------------------------- |
| |
| //---------------------------------- |
| // contentHeight |
| //---------------------------------- |
| |
| /** |
| * The height, in pixels, of the HTML content. |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get contentHeight():Number |
| { |
| if (!htmlLoader) |
| return 0; |
| |
| return htmlLoader.contentHeight; |
| } |
| |
| //---------------------------------- |
| // contentWidth |
| //---------------------------------- |
| |
| /** |
| * The width, in pixels, of the HTML content. |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get contentWidth():Number |
| { |
| if (!htmlLoader) |
| return 0; |
| |
| return htmlLoader.contentWidth; |
| } |
| |
| //---------------------------------- |
| // data |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the data property. |
| */ |
| private var _data:Object; |
| |
| [Bindable("dataChange")] |
| [Inspectable(environment="none")] |
| |
| /** |
| * Lets you pass a value to the component |
| * when you use it in an item renderer or item editor. |
| * You typically use data binding to bind a field of the <code>data</code> |
| * property to a property of this component. |
| * |
| * <p>When you use the control as a drop-in item renderer or drop-in |
| * item editor, Flex automatically writes the current value of the item |
| * to the <code>text</code> property of this control.</p> |
| * |
| * <p>You cannot set this property in MXML.</p> |
| * |
| * @default null |
| * @see mx.core.IDataRenderer |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get data():Object |
| { |
| return _data; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set data(value:Object):void |
| { |
| var newText:*; |
| |
| _data = value; |
| |
| if (_listData) |
| { |
| newText = _listData.label; |
| } |
| else if (_data != null) |
| { |
| if (_data is String) |
| newText = String(_data); |
| else |
| newText = _data.toString(); |
| } |
| |
| if (newText !== undefined && !textSet) |
| { |
| htmlText = newText; |
| textSet = false; |
| } |
| |
| dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE)); |
| } |
| |
| |
| //---------------------------------- |
| // historyLength |
| //---------------------------------- |
| |
| /** |
| * The overall length of the history list, |
| * including back and forward entries. |
| * |
| * This property has the same value |
| * as the <code>window.history.length</code> |
| * JavaScript property of the the HTML content. |
| * |
| * @see #historyPosition |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get historyLength():int |
| { |
| if (!htmlLoader) |
| return 0; |
| |
| return htmlLoader.historyLength; |
| } |
| |
| //---------------------------------- |
| // historyPosition |
| //---------------------------------- |
| |
| /** |
| * The current position in the history list. |
| * |
| * <p>The history list corresponds to the <code>window.history</code> |
| * object of the HTML content. |
| * Entries less than the current position are the "back" list; |
| * entries greater are "forward." |
| * Attempting to set the position beyond the end sets it to the end.</p> |
| * |
| * @default 0 |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get historyPosition():int |
| { |
| if (!htmlLoader) |
| return 0; |
| |
| return htmlLoader.historyPosition; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set historyPosition(value:int):void |
| { |
| if (htmlLoader) |
| htmlLoader.historyPosition = value; |
| } |
| |
| //---------------------------------- |
| // htmlLoader |
| //---------------------------------- |
| |
| /** |
| * The internal HTMLLoader object that renders |
| * the HTML content for this control. |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public var htmlLoader:HTMLLoader; |
| |
| //---------------------------------- |
| // htmlLoaderFactory |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the htmlLoaderFactory property. |
| */ |
| private var _htmlLoaderFactory:IFactory = new ClassFactory(FlexHTMLLoader); |
| |
| [Bindable("htmlLoaderFactoryChanged")] |
| |
| /** |
| * The IFactory that creates an HTMLLoader-derived instance |
| * to use as the htmlLoader. |
| * |
| * <p>The default value is an IFactory for HTMLLoader.</p> |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get htmlLoaderFactory():IFactory |
| { |
| return _htmlLoaderFactory; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set htmlLoaderFactory(value:IFactory):void |
| { |
| _htmlLoaderFactory = value; |
| |
| dispatchEvent(new Event("htmlLoaderFactoryChanged")); |
| } |
| |
| //---------------------------------- |
| // htmlHost |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the htmlHost property. |
| */ |
| private var _htmlHost:HTMLHost; |
| |
| /** |
| * @private |
| */ |
| private var htmlHostChanged:Boolean = false; |
| |
| /** |
| * The HTMLHost object is used to handle changes |
| * to certain user interface elements in the HTML content, |
| * such as the <code>window.document.title</code> property. |
| * |
| * <p>To override default behaviors for the HTMLLoader, |
| * create a subclass of the HTMLHost class, |
| * override its member functions |
| * to handle various user interface changes in the HTML content, |
| * and set this property to an instance of your subclass.</p> |
| * |
| * @default null |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get htmlHost():HTMLHost |
| { |
| return _htmlHost; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set htmlHost(value:HTMLHost):void |
| { |
| _htmlHost = value; |
| htmlHostChanged = true; |
| |
| invalidateProperties(); |
| } |
| |
| //---------------------------------- |
| // htmlText |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the htmlText property. |
| */ |
| private var _htmlText:String; |
| |
| /** |
| * @private |
| */ |
| private var htmlTextChanged:Boolean = false; |
| |
| [Bindable("htmlTextChanged")] |
| |
| /** |
| * Specifies an HTML-formatted String for display by the control. |
| * |
| * <p>Setting this property has the side effect of setting |
| * the <code>location</code> property to <code>null</code>, |
| * and vice versa.</p> |
| * |
| * <p>Content added via the <code>htmlText</code> property is put in the |
| * application security sandbox. If an AIR application includes an HTML |
| * control located in the application sandbox, and remote HTML code is |
| * directly added into the control by setting the <code>htmlText</code> |
| * property, any script contained in the HTML text is executed in the |
| * application sandbox.</p> |
| * |
| * @default "" |
| * |
| * @see #location |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get htmlText():String |
| { |
| return _htmlText; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set htmlText(value:String):void |
| { |
| _htmlText = value; |
| htmlTextChanged = true; |
| |
| // Setting both location and htmlText doesn't make sense, |
| // so setting one sets the other to null, |
| // and the last one set is applied in commitProperties(). |
| _location = null; |
| locationChanged = false; |
| |
| invalidateProperties(); |
| invalidateSize(); |
| invalidateDisplayList(); |
| |
| dispatchEvent(new Event("htmlTextChanged")); |
| } |
| |
| //---------------------------------- |
| // domWindow |
| //---------------------------------- |
| |
| /** |
| * The JavaScript <code>window</code> object |
| * for the root frame of the HTML DOM inside this control. |
| * |
| * <p>This property is <code>null</code> until the |
| * <code>htmlDOMInitialize</code> event has been dispatched.</p> |
| * |
| * @default null |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get domWindow():Object |
| { |
| if (!htmlLoader) |
| return null; |
| |
| return htmlLoader.window; |
| } |
| |
| //---------------------------------- |
| // imeMode |
| //---------------------------------- |
| |
| /** |
| * @private |
| */ |
| private var _imeMode:String = null; |
| |
| /** |
| * Specifies the IME (input method editor) mode. |
| * The IME enables users to enter text in Chinese, Japanese, and Korean. |
| * Flex sets the specified IME mode when the control gets the focus, |
| * and sets it back to the previous value when the control loses the focus. |
| * |
| * <p>The flash.system.IMEConversionMode class defines constants for the |
| * valid values for this property. |
| * You can also specify <code>null</code> to specify no IME.</p> |
| * |
| * @default null |
| * |
| * @see flash.system.IMEConversionMode |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get imeMode():String |
| { |
| return _imeMode; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set imeMode(value:String):void |
| { |
| _imeMode = value; |
| // We don't call IME.conversionMode here. We call it |
| // only on focusIn. Thus fringe cases like setting |
| // imeMode dynamically without moving focus, through |
| // keyboard events, wouldn't change the mode. Also |
| // getting imeMode asynch. from the server which gets |
| // delayed and set later after focusIn is not handled |
| // as having the text partly in one script and partly |
| // in another is not desirable. |
| } |
| |
| //---------------------------------- |
| // listData |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the listData property. |
| */ |
| private var _listData:BaseListData; |
| |
| [Bindable("dataChange")] |
| [Inspectable(environment="none")] |
| |
| /** |
| * When a component is used as a drop-in item renderer or drop-in |
| * item editor, Flex initializes the <code>listData</code> property |
| * of the component with the appropriate data from the List control. |
| * The component can then use the <code>listData</code> property |
| * to initialize the <code>data</code> property of the drop-in |
| * item renderer or drop-in item editor. |
| * |
| * <p>You do not set this property in MXML or ActionScript; |
| * Flex sets it when the component is used as a drop-in item renderer |
| * or drop-in item editor.</p> |
| * |
| * @default null |
| * @see mx.controls.listClasses.IDropInListItemRenderer |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get listData():BaseListData |
| { |
| return _listData; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set listData(value:BaseListData):void |
| { |
| _listData = value; |
| } |
| |
| //---------------------------------- |
| // loaded |
| //---------------------------------- |
| |
| /** |
| * A flag which indicates whether the JavaScript <code>load</code> event |
| * corresponding to the previous loading operation |
| * has been delivered to the HTML DOM in this control. |
| * |
| * <p>This property is <code>true</code> |
| * before the <code>complete</code> event is dispatched.</p> |
| * |
| * <p>It is possible that this property |
| * never becomes <code>true</code>. |
| * This happens in the same cases |
| * in which the <code>complete</code> event is never dispatched.</p> |
| * |
| * @default false |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get loaded():Boolean |
| { |
| if (!htmlLoader || locationChanged || htmlTextChanged) |
| return false; |
| |
| return htmlLoader.loaded; |
| } |
| |
| //---------------------------------- |
| // location |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the location property. |
| */ |
| private var _location:String; |
| |
| /** |
| * @private |
| */ |
| private var locationChanged:Boolean = false; |
| |
| [Bindable("locationChange")] |
| |
| /** |
| * The URL of an HTML page to be displayed by this control. |
| * |
| * <p>Setting this property has the side effect of setting |
| * the <code>htmlText</code> property to <code>null</code>, |
| * and vice versa.</p> |
| * |
| * @default "" |
| * |
| * @see #htmlText |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get location():String |
| { |
| return _location; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set location(value:String):void |
| { |
| _location = value; |
| locationChanged = true; |
| |
| // Setting both location and htmlText doesn't make sense, |
| // so setting one sets the other to null, |
| // and the last one set is applied in commitProperties(). |
| _htmlText = null; |
| htmlTextChanged = false; |
| |
| invalidateProperties(); |
| invalidateSize(); |
| invalidateDisplayList(); |
| |
| dispatchEvent(new Event("locationChange")); |
| } |
| |
| //---------------------------------- |
| // paintsDefaultBackground |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the paintsDefaultBackground property. |
| */ |
| private var _paintsDefaultBackground:Boolean; |
| |
| /** |
| * @private |
| */ |
| private var paintsDefaultBackgroundChanged:Boolean = false; |
| |
| /** |
| * Whether this control's HTML content |
| * has a default opaque white background or not. |
| * |
| * <p>If this property is <code>false</code>, |
| * then the background specified for this Flex control, if any, |
| * appears behind the HTML content.</p> |
| * |
| * <p>However, if any HTML element has its own opaque background color |
| * (specified by style="background-color:gray", for instance), |
| * then that background appears behind that element.</p> |
| * |
| * @default false; |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get paintsDefaultBackground():Boolean |
| { |
| return _paintsDefaultBackground; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set paintsDefaultBackground(value:Boolean):void |
| { |
| _paintsDefaultBackground = value; |
| paintsDefaultBackgroundChanged = true; |
| |
| invalidateProperties(); |
| } |
| |
| //---------------------------------- |
| // runtimeApplicationDomain |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the runtimeApplicationDomain property. |
| */ |
| private var _runtimeApplicationDomain:ApplicationDomain; |
| |
| /** |
| * @private |
| */ |
| private var runtimeApplicationDomainChanged:Boolean = false; |
| |
| /** |
| * The ApplicationDomain to use for HTML's <code>window.runtime</code> |
| * scripting. |
| * |
| * <p>If this property is <code>null</code>, or if it specifies |
| * an ApplicationDomain from a different security domain |
| * than the HTML content, the HTML page uses a default |
| * <code>ApplicationDomain</code> for the page's domain.</p> |
| * |
| * @default null |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get runtimeApplicationDomain():ApplicationDomain |
| { |
| return _runtimeApplicationDomain; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set runtimeApplicationDomain(value:ApplicationDomain):void |
| { |
| _runtimeApplicationDomain = value; |
| runtimeApplicationDomainChanged = true; |
| |
| invalidateProperties(); |
| } |
| |
| //---------------------------------- |
| // userAgent |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the userAgent property. |
| */ |
| private var _userAgent:String; |
| |
| /** |
| * @private |
| */ |
| private var userAgentChanged:Boolean = false; |
| |
| /** |
| * The user agent string to be used in content requests |
| * from this control. |
| * |
| * <p>You can set the default user agent string used by all |
| * HTML controls in an application domain by setting the |
| * static <code>URLRequestDefaults.userAgent</code> property. |
| * If no value is set for the <code>userAgent</code> property |
| * (or if the value is set to <code>null</code>), |
| * the user agent string is set to the value of |
| * <code>URLRequestDefaults.userAgent</code>.</p> |
| * |
| * <p>If neither the <code>userAgent</code> property |
| * of this control nor for <code>URLRequestDefaults.userAgent</code>, |
| * has a value set, a default value is used as the user agent string. |
| * This default value varies depending on the runtime |
| * operating system (such as Mac OS or Windows), |
| * the runtime language, and the runtime version, |
| * as in the following two examples:</p> |
| * |
| * <pre> |
| * "Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) AdobeAIR/1.0" |
| * "Mozilla/5.0 (Windows; U; en) AppleWebKit/420+ (KHTML, like Gecko) AdobeAIR/1.0" |
| * </pre> |
| * |
| * @default null |
| * |
| * @see flash.net.URLRequest#userAgent |
| * @see flash.net.URLRequestDefaults#userAgent |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get userAgent():String |
| { |
| return _userAgent; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set userAgent(value:String):void |
| { |
| _userAgent = value; |
| userAgentChanged = true; |
| |
| invalidateProperties(); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Overridden methods |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| */ |
| override protected function createChildren():void |
| { |
| super.createChildren(); |
| |
| if (!htmlLoader) |
| { |
| htmlLoader = htmlLoaderFactory.newInstance(); |
| |
| htmlLoader.addEventListener( |
| Event.HTML_DOM_INITIALIZE, htmlLoader_domInitialize); |
| |
| htmlLoader.addEventListener( |
| Event.COMPLETE, htmlLoader_completeHandler); |
| |
| htmlLoader.addEventListener( |
| Event.HTML_RENDER, htmlLoader_htmlRenderHandler); |
| |
| htmlLoader.addEventListener( |
| Event.LOCATION_CHANGE, htmlLoader_locationChangeHandler); |
| |
| htmlLoader.addEventListener( |
| Event.HTML_BOUNDS_CHANGE, htmlLoader_htmlBoundsChangeHandler); |
| |
| htmlLoader.addEventListener( |
| Event.SCROLL, htmlLoader_scrollHandler); |
| |
| htmlLoader.addEventListener( |
| HTMLUncaughtScriptExceptionEvent.UNCAUGHT_SCRIPT_EXCEPTION, |
| htmlLoader_uncaughtScriptExceptionHandler); |
| |
| addChild(htmlLoader); |
| } |
| } |
| |
| /** |
| * @private |
| */ |
| override protected function commitProperties():void |
| { |
| super.commitProperties(); |
| |
| // Change the properties of the HTMLLoader |
| // before calling its load() or loadString() method. |
| |
| if (htmlHostChanged) |
| { |
| htmlLoader.htmlHost = _htmlHost; |
| htmlHostChanged = false; |
| } |
| |
| if (paintsDefaultBackgroundChanged) |
| { |
| htmlLoader.paintsDefaultBackground = _paintsDefaultBackground; |
| paintsDefaultBackgroundChanged = false; |
| } |
| |
| if (runtimeApplicationDomainChanged) |
| { |
| htmlLoader.runtimeApplicationDomain = _runtimeApplicationDomain; |
| runtimeApplicationDomainChanged = false; |
| } |
| |
| if (userAgentChanged) |
| { |
| htmlLoader.userAgent = _userAgent; |
| userAgentChanged = false; |
| } |
| |
| if (locationChanged) |
| { |
| htmlLoader.load(new URLRequest(_location)); |
| locationChanged = false; |
| } |
| |
| if (htmlTextChanged) |
| { |
| htmlLoader.loadString(_htmlText); |
| htmlTextChanged = false; |
| } |
| } |
| |
| /** |
| * @private |
| */ |
| override protected function measure():void |
| { |
| super.measure(); |
| |
| var em:EdgeMetrics = viewMetrics; |
| |
| em.left += getStyle("paddingLeft"); |
| em.top += getStyle("paddingTop"); |
| em.right += getStyle("paddingRight"); |
| em.bottom += getStyle("paddingBottom"); |
| |
| measuredWidth = Math.min(htmlLoader.contentWidth + em.left + em.right, |
| MAX_HTML_WIDTH); |
| measuredHeight = Math.min(htmlLoader.contentHeight + em.top + em.bottom, |
| MAX_HTML_HEIGHT); |
| |
| //trace("measure", htmlLoader.contentWidth, htmlLoader.contentHeight, measuredWidth, measuredHeight); |
| } |
| |
| /** |
| * @private |
| */ |
| override protected function updateDisplayList(unscaledWidth:Number, |
| unscaledHeight:Number):void |
| { |
| super.updateDisplayList(unscaledWidth, unscaledHeight); |
| |
| var em:EdgeMetrics = viewMetrics; |
| |
| em.left += getStyle("paddingLeft"); |
| em.top += getStyle("paddingTop"); |
| em.right += getStyle("paddingRight"); |
| em.bottom += getStyle("paddingBottom"); |
| |
| htmlLoader.x = em.left; |
| htmlLoader.y = em.top; |
| |
| // The width and height of an HTMLLoader can't be 0. |
| var w:Number = Math.max(unscaledWidth - em.left - em.right, 1); |
| var h:Number = Math.max(unscaledHeight - em.top - em.bottom, 1); |
| |
| htmlLoader.width = w; |
| htmlLoader.height = h; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Methods |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Cancels any load operation in progress. |
| * |
| * <p>This method does nothing if it is called before this component's |
| * internal HTMLLoader (the <code>htmlLoader</code> property) has been created.</p> |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function cancelLoad():void |
| { |
| if (htmlLoader) |
| htmlLoader.cancelLoad(); |
| } |
| |
| /** |
| * Returns the HTMLHistoryItem at the specified position |
| * in this control's history list. |
| * |
| * <p>This method returns <code>null</code> if it is called before this |
| * component's internal HTMLLoader (the <code>htmlLoader</code> property) has been created.</p> |
| * |
| * @param position The position in the history list. |
| * |
| * @return A HTMLHistoryItem object |
| * for the history entry at the specified position. |
| * |
| * @see historyPosition |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function getHistoryAt(position:int):HTMLHistoryItem |
| { |
| if (!htmlLoader) |
| return null; |
| |
| return htmlLoader.getHistoryAt(position); |
| } |
| |
| /** |
| * Navigates back in this control's history list, if possible. |
| * |
| * <p>Calling this method of the HTMLLoader object |
| * has the same effect as calling the <code>back()</code> method |
| * of the <code>window.history</code> property in JavaScript |
| * in the HTML content.</p> |
| * |
| * <p>This method does nothing if it is called before this component's |
| * internal HTMLLoader (the <code>htmlLoader</code> property) has been created.</p> |
| * |
| * @see #historyPosition |
| * @see #historyForward() |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function historyBack():void |
| { |
| if (htmlLoader) |
| htmlLoader.historyBack(); |
| } |
| |
| /** |
| * Navigates forward in this control's history list, if possible. |
| * |
| * <p>Calling this method of the HTMLLoader object |
| * has the same effect as calling the <code>forward()</code> method |
| * of the <code>window.history</code> property in JavaScript |
| * in the HTML content.</p> |
| * |
| * <p>This function throws no errors.</p> |
| * |
| * <p>This method does nothing if it is called before this component's |
| * internal HTMLLoader (the <code>htmlLoader</code> property) has been created.</p> |
| * |
| * @see #historyPosition |
| * @see #historyBack() |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function historyForward():void |
| { |
| if (htmlLoader) |
| htmlLoader.historyForward(); |
| } |
| |
| /** |
| * Navigates the specified number of steps in this control's history list. |
| * |
| * <p>This method navigates forward if the number of steps |
| * is positive and backward if it is negative. |
| * Navigation by zero steps is equivalent |
| * to calling <code>reload()</code>.</p> |
| * |
| * <p>This method is equivalent to calling the <code>go()</code> method |
| * of the <code>window.history</code> property in JavaScript |
| * in the HTML content.</p> |
| * |
| * <p>This method does nothing if it is called before this component's |
| * internal HTMLLoader (the <code>htmlLoader</code> property) has been created.</p> |
| * |
| * @param steps The number of steps in the history list |
| * to move forward (positive) or backward (negative). |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function historyGo(steps:int):void |
| { |
| if (htmlLoader) |
| htmlLoader.historyGo(steps); |
| } |
| |
| /** |
| * Reloads the HTML content from the current <code>location</code>. |
| * |
| * <p>This method does nothing if it is called before this component's |
| * internal HTMLLoader (the <code>htmlLoader</code> property) has been created.</p> |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function reload():void |
| { |
| if (htmlLoader) |
| htmlLoader.reload(); |
| } |
| |
| /** |
| * @private |
| */ |
| private function adjustScrollBars():void |
| { |
| setScrollBarProperties(htmlLoader.contentWidth, htmlLoader.width, |
| htmlLoader.contentHeight, htmlLoader.height); |
| |
| // This is a temporary solution for adjusting the speed of scrolling |
| // via scrollbar arrows. There isn't a lot of overhead here, but |
| // we still shouldn't have to set these values every time |
| // updateDisplayList() is called. |
| if (verticalScrollBar) |
| verticalScrollBar.lineScrollSize = 20; |
| if (horizontalScrollBar) |
| horizontalScrollBar.lineScrollSize = 20; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Overridden event handlers: ScrollControlBase |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| * Gets called by internal field so we draw a focus rect around us. |
| */ |
| override protected function focusInHandler(event:FocusEvent):void |
| { |
| super.focusInHandler(event); |
| |
| if (_imeMode != null && |
| (htmlLoader is IIMESupport && IIMESupport(htmlLoader).enableIME)) |
| { |
| // When IME.conversionMode is unknown it cannot be |
| // set to anything other than unknown(English) |
| try |
| { |
| if (!errorCaught && |
| IME.conversionMode != IMEConversionMode.UNKNOWN) |
| { |
| IME.conversionMode = _imeMode; |
| } |
| errorCaught = false; |
| } |
| catch(e:Error) |
| { |
| // Once an error is thrown, focusIn is called |
| // again after the Alert is closed, throw error |
| // only the first time. |
| errorCaught = true; |
| var message:String = resourceManager.getString( |
| "controls", "unsupportedMode", [ _imeMode ]); |
| throw new Error(message); |
| } |
| } |
| } |
| |
| /** |
| * @private |
| */ |
| override protected function scrollHandler(event:Event):void |
| { |
| super.scrollHandler(event); |
| |
| htmlLoader.scrollH = horizontalScrollPosition; |
| htmlLoader.scrollV = verticalScrollPosition; |
| } |
| |
| /** |
| * @private |
| */ |
| override protected function mouseWheelHandler(event:MouseEvent):void |
| { |
| // Ignore mouseWheel events that are bubbling up |
| // from the HTMLLoader; they have already been handled there. |
| if (event.target != this) |
| return; |
| |
| // Magnify the scrolling to approximate what browsers do. |
| event.delta *= 6; |
| |
| super.mouseWheelHandler(event); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Event handlers |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| */ |
| private function htmlLoader_domInitialize(event:Event):void |
| { |
| dispatchEvent(event); |
| } |
| |
| /** |
| * @private |
| */ |
| private function htmlLoader_completeHandler(event:Event):void |
| { |
| invalidateSize(); |
| |
| dispatchEvent(event); |
| } |
| |
| /** |
| * @private |
| */ |
| private function htmlLoader_htmlRenderHandler(event:Event):void |
| { |
| dispatchEvent(event); |
| |
| adjustScrollBars(); |
| |
| // we record this property here becuase it seems to |
| // change as you interact with the content |
| hasFocusableChildren = htmlLoader.hasFocusableContent; |
| } |
| |
| /** |
| * @private |
| */ |
| private function htmlLoader_locationChangeHandler(event:Event):void |
| { |
| var change:Boolean = _location != htmlLoader.location; |
| |
| _location = htmlLoader.location; |
| |
| if (change) |
| dispatchEvent(event); |
| } |
| |
| /** |
| * @private |
| */ |
| private function htmlLoader_htmlBoundsChangeHandler(event:Event):void |
| { |
| invalidateSize(); |
| |
| adjustScrollBars(); |
| } |
| |
| /** |
| * @private |
| */ |
| private function htmlLoader_scrollHandler(event:Event):void |
| { |
| horizontalScrollPosition = htmlLoader.scrollH; |
| verticalScrollPosition = htmlLoader.scrollV; |
| } |
| |
| /** |
| * @private |
| */ |
| private function htmlLoader_uncaughtScriptExceptionHandler( |
| event:HTMLUncaughtScriptExceptionEvent):void |
| { |
| var clonedEvent:Event = event.clone(); |
| |
| dispatchEvent(clonedEvent); |
| |
| if (clonedEvent.isDefaultPrevented()) |
| event.preventDefault(); |
| } |
| } |
| |
| } |