diff --git a/SVGRendererFlex/src/com/lorentz/SVG/Flex/SVG.as b/SVGRendererFlex/src/com/lorentz/SVG/Flex/SVG.as index 23f0784..ab88a5c 100644 --- a/SVGRendererFlex/src/com/lorentz/SVG/Flex/SVG.as +++ b/SVGRendererFlex/src/com/lorentz/SVG/Flex/SVG.as @@ -5,14 +5,24 @@ package com.lorentz.SVG.Flex import com.lorentz.SVG.text.ISVGTextDrawer; import com.lorentz.SVG.utils.DisplayUtils; import com.lorentz.processing.ProcessExecutor; - - import flash.geom.Rectangle; - import flash.net.URLRequest; - - import mx.core.UIComponent; + + import flash.events.Event; + import flash.events.HTTPStatusEvent; + import flash.events.IOErrorEvent; + import flash.events.ProgressEvent; + import flash.events.SecurityErrorEvent; + + import flash.geom.Rectangle; + import flash.net.URLLoader; + import flash.net.URLRequest; + + import mx.core.UIComponent; import mx.managers.ISystemManager; - [Event(name="invalidate", type="com.lorentz.SVG.events.SVGEvent")] + import spark.core.ContentRequest; + import spark.core.IContentLoader; + + [Event(name="invalidate", type="com.lorentz.SVG.events.SVGEvent")] [Event(name="syncValidated", type="com.lorentz.SVG.events.SVGEvent")] [Event(name="asyncValidated", type="com.lorentz.SVG.events.SVGEvent")] @@ -27,8 +37,7 @@ package com.lorentz.SVG.Flex [Mixin] public class SVG extends UIComponent { - public static function init(systemManager:ISystemManager):void - { + public static function init(systemManager:ISystemManager):void { ProcessExecutor.instance.initialize(systemManager.stage); } @@ -41,8 +50,10 @@ package com.lorentz.SVG.Flex private var _svgDocument:SVGDocument; private var _sourceInvalid:Boolean = false; - - private static const CLONED_EVENTS:Vector. = new [ + private var loadingContent:Object; + + + private static const CLONED_EVENTS:Vector. = new [ SVGEvent.INVALIDATE, SVGEvent.SYNC_VALIDATED, SVGEvent.ASYNC_VALIDATED, @@ -169,26 +180,137 @@ package com.lorentz.SVG.Flex public function set useEmbeddedFonts(value:Boolean):void { _svgDocument.useEmbeddedFonts = value; } - + + + //---------------------------------- + // contentLoader + //---------------------------------- + + private var _contentLoader:IContentLoader; + private var _contentLoaderInvalid:Boolean; + + /** + * Optional custom url loader (e.g. cache or queue) to + * associate with content loader client. + * + * Don't use for it ContentCache, it works with images only. Use 'https://github.com/kelegorm/URLLoaderCache'. + * + * @default null + */ + public function get contentLoader():IContentLoader { + return _contentLoader; + } + + public function set contentLoader(value:IContentLoader):void { + if (value != _contentLoader) { + _contentLoader = value; + _contentLoaderInvalid = true; + invalidateProperties(); + } + } + override protected function commitProperties():void { super.commitProperties(); - if(_sourceInvalid){ + if(_sourceInvalid || _contentLoaderInvalid) { + applySource(); + _sourceInvalid = false; - - if((_source is String && !isXML(String(_source))) || _source is URLRequest) - { - _svgDocument.load(_source); - } - else if(_source is String || _source is XML) - { - _svgDocument.parse(_source); - } + _contentLoaderInvalid = false; } } - - private function cloneAndRedispatchEvent(e:SVGEvent):void - { + + private function applySource():void { + if ((_source is String && !isXML(String(_source))) || _source is URLRequest) { + loadExternal(_source); + } + else if (_source is String || _source is XML) { + _svgDocument.parse(_source); + } + } + + private function loadExternal(source:Object):void { + if (contentLoader) { + var contentRequest:ContentRequest = contentLoader.load(source); + if (contentRequest.complete) { + readSVG(contentRequest.content); + } else { + loadingContent = contentRequest; + attachLoadingListeners(); + } + + } else { + _svgDocument.load(source); + } + } + + private function attachLoadingListeners():void { + if (loadingContent) { + loadingContent.addEventListener(Event.COMPLETE, + loader_completeHandler, false, 0, true); + loadingContent.addEventListener(IOErrorEvent.IO_ERROR, + loader_ioErrorHandler, false, 0, true); + loadingContent.addEventListener(ProgressEvent.PROGRESS, + loader_progressHandler, false, 0, true); + loadingContent.addEventListener(SecurityErrorEvent.SECURITY_ERROR, + loader_securityErrorHandler, false, 0, true); + loadingContent.addEventListener(HTTPStatusEvent.HTTP_STATUS, + dispatchEvent, false, 0, true); + } + } + + private function loader_progressHandler(event:ProgressEvent):void { + // nothing + } + + private function loader_securityErrorHandler(event:SecurityErrorEvent):void { + clearLoadingContent(); + } + + private function loader_ioErrorHandler(event:IOErrorEvent):void { + clearLoadingContent(); + } + + private function readSVG(content:*):void { + if (content is URLLoader) { + _svgDocument.parse((content as URLLoader).data); + } + } + + private function removeLoadingListeners():void { + if (loadingContent) { + loadingContent.removeEventListener(Event.COMPLETE, + loader_completeHandler); + loadingContent.removeEventListener(IOErrorEvent.IO_ERROR, + loader_ioErrorHandler); + loadingContent.removeEventListener(ProgressEvent.PROGRESS, + loader_progressHandler); + loadingContent.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, + loader_securityErrorHandler); + loadingContent.removeEventListener(HTTPStatusEvent.HTTP_STATUS, + dispatchEvent); + } + } + + private function loader_completeHandler(event:Event):void { + var loader:URLLoader = event.target.content as URLLoader; + + if (loader) { + readSVG(loader); + } + + dispatchEvent(event); + + // Remove any event listeners from load-event dispatcher. + clearLoadingContent(); + } + + private function clearLoadingContent():void { + removeLoadingListeners(); + loadingContent = null; + } + + private function cloneAndRedispatchEvent(e:SVGEvent):void { dispatchEvent(e.clone()); }