[Laszlo-checkins] r12995 - openlaszlo/trunk/WEB-INF/lps/lfc/kernel/swf9
bargull@openlaszlo.org
bargull at openlaszlo.org
Sat Feb 21 16:45:52 PST 2009
Author: bargull
Date: 2009-02-21 16:45:48 -0800 (Sat, 21 Feb 2009)
New Revision: 12995
Modified:
openlaszlo/trunk/WEB-INF/lps/lfc/kernel/swf9/LzSprite.as
Log:
Change 20090220-bargull-Y8a by bargull at dell--p4--2-53 on 2009-02-20 00:53:38
in /home/Admin/src/svn/openlaszlo/trunk
for http://svn.openlaszlo.org/openlaszlo/trunk
Summary: loadratio for swf9 and change for security check
New Features:
Bugs Fixed: LPP-7709, LPP-7716
Technical Reviewer: max
QA Reviewer: promanik
Doc Reviewer: (pending)
Documentation:
Release Notes:
Details:
Renamed sound playback related methods:
- "startPlay" to "startSoundPlay"
- "stopPlay" to "stopSoundPlay"
- "updatePlay" to "updateSoundPlay"
Removed "frames", "source", "lastreswidth", "lastresheight", "skiponload", "baseurl". All of them were either no longer needed or left-overs from the original dhtml kernel based sprite implementation.
Moved loadurl computation in "setSource" in a separate method ("getLoadURL").
Removed null-pointer check in "applyStretchResource" because it was done twice.
Moved framenumber computation and setting from "stop()" and "play()" into a separate method ("updateResourcePlay").
LPP-7709:
Add all loader-events immediately after constructing the Loader, even though the comment at "loaderInitHandler" says that it won't work (which is a lie). See event description for "init" (flash.display.LoaderInfo):
"Dispatched when the properties and methods of a loaded SWF file are accessible and ready for use."
So the "init"-event is dispatched far too late and therefore no "progress"-events were detected and therefore no "onloadratio"-events for users.
LPP-7716:
Don't use "parentAllowsChild"/"childAllowsParent" to avoid security exceptions, instead use a simple try-catch block when accessing the loaded content. Also moved the playback warning from "loaderEventHandler" to "stop"/"play", because otherwise these warnings did appear when loading a simple application in debug-mode (triggered by avm1movie assets for the debugger).
Tests:
testcase from LPP-7709, note that "onloadratio" events are generated
amazon-demo in swf9
Modified: openlaszlo/trunk/WEB-INF/lps/lfc/kernel/swf9/LzSprite.as
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/lfc/kernel/swf9/LzSprite.as 2009-02-21 23:47:00 UTC (rev 12994)
+++ openlaszlo/trunk/WEB-INF/lps/lfc/kernel/swf9/LzSprite.as 2009-02-22 00:45:48 UTC (rev 12995)
@@ -30,7 +30,6 @@
import flash.media.SoundTransform;
import flash.media.SoundLoaderContext;
import flash.media.ID3Info;
-
}#
#passthrough {
@@ -48,18 +47,12 @@
public var clickbutton:SimpleButton = null;
public var clickregion:Shape = null;
public var masksprite:Sprite = null;
- public var frames:int = 1;
public var resource:String = null;
- public var source:String = null;
public var clip:Boolean = false;
public var resourcewidth:Number = 0;
public var resourceheight:Number = 0;
public var isroot:Boolean = false;
public static var rootSprite:LzSprite = null;
- var lastreswidth:Number = 0;
- var lastresheight:Number = 0;
- var skiponload = false;
- var baseurl;
// Used for workaround for contextmenu bug; use as a null hitArea for sprites that
// we don't want to get mouse events.
@@ -84,7 +77,7 @@
/* private */ var sound:Sound = null;
/* private */ var soundChannel:SoundChannel = null;
/* private */ var soundLoading:Boolean = false;
-
+
//@field Boolean _setrescwidth: If true, the view does not set its
//resource to the width given in a call to
//<method>setAttribute</method>. By default, views do not scale their
@@ -219,7 +212,6 @@
public function setResource (r:String):void {
if (this.resource == r) return;
if (r.indexOf('http:') == 0 || r.indexOf('https:') == 0) {
- this.skiponload = false;
this.setSource( r );
return;
}
@@ -240,7 +232,7 @@
}
return;
}
-
+
if (LzAsset.isBitmapAsset(r)
|| LzAsset.isMovieClipAsset(r)
|| LzAsset.isMovieClipLoaderAsset(r)) {
@@ -258,7 +250,7 @@
// clear resource cache
this.resourceCache = null;
}
-
+
this.__isinternalresource = true;
this.resource = r;
// instantiate resource at frame 1
@@ -270,13 +262,13 @@
this.unload();
this.__isinternalresource = true;
this.resource = r;
-
+
this.sound = new res['assetclass']() as Sound;
this.totalframes = Math.floor(this.getTotalTime() * MP3_FPS);
// TODO: add condition on this
- this.startPlay()
-
+ this.startSoundPlay()
+
// send events, but skip onload
this.sendResourceLoad(true);
} else if ($debug) {
@@ -287,7 +279,8 @@
public var imgLoader:Loader;
public var loaderMC:MovieClip;
- private var IMGDEPTH:int = 0;
+ private const IMGDEPTH:int = 0;
+ private static const MIME_SWF:String = "application/x-shockwave-flash";
/** setSource( String:url )
o Loads and displays media from the specified url
@@ -297,36 +290,7 @@
if (url == null || url == 'null') {
return;
}
- var loadurl = url;
- var proxied = this.owner.__LZcheckProxyPolicy( url );
- var proxyurl = this.owner.getProxyURL(url);
- if (proxied) {
- var params:Object = {serverproxyargs: {},
- timeout: canvas.medialoadtimeout,
- proxyurl: proxyurl,
- url: url,
- httpmethod: 'GET',
- service: 'media'
- };
- if (headers != null) {
- params.headers = headers;
- }
- if (cache == "none") {
- params.cache = false;
- params.ccache = false;
- } else if (cache == "clientonly") {
- params.cache = false;
- params.ccache = true;
- } else if (cache == "serveronly") {
- params.cache = true;
- params.ccache = false;
- } else {
- params.cache = true;
- params.ccache = true;
- }
- loadurl = lz.Browser.makeProxiedURL(params);
- }
-
+ var loadurl:String = getLoadURL(url, cache, headers);
if (getFileType(url, filetype) == "mp3") {
// unload previous image-resource and sound-resource
this.unload();
@@ -338,7 +302,7 @@
// unload previous sound-resource
this.unloadSound();
}
-
+
if (! imgLoader) {
if (this.resourceContainer) {
// unload previous internal image-resource
@@ -349,9 +313,7 @@
imgLoader.mouseChildren = false;
this.resourceContainer = imgLoader;
this.addChildAt(imgLoader, IMGDEPTH);
- var info:LoaderInfo = imgLoader.contentLoaderInfo;
- info.addEventListener(Event.INIT, loaderInitHandler);
- info.addEventListener(IOErrorEvent.IO_ERROR, loaderEventHandler);
+ this.attachLoaderEvents(imgLoader.contentLoaderInfo);
} else {
//TODO [20080911 anba] cancel current load?
// imgLoader.close();
@@ -367,8 +329,40 @@
}
}
-
- private function getFileType (url:String, filetype:String = null) :String {
+ private function getLoadURL (url:String, cache:String, headers:String) :String {
+ var loadurl:String = url;
+ var proxied:* = this.owner.__LZcheckProxyPolicy( url );
+ if (proxied) {
+ var proxyurl:String = this.owner.getProxyURL(url);
+ var params:Object = {serverproxyargs: {},
+ timeout: canvas.medialoadtimeout,
+ proxyurl: proxyurl,
+ url: url,
+ httpmethod: 'GET',
+ service: 'media'
+ };
+ if (headers != null) {
+ params.headers = headers;
+ }
+ if (cache == "none") {
+ params.cache = false;
+ params.ccache = false;
+ } else if (cache == "clientonly") {
+ params.cache = false;
+ params.ccache = true;
+ } else if (cache == "serveronly") {
+ params.cache = true;
+ params.ccache = false;
+ } else {
+ params.cache = true;
+ params.ccache = true;
+ }
+ loadurl = lz.Browser.makeProxiedURL(params);
+ }
+ return loadurl;
+ }
+
+ private function getFileType (url:String, filetype:String) :String {
if (filetype != null) {
return filetype.toLowerCase();
} else {
@@ -377,16 +371,14 @@
}
}
- public function loaderInitHandler(event:Event):void {
- // These progress event listeners can only be installed after the init event
- // has been received. You get an error if you try to add them before this.
- var loader:Loader = Loader(event.target.loader);
- var info:LoaderInfo = LoaderInfo(loader.contentLoaderInfo);
+ private function attachLoaderEvents (info:LoaderInfo) :void {
info.addEventListener(ProgressEvent.PROGRESS, loaderEventHandler);
info.addEventListener(Event.OPEN, loaderEventHandler);
- info.addEventListener(Event.UNLOAD, loaderEventHandler);
+ // info.addEventListener(Event.UNLOAD, loaderEventHandler);
+ // info.addEventListener(Event.INIT, loaderEventHandler);
info.addEventListener(Event.COMPLETE, loaderEventHandler);
info.addEventListener(SecurityErrorEvent.SECURITY_ERROR, loaderEventHandler);
+ info.addEventListener(IOErrorEvent.IO_ERROR, loaderEventHandler);
// @devnote: From the HTTPStatusEvent reference page:
// > Some Flash Player environments may be unable to detect HTTP status codes;
// > a status code of 0 is always reported in these cases.
@@ -394,7 +386,6 @@
//info.addEventListener(HTTPStatusEvent.HTTP_STATUS, loaderEventHandler);
}
-
public function loaderEventHandler(event:Event):void {
try {
//@devnote: accessing the Loader through "event.target.loader" may
@@ -411,29 +402,34 @@
}
var info:LoaderInfo = event.target as LoaderInfo;
- // avoid security exceptions
- if (info.parentAllowsChild) {
- if (info.content is AVM1Movie) {
- if ($debug) {
- Debug.warn("Playback control will not work for the resource. Please update or recompile the resource for Flash 9.", this.resource);
- }
- } else if (info.content is MovieClip) {
+ try {
+ // accessing LoaderInfo.content may throw security exceptions
+ var content:DisplayObject = info.content;
+ if (content is AVM1Movie) {
+ // no playback control
+ } else if (content is MovieClip) {
// store a reference for playback control
- this.loaderMC = MovieClip(info.content);
+ this.loaderMC = MovieClip(content);
this.totalframes = this.loaderMC.totalFrames;
this.loaderMC.addEventListener(Event.ENTER_FRAME, updateFrames);
this.owner.resourceevent('play', null, true);
this.playing = this.owner.playing = true;
- } else if (info.content is Bitmap) {
- (info.content as Bitmap).smoothing = true;
+ } else if (content is Bitmap) {
+ (content as Bitmap).smoothing = true;
}
+ } catch (error:SecurityError) {
+ // ignore for now
}
try {
- var loader:Loader = Loader(event.target.loader);
+ // accessing LoaderInfo.loader may throw security exceptions
+ // TODO [20090203 anba] why can't we use LoaderInfo.width/height,
+ // which won't generate security exceptions?
+ var loader:Loader = Loader(info.loader);
this.resourcewidth = loader.width;
this.resourceheight = loader.height;
- } catch (e) {
+ } catch (error:SecurityError) {
+ // TODO [20090203 anba] install default values?
}
// Apply stretch if needed, now that we know the asset dimensions.
this.applyStretchResource();
@@ -444,8 +440,8 @@
event.type == SecurityErrorEvent.SECURITY_ERROR) {
//TODO [20080911 anba] how can "owner" become null here?
if (this.owner != null) {
- // IOErrorEvent/SecurityErrorEvent -> ErrorEvent -> TextEvent
- this.owner.resourceloaderror( (event as TextEvent).text );
+ // IOErrorEvent/SecurityErrorEvent -> ErrorEvent
+ this.owner.resourceloaderror( (event as ErrorEvent).text );
}
} else if (event.type == ProgressEvent.PROGRESS) {
var ev:ProgressEvent = event as ProgressEvent;
@@ -488,20 +484,20 @@
this.sound.addEventListener(Event.COMPLETE, soundLoadHandler);
this.sound.addEventListener(ProgressEvent.PROGRESS, soundLoadHandler);
this.sound.addEventListener(IOErrorEvent.IO_ERROR, soundLoadHandler);
-
+
this.sound.load(new URLRequest(url), LzSprite.soundLoaderContext);
-
+
// TODO: add condition on this
- this.startPlay();
+ this.startSoundPlay();
}
-
+
/**
* Stop current playback and unload sound
*/
private function unloadSound () :void {
if (this.playing) {
// stop playing
- this.stopPlay();
+ this.stopSoundPlay();
}
if (this.sound) {
if (this.soundLoading) {
@@ -512,15 +508,15 @@
this.sound = null;
}
}
-
+
/**
* Start sound playback and tracking
* @param Number frame: frame/secs to start at playing
* @param Boolean isFrame: if set to false, treat 'frame' as seconds
*/
- private function startPlay (frame:Number = 0, isFrame:Boolean = true) :void {
+ private function startSoundPlay (frame:Number = 0, isFrame:Boolean = true) :void {
var pos:Number = (isFrame ? (frame / MP3_FPS) : frame) * 1000;
-
+
this.playing = this.owner.playing = true;
this.soundChannel = this.sound.play(pos, 0, this.soundTransform);
this.addEventListener(Event.ENTER_FRAME, soundFrameHandler);
@@ -531,31 +527,31 @@
* Stop sound playback and tracking
* @return Number: the current frame when playback was stopped
*/
- private function stopPlay () :Number {
+ private function stopSoundPlay () :Number {
var frame:Number = Math.floor(this.soundChannel.position * 0.001 * MP3_FPS);
-
+
this.playing = this.owner.playing = false;
this.removeEventListener(Event.ENTER_FRAME, soundFrameHandler);
this.soundChannel.stop();
this.soundChannel = null;
-
+
return frame;
}
-
+
/**
* Update sound play status
*/
- private function updatePlay (play:Boolean, framenumber:*, rel:Boolean) :void {
+ private function updateSoundPlay (play:Boolean, framenumber:*, rel:Boolean) :void {
var fr:Number;
if (this.playing) {
// stop previous playback
- fr = this.stopPlay();
+ fr = this.stopSoundPlay();
} else {
// TODO: this.frame is initialized with 1, which
// means we currently skip 33ms at the beginning
fr = this.frame;
}
-
+
if (framenumber != null) {
framenumber += rel ? fr : 0;
} else if (play) {
@@ -565,14 +561,14 @@
} else {
framenumber = fr;
}
-
+
if (play) {
- this.startPlay(framenumber);
+ this.startSoundPlay(framenumber);
} else {
this.frame = framenumber;
}
}
-
+
/**
* Progress sound loading
*/
@@ -600,10 +596,10 @@
this.owner.resourceloaderror( (event as IOErrorEvent).text );
}
} catch (error:Error) {
- trace(event.type + " " + error);
+ if ($debug) Debug.warn(event.type + " " + error);
}
}
-
+
/**
* Track playback
*/
@@ -619,7 +615,7 @@
private function soundCompleteHandler (event:Event) :void {
// Event.SOUND_COMPLETE
if (this.playing) {
- this.stopPlay();
+ this.stopSoundPlay();
this.frame = this.totalframes;
// SoundChannel.position does not stop exactly at Sound.length,
@@ -629,7 +625,7 @@
this.owner.resourceevent('lastframe', null, true);
}
}
-
+
//// Mouse event trampoline
public function attachMouseEvents(dobj:DisplayObject) :void {
dobj.addEventListener(MouseEvent.CLICK, __mouseEvent, false);
@@ -963,24 +959,20 @@
public function play (framenumber:* = null, rel:Boolean = false) :void {
if (this.isaudio) {
// audio-resource is attached
- this.updatePlay(true, framenumber, rel);
-
+ this.updateSoundPlay(true, framenumber, rel);
+
this.owner.resourceevent('play', null, true);
} else if (this.__isinternalresource) {
stop(framenumber, rel);
} else if (this.loaderMC) {
this.owner.resourceevent('play', null, true);
- this.playing = this.owner.playing = true;
- if (framenumber == null) {
- this.loaderMC.play();
- } else {
- if (rel) framenumber += this.frame;
- if (framenumber > this.totalframes) {
- framenumber = this.totalframes;
- } else if (framenumber < 1) {
- framenumber = 1;
+ this.updateResourcePlay(true, framenumber, rel);
+ } else if (this.imgLoader) {
+ if ($debug) {
+ var info:LoaderInfo = this.imgLoader.contentLoaderInfo;
+ if (info.contentType == LzSprite.MIME_SWF && info.swfVersion < SWFVersion.FLASH9) {
+ Debug.warn("Playback control will not work for the resource. Please update or recompile the resource for Flash 9.", this.resource);
}
- this.loaderMC.gotoAndPlay(framenumber);
}
} else {
//Debug.write('unhandled play', framenumber, rel);
@@ -996,15 +988,15 @@
if (this.isaudio) {
// audio-resource is attached
var p:Boolean = this.playing;
- this.updatePlay(false, fn, rel);
-
+ this.updateSoundPlay(false, fn, rel);
+
if (p) this.owner.resourceevent('stop', null, true);
} else if (this.__isinternalresource) {
var resinfo:Object = LzResourceLibrary[this.resource];
// Frames are one based not zero based
var frames:Array = resinfo.frames;
- var origfn = fn;
+ var origfn:* = fn;
if (fn == null || fn < 1) {
origfn = fn = 1;
} else if (fn > frames.length) {
@@ -1030,7 +1022,7 @@
if (asset == null) {
//Debug.write('CACHE MISS, new ',assetclass);
asset = new assetclass();
- asset.scaleX = 1.0
+ asset.scaleX = 1.0;
asset.scaleY = 1.0;
this.resourceCache[framenumber] = asset;
}
@@ -1043,7 +1035,7 @@
LzIdleKernel.addCallback(this, '__resetframe');
return;
}
-
+
if (this.resourceContainer != null) {
this.removeChild(this.resourceContainer);
}
@@ -1052,7 +1044,7 @@
if (asset is DisplayObjectContainer) DisplayObjectContainer(asset).mouseChildren = false;
this.resourceContainer = asset;
- this.addChildAt(asset,IMGDEPTH);
+ this.addChildAt(asset, IMGDEPTH);
this.applyStretchResource();
@@ -1078,17 +1070,13 @@
}
} else if (this.loaderMC) {
if ( this.playing ) this.owner.resourceevent('stop', null, true);
- this.playing = this.owner.playing = false;
- if (fn == null) {
- this.loaderMC.stop();
- } else {
- if (rel) fn += this.frame;
- if (fn > this.totalframes) {
- fn = this.totalframes;
- } else if (fn < 1) {
- fn = 1;
+ this.updateResourcePlay(false, fn, rel);
+ } else if (this.imgLoader) {
+ if ($debug) {
+ var info:LoaderInfo = this.imgLoader.contentLoaderInfo;
+ if (info.contentType == LzSprite.MIME_SWF && info.swfVersion < SWFVersion.FLASH9) {
+ Debug.warn("Playback control will not work for the resource. Please update or recompile the resource for Flash 9.", this.resource);
}
- this.loaderMC.gotoAndStop(fn);
}
} else {
// This shouldn't happen - but it does, on roll over
@@ -1096,6 +1084,30 @@
}
}
+ private function updateResourcePlay (play:Boolean, framenumber:*, rel:Boolean) :void {
+ this.playing = this.owner.playing = play;
+
+ if (framenumber == null) {
+ if (play) {
+ this.loaderMC.play();
+ } else {
+ this.loaderMC.stop();
+ }
+ } else {
+ if (rel) framenumber += this.frame;
+ if (framenumber > this.totalframes) {
+ framenumber = this.totalframes;
+ } else if (framenumber < 1) {
+ framenumber = 1;
+ }
+ if (play) {
+ this.loaderMC.gotoAndPlay(framenumber);
+ } else {
+ this.loaderMC.gotoAndStop(framenumber);
+ }
+ }
+ }
+
/** Callback resets resources after they have loaded and displayed */
public function __resetframe(ignore=null):void {
LzIdleKernel.removeCallback(this, '__resetframe');
@@ -1168,10 +1180,6 @@
}
public function applyStretchResource():void {
- if (this.resourceContainer == null) {
- return;
- }
-
var res = this.resourceContainer;
// Don't try to do anything while an image is loading
@@ -1335,7 +1343,7 @@
}
if (this.isaudio) this.unloadSound();
// clear out cached values
- this.lastreswidth = this.lastresheight = this.resourcewidth = this.resourceheight = 0;
+ this.resourcewidth = this.resourceheight = 0;
this.resource = null;
this.__isinternalresource = null;
if (this.loaderMC) {
@@ -1468,7 +1476,7 @@
function getPan () :Number {
return LzAudioKernel.getPan(this);
}
-
+
/**
* @param Number secs:
* @param Boolean playing:
@@ -1482,16 +1490,16 @@
if (pos > total) pos = total;
if (this.playing) {
- this.stopPlay();
+ this.stopSoundPlay();
}
if (doplay) {
- this.startPlay(pos, false);
+ this.startSoundPlay(pos, false);
} else {
this.frame = Math.floor(pos * MP3_FPS);
}
}
}
-
+
/**
* @return Number: time elapsed (in seconds)
*/
@@ -1507,14 +1515,14 @@
return 0;
}
}
-
+
/**
* @return Number: length of the current sound (in seconds)
*/
function getTotalTime () :Number {
return this.isaudio ? this.sound.length * 0.001 : 0;
}
-
+
/**
* @return ID3Info: id3-info of the current sound
*/
More information about the Laszlo-checkins
mailing list