зеркало из https://github.com/mozilla/shumway.git
Merge branch 'master' into ir-2
This commit is contained in:
Коммит
720673fe5b
|
@ -11,3 +11,6 @@ src/avm2/generated/avmplus/avmplus.cpp
|
|||
src/avm2/utils/asc.jar
|
||||
src/avm2/utils/avmshell
|
||||
src/avm2/utils/js
|
||||
|
||||
src/flash/playerGlobal.min.abc
|
||||
|
||||
|
|
|
@ -4,3 +4,6 @@
|
|||
[submodule "lib/DataView.js"]
|
||||
path = lib/DataView.js
|
||||
url = https://github.com/davidflanagan/DataView.js.git
|
||||
[submodule "lib/xstats"]
|
||||
path = lib/xstats
|
||||
url = https://github.com/bestiejs/xstats.js.git
|
||||
|
|
31
Makefile
31
Makefile
|
@ -1,6 +1,7 @@
|
|||
default:
|
||||
@echo "run: make [check-system|install-utils|install-libs|build-tamarin-tests|"
|
||||
@echo " build-playerglobal|build-extension|test|push-test|build-bot|start-build-bot]"
|
||||
@echo " build-playerglobal|build-extension|build-web|"
|
||||
@echo " test|push-test|build-bot|start-build-bot]"
|
||||
|
||||
check-system:
|
||||
echo "Checking the presence of mercurial..."
|
||||
|
@ -32,10 +33,33 @@ build-playerglobal:
|
|||
build-extension:
|
||||
make -C extension/firefox/ build
|
||||
|
||||
build-web:
|
||||
make -C web/ build
|
||||
|
||||
update-flash-refs:
|
||||
node utils/update-flash-refs.js extension/firefox/content/web/viewer.html src/flash
|
||||
node utils/update-flash-refs.js examples/inspector/inspector.html src/flash
|
||||
node utils/update-flash-refs.js examples/racing/index.html src/flash
|
||||
node utils/update-flash-refs.js test/harness/slave.html src/flash
|
||||
|
||||
test:
|
||||
make -C src/avm1/tests/ test
|
||||
make -C src/avm2/bin/ test-regress
|
||||
|
||||
BROWSER_MANIFEST ?= resources/browser_manifests/browser_manifest.json
|
||||
|
||||
check-browser-manifest:
|
||||
@ls test/$(BROWSER_MANIFEST) || { echo "ERROR: Browser manifest file is not found at test/$(BROWSER_MANIFEST). Create one using the examples at test/resources/browser_manifests/."; exit 1; }
|
||||
|
||||
reftest: check-browser-manifest
|
||||
cd test; python test.py --reftest --browserManifestFile=$(BROWSER_MANIFEST)
|
||||
|
||||
makeref: check-browser-manifest
|
||||
cd test; python test.py --masterMode --browserManifestFile=$(BROWSER_MANIFEST)
|
||||
|
||||
reftest-swfdec: check-browser-manifest
|
||||
cd test; python test.py --reftest --browserManifestFile=$(BROWSER_MANIFEST) --manifestFile=swfdec_test_manifest.json
|
||||
|
||||
hello-world:
|
||||
make -C src/avm2/bin/ hello-world
|
||||
|
||||
|
@ -86,4 +110,7 @@ start-build-bot:
|
|||
sleep 60 ; \
|
||||
done
|
||||
|
||||
.PHONY: check-system install-libs install-utils build-tamarin-tests build-playerglobal build-extension test
|
||||
.PHONY: check-system install-libs install-utils build-tamarin-tests \
|
||||
build-playerglobal build-extension build-web test default \
|
||||
reftest reftest-swfdec makeref check-browser-manifest
|
||||
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>AS3 Tiger</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="stage"></div>
|
||||
|
||||
<script src="../../src/swf/util.js"></script>
|
||||
<script src="../../src/swf/swf.js"></script>
|
||||
<script>
|
||||
SWF.workerPath = "../../src/swf/worker.js";
|
||||
</script>
|
||||
<script src="../../src/swf/worker.js"></script>
|
||||
<script src="../../src/swf/prototypes.js"></script>
|
||||
<script src="../../src/swf/embed.js"></script>
|
||||
<script src="../../src/swf/renderer.js"></script>
|
||||
|
||||
<script>
|
||||
window.print = function (msg) {
|
||||
console.log(msg);
|
||||
};
|
||||
var webShell = true;
|
||||
</script>
|
||||
<script src="../../src/avm2/DataView.js"></script>
|
||||
<script src="../../src/avm2/util.js"></script>
|
||||
<script>
|
||||
var options = new OptionSet("option(s)");
|
||||
var disassemble = options.register(new Option("disassemble", "d", false, "disassemble"));
|
||||
var traceLevel = options.register(new Option("traceLevel", "t", 0, "trace level"));
|
||||
</script>
|
||||
<script src="../../src/avm2/constants.js"></script>
|
||||
<script src="../../src/avm2/opcodes.js"></script>
|
||||
<script src="../../src/avm2/parser.js"></script>
|
||||
<script src="../../src/avm2/disassembler.js"></script>
|
||||
<script src="../../src/avm2/analyze.js"></script>
|
||||
<script src="../../src/avm2/compiler.js"></script>
|
||||
<script src="../../src/avm2/native.js"></script>
|
||||
<script src="../../src/avm2/runtime.js"></script>
|
||||
<script src="../../src/avm2/interpreter.js"></script>
|
||||
|
||||
<script src="../../src/flash/events/EventDispatcher.js"></script>
|
||||
<script src="../../src/flash/display/DisplayObject.js"></script>
|
||||
<script src="../../src/flash/display/InteractiveObject.js"></script>
|
||||
<script src="../../src/flash/display/DisplayObjectContainer.js"></script>
|
||||
<script src="../../src/flash/display/Graphics.js"></script>
|
||||
<script src="../../src/flash/display/Sprite.js"></script>
|
||||
<script src="../../src/flash/display/MovieClip.js"></script>
|
||||
|
||||
<script>
|
||||
var abcFiles = [];
|
||||
var filesLoaded = 0;
|
||||
["builtin", "playerGlobal"].forEach(function (v, i, a) {
|
||||
var xhr = new XMLHttpRequest;
|
||||
xhr.open("GET", "../../src/avm2/generated/" + v + "/" + v + ".abc");
|
||||
xhr.responseType = "arraybuffer";
|
||||
xhr.onload = function () {
|
||||
abcFiles[i] = new AbcFile(new Uint8Array(this.response), v, true);
|
||||
if (++filesLoaded === a.length) {
|
||||
abcFiles.forEach(function (abc) {
|
||||
(filesLoaded === 1 ? executeAbc : loadAbc)(abc, EXECUTION_MODE.INTERPRET);
|
||||
});
|
||||
SWF.embed("../../examples/as3_tiger/tiger.swf", document.getElementById("stage"));
|
||||
}
|
||||
}
|
||||
xhr.send();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,24 @@
|
|||
package {
|
||||
import flash.display.Bitmap;
|
||||
import flash.display.BitmapData;
|
||||
import flash.display.Sprite;
|
||||
import flash.geom.Rectangle;
|
||||
|
||||
public class BitmapTests extends Sprite {
|
||||
//---------------------- Public Properties ----------------------//
|
||||
|
||||
|
||||
//---------------------- Private / Protected Properties ----------------------//
|
||||
|
||||
|
||||
//---------------------- Public Methods ----------------------//
|
||||
public function BitmapTests() {
|
||||
var bits : BitmapData = new BitmapData(100, 100, false, 0xff0000);
|
||||
var bitmap : Bitmap = new Bitmap(bits);
|
||||
addChild(bitmap);
|
||||
bits.fillRect(new Rectangle(10, 10, 80, 80), 0x0000ff);
|
||||
}
|
||||
|
||||
//---------------------- Private / Protected Methods ----------------------//
|
||||
}
|
||||
}
|
Двоичный файл не отображается.
|
@ -6,11 +6,14 @@
|
|||
<link rel="stylesheet" href="style/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="stage"></div>
|
||||
<div id="stage">
|
||||
<div id="xstats"></div>
|
||||
</div>
|
||||
|
||||
<script src="jquery.min.js"></script>
|
||||
<script src="../../lib/DataView.js/DataView.js"></script>
|
||||
<script src="../../lib/Kanvas/kanvas.js"></script>
|
||||
<script src="../../lib/xstats/xstats.js"></script>
|
||||
|
||||
<!-- Load SWF Dependencies -->
|
||||
<script src="../../src/swf/util.js"></script>
|
||||
|
@ -96,46 +99,53 @@
|
|||
<!-- Load Flash Dependencies -->
|
||||
|
||||
<script src="../../src/flash/util.js"></script>
|
||||
<script src="../../src/flash/events/Event.js"></script>
|
||||
<script src="../../src/flash/events/KeyboardEvent.js"></script>
|
||||
<script src="../../src/flash/events/TimerEvent.js"></script>
|
||||
<script src="../../src/flash/events/EventDispatcher.js"></script>
|
||||
<script src="../../src/flash/net/NetConnection.js"></script>
|
||||
<script src="../../src/flash/net/NetStream.js"></script>
|
||||
<!-- Autogenerated flash references: base=../../src/flash/ -->
|
||||
<script src="../../src/flash/display/Bitmap.js"></script>
|
||||
<script src="../../src/flash/display/BitmapData.js"></script>
|
||||
<script src="../../src/flash/display/DisplayObject.js"></script>
|
||||
<script src="../../src/flash/display/InteractiveObject.js"></script>
|
||||
<script src="../../src/flash/display/DisplayObjectContainer.js"></script>
|
||||
<script src="../../src/flash/display/Sprite.js"></script>
|
||||
<script src="../../src/flash/display/MovieClip.js"></script>
|
||||
<script src="../../src/flash/display/Graphics.js"></script>
|
||||
<script src="../../src/flash/display/InteractiveObject.js"></script>
|
||||
<script src="../../src/flash/display/Loader.js"></script>
|
||||
<script src="../../src/flash/display/LoaderInfo.js"></script>
|
||||
<script src="../../src/flash/display/Stage.js"></script>
|
||||
<script src="../../src/flash/display/BitmapData.js"></script>
|
||||
<script src="../../src/flash/display/Graphics.js"></script>
|
||||
<script src="../../src/flash/display/MorphShape.js"></script>
|
||||
<script src="../../src/flash/display/MovieClip.js"></script>
|
||||
<script src="../../src/flash/display/Shape.js"></script>
|
||||
<script src="../../src/flash/display/SimpleButton.js"></script>
|
||||
<script src="../../src/flash/display/Sprite.js"></script>
|
||||
<script src="../../src/flash/display/Stage.js"></script>
|
||||
<script src="../../src/flash/events/Event.js"></script>
|
||||
<script src="../../src/flash/events/EventDispatcher.js"></script>
|
||||
<script src="../../src/flash/events/KeyboardEvent.js"></script>
|
||||
<script src="../../src/flash/events/MouseEvent.js"></script>
|
||||
<script src="../../src/flash/events/TextEvent.js"></script>
|
||||
<script src="../../src/flash/events/TimerEvent.js"></script>
|
||||
<script src="../../src/flash/external/ExternalInterface.js"></script>
|
||||
<script src="../../src/flash/geom/ColorTransform.js"></script>
|
||||
<script src="../../src/flash/geom/Matrix.js"></script>
|
||||
<script src="../../src/flash/geom/Point.js"></script>
|
||||
<script src="../../src/flash/geom/Rectangle.js"></script>
|
||||
<script src="../../src/flash/geom/Matrix.js"></script>
|
||||
<script src="../../src/flash/geom/ColorTransform.js"></script>
|
||||
<script src="../../src/flash/geom/Transform.js"></script>
|
||||
<!--
|
||||
<script src="../../src/flash/media/Sound.js"></script>
|
||||
<script src="../../src/flash/media/SoundMixer.js"></script>
|
||||
<script src="../../src/flash/media/SoundTransform.js"></script>
|
||||
-->
|
||||
<script src="../../src/flash/media/Video.js"></script>
|
||||
<!--
|
||||
<script src="../../src/flash/net/NetConnection.js"></script>
|
||||
<script src="../../src/flash/net/NetStream.js"></script>
|
||||
<script src="../../src/flash/net/Responder.js"></script>
|
||||
<script src="../../src/flash/net/URLRequest.js"></script>
|
||||
<script src="../../src/flash/system/Capabilities.js"></script>
|
||||
<script src="../../src/flash/system/FSCommand.js"></script>
|
||||
<script src="../../src/flash/text/Font.js"></script>
|
||||
-->
|
||||
<script src="../../src/flash/text/StaticText.js"></script>
|
||||
<script src="../../src/flash/text/TextField.js"></script>
|
||||
<script src="../../src/flash/ui/Keyboard.js"></script>
|
||||
<!--
|
||||
<script src="../../src/flash/ui/Mouse.js"></script>
|
||||
-->
|
||||
<script src="../../src/flash/utils/Timer.js"></script>
|
||||
<!-- Autogenerated flash references end -->
|
||||
<script src="../../src/flash/stubs.js"></script>
|
||||
|
||||
<input type="file" id="files" name="files[]" multiple style="visibility: hidden;">
|
||||
<input type="file" id="files" name="files[]" multiple style="visibility: hidden;" accept="application/x-shockwave-flash">
|
||||
|
||||
<!--
|
||||
Shameless copying from:
|
||||
|
@ -143,9 +153,13 @@
|
|||
-->
|
||||
|
||||
<div class="toolbarGroup">
|
||||
<div class="toolbarBox withEmphasis" style="position: fixed; bottom: 380px; left: auto; right: 0px; width: 300px;" hidden>
|
||||
<div class="closeButton"></div>
|
||||
<div class="toolbarLabel " style="width: 240px; text-align: left;" id="message">Test</div>
|
||||
</div>
|
||||
<div class="toolbarInfo" style="position: fixed; bottom: 70px; left: auto; right: 0px; width: 300px; height: 300px;" id="info">
|
||||
</div>
|
||||
<div class="toolbarBox" style="position: fixed; bottom: 35px; left: 0; right: 0; width: auto;">
|
||||
<div class="toolbarBox" style="position: fixed; bottom: 35px; left: 0; right: 0; width: auto;" id="openFileToolbar">
|
||||
<div class="closeButton"></div>
|
||||
<div class="toolbarLabel " style="width: 140px; text-align: left;">Shumway Inspector</div>
|
||||
<div class="toolbarButton" id="openFile" title="Select SWF/ABC file (or drag'n'drop the file on the stage).">Open File</div>
|
||||
|
@ -166,7 +180,12 @@
|
|||
<script src="inspector.js"></script>
|
||||
|
||||
<script>
|
||||
SHUMWAY_ROOT = "../../";
|
||||
SHUMWAY_ROOT = "../../src/";
|
||||
</script>
|
||||
|
||||
<script>
|
||||
var stats = new xStats;
|
||||
document.getElementById('xstats').appendChild(stats.element);
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
|
|
@ -65,13 +65,19 @@ var playerGlobalPath = "../../src/flash/playerGlobal.min.abc";
|
|||
* when the page loads.
|
||||
*/
|
||||
if (rfile) {
|
||||
$('#openFileToolbar')[0].setAttribute('hidden', true);
|
||||
executeFile(rfile);
|
||||
}
|
||||
|
||||
function showMessage(msg) {
|
||||
$('#message').text(msg);
|
||||
$('#message')[0].parentElement.removeAttribute('hidden');
|
||||
}
|
||||
|
||||
function executeFile(file, buffer) {
|
||||
// All execution paths must now load AVM2.
|
||||
if (!state.compiler) {
|
||||
alert ("Running in the Interpreter");
|
||||
showMessage("Running in the Interpreter");
|
||||
}
|
||||
var appMode = state.compiler ? EXECUTION_MODE.COMPILE : EXECUTION_MODE.INTERPRET;
|
||||
if (file.endsWith(".abc")) {
|
||||
|
|
|
@ -34,3 +34,6 @@ $("#openFile").click(function () {
|
|||
$("#files").click();
|
||||
});
|
||||
|
||||
$(".closeButton").click(function (event) {
|
||||
event.target.parentElement.setAttribute('hidden', true);
|
||||
});
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
function loadState() {
|
||||
return localStorage["Inspector-Settings"] ? JSON.parse(localStorage["Inspector-Settings"]): {};
|
||||
return localStorage["Inspector-Settings"] ? JSON.parse(localStorage["Inspector-Settings"]) : {
|
||||
compiler: true,
|
||||
verifier: true,
|
||||
optimizer: true,
|
||||
inlineCaching: true,
|
||||
release: true
|
||||
};
|
||||
}
|
||||
|
||||
function saveState(state) {
|
||||
|
|
|
@ -12,7 +12,7 @@ body {
|
|||
|
||||
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
||||
body {
|
||||
background: #1a2633;
|
||||
background-color: #1a2633;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,15 +22,23 @@ body {
|
|||
}
|
||||
|
||||
.toolbarInfo {
|
||||
font-family: Consolas, Lucida Grande, sans-serif;
|
||||
|
||||
padding: 4px 8px;
|
||||
background: url(images/background-noise-toolbar.png),
|
||||
background-image: url(images/background-noise-toolbar.png),
|
||||
linear-gradient(hsl(210,11%,36%), hsl(210,11%,18%));
|
||||
background-image: url(images/background-noise-toolbar.png),
|
||||
-moz-linear-gradient(hsl(210,11%,36%), hsl(210,11%,18%));
|
||||
background-image: url(images/background-noise-toolbar.png),
|
||||
-webkit-linear-gradient(hsl(210,11%,36%), hsl(210,11%,18%));
|
||||
background-image: url(images/background-noise-toolbar.png),
|
||||
-o-linear-gradient(hsl(210,11%,36%), hsl(210,11%,18%));
|
||||
background-image: url(images/background-noise-toolbar.png),
|
||||
-ms-linear-gradient(hsl(210,11%,36%), hsl(210,11%,18%));
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 1px 0 hsla(210,16%,76%,.2) inset,
|
||||
0 0 0 1px hsla(0,0%,0%,.15),
|
||||
0 10px 14px hsla(0,0%,0%,.4);
|
||||
font-family: Consolas, Lucida Grande, sans-serif;
|
||||
|
||||
0 10px 14px hsla(0,0%,0%,.4),
|
||||
0 0 0 1px hsla(210,16%,76%,.15) inset,
|
||||
0 1px 0 hsla(210,16%,76%,.15);
|
||||
color: hsl(210,30%,85%);
|
||||
|
@ -38,10 +46,8 @@ body {
|
|||
line-height: 22px;
|
||||
text-shadow: 0 -1px 0 hsla(210,8%,5%,.45);
|
||||
cursor: default;
|
||||
|
||||
line-height: 1.2em;
|
||||
font-size: 11px;
|
||||
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
|
@ -49,8 +55,17 @@ body {
|
|||
padding: 4px 8px;
|
||||
width: 600px;
|
||||
height: 24px;
|
||||
background: url(images/background-noise-toolbar.png),
|
||||
linear-gradient(hsl(210,11%,36%), hsl(210,11%,18%));
|
||||
background: url(images/background-noise-toolbar.png),
|
||||
-moz-linear-gradient(hsl(210,11%,36%), hsl(210,11%,18%));
|
||||
background: url(images/background-noise-toolbar.png),
|
||||
-webkit-linear-gradient(hsl(210,11%,36%), hsl(210,11%,18%));
|
||||
background: url(images/background-noise-toolbar.png),
|
||||
-o-linear-gradient(hsl(210,11%,36%), hsl(210,11%,18%));
|
||||
background: url(images/background-noise-toolbar.png),
|
||||
-ms-linear-gradient(hsl(210,11%,36%), hsl(210,11%,18%));
|
||||
background: url(images/background-noise-toolbar.png),
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 1px 0 hsla(210,16%,76%,.2) inset,
|
||||
0 0 0 1px hsla(0,0%,0%,.15),
|
||||
|
@ -58,6 +73,24 @@ body {
|
|||
font-family: Lucida Grande, sans-serif;
|
||||
}
|
||||
|
||||
.toolbarBox.withEmphasis {
|
||||
background: url(images/background-noise-toolbar.png),
|
||||
linear-gradient(hsl(0,51%,36%), hsl(0,51%,18%));
|
||||
background: url(images/background-noise-toolbar.png),
|
||||
-moz-linear-gradient(hsl(0,51%,36%), hsl(0,51%,18%));
|
||||
background: url(images/background-noise-toolbar.png),
|
||||
-webkit-linear-gradient(hsl(0,51%,36%), hsl(0,51%,18%));
|
||||
background: url(images/background-noise-toolbar.png),
|
||||
-o-linear-gradient(hsl(0,51%,36%), hsl(0,51%,18%));
|
||||
background: url(images/background-noise-toolbar.png),
|
||||
-ms-linear-gradient(hsl(0,51%,36%), hsl(0,51%,18%));
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 1px 0 hsla(0,56%,76%,.2) inset,
|
||||
0 0 0 1px hsla(0,0%,0%,.15),
|
||||
0 10px 14px hsla(0,0%,0%,.4);
|
||||
font-family: Lucida Grande, sans-serif;
|
||||
}
|
||||
|
||||
.closeButton {
|
||||
float: left;
|
||||
width: 16px;
|
||||
|
@ -79,14 +112,16 @@ body {
|
|||
width: 78px;
|
||||
height: 22px;
|
||||
margin-right: 10px;
|
||||
0 0 0 1px hsla(210,16%,76%,.15) inset,
|
||||
0 1px 0 hsla(210,16%,76%,.15);
|
||||
color: hsl(210,30%,85%);
|
||||
font-size: 12px;
|
||||
line-height: 22px;
|
||||
text-align: center;
|
||||
text-shadow: 0 -1px 0 hsla(210,8%,5%,.45);
|
||||
user-select: none;
|
||||
-moz-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-o-user-select: none;
|
||||
-ms-user-select: none;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
|
@ -97,7 +132,11 @@ body {
|
|||
margin-right: 10px;
|
||||
border: 1px solid hsla(210,8%,5%,.45);
|
||||
border-radius: 3px;
|
||||
background: linear-gradient(hsla(212,7%,57%,.35), hsla(212,7%,57%,.1));
|
||||
background: -moz-linear-gradient(hsla(212,7%,57%,.35), hsla(212,7%,57%,.1));
|
||||
background: -webkit-linear-gradient(hsla(212,7%,57%,.35), hsla(212,7%,57%,.1));
|
||||
background: -o-linear-gradient(hsla(212,7%,57%,.35), hsla(212,7%,57%,.1));
|
||||
background: -ms-linear-gradient(hsla(212,7%,57%,.35), hsla(212,7%,57%,.1));
|
||||
background-clip: padding-box;
|
||||
box-shadow: 0 1px 0 hsla(210,16%,76%,.15) inset,
|
||||
0 0 0 1px hsla(210,16%,76%,.15) inset,
|
||||
|
@ -107,13 +146,21 @@ body {
|
|||
line-height: 22px;
|
||||
text-align: center;
|
||||
text-shadow: 0 -1px 0 hsla(210,8%,5%,.45);
|
||||
user-select: none;
|
||||
-moz-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-o-user-select: none;
|
||||
-ms-user-select: none;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.toolbarButton:not(.pressedState):hover:active {
|
||||
border: 1px solid hsla(210,8%,5%,.6);
|
||||
background: linear-gradient(hsla(220,6%,10%,.3), hsla(212,7%,57%,.15) 65%, hsla(212,7%,57%,.3));
|
||||
background: -moz-linear-gradient(hsla(220,6%,10%,.3), hsla(212,7%,57%,.15) 65%, hsla(212,7%,57%,.3));
|
||||
background: -webkit-linear-gradient(hsla(220,6%,10%,.3), hsla(212,7%,57%,.15) 65%, hsla(212,7%,57%,.3));
|
||||
background: -o-linear-gradient(hsla(220,6%,10%,.3), hsla(212,7%,57%,.15) 65%, hsla(212,7%,57%,.3));
|
||||
background: -ms-linear-gradient(hsla(220,6%,10%,.3), hsla(212,7%,57%,.15) 65%, hsla(212,7%,57%,.3));
|
||||
box-shadow: 0 0 3px hsla(210,8%,5%,.25) inset,
|
||||
0 1px 3px hsla(210,8%,5%,.25) inset,
|
||||
0 1px 0 hsla(210,16%,76%,.15);
|
||||
|
@ -121,7 +168,11 @@ body {
|
|||
|
||||
.toolbarButton.pressedState {
|
||||
border: 1px solid hsla(210,8%,5%,.6);
|
||||
background: linear-gradient(hsla(220,6%,10%,.6), hsla(210,11%,18%,.45) 75%, hsla(210,11%,30%,.4));
|
||||
background: -moz-linear-gradient(hsla(220,6%,10%,.6), hsla(210,11%,18%,.45) 75%, hsla(210,11%,30%,.4));
|
||||
background: -webkit-linear-gradient(hsla(220,6%,10%,.6), hsla(210,11%,18%,.45) 75%, hsla(210,11%,30%,.4));
|
||||
background: -o-linear-gradient(hsla(220,6%,10%,.6), hsla(210,11%,18%,.45) 75%, hsla(210,11%,30%,.4));
|
||||
background: -ms-linear-gradient(hsla(220,6%,10%,.6), hsla(210,11%,18%,.45) 75%, hsla(210,11%,30%,.4));
|
||||
box-shadow: 0 1px 3px hsla(210,8%,5%,.25) inset,
|
||||
0 1px 3px hsla(210,8%,5%,.25) inset,
|
||||
0 1px 0 hsla(210,16%,76%,.15);
|
||||
|
@ -142,7 +193,11 @@ body {
|
|||
line-height: 22px;
|
||||
text-align: center;
|
||||
text-shadow: 0 -1px 0 hsla(210,8%,5%,.45);
|
||||
user-select: none;
|
||||
-moz-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-o-user-select: none;
|
||||
-ms-user-select: none;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
|
@ -151,10 +206,18 @@ body {
|
|||
padding: 0 4px;
|
||||
height: 24px;
|
||||
border-width: 0 13px 0 8px;
|
||||
border-image: url(images/breadcrumb-mac-start.png) 0 13 0 8 repeat;
|
||||
-moz-border-image: url(images/breadcrumb-mac-start.png) 0 13 0 8 repeat;
|
||||
-webkit-border-image: url(images/breadcrumb-mac-start.png) 0 13 0 8 repeat;
|
||||
-o-border-image: url(images/breadcrumb-mac-start.png) 0 13 0 8 repeat;
|
||||
-ms-border-image: url(images/breadcrumb-mac-start.png) 0 13 0 8 repeat;
|
||||
}
|
||||
.breadcrumbBarStart:hover:active {
|
||||
border-image: url(images/breadcrumb-mac-start-pressed.png) 0 13 0 8 repeat;
|
||||
-moz-border-image: url(images/breadcrumb-mac-start-pressed.png) 0 13 0 8 repeat;
|
||||
-webkit-border-image: url(images/breadcrumb-mac-start-pressed.png) 0 13 0 8 repeat;
|
||||
-o-border-image: url(images/breadcrumb-mac-start-pressed.png) 0 13 0 8 repeat;
|
||||
-ms-border-image: url(images/breadcrumb-mac-start-pressed.png) 0 13 0 8 repeat;
|
||||
}
|
||||
|
||||
.breadcrumbBarMiddle {
|
||||
|
@ -163,10 +226,18 @@ body {
|
|||
float: left;
|
||||
height: 24px;
|
||||
border-width: 0 13px;
|
||||
border-image: url(images/breadcrumb-mac-middle.png) 0 13 0 13 repeat;
|
||||
-moz-border-image: url(images/breadcrumb-mac-middle.png) 0 13 0 13 repeat;
|
||||
-webkit-border-image: url(images/breadcrumb-mac-middle.png) 0 13 0 13 repeat;
|
||||
-o-border-image: url(images/breadcrumb-mac-middle.png) 0 13 0 13 repeat;
|
||||
-moz-border-image: url(images/breadcrumb-mac-middle.png) 0 13 0 13 repeat;
|
||||
}
|
||||
.breadcrumbBarMiddle:hover:active {
|
||||
border-image: url(images/breadcrumb-mac-middle-pressed.png) 0 13 0 13 repeat;
|
||||
-moz-border-image: url(images/breadcrumb-mac-middle-pressed.png) 0 13 0 13 repeat;
|
||||
-webkit-border-image: url(images/breadcrumb-mac-middle-pressed.png) 0 13 0 13 repeat;
|
||||
-o-border-image: url(images/breadcrumb-mac-middle-pressed.png) 0 13 0 13 repeat;
|
||||
-ms-border-image: url(images/breadcrumb-mac-middle-pressed.png) 0 13 0 13 repeat;
|
||||
}
|
||||
|
||||
.breadcrumbBarEnd {
|
||||
|
@ -175,37 +246,70 @@ body {
|
|||
float: left;
|
||||
height: 24px;
|
||||
border-width: 0 8px 0 13px;
|
||||
border-image: url(images/breadcrumb-mac-end-selected.png) 0 8 0 13 repeat;
|
||||
-moz-border-image: url(images/breadcrumb-mac-end-selected.png) 0 8 0 13 repeat;
|
||||
-webkit-border-image: url(images/breadcrumb-mac-end-selected.png) 0 8 0 13 repeat;
|
||||
-o-border-image: url(images/breadcrumb-mac-end-selected.png) 0 8 0 13 repeat;
|
||||
-ms-border-image: url(images/breadcrumb-mac-end-selected.png) 0 8 0 13 repeat;
|
||||
color: hsl(208,100%,60%);
|
||||
}
|
||||
.breadcrumbBarEnd:hover:active {
|
||||
border-image: url(images/breadcrumb-mac-end-selected-pressed.png) 0 8 0 13 repeat;
|
||||
-moz-border-image: url(images/breadcrumb-mac-end-selected-pressed.png) 0 8 0 13 repeat;
|
||||
-webkit-border-image: url(images/breadcrumb-mac-end-selected-pressed.png) 0 8 0 13 repeat;
|
||||
-o-border-image: url(images/breadcrumb-mac-end-selected-pressed.png) 0 8 0 13 repeat;
|
||||
-ms-border-image: url(images/breadcrumb-mac-end-selected-pressed.png) 0 8 0 13 repeat;
|
||||
}
|
||||
|
||||
|
||||
.textInput {
|
||||
float: left;
|
||||
appearance: none;
|
||||
-moz-appearance: none;
|
||||
-webkit-appearance: none;
|
||||
-o-appearance: none;
|
||||
-ms-appearance: none;
|
||||
margin: 0 3px;
|
||||
background-color: transparent;
|
||||
height: 22px;
|
||||
border: 1px solid hsla(210,8%,5%,.6);
|
||||
border-radius: 6px;
|
||||
background-image: linear-gradient(hsla(210,16%,76%,.15), hsla(210,16%,76%,.35));
|
||||
background-image: -moz-linear-gradient(hsla(210,16%,76%,.15), hsla(210,16%,76%,.35));
|
||||
background-image: -webkit-linear-gradient(hsla(210,16%,76%,.15), hsla(210,16%,76%,.35));
|
||||
background-image: -o-linear-gradient(hsla(210,16%,76%,.15), hsla(210,16%,76%,.35));
|
||||
background-image: -ms-linear-gradient(hsla(210,16%,76%,.15), hsla(210,16%,76%,.35));
|
||||
background-repeat: no-repeat;
|
||||
background-position: 4px center, top left, top left;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-start: 10px;
|
||||
-moz-padding-start: 10px;
|
||||
-webkit-padding-start: 10px;
|
||||
-o-padding-start: 10px;
|
||||
-ms-padding-start: 10px;
|
||||
padding-end: 4px;
|
||||
-moz-padding-end: 4px;
|
||||
-webkit-padding-end: 4px;
|
||||
-o-padding-end: 4px;
|
||||
-ms-padding-end: 4px;
|
||||
box-shadow: 0 1px 1px hsla(210,8%,5%,.3) inset,
|
||||
0 0 0 1px hsla(210,16%,76%,.1) inset,
|
||||
0 1px 0 hsla(210,16%,76%,.15);
|
||||
color: hsl(210,30%,85%);
|
||||
font-weight: bolder;
|
||||
|
||||
}
|
||||
|
||||
.textInput:-moz-locale-dir(rtl) {
|
||||
background-position: calc(100% - 4px) center, top left, top left;
|
||||
}
|
||||
|
||||
#stage {
|
||||
float: left;
|
||||
}
|
||||
|
||||
#xstats {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
|
Двоичные данные
examples/pac/pac.fla
Двоичные данные
examples/pac/pac.fla
Двоичный файл не отображается.
Двоичные данные
examples/pac/pac.swf
Двоичные данные
examples/pac/pac.swf
Двоичный файл не отображается.
|
@ -0,0 +1,61 @@
|
|||
enableVerifier.value = true;
|
||||
enableOpt.value = true;
|
||||
enableInlineCaching.value = true;
|
||||
release = true;
|
||||
|
||||
var avm2Root = SHUMWAY_ROOT + "avm2/";
|
||||
var builtinPath = avm2Root + "generated/builtin/builtin.abc";
|
||||
var libraryPath = avm2Root + "generated/shell/shell.abc";
|
||||
var playerGlobalPath = SHUMWAY_ROOT + "flash/playerGlobal.min.abc";
|
||||
|
||||
var BinaryFileReader = (function binaryFileReader() {
|
||||
function constructor(url, responseType) {
|
||||
this.url = url;
|
||||
this.responseType = responseType || "arraybuffer";
|
||||
}
|
||||
|
||||
constructor.prototype = {
|
||||
readAll: function(progress, complete) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
var async = true;
|
||||
xhr.open("GET", this.url, async);
|
||||
xhr.responseType = this.responseType;
|
||||
if (progress) {
|
||||
xhr.onprogress = function(event) {
|
||||
progress(xhr.response, event.loaded, event.total);
|
||||
};
|
||||
}
|
||||
xhr.onreadystatechange = function(event) {
|
||||
if (xhr.readyState === 4) {
|
||||
if (xhr.status !== 200 && xhr.status !== 0) {
|
||||
complete(null, xhr.statusText);
|
||||
return;
|
||||
}
|
||||
complete(xhr.response);
|
||||
}
|
||||
}
|
||||
xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); // no-cache
|
||||
xhr.send(null);
|
||||
}
|
||||
};
|
||||
return constructor;
|
||||
})();
|
||||
|
||||
// avm2 must be global.
|
||||
var avm2;
|
||||
|
||||
function createAVM2(builtinPath, libraryPath, sysMode, appMode, next) {
|
||||
assert (builtinPath);
|
||||
new BinaryFileReader(builtinPath).readAll(null, function (buffer) {
|
||||
avm2 = new AVM2(sysMode, appMode);
|
||||
avm2.systemDomain.executeAbc(new AbcFile(new Uint8Array(buffer), "builtin.abc"));
|
||||
if (libraryPath) {
|
||||
new BinaryFileReader(libraryPath).readAll(null, function (buffer) {
|
||||
avm2.systemDomain.executeAbc(new AbcFile(new Uint8Array(buffer), libraryPath));
|
||||
next(avm2);
|
||||
});
|
||||
} else {
|
||||
next(avm2);
|
||||
}
|
||||
});
|
||||
}
|
|
@ -24,9 +24,10 @@
|
|||
color: Yellow;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="stage"></div>
|
||||
|
||||
<script>
|
||||
SHUMWAY_ROOT = "../../src/";
|
||||
</script>
|
||||
|
||||
<script src="../../lib/DataView.js/DataView.js"></script>
|
||||
<script src="../../lib/Kanvas/kanvas.js"></script>
|
||||
|
@ -50,9 +51,6 @@
|
|||
<script src="../../src/swf/shape.js"></script>
|
||||
<script src="../../src/swf/text.js"></script>
|
||||
|
||||
|
||||
<script src="../../src/swf/prototypes.js"></script>
|
||||
|
||||
<!-- Load AVM1 Dependencies -->
|
||||
<script src="../../src/avm1/classes.js"></script>
|
||||
<script src="../../src/avm1/globals.js"></script>
|
||||
|
@ -61,29 +59,108 @@
|
|||
<script src="../../src/swf/embed.js"></script>
|
||||
<script src="../../src/swf/renderer.js"></script>
|
||||
|
||||
<script src="../../src/flash/util.js"></script>
|
||||
<script src="../../src/flash/events/Event.js"></script>
|
||||
<script src="../../src/flash/events/ProgressEvent.js"></script>
|
||||
<script src="../../src/flash/events/EventDispatcher.js"></script>
|
||||
<script src="../../src/flash/display/DisplayObject.js"></script>
|
||||
<script src="../../src/flash/display/InteractiveObject.js"></script>
|
||||
<script src="../../src/flash/display/DisplayObjectContainer.js"></script>
|
||||
<script src="../../src/flash/display/Graphics.js"></script>
|
||||
<script src="../../src/flash/display/Sprite.js"></script>
|
||||
<script src="../../src/flash/display/Loader.js"></script>
|
||||
<script src="../../src/flash/display/LoaderInfo.js"></script>
|
||||
<script src="../../src/flash/display/MovieClip.js"></script>
|
||||
<script src="../../src/flash/display/Stage.js"></script>
|
||||
<script src="../../src/flash/display/StaticText.js"></script>
|
||||
<script src="../../src/flash/ui/Keyboard.js"></script>
|
||||
<script src="../../src/flash/ui/Mouse.js"></script>
|
||||
<!-- Load AVM2 Dependencies -->
|
||||
<script src="../../src/avm2/util.js"></script>
|
||||
<script src="../../src/avm2/options.js"></script>
|
||||
<script src="../../src/avm2/metrics.js"></script>
|
||||
|
||||
<script>
|
||||
Loader.LOADER_PATH = "../../src/flash/display/Loader.js";
|
||||
var Counter = new metrics.Counter(true);
|
||||
var Timer = metrics.Timer;
|
||||
var Option = options.Option;
|
||||
var OptionSet = options.OptionSet;
|
||||
var systemOptions = new OptionSet("System Options");
|
||||
var disassemble = systemOptions.register(new Option("d", "disassemble", "boolean", false, "disassemble"));
|
||||
var traceLevel = systemOptions.register(new Option("t", "traceLevel", "number", 0, "trace level"));
|
||||
|
||||
window.print = function(s) {
|
||||
console.log(s);
|
||||
};
|
||||
</script>
|
||||
|
||||
<script src="../../src/avm2/constants.js"></script>
|
||||
<script src="../../src/avm2/errors.js"></script>
|
||||
<script src="../../src/avm2/opcodes.js"></script>
|
||||
<script src="../../src/avm2/parser.js"></script>
|
||||
<script src="../../src/avm2/analyze.js"></script>
|
||||
<script src="../../src/avm2/compiler/lljs/src/estransform.js"></script>
|
||||
<script src="../../src/avm2/compiler/lljs/src/escodegen.js"></script>
|
||||
<script src="../../src/avm2/compiler/inferrer.js"></script>
|
||||
<script src="../../src/avm2/compiler/compiler.js"></script>
|
||||
<script src="../../src/avm2/domain.js"></script>
|
||||
<script src="../../src/avm2/runtime.js"></script>
|
||||
<script src="../../src/avm2/native.js"></script>
|
||||
<script src="../../src/avm2/disassembler.js"></script>
|
||||
<script src="../../src/avm2/interpreter.js"></script>
|
||||
<script src="../../src/avm2/vm.js"></script>
|
||||
|
||||
<script src="avm2utils.js"></script>
|
||||
|
||||
<!-- Load Flash Dependencies -->
|
||||
|
||||
<script src="../../src/flash/util.js"></script>
|
||||
<!-- Autogenerated flash references: base=../../src/flash/ -->
|
||||
<script src="../../src/flash/display/Bitmap.js"></script>
|
||||
<script src="../../src/flash/display/BitmapData.js"></script>
|
||||
<script src="../../src/flash/display/DisplayObject.js"></script>
|
||||
<script src="../../src/flash/display/DisplayObjectContainer.js"></script>
|
||||
<script src="../../src/flash/display/Graphics.js"></script>
|
||||
<script src="../../src/flash/display/InteractiveObject.js"></script>
|
||||
<script src="../../src/flash/display/Loader.js"></script>
|
||||
<script src="../../src/flash/display/LoaderInfo.js"></script>
|
||||
<script src="../../src/flash/display/MorphShape.js"></script>
|
||||
<script src="../../src/flash/display/MovieClip.js"></script>
|
||||
<script src="../../src/flash/display/Shape.js"></script>
|
||||
<script src="../../src/flash/display/SimpleButton.js"></script>
|
||||
<script src="../../src/flash/display/Sprite.js"></script>
|
||||
<script src="../../src/flash/display/Stage.js"></script>
|
||||
<script src="../../src/flash/events/Event.js"></script>
|
||||
<script src="../../src/flash/events/EventDispatcher.js"></script>
|
||||
<script src="../../src/flash/events/KeyboardEvent.js"></script>
|
||||
<script src="../../src/flash/events/MouseEvent.js"></script>
|
||||
<script src="../../src/flash/events/TextEvent.js"></script>
|
||||
<script src="../../src/flash/events/TimerEvent.js"></script>
|
||||
<script src="../../src/flash/external/ExternalInterface.js"></script>
|
||||
<script src="../../src/flash/geom/ColorTransform.js"></script>
|
||||
<script src="../../src/flash/geom/Matrix.js"></script>
|
||||
<script src="../../src/flash/geom/Point.js"></script>
|
||||
<script src="../../src/flash/geom/Rectangle.js"></script>
|
||||
<script src="../../src/flash/geom/Transform.js"></script>
|
||||
<script src="../../src/flash/media/Sound.js"></script>
|
||||
<script src="../../src/flash/media/SoundMixer.js"></script>
|
||||
<script src="../../src/flash/media/SoundTransform.js"></script>
|
||||
<script src="../../src/flash/media/Video.js"></script>
|
||||
<script src="../../src/flash/net/NetConnection.js"></script>
|
||||
<script src="../../src/flash/net/NetStream.js"></script>
|
||||
<script src="../../src/flash/net/Responder.js"></script>
|
||||
<script src="../../src/flash/net/URLRequest.js"></script>
|
||||
<script src="../../src/flash/system/Capabilities.js"></script>
|
||||
<script src="../../src/flash/system/FSCommand.js"></script>
|
||||
<script src="../../src/flash/text/Font.js"></script>
|
||||
<script src="../../src/flash/text/StaticText.js"></script>
|
||||
<script src="../../src/flash/text/TextField.js"></script>
|
||||
<script src="../../src/flash/ui/Keyboard.js"></script>
|
||||
<script src="../../src/flash/ui/Mouse.js"></script>
|
||||
<script src="../../src/flash/utils/Timer.js"></script>
|
||||
<!-- Autogenerated flash references end -->
|
||||
<script src="../../src/flash/stubs.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="stage"></div>
|
||||
|
||||
|
||||
<script>
|
||||
SWF.embed("../../examples/racing/race.swf", document.getElementById("stage"));
|
||||
var SWF_PATH = "race.swf";
|
||||
createAVM2(builtinPath, playerGlobalPath, EXECUTION_MODE.INTERPRET, EXECUTION_MODE.COMPILE, function (avm2) {
|
||||
function loaded() {}
|
||||
|
||||
new BinaryFileReader(SWF_PATH).readAll(null, function(buffer) {
|
||||
if (!buffer) {
|
||||
throw "Unable to open the file " + SWF_PATH + ": " + error;
|
||||
}
|
||||
SWF.embed(buffer, document.getElementById("stage"), { onComplete: loaded });
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<div id="footer">
|
||||
<sup>*</sup>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
build/*
|
||||
content/swf/*
|
||||
content/flash/*
|
||||
content/avm1/*
|
||||
|
|
|
@ -1,6 +1,63 @@
|
|||
# Just builds a ff extension
|
||||
|
||||
build:
|
||||
VERSION_BASELINE=c9d3aa7c886ce53648082
|
||||
VERSION=0.3.`git log --format=oneline $(VERSION_BASELINE)..|wc -l|tr -d ' '`
|
||||
|
||||
build: clean
|
||||
# Coping extension files
|
||||
echo "Creating extension verions: $(VERSION)"
|
||||
mkdir build
|
||||
cp -R ../../LICENSE components content bootstrap.js build/
|
||||
sed s/\(SHUMWAY_VERSION\)/$(VERSION)/ install.rdf > build/install.rdf
|
||||
sed s/\(SHUMWAY_VERSION\)/$(VERSION)/ update.rdf > build/update.rdf
|
||||
# Coping JavaScript content files
|
||||
mkdir build/content/swf
|
||||
cp ../../src/swf/*.js build/content/swf/
|
||||
mkdir build/content/flash
|
||||
cp ../../src/flash/*.js build/content/flash/
|
||||
cp ../../src/flash/playerGlobal.min.abc build/content/flash/
|
||||
mkdir build/content/flash/display
|
||||
cp ../../src/flash/display/*.js build/content/flash/display/
|
||||
mkdir build/content/flash/events
|
||||
cp ../../src/flash/events/*.js build/content/flash/events/
|
||||
mkdir build/content/flash/geom
|
||||
cp ../../src/flash/geom/*.js build/content/flash/geom/
|
||||
mkdir build/content/flash/media
|
||||
cp ../../src/flash/media/*.js build/content/flash/media/
|
||||
mkdir build/content/flash/net
|
||||
cp ../../src/flash/net/*.js build/content/flash/net/
|
||||
mkdir build/content/flash/system
|
||||
cp ../../src/flash/system/*.js build/content/flash/system/
|
||||
mkdir build/content/flash/text
|
||||
cp ../../src/flash/text/*.js build/content/flash/text/
|
||||
mkdir build/content/flash/ui
|
||||
cp ../../src/flash/ui/*.js build/content/flash/ui/
|
||||
mkdir build/content/flash/utils
|
||||
cp ../../src/flash/utils/*.js build/content/flash/utils/
|
||||
mkdir build/content/avm1
|
||||
cp ../../src/avm1/*.js build/content/avm1/
|
||||
mkdir build/content/avm2
|
||||
cp ../../src/avm2/*.js build/content/avm2/
|
||||
mkdir build/content/avm2/compiler
|
||||
cp ../../src/avm2/compiler/*.js build/content/avm2/compiler/
|
||||
mkdir -p build/content/avm2/compiler/lljs/src
|
||||
cp ../../src/avm2/compiler/lljs/src/*.js build/content/avm2/compiler/lljs/src/
|
||||
mkdir -p build/content/avm2/generated/builtin
|
||||
cp ../../src/avm2/generated/builtin/builtin.abc build/content/avm2/generated/builtin/
|
||||
mkdir build/content/lib
|
||||
mkdir build/content/lib/Kanvas
|
||||
cp ../../lib/Kanvas/* build/content/lib/Kanvas/
|
||||
mkdir build/content/lib/DataView.js
|
||||
cp ../../lib/DataView.js/* build/content/lib/DataView.js/
|
||||
# Removing hidden files
|
||||
-find build -name ".DS_Store" -exec rm {} \;
|
||||
# Packaging XPI file
|
||||
cd build; zip -r shumway.xpi *
|
||||
|
||||
clean: legacy-clean
|
||||
-rm -rf build
|
||||
|
||||
legacy-clean:
|
||||
# Cleaning old files
|
||||
-rm -rf content/swf
|
||||
-rm -rf content/flash
|
||||
|
@ -8,40 +65,7 @@ build:
|
|||
-rm -rf content/avm2
|
||||
-rm -rf content/glue
|
||||
-rm -rf content/lib
|
||||
-rm LICENSE
|
||||
-rm shumway.xpi
|
||||
# Coping JavaScript content files
|
||||
mkdir content/swf
|
||||
cp ../../src/swf/*.js content/swf/
|
||||
mkdir content/flash
|
||||
cp ../../src/flash/*.js content/flash/
|
||||
mkdir content/flash/display
|
||||
cp ../../src/flash/display/*.js content/flash/display/
|
||||
mkdir content/flash/events
|
||||
cp ../../src/flash/events/*.js content/flash/events/
|
||||
mkdir content/flash/geom
|
||||
cp ../../src/flash/geom/*.js content/flash/geom/
|
||||
mkdir content/flash/ui
|
||||
cp ../../src/flash/ui/*.js content/flash/ui/
|
||||
mkdir content/avm1
|
||||
cp ../../src/avm1/*.js content/avm1/
|
||||
mkdir content/avm2
|
||||
cp ../../src/avm2/*.js content/avm2/
|
||||
mkdir content/avm2/compiler
|
||||
cp ../../src/avm2/compiler/*.js content/avm2/compiler/
|
||||
mkdir content/avm2/compiler/lljs
|
||||
mkdir content/avm2/compiler/lljs/src
|
||||
cp ../../src/avm2/compiler/lljs/src/*.js content/avm2/compiler/lljs/src/
|
||||
# TODO src/avm2/generated/playerGlobal.swf and src/avm2/generated/builtin/builtin.abc
|
||||
mkdir content/glue
|
||||
mkdir content/glue/avm2
|
||||
cp ../../src/glue/avm2/*.js content/glue/avm2/
|
||||
mkdir content/lib
|
||||
mkdir content/lib/Kanvas
|
||||
cp ../../lib/Kanvas/* content/lib/Kanvas/
|
||||
mkdir content/lib/DataView.js
|
||||
cp ../../lib/DataView.js/* content/lib/DataView.js/
|
||||
cp ../../LICENSE .
|
||||
# Removing hidden files
|
||||
-find . -name ".DS_Store" | xargs rm
|
||||
# Packaging XPI file
|
||||
zip -r shumway.xpi install.rdf bootstrap.js content components LICENSE
|
||||
|
||||
PHONY: build clean legacy-clean
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
enableVerifier.value = true;
|
||||
enableOpt.value = true;
|
||||
enableInlineCaching.value = true;
|
||||
release = true;
|
||||
|
||||
var avm2Root = SHUMWAY_ROOT + "avm2/";
|
||||
var builtinPath = avm2Root + "generated/builtin/builtin.abc";
|
||||
var libraryPath = avm2Root + "generated/shell/shell.abc";
|
||||
var playerGlobalPath = SHUMWAY_ROOT + "flash/playerGlobal.min.abc";
|
||||
|
||||
var BinaryFileReader = (function binaryFileReader() {
|
||||
function constructor(url, responseType) {
|
||||
this.url = url;
|
||||
this.responseType = responseType || "arraybuffer";
|
||||
}
|
||||
|
||||
constructor.prototype = {
|
||||
readAll: function(progress, complete) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
var async = true;
|
||||
xhr.open("GET", this.url, async);
|
||||
xhr.responseType = this.responseType;
|
||||
if (progress) {
|
||||
xhr.onprogress = function(event) {
|
||||
progress(xhr.response, event.loaded, event.total);
|
||||
};
|
||||
}
|
||||
xhr.onreadystatechange = function(event) {
|
||||
if (xhr.readyState === 4) {
|
||||
if (xhr.status !== 200 && xhr.status !== 0) {
|
||||
complete(null, xhr.statusText);
|
||||
return;
|
||||
}
|
||||
complete(xhr.response);
|
||||
}
|
||||
}
|
||||
xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); // no-cache
|
||||
xhr.send(null);
|
||||
}
|
||||
};
|
||||
return constructor;
|
||||
})();
|
||||
|
||||
// avm2 must be global.
|
||||
var avm2;
|
||||
|
||||
function createAVM2(builtinPath, libraryPath, sysMode, appMode, next) {
|
||||
assert (builtinPath);
|
||||
new BinaryFileReader(builtinPath).readAll(null, function (buffer) {
|
||||
avm2 = new AVM2(sysMode, appMode);
|
||||
avm2.systemDomain.executeAbc(new AbcFile(new Uint8Array(buffer), "builtin.abc"));
|
||||
if (libraryPath) {
|
||||
new BinaryFileReader(libraryPath).readAll(null, function (buffer) {
|
||||
avm2.systemDomain.executeAbc(new AbcFile(new Uint8Array(buffer), libraryPath));
|
||||
next(avm2);
|
||||
});
|
||||
} else {
|
||||
next(avm2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -5,7 +5,11 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<title>Shumway viewer</title>
|
||||
|
||||
<script>
|
||||
SHUMWAY_ROOT = "resource://shumway/";
|
||||
</script>
|
||||
<!-- <base href="resource://shumway/web/viewer.html" /> -->
|
||||
|
||||
<script src="../lib/DataView.js/DataView.js"></script>
|
||||
<script src="../lib/Kanvas/kanvas.js"></script>
|
||||
|
||||
|
@ -28,9 +32,6 @@
|
|||
<script src="../swf/shape.js"></script>
|
||||
<script src="../swf/text.js"></script>
|
||||
|
||||
|
||||
<script src="../swf/prototypes.js"></script>
|
||||
|
||||
<!-- Load AVM1 Dependencies -->
|
||||
<script src="../avm1/classes.js"></script>
|
||||
<script src="../avm1/globals.js"></script>
|
||||
|
@ -39,22 +40,90 @@
|
|||
<script src="../swf/embed.js"></script>
|
||||
<script src="../swf/renderer.js"></script>
|
||||
|
||||
<!-- Load AVM2 Dependencies -->
|
||||
<script src="../avm2/util.js"></script>
|
||||
<script src="../avm2/options.js"></script>
|
||||
<script src="../avm2/metrics.js"></script>
|
||||
|
||||
<script>
|
||||
var Counter = new metrics.Counter(true);
|
||||
var Timer = metrics.Timer;
|
||||
var Option = options.Option;
|
||||
var OptionSet = options.OptionSet;
|
||||
var systemOptions = new OptionSet("System Options");
|
||||
var disassemble = systemOptions.register(new Option("d", "disassemble", "boolean", false, "disassemble"));
|
||||
var traceLevel = systemOptions.register(new Option("t", "traceLevel", "number", 0, "trace level"));
|
||||
|
||||
window.print = function(s) {
|
||||
console.log(s);
|
||||
};
|
||||
</script>
|
||||
|
||||
<script src="../avm2/constants.js"></script>
|
||||
<script src="../avm2/errors.js"></script>
|
||||
<script src="../avm2/opcodes.js"></script>
|
||||
<script src="../avm2/parser.js"></script>
|
||||
<script src="../avm2/analyze.js"></script>
|
||||
<script src="../avm2/compiler/lljs/src/estransform.js"></script>
|
||||
<script src="../avm2/compiler/lljs/src/escodegen.js"></script>
|
||||
<script src="../avm2/compiler/inferrer.js"></script>
|
||||
<script src="../avm2/compiler/compiler.js"></script>
|
||||
<script src="../avm2/domain.js"></script>
|
||||
<script src="../avm2/runtime.js"></script>
|
||||
<script src="../avm2/native.js"></script>
|
||||
<script src="../avm2/disassembler.js"></script>
|
||||
<script src="../avm2/interpreter.js"></script>
|
||||
<script src="../avm2/vm.js"></script>
|
||||
|
||||
<script src="avm2utils.js"></script>
|
||||
|
||||
<!-- Load Flash Dependencies -->
|
||||
<script src="../flash/util.js"></script>
|
||||
<script src="../flash/events/EventPhase.js"></script>
|
||||
<script src="../flash/events/Event.js"></script>
|
||||
<script src="../flash/events/ProgressEvent.js"></script>
|
||||
<script src="../flash/events/EventDispatcher.js"></script>
|
||||
<!-- Autogenerated flash references: base=../flash/ -->
|
||||
<script src="../flash/display/Bitmap.js"></script>
|
||||
<script src="../flash/display/BitmapData.js"></script>
|
||||
<script src="../flash/display/DisplayObject.js"></script>
|
||||
<script src="../flash/display/InteractiveObject.js"></script>
|
||||
<script src="../flash/display/DisplayObjectContainer.js"></script>
|
||||
<script src="../flash/display/Graphics.js"></script>
|
||||
<script src="../flash/display/Sprite.js"></script>
|
||||
<script src="../flash/display/InteractiveObject.js"></script>
|
||||
<script src="../flash/display/Loader.js"></script>
|
||||
<script src="../flash/display/LoaderInfo.js"></script>
|
||||
<script src="../flash/display/MorphShape.js"></script>
|
||||
<script src="../flash/display/MovieClip.js"></script>
|
||||
<script src="../flash/display/Shape.js"></script>
|
||||
<script src="../flash/display/SimpleButton.js"></script>
|
||||
<script src="../flash/display/Sprite.js"></script>
|
||||
<script src="../flash/display/Stage.js"></script>
|
||||
<script src="../flash/events/Event.js"></script>
|
||||
<script src="../flash/events/EventDispatcher.js"></script>
|
||||
<script src="../flash/events/KeyboardEvent.js"></script>
|
||||
<script src="../flash/events/MouseEvent.js"></script>
|
||||
<script src="../flash/events/TextEvent.js"></script>
|
||||
<script src="../flash/events/TimerEvent.js"></script>
|
||||
<script src="../flash/external/ExternalInterface.js"></script>
|
||||
<script src="../flash/geom/ColorTransform.js"></script>
|
||||
<script src="../flash/geom/Matrix.js"></script>
|
||||
<script src="../flash/geom/Point.js"></script>
|
||||
<script src="../flash/geom/Rectangle.js"></script>
|
||||
<script src="../flash/geom/Transform.js"></script>
|
||||
<script src="../flash/media/Sound.js"></script>
|
||||
<script src="../flash/media/SoundMixer.js"></script>
|
||||
<script src="../flash/media/SoundTransform.js"></script>
|
||||
<script src="../flash/media/Video.js"></script>
|
||||
<script src="../flash/net/NetConnection.js"></script>
|
||||
<script src="../flash/net/NetStream.js"></script>
|
||||
<script src="../flash/net/Responder.js"></script>
|
||||
<script src="../flash/net/URLRequest.js"></script>
|
||||
<script src="../flash/system/Capabilities.js"></script>
|
||||
<script src="../flash/system/FSCommand.js"></script>
|
||||
<script src="../flash/text/Font.js"></script>
|
||||
<script src="../flash/text/StaticText.js"></script>
|
||||
<script src="../flash/text/TextField.js"></script>
|
||||
<script src="../flash/ui/Keyboard.js"></script>
|
||||
<script src="../flash/ui/Mouse.js"></script>
|
||||
<script src="../flash/utils/Timer.js"></script>
|
||||
<!-- Autogenerated flash references end -->
|
||||
<script src="../flash/stubs.js"></script>
|
||||
|
||||
<script>
|
||||
// Extenstion communication object... as it used in pdf.js
|
||||
|
@ -151,29 +220,41 @@
|
|||
|
||||
function parseSwf(url, file) {
|
||||
console.log("Parsing " + url + "...");
|
||||
SWF.embed(file, document.getElementById("viewer"));
|
||||
function terminate() {}
|
||||
createAVM2(builtinPath, playerGlobalPath, EXECUTION_MODE.INTERPRET, EXECUTION_MODE.COMPILE, function (avm2) {
|
||||
SWF.embed(file, document.getElementById("viewer"), { onComplete: terminate });
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
<style>
|
||||
#viewer {
|
||||
position:fixed;left:0;top:0;bottom:0;right:0;
|
||||
background-color:magenta;
|
||||
body {
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#viewer {
|
||||
position:fixed;
|
||||
left:0;top:0;bottom:0;right:0;
|
||||
overflow: hidden;
|
||||
/* background-color:magenta; */
|
||||
}
|
||||
|
||||
|
||||
#fallback {
|
||||
display: none;
|
||||
}
|
||||
#fallback.enabled {
|
||||
display: block;
|
||||
position:fixed; right: 10px; bottom: 10px; width: 70px; height: 14px;
|
||||
position:fixed;
|
||||
right: 10px; bottom: 10px; width: 70px; height: 16px;
|
||||
color: white;
|
||||
background-color: #400040;
|
||||
background-color: #0b3268;
|
||||
font: bold 10px sans-serif;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0px 0px 3px 3px #888;
|
||||
box-shadow: 0px 0px 2px 2px #888;
|
||||
}
|
||||
#fallback .icon {
|
||||
display: inline-block;
|
||||
|
@ -184,6 +265,6 @@
|
|||
|
||||
<body onload="runViewer()">
|
||||
<div id="viewer"></div>
|
||||
<a id="fallback" href="#">shumway <span class="icon">×</span></a>
|
||||
<a id="fallback" href="#">Shumway <span class="icon">×</span></a>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -5,16 +5,16 @@
|
|||
|
||||
<Description about="urn:mozilla:install-manifest">
|
||||
<em:id>shumway@research.mozilla.org</em:id>
|
||||
<em:name>shumway</em:name>
|
||||
<em:version>0.2.1</em:version>
|
||||
<em:name>Shumway</em:name>
|
||||
<em:version>(SHUMWAY_VERSION)</em:version>
|
||||
<em:iconURL>chrome://shumway/skin/logo.png</em:iconURL>
|
||||
|
||||
<!-- Firefox -->
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>10.0</em:minVersion>
|
||||
<em:maxVersion>17.0a1</em:maxVersion>
|
||||
<em:minVersion>17.0</em:minVersion>
|
||||
<em:maxVersion>19.0a1</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
|
@ -22,16 +22,18 @@
|
|||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>{aa3c5121-dab2-40e2-81ca-7ea25febc110}</em:id>
|
||||
<em:minVersion>10.0</em:minVersion>
|
||||
<em:maxVersion>17.0a1</em:maxVersion>
|
||||
<em:minVersion>17.0</em:minVersion>
|
||||
<em:maxVersion>19.0a1</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
<em:bootstrap>true</em:bootstrap>
|
||||
<em:unpack>true</em:unpack>
|
||||
<em:creator>Mozilla Research</em:creator>
|
||||
<em:description>shumway loader</em:description>
|
||||
<em:description>Shumway is an HTML5 technology experiment that explores building a faithful and efficient renderer for the SWF file format without native code assistance.</em:description>
|
||||
<em:homepageURL>https://github.com/mozilla/shumway/</em:homepageURL>
|
||||
<em:type>2</em:type>
|
||||
<!-- Use the raw link for updates so we we can use SSL. -->
|
||||
<em:updateURL>https://github.com/mozilla/shumway/raw/gh-pages/extension/firefox/update.rdf</em:updateURL>
|
||||
</Description>
|
||||
</RDF>
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||
|
||||
<RDF:Description about="urn:mozilla:extension:shumway@research.mozilla.org">
|
||||
<em:updates>
|
||||
<RDF:Seq>
|
||||
<RDF:li>
|
||||
<RDF:Description>
|
||||
<em:version>(SHUMWAY_VERSION)</em:version>
|
||||
<em:targetApplication>
|
||||
<RDF:Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>17.0</em:minVersion>
|
||||
<em:maxVersion>19.0a1</em:maxVersion>
|
||||
<!-- Use the raw link for updates so we we can use SSL. -->
|
||||
<em:updateLink>https://github.com/mozilla/shumway/raw/gh-pages/extension/firefox/shumway.xpi</em:updateLink>
|
||||
</RDF:Description>
|
||||
</em:targetApplication>
|
||||
</RDF:Description>
|
||||
</RDF:li>
|
||||
</RDF:Seq>
|
||||
</em:updates>
|
||||
</RDF:Description>
|
||||
</RDF:RDF>
|
|
@ -23,10 +23,10 @@
|
|||
|
||||
var nativeCanvasProto = nativeCanvasClass.prototype;
|
||||
var native2dContextProto = native2dContextClass.prototype;
|
||||
var kanvas2dContextProto = Object.create(native2dContextProto);
|
||||
|
||||
var matrixClass;
|
||||
var pathClass;
|
||||
var wrap2dContext;
|
||||
|
||||
var shimCurrentTransform = !('currentTransform' in native2dContext);
|
||||
var shimPath = typeof Path === 'undefined';
|
||||
|
@ -44,7 +44,7 @@
|
|||
val = desc.get.call(this);
|
||||
defineProperty(this, prop, {
|
||||
value: val,
|
||||
writable: desc.writable,
|
||||
writable: true, // some browsers need that to be true
|
||||
configurable: desc.configurable,
|
||||
enumerable: desc.enumerable
|
||||
});
|
||||
|
@ -74,8 +74,7 @@
|
|||
var context;
|
||||
|
||||
if (contextId === 'kanvas-2d') {
|
||||
context = nativeGetContext.call(this, '2d');
|
||||
context.__proto__ = kanvas2dContextProto;
|
||||
context = wrap2dContext(nativeGetContext.call(this, '2d'));
|
||||
} else {
|
||||
context = nativeGetContext.apply(this, arguments);
|
||||
}
|
||||
|
@ -87,15 +86,17 @@
|
|||
};
|
||||
|
||||
try {
|
||||
var matrix = new SVGMatrix;
|
||||
matrixClass = matrix.constructor;
|
||||
} catch (err) {
|
||||
if (typeof SVGMatrix !== 'undefined')
|
||||
matrixClass = (new SVGMatrix).constructor;
|
||||
} catch (err) { }
|
||||
|
||||
if (!matrixClass) {
|
||||
var svgNamespace = 'http://www.w3.org/2000/svg';
|
||||
var svgElement = document.createElementNS(svgNamespace, 'svg');
|
||||
|
||||
matrixClass = function SVGMatrix() {
|
||||
return svgElement.createSVGMatrix();
|
||||
}
|
||||
};
|
||||
matrixClass.prototype = SVGMatrix.prototype;
|
||||
}
|
||||
|
||||
|
@ -105,8 +106,11 @@
|
|||
return new Path(d);
|
||||
|
||||
var displayList = [];
|
||||
var hitCanvas = nativeCanvas.cloneNode();
|
||||
|
||||
var hitCanvas = document.createElement('canvas');
|
||||
hitCanvas.width = hitCanvas.height = 1;
|
||||
var hitContext = hitCanvas.getContext('2d');
|
||||
|
||||
var pathState = [Number.MAX_VALUE, 0, Number.MAX_VALUE, 0];
|
||||
|
||||
defineProperties(this, {
|
||||
|
@ -225,7 +229,7 @@
|
|||
|
||||
defineLazyProperty(pathProto, '__draw__', {
|
||||
get: function () {
|
||||
return Function('c', this.__displayList__.join(';'));
|
||||
return new Function('c', this.__displayList__.join(';'));
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -240,19 +244,30 @@
|
|||
|
||||
pathClass.prototype = pathProto;
|
||||
|
||||
['fill', 'stroke', 'clip'].forEach(function (methodName) {
|
||||
var nativeMethod = kanvas2dContextProto[methodName];
|
||||
|
||||
kanvas2dContextProto[methodName] = function (path) {
|
||||
wrap2dContext = (function () {
|
||||
function wrapNativeMethod(nativeMethod, pathClass) {
|
||||
return function wrappedMethod(path) {
|
||||
if (path instanceof pathClass) {
|
||||
this.beginPath();
|
||||
path.__draw__(this);
|
||||
}
|
||||
nativeMethod.call(this);
|
||||
};
|
||||
});
|
||||
}
|
||||
var wrappedFillMethod = wrapNativeMethod(native2dContextProto.fill, pathClass);
|
||||
var wrappedStrokeMethod = wrapNativeMethod(native2dContextProto.stroke, pathClass);
|
||||
var wrappedClipMethod = wrapNativeMethod(native2dContextProto.clip, pathClass);
|
||||
|
||||
return function wrap2dContext(ctx) {
|
||||
ctx.fill = wrappedFillMethod;
|
||||
ctx.stroke = wrappedStrokeMethod;
|
||||
ctx.clip = wrappedClipMethod;
|
||||
return ctx;
|
||||
};
|
||||
})();
|
||||
} else {
|
||||
pathClass = Path;
|
||||
wrap2dContext = function(ctx) { return ctx; };
|
||||
}
|
||||
|
||||
Kanvas.SVGMatrix = matrixClass;
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Subproject commit b00277ea4a733145e01cb68c159d689f703ab2aa
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -32,23 +32,29 @@ AS2Globals.prototype = {
|
|||
nativeTarget.duplicateMovieClip(newname, depth);
|
||||
},
|
||||
fscommand: function (command, parameters) {
|
||||
flash.system.fscommand.apply(null, arguments);
|
||||
var fscommand = avm2.applicationDomain.getProperty(
|
||||
Multiname.fromSimpleName('flash.system.fscommand'), true, true);
|
||||
fscommand.apply(null, arguments);
|
||||
},
|
||||
getProperty: function(target, index) {
|
||||
var nativeTarget = AS2Context.instance.resolveTarget(target);
|
||||
return nativeTarget[PropertiesIndexMap[index]];
|
||||
},
|
||||
getTimer: function() {
|
||||
return flash.utils.getTimer();
|
||||
var getTimer = avm2.applicationDomain.getProperty(
|
||||
Multiname.fromSimpleName('flash.utils.getTimer'), true, true);
|
||||
return getTimer();
|
||||
},
|
||||
getURL: function(url, target, method) {
|
||||
var request = new AS2URLRequest(url);
|
||||
var request = new flash.net.URLRequest(url);
|
||||
if (method)
|
||||
request.method = method;
|
||||
flash.net.navigateToURL(request, target);
|
||||
var navigateToURL = avm2.applicationDomain.getProperty(
|
||||
Multiname.fromSimpleName('flash.net.navigateToURL'), true, true);
|
||||
navigateToURL(request, target);
|
||||
},
|
||||
getVersion: function() {
|
||||
return flash.system.Capalilities.version;
|
||||
return flash.system.Capabilities.version;
|
||||
},
|
||||
gotoAndPlay: function() {
|
||||
var nativeTarget = AS2Context.instance.resolveTarget();
|
||||
|
@ -83,11 +89,19 @@ AS2Globals.prototype = {
|
|||
},
|
||||
loadMovie: function(url, target, method) {
|
||||
var nativeTarget = AS2Context.instance.resolveTarget(target);
|
||||
// some swfs are using loadMovie to call fscommmand
|
||||
if (/^fscommand:/i.test(url))
|
||||
return this.fscommand(url.substring('fscommand:'.length), target);
|
||||
|
||||
// flash.display.Loader, flash.net.URLLoader
|
||||
throw 'Not implemented: loadMovie';
|
||||
},
|
||||
loadMovieNum: function(url, level, method) {
|
||||
var nativeTarget = AS2Context.instance.resolveLevel(level);
|
||||
// some swfs are using loadMovieNum to call fscommmand
|
||||
if (/^fscommand:/i.test(url))
|
||||
return this.fscommand(url.substring('fscommand:'.length));
|
||||
|
||||
// flash.display.Loader, flash.net.URLLoader
|
||||
throw 'Not implemented: loadMovieNum';
|
||||
},
|
||||
|
@ -179,7 +193,8 @@ AS2Globals.prototype = {
|
|||
nativeTarget.stop();
|
||||
},
|
||||
stopAllSounds: function() {
|
||||
flash.media.SoundMixer.stopAll();
|
||||
var soundMixerClass = avm2.systemDomain.getClass("flash.media.SoundMixer");
|
||||
soundMixerClass.native.static.stopAll();
|
||||
},
|
||||
stopDrag: function(target) {
|
||||
var nativeTarget = AS2Context.instance.resolveTarget(target);
|
||||
|
@ -190,15 +205,16 @@ AS2Globals.prototype = {
|
|||
},
|
||||
targetPath: function(target) {
|
||||
var nativeTarget = AS2Context.instance.resolveTarget(target);
|
||||
// nativeTarget.getPath() ?
|
||||
throw 'Not implemented: targetPath';
|
||||
return nativeTarget._target;
|
||||
},
|
||||
toggleHighQuality: function() {
|
||||
// flash.display.Stage.quality
|
||||
throw 'Not implemented: toggleHighQuality';
|
||||
},
|
||||
trace: function(expression) {
|
||||
console.log(expression);
|
||||
var trace = avm2.applicationDomain.getProperty(
|
||||
Multiname.fromSimpleName('trace'), true, true);
|
||||
trace(expression);
|
||||
},
|
||||
unloadMovie: function(target) {
|
||||
var nativeTarget = AS2Context.instance.resolveTarget(target);
|
||||
|
@ -234,6 +250,7 @@ AS2Globals.prototype = {
|
|||
AsBroadcaster: AS2Broadcaster,
|
||||
Stage: AS2Stage,
|
||||
Button: AS2Button,
|
||||
TextField: AS2TextField,
|
||||
Rectangle: AS2Rectangle,
|
||||
Key: AS2Key,
|
||||
Mouse: AS2Mouse
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- mode: javascript; tab-width: 4; insert-tabs-mode: nil; indent-tabs-mode: nil -*- */
|
||||
/* -*- mode: javascript; tab-width: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
var isAVM1TraceEnabled = false;
|
||||
|
||||
|
@ -17,9 +17,17 @@ function AS2Context(swfVersion) {
|
|||
this.globals = new AS2Globals(this);
|
||||
var windowScope = new AS2ScopeListItem(window, null);
|
||||
this.initialScope = new AS2ScopeListItem(this.globals, windowScope);
|
||||
this.assets = {};
|
||||
}
|
||||
AS2Context.instance = null;
|
||||
AS2Context.prototype = {
|
||||
addAssets: function(assets) {
|
||||
for (var i = 0; i < assets.length; i++) {
|
||||
if (assets[i].className) {
|
||||
this.assets[assets[i].className] = assets[i];
|
||||
}
|
||||
}
|
||||
},
|
||||
resolveTarget: function(target) {
|
||||
if (!target)
|
||||
target = this.defaultTarget;
|
||||
|
@ -35,7 +43,128 @@ AS2Context.prototype = {
|
|||
}
|
||||
};
|
||||
|
||||
function executeActions(actionsData, context, scope) {
|
||||
function as2GetType(v) {
|
||||
if (v === null)
|
||||
return 'null';
|
||||
var type = typeof v;
|
||||
if (type === 'function')
|
||||
return 'object';
|
||||
if (type === 'object' && v instanceof AS2MovieClip)
|
||||
return 'movieclip';
|
||||
return type;
|
||||
}
|
||||
|
||||
function as2ToPrimitive(value) {
|
||||
return as2GetType(value) !== 'object' ? value : value.valueOf();
|
||||
}
|
||||
|
||||
function as2ToAddPrimitive(value) {
|
||||
if (as2GetType(value) !== 'object')
|
||||
return value;
|
||||
if (value instanceof Date && AS2Context.instance.swfVersion >= 6) {
|
||||
return value.toString();
|
||||
} else {
|
||||
return value.valueOf();
|
||||
}
|
||||
}
|
||||
|
||||
function as2ToBoolean(value) {
|
||||
switch (as2GetType(value)) {
|
||||
case 'undefined':
|
||||
case 'null':
|
||||
default:
|
||||
return false;
|
||||
case 'boolean':
|
||||
return value;
|
||||
case 'number':
|
||||
return value != 0 && !isNaN(value);
|
||||
case 'string':
|
||||
return value.length !== 0;
|
||||
case 'object':
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function as2ToNumber(value) {
|
||||
value = as2ToPrimitive(value);
|
||||
switch (as2GetType(value)) {
|
||||
case 'undefined':
|
||||
case 'null':
|
||||
return AS2Context.instance.swfVersion >= 7 ? NaN : 0;
|
||||
default:
|
||||
return AS2Context.instance.swfVersion >= 5 ? NaN : 0;
|
||||
case 'null':
|
||||
return NaN;
|
||||
case 'boolean':
|
||||
return value ? 1 : +0;
|
||||
case 'number':
|
||||
return value;
|
||||
case 'string':
|
||||
if (value === '' && AS2Context.instance.swfVersion < 5)
|
||||
return 0;
|
||||
return +value;
|
||||
}
|
||||
}
|
||||
|
||||
function as2ToInteger(value) {
|
||||
var result = as2ToNumber(value);
|
||||
if (isNaN(result))
|
||||
return 0;
|
||||
if (!isFinite(result) || result == 0)
|
||||
return result;
|
||||
return (result < 0 ? -1 : 1) * Math.floor(Math.abs(result));
|
||||
}
|
||||
|
||||
function as2ToInt32(value) {
|
||||
var result = as2ToNumber(value);
|
||||
return (isNaN(result) || !isFinite(result) || result == 0) ? 0 :
|
||||
(result | 0);
|
||||
}
|
||||
|
||||
function as2ToString(value) {
|
||||
switch (as2GetType(value)) {
|
||||
case 'undefined':
|
||||
return AS2Context.instance.swfVersion >= 7 ? 'undefined' : '';
|
||||
case 'null':
|
||||
return 'null';
|
||||
case 'boolean':
|
||||
return value ? 'true' : 'false';
|
||||
case 'number':
|
||||
return value.toString();
|
||||
case 'string':
|
||||
return value;
|
||||
case 'undefined':
|
||||
return 'undefined';
|
||||
case 'movieclip':
|
||||
return value.$targetPath;
|
||||
case 'object':
|
||||
var result = value.toString !== Function.prototype.toString ?
|
||||
value.toString() : value;
|
||||
if (typeof result === 'string')
|
||||
return result;
|
||||
return typeof value === 'function' ? '[type Function]'
|
||||
: '[type Object]';
|
||||
}
|
||||
}
|
||||
|
||||
function as2Compare(x, y) {
|
||||
var x2 = as2ToPrimitive(x);
|
||||
var y2 = as2ToPrimitive(y);
|
||||
if (typeof x2 === 'string' && typeof y2 === 'string') {
|
||||
return x2 < y2;
|
||||
} else {
|
||||
return as2ToNumber(x2) < as2ToNumber(y2);
|
||||
}
|
||||
}
|
||||
|
||||
function as2InstanceOf(obj, constructor) {
|
||||
if (obj instanceof constructor)
|
||||
return true;
|
||||
// TODO interface check
|
||||
return false;
|
||||
}
|
||||
|
||||
function executeActions(actionsData, context, scope, assets) {
|
||||
var actionTracer = ActionTracerFactory.get();
|
||||
|
||||
var scopeContainer = context.initialScope.create(scope);
|
||||
|
@ -43,6 +172,9 @@ function executeActions(actionsData, context, scope) {
|
|||
try {
|
||||
AS2Context.instance = context;
|
||||
context.defaultTarget = scope;
|
||||
context.globals['this'] = scope;
|
||||
if (assets)
|
||||
context.addAssets(assets);
|
||||
actionTracer.message('ActionScript Execution Starts');
|
||||
actionTracer.indent();
|
||||
interpretActions(actionsData, scopeContainer, null, []);
|
||||
|
@ -53,6 +185,26 @@ function executeActions(actionsData, context, scope) {
|
|||
}
|
||||
}
|
||||
|
||||
function lookupAS2Children(targetPath, defaultTarget, root) {
|
||||
var path = targetPath.split('/');
|
||||
if (path[path.length - 1] === '') {
|
||||
path.pop();
|
||||
}
|
||||
var obj = defaultTarget;
|
||||
if (path[0] === '') {
|
||||
defaultTarget = root;
|
||||
path.shift();
|
||||
}
|
||||
while (path.length > 0) {
|
||||
obj = obj.$lookupChild(path[0]);
|
||||
if (!obj) {
|
||||
throw path[0] + ' is undefined in ' + targetPath;
|
||||
}
|
||||
path.shift();
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
function interpretActions(actionsData, scopeContainer,
|
||||
constantPool, registers) {
|
||||
var currentContext = AS2Context.instance;
|
||||
|
@ -61,7 +213,7 @@ function interpretActions(actionsData, scopeContainer,
|
|||
if (!targetPath)
|
||||
defaultTarget = _global._root;
|
||||
else
|
||||
defaultTarget = defaultTarget.$lookupChild(targetPath);
|
||||
defaultTarget = lookupAS2Children(targetPath, defaultTarget, _global._root);
|
||||
currentContext.defaultTarget = defaultTarget;
|
||||
}
|
||||
|
||||
|
@ -133,21 +285,12 @@ function interpretActions(actionsData, scopeContainer,
|
|||
}
|
||||
return false;
|
||||
}
|
||||
function instanceOf(obj, constructor) {
|
||||
if (obj instanceof constructor)
|
||||
return true;
|
||||
// TODO interface check
|
||||
return false;
|
||||
}
|
||||
function isMovieClip(obj) {
|
||||
return instanceOf(obj, _global.MovieClip);
|
||||
}
|
||||
function resolveVariableName(variableName) {
|
||||
var obj, name;
|
||||
if (variableName.indexOf(':') >= 0) {
|
||||
// "/A/B:FOO references the FOO variable in the movie clip with a target path of /A/B."
|
||||
var parts = variableName.split(':');
|
||||
var obj = defaultTarget.$lookupChild(parts[0]);
|
||||
var obj = lookupAS2Children(parts[0], defaultTarget, _global._root);
|
||||
name = parts[1];
|
||||
} else if (variableName.indexOf('.') >= 0) {
|
||||
// new object reference
|
||||
|
@ -156,10 +299,11 @@ function interpretActions(actionsData, scopeContainer,
|
|||
var obj = _global;
|
||||
for (var i = 0; i < objPath.length; i++) {
|
||||
obj = obj[objPath[i]];
|
||||
if (!obj)
|
||||
if (!obj) {
|
||||
throw objPath.slice(0, i + 1) + ' is undefined';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!obj)
|
||||
return; // local variable
|
||||
|
@ -176,6 +320,10 @@ function interpretActions(actionsData, scopeContainer,
|
|||
if (target)
|
||||
return target.obj[target.name];
|
||||
|
||||
var mc = defaultTarget.$lookupChild(variableName);
|
||||
if (mc)
|
||||
return mc;
|
||||
|
||||
for (var p = scopeContainer; p; p = p.next) {
|
||||
if (variableName in p.scope) {
|
||||
return p.scope[variableName];
|
||||
|
@ -194,8 +342,8 @@ function interpretActions(actionsData, scopeContainer,
|
|||
target.obj[target.name] = value;
|
||||
return;
|
||||
}
|
||||
|
||||
scope[variableName] = value;
|
||||
var _this = scope.this || getVariable('this');
|
||||
_this[variableName] = value;
|
||||
}
|
||||
function getFunction(functionName) {
|
||||
var fn = getVariable(functionName);
|
||||
|
@ -238,18 +386,29 @@ function interpretActions(actionsData, scopeContainer,
|
|||
var scope = scopeContainer.scope;
|
||||
var isSwfVersion5 = currentContext.swfVersion >= 5;
|
||||
var actionTracer = ActionTracerFactory.get();
|
||||
var nextPosition;
|
||||
|
||||
function skipActions(count) {
|
||||
while (count > 0 && stream.position < stream.end) {
|
||||
var actionCode = stream.readUI8();
|
||||
var length = actionCode >= 0x80 ? stream.readUI16() : 0;
|
||||
stream.position += length;
|
||||
count--;
|
||||
}
|
||||
nextPosition = stream.position;
|
||||
}
|
||||
|
||||
while (stream.position < stream.end) {
|
||||
var actionCode = stream.readUI8();
|
||||
var length = actionCode >= 0x80 ? stream.readUI16() : 0;
|
||||
var nextPosition = stream.position + length;
|
||||
nextPosition = stream.position + length;
|
||||
|
||||
actionTracer.print(stream.position, actionCode, stack);
|
||||
switch (actionCode) {
|
||||
// SWF 3 actions
|
||||
case 0x81: // ActionGotoFrame
|
||||
var frame = stream.readUI16();
|
||||
_global.gotoAndPlay(frame);
|
||||
_global.gotoAndPlay(frame + 1);
|
||||
break;
|
||||
case 0x83: // ActionGetURL
|
||||
var urlString = stream.readString();
|
||||
|
@ -278,7 +437,7 @@ function interpretActions(actionsData, scopeContainer,
|
|||
var frame = stream.readUI16();
|
||||
var skipCount = stream.readUI8();
|
||||
if (!_global.ifFrameLoaded(frame))
|
||||
nextPosition += skipCount; // actions or bytes ?
|
||||
skipActions(skipCount);
|
||||
break;
|
||||
case 0x8B: // ActionSetTarget
|
||||
var targetName = stream.readString();
|
||||
|
@ -334,86 +493,85 @@ function interpretActions(actionsData, scopeContainer,
|
|||
stack.pop();
|
||||
break;
|
||||
case 0x0A: // ActionAdd
|
||||
var a = +stack.pop();
|
||||
var b = +stack.pop();
|
||||
var a = as2ToNumber(stack.pop());
|
||||
var b = as2ToNumber(stack.pop());
|
||||
stack.push(a + b);
|
||||
break;
|
||||
case 0x0B: // ActionSubtract
|
||||
var a = +stack.pop();
|
||||
var b = +stack.pop();
|
||||
var a = as2ToNumber(stack.pop());
|
||||
var b = as2ToNumber(stack.pop());
|
||||
stack.push(b - a);
|
||||
break;
|
||||
case 0x0C: // ActionMultiply
|
||||
var a = +stack.pop();
|
||||
var b = +stack.pop();
|
||||
var a = as2ToNumber(stack.pop());
|
||||
var b = as2ToNumber(stack.pop());
|
||||
stack.push(a * b);
|
||||
break;
|
||||
case 0x0D: // ActionDivide
|
||||
var a = +stack.pop();
|
||||
var b = +stack.pop();
|
||||
var a = as2ToNumber(stack.pop());
|
||||
var b = as2ToNumber(stack.pop());
|
||||
var c = b / a;
|
||||
stack.push(isSwfVersion5 ? c : isFinite(c) ? c : '#ERROR#');
|
||||
break;
|
||||
case 0x0E: // ActionEquals
|
||||
var a = +stack.pop();
|
||||
var b = +stack.pop();
|
||||
var a = as2ToNumber(stack.pop());
|
||||
var b = as2ToNumber(stack.pop());
|
||||
var f = a == b;
|
||||
stack.push(isSwfVersion5 ? f : f ? 1 : 0);
|
||||
break;
|
||||
case 0x0F: // ActionLess
|
||||
var a = +stack.pop();
|
||||
var b = +stack.pop();
|
||||
var a = as2ToNumber(stack.pop());
|
||||
var b = as2ToNumber(stack.pop());
|
||||
var f = b < a;
|
||||
stack.push(isSwfVersion5 ? f : f ? 1 : 0);
|
||||
break;
|
||||
case 0x10: // ActionAnd
|
||||
var a = stack.pop();
|
||||
var b = stack.pop();
|
||||
var a = as2ToBoolean(stack.pop());
|
||||
var b = as2ToBoolean(stack.pop());
|
||||
var f = a && b;
|
||||
stack.push(isSwfVersion5 ? f : f ? 1 : 0);
|
||||
break;
|
||||
case 0x11: // ActionOr
|
||||
var a = stack.pop();
|
||||
var b = stack.pop();
|
||||
var a = as2ToBoolean(stack.pop());
|
||||
var b = as2ToBoolean(stack.pop());
|
||||
var f = a || b;
|
||||
stack.push(isSwfVersion5 ? f : f ? 1 : 0);
|
||||
break;
|
||||
case 0x12: // ActionNot
|
||||
var f = !stack.pop();
|
||||
var f = !as2ToBoolean(stack.pop());
|
||||
stack.push(isSwfVersion5 ? f : f ? 1 : 0);
|
||||
break;
|
||||
case 0x13: // ActionStringEquals
|
||||
var sa = '' + stack.pop();
|
||||
var sb = '' + stack.pop();
|
||||
var sa = as2ToString(stack.pop());
|
||||
var sb = as2ToString(stack.pop());
|
||||
var f = sa == sb;
|
||||
stack.push(isSwfVersion5 ? f : f ? 1 : 0);
|
||||
break;
|
||||
case 0x14: // ActionStringLength
|
||||
case 0x31: // ActionMBStringLength
|
||||
stack.push(_global.length(stack.pop()));
|
||||
var sa = '' + stack.pop();
|
||||
stack.push(sa.length);
|
||||
var sa = as2ToString(stack.pop());
|
||||
stack.push(_global.length(sa));
|
||||
break;
|
||||
case 0x21: // ActionStringAdd
|
||||
var sa = '' + stack.pop();
|
||||
var sb = '' + stack.pop();
|
||||
var sa = as2ToString(stack.pop());
|
||||
var sb = as2ToString(stack.pop());
|
||||
stack.push(sb + sa);
|
||||
break;
|
||||
case 0x15: // ActionStringExtract
|
||||
var count = stack.pop();
|
||||
var index = stack.pop();
|
||||
var value = stack.pop();
|
||||
var value = as2ToString(stack.pop());
|
||||
stack.push(_global.substring(value, index, count));
|
||||
break;
|
||||
case 0x35: // ActionMBStringExtract
|
||||
var count = stack.pop();
|
||||
var index = stack.pop();
|
||||
var value = stack.pop();
|
||||
var value = as2ToString(stack.pop());
|
||||
stack.push(_global.mbsubstring(value, index, count));
|
||||
break;
|
||||
case 0x29: // ActionStringLess
|
||||
var sa = '' + stack.pop();
|
||||
var sb = '' + stack.pop();
|
||||
var sa = as2ToString(stack.pop());
|
||||
var sb = as2ToString(stack.pop());
|
||||
var f = sb < sa;
|
||||
stack.push(isSwfVersion5 ? f : f ? 1 : 0);
|
||||
break;
|
||||
|
@ -529,9 +687,7 @@ function interpretActions(actionsData, scopeContainer,
|
|||
var skipCount = stream.readUI8();
|
||||
var frame = stack.pop();
|
||||
if (!_global.ifFrameLoaded(frame))
|
||||
nextPosition += skipCount; // actions or bytes ?
|
||||
debugger;
|
||||
//_global.waitForFrame(label, skipCount);
|
||||
skipActions(skipCount);
|
||||
break;
|
||||
case 0x26: // ActionTrace
|
||||
var value = stack.pop();
|
||||
|
@ -654,15 +810,23 @@ function interpretActions(actionsData, scopeContainer,
|
|||
var args = [];
|
||||
for (var i = 0; i < numArgs; i++)
|
||||
args.push(stack.pop());
|
||||
var result = {};
|
||||
var method;
|
||||
if (methodName) {
|
||||
if (!(methodName in obj))
|
||||
throw 'Method ' + methodName + ' is not defined.';
|
||||
obj[methodName].apply(result, args);
|
||||
} else
|
||||
obj.apply(result, args);
|
||||
method = obj[methodName];
|
||||
} else {
|
||||
method = obj;
|
||||
}
|
||||
// XXX: this is non-semantics-preserving, but it's
|
||||
// necessary to make constructors for runtime objects
|
||||
// work.
|
||||
var result = new (method.bind.apply(method, [null].concat(args)))();
|
||||
if (!result) {
|
||||
result = {};
|
||||
result.constructor = method;
|
||||
method.apply(result, args);
|
||||
}
|
||||
stack.push(result);
|
||||
break;
|
||||
case 0x40: // ActionNewObject
|
||||
|
@ -689,7 +853,7 @@ function interpretActions(actionsData, scopeContainer,
|
|||
break;
|
||||
case 0x45: // ActionTargetPath
|
||||
var obj = stack.pop();
|
||||
stack.push(isMovieClip(obj) ? obj.getTargetPath() : void(0));
|
||||
stack.push(as2GetType(obj) === 'movieclip' ? obj._target : void(0));
|
||||
break;
|
||||
case 0x94: // ActionWith
|
||||
var codeSize = stream.readUI16();
|
||||
|
@ -698,68 +862,73 @@ function interpretActions(actionsData, scopeContainer,
|
|||
processWith(obj, stream.readBytes(codeSize));
|
||||
break;
|
||||
case 0x4A: // ActionToNumber
|
||||
stack.push(+stack.pop());
|
||||
stack.push(as2ToNumber(stack.pop()));
|
||||
break;
|
||||
case 0x4B: // ActionToString
|
||||
stack.push("" + stack.pop());
|
||||
stack.push(as2ToString(stack.pop()));
|
||||
break;
|
||||
case 0x44: // ActionTypeOf
|
||||
var obj = stack.pop();
|
||||
var result = isMovieClip(obj) ? 'movieclip' : typeof obj;
|
||||
var result = as2GetType(obj);
|
||||
stack.push(result);
|
||||
break;
|
||||
case 0x47: // ActionAdd2
|
||||
var arg1 = stack.pop();
|
||||
var arg2 = stack.pop();
|
||||
stack.push(arg2 + arg1);
|
||||
var sb = as2ToAddPrimitive(arg1);
|
||||
var sa = as2ToAddPrimitive(arg2);
|
||||
if (typeof sa === 'string' || typeof sb === 'string')
|
||||
stack.push(as2ToString(sa) + as2ToString(sb));
|
||||
else
|
||||
stack.push(as2ToNumber(sa) + as2ToNumber(sb));
|
||||
break;
|
||||
case 0x48: // ActionLess2
|
||||
var arg1 = stack.pop();
|
||||
var arg2 = stack.pop();
|
||||
stack.push(arg2 < arg1);
|
||||
stack.push(as2Compare(arg2, arg1));
|
||||
break;
|
||||
case 0x3F: // ActionModulo
|
||||
var arg1 = stack.pop();
|
||||
var arg2 = stack.pop();
|
||||
var arg1 = as2ToNumber(stack.pop());
|
||||
var arg2 = as2ToNumber(stack.pop());
|
||||
stack.push(arg2 % arg1);
|
||||
break;
|
||||
case 0x60: // ActionBitAnd
|
||||
var arg1 = stack.pop();
|
||||
var arg2 = stack.pop();
|
||||
var arg1 = as2ToInt32(stack.pop());
|
||||
var arg2 = as2ToInt32(stack.pop());
|
||||
stack.push(arg2 & arg1);
|
||||
break;
|
||||
case 0x63: // ActionBitLShift
|
||||
var arg1 = stack.pop();
|
||||
var arg2 = stack.pop();
|
||||
var arg1 = as2ToInt32(stack.pop());
|
||||
var arg2 = as2ToInt32(stack.pop());
|
||||
stack.push(arg2 << arg1);
|
||||
break;
|
||||
case 0x61: // ActionBitOr
|
||||
var arg1 = stack.pop();
|
||||
var arg2 = stack.pop();
|
||||
var arg1 = as2ToInt32(stack.pop());
|
||||
var arg2 = as2ToInt32(stack.pop());
|
||||
stack.push(arg2 | arg1);
|
||||
break;
|
||||
case 0x64: // ActionBitRShift
|
||||
var arg1 = stack.pop();
|
||||
var arg2 = stack.pop();
|
||||
var arg1 = as2ToInt32(stack.pop());
|
||||
var arg2 = as2ToInt32(stack.pop());
|
||||
stack.push(arg2 >> arg1);
|
||||
break;
|
||||
case 0x65: // ActionBitURShift
|
||||
var arg1 = stack.pop();
|
||||
var arg2 = stack.pop();
|
||||
var arg1 = as2ToInt32(stack.pop());
|
||||
var arg2 = as2ToInt32(stack.pop());
|
||||
stack.push(arg2 >>> arg1);
|
||||
break;
|
||||
case 0x62: // ActionBitXor
|
||||
var arg1 = stack.pop();
|
||||
var arg2 = stack.pop();
|
||||
var arg1 = as2ToInt32(stack.pop());
|
||||
var arg2 = as2ToInt32(stack.pop());
|
||||
stack.push(arg2 ^ arg1);
|
||||
break;
|
||||
case 0x51: // ActionDecrement
|
||||
var arg1 = stack.pop();
|
||||
var arg1 = as2ToNumber(stack.pop());
|
||||
arg1--;
|
||||
stack.push(arg1);
|
||||
break;
|
||||
case 0x50: // ActionIncrement
|
||||
var arg1 = stack.pop();
|
||||
var arg1 = as2ToNumber(stack.pop());
|
||||
arg1++;
|
||||
stack.push(arg1);
|
||||
break;
|
||||
|
@ -779,7 +948,7 @@ function interpretActions(actionsData, scopeContainer,
|
|||
case 0x54: // ActionInstanceOf
|
||||
var constr = stack.pop();
|
||||
var obj = stack.pop();
|
||||
stack.push(instanceOf(Object(obj), constr));
|
||||
stack.push(as2InstanceOf(Object(obj), constr));
|
||||
break;
|
||||
case 0x55: // ActionEnumerate2
|
||||
var obj = stack.pop();
|
||||
|
@ -795,11 +964,11 @@ function interpretActions(actionsData, scopeContainer,
|
|||
case 0x67: // ActionGreater
|
||||
var arg1 = stack.pop();
|
||||
var arg2 = stack.pop();
|
||||
stack.push(arg2 > arg1);
|
||||
stack.push(as2Compare(arg1, arg2));
|
||||
break;
|
||||
case 0x68: // ActionStringGreater
|
||||
var sa = '' + stack.pop();
|
||||
var sb = '' + stack.pop();
|
||||
var sa = as2ToString(stack.pop());
|
||||
var sb = as2ToString(stack.pop());
|
||||
var f = sb > sa;
|
||||
stack.push(isSwfVersion5 ? f : f ? 1 : 0);
|
||||
break;
|
||||
|
@ -859,7 +1028,7 @@ function interpretActions(actionsData, scopeContainer,
|
|||
case 0x2B: // ActionCastOp
|
||||
var obj = stack.pop();
|
||||
var constr = stack.pop();
|
||||
stack.push(instanceOf(obj, constr) ? obj : null);
|
||||
stack.push(as2InstanceOf(obj, constr) ? obj : null);
|
||||
break;
|
||||
case 0x2C: // ActionImplementsOp
|
||||
var constr = stack.pop();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- mode: javascript; tab-width: 4; insert-tabs-mode: nil; indent-tabs-mode: nil -*- */
|
||||
/* -*- mode: javascript; tab-width: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
var fs = require('fs');
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- mode: javascript; tab-width: 4; insert-tabs-mode: nil; indent-tabs-mode: nil -*- */
|
||||
/* -*- mode: javascript; tab-width: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
var expect = require('expect.js');
|
||||
require('./domstubs.js');
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- mode: javascript; tab-width: 4; insert-tabs-mode: nil; indent-tabs-mode: nil -*- */
|
||||
/* -*- mode: javascript; tab-width: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
var expect = require('expect.js');
|
||||
require('./domstubs.js');
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- mode: javascript; tab-width: 4; insert-tabs-mode: nil; indent-tabs-mode: nil -*- */
|
||||
/* -*- mode: javascript; tab-width: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
var expect = require('expect.js');
|
||||
require('./domstubs.js');
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- mode: javascript; tab-width: 4; insert-tabs-mode: nil; indent-tabs-mode: nil -*- */
|
||||
/* -*- mode: javascript; tab-width: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
var expect = require('expect.js');
|
||||
require('../stream.js');
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
var Control = (function () {
|
||||
|
||||
const SEQ = 1;
|
||||
const LOOP = 2;
|
||||
const IF = 3;
|
||||
const CASE = 4;
|
||||
const SWITCH = 5;
|
||||
const LABEL_CASE = 6;
|
||||
const LABEL_SWITCH = 7;
|
||||
const EXIT = 8;
|
||||
const BREAK = 9;
|
||||
const CONTINUE = 10;
|
||||
const TRY = 11;
|
||||
const CATCH = 12;
|
||||
var SEQ = 1;
|
||||
var LOOP = 2;
|
||||
var IF = 3;
|
||||
var CASE = 4;
|
||||
var SWITCH = 5;
|
||||
var LABEL_CASE = 6;
|
||||
var LABEL_SWITCH = 7;
|
||||
var EXIT = 8;
|
||||
var BREAK = 9;
|
||||
var CONTINUE = 10;
|
||||
var TRY = 11;
|
||||
var CATCH = 12;
|
||||
|
||||
function Seq(body) {
|
||||
this.kind = SEQ;
|
||||
|
@ -398,9 +398,9 @@ var Analysis = (function () {
|
|||
function blockSetClass(length, blockById) {
|
||||
var BlockSet = BitSetFunctor(length);
|
||||
|
||||
const ADDRESS_BITS_PER_WORD = BlockSet.ADDRESS_BITS_PER_WORD;
|
||||
const BITS_PER_WORD = BlockSet.BITS_PER_WORD;
|
||||
const BIT_INDEX_MASK = BlockSet.BIT_INDEX_MASK;
|
||||
var ADDRESS_BITS_PER_WORD = BlockSet.ADDRESS_BITS_PER_WORD;
|
||||
var BITS_PER_WORD = BlockSet.BITS_PER_WORD;
|
||||
var BIT_INDEX_MASK = BlockSet.BIT_INDEX_MASK;
|
||||
|
||||
BlockSet.singleton = function singleton(b) {
|
||||
var bs = new BlockSet();
|
||||
|
@ -867,9 +867,9 @@ var Analysis = (function () {
|
|||
// The root must not have preds!
|
||||
release || assert(root.preds.length === 0);
|
||||
|
||||
const ONCE = 1;
|
||||
const BUNCH_OF_TIMES = 2;
|
||||
const BlockSet = this.BlockSet;
|
||||
var ONCE = 1;
|
||||
var BUNCH_OF_TIMES = 2;
|
||||
var BlockSet = this.BlockSet;
|
||||
|
||||
var blocks = [];
|
||||
var visited = {};
|
||||
|
@ -1014,7 +1014,7 @@ var Analysis = (function () {
|
|||
},
|
||||
|
||||
computeFrontiers: function computeFrontiers() {
|
||||
const BlockSet = this.BlockSet;
|
||||
var BlockSet = this.BlockSet;
|
||||
var blocks = this.blocks;
|
||||
|
||||
for (var b = 0, n = blocks.length; b < n; b++) {
|
||||
|
@ -1055,7 +1055,7 @@ var Analysis = (function () {
|
|||
return false;
|
||||
}
|
||||
|
||||
const BlockSet = this.BlockSet;
|
||||
var BlockSet = this.BlockSet;
|
||||
|
||||
//
|
||||
// Find all SCCs at or below the level of some root that are not already
|
||||
|
@ -1206,8 +1206,8 @@ var Analysis = (function () {
|
|||
},
|
||||
|
||||
induceControlTree: function induceControlTree() {
|
||||
const hasExceptions = this.method.exceptions.length > 0;
|
||||
const BlockSet = this.BlockSet;
|
||||
var hasExceptions = this.method.exceptions.length > 0;
|
||||
var BlockSet = this.BlockSet;
|
||||
|
||||
function maybe(exit, save) {
|
||||
exit.recount();
|
||||
|
|
|
@ -29,23 +29,23 @@ var escodegen = require(__dirname + "/../compiler/lljs/src/escodegen.js");
|
|||
var estransform = require(__dirname + "/../compiler/lljs/src/estransform.js");
|
||||
|
||||
// Import nodes
|
||||
const T = estransform;
|
||||
const Node = T.Node;
|
||||
const Literal = T.Literal;
|
||||
const Identifier = T.Identifier;
|
||||
const CallExpression = T.CallExpression;
|
||||
const ExpressionStatement = T.ExpressionStatement;
|
||||
const FunctionExpression = T.FunctionExpression;
|
||||
const FunctionDeclaration = T.FunctionDeclaration;
|
||||
const MemberExpression = T.MemberExpression;
|
||||
const AssignmentExpression = T.AssignmentExpression;
|
||||
const BlockStatement = T.BlockStatement;
|
||||
const VariableDeclaration = T.VariableDeclaration;
|
||||
const VariableDeclarator = T.VariableDeclarator;
|
||||
const ArrayExpression = T.ArrayExpression;
|
||||
const BinaryExpression = T.BinaryExpression;
|
||||
const ObjectExpression = T.ObjectExpression;
|
||||
const Property = T.Property;
|
||||
var T = estransform;
|
||||
var Node = T.Node;
|
||||
var Literal = T.Literal;
|
||||
var Identifier = T.Identifier;
|
||||
var CallExpression = T.CallExpression;
|
||||
var ExpressionStatement = T.ExpressionStatement;
|
||||
var FunctionExpression = T.FunctionExpression;
|
||||
var FunctionDeclaration = T.FunctionDeclaration;
|
||||
var MemberExpression = T.MemberExpression;
|
||||
var AssignmentExpression = T.AssignmentExpression;
|
||||
var BlockStatement = T.BlockStatement;
|
||||
var VariableDeclaration = T.VariableDeclaration;
|
||||
var VariableDeclarator = T.VariableDeclarator;
|
||||
var ArrayExpression = T.ArrayExpression;
|
||||
var BinaryExpression = T.BinaryExpression;
|
||||
var ObjectExpression = T.ObjectExpression;
|
||||
var Property = T.Property;
|
||||
|
||||
|
||||
// Parse arguments
|
||||
|
|
|
@ -241,7 +241,7 @@ function shortPath(str, length) {
|
|||
function extractData(str) {
|
||||
var lines = str.replace(/\r/g, "").split("\n");
|
||||
var data = {};
|
||||
const jsonPrefix = "SHUMWAY$JSON";
|
||||
var jsonPrefix = "SHUMWAY$JSON";
|
||||
var textLines = lines.filter(function (x) {
|
||||
if (x.indexOf(jsonPrefix) === 0) {
|
||||
var lineData = {};
|
||||
|
|
|
@ -21,43 +21,43 @@ function shouldCompile(mi) {
|
|||
return true;
|
||||
}
|
||||
|
||||
const T = estransform;
|
||||
var T = estransform;
|
||||
|
||||
const Literal = T.Literal;
|
||||
const Identifier = T.Identifier;
|
||||
const VariableDeclaration = T.VariableDeclaration;
|
||||
const VariableDeclarator = T.VariableDeclarator;
|
||||
const MemberExpression = T.MemberExpression;
|
||||
const BinaryExpression = T.BinaryExpression;
|
||||
const SequenceExpression = T.SequenceExpression;
|
||||
const CallExpression = T.CallExpression;
|
||||
const AssignmentExpression = T.AssignmentExpression;
|
||||
const ExpressionStatement = T.ExpressionStatement;
|
||||
const ReturnStatement = T.ReturnStatement;
|
||||
const Program = T.Program;
|
||||
const Statement = T.Statement;
|
||||
const FunctionDeclaration = T.FunctionDeclaration;
|
||||
const FunctionExpression = T.FunctionExpression;
|
||||
const ConditionalExpression = T.ConditionalExpression;
|
||||
const ObjectExpression = T.ObjectExpression;
|
||||
const ArrayExpression = T.ArrayExpression;
|
||||
const UnaryExpression = T.UnaryExpression;
|
||||
const NewExpression = T.NewExpression;
|
||||
const UpdateExpression = T.UpdateExpression;
|
||||
const ForStatement = T.ForStatement;
|
||||
const BlockStatement = T.BlockStatement;
|
||||
const ThisExpression = T.ThisExpression;
|
||||
const TypeAliasDirective = T.TypeAliasDirective;
|
||||
const CastExpression = T.CastExpression;
|
||||
const ThrowStatement = T.ThrowStatement;
|
||||
const IfStatement = T.IfStatement;
|
||||
const WhileStatement = T.WhileStatement;
|
||||
const BreakStatement = T.BreakStatement;
|
||||
const ContinueStatement = T.ContinueStatement;
|
||||
const SwitchStatement = T.SwitchStatement;
|
||||
const SwitchCase = T.SwitchCase;
|
||||
const TryStatement = T.TryStatement;
|
||||
const CatchClause = T.CatchClause;
|
||||
var Literal = T.Literal;
|
||||
var Identifier = T.Identifier;
|
||||
var VariableDeclaration = T.VariableDeclaration;
|
||||
var VariableDeclarator = T.VariableDeclarator;
|
||||
var MemberExpression = T.MemberExpression;
|
||||
var BinaryExpression = T.BinaryExpression;
|
||||
var SequenceExpression = T.SequenceExpression;
|
||||
var CallExpression = T.CallExpression;
|
||||
var AssignmentExpression = T.AssignmentExpression;
|
||||
var ExpressionStatement = T.ExpressionStatement;
|
||||
var ReturnStatement = T.ReturnStatement;
|
||||
var Program = T.Program;
|
||||
var Statement = T.Statement;
|
||||
var FunctionDeclaration = T.FunctionDeclaration;
|
||||
var FunctionExpression = T.FunctionExpression;
|
||||
var ConditionalExpression = T.ConditionalExpression;
|
||||
var ObjectExpression = T.ObjectExpression;
|
||||
var ArrayExpression = T.ArrayExpression;
|
||||
var UnaryExpression = T.UnaryExpression;
|
||||
var NewExpression = T.NewExpression;
|
||||
var UpdateExpression = T.UpdateExpression;
|
||||
var ForStatement = T.ForStatement;
|
||||
var BlockStatement = T.BlockStatement;
|
||||
var ThisExpression = T.ThisExpression;
|
||||
var TypeAliasDirective = T.TypeAliasDirective;
|
||||
var CastExpression = T.CastExpression;
|
||||
var ThrowStatement = T.ThrowStatement;
|
||||
var IfStatement = T.IfStatement;
|
||||
var WhileStatement = T.WhileStatement;
|
||||
var BreakStatement = T.BreakStatement;
|
||||
var ContinueStatement = T.ContinueStatement;
|
||||
var SwitchStatement = T.SwitchStatement;
|
||||
var SwitchCase = T.SwitchCase;
|
||||
var TryStatement = T.TryStatement;
|
||||
var CatchClause = T.CatchClause;
|
||||
|
||||
/**
|
||||
* When adding a new "magic" variable that the compiler has
|
||||
|
@ -88,25 +88,25 @@ const CatchClause = T.CatchClause;
|
|||
* where the "%d" is the stack index that the value occupies.
|
||||
*/
|
||||
|
||||
const VAR_PREFIX = "v";
|
||||
const LOCAL_PREFIX = "l";
|
||||
const STACK_PREFIX = "s";
|
||||
const ARGUMENT_PREFIX = "a";
|
||||
const INLINE_CACHE_GETTER_PREFIX = "get";
|
||||
const INLINE_CACHE_SETTER_PREFIX = "set";
|
||||
var VAR_PREFIX = "v";
|
||||
var LOCAL_PREFIX = "l";
|
||||
var STACK_PREFIX = "s";
|
||||
var ARGUMENT_PREFIX = "a";
|
||||
var INLINE_CACHE_GETTER_PREFIX = "get";
|
||||
var INLINE_CACHE_SETTER_PREFIX = "set";
|
||||
|
||||
const SAVED_SCOPE_NAME = "$SS";
|
||||
const scopeName = new Identifier("$S");
|
||||
const scopeObjectName = new Identifier("$O");
|
||||
const globalScopeObjectName = new Identifier("$G");
|
||||
const savedScopeName = new Identifier(SAVED_SCOPE_NAME);
|
||||
const constantsName = new Identifier("$C");
|
||||
const lastCaughtName = new Identifier("$E");
|
||||
const exceptionName = new Identifier("$e");
|
||||
const labelTestName = new Identifier("$label");
|
||||
const labelConditionName = new Identifier("$condition");
|
||||
const labelDeterminantName = new Identifier("$determinant");
|
||||
const activationName = new Identifier("$activation");
|
||||
var SAVED_SCOPE_NAME = "$SS";
|
||||
var scopeName = new Identifier("$S");
|
||||
var scopeObjectName = new Identifier("$O");
|
||||
var globalScopeObjectName = new Identifier("$G");
|
||||
var savedScopeName = new Identifier(SAVED_SCOPE_NAME);
|
||||
var constantsName = new Identifier("$C");
|
||||
var lastCaughtName = new Identifier("$E");
|
||||
var exceptionName = new Identifier("$e");
|
||||
var labelTestName = new Identifier("$label");
|
||||
var labelConditionName = new Identifier("$condition");
|
||||
var labelDeterminantName = new Identifier("$determinant");
|
||||
var activationName = new Identifier("$activation");
|
||||
|
||||
/**
|
||||
* To embed object references in compiled code we index into globally accessible constant table [$C].
|
||||
|
@ -125,7 +125,7 @@ function notUndefined(x) {
|
|||
return x !== undefined;
|
||||
}
|
||||
|
||||
const FlushStackReason = {
|
||||
var FlushStackReason = {
|
||||
EndOfBlock: 1,
|
||||
SetLocal: 2
|
||||
};
|
||||
|
@ -891,15 +891,15 @@ var Compiler = (function () {
|
|||
var temporary = this.temporary;
|
||||
var cachedScopes = this.cachedScopes;
|
||||
|
||||
const abc = this.compiler.abc;
|
||||
const ints = abc.constantPool.ints;
|
||||
const uints = abc.constantPool.uints;
|
||||
const doubles = abc.constantPool.doubles;
|
||||
const strings = abc.constantPool.strings;
|
||||
const methods = abc.methods;
|
||||
const multinames = abc.constantPool.multinames;
|
||||
const runtime = abc.runtime;
|
||||
const exceptions = this.methodInfo.exceptions;
|
||||
var abc = this.compiler.abc;
|
||||
var ints = abc.constantPool.ints;
|
||||
var uints = abc.constantPool.uints;
|
||||
var doubles = abc.constantPool.doubles;
|
||||
var strings = abc.constantPool.strings;
|
||||
var methods = abc.methods;
|
||||
var multinames = abc.constantPool.multinames;
|
||||
var runtime = abc.runtime;
|
||||
var exceptions = this.methodInfo.exceptions;
|
||||
|
||||
var savedScope = this.savedScope;
|
||||
var multiname, args, value, obj, qn, ns, name, type, factory, index;
|
||||
|
@ -911,7 +911,7 @@ var Compiler = (function () {
|
|||
}
|
||||
|
||||
function superClassInstanceObject() {
|
||||
return property(classObject(), "baseClass", "instance");
|
||||
return property(classObject(), "baseClass", "instanceNoInitialize");
|
||||
}
|
||||
|
||||
function superOf(obj) {
|
||||
|
|
|
@ -1,248 +1,248 @@
|
|||
const CONSTANT_Undefined = 0x00;
|
||||
const CONSTANT_Utf8 = 0x01;
|
||||
const CONSTANT_Float = 0x02; // May be deprecated ??
|
||||
const CONSTANT_Int = 0x03;
|
||||
const CONSTANT_UInt = 0x04;
|
||||
const CONSTANT_PrivateNs = 0x05;
|
||||
const CONSTANT_Double = 0x06;
|
||||
const CONSTANT_QName = 0x07; // ns::name, const ns, const name
|
||||
const CONSTANT_Namespace = 0x08;
|
||||
const CONSTANT_Multiname = 0x09; // [ns...]::name, const [ns...], const name
|
||||
const CONSTANT_False = 0x0A;
|
||||
const CONSTANT_True = 0x0B;
|
||||
const CONSTANT_Null = 0x0C;
|
||||
const CONSTANT_QNameA = 0x0D; // @ns::name, const ns, const name
|
||||
const CONSTANT_MultinameA = 0x0E; // @[ns...]::name, const [ns...], const name
|
||||
const CONSTANT_RTQName = 0x0F; // ns::name, var ns, const name
|
||||
const CONSTANT_RTQNameA = 0x10; // @ns::name, var ns, const name
|
||||
const CONSTANT_RTQNameL = 0x11; // ns::[name], var ns, var name
|
||||
const CONSTANT_RTQNameLA = 0x12; // @ns::[name], var ns, var name
|
||||
const CONSTANT_NameL = 0x13; // o[name], var name
|
||||
const CONSTANT_NameLA = 0x14; // @[name], var name
|
||||
const CONSTANT_NamespaceSet = 0x15;
|
||||
const CONSTANT_PackageNamespace = 0x16; // namespace for a package
|
||||
const CONSTANT_PackageInternalNs = 0x17;
|
||||
const CONSTANT_ProtectedNamespace = 0x18;
|
||||
const CONSTANT_ExplicitNamespace = 0x19;
|
||||
const CONSTANT_StaticProtectedNs = 0x1A;
|
||||
const CONSTANT_MultinameL = 0x1B;
|
||||
const CONSTANT_MultinameLA = 0x1C;
|
||||
const CONSTANT_TypeName = 0x1D;
|
||||
var CONSTANT_Undefined = 0x00;
|
||||
var CONSTANT_Utf8 = 0x01;
|
||||
var CONSTANT_Float = 0x02; // May be deprecated ??
|
||||
var CONSTANT_Int = 0x03;
|
||||
var CONSTANT_UInt = 0x04;
|
||||
var CONSTANT_PrivateNs = 0x05;
|
||||
var CONSTANT_Double = 0x06;
|
||||
var CONSTANT_QName = 0x07; // ns::name, const ns, const name
|
||||
var CONSTANT_Namespace = 0x08;
|
||||
var CONSTANT_Multiname = 0x09; // [ns...]::name, const [ns...], const name
|
||||
var CONSTANT_False = 0x0A;
|
||||
var CONSTANT_True = 0x0B;
|
||||
var CONSTANT_Null = 0x0C;
|
||||
var CONSTANT_QNameA = 0x0D; // @ns::name, const ns, const name
|
||||
var CONSTANT_MultinameA = 0x0E; // @[ns...]::name, const [ns...], const name
|
||||
var CONSTANT_RTQName = 0x0F; // ns::name, var ns, const name
|
||||
var CONSTANT_RTQNameA = 0x10; // @ns::name, var ns, const name
|
||||
var CONSTANT_RTQNameL = 0x11; // ns::[name], var ns, var name
|
||||
var CONSTANT_RTQNameLA = 0x12; // @ns::[name], var ns, var name
|
||||
var CONSTANT_NameL = 0x13; // o[name], var name
|
||||
var CONSTANT_NameLA = 0x14; // @[name], var name
|
||||
var CONSTANT_NamespaceSet = 0x15;
|
||||
var CONSTANT_PackageNamespace = 0x16; // namespace for a package
|
||||
var CONSTANT_PackageInternalNs = 0x17;
|
||||
var CONSTANT_ProtectedNamespace = 0x18;
|
||||
var CONSTANT_ExplicitNamespace = 0x19;
|
||||
var CONSTANT_StaticProtectedNs = 0x1A;
|
||||
var CONSTANT_MultinameL = 0x1B;
|
||||
var CONSTANT_MultinameLA = 0x1C;
|
||||
var CONSTANT_TypeName = 0x1D;
|
||||
|
||||
const CONSTANT_ClassSealed = 0x01;
|
||||
const CONSTANT_ClassFinal = 0x02;
|
||||
const CONSTANT_ClassInterface = 0x04;
|
||||
const CONSTANT_ClassProtectedNs = 0x08;
|
||||
var CONSTANT_ClassSealed = 0x01;
|
||||
var CONSTANT_ClassFinal = 0x02;
|
||||
var CONSTANT_ClassInterface = 0x04;
|
||||
var CONSTANT_ClassProtectedNs = 0x08;
|
||||
|
||||
const TRAIT_Slot = 0;
|
||||
const TRAIT_Method = 1;
|
||||
const TRAIT_Getter = 2;
|
||||
const TRAIT_Setter = 3;
|
||||
const TRAIT_Class = 4;
|
||||
const TRAIT_Function = 5;
|
||||
const TRAIT_Const = 6;
|
||||
var TRAIT_Slot = 0;
|
||||
var TRAIT_Method = 1;
|
||||
var TRAIT_Getter = 2;
|
||||
var TRAIT_Setter = 3;
|
||||
var TRAIT_Class = 4;
|
||||
var TRAIT_Function = 5;
|
||||
var TRAIT_Const = 6;
|
||||
|
||||
const ATTR_Final = 0x01;
|
||||
const ATTR_Override = 0x02;
|
||||
const ATTR_Metadata = 0x04;
|
||||
var ATTR_Final = 0x01;
|
||||
var ATTR_Override = 0x02;
|
||||
var ATTR_Metadata = 0x04;
|
||||
|
||||
const SLOT_var = 0;
|
||||
const SLOT_method = 1;
|
||||
const SLOT_getter = 2;
|
||||
const SLOT_setter = 3;
|
||||
const SLOT_class = 4;
|
||||
const SLOT_function = 6;
|
||||
var SLOT_var = 0;
|
||||
var SLOT_method = 1;
|
||||
var SLOT_getter = 2;
|
||||
var SLOT_setter = 3;
|
||||
var SLOT_class = 4;
|
||||
var SLOT_function = 6;
|
||||
|
||||
const METHOD_Arguments = 0x1;
|
||||
const METHOD_Activation = 0x2;
|
||||
const METHOD_Needrest = 0x4;
|
||||
const METHOD_HasOptional = 0x8;
|
||||
const METHOD_IgnoreRest = 0x10;
|
||||
const METHOD_Native = 0x20;
|
||||
const METHOD_Setsdxns = 0x40;
|
||||
const METHOD_HasParamNames = 0x80;
|
||||
var METHOD_Arguments = 0x1;
|
||||
var METHOD_Activation = 0x2;
|
||||
var METHOD_Needrest = 0x4;
|
||||
var METHOD_HasOptional = 0x8;
|
||||
var METHOD_IgnoreRest = 0x10;
|
||||
var METHOD_Native = 0x20;
|
||||
var METHOD_Setsdxns = 0x40;
|
||||
var METHOD_HasParamNames = 0x80;
|
||||
|
||||
const OP_bkpt = 0x01;
|
||||
const OP_nop = 0x02;
|
||||
const OP_throw = 0x03;
|
||||
const OP_getsuper = 0x04;
|
||||
const OP_setsuper = 0x05;
|
||||
const OP_dxns = 0x06;
|
||||
const OP_dxnslate = 0x07;
|
||||
const OP_kill = 0x08;
|
||||
const OP_label = 0x09;
|
||||
const OP_lf32x4 = 0x0A;
|
||||
const OP_sf32x4 = 0x0B;
|
||||
const OP_ifnlt = 0x0C;
|
||||
const OP_ifnle = 0x0D;
|
||||
const OP_ifngt = 0x0E;
|
||||
const OP_ifnge = 0x0F;
|
||||
const OP_jump = 0x10;
|
||||
const OP_iftrue = 0x11;
|
||||
const OP_iffalse = 0x12;
|
||||
const OP_ifeq = 0x13;
|
||||
const OP_ifne = 0x14;
|
||||
const OP_iflt = 0x15;
|
||||
const OP_ifle = 0x16;
|
||||
const OP_ifgt = 0x17;
|
||||
const OP_ifge = 0x18;
|
||||
const OP_ifstricteq = 0x19;
|
||||
const OP_ifstrictne = 0x1A;
|
||||
const OP_lookupswitch = 0x1B;
|
||||
const OP_pushwith = 0x1C;
|
||||
const OP_popscope = 0x1D;
|
||||
const OP_nextname = 0x1E;
|
||||
const OP_hasnext = 0x1F;
|
||||
const OP_pushnull = 0x20;
|
||||
const OP_pushundefined = 0x21;
|
||||
const OP_pushfloat = 0x22;
|
||||
const OP_nextvalue = 0x23;
|
||||
const OP_pushbyte = 0x24;
|
||||
const OP_pushshort = 0x25;
|
||||
const OP_pushtrue = 0x26;
|
||||
const OP_pushfalse = 0x27;
|
||||
const OP_pushnan = 0x28;
|
||||
const OP_pop = 0x29;
|
||||
const OP_dup = 0x2A;
|
||||
const OP_swap = 0x2B;
|
||||
const OP_pushstring = 0x2C;
|
||||
const OP_pushint = 0x2D;
|
||||
const OP_pushuint = 0x2E;
|
||||
const OP_pushdouble = 0x2F;
|
||||
const OP_pushscope = 0x30;
|
||||
const OP_pushnamespace = 0x31;
|
||||
const OP_hasnext2 = 0x32;
|
||||
const OP_li8 = 0x35;
|
||||
const OP_li16 = 0x36;
|
||||
const OP_li32 = 0x37;
|
||||
const OP_lf32 = 0x38;
|
||||
const OP_lf64 = 0x39;
|
||||
const OP_si8 = 0x3A;
|
||||
const OP_si16 = 0x3B;
|
||||
const OP_si32 = 0x3C;
|
||||
const OP_sf32 = 0x3D;
|
||||
const OP_sf64 = 0x3E;
|
||||
const OP_newfunction = 0x40;
|
||||
const OP_call = 0x41;
|
||||
const OP_construct = 0x42;
|
||||
const OP_callmethod = 0x43;
|
||||
const OP_callstatic = 0x44;
|
||||
const OP_callsuper = 0x45;
|
||||
const OP_callproperty = 0x46;
|
||||
const OP_returnvoid = 0x47;
|
||||
const OP_returnvalue = 0x48;
|
||||
const OP_constructsuper = 0x49;
|
||||
const OP_constructprop = 0x4A;
|
||||
const OP_callsuperid = 0x4B;
|
||||
const OP_callproplex = 0x4C;
|
||||
const OP_callinterface = 0x4D;
|
||||
const OP_callsupervoid = 0x4E;
|
||||
const OP_callpropvoid = 0x4F;
|
||||
const OP_sxi1 = 0x50;
|
||||
const OP_sxi8 = 0x51;
|
||||
const OP_sxi16 = 0x52;
|
||||
const OP_applytype = 0x53;
|
||||
const OP_pushfloat4 = 0x54;
|
||||
const OP_newobject = 0x55;
|
||||
const OP_newarray = 0x56;
|
||||
const OP_newactivation = 0x57;
|
||||
const OP_newclass = 0x58;
|
||||
const OP_getdescendants = 0x59;
|
||||
const OP_newcatch = 0x5A;
|
||||
const OP_findpropstrict = 0x5D;
|
||||
const OP_findproperty = 0x5E;
|
||||
const OP_finddef = 0x5F;
|
||||
const OP_getlex = 0x60;
|
||||
const OP_setproperty = 0x61;
|
||||
const OP_getlocal = 0x62;
|
||||
const OP_setlocal = 0x63;
|
||||
const OP_getglobalscope = 0x64;
|
||||
const OP_getscopeobject = 0x65;
|
||||
const OP_getproperty = 0x66;
|
||||
const OP_getouterscope = 0x67;
|
||||
const OP_initproperty = 0x68;
|
||||
const OP_setpropertylate = 0x69;
|
||||
const OP_deleteproperty = 0x6A;
|
||||
const OP_deletepropertylate = 0x6B;
|
||||
const OP_getslot = 0x6C;
|
||||
const OP_setslot = 0x6D;
|
||||
const OP_getglobalslot = 0x6E;
|
||||
const OP_setglobalslot = 0x6F;
|
||||
const OP_convert_s = 0x70;
|
||||
const OP_esc_xelem = 0x71;
|
||||
const OP_esc_xattr = 0x72;
|
||||
const OP_convert_i = 0x73;
|
||||
const OP_convert_u = 0x74;
|
||||
const OP_convert_d = 0x75;
|
||||
const OP_convert_b = 0x76;
|
||||
const OP_convert_o = 0x77;
|
||||
const OP_checkfilter = 0x78;
|
||||
const OP_convert_f = 0x79;
|
||||
const OP_unplus = 0x7a;
|
||||
const OP_convert_f4 = 0x7b;
|
||||
const OP_coerce = 0x80;
|
||||
const OP_coerce_b = 0x81;
|
||||
const OP_coerce_a = 0x82;
|
||||
const OP_coerce_i = 0x83;
|
||||
const OP_coerce_d = 0x84;
|
||||
const OP_coerce_s = 0x85;
|
||||
const OP_astype = 0x86;
|
||||
const OP_astypelate = 0x87;
|
||||
const OP_coerce_u = 0x88;
|
||||
const OP_coerce_o = 0x89;
|
||||
const OP_negate = 0x90;
|
||||
const OP_increment = 0x91;
|
||||
const OP_inclocal = 0x92;
|
||||
const OP_decrement = 0x93;
|
||||
const OP_declocal = 0x94;
|
||||
const OP_typeof = 0x95;
|
||||
const OP_not = 0x96;
|
||||
const OP_bitnot = 0x97;
|
||||
const OP_add = 0xA0;
|
||||
const OP_subtract = 0xA1;
|
||||
const OP_multiply = 0xA2;
|
||||
const OP_divide = 0xA3;
|
||||
const OP_modulo = 0xA4;
|
||||
const OP_lshift = 0xA5;
|
||||
const OP_rshift = 0xA6;
|
||||
const OP_urshift = 0xA7;
|
||||
const OP_bitand = 0xA8;
|
||||
const OP_bitor = 0xA9;
|
||||
const OP_bitxor = 0xAA;
|
||||
const OP_equals = 0xAB;
|
||||
const OP_strictequals = 0xAC;
|
||||
const OP_lessthan = 0xAD;
|
||||
const OP_lessequals = 0xAE;
|
||||
const OP_greaterthan = 0xAF;
|
||||
const OP_greaterequals = 0xB0;
|
||||
const OP_instanceof = 0xB1;
|
||||
const OP_istype = 0xB2;
|
||||
const OP_istypelate = 0xB3;
|
||||
const OP_in = 0xB4;
|
||||
const OP_increment_i = 0xC0;
|
||||
const OP_decrement_i = 0xC1;
|
||||
const OP_inclocal_i = 0xC2;
|
||||
const OP_declocal_i = 0xC3;
|
||||
const OP_negate_i = 0xC4;
|
||||
const OP_add_i = 0xC5;
|
||||
const OP_subtract_i = 0xC6;
|
||||
const OP_multiply_i = 0xC7;
|
||||
const OP_getlocal0 = 0xD0;
|
||||
const OP_getlocal1 = 0xD1;
|
||||
const OP_getlocal2 = 0xD2;
|
||||
const OP_getlocal3 = 0xD3;
|
||||
const OP_setlocal0 = 0xD4;
|
||||
const OP_setlocal1 = 0xD5;
|
||||
const OP_setlocal2 = 0xD6;
|
||||
const OP_setlocal3 = 0xD7;
|
||||
const OP_invalid = 0xED;
|
||||
const OP_debug = 0xEF;
|
||||
const OP_debugline = 0xF0;
|
||||
const OP_debugfile = 0xF1;
|
||||
const OP_bkptline = 0xF2;
|
||||
const OP_timestamp = 0xF3;
|
||||
var OP_bkpt = 0x01;
|
||||
var OP_nop = 0x02;
|
||||
var OP_throw = 0x03;
|
||||
var OP_getsuper = 0x04;
|
||||
var OP_setsuper = 0x05;
|
||||
var OP_dxns = 0x06;
|
||||
var OP_dxnslate = 0x07;
|
||||
var OP_kill = 0x08;
|
||||
var OP_label = 0x09;
|
||||
var OP_lf32x4 = 0x0A;
|
||||
var OP_sf32x4 = 0x0B;
|
||||
var OP_ifnlt = 0x0C;
|
||||
var OP_ifnle = 0x0D;
|
||||
var OP_ifngt = 0x0E;
|
||||
var OP_ifnge = 0x0F;
|
||||
var OP_jump = 0x10;
|
||||
var OP_iftrue = 0x11;
|
||||
var OP_iffalse = 0x12;
|
||||
var OP_ifeq = 0x13;
|
||||
var OP_ifne = 0x14;
|
||||
var OP_iflt = 0x15;
|
||||
var OP_ifle = 0x16;
|
||||
var OP_ifgt = 0x17;
|
||||
var OP_ifge = 0x18;
|
||||
var OP_ifstricteq = 0x19;
|
||||
var OP_ifstrictne = 0x1A;
|
||||
var OP_lookupswitch = 0x1B;
|
||||
var OP_pushwith = 0x1C;
|
||||
var OP_popscope = 0x1D;
|
||||
var OP_nextname = 0x1E;
|
||||
var OP_hasnext = 0x1F;
|
||||
var OP_pushnull = 0x20;
|
||||
var OP_pushundefined = 0x21;
|
||||
var OP_pushfloat = 0x22;
|
||||
var OP_nextvalue = 0x23;
|
||||
var OP_pushbyte = 0x24;
|
||||
var OP_pushshort = 0x25;
|
||||
var OP_pushtrue = 0x26;
|
||||
var OP_pushfalse = 0x27;
|
||||
var OP_pushnan = 0x28;
|
||||
var OP_pop = 0x29;
|
||||
var OP_dup = 0x2A;
|
||||
var OP_swap = 0x2B;
|
||||
var OP_pushstring = 0x2C;
|
||||
var OP_pushint = 0x2D;
|
||||
var OP_pushuint = 0x2E;
|
||||
var OP_pushdouble = 0x2F;
|
||||
var OP_pushscope = 0x30;
|
||||
var OP_pushnamespace = 0x31;
|
||||
var OP_hasnext2 = 0x32;
|
||||
var OP_li8 = 0x35;
|
||||
var OP_li16 = 0x36;
|
||||
var OP_li32 = 0x37;
|
||||
var OP_lf32 = 0x38;
|
||||
var OP_lf64 = 0x39;
|
||||
var OP_si8 = 0x3A;
|
||||
var OP_si16 = 0x3B;
|
||||
var OP_si32 = 0x3C;
|
||||
var OP_sf32 = 0x3D;
|
||||
var OP_sf64 = 0x3E;
|
||||
var OP_newfunction = 0x40;
|
||||
var OP_call = 0x41;
|
||||
var OP_construct = 0x42;
|
||||
var OP_callmethod = 0x43;
|
||||
var OP_callstatic = 0x44;
|
||||
var OP_callsuper = 0x45;
|
||||
var OP_callproperty = 0x46;
|
||||
var OP_returnvoid = 0x47;
|
||||
var OP_returnvalue = 0x48;
|
||||
var OP_constructsuper = 0x49;
|
||||
var OP_constructprop = 0x4A;
|
||||
var OP_callsuperid = 0x4B;
|
||||
var OP_callproplex = 0x4C;
|
||||
var OP_callinterface = 0x4D;
|
||||
var OP_callsupervoid = 0x4E;
|
||||
var OP_callpropvoid = 0x4F;
|
||||
var OP_sxi1 = 0x50;
|
||||
var OP_sxi8 = 0x51;
|
||||
var OP_sxi16 = 0x52;
|
||||
var OP_applytype = 0x53;
|
||||
var OP_pushfloat4 = 0x54;
|
||||
var OP_newobject = 0x55;
|
||||
var OP_newarray = 0x56;
|
||||
var OP_newactivation = 0x57;
|
||||
var OP_newclass = 0x58;
|
||||
var OP_getdescendants = 0x59;
|
||||
var OP_newcatch = 0x5A;
|
||||
var OP_findpropstrict = 0x5D;
|
||||
var OP_findproperty = 0x5E;
|
||||
var OP_finddef = 0x5F;
|
||||
var OP_getlex = 0x60;
|
||||
var OP_setproperty = 0x61;
|
||||
var OP_getlocal = 0x62;
|
||||
var OP_setlocal = 0x63;
|
||||
var OP_getglobalscope = 0x64;
|
||||
var OP_getscopeobject = 0x65;
|
||||
var OP_getproperty = 0x66;
|
||||
var OP_getouterscope = 0x67;
|
||||
var OP_initproperty = 0x68;
|
||||
var OP_setpropertylate = 0x69;
|
||||
var OP_deleteproperty = 0x6A;
|
||||
var OP_deletepropertylate = 0x6B;
|
||||
var OP_getslot = 0x6C;
|
||||
var OP_setslot = 0x6D;
|
||||
var OP_getglobalslot = 0x6E;
|
||||
var OP_setglobalslot = 0x6F;
|
||||
var OP_convert_s = 0x70;
|
||||
var OP_esc_xelem = 0x71;
|
||||
var OP_esc_xattr = 0x72;
|
||||
var OP_convert_i = 0x73;
|
||||
var OP_convert_u = 0x74;
|
||||
var OP_convert_d = 0x75;
|
||||
var OP_convert_b = 0x76;
|
||||
var OP_convert_o = 0x77;
|
||||
var OP_checkfilter = 0x78;
|
||||
var OP_convert_f = 0x79;
|
||||
var OP_unplus = 0x7a;
|
||||
var OP_convert_f4 = 0x7b;
|
||||
var OP_coerce = 0x80;
|
||||
var OP_coerce_b = 0x81;
|
||||
var OP_coerce_a = 0x82;
|
||||
var OP_coerce_i = 0x83;
|
||||
var OP_coerce_d = 0x84;
|
||||
var OP_coerce_s = 0x85;
|
||||
var OP_astype = 0x86;
|
||||
var OP_astypelate = 0x87;
|
||||
var OP_coerce_u = 0x88;
|
||||
var OP_coerce_o = 0x89;
|
||||
var OP_negate = 0x90;
|
||||
var OP_increment = 0x91;
|
||||
var OP_inclocal = 0x92;
|
||||
var OP_decrement = 0x93;
|
||||
var OP_declocal = 0x94;
|
||||
var OP_typeof = 0x95;
|
||||
var OP_not = 0x96;
|
||||
var OP_bitnot = 0x97;
|
||||
var OP_add = 0xA0;
|
||||
var OP_subtract = 0xA1;
|
||||
var OP_multiply = 0xA2;
|
||||
var OP_divide = 0xA3;
|
||||
var OP_modulo = 0xA4;
|
||||
var OP_lshift = 0xA5;
|
||||
var OP_rshift = 0xA6;
|
||||
var OP_urshift = 0xA7;
|
||||
var OP_bitand = 0xA8;
|
||||
var OP_bitor = 0xA9;
|
||||
var OP_bitxor = 0xAA;
|
||||
var OP_equals = 0xAB;
|
||||
var OP_strictequals = 0xAC;
|
||||
var OP_lessthan = 0xAD;
|
||||
var OP_lessequals = 0xAE;
|
||||
var OP_greaterthan = 0xAF;
|
||||
var OP_greaterequals = 0xB0;
|
||||
var OP_instanceof = 0xB1;
|
||||
var OP_istype = 0xB2;
|
||||
var OP_istypelate = 0xB3;
|
||||
var OP_in = 0xB4;
|
||||
var OP_increment_i = 0xC0;
|
||||
var OP_decrement_i = 0xC1;
|
||||
var OP_inclocal_i = 0xC2;
|
||||
var OP_declocal_i = 0xC3;
|
||||
var OP_negate_i = 0xC4;
|
||||
var OP_add_i = 0xC5;
|
||||
var OP_subtract_i = 0xC6;
|
||||
var OP_multiply_i = 0xC7;
|
||||
var OP_getlocal0 = 0xD0;
|
||||
var OP_getlocal1 = 0xD1;
|
||||
var OP_getlocal2 = 0xD2;
|
||||
var OP_getlocal3 = 0xD3;
|
||||
var OP_setlocal0 = 0xD4;
|
||||
var OP_setlocal1 = 0xD5;
|
||||
var OP_setlocal2 = 0xD6;
|
||||
var OP_setlocal3 = 0xD7;
|
||||
var OP_invalid = 0xED;
|
||||
var OP_debug = 0xEF;
|
||||
var OP_debugline = 0xF0;
|
||||
var OP_debugfile = 0xF1;
|
||||
var OP_bkptline = 0xF2;
|
||||
var OP_timestamp = 0xF3;
|
||||
|
||||
const INT_MIN_VALUE = -0x80000000;
|
||||
const INT_MAX_VALUE = 0x7fffffff;
|
||||
const UINT_MIN_VALUE = 0;
|
||||
const UINT_MAX_VALUE = 0xffffffff;
|
||||
var INT_MIN_VALUE = -0x80000000;
|
||||
var INT_MAX_VALUE = 0x7fffffff;
|
||||
var UINT_MIN_VALUE = 0;
|
||||
var UINT_MAX_VALUE = 0xffffffff;
|
||||
|
|
|
@ -242,8 +242,8 @@ var SourceTracer = (function () {
|
|||
|
||||
SourceTracer.prototype = {
|
||||
traceTraits: function traceTraits(traits, isStatic, inInterfaceNamespace) {
|
||||
const writer = this.writer;
|
||||
const tracer = this;
|
||||
var writer = this.writer;
|
||||
var tracer = this;
|
||||
|
||||
traits.forEach(function (trait) {
|
||||
var str;
|
||||
|
@ -316,7 +316,7 @@ var SourceTracer = (function () {
|
|||
},
|
||||
|
||||
traceClassStub2: function traceClassStub(trait) {
|
||||
const writer = this.writer;
|
||||
var writer = this.writer;
|
||||
|
||||
var ci = trait.classInfo;
|
||||
var ii = ci.instanceInfo;
|
||||
|
@ -379,7 +379,7 @@ var SourceTracer = (function () {
|
|||
},
|
||||
|
||||
traceClassStub: function traceClassStub(trait) {
|
||||
const writer = this.writer;
|
||||
var writer = this.writer;
|
||||
|
||||
var ci = trait.classInfo;
|
||||
var ii = ci.instanceInfo;
|
||||
|
@ -486,7 +486,7 @@ var SourceTracer = (function () {
|
|||
},
|
||||
|
||||
traceClass: function traceClass(ci) {
|
||||
const writer = this.writer;
|
||||
var writer = this.writer;
|
||||
|
||||
var ii = ci.instanceInfo;
|
||||
var name = ii.name;
|
||||
|
@ -521,7 +521,7 @@ var SourceTracer = (function () {
|
|||
},
|
||||
|
||||
traceMetadata: function traceMetadata(metadata) {
|
||||
const writer = this.writer;
|
||||
var writer = this.writer;
|
||||
|
||||
for (var key in metadata) {
|
||||
if (metadata.hasOwnProperty(key)) {
|
||||
|
|
|
@ -2,7 +2,7 @@ var domainOptions = systemOptions.register(new OptionSet("Domain Options"));
|
|||
var traceClasses = domainOptions.register(new Option("tc", "traceClasses", "boolean", false, "trace class creation"));
|
||||
var traceDomain = domainOptions.register(new Option("tdpa", "traceDomain", "boolean", false, "trace domain property access"));
|
||||
|
||||
const EXECUTION_MODE = {
|
||||
var EXECUTION_MODE = {
|
||||
INTERPRET: 0x1,
|
||||
COMPILE: 0x2
|
||||
};
|
||||
|
@ -44,12 +44,17 @@ var Domain = (function () {
|
|||
} else {
|
||||
this.system = this;
|
||||
|
||||
var OWN_INITIALIZE = 0x1;
|
||||
var SUPER_INITIALIZE = 0x2;
|
||||
|
||||
var Class = this.Class = function Class(name, instance, callable) {
|
||||
this.debugName = name;
|
||||
|
||||
if (instance) {
|
||||
release || assert(instance.prototype);
|
||||
this.instance = instance;
|
||||
this.instanceNoInitialize = instance;
|
||||
this.hasInitialize = 0;
|
||||
}
|
||||
|
||||
if (!callable) {
|
||||
|
@ -77,12 +82,12 @@ var Domain = (function () {
|
|||
var c = this;
|
||||
var initializes = [];
|
||||
while (c) {
|
||||
var s = c.instance.prototype.initialize;
|
||||
if (s) {
|
||||
initializes.push(s);
|
||||
if (c.hasInitialize & OWN_INITIALIZE) {
|
||||
initializes.push(c.instance.prototype.initialize);
|
||||
}
|
||||
c = c.baseClass;
|
||||
}
|
||||
var s;
|
||||
while (s = initializes.pop()) {
|
||||
s.call(obj);
|
||||
}
|
||||
|
@ -129,6 +134,15 @@ var Domain = (function () {
|
|||
extend: function (baseClass) {
|
||||
this.baseClass = baseClass;
|
||||
this.dynamicPrototype = Object.create(baseClass.dynamicPrototype);
|
||||
if (baseClass.hasInitialize) {
|
||||
var instanceNoInitialize = this.instance;
|
||||
var self = this;
|
||||
this.instance = function () {
|
||||
self.initializeInstance(this);
|
||||
instanceNoInitialize.apply(this, arguments);
|
||||
};
|
||||
this.hasInitialize |= SUPER_INITIALIZE;
|
||||
}
|
||||
this.instance.prototype = Object.create(this.dynamicPrototype);
|
||||
defineNonEnumerableProperty(this.dynamicPrototype, "public$constructor", this);
|
||||
defineReadOnlyProperty(this.instance.prototype, "class", this);
|
||||
|
@ -155,6 +169,19 @@ var Domain = (function () {
|
|||
}
|
||||
}
|
||||
|
||||
if (definition.initialize) {
|
||||
if (!this.hasInitialize) {
|
||||
var instanceNoInitialize = this.instance;
|
||||
var self = this;
|
||||
this.instance = function () {
|
||||
self.initializeInstance(this);
|
||||
instanceNoInitialize.apply(this, arguments);
|
||||
};
|
||||
this.instance.prototype = instanceNoInitialize.prototype;
|
||||
}
|
||||
this.hasInitialize |= OWN_INITIALIZE;
|
||||
}
|
||||
|
||||
var proto = this.dynamicPrototype;
|
||||
var keys = Object.keys(definition);
|
||||
for (var i = 0, j = keys.length; i < j; i++) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const Errors = {
|
||||
var Errors = {
|
||||
OutOfMemoryError : {code: 1000, message: "The system is out of memory."},
|
||||
NotImplementedError : {code: 1001, message: "The method %1 is not implemented."},
|
||||
InvalidPrecisionError : {code: 1002, message: "Number.toPrecision has a range of 1 to 21. Number.toFixed and Number.toExponential have a range of 0 to 20. Specified value is not within expected range."},
|
||||
|
@ -139,6 +139,7 @@ const Errors = {
|
|||
NullPointerError : {code: 2007, message: "Parameter %1 must be non-null."},
|
||||
InvalidEnumError : {code: 2008, message: "Parameter %1 must be one of the accepted values."},
|
||||
CantInstantiateError : {code: 2012, message: "%1 class cannot be instantiated."},
|
||||
ArgumentError : {code: 2015, message: "Invalid BitmapData."},
|
||||
EOFError : {code: 2030, message: "End of file was encountered."},
|
||||
CompressedDataError : {code: 2058, message: "There was an error decompressing the data."},
|
||||
EmptyStringError : {code: 2085, message: "Parameter %1 must be non-empty string."},
|
||||
|
|
|
@ -11,7 +11,7 @@ var Interpreter = (function () {
|
|||
this.abc = abc;
|
||||
}
|
||||
|
||||
const Apslice = [].slice;
|
||||
var Apslice = [].slice;
|
||||
|
||||
function applyNew(constructor, args) {
|
||||
return new (Function.bind.apply(constructor.instance, [,].concat(args)));
|
||||
|
@ -41,16 +41,16 @@ var Interpreter = (function () {
|
|||
interpretMethod: function interpretMethod($this, method, savedScope, args) {
|
||||
release || assert(method.analysis);
|
||||
Counter.count("Interpret Method");
|
||||
const abc = this.abc;
|
||||
const ints = abc.constantPool.ints;
|
||||
const uints = abc.constantPool.uints;
|
||||
const doubles = abc.constantPool.doubles;
|
||||
const strings = abc.constantPool.strings;
|
||||
const methods = abc.methods;
|
||||
const multinames = abc.constantPool.multinames;
|
||||
const runtime = abc.runtime;
|
||||
const domain = abc.domain;
|
||||
const rtstack = Runtime.stack;
|
||||
var abc = this.abc;
|
||||
var ints = abc.constantPool.ints;
|
||||
var uints = abc.constantPool.uints;
|
||||
var doubles = abc.constantPool.doubles;
|
||||
var strings = abc.constantPool.strings;
|
||||
var methods = abc.methods;
|
||||
var multinames = abc.constantPool.multinames;
|
||||
var runtime = abc.runtime;
|
||||
var domain = abc.domain;
|
||||
var rtstack = Runtime.stack;
|
||||
|
||||
var exceptions = method.exceptions;
|
||||
|
||||
|
@ -322,7 +322,7 @@ var Interpreter = (function () {
|
|||
case OP_constructsuper:
|
||||
args = stack.popMany(bc.argCount);
|
||||
obj = stack.pop();
|
||||
savedScope.object.baseClass.instance.apply(obj, args);
|
||||
savedScope.object.baseClass.instanceNoInitialize.apply(obj, args);
|
||||
break;
|
||||
case OP_constructprop:
|
||||
args = stack.popMany(bc.argCount);
|
||||
|
|
|
@ -175,7 +175,7 @@
|
|||
* instantiation. It is called in the usual order for its super classes,
|
||||
* i.e. super first.
|
||||
*
|
||||
* Suppose c is an instance of C, is has access to the definitions:
|
||||
* Suppose c is an instance of C, it has access to the definitions:
|
||||
*
|
||||
* c.m(); // calls m
|
||||
* print(c.x); // calls the getter
|
||||
|
@ -206,10 +206,10 @@ defineReadOnlyProperty(Object.prototype, "isInstance", function () {
|
|||
});
|
||||
*/
|
||||
|
||||
const natives = (function () {
|
||||
var natives = (function () {
|
||||
|
||||
const C = Domain.passthroughCallable;
|
||||
const CC = Domain.constructingCallable;
|
||||
var C = Domain.passthroughCallable;
|
||||
var CC = Domain.constructingCallable;
|
||||
|
||||
/**
|
||||
* Object.as
|
||||
|
@ -472,7 +472,7 @@ const natives = (function () {
|
|||
* Vector.as
|
||||
*/
|
||||
|
||||
const VM_VECTOR_IS_FIXED = "vm vector is fixed";
|
||||
var VM_VECTOR_IS_FIXED = "vm vector is fixed";
|
||||
|
||||
/**
|
||||
* Creates a typed Vector class. It steals the Array object from a new global
|
||||
|
@ -485,7 +485,7 @@ const natives = (function () {
|
|||
|
||||
// Breaks semantics with bounds checking for now.
|
||||
if (type) {
|
||||
const coerce = type.coerce;
|
||||
var coerce = type.coerce;
|
||||
TAp.indexGet = function (i) { return this[i]; };
|
||||
TAp.indexSet = function (i, v) { this[i] = coerce(v); };
|
||||
}
|
||||
|
@ -699,11 +699,7 @@ const natives = (function () {
|
|||
};
|
||||
|
||||
return function (runtime, scope, instance, baseClass) {
|
||||
var instance2 = function () {
|
||||
this.class.initializeInstance(this);
|
||||
instance.apply(this, arguments);
|
||||
};
|
||||
var c = new runtime.domain.system.Class(name, instance2, CC(instance2));
|
||||
var c = new runtime.domain.system.Class(name, instance);
|
||||
c.extend(baseClass);
|
||||
if (name === "Error") {
|
||||
c.link(ErrorDefinition);
|
||||
|
@ -930,11 +926,10 @@ const natives = (function () {
|
|||
*/
|
||||
function ByteArrayClass(runtime, scope, instance, baseClass) {
|
||||
/* The initial size of the backing, in bytes. Doubled every OOM. */
|
||||
const INITIAL_SIZE = 128;
|
||||
var INITIAL_SIZE = 128;
|
||||
|
||||
function ByteArray() {
|
||||
var a = new ArrayBuffer(INITIAL_SIZE);
|
||||
this.a = a;
|
||||
this.a = new ArrayBuffer(INITIAL_SIZE);
|
||||
this.length = 0;
|
||||
this.position = 0;
|
||||
this.cacheViews();
|
||||
|
@ -1033,7 +1028,7 @@ const natives = (function () {
|
|||
BAp.writeBoolean = function writeBoolean(v) {
|
||||
var len = this.position + 1;
|
||||
this.ensureCapacity(len);
|
||||
this.int8v[this.position++] = !!v ? 1 : 0;
|
||||
this.int8v[this.position++] = v ? 1 : 0;
|
||||
if (len > this.length) {
|
||||
this.length = len;
|
||||
}
|
||||
|
|
|
@ -136,10 +136,10 @@ function parseTraits(abc, stream, holder) {
|
|||
|
||||
var Trait = (function () {
|
||||
function trait(abc, stream, holder) {
|
||||
const constantPool = abc.constantPool;
|
||||
const methods = abc.methods;
|
||||
const classes = abc.classes;
|
||||
const metadata = abc.metadata;
|
||||
var constantPool = abc.constantPool;
|
||||
var methods = abc.methods;
|
||||
var classes = abc.classes;
|
||||
var metadata = abc.metadata;
|
||||
|
||||
this.holder = holder;
|
||||
this.name = constantPool.multinames[stream.readU30()];
|
||||
|
@ -254,8 +254,8 @@ var Namespace = (function () {
|
|||
* According to Tamarin, this is 0xe000 + 660, with 660 being an "odd legacy
|
||||
* wart".
|
||||
*/
|
||||
const MIN_API_MARK = 0xe294;
|
||||
const MAX_API_MARK = 0xf8ff;
|
||||
var MIN_API_MARK = 0xe294;
|
||||
var MAX_API_MARK = 0xf8ff;
|
||||
|
||||
function namespace(kind, uri) {
|
||||
if (kind !== undefined) {
|
||||
|
@ -435,9 +435,9 @@ var Namespace = (function () {
|
|||
*/
|
||||
|
||||
var Multiname = (function () {
|
||||
const ATTRIBUTE = 0x01;
|
||||
const RUNTIME_NAMESPACE = 0x02;
|
||||
const RUNTIME_NAME = 0x04;
|
||||
var ATTRIBUTE = 0x01;
|
||||
var RUNTIME_NAMESPACE = 0x02;
|
||||
var RUNTIME_NAME = 0x04;
|
||||
var nextID = 1;
|
||||
function multiname(namespaces, name, flags) {
|
||||
this.id = nextID ++;
|
||||
|
@ -871,7 +871,7 @@ var MethodInfo = (function () {
|
|||
}
|
||||
|
||||
function methodInfo(abc, stream) {
|
||||
const constantPool = abc.constantPool;
|
||||
var constantPool = abc.constantPool;
|
||||
|
||||
var parameterCount = stream.readU30();
|
||||
var returnType = constantPool.multinames[stream.readU30()];
|
||||
|
@ -932,7 +932,7 @@ var MethodInfo = (function () {
|
|||
};
|
||||
|
||||
function parseException(abc, stream) {
|
||||
const multinames = abc.constantPool.multinames;
|
||||
var multinames = abc.constantPool.multinames;
|
||||
|
||||
var ex = {
|
||||
start: stream.readU30(),
|
||||
|
@ -947,8 +947,8 @@ var MethodInfo = (function () {
|
|||
}
|
||||
|
||||
methodInfo.parseBody = function parseBody(abc, stream) {
|
||||
const constantPool = abc.constantPool;
|
||||
const methods = abc.methods;
|
||||
var constantPool = abc.constantPool;
|
||||
var methods = abc.methods;
|
||||
|
||||
var info = methods[stream.readU30()];
|
||||
release || assert(!info.isNative());
|
||||
|
@ -976,7 +976,7 @@ var MethodInfo = (function () {
|
|||
var MetaDataInfo = (function () {
|
||||
|
||||
function metaDataInfo(abc, stream) {
|
||||
const strings = abc.constantPool.strings;
|
||||
var strings = abc.constantPool.strings;
|
||||
this.tagName = strings[stream.readU30()];
|
||||
|
||||
var itemCount = stream.readU30();
|
||||
|
@ -1021,8 +1021,8 @@ var InstanceInfo = (function () {
|
|||
var nextID = 1;
|
||||
function instanceInfo(abc, stream) {
|
||||
this.id = nextID ++;
|
||||
const constantPool = abc.constantPool;
|
||||
const methods = abc.methods;
|
||||
var constantPool = abc.constantPool;
|
||||
var methods = abc.methods;
|
||||
|
||||
this.name = constantPool.multinames[stream.readU30()];
|
||||
release || assert(Multiname.isQName(this.name));
|
||||
|
|
|
@ -8,31 +8,31 @@ var compileOnly = compilerOptions.register(new Option("co", "compileOnly", "numb
|
|||
var compileUntil = compilerOptions.register(new Option("cu", "compileUntil", "number", -1, "Compiles only until a function number."));
|
||||
var debuggerMode = runtimeOptions.register(new Option("dm", "debuggerMode", "boolean", false, "matches avm2 debugger build semantics"));
|
||||
|
||||
const jsGlobal = (function() { return this || (1, eval)('this'); })();
|
||||
var jsGlobal = (function() { return this || (1, eval)('this'); })();
|
||||
|
||||
const VM_SLOTS = "vm slots";
|
||||
const VM_LENGTH = "vm length";
|
||||
const VM_BINDINGS = "vm bindings";
|
||||
const VM_NATIVE_PROTOTYPE_FLAG = "vm native prototype";
|
||||
const VM_ENUMERATION_KEYS = "vm enumeration keys";
|
||||
const VM_OPEN_METHODS = "vm open methods";
|
||||
const VM_NEXT_NAME = "vm next name";
|
||||
const VM_NEXT_NAME_INDEX = "vm next name index";
|
||||
const VM_UNSAFE_CLASSES = ["Shumway"];
|
||||
var VM_SLOTS = "vm slots";
|
||||
var VM_LENGTH = "vm length";
|
||||
var VM_BINDINGS = "vm bindings";
|
||||
var VM_NATIVE_PROTOTYPE_FLAG = "vm native prototype";
|
||||
var VM_ENUMERATION_KEYS = "vm enumeration keys";
|
||||
var VM_OPEN_METHODS = "vm open methods";
|
||||
var VM_NEXT_NAME = "vm next name";
|
||||
var VM_NEXT_NAME_INDEX = "vm next name index";
|
||||
var VM_UNSAFE_CLASSES = ["Shumway"];
|
||||
|
||||
const VM_NATIVE_BUILTINS = [Object, Number, Boolean, String, Array, Date, RegExp];
|
||||
var VM_NATIVE_BUILTINS = [Object, Number, Boolean, String, Array, Date, RegExp];
|
||||
|
||||
var VM_NATIVE_BUILTIN_SURROGATES = [
|
||||
{ object: Object, methods: ["toString", "valueOf"] },
|
||||
{ object: Function, methods: ["toString", "valueOf"] }
|
||||
];
|
||||
|
||||
const VM_NATIVE_BUILTIN_ORIGINALS = "vm originals";
|
||||
var VM_NATIVE_BUILTIN_ORIGINALS = "vm originals";
|
||||
|
||||
var $M = [];
|
||||
|
||||
function initializeGlobalObject(global) {
|
||||
const PUBLIC_MANGLED = /^public\$/;
|
||||
var PUBLIC_MANGLED = /^public\$/;
|
||||
|
||||
function getEnumerationKeys(obj) {
|
||||
var keys = [];
|
||||
|
@ -161,7 +161,7 @@ function coerce(value, type) {
|
|||
return type.coerce(value);
|
||||
}
|
||||
|
||||
if (isNullOrUndefiend(value)) {
|
||||
if (isNullOrUndefined(value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -787,11 +787,11 @@ var Runtime = (function () {
|
|||
* compiler bakes it in as a constant which should be much more efficient.
|
||||
*/
|
||||
runtime.prototype.createFunction = function createFunction(methodInfo, scope, hasDynamicScope) {
|
||||
const mi = methodInfo;
|
||||
var mi = methodInfo;
|
||||
release || assert(!mi.isNative(), "Method should have a builtin: ", mi.name);
|
||||
|
||||
var hasDefaults = false;
|
||||
const defaults = mi.parameters.map(function (p) {
|
||||
var defaults = mi.parameters.map(function (p) {
|
||||
if (p.value !== undefined) {
|
||||
hasDefaults = true;
|
||||
}
|
||||
|
@ -814,7 +814,7 @@ var Runtime = (function () {
|
|||
return fn;
|
||||
}
|
||||
|
||||
const mode = this.domain.mode;
|
||||
var mode = this.domain.mode;
|
||||
|
||||
// We use not having an analysis to mean "not initialized".
|
||||
if (!mi.analysis) {
|
||||
|
@ -955,7 +955,7 @@ var Runtime = (function () {
|
|||
return this.createInterface(classInfo);
|
||||
}
|
||||
|
||||
const domain = this.domain;
|
||||
var domain = this.domain;
|
||||
|
||||
var className = Multiname.getName(ii.name);
|
||||
if (traceExecution.value) {
|
||||
|
@ -1011,7 +1011,7 @@ var Runtime = (function () {
|
|||
cls.scope = scope;
|
||||
scope.object = cls;
|
||||
cls.extend(baseClass);
|
||||
this.applyTraits(instance.prototype, scope, baseBindings, ii.traits, null, true);
|
||||
this.applyTraits(cls.instance.prototype, scope, baseBindings, ii.traits, null, true);
|
||||
this.applyTraits(cls, scope, null, ci.traits, null, false);
|
||||
}
|
||||
|
||||
|
@ -1136,8 +1136,8 @@ var Runtime = (function () {
|
|||
};
|
||||
|
||||
runtime.prototype.applyTraits = function applyTraits(obj, scope, base, traits, classNatives, delayBinding) {
|
||||
const runtime = this;
|
||||
const domain = this.domain;
|
||||
var runtime = this;
|
||||
var domain = this.domain;
|
||||
|
||||
function makeClosure(trait) {
|
||||
release || assert(scope);
|
||||
|
@ -1246,7 +1246,7 @@ var Runtime = (function () {
|
|||
} else if (trait.isMethod()) {
|
||||
// FIXME: Breaking compat with AS and using .bind here instead of the
|
||||
// MethodClosure class to work around a SpiderMonkey bug 771871.
|
||||
const MethodClosureClass = domain.system.MethodClosureClass;
|
||||
var MethodClosureClass = domain.system.MethodClosureClass;
|
||||
|
||||
var closure;
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
abc/
|
||||
tamarin/
|
||||
acceptance/
|
||||
regress/*/*.abc
|
||||
hello-world.abc
|
||||
|
|
|
@ -82,7 +82,7 @@ function defineNonEnumerableProperty(obj, name, value) {
|
|||
enumerable: false });
|
||||
}
|
||||
|
||||
function isNullOrUndefiend(value) {
|
||||
function isNullOrUndefined(value) {
|
||||
return value === null || value === undefined;
|
||||
}
|
||||
|
||||
|
@ -269,7 +269,7 @@ function utf8decode(str) {
|
|||
|
||||
function utf8encode(bytes) {
|
||||
var str = "";
|
||||
const fcc = String.fromCharCode;
|
||||
var fcc = String.fromCharCode;
|
||||
for (var i = 0, j = bytes.length; i < j; i++) {
|
||||
var b = bytes[i];
|
||||
str += b <= 0x7f ? b === 0x25 ? "%25" : fcc(b) : "%" + b.toString(16).toUpperCase();
|
||||
|
@ -304,10 +304,10 @@ function bitCount(i) {
|
|||
* If the set fits in a single word, a single int is used.
|
||||
*/
|
||||
function BitSetFunctor(length) {
|
||||
const ADDRESS_BITS_PER_WORD = 5;
|
||||
const BITS_PER_WORD = 1 << ADDRESS_BITS_PER_WORD;
|
||||
const BIT_INDEX_MASK = BITS_PER_WORD - 1;
|
||||
const SIZE = ((length + (BITS_PER_WORD - 1)) >> ADDRESS_BITS_PER_WORD) << ADDRESS_BITS_PER_WORD;
|
||||
var ADDRESS_BITS_PER_WORD = 5;
|
||||
var BITS_PER_WORD = 1 << ADDRESS_BITS_PER_WORD;
|
||||
var BIT_INDEX_MASK = BITS_PER_WORD - 1;
|
||||
var SIZE = ((length + (BITS_PER_WORD - 1)) >> ADDRESS_BITS_PER_WORD) << ADDRESS_BITS_PER_WORD;
|
||||
|
||||
function BitSet() {
|
||||
/* How many bits are set. */
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
var BitmapDefinition = (function () {
|
||||
var def = {
|
||||
__class__: 'flash.display.Bitmap',
|
||||
draw : function(ctx, ratio) {
|
||||
ctx.drawImage(this._bitmapData._canvas, 0, 0);
|
||||
}
|
||||
};
|
||||
|
||||
def.__glue__ = {
|
||||
native: {
|
||||
instance: {
|
||||
ctor : function(bitmapData, pixelSnapping, smoothing) {
|
||||
this._bitmapData = bitmapData;
|
||||
this._pixelSnapping = pixelSnapping;
|
||||
this._smoothing = smoothing;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return def;
|
||||
}).call(this);
|
|
@ -1,3 +1,144 @@
|
|||
const BitmapDataDefinition = {
|
||||
__class__: 'flash.display.BitmapData'
|
||||
var BitmapDataDefinition = (function () {
|
||||
var def = {
|
||||
__class__: 'flash.display.BitmapData',
|
||||
|
||||
initialize: function () {
|
||||
var s = this.symbol;
|
||||
if (s) {
|
||||
this.ctor(s.width, s.height);
|
||||
this._ctx.drawImage(s.img, 0, 0);
|
||||
}
|
||||
},
|
||||
|
||||
_checkCanvas: function() {
|
||||
if (this._drawable === null)
|
||||
throw ArgumentError();
|
||||
},
|
||||
|
||||
ctor : function(width, height, transparent, backgroundColor) {
|
||||
if (isNaN(width + height) || width <= 0 || height <= 0)
|
||||
throw ArgumentError();
|
||||
|
||||
this._transparent = !!transparent;
|
||||
var canvas = document.createElement('canvas');
|
||||
this._ctx = canvas.getContext('2d');
|
||||
canvas.width = width | 0;
|
||||
canvas.height = height | 0;
|
||||
this._drawable = canvas;
|
||||
this._backgroundColor = backgroundColor;
|
||||
|
||||
if (!transparent || backgroundColor | 0)
|
||||
this.fillRect(new flash.geom.Rectangle(0, 0, width | 0, height | 0), backgroundColor);
|
||||
},
|
||||
dispose: function() {
|
||||
this._ctx = null;
|
||||
this._drawable.width = 0;
|
||||
this._drawable.height = 0;
|
||||
this._drawable = null;
|
||||
},
|
||||
draw : function(source, matrix, colorTransform, blendMode, clipRect) {
|
||||
this._checkCanvas();
|
||||
this._ctx.save();
|
||||
this._ctx.beginPath();
|
||||
this._ctx.rect(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
|
||||
this._ctx.clip();
|
||||
renderDisplayObject(source, this._ctx, matrix, colorTransform);
|
||||
this._ctx.restore();
|
||||
},
|
||||
fillRect : function(rect, color) {
|
||||
this._checkCanvas();
|
||||
if (!this._transparent) {
|
||||
color |= 0xff000000 >>> 0;
|
||||
}
|
||||
var ctx = this._ctx;
|
||||
ctx.fillStyle = ARGBtoCSSColor(color);
|
||||
ctx.fillRect(rect.x, rect.y, rect.width, rect.height);
|
||||
},
|
||||
getPixel : function(x, y) {
|
||||
this._checkCanvas();
|
||||
var data = this._ctx.getImageData(x, y, 1, 1);
|
||||
return dataToRGB(data);
|
||||
},
|
||||
getPixel32 : function(x, y) {
|
||||
this._checkCanvas();
|
||||
var data = this._ctx.getImageData(x, y, 1, 1);
|
||||
return dataToARGB(data);
|
||||
},
|
||||
setPixel : function(x, y, color) {
|
||||
this.fillRect({ x: x, y: y, width: 1, height: 1 }, color | 0xFF000000);
|
||||
},
|
||||
setPixel32 : function(x, y, color) {
|
||||
this.fillRect({ x: x, y: y, width: 1, height: 1 }, color);
|
||||
},
|
||||
clone : function() {
|
||||
this._checkCanvas();
|
||||
var bd = new flash.display.BitmapData(this._drawable.width, this._drawable.height, true, 0);
|
||||
bd._ctx.drawImage(this._drawable, 0, 0);
|
||||
return bd;
|
||||
},
|
||||
scroll : function(x, y) {
|
||||
this._checkCanvas();
|
||||
this._ctx.draw(this._drawable, x, y);
|
||||
this._ctx.save();
|
||||
this._ctx.fillStyle = ARGBtoCSSColor(this._backgroundColor);
|
||||
var w = this._drawable.width;
|
||||
var h = this._drawable.height;
|
||||
if (x > 0) {
|
||||
this._ctx.fillRect(0, 0, x, h);
|
||||
} else if (x < 0) {
|
||||
this._ctx.fillRect(x, 0, w, h);
|
||||
}
|
||||
if (y > 0) {
|
||||
this._ctx.fillRect(x, y, w, h);
|
||||
} else if (y < 0) {
|
||||
this._ctx.fillRect(0, y, w, h);
|
||||
}
|
||||
this._ctx.restore();
|
||||
},
|
||||
|
||||
get width() {
|
||||
return this._drawable.width;
|
||||
},
|
||||
|
||||
get height() {
|
||||
return this._drawable.height;
|
||||
},
|
||||
};
|
||||
|
||||
var desc = Object.getOwnPropertyDescriptor;
|
||||
|
||||
def.__glue__ = {
|
||||
native: {
|
||||
instance: {
|
||||
ctor : def.ctor,
|
||||
fillRect : def.fillRect,
|
||||
dispose : def.dispose,
|
||||
getPixel : def.getPixel,
|
||||
getPixel32 : def.getPixel32,
|
||||
setPixel : def.setPixel,
|
||||
setPixel32 : def.setPixel32,
|
||||
draw : def.draw,
|
||||
clone : def.clone,
|
||||
scroll : def.scroll,
|
||||
width : desc(def, "width"),
|
||||
height : desc(def, "height"),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return def;
|
||||
}).call(this);
|
||||
|
||||
function dataToRGB(data) {
|
||||
return data[0] << 24 | data[1] << 16 | data[2];
|
||||
}
|
||||
function dataToARGB(data) {
|
||||
return data[3] << 32 | dataToRGB(data);
|
||||
}
|
||||
function ARGBtoRGBA(argb) {
|
||||
return (argb >>> 24 | argb << 8) >>> 0;
|
||||
}
|
||||
function ARGBtoCSSColor(argb) {
|
||||
return 'rgba(' + (argb >>> 16 & 0xff) + ',' + (argb >>> 8 & 0xff) + ',' +
|
||||
(argb & 0xff) + ',' + (argb >>> 24 & 0xff) / 0xff + ')';
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const DisplayObjectDefinition = (function () {
|
||||
var DisplayObjectDefinition = (function () {
|
||||
var BLEND_MODE_ADD = 'add';
|
||||
var BLEND_MODE_ALPHA = 'alpha';
|
||||
var BLEND_MODE_DARKEN = 'darken';
|
||||
|
@ -21,18 +21,26 @@ const DisplayObjectDefinition = (function () {
|
|||
initialize: function () {
|
||||
this._alpha = 1;
|
||||
this._animated = false;
|
||||
this._cacheAsBitmap = false;
|
||||
this._control = document.createElement('div');
|
||||
this._bbox = null;
|
||||
this._bounds = null;
|
||||
this._cacheAsBitmap = false;
|
||||
this._children = [];
|
||||
this._control = document.createElement('div');
|
||||
this._clipDepth = 0;
|
||||
this._currentTransform = null;
|
||||
this._cxform = null;
|
||||
this._dirtyArea = null;
|
||||
this._graphics = null;
|
||||
this._loaderInfo = null;
|
||||
this._mouseChildren = true;
|
||||
this._mouseOver = false;
|
||||
this._mouseX = 0;
|
||||
this._mouseY = 0;
|
||||
this._name = null;
|
||||
this._opaqueBackground = null;
|
||||
this._owned = false;
|
||||
this._parent = null;
|
||||
this._revision = 0;
|
||||
this._root = null;
|
||||
this._rotation = 0;
|
||||
this._scaleX = 1;
|
||||
|
@ -42,12 +50,139 @@ const DisplayObjectDefinition = (function () {
|
|||
this._visible = true;
|
||||
this._x = 0;
|
||||
this._y = 0;
|
||||
this._updateTransformMatrix();
|
||||
|
||||
var s = this.symbol;
|
||||
if (s) {
|
||||
this._bbox = s.bbox || null;
|
||||
this._children = s.children || [];
|
||||
}
|
||||
|
||||
this._updateCurrentTransform();
|
||||
},
|
||||
|
||||
_applyCurrentInverseTransform: function (point, targetCoordSpace) {
|
||||
if (this._parent !== this._stage && this._parent !== targetCoordSpace)
|
||||
this._parent._applyCurrentInverseTransform(point);
|
||||
|
||||
var m = this._currentTransform;
|
||||
var x = point.x - m.tx;
|
||||
var y = point.y - m.ty;
|
||||
var d = 1 / (m.a * m.d - m.b * m.c);
|
||||
point.x = (m.d * x - m.c * y) * d;
|
||||
point.y = (m.a * y - m.b * x) * d;
|
||||
},
|
||||
_applyCurrentTransform: function (point, targetCoordSpace) {
|
||||
var m = this._currentTransform;
|
||||
var x = point.x;
|
||||
var y = point.y;
|
||||
|
||||
point.x = m.a * x + m.c * y + m.tx;
|
||||
point.y = m.d * y + m.b * x + m.ty;
|
||||
|
||||
if (this._parent !== this._stage && this._parent !== targetCoordSpace)
|
||||
this._parent._applyCurrentTransform(point, targetCoordSpace);
|
||||
},
|
||||
_hitTest: function (use_xy, x, y, useShape, hitTestObject, ignoreChildren) {
|
||||
if (use_xy) {
|
||||
var pt = { x: x, y: y };
|
||||
this._applyCurrentInverseTransform(pt);
|
||||
|
||||
if (useShape) {
|
||||
if (this._graphics) {
|
||||
var scale = this._graphics._scale;
|
||||
if (scale !== 1) {
|
||||
pt.x /= scale;
|
||||
pt.y /= scale;
|
||||
}
|
||||
|
||||
var subpaths = this._graphics._subpaths;
|
||||
for (var i = 0, n = subpaths.length; i < n; i++) {
|
||||
var pathTracker = subpaths[i];
|
||||
var path = pathTracker.target;
|
||||
var hitCtx = path.__hitContext__;
|
||||
|
||||
if (hitCtx.isPointInPath(pt.x, pt.y))
|
||||
return true;
|
||||
|
||||
if (!path.strokeStyle)
|
||||
continue;
|
||||
|
||||
var drawingStyles = pathTracker.drawingStyles;
|
||||
if (hitCtx.mozIsPointInStroke) {
|
||||
hitCtx.strokeStyle = path.strokeStyle;
|
||||
for (var prop in drawingStyles)
|
||||
hitCtx[prop] = drawingStyles[prop];
|
||||
|
||||
if (hitCtx.mozIsPointInStroke(pt.x, pt.y))
|
||||
return true;
|
||||
} else {
|
||||
var strokeHitCtx = path._strokeHitContext;
|
||||
if (!strokeHitCtx) {
|
||||
var strokeHitCanvas = hitCtx.canvas.cloneNode();
|
||||
strokeHitCtx = strokeHitCanvas.getContext('2d');
|
||||
path._strokeHitContext = strokeHitCtx;
|
||||
pathTracker.strokeToPath(strokeHitCtx, {
|
||||
strokeWidth: drawingStyles.lineWidth,
|
||||
startCap: drawingStyles.lineCap,
|
||||
endCap: drawingStyles.lineCap,
|
||||
join: drawingStyles.lineJoin,
|
||||
miterLimit: drawingStyles.miterLimit
|
||||
});
|
||||
}
|
||||
if (strokeHitCtx.isPointInPath(pt.x, pt.y))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ignoreChildren) {
|
||||
var children = this._children;
|
||||
for (var i = 0, n = children.length; i < n; i++) {
|
||||
var child = children[i];
|
||||
if (child._hitTest(true, x, y, true))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
} else {
|
||||
var b = this.getBounds();
|
||||
return pt.x >= b.x && pt.x < b.x + b.width &&
|
||||
pt.y >= b.y && pt.y < b.y + b.height;
|
||||
}
|
||||
}
|
||||
|
||||
var b1 = this.getBounds();
|
||||
var b2 = hitTestObject.getBounds();
|
||||
var x = Math.max(b1.x, b2.x);
|
||||
var y = Math.max(b1.y, b2.y);
|
||||
var width = Math.min(b1.x + b1.width, b2.x + b2.width) - x;
|
||||
var height = Math.min(b1.y + b1.height, b2.y + b2.height) - y;
|
||||
return width > 0 && height > 0;
|
||||
},
|
||||
_markAsDirty: function() {
|
||||
if (!this._dirtyArea) {
|
||||
this._dirtyArea = this.getBounds();
|
||||
} else {
|
||||
this._dirtyArea = this.getBounds().union(this._dirtyArea);
|
||||
}
|
||||
this._bounds = null;
|
||||
},
|
||||
_updateCurrentTransform: function () {
|
||||
var rotation = this._rotation / 180 * Math.PI;
|
||||
var scaleX = this._scaleX;
|
||||
var scaleY = this._scaleY;
|
||||
var u = Math.cos(rotation);
|
||||
var v = Math.sin(rotation);
|
||||
|
||||
this._currentTransform = {
|
||||
a: u * scaleX,
|
||||
b: v * scaleX,
|
||||
c: -v * scaleY,
|
||||
d: u * scaleY,
|
||||
tx: this._x,
|
||||
ty: this._y
|
||||
};
|
||||
},
|
||||
|
||||
get accessibilityProperties() {
|
||||
|
@ -81,83 +216,6 @@ const DisplayObjectDefinition = (function () {
|
|||
set filters(val) {
|
||||
notImplemented();
|
||||
},
|
||||
getBounds: function (targetCoordSpace) {
|
||||
var bbox = this._bbox;
|
||||
|
||||
if (!bbox)
|
||||
return new flash.geom.Rectangle;
|
||||
|
||||
var p1 = {x: bbox.left, y: bbox.top};
|
||||
this._applyCurrentTransform(p1, targetCoordSpace);
|
||||
var p2 = {x: bbox.right, y: bbox.top};
|
||||
this._applyCurrentTransform(p2, targetCoordSpace);
|
||||
var p3 = {x: bbox.right, y: bbox.bottom};
|
||||
this._applyCurrentTransform(p3, targetCoordSpace);
|
||||
var p4 = {x: bbox.left, y: bbox.bottom};
|
||||
this._applyCurrentTransform(p4, targetCoordSpace);
|
||||
|
||||
var xMin = Math.min(p1.x, p2.x, p3.x, p4.x);
|
||||
var xMax = Math.max(p1.x, p2.x, p3.x, p4.x);
|
||||
var yMin = Math.min(p1.y, p2.y, p3.y, p4.y);
|
||||
var yMax = Math.max(p1.y, p2.y, p3.y, p4.y);
|
||||
|
||||
return new flash.geom.Rectangle(
|
||||
xMin,
|
||||
yMin,
|
||||
(xMax - xMin),
|
||||
(yMax - yMin)
|
||||
);
|
||||
},
|
||||
_updateTransformMatrix: function () {
|
||||
var rotation = this._rotation / 180 * Math.PI;
|
||||
var scaleX = this._scaleX;
|
||||
var scaleY = this._scaleY;
|
||||
var u = Math.cos(rotation);
|
||||
var v = Math.sin(rotation);
|
||||
|
||||
this._currentTransformMatrix = {
|
||||
a: u * scaleX,
|
||||
b: v * scaleX,
|
||||
c: -v * scaleY,
|
||||
d: u * scaleY,
|
||||
tx: this._x,
|
||||
ty: this._y
|
||||
};
|
||||
},
|
||||
_applyCurrentTransform: function (point, targetCoordSpace) {
|
||||
var m = this._currentTransformMatrix;
|
||||
var x = point.x;
|
||||
var y = point.y;
|
||||
|
||||
point.x = m.a * x + m.c * y + m.tx;
|
||||
point.y = m.d * y + m.b * x + m.ty;
|
||||
|
||||
if (this._parent !== this._stage && this._parent !== targetCoordSpace) {
|
||||
this._parent._applyCurrentTransform(point, targetCoordSpace);
|
||||
}
|
||||
},
|
||||
_applyCurrentInverseTransform: function (point, targetCoordSpace) {
|
||||
if (this._parent !== this._stage && this._parent !== targetCoordSpace) {
|
||||
this._parent._applyCurrentInverseTransform(point);
|
||||
}
|
||||
|
||||
var m = this._currentTransformMatrix;
|
||||
|
||||
var x = point.x - m.tx;
|
||||
var y = point.y - m.ty;
|
||||
var d = 1 / (m.a * m.d - m.b * m.c);
|
||||
|
||||
point.x = (m.d * x - m.c * y) * d;
|
||||
point.y = (m.a * y - m.b * x) * d;
|
||||
},
|
||||
getRect: function (targetCoordSpace) {
|
||||
notImplemented();
|
||||
},
|
||||
globalToLocal: function (pt) {
|
||||
var result = new flash.geom.Point(pt.x, pt.y);
|
||||
this._applyCurrentInverseTransform(result);
|
||||
return result;
|
||||
},
|
||||
get height() {
|
||||
var bounds = this.getBounds();
|
||||
return bounds.height;
|
||||
|
@ -165,30 +223,9 @@ const DisplayObjectDefinition = (function () {
|
|||
set height(val) {
|
||||
notImplemented();
|
||||
},
|
||||
hitTestObject: function (obj) {
|
||||
return this._hitTest(false, 0, 0, false, obj);
|
||||
},
|
||||
hitTestPoint: function (x, y, shapeFlag) {
|
||||
return this._hitTest(true, x, y, shapeFlag, null);
|
||||
},
|
||||
_hitTest: function _hitTest(use_xy, x, y, useShape, hitTestObject) {
|
||||
if (use_xy) {
|
||||
// debugger;
|
||||
return false; //notImplemented();
|
||||
} else {
|
||||
var box1 = this.getBounds();
|
||||
var box2 = hitTestObject.getBounds();
|
||||
return box1.intersects(box2);
|
||||
}
|
||||
},
|
||||
get loaderInfo() {
|
||||
return this._loaderInfo || (this._parent ? this._parent.loaderInfo : null);
|
||||
},
|
||||
localToGlobal: function (pt) {
|
||||
var result = new flash.geom.Point(pt.x, pt.y);
|
||||
this._applyCurrentTransform(result);
|
||||
return result;
|
||||
},
|
||||
get mask() {
|
||||
return null;
|
||||
},
|
||||
|
@ -217,15 +254,18 @@ const DisplayObjectDefinition = (function () {
|
|||
return this._parent;
|
||||
},
|
||||
get root() {
|
||||
return this._root || (this._parent ? this._parent._root : null);
|
||||
return this._root || (this._parent ? this._parent.root : null);
|
||||
},
|
||||
get rotation() {
|
||||
return this._rotation;
|
||||
},
|
||||
set rotation(val) {
|
||||
this._markAsDirty();
|
||||
|
||||
this._rotation = val;
|
||||
this._updateTransformMatrix();
|
||||
this._slave = false;
|
||||
|
||||
this._updateCurrentTransform();
|
||||
},
|
||||
get stage() {
|
||||
return this._stage || (this._parent ? this._parent.stage : null);
|
||||
|
@ -234,17 +274,23 @@ const DisplayObjectDefinition = (function () {
|
|||
return this._scaleX;
|
||||
},
|
||||
set scaleX(val) {
|
||||
this._markAsDirty();
|
||||
|
||||
this._scaleX = val;
|
||||
this._updateTransformMatrix();
|
||||
this._slave = false;
|
||||
|
||||
this._updateCurrentTransform();
|
||||
},
|
||||
get scaleY() {
|
||||
return this._scaleY;
|
||||
},
|
||||
set scaleY(val) {
|
||||
this._markAsDirty();
|
||||
|
||||
this._scaleY = val;
|
||||
this._updateTransformMatrix();
|
||||
this._slave = false;
|
||||
|
||||
this._updateCurrentTransform();
|
||||
},
|
||||
get scale9Grid() {
|
||||
return null;
|
||||
|
@ -262,45 +308,152 @@ const DisplayObjectDefinition = (function () {
|
|||
return this._transform || new flash.geom.Transform(this);
|
||||
},
|
||||
set transform(val) {
|
||||
this._currentTransform = val.matrix;
|
||||
this._slave = false;
|
||||
|
||||
var transform = this._transform;
|
||||
transform.colorTransform = val.colorTransform;
|
||||
transform.matrix = val.matrix;
|
||||
this._currentTransformMatrix = val.matrix;
|
||||
this._slave = false;
|
||||
|
||||
this._markAsDirty();
|
||||
},
|
||||
get visible() {
|
||||
return this._visible;
|
||||
},
|
||||
set visible(val) {
|
||||
this._visible = val;
|
||||
this._slave = false;
|
||||
this._visible = val;
|
||||
|
||||
this._markAsDirty();
|
||||
},
|
||||
get width() {
|
||||
var bounds = this.getBounds();
|
||||
return bounds.width;
|
||||
},
|
||||
set width(val) {
|
||||
//notImplemented();
|
||||
notImplemented();
|
||||
},
|
||||
get x() {
|
||||
return this._x;
|
||||
},
|
||||
set x(val) {
|
||||
this._x = val;
|
||||
this._updateTransformMatrix();
|
||||
this._markAsDirty();
|
||||
|
||||
this._slave = false;
|
||||
this._x = val;
|
||||
|
||||
this._updateCurrentTransform();
|
||||
},
|
||||
get y() {
|
||||
return this._y;
|
||||
},
|
||||
set y(val) {
|
||||
this._y = val;
|
||||
this._updateTransformMatrix();
|
||||
this._markAsDirty();
|
||||
|
||||
this._slave = false;
|
||||
this._y = val;
|
||||
|
||||
this._updateCurrentTransform();
|
||||
},
|
||||
|
||||
getBounds: function (targetCoordSpace) {
|
||||
if (this._bounds)
|
||||
return this._bounds;
|
||||
|
||||
var bbox = this._bbox;
|
||||
|
||||
var xMin = Number.MAX_VALUE;
|
||||
var xMax = Number.MIN_VALUE;
|
||||
var yMin = Number.MAX_VALUE;
|
||||
var yMax = Number.MIN_VALUE;
|
||||
|
||||
if (!bbox) {
|
||||
var children = this._children;
|
||||
var numChildren = children.length;
|
||||
var b;
|
||||
for (var i = 0; i < numChildren; i++) {
|
||||
var child = children[i];
|
||||
var b = child.getBounds(this);
|
||||
|
||||
var x1 = b.x;
|
||||
var y1 = b.y;
|
||||
var x2 = b.x + b.width;
|
||||
var y2 = b.y + b.height;
|
||||
|
||||
xMin = Math.min(xMin, x1, x2);
|
||||
xMax = Math.max(xMax, x1, x2);
|
||||
yMin = Math.min(yMin, y1, y2);
|
||||
yMax = Math.max(yMax, y1, y2);
|
||||
}
|
||||
} else {
|
||||
xMin = bbox.left;
|
||||
xMax = bbox.right;
|
||||
yMin = bbox.top;
|
||||
yMax = bbox.bottom;
|
||||
}
|
||||
|
||||
if (this._graphics) {
|
||||
var b = this._graphics._getBounds(true);
|
||||
if (b) {
|
||||
var x1 = b.x;
|
||||
var y1 = b.y;
|
||||
var x2 = b.x + b.width;
|
||||
var y2 = b.y + b.height;
|
||||
|
||||
xMin = Math.min(xMin, x1, x2);
|
||||
xMax = Math.max(xMax, x1, x2);
|
||||
yMin = Math.min(yMin, y1, y2);
|
||||
yMax = Math.max(yMax, y1, y2);
|
||||
}
|
||||
}
|
||||
|
||||
if (xMin === Number.MAX_VALUE) {
|
||||
return new flash.geom.Rectangle();
|
||||
}
|
||||
|
||||
var p1 = { x: xMin, y: yMin };
|
||||
this._applyCurrentTransform(p1, targetCoordSpace);
|
||||
var p2 = { x: xMax, y: yMin };
|
||||
this._applyCurrentTransform(p2, targetCoordSpace);
|
||||
var p3 = { x: xMax, y: yMax };
|
||||
this._applyCurrentTransform(p3, targetCoordSpace);
|
||||
var p4 = { x: xMin, y: yMax };
|
||||
this._applyCurrentTransform(p4, targetCoordSpace);
|
||||
|
||||
xMin = Math.min(p1.x, p2.x, p3.x, p4.x);
|
||||
xMax = Math.max(p1.x, p2.x, p3.x, p4.x);
|
||||
yMin = Math.min(p1.y, p2.y, p3.y, p4.y);
|
||||
yMax = Math.max(p1.y, p2.y, p3.y, p4.y);
|
||||
|
||||
return new flash.geom.Rectangle(
|
||||
xMin,
|
||||
yMin,
|
||||
(xMax - xMin),
|
||||
(yMax - yMin)
|
||||
);
|
||||
},
|
||||
getRect: function (targetCoordSpace) {
|
||||
notImplemented();
|
||||
},
|
||||
globalToLocal: function (pt) {
|
||||
var result = new flash.geom.Point(pt.x, pt.y);
|
||||
this._applyCurrentInverseTransform(result);
|
||||
return result;
|
||||
},
|
||||
hitTestObject: function (obj) {
|
||||
return this._hitTest(false, 0, 0, false, obj);
|
||||
},
|
||||
hitTestPoint: function (x, y, shapeFlag) {
|
||||
return this._hitTest(true, x, y, shapeFlag, null);
|
||||
},
|
||||
localToGlobal: function (pt) {
|
||||
var result = new flash.geom.Point(pt.x, pt.y);
|
||||
this._applyCurrentTransform(result);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
const desc = Object.getOwnPropertyDescriptor;
|
||||
var desc = Object.getOwnPropertyDescriptor;
|
||||
|
||||
def.__glue__ = {
|
||||
native: {
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
const DisplayObjectContainerDefinition = (function () {
|
||||
var DisplayObjectContainerDefinition = (function () {
|
||||
var def = {
|
||||
initialize: function () {
|
||||
this._children = [];
|
||||
},
|
||||
|
||||
get mouseChildren() {
|
||||
return true;
|
||||
return this._mouseChildren;
|
||||
},
|
||||
set mouseChildren(val) {
|
||||
notImplemented();
|
||||
this._mouseChildren = val;
|
||||
},
|
||||
get numChildren() {
|
||||
return this._children.length;
|
||||
|
@ -45,6 +41,10 @@ const DisplayObjectContainerDefinition = (function () {
|
|||
child._owned = false;
|
||||
child._parent = this;
|
||||
|
||||
this._control.appendChild(child._control);
|
||||
|
||||
this._markAsDirty();
|
||||
|
||||
return child;
|
||||
},
|
||||
areInaccessibleObjectsUnderPoint: function (pt) {
|
||||
|
@ -100,6 +100,10 @@ const DisplayObjectContainerDefinition = (function () {
|
|||
children.splice(index, 1);
|
||||
child._parent = null;
|
||||
|
||||
this._control.removeChild(child._control);
|
||||
|
||||
this._markAsDirty();
|
||||
|
||||
return child;
|
||||
},
|
||||
setChildIndex: function (child, index) {
|
||||
|
@ -117,6 +121,8 @@ const DisplayObjectContainerDefinition = (function () {
|
|||
children.splice(index, 0, child);
|
||||
child._owned = false;
|
||||
|
||||
this._markAsDirty();
|
||||
|
||||
return child;
|
||||
},
|
||||
removeChildren: function (begin, end) {
|
||||
|
@ -152,50 +158,12 @@ const DisplayObjectContainerDefinition = (function () {
|
|||
children[index2] = child1;
|
||||
child1._owned = false;
|
||||
child2._owned = false;
|
||||
},
|
||||
get _bbox() {
|
||||
var children = this._children;
|
||||
var numChildren = children.length;
|
||||
|
||||
if (!numChildren) {
|
||||
return {
|
||||
left: 0,
|
||||
top: 0,
|
||||
right: 0,
|
||||
bottom: 0
|
||||
}
|
||||
}
|
||||
|
||||
var xMin = Number.MAX_VALUE;
|
||||
var xMax = 0;
|
||||
var yMin = Number.MAX_VALUE;
|
||||
var yMax = 0;
|
||||
|
||||
for (var i = 0; i < numChildren; i++) {
|
||||
var child = children[i];
|
||||
var b = child.getBounds();
|
||||
|
||||
var x1 = b.x;
|
||||
var y1 = b.y;
|
||||
var x2 = b.x + b.width;
|
||||
var y2 = b.y + b.height;
|
||||
|
||||
xMin = Math.min(xMin, x1, x2);
|
||||
xMax = Math.max(xMax, x1, x2);
|
||||
yMin = Math.min(yMin, y1, y2);
|
||||
yMax = Math.max(yMax, y1, y2);
|
||||
}
|
||||
|
||||
return {
|
||||
left: xMin,
|
||||
top: yMin,
|
||||
right: xMax,
|
||||
bottom: yMax
|
||||
};
|
||||
this._markAsDirty();
|
||||
}
|
||||
};
|
||||
|
||||
const desc = Object.getOwnPropertyDescriptor;
|
||||
var desc = Object.getOwnPropertyDescriptor;
|
||||
|
||||
def.__glue__ = {
|
||||
native: {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const GraphicsDefinition = (function () {
|
||||
var GraphicsDefinition = (function () {
|
||||
var GRAPHICS_PATH_COMMAND_CUBIC_CURVE_TO = 6;
|
||||
var GRAPHICS_PATH_COMMAND_CURVE_TO = 3;
|
||||
var GRAPHICS_PATH_COMMAND_LINE_TO = 2;
|
||||
|
@ -25,42 +25,13 @@ const GraphicsDefinition = (function () {
|
|||
this._drawingStyles = null;
|
||||
this._fillStyle = null;
|
||||
this._fillTransform = null;
|
||||
this._revision = 0;
|
||||
this._scale = 1;
|
||||
this._strokeStyle = null;
|
||||
this._subpaths = [];
|
||||
},
|
||||
|
||||
beginFill: function (color, alpha) {
|
||||
if (alpha === undefined)
|
||||
alpha = 1;
|
||||
|
||||
delete this._currentPath;
|
||||
|
||||
this._fillStyle = alpha ? toRgba(color, alpha) : null;
|
||||
this._fillTransform = null;
|
||||
},
|
||||
beginGradientFill: function (type, colors, alphas, ratios, matrix, spreadMethod, interpolationMethod, focalPos) {
|
||||
var gradient;
|
||||
|
||||
if (type === 'linear')
|
||||
gradient = fillContext.createLinearGradient(-819.2, 0, 819.2, 0);
|
||||
else if (type == 'radial')
|
||||
gradient = fillContext.createRadialGradient(819.2 * (focalPos || 0), 0, 0, 0, 0, 819.2);
|
||||
else
|
||||
throw ArgumentError();
|
||||
|
||||
for (var i = 0, n = colors.length; i < n; i++)
|
||||
gradient.addColorStop(ratios[i], toRgba(colors[i], alphas[i]));
|
||||
|
||||
this._fillStyle = gradient;
|
||||
this._fillTransform = matrix;
|
||||
},
|
||||
|
||||
beginBitmapFill: function (bitmap, matrix, repeat, smooth) {
|
||||
//notImplemented();
|
||||
// stub this out
|
||||
},
|
||||
beginFillObject: function (fill) {
|
||||
_beginFillObject: function (fill) {
|
||||
if (fill === null) {
|
||||
this.endFill();
|
||||
} else {
|
||||
|
@ -92,7 +63,7 @@ const GraphicsDefinition = (function () {
|
|||
}
|
||||
}
|
||||
},
|
||||
beginStrokeObject: function (istroke) {
|
||||
_beginStrokeObject: function (istroke) {
|
||||
var stroke = null;
|
||||
var fill = null;
|
||||
|
||||
|
@ -148,6 +119,64 @@ const GraphicsDefinition = (function () {
|
|||
}
|
||||
}
|
||||
},
|
||||
_drawPathObject: function (path) {
|
||||
if (path.__class__ === 'flash.display.GraphicsPath')
|
||||
this.drawPath(path.commands, path.data, path.winding);
|
||||
else if (path.__class__ === 'flash.display.GraphicsTrianglePath')
|
||||
this.drawTriangles(path.vertices, path.indices, path.uvtData, path.culling);
|
||||
},
|
||||
|
||||
get _currentPath() {
|
||||
var path = new Kanvas.Path;
|
||||
var pathTracker = new PolygonTracker(path);
|
||||
pathTracker.drawingStyles = this._drawingStyles;
|
||||
path.fillStyle = this._fillStyle;
|
||||
path.fillTransform = this._fillTransform;
|
||||
path.strokeStyle = this._strokeStyle;
|
||||
this._subpaths.push(pathTracker);
|
||||
// Cache as an own property.
|
||||
Object.defineProperty(this, '_currentPath', describeProperty(pathTracker));
|
||||
return pathTracker;
|
||||
},
|
||||
|
||||
beginFill: function (color, alpha) {
|
||||
if (alpha === undefined)
|
||||
alpha = 1;
|
||||
|
||||
delete this._currentPath;
|
||||
|
||||
this._fillStyle = alpha ? toRgba(color, alpha) : null;
|
||||
this._fillTransform = null;
|
||||
},
|
||||
beginGradientFill: function (type, colors, alphas, ratios, matrix, spreadMethod, interpolationMethod, focalPos) {
|
||||
var gradient;
|
||||
if (type === 'linear')
|
||||
gradient = fillContext.createLinearGradient(-1, 0, 1, 0);
|
||||
else if (type == 'radial')
|
||||
gradient = fillContext.createRadialGradient((focalPos || 0), 0, 0, 0, 0, 1);
|
||||
else
|
||||
throw ArgumentError();
|
||||
|
||||
for (var i = 0, n = colors.length; i < n; i++)
|
||||
gradient.addColorStop(ratios[i], toRgba(colors[i], alphas[i]));
|
||||
|
||||
this._fillStyle = gradient;
|
||||
|
||||
// NOTE firefox really sensitive to really small scale when painting gradients
|
||||
var scale = 819.2;
|
||||
this._fillTransform = matrix ?
|
||||
{ a: scale * matrix.a, b: scale * matrix.b, c: scale * matrix.c, d: scale * matrix.d, tx: matrix.tx, ty: matrix.ty } :
|
||||
{ a: scale, b: 0, c: 0, d: scale, tx: 0, ty: 0 };
|
||||
},
|
||||
beginBitmapFill: function (bitmap, matrix, repeat, smooth) {
|
||||
var repeatStyle = repeat ? 'repeat' : 'no-repeat';
|
||||
this._fillStyle = fillContext.createPattern(bitmap._drawable, repeatStyle);
|
||||
|
||||
var scale = this._scale;
|
||||
this._fillTransform = matrix ?
|
||||
{ a: scale * matrix.a, b: scale * matrix.b, c: scale * matrix.c, d: scale * matrix.d, tx: matrix.tx, ty: matrix.ty } :
|
||||
{ a: scale, b: 0, c: 0, d: scale, tx: 0, ty: 0 };
|
||||
},
|
||||
clear: function () {
|
||||
delete this._currentPath;
|
||||
|
||||
|
@ -162,19 +191,21 @@ const GraphicsDefinition = (function () {
|
|||
},
|
||||
cubicCurveTo: function (cp1x, cp1y, cp2x, cp2y, x, y) {
|
||||
this._currentPath.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
|
||||
this._revision++;
|
||||
},
|
||||
curveTo: function (cpx, cpy, x, y) {
|
||||
this._currentPath.quadraticCurveTo(cpx, cpy, x, y);
|
||||
this._revision++;
|
||||
},
|
||||
drawGraphicsData: function (graphicsData) {
|
||||
for (var i = 0, n = graphicsData.length; i < n; i++) {
|
||||
var item = graphicsData[i];
|
||||
if (item.__isIGraphicsPath__)
|
||||
this.drawPathObject(item);
|
||||
this._drawPathObject(item);
|
||||
else if (item.__isIGraphicsFill__)
|
||||
this.beginFillObject(item);
|
||||
this._beginFillObject(item);
|
||||
else if (item.__isIGraphicsStroke__)
|
||||
this.beginStrokeObject(item);
|
||||
this._beginStrokeObject(item);
|
||||
}
|
||||
},
|
||||
drawPath: function (commands, data, winding) {
|
||||
|
@ -202,29 +233,44 @@ const GraphicsDefinition = (function () {
|
|||
}
|
||||
}
|
||||
},
|
||||
drawPathObject: function (path) {
|
||||
if (path.__class__ === 'flash.display.GraphicsPath')
|
||||
this.drawPath(path.commands, path.data, path.winding);
|
||||
else if (path.__class__ === 'flash.display.GraphicsTrianglePath')
|
||||
this.drawTriangles(path.vertices, path.indices, path.uvtData, path.culling);
|
||||
},
|
||||
drawRect: function (x, y, w, h) {
|
||||
if (isNaN(w + h))
|
||||
throw ArgumentError();
|
||||
|
||||
this._currentPath.rect(x, y, w, h);
|
||||
this._revision++;
|
||||
},
|
||||
drawRoundRect: function (x, y, w, h, ellipseWidth, ellipseHeight) {
|
||||
if (isNaN(w + h + ellipseWidth) || (ellipseHeight !== undefined && isNaN(ellipseHeight)))
|
||||
throw ArgumentError();
|
||||
|
||||
notImplemented();
|
||||
var radiusW = ellipseWidth / 2;
|
||||
var radiusH = ellipseHeight / 2;
|
||||
|
||||
// A-----B
|
||||
// H C
|
||||
// G D
|
||||
// F-----E
|
||||
//
|
||||
// Through some testing, it has been discovered
|
||||
// tha the Flash player starts and stops the pen
|
||||
// at 'D', so we will too.
|
||||
|
||||
this._currentPath.moveTo(x+w, y+h-radiusH);
|
||||
this._currentPath.arcTo(x+w, y+h, x+w-radiusW, y+h-radiusH, radiusW, radiusH);
|
||||
this._currentPath.arcTo(x, y+h, x, y+h-radiusH, radiusW, radiusH);
|
||||
this._currentPath.arcTo(x, y, x+radiusW, y, radiusW, radiusH);
|
||||
this._currentPath.arcTo(x+w, y, x+w, y+radiusH, radiusW, radiusH);
|
||||
},
|
||||
drawRoundRectComplex: function (x, y, w, h, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius) {
|
||||
if (isNaN(h + topLeftRadius + topRightRadius + bottomLeftRadius + bottomRightRadius))
|
||||
if (isNaN(w + h + topLeftRadius + topRightRadius + bottomLeftRadius + bottomRightRadius))
|
||||
throw ArgumentError();
|
||||
|
||||
notImplemented();
|
||||
this._currentPath.moveTo(x+w, y+h-radiusH);
|
||||
this._currentPath.arcTo(x+w, y+h, x+w-bottomRightRadius, y+h-bottomRightRadius, bottomRightRadius);
|
||||
this._currentPath.arcTo(x, y+h, x, y+h-bottomLeftRadius, bottomLeftRadius);
|
||||
this._currentPath.arcTo(x, y, x+topLeftRadius, y, topLeftRadius);
|
||||
this._currentPath.arcTo(x+w, y, x+w, y+topRightRadius, topRightRadius);
|
||||
},
|
||||
drawTriangles: function (vertices, indices, uvtData, culling) {
|
||||
notImplemented();
|
||||
|
@ -255,7 +301,7 @@ const GraphicsDefinition = (function () {
|
|||
lineCap: cap || 'round',
|
||||
lineJoin: cap || 'round',
|
||||
lineWidth: width,
|
||||
miterLimit: mlimit
|
||||
miterLimit: mlimit * 2
|
||||
};
|
||||
this._strokeStyle = toRgba(color, alpha);
|
||||
} else {
|
||||
|
@ -263,26 +309,445 @@ const GraphicsDefinition = (function () {
|
|||
this._strokeStyle = null;
|
||||
}
|
||||
},
|
||||
moveTo: function (x, y) {
|
||||
this._currentPath.moveTo(x, y);
|
||||
},
|
||||
lineTo: function (x, y) {
|
||||
this._currentPath.lineTo(x, y);
|
||||
this._revision++;
|
||||
},
|
||||
|
||||
get _currentPath() {
|
||||
var path = new Kanvas.Path;
|
||||
path.drawingStyles = this._drawingStyles;
|
||||
path.fillStyle = this._fillStyle;
|
||||
path.fillTransform = this._fillTransform;
|
||||
path.strokeStyle = this._strokeStyle;
|
||||
this._subpaths.push(path);
|
||||
// Cache as an own property.
|
||||
Object.defineProperty(this, '_currentPath', describeProperty(path));
|
||||
return path;
|
||||
moveTo: function (x, y) {
|
||||
this._currentPath.moveTo(x, y);
|
||||
this._revision++;
|
||||
},
|
||||
_getBounds: function (includeStroke) {
|
||||
var subpaths = this._subpaths;
|
||||
var xMins = [], yMins = [], xMaxs = [], yMaxs = [];
|
||||
for (var i = 0, n = subpaths.length; i < n; i++) {
|
||||
var pathTracker = subpaths[i];
|
||||
var b = pathTracker.getBounds();
|
||||
if (b) {
|
||||
xMins.push(b.minX); yMins.push(b.minY); xMaxs.push(b.maxX); yMaxs.push(b.maxY);
|
||||
}
|
||||
if (includeStroke && pathTracker.target.strokeStyle) {
|
||||
var strokeTracker = new PolygonTracker();
|
||||
var drawingStyles = pathTracker.drawingStyles;
|
||||
pathTracker.strokeToPath(strokeTracker, {
|
||||
strokeWidth: drawingStyles.lineWidth,
|
||||
startCap: drawingStyles.lineCap,
|
||||
endCap: drawingStyles.lineCap,
|
||||
join: drawingStyles.lineJoin,
|
||||
miterLimit: drawingStyles.miterLimit
|
||||
});
|
||||
var b = strokeTracker.getBounds();
|
||||
if (b) {
|
||||
xMins.push(b.minX); yMins.push(b.minY); xMaxs.push(b.maxX); yMaxs.push(b.maxY);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (xMins.length === 0) {
|
||||
return 0;
|
||||
}
|
||||
var scale = this._scale;
|
||||
var xMin = Math.min.apply(Math, xMins) * scale;
|
||||
var yMin = Math.min.apply(Math, yMins) * scale;
|
||||
var xMax = Math.max.apply(Math, xMaxs) * scale;
|
||||
var yMax = Math.max.apply(Math, yMaxs) * scale;
|
||||
return { x: xMin, y: yMin, width: xMax - xMin, height: yMax - yMin};
|
||||
}
|
||||
};
|
||||
|
||||
var PolygonTracker = (function PolygonTrackerClosure() {
|
||||
var CURVE_APPROX_POINTS = 8;
|
||||
var CIRCLE_APPROX_POINTS = 12; // per PI
|
||||
var CIRCLE_APPROX_SIN = Math.sin(Math.PI / CIRCLE_APPROX_POINTS);
|
||||
var CIRCLE_APPROX_COS = Math.cos(Math.PI / CIRCLE_APPROX_POINTS);
|
||||
function strokeToPath(tracker, options, output) {
|
||||
function buildCap(lines, capStyle, line1, line2) {
|
||||
line1.type = 3;
|
||||
switch (capStyle) {
|
||||
case 'round':
|
||||
var cx = (line1.x2 + line2.x1) / 2;
|
||||
var cy = (line1.y2 + line2.y1) / 2;
|
||||
var dx = (line1.x2 - cx), dy = (line1.y2 - cy);
|
||||
for (var i = 0; i < CIRCLE_APPROX_POINTS; i++) {
|
||||
var dx1 = dx * CIRCLE_APPROX_COS - dy * CIRCLE_APPROX_SIN;
|
||||
var dy1 = dx * CIRCLE_APPROX_SIN + dy * CIRCLE_APPROX_COS;
|
||||
lines.push({
|
||||
x1: cx + dx, y1: cy + dy,
|
||||
x2: cx + dx1, y2: cy + dy1,
|
||||
type: 3});
|
||||
dx = dx1; dy = dy1;
|
||||
}
|
||||
break;
|
||||
case 'square':
|
||||
var capHeight = options.strokeWidth / 2;
|
||||
var dx = line1.x2 - line1.x1, dy = line1.y2 - line1.y1;
|
||||
var d = Math.sqrt(dx * dx + dy * dy);
|
||||
line1.x2 += dx * capHeight / d;
|
||||
line1.y2 += dy * capHeight / d;
|
||||
line2.x1 += dx * capHeight / d;
|
||||
line2.y1 += dy * capHeight / d;
|
||||
// fall throw
|
||||
case 'none':
|
||||
default:
|
||||
lines.push({
|
||||
x1: line1.x2, y1: line1.y2,
|
||||
x2: line2.x1, y2: line2.y1,
|
||||
type: 3});
|
||||
break;
|
||||
}
|
||||
}
|
||||
function joinLines(cmds, line1, line2, type) {
|
||||
// (x - x1) * (y2 - y1) - (y - y1) * (x2 - x1) = 0, a*x + b*y = c
|
||||
var a1 = (line1.y2 - line1.y1), b1 = -(line1.x2 - line1.x1), c1 = line1.x1 * line1.y2 - line1.x2 * line1.y1;
|
||||
var a2 = (line2.y2 - line2.y1), b2 = -(line2.x2 - line2.x1), c2 = line2.x1 * line2.y2 - line2.x2 * line2.y1;
|
||||
var d = a1 * b2 - b1 * a2;
|
||||
if (d == 0) {
|
||||
// parellel lines doing bevel
|
||||
cmds.push({type: 'lineTo', args: [line1.x2, line1.y2]});
|
||||
cmds.push({type: 'lineTo', args: [line2.x1, line2.y1]});
|
||||
return;
|
||||
}
|
||||
var x = (c1 * b2 - b1 * c2) / d;
|
||||
var y = (a1 * c2 - c1 * a2) / d;
|
||||
var onLine1 = !(
|
||||
(x < line1.x1 && x < line1.x2) || (x > line1.x1 && x > line1.x2) ||
|
||||
(y < line1.y1 && y < line1.y2) || (y > line1.y1 && y > line1.y2));
|
||||
var onLine2 = !(
|
||||
(x < line2.x1 && x < line2.x2) || (x > line2.x1 && x > line2.x2) ||
|
||||
(y < line2.y1 && y < line2.y2) || (y > line2.y1 && y > line2.y2));
|
||||
if (!onLine1 && !onLine2) {
|
||||
switch (type) {
|
||||
default:
|
||||
case 'bevel':
|
||||
cmds.push({type: 'lineTo', args: [line1.x2, line1.y2]});
|
||||
cmds.push({type: 'lineTo', args: [line2.x1, line2.y1]});
|
||||
break;
|
||||
case 'round':
|
||||
cmds.push({type: 'lineTo', args: [line1.x2, line1.y2]});
|
||||
cmds.push({type: 'quadraticCurveTo', args: [x, y, line2.x1, line2.y1]});
|
||||
break;
|
||||
case 'miter':
|
||||
cmds.push({type: 'lineTo', args: [line1.x2, line1.y2]});
|
||||
var a = -(line1.y2 - line2.y1), b = line1.x2 - line2.x1;
|
||||
var d = Math.sqrt(a * a + b * b);
|
||||
var miterLength = (a * (x - line2.x1) + b * (y - line2.y1)) / d;
|
||||
var maxAllowedLength = options.miterLimit * options.strokeWidth / 2;
|
||||
if (miterLength > maxAllowedLength) {
|
||||
var p2 = maxAllowedLength / miterLength, p1 = 1 - p2;
|
||||
cmds.push({type: 'lineTo', args: [line1.x2 * p1 + x * p2, line1.y2 * p1 + y * p2]});
|
||||
cmds.push({type: 'lineTo', args: [line2.x1 * p1 + x * p2, line2.y1 * p1 + y * p2]});
|
||||
} else {
|
||||
cmds.push({type: 'lineTo', args: [x, y]});
|
||||
}
|
||||
cmds.push({type: 'lineTo', args: [line2.x1, line2.y1]});
|
||||
break;
|
||||
}
|
||||
} else if (!onLine1 || !onLine2) {
|
||||
cmds.push({type: 'lineTo', args: onLine1 ? [x, y] : [line1.x2, line1.y2]});
|
||||
cmds.push({type: 'lineTo', args: onLine2 ? [x, y] : [line2.x1, line2.y1]});
|
||||
} else {
|
||||
cmds.push({type: 'lineTo', args: [x, y]});
|
||||
}
|
||||
}
|
||||
function buildPath(lines) {
|
||||
var moveCmd = {type: 'moveTo', args: null};
|
||||
var cmds = [moveCmd];
|
||||
var joinType = options.join;
|
||||
for (var j = 0; j < lines.length; j++) {
|
||||
var type = lines[j].type;
|
||||
switch (type) {
|
||||
default:
|
||||
joinLines(cmds, lines[j], lines[(j + 1) % lines.length], joinType);
|
||||
break;
|
||||
case 3: // simple line
|
||||
cmds.push({type: 'lineTo', args: [lines[j].x2, lines[j].y2]});
|
||||
break;
|
||||
case 4: // curve segment connector
|
||||
joinLines(cmds, lines[j], lines[(j + 1) % lines.length], 'bevel');
|
||||
break;
|
||||
}
|
||||
}
|
||||
moveCmd.args = cmds[cmds.length - 1].args.slice(-2);
|
||||
cmds.push({type: 'closePath'});
|
||||
for (var i = 0; i < cmds.length; i++) {
|
||||
output[cmds[i].type].apply(output, cmds[i].args);
|
||||
}
|
||||
}
|
||||
var i = 0;
|
||||
var segments = tracker.segments;
|
||||
var points = tracker.points;
|
||||
var start = segments[0];
|
||||
do {
|
||||
++i;
|
||||
var end = i < segments.length ? segments[i] : points.length;
|
||||
if (points[start].type !== 0) {
|
||||
throw 'invalid points structure';
|
||||
}
|
||||
if (start + 1 >= end) {
|
||||
// only moveTo operation
|
||||
end = start;
|
||||
continue;
|
||||
}
|
||||
var pathClosed = points[end - 1].type === 2;
|
||||
var lastX = points[start].x;
|
||||
var lastY = points[start].y;
|
||||
var lastType = 0;
|
||||
start++;
|
||||
// building paths
|
||||
var forward = [], backward = [];
|
||||
var strokeHalfWidth = options.strokeWidth / 2;
|
||||
for (var j = start; j < end; j++) {
|
||||
var x = points[j].x, y = points[j].y, type = points[j].type;
|
||||
var dx = x - lastX;
|
||||
var dy = y - lastY;
|
||||
if (dx == 0 && dy == 0) continue;
|
||||
var k = strokeHalfWidth / Math.sqrt(dx * dx + dy * dy);
|
||||
dx *= k; dy *= k;
|
||||
forward.push({
|
||||
x1: lastX + dy, y1: lastY - dx,
|
||||
x2: x + dy, y2: y - dx,
|
||||
type: type
|
||||
});
|
||||
backward.push({
|
||||
x1: x - dy, y1: y + dx,
|
||||
x2: lastX - dy, y2: lastY + dx,
|
||||
type: lastType
|
||||
});
|
||||
lastX = x; lastY = y; lastType = type;
|
||||
}
|
||||
backward.reverse();
|
||||
if (!pathClosed) {
|
||||
buildCap(forward, options.endCap, forward[forward.length - 1], backward[0]);
|
||||
buildCap(backward, options.startCap, backward[backward.length - 1], forward[0]);
|
||||
forward = forward.concat(backward);
|
||||
buildPath(forward);
|
||||
} else {
|
||||
buildPath(forward);
|
||||
buildPath(backward);
|
||||
}
|
||||
start = end;
|
||||
} while (i < segments.length);
|
||||
}
|
||||
|
||||
function pushCurveApprox(points, x1, y1, x2, y2) {
|
||||
var x0 = points[points.length - 1].x;
|
||||
var y0 = points[points.length - 1].y;
|
||||
for (var i = 0; i < CURVE_APPROX_POINTS; i++) {
|
||||
var p2 = (i + 1) / CURVE_APPROX_POINTS, p1 = 1 - p2;
|
||||
var x01 = x0 * p1 + x1 * p2, y01 = y0 * p1 + y1 * p2;
|
||||
var x12 = x1 * p1 + x2 * p2, y12 = y1 * p1 + y2 * p2;
|
||||
var x = x01 * p1 + x12 * p2, y = y01 * p1 + y12 * p2;
|
||||
points.push({x: x, y: y, type: 4});
|
||||
}
|
||||
points[points.length - 1].type = 1;
|
||||
}
|
||||
function pushBezierCurveApprox(points, x1, y1, x2, y2, x3, y3) {
|
||||
var x0 = points[points.length - 1].x;
|
||||
var y0 = points[points.length - 1].y;
|
||||
for (var i = 0; i < CURVE_APPROX_POINTS; i++) {
|
||||
var p2 = (i + 1) / CURVE_APPROX_POINTS, p1 = 1 - p2;
|
||||
var x01 = x0 * p1 + x1 * p2, y01 = y0 * p1 + y1 * p2;
|
||||
var x12 = x1 * p1 + x2 * p2, y12 = y1 * p1 + y2 * p2;
|
||||
var x23 = x2 * p1 + x3 * p2, y23 = y2 * p1 + y3 * p2;
|
||||
var x012 = x01 * p1 + x12 * p2, y012 = y01 * p1 + y12 * p2;
|
||||
var x123 = x12 * p1 + x23 * p2, y123 = y12 * p1 + y23 * p2;
|
||||
var x = x012 * p1 + x123 * p2, y = y012 * p1 + y123 * p2;
|
||||
points.push({x: x, y: y, type: 4});
|
||||
}
|
||||
points[points.length - 1].type = 1;
|
||||
}
|
||||
function normalizeAngle(angle) {
|
||||
while (angle > Math.PI)
|
||||
angle -= 2 * Math.PI;
|
||||
while (angle <= -Math.PI)
|
||||
angle += 2 * Math.PI;
|
||||
return angle;
|
||||
}
|
||||
function pushArcApprox(points, x1, y1, x2, y2, radiusX, radiusY, rotation) {
|
||||
var x0 = points[points.length - 1].x;
|
||||
var y0 = points[points.length - 1].y;
|
||||
var dx01 = x1 - x0, dy01 = y1 - y0, dx12 = x2 - x1, dy12 = y2 - y1;
|
||||
var winding = dx01 * dy12 - dy01 * dx12;
|
||||
// if radiusX or radiusY == 0, or points #0, #1, and #2 are on one line,
|
||||
// just draw simple line to point #1
|
||||
if (radiusX <= 0 || radiusY <= 0 || winding == 0) {
|
||||
points.push({x: x1, y: y1, type: 1});
|
||||
return;
|
||||
}
|
||||
var rotationCos = 1, rotationSin = 0;
|
||||
if (rotation) {
|
||||
rotationCos = Math.cos(rotation);
|
||||
rotationSin = Math.sin(rotation);
|
||||
}
|
||||
// placing major axis to x
|
||||
var dx01_ = dx01 * rotationCos + dy01 * rotationSin;
|
||||
var dy01_ = -dx01 * rotationSin + dy01 * rotationCos;
|
||||
var dx12_ = dx12 * rotationCos + dy12 * rotationSin;
|
||||
var dy12_ = -dx12 * rotationSin + dy12 * rotationCos;
|
||||
var alpha1 = Math.atan2(-dx01_ * radiusY, dy01_ * radiusX);
|
||||
var alpha2 = Math.atan2(-dx12_ * radiusY, dy12_ * radiusX);
|
||||
if (winding < 0) {
|
||||
alpha1 = (alpha1 >= 0 ? -Math.PI : Math.PI) + alpha1;
|
||||
alpha2 = (alpha2 >= 0 ? -Math.PI : Math.PI) + alpha2;
|
||||
}
|
||||
|
||||
// start and end offsets of the arc from center
|
||||
var bx1_ = radiusX * Math.cos(alpha1), by1_ = radiusY * Math.sin(alpha1);
|
||||
var bx2_ = radiusX * Math.cos(alpha2), by2_ = radiusY * Math.sin(alpha2);
|
||||
var bx1 = bx1_ * rotationCos - by1_ * rotationSin;
|
||||
var by1 = bx1_ * rotationSin + by1_ * rotationCos;
|
||||
var bx2 = bx2_ * rotationCos - by2_ * rotationSin;
|
||||
var by2 = bx2_ * rotationSin + by2_ * rotationCos;
|
||||
|
||||
// finding center
|
||||
// (x1 - bx1 - cx) * (y1 - y0) - (y1 - by1 - cy) * (x1 - x0) = 0
|
||||
var a1 = y1 - y0, b1 = -(x1 - x0), c1 = (x1 - bx1) * (y1 - y0) - (y1 - by1) * (x1 - x0);
|
||||
var a2 = y2 - y1, b2 = -(x2 - x1), c2 = (x2 - bx2) * (y2 - y1) - (y2 - by2) * (x2 - x1);
|
||||
var d = a1 * b2 - b1 * a2;
|
||||
var cx = (c1 * b2 - b1 * c2) / d;
|
||||
var cy = (a1 * c2 - c1 * a2) / d;
|
||||
|
||||
points.push({x: bx1 + cx, y: by1 + cy, type: 1}); // line from point #0
|
||||
|
||||
// building arc segments
|
||||
var angleDistance = normalizeAngle(alpha2 - alpha1);
|
||||
var stepsCount = Math.ceil(Math.abs(angleDistance) / Math.PI * CIRCLE_APPROX_POINTS);
|
||||
var step = angleDistance / stepsCount;
|
||||
for (var i = 1; i <= stepsCount; i++) {
|
||||
var alpha = alpha1 + (angleDistance * i / stepsCount);
|
||||
var x_ = radiusX * Math.cos(alpha), y_ = radiusY * Math.sin(alpha);
|
||||
var x = x_ * rotationCos - y_ * rotationSin + cx;
|
||||
var y = x_ * rotationSin + y_ * rotationCos + cy;
|
||||
points.push({x: x, y: y, type: 4});
|
||||
}
|
||||
points[points.length - 1].type = 1;
|
||||
}
|
||||
|
||||
function PolygonTrackerNullOutput() {}
|
||||
PolygonTrackerNullOutput.prototype = {
|
||||
moveTo: function () {},
|
||||
lineTo: function () {},
|
||||
quadraticCurveTo: function () {},
|
||||
closePath: function () {}
|
||||
};
|
||||
|
||||
function PolygonTracker(target) {
|
||||
this.target = target || new PolygonTrackerNullOutput;
|
||||
this.segments = [0];
|
||||
this.points = [{x: 0, y: 0, type: 0}];
|
||||
}
|
||||
PolygonTracker.prototype = {
|
||||
get lineWidth() {
|
||||
return this.target.lineWidth;
|
||||
},
|
||||
set lineWidth(value) {
|
||||
this.target.lineWidth = value;
|
||||
},
|
||||
get lineCap() {
|
||||
return this.target.lineCap;
|
||||
},
|
||||
set lineCap(value) {
|
||||
this.target.lineCap = value;
|
||||
},
|
||||
get lineJoin() {
|
||||
return this.target.lineJoin;
|
||||
},
|
||||
set lineJoin(value) {
|
||||
this.target.lineJoin = value;
|
||||
},
|
||||
get miterLimit() {
|
||||
return this.target.miterLimit;
|
||||
},
|
||||
set miterLimit(value) {
|
||||
this.target.miterLimit = value;
|
||||
},
|
||||
moveTo: function (x, y) {
|
||||
var segmentStartIndex = this.segments[this.segments.length - 1];
|
||||
if (segmentStartIndex === this.points.length - 1) {
|
||||
this.points[segmentStartIndex].x = x;
|
||||
this.points[segmentStartIndex].y = y;
|
||||
} else {
|
||||
this.segments.push(this.points.length);
|
||||
this.points.push({x: x, y: y, type: 0});
|
||||
}
|
||||
this.target.moveTo(x, y);
|
||||
},
|
||||
lineTo: function (x, y) {
|
||||
this.points.push({x: x, y: y, type: 1});
|
||||
this.target.lineTo(x, y);
|
||||
},
|
||||
closePath: function () {
|
||||
var segmentStartIndex = this.segments[this.segments.length - 1];
|
||||
this.points.push({x: this.points[segmentStartIndex].x,
|
||||
y: this.points[segmentStartIndex].y,
|
||||
type: 2});
|
||||
|
||||
this.target.closePath();
|
||||
|
||||
this.segments.push(this.points.length);
|
||||
this.points.push({x: this.points[segmentStartIndex].x,
|
||||
y: this.points[segmentStartIndex].y,
|
||||
type: 0});
|
||||
},
|
||||
quadraticCurveTo: function (cpx, cpy, x, y) {
|
||||
pushCurveApprox(this.points, cpx, cpy, x, y);
|
||||
this.target.quadraticCurveTo(cpx, cpy, x, y);
|
||||
},
|
||||
bezierCurveTo: function (cpx1, cpy1, cpx2, cpy2, x, y) {
|
||||
pushBezierCurveApprox(this.points, cpx1, cpy1, cpx2, cpy2, x, y);
|
||||
this.target.bezierCurveTo(cpx1, cpy1, cpx2, cpy2, x, y);
|
||||
},
|
||||
arcTo: function (x1, y1, x2, y2, radiusX, radiusY, rotation) {
|
||||
pushArcApprox(this.points, x1, y1, x2, y2, radiusX,
|
||||
arguments.length < 6 ? radiusX : radiusY,
|
||||
rotation);
|
||||
this.target.arcTo.apply(this.target, arguments);
|
||||
},
|
||||
rect: function (x, y, w, h) {
|
||||
var segmentStartIndex = this.segments[this.segments.length - 1];
|
||||
if (segmentStartIndex === this.points.length - 1) {
|
||||
this.points[segmentStartIndex].x = x;
|
||||
this.points[segmentStartIndex].y = y;
|
||||
} else {
|
||||
this.segments.push(this.points.length);
|
||||
this.points.push({x: x, y: y, type: 0});
|
||||
}
|
||||
this.points.push({x: x + w, y: y, type: 1});
|
||||
this.points.push({x: x + w, y: y + h, type: 1});
|
||||
this.points.push({x: x, y: y + h, type: 1});
|
||||
this.points.push({x: x, y: y, type: 2});
|
||||
|
||||
this.target.rect(x, y, w, h);
|
||||
},
|
||||
strokeToPath: function (output, options) {
|
||||
strokeToPath(this, options || {
|
||||
strokeWidth: this.lineWidth,
|
||||
startCap: this.lineCap,
|
||||
endCap: this.lineCap,
|
||||
join: this.lineJoin,
|
||||
miterLimit: this.miterLimit
|
||||
}, output);
|
||||
},
|
||||
getBounds: function () {
|
||||
var points = this.points;
|
||||
if (points.length <= 1) { // HACK only moveTo
|
||||
return null;
|
||||
}
|
||||
var minX, minY, maxX, maxY;
|
||||
minX = maxX = points[0].x;
|
||||
minY = maxY = points[0].y;
|
||||
for (var i = 1; i < points.length; i++) {
|
||||
var x = points[i].x, y = points[i].y;
|
||||
if (x < minX) minX = x;
|
||||
if (y < minY) minY = y;
|
||||
if (x > maxX) maxX = x;
|
||||
if (y > maxY) maxY = y;
|
||||
}
|
||||
return {minX: minX, minY: minY, maxX: maxX, maxY: maxY};
|
||||
}
|
||||
};
|
||||
return PolygonTracker;
|
||||
})();
|
||||
|
||||
def.__glue__ = {
|
||||
native: {
|
||||
instance: {
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
const InteractiveObjectDefinition = (function () {
|
||||
var InteractiveObjectDefinition = (function () {
|
||||
var def = {
|
||||
initialize: function () {
|
||||
this._control = document.createElement('div');
|
||||
this._doubleClickEnabled = false;
|
||||
this._hitArea = null;
|
||||
this._mouseEnabled = true;
|
||||
},
|
||||
|
||||
get accessibilityImplementation() {
|
||||
|
@ -17,10 +20,10 @@ const InteractiveObjectDefinition = (function () {
|
|||
notImplemented();
|
||||
},
|
||||
get doubleClickEnabled() {
|
||||
return false;
|
||||
return this._doubleClickEnabled;
|
||||
},
|
||||
set doubleClickEnabled(val) {
|
||||
notImplemented();
|
||||
this._doubleClickEnabled = val;
|
||||
},
|
||||
get focusRect() {
|
||||
return null;
|
||||
|
@ -29,10 +32,10 @@ const InteractiveObjectDefinition = (function () {
|
|||
notImplemented();
|
||||
},
|
||||
get mouseEnabled() {
|
||||
return true;
|
||||
return this._mouseEnabled;
|
||||
},
|
||||
set mouseEnabled(val) {
|
||||
// notImplemented();
|
||||
this._mouseEnabled = val;
|
||||
},
|
||||
get needsSoftKeyboard() {
|
||||
return false;
|
||||
|
@ -40,9 +43,6 @@ const InteractiveObjectDefinition = (function () {
|
|||
set needsSoftKeyboard(val) {
|
||||
notImplemented();
|
||||
},
|
||||
requestSoftKeyboard: function () {
|
||||
notImplemented();
|
||||
},
|
||||
get softKeyboardInputAreaOfInterest() {
|
||||
return null;
|
||||
},
|
||||
|
@ -57,12 +57,17 @@ const InteractiveObjectDefinition = (function () {
|
|||
},
|
||||
get tabIndex() {
|
||||
return -1;
|
||||
},
|
||||
|
||||
requestSoftKeyboard: function () {
|
||||
notImplemented();
|
||||
}
|
||||
};
|
||||
|
||||
const desc = Object.getOwnPropertyDescriptor;
|
||||
var desc = Object.getOwnPropertyDescriptor;
|
||||
|
||||
def.__glue__ = {
|
||||
native: {
|
||||
instance: {
|
||||
tabEnabled: desc(def, "tabEnabled"),
|
||||
tabIndex: desc(def, "tabIndex"),
|
||||
|
@ -75,6 +80,7 @@ const InteractiveObjectDefinition = (function () {
|
|||
contextMenu: desc(def, "contextMenu"),
|
||||
requestSoftKeyboard: def.requestSoftKeyboard
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return def;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const LoaderDefinition = (function () {
|
||||
const WORKERS_ENABLED = true;
|
||||
const LOADER_PATH = 'src/flash/display/Loader.js';
|
||||
const WORKER_SCRIPTS = [
|
||||
var LoaderDefinition = (function () {
|
||||
var WORKERS_ENABLED = true;
|
||||
var LOADER_PATH = 'flash/display/Loader.js';
|
||||
var WORKER_SCRIPTS = [
|
||||
'../../../lib/DataView.js/DataView.js',
|
||||
|
||||
'../util.js',
|
||||
|
@ -33,7 +33,7 @@ const LoaderDefinition = (function () {
|
|||
var commitData;
|
||||
if (loader) {
|
||||
commitData = function (data) {
|
||||
return loader.commitData(data);
|
||||
return loader._commitData(data);
|
||||
};
|
||||
} else {
|
||||
commitData = function (data) {
|
||||
|
@ -77,21 +77,29 @@ const LoaderDefinition = (function () {
|
|||
case SWF_TAG_CODE_DEFINE_SHAPE4:
|
||||
symbol = defineShape(swfTag, symbols);
|
||||
break;
|
||||
case SWF_TAG_CODE_DEFINE_SOUND:
|
||||
symbol = {
|
||||
type: 'sound',
|
||||
id: swfTag.id
|
||||
};
|
||||
break;
|
||||
case SWF_TAG_CODE_DEFINE_SPRITE:
|
||||
var depths = { };
|
||||
var frame = { type: 'frame' };
|
||||
var frames = [];
|
||||
var tags = swfTag.tags;
|
||||
var frameScripts = null;
|
||||
var frameIndex = 0;
|
||||
for (var i = 0, n = tags.length; i < n; i++) {
|
||||
var tag = tags[i];
|
||||
switch (tag.code) {
|
||||
//case SWF_TAG_CODE_DO_ACTION:
|
||||
// var actionBlocks = frame.actionBlocks;
|
||||
// if (!actionBlocks)
|
||||
// frame.actionBlocks = [tag.actionsData];
|
||||
// else
|
||||
// actionBlocks.push(tag.actionsData);
|
||||
// break;
|
||||
case SWF_TAG_CODE_DO_ACTION:
|
||||
if (!frameScripts)
|
||||
frameScripts = [];
|
||||
frameScripts.push(frameIndex);
|
||||
frameScripts.push(tag.actionsData);
|
||||
break;
|
||||
// case SWF_TAG_CODE_DO_INIT_ACTION: ??
|
||||
case SWF_TAG_CODE_FRAME_LABEL:
|
||||
frame.labelName = tag.name;
|
||||
break;
|
||||
|
@ -113,7 +121,7 @@ const LoaderDefinition = (function () {
|
|||
i++;
|
||||
repeat++;
|
||||
}
|
||||
if (repeat > 1)
|
||||
frameIndex += repeat;
|
||||
frame.repeat = repeat;
|
||||
frame.depths = depths;
|
||||
frames.push(frame);
|
||||
|
@ -126,7 +134,8 @@ const LoaderDefinition = (function () {
|
|||
type: 'sprite',
|
||||
id: swfTag.id,
|
||||
frameCount: swfTag.frameCount,
|
||||
frames: frames
|
||||
frames: frames,
|
||||
frameScripts: frameScripts
|
||||
};
|
||||
break;
|
||||
case SWF_TAG_CODE_DEFINE_TEXT:
|
||||
|
@ -146,7 +155,6 @@ const LoaderDefinition = (function () {
|
|||
symbols[swfTag.id] = symbol;
|
||||
commitData(symbol);
|
||||
}
|
||||
|
||||
function parseBytes(bytes) {
|
||||
var depths = { };
|
||||
var frame = { type: 'frame' };
|
||||
|
@ -174,21 +182,20 @@ const LoaderDefinition = (function () {
|
|||
else
|
||||
frame.abcBlocks = [tag.data];
|
||||
break;
|
||||
//case SWF_TAG_CODE_DO_ACTION:
|
||||
// var actionBlocks = frame.actionBlocks;
|
||||
// if (actionBlocks)
|
||||
// actionBlocks.push(tag.actionData);
|
||||
// else
|
||||
// frame.actionBlocks = [tag.actionData];
|
||||
// break;
|
||||
//case SWF_TAG_CODE_DO_INIT_ACTION:
|
||||
// var initActionBlocks = frame.initActionBlocks;
|
||||
// if (!initActionBlocks) {
|
||||
// initActionBlocks = { };
|
||||
// frame.initActionBlocks = initActionBlocks;
|
||||
// }
|
||||
// initActionBlocks[tag.spriteId] = tag.actionsData;
|
||||
// break;
|
||||
case SWF_TAG_CODE_DO_ACTION:
|
||||
var actionBlocks = frame.actionBlocks;
|
||||
if (actionBlocks)
|
||||
actionBlocks.push(tag.actionsData);
|
||||
else
|
||||
frame.actionBlocks = [tag.actionsData];
|
||||
break;
|
||||
case SWF_TAG_CODE_DO_INIT_ACTION:
|
||||
var initActionBlocks = frame.initActionBlocks;
|
||||
if (!initActionBlocks) {
|
||||
frame.initActionBlocks = initActionBlocks = {};
|
||||
}
|
||||
initActionBlocks[tag.spriteId] = tag.actionsData;
|
||||
break;
|
||||
case SWF_TAG_CODE_EXPORT_ASSETS:
|
||||
case SWF_TAG_CODE_SYMBOL_CLASS:
|
||||
var exports = frame.exports;
|
||||
|
@ -221,7 +228,6 @@ const LoaderDefinition = (function () {
|
|||
tagsProcessed++;
|
||||
repeat++;
|
||||
}
|
||||
if (repeat > 1)
|
||||
frame.repeat = repeat;
|
||||
frame.depths = depths;
|
||||
commitData(frame);
|
||||
|
@ -287,28 +293,14 @@ const LoaderDefinition = (function () {
|
|||
this._timeline = [];
|
||||
},
|
||||
|
||||
get contentLoaderInfo() {
|
||||
// XXX: Why is this lazily initialized?
|
||||
var loaderInfo = this._contentLoaderInfo;
|
||||
if (!loaderInfo) {
|
||||
loaderInfo = new flash.display.LoaderInfo;
|
||||
loaderInfo._loader = this;
|
||||
this._contentLoaderInfo = loaderInfo;
|
||||
}
|
||||
return loaderInfo;
|
||||
},
|
||||
|
||||
close: function () {
|
||||
notImplemented();
|
||||
},
|
||||
commitData: function (data) {
|
||||
_commitData: function (data) {
|
||||
var loaderInfo = this.contentLoaderInfo;
|
||||
|
||||
loaderInfo.dispatchEvent(new flash.events.Event("progress"));
|
||||
|
||||
switch (data.command) {
|
||||
case 'init':
|
||||
this.init(data.result);
|
||||
this._init(data.result);
|
||||
break;
|
||||
case 'complete':
|
||||
loaderInfo.dispatchEvent(new flash.events.Event("complete"));
|
||||
|
@ -318,14 +310,16 @@ const LoaderDefinition = (function () {
|
|||
break;
|
||||
default:
|
||||
if (data.id)
|
||||
this.commitSymbol(data);
|
||||
this._commitSymbol(data);
|
||||
else if (data.type === 'frame')
|
||||
this.commitFrame(data);
|
||||
this._commitFrame(data);
|
||||
break;
|
||||
}
|
||||
},
|
||||
commitFrame: function (frame) {
|
||||
_commitFrame: function (frame) {
|
||||
var abcBlocks = frame.abcBlocks;
|
||||
var actionBlocks = frame.actionBlocks;
|
||||
var initActionBlocks = frame.initActionBlocks;
|
||||
var depths = frame.depths;
|
||||
var exports = frame.exports;
|
||||
var loader = this;
|
||||
|
@ -353,8 +347,10 @@ const LoaderDefinition = (function () {
|
|||
|
||||
if (frame.bgcolor)
|
||||
loaderInfo._backgroundColor = frame.bgcolor;
|
||||
else
|
||||
loaderInfo._backgroundColor = { color: 0xFFFFFF, alpha: 0xFF };
|
||||
|
||||
var i = frame.repeat || 1;
|
||||
var i = frame.repeat;
|
||||
while (i--)
|
||||
timeline.push(framePromise);
|
||||
|
||||
|
@ -367,7 +363,7 @@ const LoaderDefinition = (function () {
|
|||
}
|
||||
}
|
||||
|
||||
if (exports) {
|
||||
if (exports && loader._isAvm2Enabled) {
|
||||
for (var i = 0, n = exports.length; i < n; i++) {
|
||||
var asset = exports[i];
|
||||
var symbolPromise = dictionary[asset.symbolId];
|
||||
|
@ -387,8 +383,8 @@ const LoaderDefinition = (function () {
|
|||
}
|
||||
|
||||
var root = loader._content;
|
||||
|
||||
if (!root) {
|
||||
var needRootObject = !root;
|
||||
if (needRootObject) {
|
||||
var stage = loader._stage;
|
||||
var rootClass = avm2.applicationDomain.getClass(val.className);
|
||||
|
||||
|
@ -404,10 +400,15 @@ const LoaderDefinition = (function () {
|
|||
loader._content = root;
|
||||
}
|
||||
|
||||
framePromise.resolve(displayList);
|
||||
root._framesLoaded++;
|
||||
if (!loader._isAvm2Enabled) {
|
||||
loader._initAvm1Bindings(root, needRootObject, frameNum,
|
||||
actionBlocks, initActionBlocks, exports);
|
||||
}
|
||||
|
||||
if (labelName) {
|
||||
framePromise.resolve(displayList);
|
||||
root._framesLoaded += frame.repeat;
|
||||
|
||||
if (labelName && root._frameLabels) {
|
||||
root._frameLabels[labelName] = {
|
||||
__class__: 'flash.display.FrameLabel',
|
||||
frame: frameNum,
|
||||
|
@ -419,7 +420,57 @@ const LoaderDefinition = (function () {
|
|||
loaderInfo.dispatchEvent(new flash.events.Event('init'));
|
||||
});
|
||||
},
|
||||
commitSymbol: function (symbol) {
|
||||
_initAvm1Bindings: function(root, initializeRoot, frameNum,
|
||||
actionBlocks, initActionBlocks, exports) {
|
||||
var avm1Context = this._avm1Context;
|
||||
if (initializeRoot) {
|
||||
var as2Object = root._getAS2Object();
|
||||
avm1Context.globals._root = as2Object;
|
||||
avm1Context.globals._level0 = as2Object;
|
||||
}
|
||||
if (exports) {
|
||||
// HACK mocking the sound clips presence
|
||||
var SoundMock = function(assets) {
|
||||
var clip = {
|
||||
start: function() {},
|
||||
setVolume: function() {}
|
||||
};
|
||||
for (var i = 0; i < assets.length; i++) {
|
||||
if (assets[i].className) {
|
||||
this[assets[i].className] = clip;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var rootAS2Object = root._getAS2Object();
|
||||
rootAS2Object.soundmc = new SoundMock(exports);
|
||||
var soundClass = avm2.systemDomain.getClass("flash.display.MovieClip");
|
||||
var soundMock = soundClass.createInstance();
|
||||
soundMock._name = 'soundmc';
|
||||
soundMock._timeline = [new Promise];
|
||||
soundMock._timeline[0].resolve([]);
|
||||
soundMock._exports = exports;
|
||||
soundMock.$as2Object = rootAS2Object.soundmc;
|
||||
root.addChild(soundMock);
|
||||
}
|
||||
if (initActionBlocks) {
|
||||
// HACK using symbol init actions as regular action blocks, the spec has a note
|
||||
// "DoAction tag is not the same as specifying them in a DoInitAction tag"
|
||||
for (var symbolId in initActionBlocks) {
|
||||
root.addFrameScript(frameNum - 1, function(actionBlock) {
|
||||
return executeActions(actionBlock, avm1Context, avm1Context.globals._root, exports);
|
||||
}.bind(root, initActionBlocks[symbolId]));
|
||||
}
|
||||
}
|
||||
if (actionBlocks) {
|
||||
for (var i = 0; i < actionBlocks.length; i++) {
|
||||
root.addFrameScript(frameNum - 1, function(actionBlock) {
|
||||
return executeActions(actionBlock, avm1Context, avm1Context.globals._root, exports);
|
||||
}.bind(root, actionBlocks[i]));
|
||||
}
|
||||
}
|
||||
},
|
||||
_commitSymbol: function (symbol) {
|
||||
var dependencies = symbol.require;
|
||||
var dictionary = this._dictionary;
|
||||
var promiseQueue = [];
|
||||
|
@ -437,7 +488,37 @@ const LoaderDefinition = (function () {
|
|||
|
||||
switch (symbol.type) {
|
||||
case 'button':
|
||||
var states = { };
|
||||
for (var stateName in symbol.states) {
|
||||
var children = [];
|
||||
|
||||
var depths = symbol.states[stateName];
|
||||
for (var depth in depths) {
|
||||
var cmd = depths[depth];
|
||||
if (cmd && cmd.symbolId) {
|
||||
var childPromise = dictionary[cmd.symbolId];
|
||||
if (childPromise && !childPromise.resolved)
|
||||
promiseQueue.push(childPromise);
|
||||
}
|
||||
children.push(childPromise);
|
||||
}
|
||||
|
||||
if (children.length === 1) {
|
||||
states[stateName] = children[0];
|
||||
} else {
|
||||
var statePromise = new Promise;
|
||||
stateInfo = { };
|
||||
stateInfo.className = 'flash.display.Sprite';
|
||||
stateInfo.props = { children: children };
|
||||
statePromise.resolve(stateInfo);
|
||||
states[stateName] = statePromise;
|
||||
}
|
||||
}
|
||||
|
||||
symbolInfo.className = 'flash.display.SimpleButton';
|
||||
symbolInfo.props = {
|
||||
states: states
|
||||
};
|
||||
break;
|
||||
case 'font':
|
||||
var charset = fromCharCode.apply(null, symbol.codes);
|
||||
|
@ -462,14 +543,20 @@ const LoaderDefinition = (function () {
|
|||
imgPromise.resolve();
|
||||
};
|
||||
img.src = 'data:' + symbol.mimeType + ';base64,' + btoa(symbol.data);
|
||||
|
||||
promiseQueue.push(imgPromise);
|
||||
symbolInfo.className = 'flash.display.BitmapData';
|
||||
symbolInfo.props = { img: describeProperty(img) };
|
||||
symbolInfo.props = {
|
||||
img: img,
|
||||
width: symbol.width,
|
||||
height: symbol.height
|
||||
};
|
||||
break;
|
||||
case 'label':
|
||||
var drawFn = new Function('d,c,r', symbol.data);
|
||||
symbolInfo.className = 'flash.text.StaticText';
|
||||
symbolInfo.props = {
|
||||
bbox: symbol.bbox,
|
||||
draw: function (c, r) {
|
||||
return drawFn.call(this, dictionary, c, r);
|
||||
}
|
||||
|
@ -479,29 +566,32 @@ const LoaderDefinition = (function () {
|
|||
var drawFn = new Function('d,c,r', symbol.data);
|
||||
symbolInfo.className = 'flash.text.TextField';
|
||||
symbolInfo.props = {
|
||||
bbox: symbol.bbox,
|
||||
draw: function (c, r) {
|
||||
return drawFn.call(this, dictionary, c, r);
|
||||
},
|
||||
text: symbol.value
|
||||
text: symbol.value,
|
||||
variableName: symbol.variableName
|
||||
};
|
||||
break;
|
||||
case 'shape':
|
||||
var bbox = symbol.bbox;
|
||||
var createGraphicsData = new Function('d,r', 'return ' + symbol.data);
|
||||
var graphics = new flash.display.Graphics;
|
||||
graphics._scale = 0.05;
|
||||
graphics.drawGraphicsData(createGraphicsData(dictionary, 0));
|
||||
|
||||
symbolInfo.className = 'flash.display.Shape';
|
||||
symbolInfo.props = {
|
||||
bbox: {
|
||||
left: bbox.left / 20,
|
||||
top: bbox.top / 20,
|
||||
right: bbox.right / 20,
|
||||
bottom: bbox.bottom / 20
|
||||
},
|
||||
bbox: symbol.bbox,
|
||||
graphics: graphics
|
||||
};
|
||||
|
||||
symbolPromise.then(function () {
|
||||
graphics.drawGraphicsData(createGraphicsData(dictionary, 0));
|
||||
});
|
||||
break;
|
||||
case 'sound':
|
||||
symbolInfo.className = 'flash.media.Sound';
|
||||
symbolInfo.props = { };
|
||||
break;
|
||||
case 'sprite':
|
||||
var frameCount = symbol.frameCount;
|
||||
|
@ -537,7 +627,7 @@ const LoaderDefinition = (function () {
|
|||
};
|
||||
}
|
||||
|
||||
var j = frame.repeat || 1;
|
||||
var j = frame.repeat;
|
||||
while (j--)
|
||||
timeline.push(framePromise);
|
||||
|
||||
|
@ -549,6 +639,7 @@ const LoaderDefinition = (function () {
|
|||
timeline: timeline,
|
||||
framesLoaded: frameCount,
|
||||
frameLabels: frameLabels,
|
||||
frameScripts: symbol.frameScripts,
|
||||
totalFrames: frameCount
|
||||
};
|
||||
break;
|
||||
|
@ -559,30 +650,16 @@ const LoaderDefinition = (function () {
|
|||
symbolPromise.resolve(symbolInfo);
|
||||
});
|
||||
},
|
||||
getSymbolInfoByName: function (className) {
|
||||
var dictionary = this._dictionary;
|
||||
for (var id in dictionary) {
|
||||
var promise = dictionary[id];
|
||||
var symbolInfo = promise.value;
|
||||
if (symbolInfo && symbolInfo.className === className)
|
||||
return symbolInfo;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
getSymbolInfoById: function (id) {
|
||||
var promise = this._dictionary[id];
|
||||
return promise ? promise.value : null;
|
||||
},
|
||||
init: function (info) {
|
||||
_init: function (info) {
|
||||
var loader = this;
|
||||
|
||||
var loaderInfo = loader.contentLoaderInfo;
|
||||
|
||||
loaderInfo._swfVersion = info.swfVersion;
|
||||
|
||||
var bounds = info.bounds;
|
||||
loaderInfo._width = (bounds.xMax - bounds.xMin) / 20;
|
||||
loaderInfo._height = (bounds.yMax - bounds.yMin) / 20;
|
||||
var bbox = info.bbox;
|
||||
loaderInfo._width = bbox.right - bbox.left;
|
||||
loaderInfo._height = bbox.bottom - bbox.top;
|
||||
|
||||
loaderInfo._frameRate = info.frameRate;
|
||||
|
||||
|
@ -600,37 +677,36 @@ const LoaderDefinition = (function () {
|
|||
loader._vmPromise = vmPromise;
|
||||
|
||||
loader._isAvm2Enabled = info.fileAttributes.doAbc;
|
||||
this.setup();
|
||||
this._setup();
|
||||
},
|
||||
load: function (request, context) {
|
||||
this.loadFrom(request.url);
|
||||
},
|
||||
loadBytes: function (bytes, context) {
|
||||
if (!bytes.length)
|
||||
throw ArgumentError();
|
||||
|
||||
this.loadFrom(bytes);
|
||||
},
|
||||
loadFrom: function (input, context) {
|
||||
_loadFrom: function (input, context) {
|
||||
if (typeof window !== 'undefined' && WORKERS_ENABLED) {
|
||||
var loader = this;
|
||||
var worker = new Worker(SHUMWAY_ROOT + LOADER_PATH);
|
||||
worker.onmessage = function (evt) {
|
||||
loader.commitData(evt.data);
|
||||
loader._commitData(evt.data);
|
||||
};
|
||||
worker.postMessage(input);
|
||||
} else {
|
||||
loadFromWorker(this, input, context);
|
||||
}
|
||||
},
|
||||
setup: function () {
|
||||
_setup: function () {
|
||||
var loader = this;
|
||||
var stage = loader._stage;
|
||||
|
||||
if (loader._isAvm2Enabled) {
|
||||
// HACK: bind the mouse through awful shenanigans.
|
||||
var mouseClass = avm2.systemDomain.getClass("flash.ui.Mouse");
|
||||
mouseClass.dynamicPrototype.$bind(stage);
|
||||
|
||||
loader._vmPromise.resolve();
|
||||
} else {
|
||||
// TODO avm1 initialization
|
||||
// avm1 initialization
|
||||
var loaderInfo = loader.contentLoaderInfo;
|
||||
var avm1Context = new AS2Context(loaderInfo._swfVersion);
|
||||
avm1Context.stage = stage;
|
||||
loader._avm1Context = avm1Context;
|
||||
|
||||
AS2Key.$bind(stage);
|
||||
AS2Mouse.$bind(stage);
|
||||
|
@ -638,6 +714,30 @@ const LoaderDefinition = (function () {
|
|||
loader._vmPromise.resolve();
|
||||
}
|
||||
},
|
||||
|
||||
get contentLoaderInfo() {
|
||||
// XXX: Why is this lazily initialized?
|
||||
var loaderInfo = this._contentLoaderInfo;
|
||||
if (!loaderInfo) {
|
||||
loaderInfo = new flash.display.LoaderInfo;
|
||||
loaderInfo._loader = this;
|
||||
this._contentLoaderInfo = loaderInfo;
|
||||
}
|
||||
return loaderInfo;
|
||||
},
|
||||
|
||||
close: function () {
|
||||
notImplemented();
|
||||
},
|
||||
load: function (request, context) {
|
||||
this._loadFrom(request.url);
|
||||
},
|
||||
loadBytes: function (bytes, context) {
|
||||
if (!bytes.length)
|
||||
throw ArgumentError();
|
||||
|
||||
this._loadFrom(bytes);
|
||||
},
|
||||
unload: function () {
|
||||
notImplemented();
|
||||
},
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const LoaderInfoDefinition = (function () {
|
||||
var LoaderInfoDefinition = (function () {
|
||||
var def = {
|
||||
__class__: 'flash.display.LoaderInfo',
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
function MorphShape() {
|
||||
DisplayObject.call(this);
|
||||
}
|
||||
var MorphShapeDefinition = (function () {
|
||||
var def = {
|
||||
__class__: 'flash.display.MorphShape',
|
||||
};
|
||||
|
||||
MorphShape.prototype = Object.create(DisplayObject.prototype, {
|
||||
__class__: describeInternalProperty('flash.display.MorphShape')
|
||||
});
|
||||
return def;
|
||||
}).call(this);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const MovieClipDefinition = (function () {
|
||||
var MovieClipDefinition = (function () {
|
||||
var def = {
|
||||
__class__: 'flash.display.MovieClip',
|
||||
|
||||
|
@ -16,7 +16,6 @@ const MovieClipDefinition = (function () {
|
|||
this._scenes = { };
|
||||
this._timeline = null;
|
||||
this._totalFrames = 1;
|
||||
this._scenes = { };
|
||||
|
||||
var s = this.symbol;
|
||||
if (s) {
|
||||
|
@ -27,27 +26,265 @@ const MovieClipDefinition = (function () {
|
|||
}
|
||||
},
|
||||
|
||||
addFrameScript: function () {
|
||||
// arguments are pairs of frameIndex and script/function
|
||||
// frameIndex is in range 0..totalFrames-1
|
||||
var frameScripts = this._frameScripts;
|
||||
for (var i = 0, n = arguments.length; i < n; i += 2) {
|
||||
var frameNum = arguments[i] + 1;
|
||||
var fn = arguments[i + 1];
|
||||
var scripts = frameScripts[frameNum];
|
||||
if (scripts)
|
||||
scripts.push(fn);
|
||||
else
|
||||
frameScripts[frameNum] = [fn];
|
||||
}
|
||||
},
|
||||
callFrame: function (frameNum) {
|
||||
_callFrame: function (frameNum) {
|
||||
if (frameNum in this._frameScripts) {
|
||||
var scripts = this._frameScripts[frameNum];
|
||||
for (var i = 0, n = scripts.length; i < n; i++)
|
||||
scripts[i].call(this);
|
||||
}
|
||||
},
|
||||
_getAS2Object: function () {
|
||||
if (!this.$as2Object) {
|
||||
new AS2MovieClip().$attachNativeObject(this);
|
||||
}
|
||||
return this.$as2Object;
|
||||
},
|
||||
_insertChildAtDepth: function (instance, depth) {
|
||||
var children = this._children;
|
||||
var depthMap = this._depthMap;
|
||||
var current = depthMap[depth];
|
||||
var highestDepth = depthMap.length;
|
||||
var replace = false;
|
||||
var index;
|
||||
if (current && current._owned) {
|
||||
replace = true;
|
||||
index = children.indexOf(current);
|
||||
} else {
|
||||
var top = null;
|
||||
for (var i = +depth + 1; i < highestDepth; i++) {
|
||||
var info = depthMap[i];
|
||||
if (info && info._animated) {
|
||||
top = info;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
index = top ? children.indexOf(top) : children.length;
|
||||
}
|
||||
|
||||
children.splice(index, replace, instance);
|
||||
depthMap[depth] = instance;
|
||||
|
||||
if (replace)
|
||||
this._control.replaceChild(instance._control, current._control);
|
||||
else
|
||||
this._control.appendChild(instance._control);
|
||||
|
||||
instance._animated = true;
|
||||
instance._owned = true;
|
||||
instance._parent = this;
|
||||
|
||||
instance.dispatchEvent(new flash.events.Event("added"));
|
||||
},
|
||||
|
||||
_constructSymbol: function(symbolId, name) {
|
||||
var loader = this.loaderInfo._loader;
|
||||
var symbolPromise = loader._dictionary[symbolId];
|
||||
var symbolInfo = symbolPromise.value;
|
||||
// HACK application domain may have the symbol class --
|
||||
// checking which domain has a symbol class
|
||||
var symbolClass = avm2.systemDomain.findClass(symbolInfo.className) ?
|
||||
avm2.systemDomain.getClass(symbolInfo.className) :
|
||||
avm2.applicationDomain.getClass(symbolInfo.className);
|
||||
var instance = symbolClass.createAsSymbol(symbolInfo.props);
|
||||
|
||||
// If we bound the instance to a name, set it.
|
||||
//
|
||||
// XXX: I think this always has to be a trait.
|
||||
if (name)
|
||||
this[Multiname.getPublicQualifiedName(name)] = instance;
|
||||
|
||||
// Call the constructor now that we've made the symbol instance,
|
||||
// instantiated all its children, and set the display list-specific
|
||||
// properties.
|
||||
//
|
||||
// XXX: I think we're supposed to throw if the symbol class
|
||||
// constructor is not nullary.
|
||||
symbolClass.instance.call(instance);
|
||||
|
||||
instance._markAsDirty();
|
||||
instance._name = name || null;
|
||||
|
||||
instance.dispatchEvent(new flash.events.Event("load"));
|
||||
|
||||
return instance;
|
||||
},
|
||||
|
||||
_gotoFrame: function (frameNum, scene) {
|
||||
if (frameNum > this._totalFrames)
|
||||
frameNum = 1;
|
||||
|
||||
if (frameNum > this.framesLoaded)
|
||||
frameNum = this.framesLoaded;
|
||||
|
||||
var currentFrame = this._currentFrame;
|
||||
|
||||
if (frameNum === currentFrame)
|
||||
return;
|
||||
|
||||
if (frameNum === 0) {
|
||||
// HACK there is no data for this frame, but AS2 can jump to this frame index
|
||||
this._currentFrame = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
while (currentFrame++ < frameNum) {
|
||||
var children = this._children;
|
||||
var depthMap = this._depthMap;
|
||||
var framePromise = this._timeline[currentFrame - 1];
|
||||
var highestDepth = depthMap.length;
|
||||
var displayList = framePromise.value;
|
||||
var loader = this.loaderInfo._loader;
|
||||
|
||||
for (var depth in displayList) {
|
||||
this._markAsDirty();
|
||||
|
||||
var cmd = displayList[depth];
|
||||
var current = depthMap[depth];
|
||||
if (cmd === null) {
|
||||
if (current && current._owned) {
|
||||
var index = children.indexOf(current);
|
||||
var removed = children.splice(index, 1);
|
||||
this._control.removeChild(current._control);
|
||||
|
||||
removed[0].dispatchEvent(new flash.events.Event("removed"));
|
||||
|
||||
if (depth < highestDepth)
|
||||
depthMap[depth] = undefined;
|
||||
else
|
||||
depthMap.splice(-1);
|
||||
}
|
||||
} else {
|
||||
var clipDepth = cmd.clipDepth;
|
||||
var cxform = cmd.cxform;
|
||||
var matrix = cmd.matrix;
|
||||
var target;
|
||||
|
||||
if (cmd.symbolId) {
|
||||
var name = cmd.name;
|
||||
var events = cmd.hasEvents ? cmd.events : null;
|
||||
var instance = this._constructSymbol(cmd.symbolId, name);
|
||||
if (!loader._isAvm2Enabled) {
|
||||
this._initAvm1Bindings(instance, name, events);
|
||||
}
|
||||
this._insertChildAtDepth(instance, depth);
|
||||
if (current && current._owned) {
|
||||
if (!clipDepth)
|
||||
clipDepth = current._clipDepth;
|
||||
if (!cxform)
|
||||
cxform = current._cxform;
|
||||
if (!matrix)
|
||||
matrix = current._currentTransform;
|
||||
}
|
||||
target = instance;
|
||||
} else if (current && current._animated) {
|
||||
target = current;
|
||||
}
|
||||
|
||||
if (clipDepth)
|
||||
target._clipDepth = clipDepth;
|
||||
if (cxform)
|
||||
target._cxform = cxform;
|
||||
|
||||
if (matrix) {
|
||||
var a = matrix.a;
|
||||
var b = matrix.b;
|
||||
var c = matrix.c;
|
||||
var d = matrix.d;
|
||||
|
||||
target._rotation = Math.atan2(b, a) * 180 / Math.PI;
|
||||
var sx = Math.sqrt(a * a + b * b);
|
||||
target._scaleX = a > 0 ? sx : -sx;
|
||||
var sy = Math.sqrt(d * d + c * c);
|
||||
target._scaleY = d > 0 ? sy : -sy;
|
||||
var x = target._x = matrix.tx;
|
||||
var y = target._y = matrix.ty;
|
||||
|
||||
target._currentTransform = matrix;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this._currentFrame = frameNum;
|
||||
this._requestCallFrame();
|
||||
},
|
||||
_requestCallFrame: function () {
|
||||
this._scriptExecutionPending = true;
|
||||
this.stage._callFrameRequested = true;
|
||||
},
|
||||
_initAvm1Bindings: function (instance, name, events) {
|
||||
var loader = this.loaderInfo._loader;
|
||||
var avm1Context = loader._avm1Context;
|
||||
var symbolProps = instance.symbol;
|
||||
if (symbolProps.frameScripts) {
|
||||
var frameScripts = symbolProps.frameScripts;
|
||||
for (var i = 0; i < frameScripts.length; i += 2) {
|
||||
var frameIndex = frameScripts[i];
|
||||
var actionBlock = frameScripts[i + 1];
|
||||
instance.addFrameScript(frameIndex, function(actionBlock) {
|
||||
return executeActions(actionBlock, avm1Context, this._getAS2Object());
|
||||
}.bind(instance, actionBlock));
|
||||
}
|
||||
}
|
||||
if (symbolProps.variableName) {
|
||||
var variableName = symbolProps.variableName;
|
||||
var i = variableName.lastIndexOf('.');
|
||||
var clip;
|
||||
if (i >= 0) {
|
||||
var targetPath = variableName.substring(0, i).split('.');
|
||||
if (targetPath[0] == '_root') {
|
||||
clip = this.root._getAS2Object();
|
||||
targetPath.shift();
|
||||
} else {
|
||||
clip = instance._getAS2Object();
|
||||
}
|
||||
while (targetPath.length > 0) {
|
||||
if (!(targetPath[0] in clip))
|
||||
throw 'Cannot find ' + variableName + ' variable';
|
||||
clip = clip[targetPath.shift()];
|
||||
}
|
||||
variableName = variableName.substring(i + 1);
|
||||
} else
|
||||
clip = instance._getAS2Object();
|
||||
if (!(variableName in clip))
|
||||
clip[variableName] = instance.text;
|
||||
instance._refreshAS2Variables = function() {
|
||||
instance.text = clip[variableName];
|
||||
};
|
||||
}
|
||||
|
||||
if (events) {
|
||||
var eventsBound = [];
|
||||
for (var i = 0; i < events.length; i++) {
|
||||
var event = events[i];
|
||||
if (event.eoe) {
|
||||
break;
|
||||
}
|
||||
var fn = function(actionBlock) {
|
||||
return executeActions(actionBlock, avm1Context, this._getAS2Object());
|
||||
}.bind(instance, event.actionsData);
|
||||
for (var eventName in event) {
|
||||
if (eventName.indexOf("on") !== 0 || !event[eventName])
|
||||
continue;
|
||||
var avm2EventName = eventName[2].toLowerCase() + eventName.substring(3);
|
||||
this.addEventListener(avm2EventName, fn, false);
|
||||
eventsBound.push({name: avm2EventName, fn: fn});
|
||||
}
|
||||
}
|
||||
if (eventsBound.length > 0) {
|
||||
instance.addEventListener('removed', function (eventsBound) {
|
||||
for (var i = 0; i < eventsBound.length; i++) {
|
||||
this.removeEventListener(eventsBound[i].name, eventsBound[i].fn, false);
|
||||
}
|
||||
}.bind(this, eventsBound), false);
|
||||
}
|
||||
}
|
||||
if (name) {
|
||||
this._getAS2Object()[name] = instance._getAS2Object();
|
||||
}
|
||||
},
|
||||
|
||||
get currentFrame() {
|
||||
return this._currentFrame;
|
||||
},
|
||||
|
@ -72,142 +309,48 @@ const MovieClipDefinition = (function () {
|
|||
get framesLoaded() {
|
||||
return this._framesLoaded;
|
||||
},
|
||||
gotoFrame: function (frameNum, scene) {
|
||||
if (frameNum > this._totalFrames)
|
||||
frameNum = 1;
|
||||
get totalFrames() {
|
||||
return this._totalFrames;
|
||||
},
|
||||
get trackAsMenu() {
|
||||
return false;
|
||||
},
|
||||
set trackAsMenu(val) {
|
||||
notImplemented();
|
||||
},
|
||||
|
||||
if (frameNum > this.framesLoaded)
|
||||
frameNum = this.framesLoaded;
|
||||
|
||||
if (frameNum === this._currentFrame) {
|
||||
return;
|
||||
}
|
||||
|
||||
var children = this._children;
|
||||
var depthMap = this._depthMap;
|
||||
var framePromise = this._timeline[frameNum - 1];
|
||||
var highestDepth = depthMap.length;
|
||||
var displayList = framePromise.value;
|
||||
var loader = this.loaderInfo._loader;
|
||||
var newInstances = [];
|
||||
|
||||
for (var depth in displayList) {
|
||||
var cmd = displayList[depth];
|
||||
var current = depthMap[depth];
|
||||
if (cmd === null) {
|
||||
if (current && current._owned) {
|
||||
var index = children.indexOf(current);
|
||||
children.splice(index, 1);
|
||||
|
||||
if (depth <= highestDepth)
|
||||
depthMap[depth] = undefined;
|
||||
addFrameScript: function () {
|
||||
// arguments are pairs of frameIndex and script/function
|
||||
// frameIndex is in range 0..totalFrames-1
|
||||
var frameScripts = this._frameScripts;
|
||||
for (var i = 0, n = arguments.length; i < n; i += 2) {
|
||||
var frameNum = arguments[i] + 1;
|
||||
var fn = arguments[i + 1];
|
||||
var scripts = frameScripts[frameNum];
|
||||
if (scripts)
|
||||
scripts.push(fn);
|
||||
else
|
||||
depthMap.splice(-1);
|
||||
frameScripts[frameNum] = [fn];
|
||||
}
|
||||
} else {
|
||||
var cxform = cmd.cxform;
|
||||
var matrix = cmd.matrix;
|
||||
var target;
|
||||
|
||||
if (cmd.symbolId) {
|
||||
var index = 0;
|
||||
var symbolInfo = loader.getSymbolInfoById(cmd.symbolId);
|
||||
// HACK application domain may have the symbol class --
|
||||
// checking which domain has a symbol class
|
||||
var symbolClass = avm2.systemDomain.findClass(symbolInfo.className) ?
|
||||
avm2.systemDomain.getClass(symbolInfo.className) :
|
||||
avm2.applicationDomain.getClass(symbolInfo.className);
|
||||
var instance = symbolClass.createAsSymbol(symbolInfo.props);
|
||||
var replace = 0;
|
||||
|
||||
if (current && current._owned) {
|
||||
if (!cxform)
|
||||
cxform = current._cxform;
|
||||
index = children.indexOf(current);
|
||||
if (!matrix)
|
||||
matrix = current.transform.matrix;
|
||||
replace = 1;
|
||||
} else {
|
||||
var top = null;
|
||||
for (var i = +depth + 1; i < highestDepth; i++) {
|
||||
var info = depthMap[i];
|
||||
if (info && info._animated)
|
||||
top = info;
|
||||
}
|
||||
|
||||
index = top ? children.indexOf(top) : children.length;
|
||||
}
|
||||
|
||||
children.splice(index, replace, instance);
|
||||
depthMap[depth] = instance;
|
||||
|
||||
target = instance;
|
||||
|
||||
// If we bound the instance to a name, set it.
|
||||
//
|
||||
// XXX: I think this always has to be a trait.
|
||||
if (cmd.name) {
|
||||
this[Multiname.getPublicQualifiedName(cmd.name)] = instance;
|
||||
}
|
||||
|
||||
// Call the constructor now that we've made the symbol instance,
|
||||
// instantiated all its children, and set the display list-specific
|
||||
// properties.
|
||||
//
|
||||
// XXX: I think we're supposed to throw if the symbol class
|
||||
// constructor is not nullary.
|
||||
symbolClass.instance.call(instance);
|
||||
|
||||
instance._animated = true;
|
||||
instance._owned = true;
|
||||
instance._parent = this;
|
||||
} else if (current && current._animated) {
|
||||
target = current;
|
||||
}
|
||||
|
||||
if (cxform)
|
||||
target._cxform = cxform;
|
||||
if (matrix) {
|
||||
target._rotation = Math.atan2(matrix.b, matrix.a) * 180 / Math.PI;
|
||||
var sx = Math.sqrt(matrix.a * matrix.a + matrix.b * matrix.b);
|
||||
target._scaleX = matrix.a > 0 ? sx : -sx;
|
||||
var sy = Math.sqrt(matrix.d * matrix.d + matrix.c * matrix.c);
|
||||
target._scaleY = matrix.d > 0 ? sy : -sy;
|
||||
target._x = matrix.tx / 20;
|
||||
target._y = matrix.ty / 20;
|
||||
target._currentTransformMatrix = {
|
||||
a: matrix.a,
|
||||
b: matrix.b,
|
||||
c: matrix.c,
|
||||
d: matrix.d,
|
||||
tx: target._x,
|
||||
ty: target._y
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this._currentFrame = frameNum;
|
||||
this._scriptExecutionPending = true;
|
||||
},
|
||||
gotoAndPlay: function (frame, scene) {
|
||||
this.play();
|
||||
if (isNaN(frame))
|
||||
this.gotoLabel(frame);
|
||||
else
|
||||
this.gotoFrame(frame);
|
||||
this._gotoFrame(frame);
|
||||
},
|
||||
gotoAndStop: function (frame, scene) {
|
||||
this.stop();
|
||||
if (isNaN(frame))
|
||||
this.gotoLabel(frame);
|
||||
else
|
||||
this.gotoFrame(frame);
|
||||
this._gotoFrame(frame);
|
||||
},
|
||||
gotoLabel: function (labelName) {
|
||||
var frameLabel = this._frameLabels[labelName];
|
||||
if (frameLabel)
|
||||
this.gotoFrame(frameLabel.frame);
|
||||
this._gotoFrame(frameLabel.frame);
|
||||
},
|
||||
isPlaying: function () {
|
||||
return this._isPlaying;
|
||||
|
@ -229,19 +372,10 @@ const MovieClipDefinition = (function () {
|
|||
},
|
||||
stop: function () {
|
||||
this._isPlaying = false;
|
||||
},
|
||||
get totalFrames() {
|
||||
return this._totalFrames;
|
||||
},
|
||||
get trackAsMenu() {
|
||||
return false;
|
||||
},
|
||||
set trackAsMenu(val) {
|
||||
notImplemented();
|
||||
}
|
||||
};
|
||||
|
||||
const desc = Object.getOwnPropertyDescriptor;
|
||||
var desc = Object.getOwnPropertyDescriptor;
|
||||
|
||||
def.__glue__ = {
|
||||
native: {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const ShapeDefinition = (function () {
|
||||
var ShapeDefinition = (function () {
|
||||
var def = {
|
||||
__class__: 'flash.display.Shape',
|
||||
|
||||
|
|
|
@ -1,3 +1,131 @@
|
|||
const SimpleButtonDefinition = {
|
||||
__class__: 'flash.display.SimpleButton'
|
||||
var SimpleButtonDefinition = (function () {
|
||||
var def = {
|
||||
__class__: 'flash.display.SimpleButton',
|
||||
|
||||
get downState() {
|
||||
return this._downState;
|
||||
},
|
||||
set downState(val) {
|
||||
this._downState = val;
|
||||
},
|
||||
get hitTestState() {
|
||||
return this._hitArea;
|
||||
},
|
||||
set hitTestState(val) {
|
||||
this._hitArea = val;
|
||||
},
|
||||
get overState() {
|
||||
return this._overState;
|
||||
},
|
||||
set overState(val) {
|
||||
this._overState = val;
|
||||
},
|
||||
get upState() {
|
||||
return this._upState;
|
||||
},
|
||||
set upState(val) {
|
||||
this._upState = val;
|
||||
},
|
||||
get useHandCursor() {
|
||||
return this._useHandCursor;
|
||||
},
|
||||
set useHandCursor(val) {
|
||||
this._useHandCursor = val;
|
||||
},
|
||||
|
||||
_getAS2Object: function () {
|
||||
if (!this.$as2Object) {
|
||||
new AS2Button().$attachNativeObject(this);
|
||||
}
|
||||
return this.$as2Object;
|
||||
},
|
||||
initialize: function () {
|
||||
this._downState = null;
|
||||
this._hitArea = null;
|
||||
this._isMouseDown = false;
|
||||
this._isMouseOver = false;
|
||||
this._mouseChildren = false;
|
||||
this._overState = null;
|
||||
this._upState = null;
|
||||
this._useHandCursor = true;
|
||||
|
||||
var s = this.symbol;
|
||||
if (s) {
|
||||
var states = s.states;
|
||||
if (states.down)
|
||||
this._downState = createState(states.down.value, this);
|
||||
if (states.hitTest)
|
||||
this._hitArea = createState(states.hitTest.value, this);
|
||||
if (states.over)
|
||||
this._overState = createState(states.over.value, this);
|
||||
if (states.up)
|
||||
this._upState = createState(states.up.value, this);
|
||||
}
|
||||
|
||||
// binding mouse events
|
||||
var MouseEventClass = avm2.systemDomain.getClass("flash.events.MouseEvent");
|
||||
this.addEventListener(MouseEventClass.MOUSE_DOWN, function (evt) {
|
||||
this._isMouseDown = true;
|
||||
this._updateButton();
|
||||
}.bind(this), true);
|
||||
this.addEventListener(MouseEventClass.MOUSE_OUT, function (evt) {
|
||||
this._isMouseOver = false;
|
||||
this._updateButton();
|
||||
}.bind(this), true);
|
||||
this.addEventListener(MouseEventClass.MOUSE_OVER, function (evt) {
|
||||
this._isMouseOver = true;
|
||||
this._updateButton();
|
||||
}.bind(this), true);
|
||||
this.addEventListener(MouseEventClass.MOUSE_UP, function (evt) {
|
||||
this._isMouseDown = false;
|
||||
this._updateButton();
|
||||
}.bind(this), true);
|
||||
},
|
||||
|
||||
_updateButton: function () {
|
||||
this._markAsDirty();
|
||||
|
||||
var state = this._upState;
|
||||
if (this._isMouseDown && this._isMouseOver && this._downState)
|
||||
state = this._downState;
|
||||
else if (this._isMouseOver && this._overState)
|
||||
state = this._overState;
|
||||
this._children = [state];
|
||||
},
|
||||
|
||||
get shouldHaveHandCursor() {
|
||||
return this._useHandCursor;
|
||||
}
|
||||
};
|
||||
|
||||
function createState(symbolInfo, parent) {
|
||||
if (!symbolInfo)
|
||||
return null;
|
||||
|
||||
var symbolClass = avm2.systemDomain.findClass(symbolInfo.className) ?
|
||||
avm2.systemDomain.getClass(symbolInfo.className) :
|
||||
avm2.applicationDomain.getClass(symbolInfo.className);
|
||||
var instance = symbolClass.createAsSymbol(symbolInfo.props);
|
||||
symbolClass.instance.call(instance);
|
||||
instance._animated = true;
|
||||
instance._parent = parent;
|
||||
return instance;
|
||||
}
|
||||
|
||||
var desc = Object.getOwnPropertyDescriptor;
|
||||
|
||||
def.__glue__ = {
|
||||
native: {
|
||||
instance: {
|
||||
downState: desc(def, "downState"),
|
||||
hitTestState: desc(def, "hitTestState"),
|
||||
overState: desc(def, "overState"),
|
||||
upState: desc(def, "upState"),
|
||||
useHandCursor: desc(def, "useHandCursor"),
|
||||
_updateButton: def._updateButton,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return def;
|
||||
}).call(this);
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
const SpriteDefinition = (function () {
|
||||
var SpriteDefinition = (function () {
|
||||
var def = {
|
||||
__class__: 'flash.display.Sprite',
|
||||
|
||||
initialize: function () {
|
||||
this._buttonMode = false;
|
||||
this._useHandCursor = true;
|
||||
var s = this.symbol;
|
||||
if (s) {
|
||||
this._graphics = s.graphics || new flash.display.Graphics;
|
||||
|
@ -11,20 +13,36 @@ const SpriteDefinition = (function () {
|
|||
}
|
||||
},
|
||||
|
||||
_constructChildren: function () {
|
||||
var children = this._children;
|
||||
for (var i = 0, n = children.length; i < n; i++) {
|
||||
var symbolPromise = children[i];
|
||||
var symbolInfo = symbolPromise.value;
|
||||
var symbolClass = avm2.systemDomain.findClass(symbolInfo.className) ?
|
||||
avm2.systemDomain.getClass(symbolInfo.className) :
|
||||
avm2.applicationDomain.getClass(symbolInfo.className);
|
||||
var child = symbolClass.createAsSymbol(symbolInfo.props);
|
||||
symbolClass.instance.call(child);
|
||||
children[i] = child;
|
||||
child._owned = false;
|
||||
child._parent = this;
|
||||
}
|
||||
},
|
||||
|
||||
get buttonMode() {
|
||||
return false;
|
||||
return this._buttonMode;
|
||||
},
|
||||
set buttonMode(val) {
|
||||
notImplemented();
|
||||
this._buttonMode = val;
|
||||
},
|
||||
get graphics() {
|
||||
return this._graphics;
|
||||
},
|
||||
get hitArea() {
|
||||
return null;
|
||||
return this._hitArea;
|
||||
},
|
||||
set hitArea(val) {
|
||||
notImplemented();
|
||||
this._hitArea = val;
|
||||
},
|
||||
get soundTransform() {
|
||||
notImplemented();
|
||||
|
@ -32,6 +50,17 @@ const SpriteDefinition = (function () {
|
|||
set soundTransform(val) {
|
||||
notImplemented();
|
||||
},
|
||||
get useHandCursor() {
|
||||
return this._useHandCursor;
|
||||
},
|
||||
set useHandCursor(val) {
|
||||
this._useHandCursor = val;
|
||||
this._stage._syncCursor();
|
||||
},
|
||||
get shouldHaveHandCursor() {
|
||||
return this._buttonMode && this._useHandCursor;
|
||||
},
|
||||
|
||||
startDrag: function (lockCenter, bounds) {
|
||||
notImplemented();
|
||||
},
|
||||
|
@ -43,19 +72,10 @@ const SpriteDefinition = (function () {
|
|||
},
|
||||
stopTouchDrag: function (touchPointID) {
|
||||
notImplemented();
|
||||
},
|
||||
get useHandCursor() {
|
||||
return true;
|
||||
},
|
||||
set useHandCursor(val) {
|
||||
notImplemented();
|
||||
},
|
||||
constructChildren: function () {
|
||||
// notImplemented();
|
||||
}
|
||||
};
|
||||
|
||||
const desc = Object.getOwnPropertyDescriptor;
|
||||
var desc = Object.getOwnPropertyDescriptor;
|
||||
|
||||
def.__glue__ = {
|
||||
native: {
|
||||
|
@ -67,7 +87,7 @@ const SpriteDefinition = (function () {
|
|||
stopDrag: def.stopDrag,
|
||||
startTouchDrag: def.startTouchDrag,
|
||||
stopTouchDrag: def.stopTouchDrag,
|
||||
constructChildren: def.constructChildren,
|
||||
constructChildren: def._constructChildren,
|
||||
hitArea: desc(def, "hitArea"),
|
||||
useHandCursor: desc(def, "useHandCursor"),
|
||||
soundTransform: desc(def, "soundTransform")
|
||||
|
@ -77,4 +97,3 @@ const SpriteDefinition = (function () {
|
|||
|
||||
return def;
|
||||
}).call(this);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const StageDefinition = (function () {
|
||||
var StageDefinition = (function () {
|
||||
var COLOR_CORRECTION_DEFAULT = 'default';
|
||||
var COLOR_CORRECTION_OFF = 'on';
|
||||
var COLOR_CORRECTION_ON = 'off';
|
||||
|
@ -31,8 +31,14 @@ const StageDefinition = (function () {
|
|||
|
||||
initialize: function () {
|
||||
this._color = 0xFFFFFFFF;
|
||||
this._focus = null;
|
||||
this._clickTarget = null;
|
||||
this._showRedrawRegions = false;
|
||||
this._stage = this;
|
||||
this._stageHeight = 0;
|
||||
this._stageWidth = 0;
|
||||
this._transform = { };
|
||||
this._mouseJustLeft = false;
|
||||
},
|
||||
|
||||
get allowsFullScreen() {
|
||||
|
@ -116,6 +122,7 @@ const StageDefinition = (function () {
|
|||
get wmodeGPU() {
|
||||
return false;
|
||||
},
|
||||
|
||||
invalidate: function () {
|
||||
notImplemented();
|
||||
},
|
||||
|
@ -124,7 +131,7 @@ const StageDefinition = (function () {
|
|||
}
|
||||
};
|
||||
|
||||
const desc = Object.getOwnPropertyDescriptor;
|
||||
var desc = Object.getOwnPropertyDescriptor;
|
||||
|
||||
// TODO
|
||||
def.__glue__ = {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const EventDefinition = (function () {
|
||||
var EventDefinition = (function () {
|
||||
var EVENT_PHASE_CAPTURING_PHASE = 1;
|
||||
var EVENT_PHASE_AT_TARGET = 2;
|
||||
var EVENT_PHASE_BUBBLING_PHASE = 3;
|
||||
|
@ -13,17 +13,21 @@ const EventDefinition = (function () {
|
|||
this._target = null;
|
||||
},
|
||||
|
||||
ctor: function (type, bubbles, cancelable) {
|
||||
this.type = type;
|
||||
this.bubbles = !!bubbles;
|
||||
this.cancelable = !!cancelable;
|
||||
},
|
||||
get currentTarget() {
|
||||
return this._currentTarget;
|
||||
},
|
||||
get eventPhase() {
|
||||
return this._eventPhase;
|
||||
},
|
||||
get target() {
|
||||
return this._target;
|
||||
},
|
||||
|
||||
ctor: function (type, bubbles, cancelable) {
|
||||
this.type = type;
|
||||
this.bubbles = !!bubbles;
|
||||
this.cancelable = !!cancelable;
|
||||
},
|
||||
isDefaultPrevented: function () {
|
||||
return this._isDefaultPrevented;
|
||||
},
|
||||
|
@ -35,13 +39,10 @@ const EventDefinition = (function () {
|
|||
},
|
||||
stopPropagation: function () {
|
||||
notImplemented();
|
||||
},
|
||||
get target() {
|
||||
return this._target;
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
const desc = Object.getOwnPropertyDescriptor;
|
||||
var desc = Object.getOwnPropertyDescriptor;
|
||||
|
||||
def.__glue__ = {
|
||||
script: {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const EventDispatcherDefinition = (function () {
|
||||
var EventDispatcherDefinition = (function () {
|
||||
var CUSTOM_DOM_EVENT_PREFIX = 'shumway.';
|
||||
|
||||
var def = {
|
||||
|
@ -13,7 +13,6 @@ const EventDispatcherDefinition = (function () {
|
|||
ctor: function (target) {
|
||||
this._target = target;
|
||||
},
|
||||
|
||||
addEventListener: function (type, listener, useCapture, prio, useWeakReference) {
|
||||
if (typeof listener !== 'function')
|
||||
throw ArgumentError();
|
||||
|
@ -89,12 +88,14 @@ const EventDispatcherDefinition = (function () {
|
|||
var handlers = useCapture ? this._captureHandlers : this._handlers;
|
||||
var handler = handlers[type];
|
||||
if (handler) {
|
||||
var listeners = handler.listeners;
|
||||
var i = listeners.indexOf(listener);
|
||||
if (i > -1)
|
||||
listeners.splice(i, 1);
|
||||
|
||||
if (!listeners.length) {
|
||||
var queue = handler.queue;
|
||||
for (var i = 0; i < queue.length; i++) {
|
||||
if (queue[i].listener === listener) {
|
||||
queue.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!queue.length) {
|
||||
if (this._control)
|
||||
this._control.removeEventListener(CUSTOM_DOM_EVENT_PREFIX + type, handler, useCapture);
|
||||
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
const KeyboardEventDefinition = (function () {
|
||||
var KeyboardEventDefinition = (function () {
|
||||
var def = {
|
||||
__class__: 'flash.events.KeyboardEvent',
|
||||
|
||||
updateAfterEvent: function () {
|
||||
notImplemented();
|
||||
},
|
||||
get keyCode() {
|
||||
return this.private$flash$events$KeyboardEvent$m_keyCode;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const MouseEventDefinition = (function () {
|
||||
var MouseEventDefinition = (function () {
|
||||
var def = {
|
||||
__class__: 'flash.events.MouseEvent',
|
||||
|
||||
|
@ -31,7 +31,7 @@ const MouseEventDefinition = (function () {
|
|||
ROLL_OUT: 'public ROLL_OUT',
|
||||
ROLL_OVER: 'public ROLL_OVER'
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
native: {
|
||||
instance: {
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
var TextEventDefinition = (function () {
|
||||
var def = {
|
||||
__class__: 'flash.events.TextEvent'
|
||||
};
|
||||
|
||||
def.__glue__ = {
|
||||
script: {
|
||||
static: {
|
||||
LINK: "public LINK",
|
||||
TEXT_INPUT: "public TEXT_INPUT"
|
||||
}
|
||||
},
|
||||
|
||||
native: {
|
||||
instance: {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return def;
|
||||
}).call(this);
|
|
@ -1,4 +1,4 @@
|
|||
const TimerEventDefinition = (function () {
|
||||
var TimerEventDefinition = (function () {
|
||||
var def = {
|
||||
__class__: 'flash.events.TimerEvent',
|
||||
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
var ExternalInterfaceDefinition = (function () {
|
||||
var def = {};
|
||||
|
||||
function getAvailable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
def.__glue__ = {
|
||||
native: {
|
||||
static: {
|
||||
available: { get: getAvailable }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return def;
|
||||
}).call(this);
|
|
@ -1,4 +1,4 @@
|
|||
const ColorTransformDefinition = (function () {
|
||||
var ColorTransformDefinition = (function () {
|
||||
var def = {
|
||||
__class__: 'flash.geom.ColorTransform',
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const MatrixDefinition = (function () {
|
||||
var MatrixDefinition = (function () {
|
||||
var def = {
|
||||
__class__: 'flash.geom.Matrix',
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const PointDefinition = (function () {
|
||||
var PointDefinition = (function () {
|
||||
var def = {
|
||||
__class__: 'flash.geom.Point',
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const RectangleDefinition = (function () {
|
||||
var RectangleDefinition = (function () {
|
||||
var def = {
|
||||
__class__: 'flash.geom.Rectangle',
|
||||
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
const TransformDefinition = (function () {
|
||||
var TransformDefinition = (function () {
|
||||
var def = {
|
||||
__class__: 'flash.geom.Transform',
|
||||
|
||||
ctor: function (target) {
|
||||
this._target = target;
|
||||
|
||||
target._transform = this;
|
||||
},
|
||||
get colorTransform() {
|
||||
var cxform = this._target._cxform;
|
||||
if (cxform) {
|
||||
|
@ -51,34 +46,48 @@ const TransformDefinition = (function () {
|
|||
return m;
|
||||
},
|
||||
get matrix() {
|
||||
var target = this._target;
|
||||
var m = new flash.geom.Matrix;
|
||||
m.createBox(
|
||||
target._scaleX,
|
||||
target._scaleY,
|
||||
target._rotation * Math.PI / 180,
|
||||
target._x,
|
||||
target._y
|
||||
);
|
||||
return m;
|
||||
var m = this._target._currentTransform;
|
||||
return new flash.geom.Matrix(m.a, m.b, m.c, m.d, m.tx, m.ty);
|
||||
},
|
||||
set matrix(val) {
|
||||
var MatrixClass = avm2.systemDomain.getClass("flash.geom.Matrix");
|
||||
if (!MatrixClass.isInstanceOf(val))
|
||||
throw TypeError();
|
||||
|
||||
var a = val.a;
|
||||
var b = val.b;
|
||||
var c = val.c;
|
||||
var d = val.d;
|
||||
var tx = val.tx;
|
||||
var ty = val.ty;
|
||||
|
||||
var target = this._target;
|
||||
target._rotation = Math.atan2(val.b, val.a) * 180 / Math.PI;
|
||||
var sx = Math.sqrt(val.a * val.a + val.b * val.b);
|
||||
target._scaleX = val.a > 0 ? sx : -sx;
|
||||
var sy = Math.sqrt(val.d * val.d + val.c * val.c);
|
||||
target._scaleY = val.d > 0 ? sy : -sy;
|
||||
target._rotation = Math.atan2(b, a) * 180 / Math.PI;
|
||||
var sx = Math.sqrt(a * a + b * b);
|
||||
target._scaleX = a > 0 ? sx : -sx;
|
||||
var sy = Math.sqrt(d * d + c * c);
|
||||
target._scaleY = d > 0 ? sy : -sy;
|
||||
target._x = val.tx;
|
||||
target._y = val.ty;
|
||||
|
||||
target._currentTransform = {
|
||||
a: a,
|
||||
b: b,
|
||||
c: c,
|
||||
d: d,
|
||||
tx: tx,
|
||||
ty: ty
|
||||
};
|
||||
},
|
||||
|
||||
ctor: function (target) {
|
||||
this._target = target;
|
||||
|
||||
target._transform = this;
|
||||
}
|
||||
};
|
||||
|
||||
const desc = Object.getOwnPropertyDescriptor;
|
||||
var desc = Object.getOwnPropertyDescriptor;
|
||||
|
||||
def.__glue__ = {
|
||||
native: {
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
var SoundDefinition = (function () {
|
||||
var def = {
|
||||
initialize: function initialize() {
|
||||
}
|
||||
};
|
||||
|
||||
def.__glue__ = {
|
||||
native: {
|
||||
instance: {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return def;
|
||||
}).call(this);
|
|
@ -0,0 +1,17 @@
|
|||
var SoundMixerDefinition = (function () {
|
||||
var def = {};
|
||||
|
||||
function stopAll() {
|
||||
// TODO stop all sounds
|
||||
}
|
||||
|
||||
def.__glue__ = {
|
||||
native: {
|
||||
static: {
|
||||
stopAll: stopAll
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return def;
|
||||
}).call(this);
|
|
@ -1,13 +1,7 @@
|
|||
function SoundTransform(volume, pan) {
|
||||
EventDispatcher.call(this);
|
||||
var SoundTransformDefinition = (function () {
|
||||
var def = {
|
||||
__class__: 'flash.media.SoundTransform',
|
||||
};
|
||||
|
||||
this.volume = volume;
|
||||
this.pan = pan || 0;
|
||||
}
|
||||
|
||||
SoundTransform.prototype = Object.create(null, {
|
||||
__class__: describeInternalProperty('flash.media.SoundTransform'),
|
||||
|
||||
_timerDispatch: describeMethod(function () {
|
||||
})
|
||||
});
|
||||
return def;
|
||||
}).call(this);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const VideoDefinition = (function () {
|
||||
var VideoDefinition = (function () {
|
||||
var def = {
|
||||
initialize: function initialize() {
|
||||
this._element = document.createElement('video');
|
||||
|
@ -11,6 +11,9 @@ const VideoDefinition = (function () {
|
|||
this._netStream = netStream;
|
||||
this._element.src = netStream._url;
|
||||
},
|
||||
ctor: function(width, height) {
|
||||
// notImplemented();
|
||||
},
|
||||
draw: function (ctx) {
|
||||
if (!this._added) {
|
||||
ctx.canvas.parentNode.appendChild(this._element);
|
||||
|
@ -23,7 +26,8 @@ const VideoDefinition = (function () {
|
|||
def.__glue__ = {
|
||||
native: {
|
||||
instance: {
|
||||
attachNetStream: def.attachNetStream
|
||||
attachNetStream: def.attachNetStream,
|
||||
ctor: def.ctor
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,5 +1,20 @@
|
|||
const NetConnectionDefinition = (function () {
|
||||
var NetConnectionDefinition = (function () {
|
||||
var def = {
|
||||
connect: function(command /*, ...arguments */) {
|
||||
// notImplemented();
|
||||
},
|
||||
invokeWithArgsArray: function() {
|
||||
// notImplemented();
|
||||
}
|
||||
};
|
||||
|
||||
def.__glue__ = {
|
||||
native: {
|
||||
instance: {
|
||||
connect: def.connect,
|
||||
invokeWithArgsArray: def.invokeWithArgsArray
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return def;
|
||||
|
|
|
@ -1,9 +1,21 @@
|
|||
const NetStreamDefinition = (function () {
|
||||
var NetStreamDefinition = (function () {
|
||||
var def = {
|
||||
ctor: function(connection, peerID) {
|
||||
// notImplemented();
|
||||
},
|
||||
play: function (url) {
|
||||
this._url = url;
|
||||
}
|
||||
};
|
||||
|
||||
def.__glue__ = {
|
||||
native: {
|
||||
instance: {
|
||||
ctor: def.ctor,
|
||||
play: def.play
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return def;
|
||||
}).call(this);
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
var ResponderDefinition = (function () {
|
||||
var def = {
|
||||
ctor: function(result, status) {
|
||||
// notImplemented();
|
||||
}
|
||||
};
|
||||
|
||||
def.__glue__ = {
|
||||
native: {
|
||||
instance: {
|
||||
ctor: def.ctor
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return def;
|
||||
}).call(this);
|
|
@ -0,0 +1,59 @@
|
|||
var URLRequestDefinition = (function () {
|
||||
var def = {
|
||||
initialize: function () {
|
||||
this._url = null;
|
||||
this._method = 'GET';
|
||||
this._data = null;
|
||||
this._contentType = 'application/x-www-form-urlencoded';
|
||||
},
|
||||
|
||||
get contentType() {
|
||||
return this._contentType;
|
||||
},
|
||||
set contentType(val) {
|
||||
this._contentType = val;
|
||||
},
|
||||
get data() {
|
||||
return this._data;
|
||||
},
|
||||
set data(val) {
|
||||
this._data = val;
|
||||
},
|
||||
get method() {
|
||||
return this._method;
|
||||
},
|
||||
setMethod: function (val) {
|
||||
this._method = val;
|
||||
},
|
||||
get requestHeaders() {
|
||||
return this._requestHeaders;
|
||||
},
|
||||
setRequestHeaders: function (val) {
|
||||
this._requestHeaders = val;
|
||||
},
|
||||
get url() {
|
||||
return this._url;
|
||||
},
|
||||
set url(val) {
|
||||
this._url= val;
|
||||
},
|
||||
};
|
||||
|
||||
var desc = Object.getOwnPropertyDescriptor;
|
||||
|
||||
def.__glue__ = {
|
||||
native: {
|
||||
instance: {
|
||||
contentType: desc(def, 'contentType'),
|
||||
data: desc(def, 'data'),
|
||||
method: desc(def, 'method'),
|
||||
requestHeaders: desc(def, 'requestHeaders'),
|
||||
setMethod: def.setMethod,
|
||||
setRequestHeaders: def.setRequestHeaders,
|
||||
url: desc(def, 'url')
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return def;
|
||||
}).call(this);
|
|
@ -99,10 +99,14 @@ var as3error = {};
|
|||
M("flash.display.Sprite", "SpriteClass", SpriteDefinition),
|
||||
M("flash.display.MovieClip", "MovieClipClass", MovieClipDefinition),
|
||||
M("flash.display.Shape", "ShapeClass", ShapeDefinition),
|
||||
M("flash.display.Bitmap", "BitmapClass", BitmapDefinition),
|
||||
M("flash.display.BitmapData", "BitmapDataClass", BitmapDataDefinition),
|
||||
M("flash.display.Stage", "StageClass", StageDefinition),
|
||||
M("flash.display.Loader", "LoaderClass", LoaderDefinition),
|
||||
M("flash.display.LoaderInfo", "LoaderInfoClass", LoaderInfoDefinition),
|
||||
M("flash.display.Graphics", "GraphicsClass", GraphicsDefinition),
|
||||
M("flash.display.SimpleButton", "SimpleButtonClass", SimpleButtonDefinition),
|
||||
M("flash.display.MorphShape", "MorphShapeClass", MorphShapeDefinition),
|
||||
|
||||
M("flash.geom.Point", "PointClass", PointDefinition),
|
||||
M("flash.geom.Rectangle", "RectangleClass", RectangleDefinition),
|
||||
|
@ -113,14 +117,31 @@ var as3error = {};
|
|||
M("flash.events.EventDispatcher", "EventDispatcherClass", EventDispatcherDefinition),
|
||||
M("flash.events.Event", "EventClass", EventDefinition),
|
||||
M("flash.events.KeyboardEvent", "KeyboardEventClass", KeyboardEventDefinition),
|
||||
M("flash.events.MouseEvent", "MouseEventClass", MouseEventDefinition),
|
||||
M("flash.events.TextEvent", "TextEventClass", TextEventDefinition),
|
||||
M("flash.events.TimerEvent", "TimerEventClass", TimerEventDefinition),
|
||||
|
||||
M("flash.ui.Keyboard", "KeyboardClass", KeyboardDefinition),
|
||||
M("flash.external.ExternalInterface", "ExternalInterfaceClass", ExternalInterfaceDefinition),
|
||||
|
||||
M("flash.ui.Keyboard", "KeyboardClass", KeyboardDefinition),
|
||||
M("flash.ui.Mouse", "MouseClass", MouseDefinition),
|
||||
|
||||
M("flash.text.Font", "FontClass", FontDefinition),
|
||||
M("flash.text.TextField", "TextFieldClass", TextFieldDefinition),
|
||||
M("flash.text.StaticText", "StaticTextClass", StaticTextDefinition),
|
||||
|
||||
M("flash.text.Video", "VideoClass", VideoDefinition),
|
||||
M("flash.media.Sound", "SoundClass", SoundDefinition),
|
||||
M("flash.media.SoundMixer", "SoundMixerClass", SoundMixerDefinition),
|
||||
M("flash.media.SoundTransform", "SoundTransformClass", SoundTransformDefinition),
|
||||
M("flash.media.Video", "VideoClass", VideoDefinition),
|
||||
|
||||
M("flash.net.NetConnection", "NetConnectionClass", NetConnectionDefinition),
|
||||
M("flash.net.NetStream", "NetStreamClass", NetStreamDefinition),
|
||||
M("flash.net.Responder", "ResponderClass", ResponderDefinition),
|
||||
M("flash.net.URLRequest", "URLRequestClass", URLRequestDefinition),
|
||||
|
||||
M("flash.system.FSCommand", "FSCommandClass", FSCommandDefinition),
|
||||
M("flash.system.Capabilities", "CapabilitiesClass", CapabilitiesDefinition),
|
||||
|
||||
M("flash.utils.Timer", "TimerClass", TimerDefinition)].forEach(function (m) {
|
||||
var path = m.className.split(".");
|
||||
|
@ -136,10 +157,7 @@ var as3error = {};
|
|||
|
||||
// Hook up the native.
|
||||
natives[m.nativeName] = function (runtime, scope, instance, baseClass) {
|
||||
var c = new runtime.domain.system.Class(name, function () {
|
||||
this.class.initializeInstance(this);
|
||||
instance.apply(this, arguments);
|
||||
});
|
||||
var c = new runtime.domain.system.Class(name, instance);
|
||||
c.extend(baseClass);
|
||||
c.link(m.definition);
|
||||
return c;
|
||||
|
@ -153,3 +171,19 @@ natives['FlashUtilScript::getTimer'] = function GetTimerMethod(runtime, scope, i
|
|||
return Date.now() - start;
|
||||
};
|
||||
};
|
||||
|
||||
natives['FlashNetScript::navigateToURL'] = function GetNavigateToURLMethod(runtime, scope, instance, baseClass) {
|
||||
return function navigateToURL(request, window) {
|
||||
if (!request || !request.url)
|
||||
throw new Error('Invalid request object');
|
||||
var url = request.url;
|
||||
if (/^fscommand:/i.test(url)) {
|
||||
var fscommand = avm2.applicationDomain.getProperty(
|
||||
Multiname.fromSimpleName('flash.system.fscommand'), true, true);
|
||||
fscommand.call(null, url.substring('fscommand:'.length), window);
|
||||
return;
|
||||
}
|
||||
// TODO handle other methods than GET
|
||||
window.open(url, window);
|
||||
};
|
||||
};
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
var CapabilitiesDefinition = (function () {
|
||||
var def = {};
|
||||
|
||||
def.__glue__ = {
|
||||
native: {
|
||||
static: {
|
||||
version: {
|
||||
get: function version() {
|
||||
return 'SHUMWAY 10,0,0,0';
|
||||
},
|
||||
enumerable: true
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return def;
|
||||
}).call(this);
|
|
@ -0,0 +1,18 @@
|
|||
var FSCommandDefinition = (function () {
|
||||
var def = {};
|
||||
|
||||
function fscommand(command, parameters) {
|
||||
// TODO ignoring all fscommand
|
||||
console.log('FSCommand: ' + command + '; ' + parameters);
|
||||
}
|
||||
|
||||
def.__glue__ = {
|
||||
native: {
|
||||
static: {
|
||||
_fscommand: fscommand
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return def;
|
||||
}).call(this);
|
|
@ -1,3 +1,52 @@
|
|||
const FontDefinition = {
|
||||
__class__: 'flash.text.Font'
|
||||
var FontDefinition = (function () {
|
||||
var def = {
|
||||
__class__: 'flash.text.Font',
|
||||
|
||||
initialize: function () {
|
||||
var s = this.symbol;
|
||||
if (s) {
|
||||
this._fontName = s.name || null;
|
||||
}
|
||||
},
|
||||
|
||||
get fontName() {
|
||||
return this._fontName;
|
||||
},
|
||||
get fontStyle() {
|
||||
return this._fontStyle;
|
||||
},
|
||||
get fontType() {
|
||||
return this._fontType;
|
||||
},
|
||||
hasGlyphs: function hasGlyphs(str) {
|
||||
return true; // TODO
|
||||
},
|
||||
};
|
||||
|
||||
function enumerateFonts() {
|
||||
return []; // TODO
|
||||
}
|
||||
|
||||
function registerFont(font) {
|
||||
throw 'Not implemented: registerFont';
|
||||
}
|
||||
|
||||
var desc = Object.getOwnPropertyDescriptor;
|
||||
|
||||
def.__glue__ = {
|
||||
native: {
|
||||
instance: {
|
||||
fontName: desc(def, "fontName"),
|
||||
fontStyle: desc(def, "fontStyle"),
|
||||
fontType: desc(def, "fontType"),
|
||||
hasGlyphs: def.hasGlyphs
|
||||
},
|
||||
static: {
|
||||
enumerateFonts: enumerateFonts,
|
||||
registerFont: registerFont
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return def;
|
||||
}).call(this);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const StaticTextDefinition = (function () {
|
||||
var StaticTextDefinition = (function () {
|
||||
var def = {
|
||||
__class__: 'flash.text.StaticText',
|
||||
|
||||
|
@ -17,7 +17,7 @@ const StaticTextDefinition = (function () {
|
|||
}
|
||||
};
|
||||
|
||||
const desc = Object.getOwnPropertyDescriptor;
|
||||
var desc = Object.getOwnPropertyDescriptor;
|
||||
|
||||
def.__glue__ = {
|
||||
native: {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const TextFieldDefinition = (function () {
|
||||
var TextFieldDefinition = (function () {
|
||||
var def = {
|
||||
__class__: 'flash.text.TextField',
|
||||
|
||||
|
@ -10,15 +10,25 @@ const TextFieldDefinition = (function () {
|
|||
}
|
||||
},
|
||||
|
||||
_getAS2Object: function () {
|
||||
if (!this.$as2Object) {
|
||||
new AS2TextField().$attachNativeObject(this);
|
||||
}
|
||||
return this.$as2Object;
|
||||
},
|
||||
|
||||
get text() {
|
||||
return this._text;
|
||||
},
|
||||
set text(val) {
|
||||
if (this._text !== val) {
|
||||
this._text = val;
|
||||
this._markAsDirty();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const desc = Object.getOwnPropertyDescriptor;
|
||||
var desc = Object.getOwnPropertyDescriptor;
|
||||
|
||||
def.__glue__ = {
|
||||
native: {
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
var ShumwayKeyboardListener = {
|
||||
handleEvent: function (domEvt) {
|
||||
// XXX: Use strings directly if KEY_UP/KEY_DOWN and class lookup is too
|
||||
// slow.
|
||||
var KEClass = avm2.systemDomain.getClass("flash.events.KeyboardEvent");
|
||||
if (this.focus) {
|
||||
this.focus.dispatchEvent(new flash.events.KeyboardEvent(
|
||||
domEvt.type === 'keyup' ? KEClass.KEY_UP : KEClass.KEY_DOWN,
|
||||
domEvt.type === 'keyup' ? 'keyUp' : 'keyDown',
|
||||
true,
|
||||
false,
|
||||
domEvt.charCode,
|
||||
|
@ -22,7 +19,7 @@ var ShumwayKeyboardListener = {
|
|||
window.addEventListener('keydown', ShumwayKeyboardListener);
|
||||
window.addEventListener('keyup', ShumwayKeyboardListener);
|
||||
|
||||
const KeyboardDefinition = (function () {
|
||||
var KeyboardDefinition = (function () {
|
||||
var def = {
|
||||
get capsLock() {
|
||||
return false; // TODO Stage.instance.$keyboard.capsLock;
|
||||
|
@ -41,7 +38,7 @@ const KeyboardDefinition = (function () {
|
|||
}
|
||||
};
|
||||
|
||||
const desc = Object.getOwnPropertyDescriptor;
|
||||
var desc = Object.getOwnPropertyDescriptor;
|
||||
|
||||
def.__glue__ = {
|
||||
script: {
|
||||
|
|
|
@ -1,29 +1,51 @@
|
|||
var Mouse = describePrototype({
|
||||
cursor: describeAccessor(
|
||||
function () {
|
||||
return 'auto'; // TODO
|
||||
var MouseDefinition = (function() {
|
||||
|
||||
var def = {
|
||||
__class__: 'flash.ui.Mouse',
|
||||
|
||||
$bind: function(stage) {
|
||||
this._stage = stage;
|
||||
},
|
||||
function (val) {
|
||||
};
|
||||
|
||||
function hide() {
|
||||
this._stage._setCursorVisible(false);
|
||||
}
|
||||
|
||||
function show() {
|
||||
this._stage._setCursorVisible(true);
|
||||
}
|
||||
|
||||
function registerCursor() {
|
||||
notImplemented();
|
||||
}
|
||||
),
|
||||
supportsCursor: describeAccessor(function () {
|
||||
return true; // TODO
|
||||
}),
|
||||
supportsNativeCursor: describeAccessor(function () {
|
||||
return true; // TODO
|
||||
}),
|
||||
|
||||
hide: describeMethod(function () {
|
||||
function unregisterCursor() {
|
||||
notImplemented();
|
||||
}),
|
||||
registerCursor: describeMethod(function (name, cursor) {
|
||||
notImplemented();
|
||||
}),
|
||||
show: describeMethod(function () {
|
||||
notImplemented();
|
||||
}),
|
||||
unregisterCursor: describeMethod(function (name) {
|
||||
notImplemented();
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
def.__glue__ = {
|
||||
native: {
|
||||
static: {
|
||||
cursor: {
|
||||
get: function () { return 'auto'; }, //TODO
|
||||
set: function () { notImplemented(); }
|
||||
},
|
||||
|
||||
supportsCursor: {
|
||||
get: function () { return true; } // TODO
|
||||
},
|
||||
supportsNativeCursor: {
|
||||
get: function () { return true; } // TODO
|
||||
},
|
||||
|
||||
hide: hide,
|
||||
show: show,
|
||||
registerCursor: registerCursor,
|
||||
unregisterCursor: unregisterCursor
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
return def;
|
||||
}).call(this);
|
||||
|
|
|
@ -1,28 +1,3 @@
|
|||
function describePrototype() {
|
||||
if (arguments.length === 1) {
|
||||
return Object.create(Object.prototype, arguments[0]);
|
||||
}
|
||||
return Object.create(arguments[0], arguments[1]);
|
||||
}
|
||||
function describeAccessor(get, set) {
|
||||
return { get: get, set: set, configurable: true, enumerable: true };
|
||||
}
|
||||
function describeConst(val) {
|
||||
return { value: val, configurable: true, enumerable: true };
|
||||
}
|
||||
function describeInternalProperty(val) {
|
||||
return { value: val, writable: true };
|
||||
}
|
||||
function describeLazyProperty(name, getter) {
|
||||
return describeAccessor(function () {
|
||||
var val = getter.call(this);
|
||||
Object.defineProperty(this, name, describeProperty(val));
|
||||
return val;
|
||||
});
|
||||
}
|
||||
function describeMethod(fn) {
|
||||
return describeProperty(fn);
|
||||
}
|
||||
function describeProperty(val) {
|
||||
return { value: val, writable: true, configurable: true, enumerable: true };
|
||||
}
|
||||
|
@ -45,7 +20,7 @@ Promise.when = function () {
|
|||
promise.resolve();
|
||||
} else {
|
||||
var values = [];
|
||||
for (var i = 0; i < numPromises; i++) {
|
||||
for (var i = 0, n = numPromises; i < n; i++) {
|
||||
var arg = arguments[i];
|
||||
arg.then(function (val) {
|
||||
values.push(val);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const TimerDefinition = (function () {
|
||||
var TimerDefinition = (function () {
|
||||
var def = {
|
||||
__class__: 'flash.utils.Timer',
|
||||
initialize: function () {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- mode: javascript; tab-width: 4; insert-tabs-mode: nil; indent-tabs-mode: nil -*- */
|
||||
/* -*- mode: javascript; tab-width: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
/** @const */ var FORMAT_COLORMAPPED = 3;
|
||||
/** @const */ var FORMAT_15BPP = 4;
|
||||
|
@ -12,13 +12,13 @@ function rgbToString(bytes, pos) {
|
|||
return fromCharCode(red, green, blue);
|
||||
}
|
||||
function argbToString(bytes, pos) {
|
||||
var alpha = bytes[pos];
|
||||
var alpha = bytes[pos] / 0xff;
|
||||
if (!alpha)
|
||||
return '\x00\x00\x00\x00';
|
||||
// RGB values are alpha pre-multiplied (per SWF spec).
|
||||
var red = 0 | ((bytes[pos + 1] * 255) / alpha);
|
||||
var green = 0 | ((bytes[pos + 2] * 255) / alpha);
|
||||
var blue = 0 | ((bytes[pos + 3] * 255) / alpha);
|
||||
var red = 0 | (bytes[pos + 1] / alpha);
|
||||
var green = 0 | (bytes[pos + 2] / alpha);
|
||||
var blue = 0 | (bytes[pos + 3] / alpha);
|
||||
return fromCharCode(red, green, blue, alpha);
|
||||
}
|
||||
|
||||
|
@ -161,6 +161,8 @@ function defineBitmap(tag) {
|
|||
return {
|
||||
type: 'image',
|
||||
id: tag.id,
|
||||
width: width,
|
||||
height: height,
|
||||
mimeType: 'image/png',
|
||||
data: data
|
||||
};
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
/* -*- mode: javascript; tab-width: 4; insert-tabs-mode: nil; indent-tabs-mode: nil -*- */
|
||||
/* -*- mode: javascript; tab-width: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
function defineButton(tag, dictionary) {
|
||||
var characters = tag.characters;
|
||||
var dependencies = [];
|
||||
var states = {
|
||||
up: {type: 'pframe'},
|
||||
over: {type: 'pframe'},
|
||||
down: {type: 'pframe'},
|
||||
hitTest: {type: 'pframe'}
|
||||
up: {},
|
||||
over: {},
|
||||
down: {},
|
||||
hitTest: {}
|
||||
};
|
||||
var i = 0;
|
||||
while (character = characters[i++]) {
|
||||
|
@ -16,7 +15,7 @@ function defineButton(tag, dictionary) {
|
|||
var characterItem = dictionary[character.characterId];
|
||||
assert(characterItem, 'undefined character', 'button');
|
||||
var entry = {
|
||||
id: characterItem.id,
|
||||
symbolId: characterItem.id,
|
||||
matrix: character.matrix
|
||||
};
|
||||
if (character.stateUp)
|
||||
|
@ -27,7 +26,6 @@ function defineButton(tag, dictionary) {
|
|||
states.down[character.depth] = entry;
|
||||
if (character.stateHitTest)
|
||||
states.hitTest[character.depth] = entry;
|
||||
dependencies.push(characterItem.id);
|
||||
}
|
||||
var button = {
|
||||
type: 'button',
|
||||
|
@ -35,7 +33,5 @@ function defineButton(tag, dictionary) {
|
|||
buttonActions: tag.buttonActions,
|
||||
states: states
|
||||
};
|
||||
if (dependencies.length)
|
||||
button.require = dependencies;
|
||||
return button;
|
||||
}
|
||||
|
|
101
src/swf/embed.js
101
src/swf/embed.js
|
@ -5,12 +5,32 @@ SWF.embed = function(file, container, options) {
|
|||
var loaderInfo = loader.contentLoaderInfo;
|
||||
var stage = new flash.display.Stage;
|
||||
|
||||
// HACK support of HiDPI displays
|
||||
var pixelRatio = 'devicePixelRatio' in window ? window.devicePixelRatio : 1;
|
||||
var canvasHolder = null;
|
||||
if (pixelRatio > 1) {
|
||||
var cssScale = 'scale(' + (1/pixelRatio) + ', ' + (1/pixelRatio) + ')';
|
||||
canvas.setAttribute('style', '-moz-transform: ' + cssScale + ';' +
|
||||
'-webkit-transform: ' + cssScale + ';' +
|
||||
'transform: ' + cssScale + ';' +
|
||||
'-moz-transform-origin: 0% 0%;' +
|
||||
'-webkit-transform-origin: 0% 0%;' +
|
||||
'transform-origin: 0% 0%;');
|
||||
canvasHolder = document.createElement('div');
|
||||
canvasHolder.setAttribute('style', 'display: inline-block; overflow: hidden;');
|
||||
canvasHolder.appendChild(canvas);
|
||||
}
|
||||
|
||||
loader._stage = stage;
|
||||
stage._loader = loader;
|
||||
|
||||
function fitCanvas(container, canvas) {
|
||||
canvas.width = container.clientWidth;
|
||||
canvas.height = container.clientHeight;
|
||||
if (canvasHolder) {
|
||||
canvasHolder.style.width = container.clientWidth + 'px';
|
||||
canvasHolder.style.height = container.clientHeight + 'px';
|
||||
}
|
||||
canvas.width = container.clientWidth * pixelRatio;
|
||||
canvas.height = container.clientHeight * pixelRatio;
|
||||
}
|
||||
|
||||
loaderInfo.addEventListener('init', function () {
|
||||
|
@ -25,27 +45,88 @@ SWF.embed = function(file, container, options) {
|
|||
fitCanvas.bind(container, canvas);
|
||||
});
|
||||
} else {
|
||||
canvas.width = stage._stageWidth;
|
||||
canvas.height = stage._stageHeight;
|
||||
if (canvasHolder) {
|
||||
canvasHolder.style.width = stage._stageWidth + 'px';
|
||||
canvasHolder.style.height = stage._stageHeight + 'px';
|
||||
}
|
||||
canvas.width = stage._stageWidth * pixelRatio;
|
||||
canvas.height = stage._stageHeight * pixelRatio;
|
||||
}
|
||||
|
||||
container.setAttribute("style", "position: relative");
|
||||
|
||||
canvas.addEventListener('click', function () {
|
||||
ShumwayKeyboardListener.focus = stage;
|
||||
|
||||
if (stage._clickTarget)
|
||||
stage._clickTarget.dispatchEvent(new flash.events.MouseEvent('click'));
|
||||
});
|
||||
canvas.addEventListener('dblclick', function () {
|
||||
if (stage._clickTarget && stage._clickTarget._doubleClickEnabled)
|
||||
stage._clickTarget.dispatchEvent(new flash.events.MouseEvent('doubleClick'));
|
||||
});
|
||||
canvas.addEventListener('mousedown', function () {
|
||||
if (stage._clickTarget)
|
||||
stage._clickTarget.dispatchEvent(new flash.events.MouseEvent('mouseDown'));
|
||||
});
|
||||
canvas.addEventListener('mousemove', function (domEvt) {
|
||||
stage._mouseX = domEvt.pageX - this.offsetLeft;
|
||||
stage._mouseY = domEvt.pageY - this.offsetTop;
|
||||
var node = this;
|
||||
var left = 0;
|
||||
var top = 0;
|
||||
if (node.offsetParent) {
|
||||
do {
|
||||
left += node.offsetLeft;
|
||||
top += node.offsetTop;
|
||||
} while (node = node.offsetParent);
|
||||
}
|
||||
|
||||
stage._mouseX = domEvt.pageX - left;
|
||||
stage._mouseY = domEvt.pageY - top;
|
||||
});
|
||||
canvas.addEventListener('mouseup', function () {
|
||||
if (stage._clickTarget)
|
||||
stage._clickTarget.dispatchEvent(new flash.events.MouseEvent('mouseUp'));
|
||||
});
|
||||
canvas.addEventListener('mouseover', function () {
|
||||
stage._mouseOver = true;
|
||||
});
|
||||
canvas.removeEventListener('mouseout', function () {
|
||||
stage._mouseOver = false;
|
||||
stage._mouseJustLeft = true;
|
||||
});
|
||||
|
||||
var bgcolor = loaderInfo._backgroundColor;
|
||||
stage._color = bgcolor;
|
||||
canvas.style.background = toStringRgba(bgcolor);
|
||||
|
||||
stage._children[0] = loader._content;
|
||||
container.appendChild(canvas);
|
||||
renderStage(stage, ctx);
|
||||
var root = loader._content;
|
||||
stage._children[0] = root;
|
||||
stage._control.appendChild(root._control);
|
||||
|
||||
var cursorVisible = true;
|
||||
function syncCursor() {
|
||||
var newCursor;
|
||||
if (cursorVisible) {
|
||||
if (stage._clickTarget && stage._clickTarget.shouldHaveHandCursor)
|
||||
newCursor = 'pointer';
|
||||
else
|
||||
newCursor = 'auto';
|
||||
} else {
|
||||
newCursor = 'none';
|
||||
}
|
||||
|
||||
container.style.cursor = newCursor;
|
||||
}
|
||||
|
||||
stage._setCursorVisible = function(val) {
|
||||
cursorVisible = val;
|
||||
syncCursor();
|
||||
};
|
||||
stage._syncCursor = syncCursor;
|
||||
syncCursor();
|
||||
|
||||
container.appendChild(canvasHolder || canvas);
|
||||
renderStage(stage, ctx, options.onFrame);
|
||||
});
|
||||
|
||||
if (options.onComplete) {
|
||||
|
@ -54,5 +135,5 @@ SWF.embed = function(file, container, options) {
|
|||
});
|
||||
}
|
||||
|
||||
loader.loadFrom(file);
|
||||
loader._loadFrom(file);
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- mode: javascript; tab-width: 4; insert-tabs-mode: nil; indent-tabs-mode: nil -*- */
|
||||
/* -*- mode: javascript; tab-width: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
var nextFontId = 1;
|
||||
|
||||
|
@ -18,6 +18,9 @@ function defineFont(tag, dictionary) {
|
|||
var glyphIndex = { };
|
||||
var ranges = [];
|
||||
|
||||
var glyphs = tag.glyphs;
|
||||
var glyphCount = glyphs.length;
|
||||
|
||||
if (tag.codes) {
|
||||
codes = codes.concat(tag.codes);
|
||||
for (var i = 0, code; code = codes[i]; ++i)
|
||||
|
@ -39,13 +42,15 @@ function defineFont(tag, dictionary) {
|
|||
ranges.push([start, end, indices]);
|
||||
}
|
||||
} else {
|
||||
var indices = [];
|
||||
var UAC_OFFSET = 0xe000;
|
||||
for (var i = 0; i < glyphCount; i++) {
|
||||
var code = 0xe000 + i;
|
||||
var code = UAC_OFFSET + i;
|
||||
codes.push(code);
|
||||
glyphIndex[code] = i;
|
||||
indices.push(i);
|
||||
}
|
||||
ranges.push([0, glyphCount - 1, indices]);
|
||||
ranges.push([UAC_OFFSET, UAC_OFFSET + glyphCount - 1, indices]);
|
||||
}
|
||||
|
||||
var ascent = tag.ascent || 1024;
|
||||
|
@ -130,7 +135,6 @@ function defineFont(tag, dictionary) {
|
|||
format314
|
||||
;
|
||||
|
||||
var glyphs = tag.glyphs;
|
||||
var glyf = '\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00';
|
||||
var loca = '\x00\x00';
|
||||
var resolution = tag.resolution || 1;
|
||||
|
@ -282,7 +286,6 @@ function defineFont(tag, dictionary) {
|
|||
|
||||
var advance = tag.advance;
|
||||
var resolution = tag.resolution || 1;
|
||||
var glyphCount = glyphs.length;
|
||||
tables['hhea'] =
|
||||
'\x00\x01\x00\x00' + // version
|
||||
toString16(ascent) + // ascender
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- mode: javascript; tab-width: 4; insert-tabs-mode: nil; indent-tabs-mode: nil -*- */
|
||||
/* -*- mode: javascript; tab-width: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
var defaultTemplateSet = [
|
||||
readSi8, readSi16, readSi32, readUi8, readUi16, readUi32, readFixed,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- mode: javascript; tab-width: 4; insert-tabs-mode: nil; indent-tabs-mode: nil -*- */
|
||||
/* -*- mode: javascript; tab-width: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
var plte = createPngChunk('PLTE', (new Array(769)).join('\x00'));
|
||||
var alphaValues = [];
|
||||
|
@ -18,7 +18,7 @@ function defineImage(tag, dictionary) {
|
|||
if (tag.mimeType === 'image/jpeg') {
|
||||
var width = 0;
|
||||
var height = 0;
|
||||
var i = 2;
|
||||
var i = 0;
|
||||
var n = imgData.length;
|
||||
var code;
|
||||
do {
|
||||
|
@ -103,7 +103,7 @@ function defineImage(tag, dictionary) {
|
|||
var header = tables.data;
|
||||
data = header.substr(0, header.length - 2) + data;
|
||||
} else {
|
||||
data = '\xff\xd8' + data;
|
||||
data = data;
|
||||
}
|
||||
} else {
|
||||
var numChunks = imgData.length / 65536;
|
||||
|
@ -118,6 +118,8 @@ function defineImage(tag, dictionary) {
|
|||
var img = {
|
||||
type: 'image',
|
||||
id: tag.id,
|
||||
width: width,
|
||||
height: height,
|
||||
mimeType: tag.mimeType,
|
||||
data: data
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- mode: javascript; tab-width: 4; insert-tabs-mode: nil; indent-tabs-mode: nil -*- */
|
||||
/* -*- mode: javascript; tab-width: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
var codeLengthOrder = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15];
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- mode: javascript; tab-width: 4; insert-tabs-mode: nil; indent-tabs-mode: nil -*- */
|
||||
/* -*- mode: javascript; tab-width: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
function defineLabel(tag, dictionary) {
|
||||
var records = tag.records;
|
||||
|
@ -42,16 +42,10 @@ function defineLabel(tag, dictionary) {
|
|||
}
|
||||
}
|
||||
cmds.push('c.restore()');
|
||||
var bounds = tag.bounds;
|
||||
var label = {
|
||||
type: 'label',
|
||||
id: tag.id,
|
||||
bbox: {
|
||||
left: bounds.xMin,
|
||||
top: bounds.xMax,
|
||||
right: bounds.yMin,
|
||||
bottom: bounds.yMax
|
||||
},
|
||||
bbox: tag.bbox,
|
||||
data: cmds.join('\n')
|
||||
};
|
||||
if (dependencies.length)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- mode: javascript; tab-width: 4; insert-tabs-mode: nil; indent-tabs-mode: nil -*- */
|
||||
/* -*- mode: javascript; tab-width: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
var tagHandler = {
|
||||
/* End */ 0: undefined,
|
||||
|
|
|
@ -1,700 +0,0 @@
|
|||
/* -*- mode: javascript; tab-width: 4; insert-tabs-mode: nil; indent-tabs-mode: nil -*- */
|
||||
|
||||
//var identityMatrix = {
|
||||
// scaleX: 1,
|
||||
// scaleY: 1,
|
||||
// skew0: 0,
|
||||
// skew1: 0,
|
||||
// translateX: 0,
|
||||
// translateY: 0
|
||||
//};
|
||||
//
|
||||
//function DisplayListItem(character) {
|
||||
// this.character = character;
|
||||
//}
|
||||
|
||||
//function TimelineLoader(totalFrames, pframes, dictionary) {
|
||||
// var currentPframe = 0;
|
||||
// var ptimeline = [];
|
||||
// var frameLabels = {};
|
||||
// var framesLoaded = 0;
|
||||
//
|
||||
// var ptimelinePromises = [];
|
||||
// for (var i = 0; i < totalFrames; i++)
|
||||
// ptimelinePromises.push(new Promise);
|
||||
//
|
||||
// function prefetchFrame() {
|
||||
// var prefetchPortion = 20, prefetchInterval = 100;
|
||||
// setTimeout(function() {
|
||||
// ensureFrame(Math.min(ptimeline.length + prefetchPortion, totalFrames));
|
||||
// }, prefetchInterval);
|
||||
// }
|
||||
//
|
||||
// var loader = this;
|
||||
// var lastFramePromise = Promise.resolved, lastFrame = null;
|
||||
// function ensureFrame(frameNum) {
|
||||
// var n = ptimeline.length;
|
||||
// while (n < frameNum) {
|
||||
// var frame = create(lastFrame);
|
||||
// lastFrame = frame;
|
||||
// var pframe = pframes[currentPframe++];
|
||||
// if (!pframe)
|
||||
// break;
|
||||
// var currentFrame = n + 1;
|
||||
// if (pframe.labelName)
|
||||
// frameLabels[pframe.labelName.toLowerCase()] = currentFrame;
|
||||
// var i = pframe.repeat || 1;
|
||||
// while (i--) {
|
||||
// ptimeline.push(frame);
|
||||
// ++n;
|
||||
// }
|
||||
//
|
||||
// function initCharacter(proto, entry, initObj, parent, as2Context) {
|
||||
// var character;
|
||||
// var matrix = entry.matrix || initObj.matrix || identityMatrix;
|
||||
// var cxform = entry.cxform || initObj.cxform;
|
||||
// var ratio = (entry.ratio || 0) / 0xffff;
|
||||
//
|
||||
// if (proto instanceof DisplayListItem)
|
||||
// character = proto.character; // reusing created one
|
||||
// else {
|
||||
// // creates new instance of the character
|
||||
// if (typeof proto === 'function')
|
||||
// character = new proto(as2Context);
|
||||
// else if (proto.constructor !== Object)
|
||||
// character = proto.constructor(as2Context);
|
||||
// else
|
||||
// character = create(proto);
|
||||
//
|
||||
// character.matrix = matrix;
|
||||
// character.cxform = cxform;
|
||||
// if (character.draw)
|
||||
// character.ratio = ratio;
|
||||
//
|
||||
// if (entry.events)
|
||||
// character.events = entry.events;
|
||||
// if (entry.name) {
|
||||
// character.name = entry.name;
|
||||
// parent.$addChild(entry.name, character);
|
||||
// }
|
||||
// character._parent = parent;
|
||||
// character._root = parent.root || parent;
|
||||
// if (character.variableName)
|
||||
// parent.$bindVariable(character);
|
||||
// }
|
||||
//
|
||||
// var item = new DisplayListItem(character);
|
||||
// item.matrix = matrix;
|
||||
// item.cxform = cxform;
|
||||
// if (character.draw)
|
||||
// item.ratio = ratio;
|
||||
//
|
||||
// return item;
|
||||
// }
|
||||
//
|
||||
// function buildFromPrototype(proto, entry, obj, frame, depth, promise) {
|
||||
// var objectCreator = (function objectCreator(parent, objectCache, asContext) {
|
||||
// var character = initCharacter(objectCache.get(proto) || proto, entry,
|
||||
// objectCache.get(obj) || obj, parent, asContext);
|
||||
// objectCache.set(objectCreator, character);
|
||||
// return character;
|
||||
// });
|
||||
// frame[depth] = objectCreator;
|
||||
// if (promise)
|
||||
// promise.resolve(objectCreator);
|
||||
// }
|
||||
//
|
||||
// var framePromises = [lastFramePromise];
|
||||
//
|
||||
// var depths = keys(pframe), depth;
|
||||
// while (depth = depths[0]) {
|
||||
// if (+depth) {
|
||||
// var entry = pframe[depth];
|
||||
// if (entry) {
|
||||
// var promise = null;
|
||||
// var initObj = (entry.move ? frame[depth] : null) || {};
|
||||
// var id = entry.symbolId;
|
||||
// if (id) {
|
||||
// assert(id in dictionary, 'unknown object', 'place');
|
||||
// var protoPromise = dictionary.getPromise(id);
|
||||
// promise = new Promise();
|
||||
// frame[depth] = promise;
|
||||
// protoPromise.then((function(frame, depth, entry, initObj, promise, proto) {
|
||||
// if (initObj instanceof Promise) {
|
||||
// initObj.then(function(obj) {
|
||||
// buildFromPrototype(proto, entry, obj, frame, depth, promise);
|
||||
// });
|
||||
// } else {
|
||||
// buildFromPrototype(proto, entry, initObj, frame, depth, promise);
|
||||
// }
|
||||
// }).bind(null, frame, depth, entry, initObj, promise));
|
||||
// } else {
|
||||
// if (initObj instanceof Promise) {
|
||||
// promise = new Promise();
|
||||
// frame[depth] = promise;
|
||||
// initObj.then((function(frame, depth, promise, obj) {
|
||||
// buildFromPrototype(obj, entry, obj, frame, depth, promise);
|
||||
// }).bind(null, frame, depth, promise));
|
||||
// } else {
|
||||
// buildFromPrototype(initObj, entry, initObj, frame, depth, null);
|
||||
// }
|
||||
// }
|
||||
// if (promise)
|
||||
// framePromises.push(promise);
|
||||
// } else {
|
||||
// frame[depth] = null;
|
||||
// }
|
||||
// }
|
||||
// depths.shift();
|
||||
// }
|
||||
// var framePromise = Promise.all(framePromises);
|
||||
// lastFramePromise = framePromise;
|
||||
// framePromise.then((function(pframe, frame, currentFrame, lastInserted) {
|
||||
// function initialize(instance) {
|
||||
// if (pframe.actionsData && pframe.actionsData.length > 0) {
|
||||
// for (var i = 0; i < pframe.actionsData.length; i++)
|
||||
// instance.addFrameScript(currentFrame - 1,
|
||||
// instance.$createAS2Script(pframe.actionsData[i]));
|
||||
// }
|
||||
//
|
||||
// if (pframe.initActionsData) {
|
||||
// for (var spriteId in pframe.initActionsData) {
|
||||
// instance.$createAS2Script(pframe.initActionsData[spriteId]).call(instance);
|
||||
// }
|
||||
// }
|
||||
// if (pframe.exports) {
|
||||
// instance.$addChild('soundmc', new SoundMock(pframe.exports));
|
||||
// }
|
||||
// if (currentFrame == 1)
|
||||
// instance.$dispatchEvent('onLoad');
|
||||
// }
|
||||
//
|
||||
// ptimelinePromises[framesLoaded].resolve(frame, ptimeline[framesLoaded - 1], initialize);
|
||||
// framesLoaded++;
|
||||
// while(framesLoaded < lastInserted) {
|
||||
// ptimelinePromises[framesLoaded].resolve(null, frame);
|
||||
// framesLoaded++;
|
||||
// }
|
||||
// loader.framesLoaded = framesLoaded;
|
||||
// }).bind(null, pframe, frame, currentFrame, n));
|
||||
// }
|
||||
// if (n < totalFrames) {
|
||||
// lastFramePromise.then(function() {
|
||||
// prefetchFrame();
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// function prepareTimeline(instance, as2Context) {
|
||||
// // instance shall implement the following methods:
|
||||
// // $setDisplayList, $createAS2Script, $addChild, $dispatchEvent, $addFrameScript
|
||||
// var previousDisplayList = null;
|
||||
// var objectCache = new WeakMap();
|
||||
// for (var i = 0; i < totalFrames; i++) {
|
||||
// ptimelinePromises[i].then((function(i, frame, previousFrame, initialize) {
|
||||
// if (!frame) {
|
||||
// // repeat of the previous frame
|
||||
// instance.$setDisplayList(i + 1, previousDisplayList);
|
||||
// return;
|
||||
// }
|
||||
// var displayList = [];
|
||||
// for (var depth in frame) {
|
||||
// if (previousFrame && previousFrame[depth] === frame[depth]) {
|
||||
// displayList[depth] = previousDisplayList[depth];
|
||||
// continue;
|
||||
// }
|
||||
// var creator = frame[depth];
|
||||
// if (typeof creator === 'function')
|
||||
// displayList[depth] = creator(this, objectCache, as2Context);
|
||||
// else
|
||||
// displayList[depth] = creator;
|
||||
// }
|
||||
// initialize(this);
|
||||
// instance.$setDisplayList(i + 1, displayList);
|
||||
// previousDisplayList = displayList;
|
||||
// }).bind(instance, i));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// this.totalFrames = totalFrames;
|
||||
// this.framesLoaded = 0;
|
||||
// this.ptimelinePromises = ptimelinePromises;
|
||||
// this.frameLabels = frameLabels;
|
||||
// this.ensureFrame = ensureFrame;
|
||||
// this.prepareTimeline = prepareTimeline;
|
||||
//}
|
||||
|
||||
function MovieClipClass() {
|
||||
var timeline = [];
|
||||
var children = {};
|
||||
var instance = this;
|
||||
var as2Context = this._as2Context;
|
||||
|
||||
function createAS2Script(data) {
|
||||
return (function() {
|
||||
var as2Object = this.$as2Object;
|
||||
|
||||
try {
|
||||
executeActions(data, as2Context, as2Object);
|
||||
} catch (e) {
|
||||
console.log('Error during ActionScript execution: ' + e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function dispatchEvent(eventName, args) {
|
||||
var as2Object = instance.$as2Object;
|
||||
if (as2Object && as2Object[eventName])
|
||||
as2Object[eventName].apply(as2Object, args);
|
||||
|
||||
if (instance.events) {
|
||||
for (var i = 0; i < instance.events.length; ++i) {
|
||||
var event = instance.events[i];
|
||||
if (!event[eventName])
|
||||
continue;
|
||||
var actions = event.actionsData;
|
||||
if (typeof actions !== 'function')
|
||||
event.actionsData = actions = createAS2Script(actions);
|
||||
actions.call(instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var as2Object;
|
||||
|
||||
var lastMouseCoordinates = null;
|
||||
function getMouseCoordinates() {
|
||||
if (lastMouseCoordinates)
|
||||
return lastMouseCoordinates;
|
||||
|
||||
lastMouseCoordinates = { x: AS2Mouse.$lastX, y: AS2Mouse.$lastY };
|
||||
instance.globalToLocal(lastMouseCoordinates);
|
||||
return lastMouseCoordinates;
|
||||
}
|
||||
|
||||
this.renderNextFrame = function(context) {
|
||||
if (this.isPlaying())
|
||||
this.gotoFrame((this._currentFrame % this._totalFrames) + 1);
|
||||
|
||||
var frameIndex = this._currentFrame - 1;
|
||||
var displayList = timeline[frameIndex];
|
||||
if (!displayList)
|
||||
return; // skiping non-prepared frame
|
||||
|
||||
render(displayList, context);
|
||||
}
|
||||
|
||||
|
||||
|
||||
this.$dispatchEvent = dispatchEvent;
|
||||
this.$createAS2Script = createAS2Script;
|
||||
this.$addChild = function(name, child) {
|
||||
children[name] = child;
|
||||
};
|
||||
this.$setDisplayList = function(frameNum, displayList) {
|
||||
timeline[frameNum - 1] = displayList;
|
||||
};
|
||||
this.$getDisplayList = function(frameNum) {
|
||||
return timeline[frameNum - 1];
|
||||
};
|
||||
defineObjectProperties(this, {
|
||||
$as2Object: {
|
||||
get: function() {
|
||||
if (!as2Object) {
|
||||
var nativeObjectContructor = this.nativeObjectContructor || AS2MovieClip;
|
||||
as2Object = new nativeObjectContructor();
|
||||
as2Object.$attachNativeObject(this);
|
||||
as2Object['this'] = as2Object;
|
||||
|
||||
var registerChild = (function(name, obj) {
|
||||
Object.defineProperty(as2Object, name, {
|
||||
get: function() {
|
||||
return obj.$as2Object;
|
||||
},
|
||||
configurable: true,
|
||||
enumerable: true
|
||||
});
|
||||
});
|
||||
for (var child in children) {
|
||||
registerChild(child, children[child]);
|
||||
}
|
||||
var oldAddChild = this.$addChild;
|
||||
this.$addChild = (function(name, child) {
|
||||
oldAddChild.call(this, name, child);
|
||||
registerChild(name, child);
|
||||
});
|
||||
}
|
||||
return as2Object;
|
||||
},
|
||||
enumerable: false
|
||||
},
|
||||
$parent: {
|
||||
get: function get$parent() {
|
||||
return this.parent.$as2Object;
|
||||
},
|
||||
enumerable: false
|
||||
},
|
||||
$lookupChild: {
|
||||
value: function(name) {
|
||||
var i = name.indexOf('/');
|
||||
if (i == 0) {
|
||||
if (this.parent) {
|
||||
// moving to _root
|
||||
var mc = this;
|
||||
while (mc.parent)
|
||||
mc = mc.parent;
|
||||
return mc.$lookupChild(name.substring(1));
|
||||
}
|
||||
// already a root
|
||||
name = name.substring(1);
|
||||
i = name.indexOf('/');
|
||||
}
|
||||
var childName = i > 0 ? name.substring(0, i) : name;
|
||||
var child = this;
|
||||
if (childName == '..') {
|
||||
if (!this.parent)
|
||||
throw 'mc is _root';
|
||||
child = this.parent;
|
||||
} else if (childName) {
|
||||
if (!(childName in children))
|
||||
throw 'Child mc is not found: ' + childName;
|
||||
child = children[childName];
|
||||
}
|
||||
|
||||
return i < 0 ? child.$as2Object : child.$lookupChild(name.substring(i + 1));
|
||||
},
|
||||
enumerable: false
|
||||
},
|
||||
$bindVariable: {
|
||||
value: function bindVariable(character) {
|
||||
var clip;
|
||||
var variableName = character.variableName;
|
||||
var i = variableName.lastIndexOf('.');
|
||||
if (i >= 0) {
|
||||
var targetPath = variableName.substring(0, i);
|
||||
targetPath = targetPath == '_root' ? '/' :
|
||||
targetPath.replace('_root', '').replace('.', '/');
|
||||
clip = this.$lookupChild(targetPath);
|
||||
variableName = variableName.substring(i + 1);
|
||||
} else
|
||||
clip = instance.$as2Object;
|
||||
if (!(variableName in clip))
|
||||
clip[variableName] = character.value;
|
||||
delete character.value;
|
||||
Object.defineProperty(character, 'value', {
|
||||
get: function () {
|
||||
return clip[variableName];
|
||||
},
|
||||
enumerable: true
|
||||
});
|
||||
},
|
||||
enumerable: false
|
||||
},
|
||||
|
||||
getBounds: {
|
||||
value: function getBounds(bounds) {
|
||||
// TODO move the getBounds into utility/core classes
|
||||
var frame = timeline[this._currentFrame - 1];
|
||||
var rect = new Rectangle;
|
||||
for (var i in frame) {
|
||||
var character = frame[i].character;
|
||||
rect = rect.union(character.getBounds(this));
|
||||
}
|
||||
//if (!bounds || bounds === this)
|
||||
return rect;
|
||||
|
||||
//var pt1 = bounds.globalToLocal(
|
||||
// this.localToGlobal({x: xMin, y: yMin}));
|
||||
//var pt2 = bounds.globalToLocal(
|
||||
// this.localToGlobal({x: xMax, y: yMin}));
|
||||
//var pt3 = bounds.globalToLocal(
|
||||
// this.localToGlobal({x: xMax, y: yMax}));
|
||||
//var pt4 = bounds.globalToLocal(
|
||||
// this.localToGlobal({x: xMin, y: yMax}));
|
||||
//
|
||||
//return {
|
||||
// xMin: Math.min(pt1.x, pt2.x, pt3.x, pt4.x),
|
||||
// yMin: Math.min(pt1.y, pt2.y, pt3.y, pt4.y),
|
||||
// xMax: Math.max(pt1.x, pt2.x, pt3.x, pt4.x),
|
||||
// yMax: Math.max(pt1.y, pt2.y, pt3.y, pt4.y)
|
||||
//};
|
||||
},
|
||||
enumerable: false
|
||||
},
|
||||
localToGlobal: {
|
||||
value: function localToGlobal(pt) {
|
||||
var m = this.matrix;
|
||||
if (this.rotation) {
|
||||
var rotationCos = Math.cos(this.rotation * Math.PI / 180);
|
||||
var rotationSin = Math.sin(this.rotation * Math.PI / 180);
|
||||
pt = {
|
||||
x: rotationCos * pt.x - rotationSin * pt.y,
|
||||
y: rotationSin * pt.x + rotationCos * pt.y
|
||||
};
|
||||
}
|
||||
var result = !m ? pt : {
|
||||
x: m.a * pt.x + m.b * pt.y + m.e / 20,
|
||||
y: m.c * pt.x + m.d * pt.y + m.f / 20
|
||||
};
|
||||
return this.parent ? this.parent.localToGlobal(result) : result;
|
||||
},
|
||||
enumerable: false
|
||||
},
|
||||
globalToLocal: {
|
||||
value: function globalToLocal(pt) {
|
||||
var result = this.parent ? this.parent.globalToLocal(pt) : pt;
|
||||
var m = this.matrix;
|
||||
var k = m ? 1 / (m.a * m.d - m.b * m.c) : 0;
|
||||
var result = !m ? result : {
|
||||
x: m.a * k * result.x - m.b * k * result.y +
|
||||
(m.e * m.b - m.e * m.a) * k / 20,
|
||||
y: -m.c * k * result.x + m.d * k * result.y +
|
||||
(m.f * m.c - m.f * m.d) * k / 20
|
||||
};
|
||||
if (this.rotation) {
|
||||
var rotationCos = Math.cos(this.rotation * Math.PI / 180);
|
||||
var rotationSin = Math.sin(this.rotation * Math.PI / 180);
|
||||
result = {
|
||||
x: rotationCos * result.x + rotationSin * result.y,
|
||||
y: -rotationSin * result.x + rotationCos * result.y
|
||||
};
|
||||
}
|
||||
return result;
|
||||
},
|
||||
enumerable: false
|
||||
},
|
||||
hitTest: {
|
||||
value: function hitTest() {
|
||||
var bounds = this.getBounds(this.root);
|
||||
if (typeof arguments[0] === 'object') {
|
||||
var target = arguments[0];
|
||||
var targetBounds = target.getBounds(this.root);
|
||||
var x1 = this.x;
|
||||
var y1 = this.y;
|
||||
var x2 = target.x;
|
||||
var y2 = target.y;
|
||||
var x3 = Math.max(x1, x2);
|
||||
var y3 = Math.max(y1, y2);
|
||||
var width = Math.min(
|
||||
x1 + (bounds.xMax - bounds.xMin) / 20,
|
||||
x2 + (targetBounds.xMax - targetBounds.xMin) / 20
|
||||
) - x3;
|
||||
var height = Math.min(
|
||||
y1 + (bounds.yMax - bounds.yMin) / 20,
|
||||
y2 + (targetBounds.yMax - targetBounds.yMin) / 20
|
||||
) - y3;
|
||||
return width > 0 && height > 0;
|
||||
} else {
|
||||
var x = arguments[0];
|
||||
var y = arguments[1];
|
||||
var shapeFlag = arguments[2];
|
||||
if (shapeFlag) {
|
||||
// HACK shadow canvas hit testing
|
||||
if (!this.hitTestCache) {
|
||||
this.hitTestCache = {};
|
||||
renderShadowCanvas(this);
|
||||
}
|
||||
var pt = this.globalToLocal({x: x, y: y});
|
||||
return this.hitTestCache.isPixelPainted(pt.x, pt.y);
|
||||
} else {
|
||||
return x > bounds.xMin / 20 && x < bounds.xMax / 20 &&
|
||||
y > bounds.yMin / 20 && y < bounds.yMax / 20;
|
||||
}
|
||||
}
|
||||
},
|
||||
enumerable: false
|
||||
},
|
||||
x: {
|
||||
get: function get$x() {
|
||||
return this.matrix.e / 20;
|
||||
},
|
||||
set: function set$x(value) {
|
||||
if (!this.matrix)
|
||||
debugger;
|
||||
this.matrix.e = ~~(value * 20);
|
||||
this.$fixMatrix = true;
|
||||
},
|
||||
enumerable: true
|
||||
},
|
||||
y: {
|
||||
get: function get$y() {
|
||||
return this.matrix.f / 20;
|
||||
},
|
||||
set: function set$y(value) {
|
||||
this.matrix.f = ~~(value * 20);
|
||||
this.$fixMatrix = true;
|
||||
},
|
||||
enumerable: true
|
||||
},
|
||||
mouseX: {
|
||||
get: function get$mouseY() {
|
||||
return getMouseCoordinates().x;
|
||||
},
|
||||
enumerable: true
|
||||
},
|
||||
mouseY: {
|
||||
get: function get$mouseY() {
|
||||
return getMouseCoordinates().y;
|
||||
},
|
||||
enumerable: true
|
||||
}
|
||||
});
|
||||
|
||||
var events = {
|
||||
onMouseDown: function() {
|
||||
lastMouseCoordinates = null;
|
||||
dispatchEvent('onMouseDown');
|
||||
},
|
||||
onMouseMove: function() {
|
||||
lastMouseCoordinates = null;
|
||||
dispatchEvent('onMouseMove');
|
||||
},
|
||||
onMouseUp: function () {
|
||||
lastMouseCoordinates = null;
|
||||
dispatchEvent('onMouseUp');
|
||||
},
|
||||
onMouseWheel: function () {
|
||||
dispatchEvent('onMouseWheel', arguments);
|
||||
},
|
||||
onKeyDown: function() {
|
||||
dispatchEvent('onKeyDown');
|
||||
},
|
||||
onKeyUp: function() {
|
||||
dispatchEvent('onKeyUp');
|
||||
},
|
||||
};
|
||||
AS2Mouse.addListener(events);
|
||||
AS2Key.addListener(events);
|
||||
};
|
||||
|
||||
// HACK button as movieclip
|
||||
var ButtonPrototype = function(obj, timelineLoader) {
|
||||
var instance;
|
||||
|
||||
var AS2ButtonConditions = [
|
||||
[null, 'idleToOverUp', 'idleToOverDown', null],
|
||||
['overUpToIdle', null, 'overUpToOverDown', null],
|
||||
['overDownToIdle', 'overDownToOverUp', null, 'overDownToOutDown'],
|
||||
['outDownToIdle', null, 'outDownToOverDown', null]
|
||||
];
|
||||
|
||||
function ButtonEvents(instance) {
|
||||
this.instance = instance;
|
||||
this.buttonPressed = false;
|
||||
this.inBounds = false;
|
||||
this.lastState = 0;
|
||||
}
|
||||
ButtonEvents.prototype = {
|
||||
onMouseDown: function() {
|
||||
this.buttonPressed = true;
|
||||
this.updateButtonState();
|
||||
},
|
||||
onMouseMove: function() {
|
||||
this.inBounds = this.instance.hitTest(this.instance.mouseX, this.instance.mouseY, true);
|
||||
this.updateButtonState();
|
||||
},
|
||||
onMouseUp: function () {
|
||||
this.buttonPressed = false;
|
||||
this.updateButtonState();
|
||||
},
|
||||
updateButtonState: function() {
|
||||
var state = 0, lastState = this.lastState;
|
||||
if (!this.inBounds)
|
||||
state = 0;
|
||||
else if (!this.buttonPressed)
|
||||
state = 1;
|
||||
else
|
||||
state = 2;
|
||||
|
||||
switch (state) {
|
||||
case 0:
|
||||
this.instance.gotoAndStop(1);
|
||||
break;
|
||||
case 1:
|
||||
this.instance.gotoAndStop(2);
|
||||
break;
|
||||
case 2:
|
||||
this.instance.gotoAndStop(3);
|
||||
break;
|
||||
}
|
||||
|
||||
if (lastState == 0 && state != 0)
|
||||
this.instance.$dispatchEvent('onRollOver');
|
||||
else if (lastState != 0 && state == 0)
|
||||
this.instance.$dispatchEvent('onRollOut');
|
||||
else if (lastState != 2 && state == 2)
|
||||
this.instance.$dispatchEvent('onPress');
|
||||
else if (lastState == 2 && state != 2)
|
||||
this.instance.$dispatchEvent('onRelease');
|
||||
|
||||
this.dispatchAS2Events(lastState, state);
|
||||
this.lastState = state;
|
||||
},
|
||||
dispatchAS2Events: function(lastState, state) {
|
||||
var buttonActions = this.instance.buttonActions;
|
||||
if (!buttonActions)
|
||||
return;
|
||||
var buttonCondition = AS2ButtonConditions[lastState][state];
|
||||
if (!buttonCondition)
|
||||
return;
|
||||
if (!this.as2ActionsCache)
|
||||
this.as2ActionsCache = {};
|
||||
var buttonActionsCache = this.as2ActionsCache[buttonCondition];
|
||||
if (!buttonActionsCache) {
|
||||
buttonActionsCache = [];
|
||||
for (var i = 0; i < buttonActions.length; i++) {
|
||||
if (!buttonActions[i][buttonCondition])
|
||||
continue;
|
||||
var actionsData = buttonActions[i].actionsData;
|
||||
buttonActionsCache.push(this.instance.$createAS2Script(actionsData));
|
||||
}
|
||||
this.as2ActionsCache[buttonCondition] = buttonActionsCache;
|
||||
}
|
||||
for (var i = 0; i < buttonActionsCache.length; i++)
|
||||
buttonActionsCache[i].call(this.instance);
|
||||
},
|
||||
onMouseWheel: function () {}
|
||||
};
|
||||
|
||||
this._timelineLoader = timelineLoader;
|
||||
var proto = MovieClipClass.apply(this, arguments) || this;
|
||||
proto.nativeObjectContructor = AS2Button;
|
||||
proto.buttonActions = obj.buttonActions;
|
||||
proto.constructor = (function(oldContructor) {
|
||||
return (function() {
|
||||
var result = oldContructor.apply(this, arguments);
|
||||
result.gotoAndStop(4); // invoke hitTest layer
|
||||
result.gotoAndStop(1); // then return to the normal
|
||||
|
||||
result.renderNextFrame = (function(oldRenderNextFrame) {
|
||||
return (function(context) {
|
||||
if (!context.isHitTestRendering)
|
||||
return oldRenderNextFrame.apply(this, arguments);
|
||||
|
||||
var displayList = this.$getDisplayList(4);
|
||||
if (!displayList)
|
||||
return; // skiping non-prepared frame
|
||||
|
||||
render(displayList, context);
|
||||
});
|
||||
})(result.renderNextFrame);
|
||||
|
||||
AS2Mouse.addListener(new ButtonEvents(result));
|
||||
return result;
|
||||
});
|
||||
})(proto.constructor);
|
||||
return proto;
|
||||
};
|
||||
|
||||
// HACK mocking the sound clips presence
|
||||
var SoundMock = function(assets) {
|
||||
var clip = {
|
||||
start: function() {},
|
||||
setVolume: function() {}
|
||||
};
|
||||
var as2Object = {};
|
||||
for (var i = 0; i < assets.length; i++)
|
||||
if (assets[i].className)
|
||||
as2Object[assets[i].className] = clip;
|
||||
this.$as2Object = as2Object;
|
||||
};
|
|
@ -1,158 +1,7 @@
|
|||
/* -*- mode: javascript; tab-width: 4; insert-tabs-mode: nil; indent-tabs-mode: nil -*- */
|
||||
|
||||
//function renderShadowCanvas(child) {
|
||||
// var cache = child.hitTestCache;
|
||||
//
|
||||
// var bounds = child.getBounds();
|
||||
// var offsetX = Math.floor(bounds.x / 20);
|
||||
// var offsetY = Math.floor(bounds.y / 20);
|
||||
// var sizeX = Math.ceil(bounds.width / 20);
|
||||
// var sizeY = Math.ceil(bounds.height / 20);
|
||||
//
|
||||
// var canvas = cache.canvas;
|
||||
// if (!canvas) {
|
||||
// cache.canvas = canvas = document.createElement('canvas');
|
||||
// cache.isPixelPainted = function(x, y) {
|
||||
// x = 0 | (x - offsetX);
|
||||
// y = 0 | (y - offsetY);
|
||||
// if (x < 0 || y < 0 || x >= sizeX || y >= sizeY)
|
||||
// return false;
|
||||
// var data = cache.imageData.data;
|
||||
// var result = data[(x + sizeX * y) * 4 + 3];
|
||||
// return !!result;
|
||||
// };
|
||||
// }
|
||||
//
|
||||
// if (sizeX <= 0 || sizeY <= 0)
|
||||
// return;
|
||||
//
|
||||
// canvas.width = sizeX;
|
||||
// canvas.height = sizeY;
|
||||
//
|
||||
// var ctx = canvas.getContext('2d');
|
||||
// ctx.save();
|
||||
// ctx.mozFillRule = 'evenodd';
|
||||
// ctx.clearRect(0, 0, sizeX, sizeY);
|
||||
// ctx.translate(-offsetX, -offsetY);
|
||||
// ctx.scale(0.05, 0.05);
|
||||
//
|
||||
// if (child.draw)
|
||||
// child.draw(ctx, child.ratio);
|
||||
// else if (child.nextFrame) {
|
||||
// var renderContext = {
|
||||
// isHitTestRendering: true,
|
||||
// beginDrawing: function() { return ctx; },
|
||||
// endDrawing: function() {}
|
||||
// };
|
||||
// child.renderNextFrame(renderContext);
|
||||
// }
|
||||
//
|
||||
// ctx.restore();
|
||||
//
|
||||
// cache.ratio = child.ratio;
|
||||
// cache.imageData = ctx.getImageData(0, 0, sizeX, sizeY);
|
||||
//}
|
||||
|
||||
function renderStage(stage, ctx) {
|
||||
// All the visitors close over this class to do instance testing.
|
||||
const MovieClipClass = avm2.systemDomain.getClass("flash.display.MovieClip");
|
||||
const ContainerClass = avm2.systemDomain.getClass("flash.display.DisplayObjectContainer");
|
||||
|
||||
function visitContainer(container, visitor) {
|
||||
var children = container._children;
|
||||
visitor.childrenStart(container);
|
||||
for (var i = 0, n = children.length; i < n; i++) {
|
||||
var child = children[i];
|
||||
if (child) {
|
||||
var isContainer = ContainerClass.isInstanceOf(child);
|
||||
visitor.visit(child, isContainer);
|
||||
if (isContainer) {
|
||||
visitContainer(child, visitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
visitor.childrenEnd(container);
|
||||
}
|
||||
|
||||
function EnterFrameVisitor() {
|
||||
}
|
||||
EnterFrameVisitor.prototype = {
|
||||
childrenStart: function() {},
|
||||
childrenEnd: function() {},
|
||||
visit: function (obj) {
|
||||
if (MovieClipClass.isInstanceOf(obj)) {
|
||||
if (obj.isPlaying()) {
|
||||
obj.nextFrame();
|
||||
}
|
||||
obj.dispatchEvent(new flash.events.Event("enterFrame"));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function ExitFrameVisitor() {
|
||||
}
|
||||
ExitFrameVisitor.prototype = {
|
||||
childrenStart: function() {},
|
||||
childrenEnd: function() {},
|
||||
visit: function (obj) {
|
||||
if (MovieClipClass.isInstanceOf(obj)) {
|
||||
obj.dispatchEvent(new flash.events.Event("exitFrame"));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function RenderVisitor(ctx) {
|
||||
this.depth = 0;
|
||||
this.ctx = ctx;
|
||||
}
|
||||
RenderVisitor.prototype = {
|
||||
childrenStart: function(parent) {
|
||||
if (this.depth == 0) {
|
||||
var ctx = this.ctx;
|
||||
var stage = parent;
|
||||
var frameWidth = ctx.canvas.width;
|
||||
var frameHeight = ctx.canvas.height;
|
||||
|
||||
var scaleX = frameWidth / stage.stageWidth;
|
||||
var scaleY = frameHeight / stage.stageHeight;
|
||||
var scale = Math.min(scaleX, scaleY);
|
||||
var offsetX = (frameWidth - scale * stage.stageWidth) / 2;
|
||||
var offsetY = (frameHeight - scale * stage.stageHeight) / 2;
|
||||
|
||||
ctx.clearRect(0, 0, frameWidth, frameHeight);
|
||||
ctx.save();
|
||||
ctx.translate(offsetX, offsetY);
|
||||
|
||||
ctx.canvas.currentTransform = {
|
||||
scale: scale,
|
||||
offsetX: offsetX,
|
||||
offsetY: offsetY
|
||||
};
|
||||
}
|
||||
this.depth++;
|
||||
|
||||
// TODO move into separate visitor?
|
||||
if (MovieClipClass.isInstanceOf(parent) && parent._scriptExecutionPending) {
|
||||
parent.callFrame(parent.currentFrame);
|
||||
parent._scriptExecutionPending = false;
|
||||
}
|
||||
},
|
||||
childrenEnd: function(parent) {
|
||||
this.depth--;
|
||||
this.ctx.restore();
|
||||
},
|
||||
visit: function (child, isContainer) {
|
||||
var ctx = this.ctx;
|
||||
ctx.save();
|
||||
//if (child.matrix && !child.$fixMatrix)
|
||||
// child.matrix = create(child.matrix);
|
||||
//if (child.cxform && !child.$fixCxform)
|
||||
// child.cxform = create(child.cxform);
|
||||
|
||||
var m = child._currentTransformMatrix;
|
||||
function renderDisplayObject(child, ctx, transform, cxform) {
|
||||
var m = transform;
|
||||
ctx.transform(m.a, m.b, m.c, m.d, m.tx, m.ty);
|
||||
|
||||
var cxform = child._cxform;
|
||||
if (cxform) {
|
||||
// We only support alpha channel transformation for now
|
||||
ctx.globalAlpha = (ctx.globalAlpha * cxform.alphaMultiplier + cxform.alphaOffset) / 256;
|
||||
|
@ -167,11 +16,12 @@ function renderStage(stage, ctx) {
|
|||
|
||||
var subpaths = graphics._subpaths;
|
||||
for (var j = 0, o = subpaths.length; j < o; j++) {
|
||||
var path = subpaths[j];
|
||||
var pathTracker = subpaths[j], path = pathTracker.target;
|
||||
if (path.fillStyle) {
|
||||
ctx.fillStyle = path.fillStyle;
|
||||
if (path.fillTransform) {
|
||||
var m = path.fillTransform;
|
||||
ctx.beginPath();
|
||||
path.__draw__(ctx);
|
||||
ctx.save();
|
||||
ctx.transform(m.a, m.b, m.c, m.d, m.tx, m.ty);
|
||||
|
@ -183,7 +33,7 @@ function renderStage(stage, ctx) {
|
|||
}
|
||||
if (path.strokeStyle) {
|
||||
ctx.strokeStyle = path.strokeStyle;
|
||||
var drawingStyles = path.drawingStyles;
|
||||
var drawingStyles = pathTracker.drawingStyles;
|
||||
for (var prop in drawingStyles)
|
||||
ctx[prop] = drawingStyles[prop];
|
||||
ctx.stroke(path);
|
||||
|
@ -191,74 +41,245 @@ function renderStage(stage, ctx) {
|
|||
}
|
||||
}
|
||||
|
||||
if (child.draw) {
|
||||
if (child.draw)
|
||||
child.draw(ctx, child.ratio);
|
||||
}
|
||||
|
||||
function renderStage(stage, ctx, onFrame) {
|
||||
var frameWidth = ctx.canvas.width;
|
||||
var frameHeight = ctx.canvas.height;
|
||||
|
||||
var scaleX = frameWidth / stage._stageWidth;
|
||||
var scaleY = frameHeight / stage._stageHeight;
|
||||
|
||||
var scale = Math.min(scaleX, scaleY);
|
||||
var offsetX = (frameWidth - scale * stage.stageWidth) / 2;
|
||||
var offsetY = (frameHeight - scale * stage.stageHeight) / 2;
|
||||
|
||||
ctx.translate(offsetX, offsetY);
|
||||
ctx.scale(scale, scale);
|
||||
|
||||
// All the visitors close over this class to do instance testing.
|
||||
var MovieClipClass = avm2.systemDomain.getClass("flash.display.MovieClip");
|
||||
var ContainerClass = avm2.systemDomain.getClass("flash.display.DisplayObjectContainer");
|
||||
var SimpleButtonClass = avm2.systemDomain.getClass("flash.display.SimpleButton");
|
||||
var InteractiveClass = avm2.systemDomain.getClass("flash.display.InteractiveObject");
|
||||
|
||||
function visitContainer(container, visitor, interactiveParent) {
|
||||
var children = container._children;
|
||||
var dirty = false;
|
||||
|
||||
visitor.childrenStart(container);
|
||||
|
||||
for (var i = 0, n = children.length; i < n; i++) {
|
||||
var child = children[i];
|
||||
if (child) {
|
||||
var isContainer = ContainerClass.isInstanceOf(child) ||
|
||||
SimpleButtonClass.isInstanceOf(child);
|
||||
|
||||
if (InteractiveClass.isInstanceOf(child) && child._mouseEnabled) {
|
||||
if (!interactiveParent || interactiveParent._mouseChildren)
|
||||
interactiveParent = child;
|
||||
}
|
||||
|
||||
visitor.visit(child, isContainer, interactiveParent);
|
||||
|
||||
if (isContainer)
|
||||
visitContainer(child, visitor, interactiveParent);
|
||||
|
||||
if (child._dirtyArea)
|
||||
dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
visitor.childrenEnd(container);
|
||||
|
||||
if (dirty)
|
||||
container._bounds = null;
|
||||
}
|
||||
|
||||
function PreVisitor(ctx) {
|
||||
this.ctx = ctx;
|
||||
}
|
||||
PreVisitor.prototype = {
|
||||
childrenStart: function() {},
|
||||
childrenEnd: function() {},
|
||||
visit: function (child, isContainer, interactiveParent) {
|
||||
if (MovieClipClass.isInstanceOf(child)) {
|
||||
if (child.isPlaying()) {
|
||||
child.nextFrame();
|
||||
}
|
||||
child.dispatchEvent(new flash.events.Event("enterFrame"));
|
||||
}
|
||||
|
||||
if (child._refreshAS2Variables) {
|
||||
child._refreshAS2Variables();
|
||||
}
|
||||
|
||||
var mouseMoved = false;
|
||||
|
||||
var pt = { x: stage._mouseX, y: stage._mouseY };
|
||||
child._applyCurrentInverseTransform(pt, child._parent);
|
||||
|
||||
if (pt.x !== child._mouseX || pt.y !== child._mouseY)
|
||||
mouseMoved = true;
|
||||
|
||||
child._mouseX = pt.x;
|
||||
child._mouseY = pt.y;
|
||||
|
||||
if (interactiveParent && (stage._mouseOver || stage._mouseJustLeft)) {
|
||||
var hitArea = child._hitArea || child;
|
||||
|
||||
if (child._hitTest(true, pt.x, pt.y, true, true)) {
|
||||
if (interactiveParent._mouseOver) {
|
||||
if (mouseMoved)
|
||||
interactiveParent.dispatchEvent(new flash.events.MouseEvent('mouseMove'));
|
||||
} else {
|
||||
interactiveParent._mouseOver = true;
|
||||
interactiveParent.dispatchEvent(new flash.events.MouseEvent('mouseOver'));
|
||||
}
|
||||
|
||||
stage._clickTarget = interactiveParent;
|
||||
} else {
|
||||
if (interactiveParent._mouseOver) {
|
||||
interactiveParent._mouseOver = false;
|
||||
interactiveParent.dispatchEvent(new flash.events.MouseEvent('mouseOut'));
|
||||
}
|
||||
|
||||
if (stage._clickTarget === interactiveParent)
|
||||
stage._clickTarget = null;
|
||||
}
|
||||
stage._mouseJustLeft = false;
|
||||
}
|
||||
|
||||
if (child._dirtyArea) {
|
||||
var b1 = child._dirtyArea;
|
||||
var b2 = child.getBounds();
|
||||
this.ctx.rect((~~b1.x) - 5, (~~b1.y) - 5, (~~b1.width) + 10, (~~b1.height) + 10);
|
||||
this.ctx.rect((~~b2.x) - 5, (~~b2.y) - 5, (~~b2.width) + 10, (~~b2.height) + 10);
|
||||
} else if (child._graphics && (child._graphics._revision !== child._revision)) {
|
||||
child._revision = child._graphics._revision;
|
||||
child._markAsDirty();
|
||||
// redraw entire stage till we calculate bounding boxes for dynamic graphics
|
||||
this.ctx.rect(0, 0, frameWidth, frameHeight);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function PostVisitor() {
|
||||
}
|
||||
PostVisitor.prototype = {
|
||||
childrenStart: function() {},
|
||||
childrenEnd: function() {},
|
||||
visit: function (child) {
|
||||
if (MovieClipClass.isInstanceOf(child))
|
||||
child.dispatchEvent(new flash.events.Event("exitFrame"));
|
||||
}
|
||||
};
|
||||
|
||||
function ScriptExecutionVisitor() {}
|
||||
ScriptExecutionVisitor.prototype = {
|
||||
childrenStart: function() {},
|
||||
childrenEnd: function() {},
|
||||
visit: function (obj) {
|
||||
if (obj._scriptExecutionPending) {
|
||||
obj._scriptExecutionPending = false;
|
||||
|
||||
var currentFrame = obj._currentFrame;
|
||||
obj._callFrame(currentFrame);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function RenderVisitor(ctx) {
|
||||
this.ctx = ctx;
|
||||
this.depth = 0;
|
||||
}
|
||||
RenderVisitor.prototype = {
|
||||
childrenStart: function(parent) {
|
||||
if (this.depth == 0) {
|
||||
var ctx = this.ctx;
|
||||
|
||||
ctx.save();
|
||||
|
||||
ctx.clip();
|
||||
|
||||
ctx.clearRect(0, 0, frameWidth, frameHeight);
|
||||
|
||||
ctx.mozFillRule = 'evenodd';
|
||||
|
||||
stage._canvasState = {
|
||||
canvas: ctx.canvas,
|
||||
scale: scale,
|
||||
offsetX: offsetX,
|
||||
offsetY: offsetY
|
||||
};
|
||||
}
|
||||
this.depth++;
|
||||
},
|
||||
childrenEnd: function(parent) {
|
||||
this.depth--;
|
||||
this.ctx.restore();
|
||||
},
|
||||
visit: function (child, isContainer) {
|
||||
if (child._clipDepth) {
|
||||
// TODO handle masking
|
||||
return;
|
||||
}
|
||||
|
||||
var ctx = this.ctx;
|
||||
ctx.save();
|
||||
|
||||
renderDisplayObject(child, ctx, child._currentTransform, child._cxform);
|
||||
|
||||
if (!isContainer) {
|
||||
// letting the container to restore transforms after all children are painted
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
//if (child.hitTestCache && child.hitTestCache.ratio != child.ratio)
|
||||
// renderShadowCanvas(child);
|
||||
if (stage._showRedrawRegions && child._dirtyArea) {
|
||||
var b = child._dirtyArea;
|
||||
ctx.save();
|
||||
ctx.strokeStyle = '#f00';
|
||||
ctx.lineWidth = 1;
|
||||
ctx.strokeRect(b.x, b.y, b.width, b.height);
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
child._dirtyArea = null;
|
||||
}
|
||||
};
|
||||
|
||||
var frameTime = 0;
|
||||
var maxDelay = 1000 / stage.frameRate;
|
||||
|
||||
ctx.mozFillRule = 'evenodd';
|
||||
|
||||
var requestAnimationFrame = window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame;
|
||||
|
||||
var FPS = (function () {
|
||||
var width = Math.max(ctx.canvas.width / 5, 100);
|
||||
var height = width / 8;
|
||||
var sampleWidth = 2;
|
||||
var sampleCount = width / (sampleWidth + 1);
|
||||
var last = null;
|
||||
var samples = [];
|
||||
var max = 0;
|
||||
|
||||
return {
|
||||
tick: function () {
|
||||
var curr = new Date();
|
||||
if (last) {
|
||||
if (samples.length > sampleCount) {
|
||||
samples.shift();
|
||||
}
|
||||
var elapsed = curr - last;
|
||||
samples.push(elapsed);
|
||||
var sum = 0;
|
||||
for (var i = 0; i < samples.length; i++) {
|
||||
sum += samples[i];
|
||||
max = Math.max(max, samples[i]);
|
||||
}
|
||||
var avg = sum / samples.length;
|
||||
var xOffset = ctx.canvas.width - width;
|
||||
var yOffset = height;
|
||||
for (var i = 0; i < samples.length; i++) {
|
||||
var scaledSample = (samples[i] / (2 * avg));
|
||||
ctx.fillRect(xOffset + i * (sampleWidth + 1), yOffset, sampleWidth, - scaledSample * height);
|
||||
}
|
||||
ctx.font = "6pt Verdana";
|
||||
ctx.fillText("FPS: " + (1000 / avg).toFixed(2), xOffset, height + 15);
|
||||
}
|
||||
last = curr;
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
var requestAnimationFrame = window.requestAnimationFrame ||
|
||||
window.mozRequestAnimationFrame ||
|
||||
window.webkitRequestAnimationFrame ||
|
||||
window.oRequestAnimationFrame ||
|
||||
window.msRequestAnimationFrame ||
|
||||
window.setTimeout;
|
||||
|
||||
(function draw() {
|
||||
var now = +new Date;
|
||||
if (now - frameTime >= maxDelay) {
|
||||
frameTime = now;
|
||||
visitContainer(stage, new EnterFrameVisitor());
|
||||
|
||||
ctx.beginPath();
|
||||
|
||||
stage._callFrameRequested = false;
|
||||
visitContainer(stage, new PreVisitor(ctx));
|
||||
while (stage._callFrameRequested) {
|
||||
stage._callFrameRequested = false;
|
||||
visitContainer(stage, new ScriptExecutionVisitor());
|
||||
}
|
||||
visitContainer(stage, new RenderVisitor(ctx));
|
||||
visitContainer(stage, new ExitFrameVisitor());
|
||||
FPS.tick();
|
||||
visitContainer(stage, new PostVisitor());
|
||||
stage._syncCursor();
|
||||
|
||||
if (onFrame) {
|
||||
onFrame();
|
||||
}
|
||||
}
|
||||
requestAnimationFrame(draw);
|
||||
})();
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче