Skip to content

Commit baae767

Browse files
committedFeb 17, 2017
Rework on WebWorkers to not require blob urls, introduced new script and font variables for better minification support (#106, #116)
1 parent a074c04 commit baae767

14 files changed

+665
-564
lines changed
 

‎Build/JavaScript/AlphaTab.js

+160-138
Large diffs are not rendered by default.

‎Build/JavaScript/AlphaTab.min.js

+15-18
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Build/JavaScript/jquery.alphaTab.alphaSynth.js

+27-13
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,22 @@
1-
(function($) {
1+
/*
2+
* This file is part of alphaTab.
3+
* Copyright c 2013, Daniel Kuschny and Contributors, All rights reserved.
4+
*
5+
* This library is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation; either
8+
* version 3.0 of the License, or at your option any later version.
9+
*
10+
* This library is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public
16+
* License along with this library.
17+
*/
18+
(function ($) {
19+
if(!$) { return; }
220
function loadMidi(element, context, as, score) {
321
// invalid score
422
if(score == null || !as.Ready) return;
@@ -48,13 +66,13 @@
4866
var selectionEnd = null;
4967
var selecting = false;
5068

51-
api.getTickCache = function(element) {
52-
return element.data('alphaSynthTickCache');
53-
}
54-
api.getCursorCache = function(element) {
55-
return element.data('alphaSynthCursorCache');
56-
}
57-
69+
api.getTickCache = function(element) {
70+
return element.data('alphaSynthTickCache');
71+
}
72+
api.getCursorCache = function(element) {
73+
return element.data('alphaSynthCursorCache');
74+
}
75+
5876
// updates the cursors to highlight the beat at the specified tick position
5977
api.playerCursorUpdateTick = function(element, context, tick) {
6078
requestAnimationFrame(function() {
@@ -450,8 +468,4 @@
450468
var cache = api.getCursorCache(element);
451469
return cache.GetBeatAtPos(x, y);
452470
};
453-
454-
455-
})(jQuery);
456-
457-
471+
})(typeof jQuery !== 'undefined' ? jQuery : null);

‎Build/JavaScript/jquery.alphaTab.drop.js

+21-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,23 @@
1-
(function($)
2-
{
1+
/*
2+
* This file is part of alphaTab.
3+
* Copyright c 2013, Daniel Kuschny and Contributors, All rights reserved.
4+
*
5+
* This library is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation; either
8+
* version 3.0 of the License, or at your option any later version.
9+
*
10+
* This library is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public
16+
* License along with this library.
17+
*/
18+
(function($) {
19+
if(!$) { return; }
20+
321
var supported = (window.File && window.FileReader && window.FileList && window.Blob);
422

523
// extend the api
@@ -39,6 +57,4 @@
3957
});
4058
}
4159
};
42-
43-
44-
})(jQuery);
60+
})(typeof jQuery !== 'undefined' ? jQuery : null);

‎Build/JavaScript/jquery.alphaTab.js

