avm2: Call set_expose_content for swf loaded through Loader

This exposes non-null 'content' and 'url' fields to the SWF
at the proper time
This commit is contained in:
Aaron Hill 2024-09-11 21:04:49 -05:00
parent 90adab7015
commit bd27a6bbd6
8 changed files with 47 additions and 32 deletions

View File

@ -352,16 +352,17 @@ pub fn get_url<'gc>(
this: Object<'gc>,
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
if let Some(loader_stream) = this
.as_loader_info_object()
.and_then(|o| o.as_loader_stream())
{
if let Some(loader_info) = this.as_loader_info_object() {
if !loader_info.expose_content() {
return Ok(Value::Null);
}
if let Some(loader_stream) = loader_info.as_loader_stream() {
let root = match &*loader_stream {
LoaderStream::NotYetLoaded(_, _, false) => return Ok(Value::Null),
LoaderStream::NotYetLoaded(root, _, true) | LoaderStream::Swf(root, _) => root,
LoaderStream::NotYetLoaded(root, _, _) | LoaderStream::Swf(root, _) => root,
};
return Ok(AvmString::new_utf8(activation.context.gc_context, root.url()).into());
}
}
Ok(Value::Undefined)
}

View File

@ -2521,6 +2521,10 @@ impl<'gc> Loader<'gc> {
"addChild at the correct time"
);
if let Some(loader_info) = loader_info.as_loader_info_object() {
loader_info.set_expose_content();
}
// Note that we do *not* use the 'addChild' method here:
// Per the flash docs, our implementation always throws
// an 'unsupported' error. Also, the AVM2 side of our movie

View File

@ -1,16 +1,26 @@
package {
import flash.display.Stage;
import flash.display.Sprite;
import flash.display.MovieClip;
import flash.events.Event;
public class Loadable {
public function Loadable(stage: Stage) {
trace("Hello from loaded SWF!");
public class Loadable extends MovieClip {
public function Loadable() {
trace("Hello from loaded SWF:");
trace("Loaded swf loaderInfo.url: " + this.urlPrefix(this.loaderInfo.url) + " content: " + this.loaderInfo.content);
this.addEventListener(Event.ADDED_TO_STAGE, this.onAddedToStage);
var circle:Sprite = new Sprite();
circle.graphics.beginFill(0xFFCC00);
circle.graphics.drawCircle(50, 50, 50);
stage.addChild(circle);
this.addChild(circle);
}
private function onAddedToStage(event: *) {
trace("Added to stage: this.loaderInfo.url = " + this.urlPrefix(this.loaderInfo.url) + " this.loaderInfo.content = " + this.loaderInfo.content);
}
private function urlPrefix(url: String): String {
return url ? url.substr(0, 8) : url;
}
}
}

View File

@ -12,6 +12,10 @@
addFrameScript(0,this.frame1);
}
function urlPrefix(url: String): String {
return url ? url.substring(0, 8) : url;
}
function frame1() {
import flash.display.Loader;
import flash.net.URLRequest;
@ -28,23 +32,17 @@
trace("loader.contentLoaderInfo.bytesLoaded = " + loader.contentLoaderInfo.bytesLoaded);
trace("loader.contentLoaderInfo.bytesTotal = " + loader.contentLoaderInfo.bytesTotal);
trace("loader.contentLoaderInfo.bytes = " + loader.contentLoaderInfo.bytes);
trace("loader.contentLoaderInfo.url = " + loader.contentLoaderInfo.url);
trace("loader.contentLoaderInfo.url = " + this.urlPrefix(loader.contentLoaderInfo.url));
var bytes = ByteArray(new loadableSwf);
function dump(event:Event) {
var url = loader.contentLoaderInfo.url;
if (url) {
// This truncates the path to 'file:///' to make the output
// reproducible across deifferent machines
url = url.substr(0, 8);
}
trace("Event " + event + ": "
+ "loader.numChildren = " + loader.numChildren
+ ", loader.content = " + loader.content
+ ", loader.contentLoaderInfo.bytesLoaded = " + loader.contentLoaderInfo.bytesLoaded
+ ", loader.contentLoaderInfo.bytesTotal = " + loader.contentLoaderInfo.bytesTotal
+ ", loader.contentLoaderInfo.url = " + url);
+ ", loader.contentLoaderInfo.url = " + self.urlPrefix(loader.contentLoaderInfo.url));
trace("bytes.position = " + bytes.position);
}

BIN
tests/tests/swfs/avm2/loader_loadbytes_events/loadable.fla vendored Normal file → Executable file

Binary file not shown.

View File

@ -4,24 +4,26 @@ loader.contentLoaderInfo.bytesLoaded = 0
loader.contentLoaderInfo.bytesTotal = 0
loader.contentLoaderInfo.bytes = null
loader.contentLoaderInfo.url = null
Event [ProgressEvent type="progress" bubbles=false cancelable=false eventPhase=2 bytesLoaded=0 bytesTotal=738]: loader.numChildren = 0, loader.content = null, loader.contentLoaderInfo.bytesLoaded = 0, loader.contentLoaderInfo.bytesTotal = 738, loader.contentLoaderInfo.url = null
Event [ProgressEvent type="progress" bubbles=false cancelable=false eventPhase=2 bytesLoaded=0 bytesTotal=953]: loader.numChildren = 0, loader.content = null, loader.contentLoaderInfo.bytesLoaded = 0, loader.contentLoaderInfo.bytesTotal = 953, loader.contentLoaderInfo.url = null
bytes.position = 0
Event [ProgressEvent type="progress" bubbles=false cancelable=false eventPhase=2 bytesLoaded=738 bytesTotal=738]: loader.numChildren = 0, loader.content = null, loader.contentLoaderInfo.bytesLoaded = 738, loader.contentLoaderInfo.bytesTotal = 738, loader.contentLoaderInfo.url = null
Event [ProgressEvent type="progress" bubbles=false cancelable=false eventPhase=2 bytesLoaded=953 bytesTotal=953]: loader.numChildren = 0, loader.content = null, loader.contentLoaderInfo.bytesLoaded = 953, loader.contentLoaderInfo.bytesTotal = 953, loader.contentLoaderInfo.url = null
bytes.position = 0
Hello from loaded SWF:
Loaded swf loaderInfo.url: null content: null
Added to stage: this.loaderInfo.url = file:/// this.loaderInfo.content = [object Loadable]
Framescript frame 1
Hello from loaded SWF!
loader.contentLoaderInfo === loader.content.loaderInfo : true
loader.contentLoaderInfo.content === loader.content : true
Event [Event type="init" bubbles=false cancelable=false eventPhase=2]: loader.numChildren = 1, loader.content = [object LoadableMainTimeline], loader.contentLoaderInfo.bytesLoaded = 738, loader.contentLoaderInfo.bytesTotal = 738, loader.contentLoaderInfo.url = file:///
Event [Event type="init" bubbles=false cancelable=false eventPhase=2]: loader.numChildren = 1, loader.content = [object Loadable], loader.contentLoaderInfo.bytesLoaded = 953, loader.contentLoaderInfo.bytesTotal = 953, loader.contentLoaderInfo.url = file:///
bytes.position = 0
Event [Event type="complete" bubbles=false cancelable=false eventPhase=2]: loader.numChildren = 1, loader.content = [object LoadableMainTimeline], loader.contentLoaderInfo.bytesLoaded = 738, loader.contentLoaderInfo.bytesTotal = 738, loader.contentLoaderInfo.url = file:///
Event [Event type="complete" bubbles=false cancelable=false eventPhase=2]: loader.numChildren = 1, loader.content = [object Loadable], loader.contentLoaderInfo.bytesLoaded = 953, loader.contentLoaderInfo.bytesTotal = 953, loader.contentLoaderInfo.url = file:///
bytes.position = 0
Stage children before addChild attempt: 3
Stage children before addChild attempt: 2
loader.numChildren before addChild attempt: 1
loader.content before addChild attempt: [object LoadableMainTimeline]
Stage children after addChild attempt: 4
loader.content before addChild attempt: [object Loadable]
Added to stage: this.loaderInfo.url = file:/// this.loaderInfo.content = [object Loadable]
Stage children after addChild attempt: 3
loader.numChildren after addChild attempt: 0
loader.content after addChild attempt: [object LoadableMainTimeline]
loader.content after addChild attempt: [object Loadable]
Framescript frame 2
Framescript frame 1
Hello from loaded SWF!