+38-37
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
* License along with this library.
1717
*/
1818
(function ($) {
19+
if(!$) { return }
1920

2021
var api = {
2122
init: function(element, context, options) {
@@ -105,41 +106,41 @@
105106
};
106107
// allow plugins to add methods
107108
$.fn.alphaTab.fn = api;
109+
110+
/**
111+
* VB Loader For IE
112+
* This code is based on the code of
113+
* http://nagoon97.com/reading-binary-files-using-ajax/
114+
* Copyright (c) 2008 Andy G.P. Na <nagoon97@naver.com>
115+
* The source code is freely distributable under the terms of an MIT-style license.
116+
*/
117+
document.write('<script type="text/vbscript">\n\
118+
Function VbAjaxLoader(method, fileName)\n\
119+
Dim xhr\n\
120+
Set xhr = CreateObject("Microsoft.XMLHTTP")\n\
121+
\n\
122+
xhr.Open method, fileName, False\n\
123+
\n\
124+
xhr.setRequestHeader "Accept-Charset", "x-user-defined"\n\
125+
xhr.send\n\
126+
\n\
127+
Dim byteArray()\n\
128+
\n\
129+
if xhr.Status = 200 Then\n\
130+
Dim byteString\n\
131+
Dim i\n\
132+
\n\
133+
byteString=xhr.responseBody\n\
134+
\n\
135+
ReDim byteArray(LenB(byteString))\n\
136+
\n\
137+
For i = 1 To LenB(byteString)\n\
138+
byteArray(i-1) = AscB(MidB(byteString, i, 1))\n\
139+
Next\n\
140+
End If\n\
141+
\n\
142+
VbAjaxLoader=byteArray\n\
143+
End Function\n\
144+
</script>');
108145

109-
})(jQuery);
110-
111-
/**
112-
* VB Loader For IE
113-
* This code is based on the code of
114-
* http://nagoon97.com/reading-binary-files-using-ajax/
115-
* Copyright (c) 2008 Andy G.P. Na <nagoon97@naver.com>
116-
* The source code is freely distributable under the terms of an MIT-style license.
117-
*/
118-
document.write('<script type="text/vbscript">\n\
119-
Function VbAjaxLoader(method, fileName)\n\
120-
Dim xhr\n\
121-
Set xhr = CreateObject("Microsoft.XMLHTTP")\n\
122-
\n\
123-
xhr.Open method, fileName, False\n\
124-
\n\
125-
xhr.setRequestHeader "Accept-Charset", "x-user-defined"\n\
126-
xhr.send\n\
127-
\n\
128-
Dim byteArray()\n\
129-
\n\
130-
if xhr.Status = 200 Then\n\
131-
Dim byteString\n\
132-
Dim i\n\
133-
\n\
134-
byteString=xhr.responseBody\n\
135-
\n\
136-
ReDim byteArray(LenB(byteString))\n\
137-
\n\
138-
For i = 1 To LenB(byteString)\n\
139-
byteArray(i-1) = AscB(MidB(byteString, i, 1))\n\
140-
Next\n\
141-
End If\n\
142-
\n\
143-
VbAjaxLoader=byteArray\n\
144-
End Function\n\
145-
</script>');
146+
})(typeof jQuery !== 'undefined' ? jQuery : null);

‎Samples/JavaScript/lib/alphaSynth/AlphaSynth.js

+129-121
Large diffs are not rendered by default.

‎Samples/JavaScript/lib/alphaSynth/AlphaSynth.min.js

+7-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Source/AlphaTab.JavaScript/AlphaTab.JavaScript.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
<Compile Include="Environment.cs" />
6868
<Compile Include="Model\JsonConverter.cs" />
6969
<Compile Include="Platform\JavaScript\JsApiBase.cs" />
70+
<Compile Include="Platform\JavaScript\JsWorker.cs" />
7071
<Compile Include="Platform\JavaScript\JsWorkerApi.cs" />
7172
<Compile Include="Platform\JavaScript\Html5Canvas.cs" />
7273
<Compile Include="Platform\JavaScript\JsApi.cs" />

‎Source/AlphaTab.JavaScript/Environment.cs

+5-3
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ static void PlatformInit()
5151
// try to build the find the alphaTab script url in case we are not in the webworker already
5252
if (HtmlContext.self.document.As<bool>())
5353
{
54-
var scriptElement = HtmlContext.document.Member("currentScript").As<HtmlScriptElement>();
5554

55+
var scriptElement = HtmlContext.document.Member("currentScript").As<HtmlScriptElement>();
5656
if (!scriptElement.As<bool>())
5757
{
5858
// try to get javascript from exception stack
@@ -72,7 +72,8 @@ static void PlatformInit()
7272
var stack = e.Member("stack");
7373
if (!stack.As<bool>())
7474
{
75-
scriptElement = HtmlContext.document.querySelector("script[data-alphatab]").As<HtmlScriptElement>();
75+
scriptElement =
76+
HtmlContext.document.querySelector("script[data-alphatab]").As<HtmlScriptElement>();
7677
}
7778
else
7879
{
@@ -170,7 +171,8 @@ private static void CheckFontLoad()
170171
}
171172
else
172173
{
173-
HtmlContext.window.setTimeout(() => {
174+
HtmlContext.window.setTimeout(() =>
175+
{
174176
checkFont();
175177
}, 1000);
176178
}

‎Source/AlphaTab.JavaScript/Platform/JavaScript/JsApiBase.cs

+1-3
Original file line numberDiff line numberDiff line change
@@ -369,9 +369,7 @@ private void CreateStyleElement(Settings settings)
369369
var styleElement = (HtmlStyleElement)document.getElementById("alphaTabStyle");
370370
if (styleElement == null)
371371
{
372-
var fontDirectory = settings.ScriptFile;
373-
fontDirectory = fontDirectory.Substring(0, fontDirectory.LastIndexOf("/")) + "/Font/";
374-
372+
string fontDirectory = settings.FontDirectory;
375373
styleElement = (HtmlStyleElement)document.createElement("style");
376374
styleElement.id = "alphaTabStyle";
377375
styleElement.type = "text/css";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
using System;
2+
using AlphaTab.Collections;
3+
using AlphaTab.Importer;
4+
using AlphaTab.IO;
5+
using AlphaTab.Model;
6+
using AlphaTab.Rendering;
7+
using SharpKit.Html;
8+
using SharpKit.JavaScript;
9+
using WorkerContext = SharpKit.Html.workers.WorkerContext;
10+
11+
namespace AlphaTab.Platform.JavaScript
12+
{
13+
public class JsWorker
14+
{
15+
private ScoreRenderer _renderer;
16+
private WorkerContext _main;
17+
private int[] _trackIndexes;
18+
19+
public Score Score { get; set; }
20+
21+
public Track[] Tracks
22+
{
23+
get
24+
{
25+
var tracks = new FastList<Track>();
26+
27+
foreach (var track in _trackIndexes)
28+
{
29+
if (track >= 0 && track < Score.Tracks.Count)
30+
{
31+
tracks.Add(Score.Tracks[track]);
32+
}
33+
}
34+
35+
if (tracks.Count == 0 && Score.Tracks.Count > 0)
36+
{
37+
tracks.Add(Score.Tracks[0]);
38+
}
39+
40+
return tracks.ToArray();
41+
}
42+
}
43+
44+
public JsWorker(SharpKit.Html.workers.WorkerContext main)
45+
{
46+
_main = main;
47+
_main.addEventListener("message", HandleMessage, false);
48+
}
49+
50+
static JsWorker()
51+
{
52+
if (!HtmlContext.self.document.As<bool>())
53+
{
54+
new JsWorker(HtmlContext.self.As<WorkerContext>());
55+
}
56+
}
57+
58+
59+
private void HandleMessage(DOMEvent e)
60+
{
61+
var data = e.As<MessageEvent>().data;
62+
var cmd = data.Member("cmd").As<string>();
63+
switch (cmd)
64+
{
65+
case "alphaTab.initialize":
66+
var settings = Settings.FromJson(data.Member("settings"));
67+
_renderer = new ScoreRenderer(settings);
68+
_renderer.PartialRenderFinished += result => PostMessage(new { cmd = "alphaTab.partialRenderFinished", result = result });
69+
_renderer.RenderFinished += result => PostMessage(new { cmd = "alphaTab.renderFinished", result = result });
70+
_renderer.PostRenderFinished += () => PostMessage(new { cmd = "alphaTab.postRenderFinished", boundsLookup = _renderer.BoundsLookup.ToJson() });
71+
_renderer.PreRender += result => PostMessage(new { cmd = "alphaTab.preRender", result = result });
72+
break;
73+
case "alphaTab.load":
74+
Load(data.Member("data"), data.Member("indexes").As<int[]>());
75+
break;
76+
case "alphaTab.invalidate":
77+
_renderer.Invalidate();
78+
break;
79+
case "alphaTab.resize":
80+
_renderer.Resize(data.Member("width").As<int>());
81+
break;
82+
case "alphaTab.tex":
83+
Tex(data.Member("data").As<string>());
84+
break;
85+
case "alphaTab.renderMultiple":
86+
RenderMultiple(data.Member("data").As<int[]>());
87+
break;
88+
case "alphaTab.updateSettings":
89+
UpdateSettings(data.Member("settings"));
90+
break;
91+
}
92+
}
93+
94+
private void UpdateSettings(object settings)
95+
{
96+
_renderer.UpdateSettings(Settings.FromJson(settings));
97+
}
98+
99+
private void RenderMultiple(int[] trackIndexes)
100+
{
101+
_trackIndexes = trackIndexes;
102+
Render();
103+
}
104+
105+
private void Tex(string contents)
106+
{
107+
try
108+
{
109+
var parser = new AlphaTexImporter();
110+
var data = ByteBuffer.FromBuffer(Std.StringToByteArray(contents));
111+
parser.Init(data);
112+
_trackIndexes = new[] { 0 };
113+
ScoreLoaded(parser.ReadScore());
114+
}
115+
catch (Exception e)
116+
{
117+
Error(e);
118+
}
119+
}
120+
121+
private void Load(object data, int[] trackIndexes)
122+
{
123+
try
124+
{
125+
_trackIndexes = trackIndexes;
126+
if (Std.InstanceOf<ArrayBuffer>(data))
127+
{
128+
ScoreLoaded(ScoreLoader.LoadScoreFromBytes(Std.ArrayBufferToByteArray((ArrayBuffer)data)));
129+
}
130+
else if (Std.InstanceOf<Uint8Array>(data))
131+
{
132+
ScoreLoaded(ScoreLoader.LoadScoreFromBytes((byte[])data));
133+
}
134+
else if (JsContext.JsTypeOf(data) == JsTypes.@string)
135+
{
136+
ScoreLoader.LoadScoreAsync((string)data, ScoreLoaded, Error);
137+
}
138+
}
139+
catch (Exception e)
140+
{
141+
Error(e);
142+
}
143+
}
144+
145+
private void Error(Exception e)
146+
{
147+
PostMessage(new { cmd = "alphaTab.error", exception = JSON.parse(JSON.stringify(e)) });
148+
}
149+
150+
private void ScoreLoaded(Score score)
151+
{
152+
Score = score;
153+
var json = new JsonConverter();
154+
PostMessage(new { cmd = "alphaTab.loaded", score = json.ScoreToJsObject(score) });
155+
Render();
156+
}
157+
158+
private void Render()
159+
{
160+
_renderer.RenderMultiple(Tracks);
161+
}
162+
163+
[JsMethod(Export = false, InlineCodeExpression = "this._main.postMessage(o)")]
164+
private void PostMessage(object o)
165+
{
166+
}
167+
}
168+
}

‎Source/AlphaTab.JavaScript/Platform/JavaScript/JsWorkerApi.cs

+1-150
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,7 @@
1515
* You should have received a copy of the GNU Lesser General Public
1616
* License along with this library.
1717
*/
18-
using System;
19-
using AlphaTab.Collections;
20-
using AlphaTab.Importer;
21-
using AlphaTab.IO;
22-
using AlphaTab.Model;
18+
2319
using AlphaTab.Rendering;
2420
using SharpKit.Html;
2521
using SharpKit.JavaScript;
@@ -84,149 +80,4 @@ public override void Tex(string contents)
8480
Renderer.As<WorkerScoreRenderer>().Tex(contents);
8581
}
8682
}
87-
88-
public class JsWorker
89-
{
90-
private readonly ScoreRenderer _renderer;
91-
private SharpKit.Html.workers.WorkerContext _main;
92-
private int[] _trackIndexes;
93-
94-
public Score Score { get; set; }
95-
96-
public Track[] Tracks
97-
{
98-
get
99-
{
100-
var tracks = new FastList<Track>();
101-
102-
foreach (var track in _trackIndexes)
103-
{
104-
if (track >= 0 && track < Score.Tracks.Count)
105-
{
106-
tracks.Add(Score.Tracks[track]);
107-
}
108-
}
109-
110-
if (tracks.Count == 0 && Score.Tracks.Count > 0)
111-
{
112-
tracks.Add(Score.Tracks[0]);
113-
}
114-
115-
return tracks.ToArray();
116-
}
117-
}
118-
119-
public JsWorker(SharpKit.Html.workers.WorkerContext main, object options)
120-
{
121-
_main = main;
122-
_main.addEventListener("message", HandleMessage, false);
123-
Settings settings = Settings.FromJson(options);
124-
_renderer = new ScoreRenderer(settings);
125-
_renderer.PartialRenderFinished += result => PostMessage(new { cmd = "partialRenderFinished", result = result });
126-
_renderer.RenderFinished += result => PostMessage(new { cmd = "renderFinished", result = result });
127-
_renderer.PostRenderFinished += () => PostMessage(new { cmd = "postRenderFinished", boundsLookup = _renderer.BoundsLookup.ToJson() });
128-
_renderer.PreRender += result => PostMessage(new { cmd = "preRender", result = result });
129-
}
130-
131-
private void HandleMessage(DOMEvent e)
132-
{
133-
var data = e.As<MessageEvent>().data;
134-
var cmd = data.Member("cmd").As<string>();
135-
switch (cmd)
136-
{
137-
case "load":
138-
Load(data.Member("data"), data.Member("indexes").As<int[]>());
139-
break;
140-
case "invalidate":
141-
_renderer.Invalidate();
142-
break;
143-
case "resize":
144-
_renderer.Resize(data.Member("width").As<int>());
145-
break;
146-
case "tex":
147-
Tex(data.Member("data").As<string>());
148-
break;
149-
case "renderMultiple":
150-
RenderMultiple(data.Member("data").As<int[]>());
151-
break;
152-
case "updateSettings":
153-
UpdateSettings(data.Member("settings"));
154-
break;
155-
}
156-
}
157-
158-
private void UpdateSettings(object settings)
159-
{
160-
_renderer.UpdateSettings(Settings.FromJson(settings));
161-
}
162-
163-
private void RenderMultiple(int[] trackIndexes)
164-
{
165-
_trackIndexes = trackIndexes;
166-
Render();
167-
}
168-
169-
private void Tex(string contents)
170-
{
171-
try
172-
{
173-
var parser = new AlphaTexImporter();
174-
var data = ByteBuffer.FromBuffer(Std.StringToByteArray(contents));
175-
parser.Init(data);
176-
_trackIndexes = new[] { 0 };
177-
ScoreLoaded(parser.ReadScore());
178-
}
179-
catch (Exception e)
180-
{
181-
Error(e);
182-
}
183-
}
184-
185-
private void Load(object data, int[] trackIndexes)
186-
{
187-
try
188-
{
189-
_trackIndexes = trackIndexes;
190-
if (Std.InstanceOf<ArrayBuffer>(data))
191-
{
192-
ScoreLoaded(ScoreLoader.LoadScoreFromBytes(Std.ArrayBufferToByteArray((ArrayBuffer)data)));
193-
}
194-
else if (Std.InstanceOf<Uint8Array>(data))
195-
{
196-
ScoreLoaded(ScoreLoader.LoadScoreFromBytes((byte[])data));
197-
}
198-
else if (JsContext.JsTypeOf(data) == JsTypes.@string)
199-
{
200-
ScoreLoader.LoadScoreAsync((string)data, ScoreLoaded, Error);
201-
}
202-
}
203-
catch (Exception e)
204-
{
205-
Error(e);
206-
}
207-
}
208-
209-
private void Error(Exception e)
210-
{
211-
PostMessage(new { cmd = "error", exception = e });
212-
}
213-
214-
private void ScoreLoaded(Score score)
215-
{
216-
Score = score;
217-
var json = new JsonConverter();
218-
PostMessage(new { cmd = "loaded", score = json.ScoreToJsObject(score) });
219-
Render();
220-
}
221-
222-
private void Render()
223-
{
224-
_renderer.RenderMultiple(Tracks);
225-
}
226-
227-
[JsMethod(Export = false, InlineCodeExpression = "this._main.postMessage(o)")]
228-
private void PostMessage(object o)
229-
{
230-
}
231-
}
23283
}

‎Source/AlphaTab.JavaScript/Platform/JavaScript/WorkerScoreRenderer.cs

+15-44
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,13 @@
1616
* License along with this library.
1717
*/
1818
using System;
19-
using AlphaTab.Collections;
2019
using AlphaTab.Model;
2120
using AlphaTab.Rendering;
2221
using AlphaTab.Rendering.Utils;
2322
using SharpKit.Html;
24-
using SharpKit.Html.fileapi;
2523
using SharpKit.Html.workers;
2624
using SharpKit.JavaScript;
25+
using WorkerContext = SharpKit.Html.workers.WorkerContext;
2726

2827
namespace AlphaTab.Platform.JavaScript
2928
{
@@ -36,57 +35,29 @@ public class WorkerScoreRenderer : HtmlContext, IScoreRenderer
3635

3736
public WorkerScoreRenderer(Settings settings)
3837
{
39-
_worker = new Worker(CreateWorkerUrl());
40-
_worker.postMessage(new { cmd = "initialize", settings = settings.ToJson() });
38+
_worker = new Worker(settings.ScriptFile);
39+
_worker.postMessage(new { cmd = "alphaTab.initialize", settings = settings.ToJson() });
4140
_worker.addEventListener("message", HandleWorkerMessage, false);
4241
}
4342

44-
private string CreateWorkerUrl()
45-
{
46-
var source = @"self.onmessage = function(e) {
47-
if(e.data.cmd == 'initialize') {
48-
importScripts(e.data.settings.atRoot);
49-
new AlphaTab.Platform.JavaScript.JsWorker(self, e.data.settings);
50-
}
51-
}";
52-
53-
JsCode("window.URL = window.URL || window.webkitURL;");
54-
JsCode("window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder;");
55-
56-
Blob blob;
57-
try
58-
{
59-
blob = new Blob(new[] {source}, new {type = "application/javascript"});
60-
}
61-
catch
62-
{
63-
dynamic builder = JsCode("new BlobBuilder()");
64-
builder.append(source);
65-
blob = builder.getBlob();
66-
}
67-
68-
return JsCode("URL.createObjectURL(blob)").As<string>();
69-
70-
}
71-
7243
public void UpdateSettings(Settings settings)
7344
{
74-
_worker.postMessage(new { cmd = "updateSettings", settings = settings.ToJson() });
45+
_worker.postMessage(new { cmd = "alphaTab.updateSettings", settings = settings.ToJson() });
7546
}
7647

7748
public void Invalidate()
7849
{
79-
_worker.postMessage(new { cmd = "invalidate" });
50+
_worker.postMessage(new { cmd = "alphaTab.invalidate" });
8051
}
8152

8253
public void Resize(int width)
8354
{
84-
_worker.postMessage(new { cmd = "resize", width = width });
55+
_worker.postMessage(new { cmd = "alphaTab.resize", width = width });
8556
}
8657

8758
public void Load(object data, int[] trackIndexes)
8859
{
89-
_worker.postMessage(new { cmd = "load", data = data, indexes = trackIndexes });
60+
_worker.postMessage(new { cmd = "alphaTab.load", data = data, indexes = trackIndexes });
9061
}
9162

9263
private void HandleWorkerMessage(DOMEvent e)
@@ -95,23 +66,23 @@ private void HandleWorkerMessage(DOMEvent e)
9566
var cmd = data.Member("cmd").As<string>();
9667
switch (cmd)
9768
{
98-
case "preRender":
69+
case "alphaTab.preRender":
9970
OnPreRender(data.Member("result").As<RenderFinishedEventArgs>());
10071
break;
101-
case "partialRenderFinished":
72+
case "alphaTab.partialRenderFinished":
10273
OnPartialRenderFinished(data.Member("result").As<RenderFinishedEventArgs>());
10374
break;
104-
case "renderFinished":
75+
case "alphaTab.renderFinished":
10576
OnRenderFinished(data.Member("result").As<RenderFinishedEventArgs>());
10677
break;
107-
case "postRenderFinished":
78+
case "alphaTab.postRenderFinished":
10879
BoundsLookup = BoundsLookup.FromJson(data.Member("boundsLookup"), Score);
10980
OnPostRenderFinished();
11081
break;
111-
case "error":
82+
case "alphaTab.error":
11283
console.error(data.Member("exception"));
11384
break;
114-
case "loaded":
85+
case "alphaTab.loaded":
11586
var score = data.Member("score").As<Score>();
11687
if (score.As<bool>())
11788
{
@@ -126,7 +97,7 @@ private void HandleWorkerMessage(DOMEvent e)
12697

12798
public void RenderMultiple(int[] trackIndexes)
12899
{
129-
_worker.postMessage(new { cmd = "renderMultiple", data = trackIndexes });
100+
_worker.postMessage(new { cmd = "alphaTab.renderMultiple", data = trackIndexes });
130101
}
131102

132103
public event Action<RenderFinishedEventArgs> PreRender;
@@ -166,7 +137,7 @@ protected virtual void OnLoaded(Score score)
166137

167138
public void Tex(string contents)
168139
{
169-
_worker.postMessage(new { cmd = "tex", data = contents });
140+
_worker.postMessage(new { cmd = "alphaTab.tex", data = contents });
170141
}
171142

172143
}

‎Source/AlphaTab.JavaScript/Settings.cs

+77-26
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ public string ScriptFile
3333
get; set;
3434
}
3535

36+
public string FontDirectory
37+
{
38+
get; set;
39+
}
40+
3641
public dynamic ToJson()
3742
{
3843
dynamic json = Std.NewObject();
@@ -44,7 +49,8 @@ public dynamic ToJson()
4449
json.stretchForce = StretchForce;
4550
json.forcePianoFingering = ForcePianoFingering;
4651

47-
json.atRoot = ScriptFile;
52+
json.scriptFile = ScriptFile;
53+
json.fontDirectory = FontDirectory;
4854

4955
json.layout = Std.NewObject();
5056
json.layout.mode = Layout.Mode;
@@ -80,6 +86,7 @@ public static Settings FromJson(dynamic json)
8086

8187
return settings;
8288
}
89+
8390
public static void FillFromJson(Settings settings, dynamic json)
8491
{
8592
if (!json) return;
@@ -90,38 +97,44 @@ public static void FillFromJson(Settings settings, dynamic json)
9097
if (Std.JsonExists(json, "stretchForce")) settings.StretchForce = json.stretchForce;
9198
if (Std.JsonExists(json, "forcePianoFingering")) settings.ForcePianoFingering = json.forcePianoFingering;
9299

93-
if (Std.JsonExists(json, "atRoot"))
100+
if (Std.JsonExists(json, "scriptFile"))
94101
{
95-
settings.ScriptFile = json.atRoot;
96-
// append script name
97-
if (!settings.ScriptFile.EndsWith(".js"))
98-
{
99-
if (!settings.ScriptFile.EndsWith("/"))
100-
{
101-
settings.ScriptFile += "/";
102-
}
103-
settings.ScriptFile += "AlphaTab.js";
104-
}
105-
if (!settings.ScriptFile.StartsWith("http") && !settings.ScriptFile.StartsWith("https"))
106-
{
107-
var root = new StringBuilder();
108-
root.Append(HtmlContext.window.location.protocol);
109-
root.Append("//");
110-
root.Append(HtmlContext.window.location.hostname);
111-
if (HtmlContext.window.location.port.As<bool>())
112-
{
113-
root.Append(":");
114-
root.Append(HtmlContext.window.location.port);
115-
}
116-
root.Append(settings.ScriptFile);
117-
settings.ScriptFile = root.ToString();
118-
}
102+
settings.ScriptFile = EnsureFullUrl(settings.ScriptFile);
103+
settings.ScriptFile = AppendScriptName(json.scriptFile);
104+
}
105+
else if (HtmlContext.self.document.As<bool>() && HtmlContext.self.window.Member("ALPHATAB_ROOT").As<bool>())
106+
{
107+
settings.ScriptFile = HtmlContext.self.window.Member("ALPHATAB_ROOT").As<string>();
108+
settings.ScriptFile = EnsureFullUrl(settings.ScriptFile);
109+
settings.ScriptFile = AppendScriptName(settings.ScriptFile);
119110
}
120111
else
121112
{
122113
settings.ScriptFile = Environment.ScriptFile;
123114
}
124115

116+
if (Std.JsonExists(json, "fontDirectory"))
117+
{
118+
settings.FontDirectory = EnsureFullUrl(json.fontDirectory);
119+
}
120+
else if (HtmlContext.self.document.As<bool>() && HtmlContext.self.window.Member("ALPHATAB_FONT").As<bool>())
121+
{
122+
settings.FontDirectory = HtmlContext.self.window.Member("ALPHATAB_FONT").As<string>();
123+
settings.FontDirectory = EnsureFullUrl(settings.FontDirectory);
124+
}
125+
else
126+
{
127+
settings.FontDirectory = settings.ScriptFile;
128+
if (!string.IsNullOrEmpty(settings.FontDirectory))
129+
{
130+
var lastSlash = settings.FontDirectory.LastIndexOf('/');
131+
if (lastSlash >= 0)
132+
{
133+
settings.FontDirectory = settings.FontDirectory.Substring(0, lastSlash) + "/Font/";
134+
}
135+
}
136+
}
137+
125138
if (Std.JsonExists(json, "layout"))
126139
{
127140
if (JsContext.@typeof(json.layout) == "string")
@@ -167,5 +180,43 @@ public static void FillFromJson(Settings settings, dynamic json)
167180
}
168181
}
169182
}
183+
184+
private static string AppendScriptName(string url)
185+
{
186+
// append script name
187+
if (!string.IsNullOrEmpty(url) && !url.EndsWith(".js"))
188+
{
189+
if (!url.EndsWith("/"))
190+
{
191+
url += "/";
192+
}
193+
url += "AlphaTab.js";
194+
}
195+
return url;
196+
}
197+
198+
private static string EnsureFullUrl(string relativeUrl)
199+
{
200+
if (!relativeUrl.StartsWith("http") && !relativeUrl.StartsWith("https"))
201+
{
202+
var root = new StringBuilder();
203+
root.Append(HtmlContext.window.location.protocol);
204+
root.Append("//");
205+
root.Append(HtmlContext.window.location.hostname);
206+
if (HtmlContext.window.location.port.As<bool>())
207+
{
208+
root.Append(":");
209+
root.Append(HtmlContext.window.location.port);
210+
}
211+
root.Append(relativeUrl);
212+
if (!relativeUrl.EndsWith("/"))
213+
{
214+
root.Append("/");
215+
}
216+
return root.ToString();
217+
}
218+
219+
return relativeUrl;
220+
}
170221
}
171222
}

0 commit comments

Comments
 (0)
Please sign in to comment.