forked from jonnyreeves/jonnyreeves.github.io
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index2.html
990 lines (837 loc) · 114 KB
/
index2.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
<!DOCTYPE html>
<html lang="en">
<head>
<link href='//fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,700,400italic' rel='stylesheet' type='text/css'>
<link rel="stylesheet" type="text/css" href="http://jonnyreeves.co.uk/theme/css/style.min.css">
<link rel="stylesheet" type="text/css" href="http://jonnyreeves.co.uk/theme/css/pygments.min.css">
<link rel="stylesheet" type="text/css" href="http://jonnyreeves.co.uk/theme/css/font-awesome.min.css">
<link href="http://jonnyreeves.co.uk/feeds/all.atom.xml" type="application/atom+xml" rel="alternate" title="Jonny Reeves Atom">
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="robots" content="" />
<meta name="author" content="Jonny Reeves" />
<meta name="description" content="" />
<meta property="og:site_name" content="Jonny Reeves"/>
<meta property="og:type" content="blog"/>
<meta property="og:title" content="Jonny Reeves"/>
<meta property="og:description" content=""/>
<meta property="og:locale" content="en_US"/>
<meta property="og:url" content="http://jonnyreeves.co.uk"/>
<meta property="og:image" content="/images/avatar.jpg">
<title>Jonny Reeves</title>
</head>
<body>
<aside>
<div>
<a href="http://jonnyreeves.co.uk">
<img src="/images/avatar.jpg" alt="Jonny Reeves" title="Jonny Reeves">
</a>
<h1><a href="http://jonnyreeves.co.uk">Jonny Reeves</a></h1>
<p>code && coffee || music</p>
<nav>
<ul class="list">
</ul>
</nav>
<ul class="social">
<li><a class="sc-linkedin" href="https://br.linkedin.com/in/jonnyreeves/en" target="_blank"><i class="fa fa-linkedin"></i></a></li>
<li><a class="sc-google" href="https://plus.google.com/+JohnReeves" target="_blank"><i class="fa fa-google"></i></a></li>
<li><a class="sc-github" href="https://github.com/jonnyreeves" target="_blank"><i class="fa fa-github"></i></a></li>
</ul>
</div>
</aside>
<main>
<article>
<header>
<h2><a href="http://jonnyreeves.co.uk/2014/using-browserify-without-a-node_modules-directory/#using-browserify-without-a-node_modules-directory">Using Browserify without a node_modules directory</a></h2>
<p>
Posted on Sat 19 July 2014 in <a href="http://jonnyreeves.co.uk/category/javascript.html">JavaScript</a> •
</p>
</header>
<div>
<p>NPM and Bower are pretty awesome; they provides both NodeJS and web developers a way to share CommonJS modules (aka packages) amongst code-bases without relying on copy/pasting concatenated .js files. Browserify fills in the missing link for deploying an application to the web; it gathers up disparate CommonJS modules which NPM/Bower resolved and bundles them up into a single .js file ready to be dropped into a <code><script></code> tag.</p>
<p>When writing CommonJS code, you can import files by two methods, either relativley, (typically used internally inside your app / module), ie:</p>
<div class="highlight"><pre>var MakePizzaCommand = require("./commands/MakePizzaCommand");
</pre></div>
<p>Or you can import entire libraries, eg: those which were resolved by Bower / NPM</p>
<div class="highlight"><pre>var reqwest = require("reqwest");
</pre></div>
<p>In the first example, Browserify will locate the <code>MakePizzaCommand</code> object by reading the file relative from the host file making the <code>require</code> call; ie:</p>
<div class="highlight"><pre>├── app.js <-- makes the require call
└── commands
└── MakePizzaCommand.js <-- gets included
</pre></div>
<p>In the second example, Browserify identifies that you are not referencing a local file (as the <code>require</code> argument does not look like a path), so instead it starts looking up the directory tree for a <code>node_modules</code> folder which contains a subfolder for the module the host file making the require call is trying to import.</p>
<div class="highlight"><pre>pizzajs
├── node_modules <-- 3. found it! now look in each subfolder
│ │ for a package.json file with the name of
│ │ the module we are trying to import.
│ └── reqwest
│ └── package.json
│
├── src <-- 2. no `node_modules` dir here either, so look in the
│ │ parent dir (pizzajs)
│ │
│ ├── app.js <-- 1. makes the require call, no `node_modules` dir
│ │ here so look in parent dir (src)
│ └── commands
│ └── MakePizzaCommand.js
└── test
</pre></div>
<p>But what if you don't want to use NPM / Bower to resolve your dependencies? AFAIK you have two options avaiable to you:</p>
<ol>
<li>
<p>Create a <code>node_modules</code> folder in your project and copy all your CommonJS libraries into it during the build process; note that the <code>node_modules</code> folder must sit either adjacent to your project's sources (<code>src</code>) or in a ancestor folder.</p>
</li>
<li>
<p>Make use of the <a href="http://nodejs.org/api/modules.html"><code>NODE_PATH</code> environment variable</a>, this provides another absolute URL for browserify to use when looking for CommonJS modules. This allows you to pull off the following folder structure (which may suit none-javascript-based build systems better):</p>
</li>
</ol>
<div class="highlight"><pre>pizzajs
├── lib
│ └── reqwest
│ └── package.json
└── src
└── app.js
</pre></div>
<p>If you're using Grunt, you can easily set the <code>NODE_PATH</code> environment variable with each build by adding the following to the top of your <code>Gruntfile.js</code>:</p>
<div class="highlight"><pre><span class="c1">// Set NODE_PATH env-var to the cwd.</span>
<span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="cp">[</span><span class="s2">"NODE_PATH"</span><span class="cp">]</span> <span class="o">=</span> <span class="nx">__dirname</span><span class="p">;</span>
<span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">grunt</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">grunt</span><span class="p">.</span><span class="nx">initConfig</span><span class="p">({</span> <span class="p">..</span> <span class="p">});</span>
<span class="p">});</span>
</pre></div>
</div>
<hr />
</article>
<article>
<header>
<h2><a href="http://jonnyreeves.co.uk/2013/making-xhr-request-to-https-domains-with-winjs/#making-xhr-request-to-https-domains-with-winjs">Making XHR Request to HTTPS domains with WinJS</a></h2>
<p>
Posted on Fri 25 January 2013 in <a href="http://jonnyreeves.co.uk/category/winjs.html">WinJS</a> •
</p>
</header>
<div>
<p>I recently came across an interesting caveat when working with WinJS (the JavaScript layer for creating Windows 8 Store applications). If you attempt to make an HTTP POST request to a server over the HTTPS protocol you may run into the following error:</p>
<div class="highlight"><pre><span class="n">XMLHttpRequest</span><span class="o">:</span> <span class="n">Network</span> <span class="n">Error</span> <span class="mh">0x2ef3</span><span class="o">,</span> <span class="n">Could</span> <span class="n">not</span> <span class="n">complete</span> <span class="n">the</span> <span class="n">operation</span> <span class="n">due</span> <span class="n">to</span> <span class="n">error</span> <span class="mi">00002</span><span class="n">ef3</span><span class="o">.</span>
</pre></div>
<p>This error appears to be caused by a security certificate issue; however the solution is pretty straight forward – you just need to make a GET request before attempting subsequent POST request, for example:</p>
<div class="highlight"><pre><span class="c1">// Before making a POST request we first have to issue a GET against the target</span>
<span class="c1">// server to work around Network Error 0x2ef3. Note you only need to do this</span>
<span class="c1">// ONCE in your app, not every time.</span>
<span class="nx">WinJS</span><span class="p">.</span><span class="nx">xhr</span><span class="p">({</span>
<span class="nx">url</span><span class="o">:</span> <span class="s2">"https://my.server/"</span>
<span class="p">}).</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
<span class="c1">// After a single GET request we can now invoke POST requests.</span>
<span class="nx">WinJS</span><span class="p">.</span><span class="nx">xhr</span><span class="p">({</span>
<span class="nx">url</span><span class="o">:</span> <span class="s2">"https://my.server/endpoint"</span><span class="p">,</span>
<span class="nx">type</span><span class="o">:</span> <span class="s2">"POST"</span><span class="p">,</span>
<span class="nx">data</span><span class="o">:</span> <span class="p">{</span>
<span class="nx">foo</span><span class="o">:</span> <span class="s2">"bar"</span>
<span class="p">}</span>
<span class="p">})</span>
<span class="p">}).</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">"HTTPS POST request complete!"</span><span class="p">);</span>
<span class="p">});</span>
</pre></div>
</div>
<hr />
</article>
<article>
<header>
<h2><a href="http://jonnyreeves.co.uk/2012/modular-javascript-unit-testing-with-qunit-and-requirejs/#modular-javascript-unit-testing-with-qunit-and-requirejs">Modular Javascript Unit Testing with QUnit and RequireJS</a></h2>
<p>
Posted on Tue 14 August 2012 in <a href="http://jonnyreeves.co.uk/category/javascript.html">JavaScript</a> •
</p>
</header>
<div>
<p>Modular application development is essential when working on a large project with more than a handful of developers. Breaking your code into separate modules improves code legibility and organization making it easier to locate logic and help create ‘seams’ in your code so you can do your best to adhere to <a href="http://www.codinghorror.com/blog/2007/03/curlys-law-do-one-thing.html">Single Responsibility Principle</a>. This is all well and good for your application code, but what about the Unit Tests which support it – how can we decompose these tests into modules so they’re well organized and easy to find?</p>
<h3>Test Case Structure</h3>
<p>First things first, you need to get your Unit Tests broken up into separate test cases. QUnit provides the QUnit.module method which takes care of this, allowing your to group tests in the QUnit test runner. We can extend this metaphor further by ensuring that each QUnit module resides in its own file, or, in other words – each application module has it’s own QUnit module of tests.</p>
<p>Here’s an example of a simple QUnit Test Case defined as a RequireJS module:</p>
<div class="highlight"><pre><span class="nx">define</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">require</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// Import depdendencies (note you can use relative paths here)</span>
<span class="kd">var</span> <span class="nx">PegiRatings</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s2">"./PegiRatings"</span><span class="p">);</span>
<span class="c1">// Define the QUnit module and lifecycle.</span>
<span class="nx">QUnit</span><span class="p">.</span><span class="nx">module</span><span class="p">(</span><span class="s2">"example/model/PegiRatings"</span><span class="p">);</span>
<span class="nx">QUnit</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="s2">"isSuitibleFor - younger age supplied, returns false"</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
<span class="nx">QUnit</span><span class="p">.</span><span class="nx">equal</span><span class="p">(</span><span class="nx">PegiRatings</span><span class="p">.</span><span class="nx">PEGI_18</span><span class="p">.</span><span class="nx">isSuitibleFor</span><span class="p">(</span><span class="mi">17</span><span class="p">),</span> <span class="kc">false</span><span class="p">);</span>
<span class="p">});</span>
<span class="nx">QUnit</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="s2">"isSuitibleFor - same age supplied, returns true"</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
<span class="nx">QUnit</span><span class="p">.</span><span class="nx">equal</span><span class="p">(</span><span class="nx">PegiRatings</span><span class="p">.</span><span class="nx">PEGI_18</span><span class="p">.</span><span class="nx">isSuitibleFor</span><span class="p">(</span><span class="mi">18</span><span class="p">),</span> <span class="kc">true</span><span class="p">);</span>
<span class="p">});</span>
<span class="nx">QUnit</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="s2">"isSuitibleFor - older age supplied, returns true"</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
<span class="nx">QUnit</span><span class="p">.</span><span class="nx">equal</span><span class="p">(</span><span class="nx">PegiRatings</span><span class="p">.</span><span class="nx">PEGI_18</span><span class="p">.</span><span class="nx">isSuitibleFor</span><span class="p">(</span><span class="mi">19</span><span class="p">),</span> <span class="kc">true</span><span class="p">);</span>
<span class="p">});</span>
<span class="p">});</span>
</pre></div>
<p>As you can see above, we are able to use <code>require</code> to import other modules from the src folder into the test case (in the above example we are including the PegiRatings object, which just happens to be the module under test). Here’s another example where we pull in not only other modules from the source tree, but also a vendor library (the ever popular, underscore.js):</p>
<div class="highlight"><pre><span class="nx">define</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">require</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// Import depdendencies.</span>
<span class="kd">var</span> <span class="nx">_</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s2">"vendor/underscore"</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">Player</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s2">"./Player"</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">Game</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s2">"./Game"</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">PegiRatings</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s2">"./PegiRatings"</span><span class="p">);</span>
<span class="c1">// ... rest of test case omitted for brevity</span>
<span class="p">});</span>
</pre></div>
<h3>Configuring QUnit and RequireJS</h3>
<p>Now that we have our unit tests split out into separate modules, we need to configure the QUnit Test Runner so that it will work with RequireJS to resolve the dependencies. The first step is to modify the stock QUnit Test Runner HTML document so RequireJS is loaded along with all our testcases.</p>
<div class="highlight"><pre><span class="cp"><!DOCTYPE html></span>
<span class="nt"><html></span>
<span class="nt"><head></span>
<span class="nt"><title></span>Example Test Runner<span class="nt"></title></span>
<span class="nt"><link</span> <span class="na">rel=</span><span class="s">"stylesheet"</span> <span class="na">href=</span><span class="s">"vendor/qunit.css"</span> <span class="nt">/></span>
<span class="c"><!-- QUnit includes --></span>
<span class="nt"><script </span><span class="na">src=</span><span class="s">"vendor/qunit.js"</span><span class="nt">></script></span>
<span class="c"><!-- Load RequireJS & the testsuite --></span>
<span class="nt"><script </span><span class="na">src=</span><span class="s">"../src/require-config.js"</span><span class="nt">></script></span>
<span class="nt"><script </span><span class="na">src=</span><span class="s">"../src/vendor/require.js"</span> <span class="na">data-main=</span><span class="s">"testsuite.js"</span><span class="nt">></script></span>
<span class="nt"></head></span>
<span class="nt"><body></span>
<span class="nt"><div</span> <span class="na">id=</span><span class="s">"qunit"</span><span class="nt">></div></span>
<span class="nt"></body></span>
<span class="nt"></html></span>
</pre></div>
<p>In a typical QUnit Test Runner setup you would include your <code>tests.js</code> file which included all your QUnit tests. Instead we load the project’s <a href="http://requirejs.org/docs/api.html#config">RequireJS configuration file</a> (which is also used by the main project, to avoid duplication of configuration settings between the tests and the build) and then RequireJS itself with a callback to the <code>testsuite.js</code> file.</p>
<div class="highlight"><pre><span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
<span class="c1">// Defer Qunit so RequireJS can work its magic and resolve all modules.</span>
<span class="nx">QUnit</span><span class="p">.</span><span class="nx">config</span><span class="p">.</span><span class="nx">autostart</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
<span class="c1">// Configure RequireJS so it resolves relative module paths from the `src`</span>
<span class="c1">// folder.</span>
<span class="nx">require</span><span class="p">.</span><span class="nx">config</span><span class="p">({</span>
<span class="nx">baseUrl</span><span class="o">:</span> <span class="s2">"../src"</span><span class="p">,</span>
<span class="p">});</span>
<span class="c1">// A list of all QUnit test Modules. Make sure you include the `.js` </span>
<span class="c1">// extension so RequireJS resolves them as relative paths rather than using</span>
<span class="c1">// the `baseUrl` value supplied above.</span>
<span class="kd">var</span> <span class="nx">testModules</span> <span class="o">=</span> <span class="p">[</span>
<span class="s2">"example/model/PlayerTests.js"</span><span class="p">,</span>
<span class="s2">"example/model/PegiRatingsTests.js"</span>
<span class="p">];</span>
<span class="c1">// Resolve all testModules and then start the Test Runner.</span>
<span class="nx">require</span><span class="p">(</span><span class="nx">testModules</span><span class="p">,</span> <span class="nx">QUnit</span><span class="p">.</span><span class="nx">start</span><span class="p">);</span>
<span class="p">}());</span>
</pre></div>
<p>This file configures RequireJS ready for our Unit Test run and also provides a list of all test cases that we wish to execute. Once RequireJS has finished loading all the test cases, it makes a call to <code>QUnit.start</code> which kicks off the Test Runner.</p>
<h3>Example Project Download</h3>
<p>I’ve pushed all the source for this example project to the <a href="https://github.com/jonnyreeves/qunit-require/">qunit-require GitHub Repo</a>. You can <a href="https://github.com/jonnyreeves/qunit-require/zipball/master">download the zipball</a> and run the tests to gain a better understanding of the project structure.</p>
</div>
<hr />
</article>
<article>
<header>
<h2><a href="http://jonnyreeves.co.uk/2012/listening-for-jquery-mobile-slider-events/#listening-for-jquery-mobile-slider-events">Listening for jQuery Mobile Slider Events</a></h2>
<p>
Posted on Tue 24 July 2012 in <a href="http://jonnyreeves.co.uk/category/javascript.html">JavaScript</a> •
</p>
</header>
<div>
<p>jQuery Mobile provides a neat little slider control; however, the version 1.1 release doesn’t behave very well and fails to dispatch the expected start and stop events triggered by jQuery UI’s slider control. <a href="https://github.com/jquery/jquery-mobile/issues/1589">This issue (#1589)</a> has been raised on jQuery Mobile’s GitHub Issue Tracker but it looks like it won’t be addressed until jQuery Mobile 1.2</p>
<p>The code below is a patch which you can drop into your application’s startup routine; it adds a couple of event listeners to the DOM which will trigger the start and stop events based on the user’s interaction with the slider’s thumb and track.</p>
<div class="highlight"><pre><span class="nx">$</span><span class="p">(</span><span class="nb">document</span><span class="p">).</span><span class="nx">on</span><span class="p">({</span>
<span class="s2">"mousedown touchstart"</span><span class="o">:</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
<span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">siblings</span><span class="p">(</span><span class="s2">"input"</span><span class="p">).</span><span class="nx">trigger</span><span class="p">(</span><span class="s2">"start"</span><span class="p">);</span>
<span class="p">},</span>
<span class="s2">"mouseup touchend"</span><span class="o">:</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
<span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">siblings</span><span class="p">(</span><span class="s2">"input"</span><span class="p">).</span><span class="nx">trigger</span><span class="p">(</span><span class="s2">"stop"</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">},</span> <span class="s2">".ui-slider"</span><span class="p">);</span>
</pre></div>
<p>In a nutshell, it binds an event listener to the document object which listens for both <code>mousedown</code> and <code>touchstart</code> events triggered from <code>.ui-slider</code> elements. Once triggered the handler function will find the input element which sits alongside the <code>.ui-slider</code> control that was interacted with and trigger the corresponding event. You can consume these events like so:</p>
<div class="highlight"><pre><span class="nx">$</span><span class="p">(</span><span class="s2">"#my-slider"</span><span class="p">).</span><span class="nx">on</span><span class="p">(</span><span class="s2">"start"</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">"User has started sliding my-slider!"</span><span class="p">);</span>
<span class="p">});</span>
<span class="nx">$</span><span class="p">(</span><span class="s2">"#my-slider"</span><span class="p">).</span><span class="nx">on</span><span class="p">(</span><span class="s2">"stop"</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">value</span> <span class="o">=</span> <span class="nx">event</span><span class="p">.</span><span class="nx">target</span><span class="p">.</span><span class="nx">value</span><span class="p">;</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">"User has finished sliding my slider, final value: "</span> <span class="o">+</span> <span class="nx">value</span><span class="p">);</span>
<span class="p">});</span>
</pre></div>
<p>As always, you can also subscribe to the slider’s change event if you want to listen for the actual slide.</p>
<div class="highlight"><pre><span class="nx">$</span><span class="p">(</span><span class="s2">"#my-slider"</span><span class="p">).</span><span class="nx">on</span><span class="p">(</span><span class="s2">"change"</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">value</span> <span class="o">=</span> <span class="nx">event</span><span class="p">.</span><span class="nx">target</span><span class="p">.</span><span class="nx">value</span><span class="p">;</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">"Slider is moving, it's value is now: "</span> <span class="o">+</span> <span class="nx">value</span><span class="p">);</span>
<span class="p">});</span>
</pre></div>
</div>
<hr />
</article>
<article>
<header>
<h2><a href="http://jonnyreeves.co.uk/2012/streaming-video-from-azure-blob-storage/#streaming-video-from-azure-blob-storage">Streaming Video from Azure Blob Storage</a></h2>
<p>
Posted on Fri 20 July 2012 in <a href="http://jonnyreeves.co.uk/category/azure.html">Azure</a> •
</p>
</header>
<div>
<p>By default Azure Blob Storage and Video do not mix well; the first hurdle that developers must get over is that the Content Type for the video must be set correctly (for .mp4 videos that’s usually <code>video/mp4</code>).</p>
<p>The next problem that you’ll face is that the video will not seek correctly; trying to jump forward or backwards in the video won’t work.</p>
<p>This is resolved by changing the <code>DefaultServiceVersion</code> to 2011-08-18 which can be achieved via the Azure’s REST API, or the Managed C# Library as laid out at the end of <a href="http://blogs.msdn.com/b/windowsazurestorage/archive/2011/09/15/windows-azure-blobs-improved-http-headers-for-resume-on-download-and-a-change-in-if-match-conditions.aspx">this MSDN blog post</a>.</p>
<div class="highlight"><pre>var account = CloudStorageAccount.Parse(ConnectionString);
var blobClient = account.CreateCloudBlobClient();
blobClient.SetServiceSettings(new ServiceSettings()
{
DefaultServiceVersion = "2011-08-18"
});
</pre></div>
</div>
<hr />
</article>
<article>
<header>
<h2><a href="http://jonnyreeves.co.uk/2012/stubbing-javascript-promises-with-sinonjs/#stubbing-javascript-promises-with-sinonjs">Stubbing JavaScript Promises with SinonJS</a></h2>
<p>
Posted on Sat 02 June 2012 in <a href="http://jonnyreeves.co.uk/category/javascript.html">JavaScript</a> •
</p>
</header>
<div>
<p>Asynchronous code lies at the heart of front end development; in order to make your application feel responsive you can’t afford to block execution until some external data has been read. <a href="http://wiki.commonjs.org/wiki/Promises/A">Promises</a> are a well understood design pattern to help encapsulate the state of an asynchronous action. A Promise will only ever transfer from a pending state (ie: when the initial request has been made to the server) to a resolved state. The resolved state can be one of either a failure state (ie: the server sends back a 500 error) or a success state (ie: the JSON data you were expecting has come back). Once a promise has transferred to a resolved state it will not change (it becomes immutable). By employing this pattern you can write some very succinct code which is both easy to read and maintain:</p>
<div class="highlight"><pre><span class="nx">service</span><span class="p">.</span><span class="nx">fetch</span><span class="p">(</span><span class="s2">"someData"</span><span class="p">)</span>
<span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">response</span><span class="p">)</span> <span class="p">{</span> <span class="cm">/* process response */</span> <span class="p">});</span>
<span class="p">.</span><span class="nx">otherwise</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span> <span class="cm">/* handle the error */</span> <span class="p">});</span>
</pre></div>
<p>The code above makes use of Brain Cavalier’s <a href="https://github.com/cujojs/when">when.js</a> Promises implementation. The rest of this post aims to highlight how you can combine when.js with a mocking framework to make unit testing Promises a piece of cake. If you would still like to learn more about using Promises, and how they make writing asynchronous code easier, then I’d suggest reading <a href="http://blog.briancavalier.com/async-programming-part-1-its-messy">his excellent articles on the subject</a>.</p>
<h3>Why mock Promises?</h3>
<p>One of the golden rules of unit testing is that the <a href="http://martinfowler.com/articles/nonDeterminism.html">code under test must be deterministic</a>. Another golden rule is that <a href="http://pragprog.com/magazines/2012-01/unit-tests-are-first">unit tests must be fast to execute</a>. Although Promises make writing asynchronous code easier, they don’t help with the two points above, take the following example:</p>
<div class="highlight"><pre><span class="c1">// Example of a module that abstracts a RESTful web service.</span>
<span class="kd">var</span> <span class="nx">service</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">fetch</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">query</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// Returns a when.js Promise which will resolve when the data</span>
<span class="c1">// has been fetched.</span>
<span class="k">return</span> <span class="nx">when</span><span class="p">(</span><span class="nx">jQuery</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">"http://myservice.com/api?q="</span> <span class="o">+</span> <span class="nx">query</span><span class="p">));</span>
<span class="p">}</span>
<span class="p">};</span>
<span class="c1">// A client object which consumes the Service, this is what we are going to be </span>
<span class="c1">// unit testing.</span>
<span class="kd">var</span> <span class="nx">client</span> <span class="o">=</span> <span class="p">{</span>
<span class="c1">// Returns a promise which will yield the number of pages returned</span>
<span class="c1">// the supplied query.</span>
<span class="nx">getNumPages</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">query</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// Create a fresh service instance.</span>
<span class="kd">var</span> <span class="nx">service</span> <span class="o">=</span> <span class="nx">createService</span><span class="p">();</span>
<span class="c1">// Return a promise which will resolve after the following</span>
<span class="c1">// `then` block has performed.</span>
<span class="k">return</span> <span class="nx">service</span><span class="p">.</span><span class="nx">fetch</span><span class="p">(</span><span class="nx">query</span><span class="p">)</span>
<span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">response</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// Modifies the result of the Service's Promise,</span>
<span class="c1">// future success handlers will reicieve the</span>
<span class="c1">// number of pages instead of the response data.</span>
<span class="k">return</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">response</span><span class="p">).</span><span class="nx">pages</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
<p>Unit testing the above client is pretty easy; a simple test-case could look like this (This example will be based on QUnit):</p>
<div class="highlight"><pre><span class="nx">asyncTest</span><span class="p">(</span><span class="s2">"getNumPages fetches expected number of pages"</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
<span class="c1">// A special query which we know will return the expected number of pages.</span>
<span class="nx">client</span><span class="p">.</span><span class="nx">getNumPages</span><span class="p">(</span><span class="s2">"testcase-query"</span><span class="p">)</span>
<span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">numPages</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">equal</span><span class="p">(</span><span class="nx">numPages</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="s2">"5 pages returned"</span><span class="p">);</span>
<span class="nx">start</span><span class="p">();</span>
<span class="p">});</span>
<span class="p">});</span>
</pre></div>
<p>Although the above test case is easy to read, it doesn’t make for a very good unit test for the following reasons:</p>
<ul>
<li>It’s non-deterministic – if the server over at myservice.com is down, or you try and execute these unit tests offline then the test will fail (infact, it will hang the test-runner as it waits for this asyncTest to complete.)</li>
<li>It’s not going to be fast – a connection needs to be established to the server.</li>
<li>It only tests the success state – we need to test what happens if the service is down, but there’s no obvious way to do that (other than to request an invalid query value from the API.</li>
</ul>
<p>This is where a mocking framework comes in – it will help us solve all three of the problems listed above.</p>
<h3>Promises, Lies and stubbing the truth</h3>
<p>A mocking framework allows you to alter the way functions behave during a unit test. Mocking frameworks are especially powerful in dynamic languages, like JavaScript, as they are able to make large changes to your codebase for a given unit test and then restore all those changes immediately after the test completes. This tutorial is going to be looking at <a href="http://sinonjs.org/">SinonJS</a></p>
<p>As mentioned above, Sinon.js is able to completely rewrite a function during a test-case, let’s revisit our service module above:</p>
<div class="highlight"><pre><span class="nx">test</span><span class="p">(</span><span class="s2">"Sinon.js stubbing example"</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
<span class="c1">// Use sinon.js to redefine the `service.fetch` function.</span>
<span class="nx">sinon</span><span class="p">.</span><span class="nx">stub</span><span class="p">(</span><span class="nx">service</span><span class="p">,</span> <span class="s1">'fetch'</span><span class="p">).</span><span class="nx">returns</span><span class="p">(</span><span class="s2">"Hello!"</span><span class="p">);</span>
<span class="c1">// Now when we call it, instead of invoking `jQuery.get`, it returns a String.</span>
<span class="nx">equal</span><span class="p">(</span><span class="nx">service</span><span class="p">.</span><span class="nx">fetch</span><span class="p">(</span><span class="s2">"testcase-data"</span><span class="p">),</span> <span class="s2">"Hello!"</span><span class="p">);</span>
<span class="p">});</span>
</pre></div>
<p>The above example isn’t very useful; however, instead of returning a String, we can just as easily return a Promise instance, and that’s when things start getting useful:</p>
<div class="highlight"><pre><span class="nx">test</span><span class="p">(</span><span class="s2">"Stubbing the service so it returns an expected response"</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
<span class="c1">// Stub the service so it returns a resolved promise. Note that `when(value)`</span>
<span class="c1">// is a neat short-cut for creating a Deferred and resolving it.</span>
<span class="kd">var</span> <span class="nx">expectedResponse</span> <span class="o">=</span> <span class="s1">'{ "pages": [ "page1", "page2", "page3" ]}'</span><span class="p">;</span>
<span class="nx">sinon</span><span class="p">.</span><span class="nx">stub</span><span class="p">(</span><span class="nx">service</span><span class="p">,</span> <span class="s1">'fetch'</span><span class="p">).</span><span class="nx">returns</span><span class="p">(</span><span class="nx">when</span><span class="p">(</span><span class="nx">expectedResponse</span><span class="p">));</span>
<span class="c1">// Call the client...</span>
<span class="nx">client</span><span class="p">.</span><span class="nx">getNumPages</span><span class="p">(</span><span class="s1">'testcase-query'</span><span class="p">)</span>
<span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">numPages</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">strictEqual</span><span class="p">(</span><span class="nx">numPages</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="s2">"3 pages returned"</span><span class="p">);</span>
<span class="p">});</span>
<span class="p">});</span>
</pre></div>
<p>Note that the above test-case didn’t need to make user of QUnits <code>asyncTest</code> block – that’s because the expectedPromise Promise object has already been resolved – no need to wait for anything to complete asynchronously. Our test is no longer reliant on the server (hence deterministic) and it no longer relies on a service call (and will therefore execute almost instantly). That leaves only one last point from our rules above – how to test the failure path…</p>
<div class="highlight"><pre><span class="nx">test</span><span class="p">(</span><span class="s2">"Simulating a service failure"</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
<span class="c1">// Again, start by stubbing our service's fetch method. This time we will</span>
<span class="c1">// return a rejected Promise with an error.</span>
<span class="kd">var</span> <span class="nx">expectedError</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="s2">"Bad Query"</span><span class="p">);</span>
<span class="nx">sinon</span><span class="p">.</span><span class="nx">stub</span><span class="p">(</span><span class="nx">service</span><span class="p">,</span> <span class="s1">'fetch'</span><span class="p">).</span><span class="nx">returns</span><span class="p">(</span><span class="nx">when</span><span class="p">.</span><span class="nx">reject</span><span class="p">(</span><span class="nx">expectedError</span><span class="p">));</span>
<span class="c1">// Call the client and expect it to fail</span>
<span class="nx">client</span><span class="p">.</span><span class="nx">getNumPages</span><span class="p">(</span><span class="s1">'testcase-query'</span><span class="p">)</span>
<span class="p">.</span><span class="nx">otherwise</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">strictEqual</span><span class="p">(</span><span class="nx">error</span><span class="p">,</span> <span class="nx">expectedError</span><span class="p">,</span> <span class="s2">"Error from API provided to handler"</span><span class="p">);</span>
<span class="p">});</span>
<span class="p">});</span>
</pre></div>
<p>Hopefully this post has been useful in highlight just a couple of the ways in which Promises and a mocking framework can be combined to remove both non-determinism, and slow execution speed from your tests as well as making it easy to test all paths of your code, even if they depend on external data. I’ve created <a href="https://gist.github.com/2858452">a gist which shows a few other techniques</a> which can be employed for unit testing Promises including the use of Sinon’s yieldTo method which makes it easy to resolve, or reject a Promise resolver supplied as an argument.</p>
</div>
<hr />
</article>
<article>
<header>
<h2><a href="http://jonnyreeves.co.uk/2012/jquery-a-single-click-handler-for-multiple-buttons/#jquery-a-single-click-handler-for-multiple-buttons">jQuery - A single click handler for multiple buttons</a></h2>
<p>
Posted on Wed 23 May 2012 in <a href="http://jonnyreeves.co.uk/category/javascript.html">JavaScript</a> •
</p>
</header>
<div>
<p>Event bubbling is a wonderful thing; in ActionScript mouse events would readily <a href="http://www.rubenswieringa.com/blog/eventbubbles-eventcancelable-and-eventcurrenttarget">bubble up through the DisplayList</a> all the way up to the Stage allowing you to add a single event Handler to a parent DisplayObject and then inspecting the <code>event.target</code> property to determine which child button the user had interacted with. The same is true in JavaScript; but instead of events bubbling up the DisplayList they bubble up through the DOM.</p>
<p>Take the following example, here we have three buttons that we want to respond to when they’re clicked:</p>
<p><img alt="Alt Text" src="http://jonnyreeves.co.uk/images/jquery-a-single-click-handler-for-multiple-buttons/three-buttons.png" /></p>
<p>The HTML for this button group is nice and simple, making use of jQuery mobile:</p>
<div class="highlight"><pre><span class="nt"><div</span> <span class="na">id=</span><span class="s">"screen-selector"</span> <span class="na">data-role=</span><span class="s">"navbar"</span><span class="nt">></span>
<span class="nt"><ul></span>
<span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">class=</span><span class="s">"ui-btn-active"</span><span class="nt">></span>Applications<span class="nt"></a></li></span>
<span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Properties<span class="nt"></a></li></span>
<span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>Events<span class="nt"></a></li></span>
<span class="nt"></ul></span>
<span class="nt"></div></span>
</pre></div>
<p>We can easily bind a click event handler to the <code>#screen-selector</code> element which will capture the click events as they bubble up the DOM.</p>
<div class="highlight"><pre><span class="nx">$</span><span class="p">(</span><span class="s1">'#screen-selector'</span><span class="p">).</span><span class="nx">on</span><span class="p">(</span><span class="s1">'click'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">"You clicked on: "</span><span class="p">,</span> <span class="nx">event</span><span class="p">.</span><span class="nx">target</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
<p>This almost works as desired, but not quite. jQuery Mobile does some magic behind the scenes to transform our button markup into a more complex design, this results in the <code>event.target</code> of the click event being child elements of the <code><a></code> tag:</p>
<p><img alt="Alt Text" src="http://jonnyreeves.co.uk/images/jquery-a-single-click-handler-for-multiple-buttons/button-event-target.png" /></p>
<p>Instead, what we really want is to know which <a> element the user clicked so we can tie it back to the buttons in our original HTML. In ActionScript this could be solved quite easily by setting the <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/DisplayObjectContainer.html#mouseChildren"><code>mouseChildren</code> attribute</a> of the button DisplayObjects to false, ie:</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="n">buttons</span> <span class="p">:</span> <span class="kt">Array</span> <span class="o">=</span> <span class="o">[</span> <span class="n">getChildByName</span><span class="o">(</span><span class="s2">"btnApplications"</span><span class="o">),</span> <span class="n">getChildByName</span><span class="o">(</span><span class="s2">"btnProperties"</span><span class="o">),</span> <span class="n">getChildByName</span><span class="o">(</span><span class="s2">"btnEvents"</span><span class="o">)</span> <span class="o">];</span>
<span class="k">for</span> <span class="k">each</span> <span class="o">(</span><span class="kd">var</span> <span class="n">button</span> <span class="p">:</span> <span class="kt">Sprite</span> <span class="k">in</span> <span class="n">buttons</span><span class="o">)</span> <span class="o">{</span>
<span class="c1">// Disable mouse interaction with any children nested within the button's DisplayObject.</span>
<span class="n">button</span><span class="o">.</span><span class="na">mouseChildren</span> <span class="o">=</span> <span class="kc">false</span><span class="o">;</span>
<span class="o">}</span>
</pre></div>
<p>JavaScript lacks the ability to toggle the mouse interactivity of nested elements, but luckily jQuery comes to the rescue with the <a href="http://api.jquery.com/closest/">closest traversal method</a>. This method will walk up the DOM tree until if finds the first element that matches the supplied selector. In our case we just want to walk up from the click event’s target element until we find an <code><a></code> tag:</p>
<div class="highlight"><pre><span class="nx">$</span><span class="p">(</span><span class="s1">'#screen-selector'</span><span class="p">).</span><span class="nx">on</span><span class="p">(</span><span class="s1">'click'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">button</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">target</span><span class="p">).</span><span class="nx">closest</span><span class="p">(</span><span class="s1">'a'</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">"You clicked on:"</span><span class="p">,</span> <span class="nx">button</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
<p>This now logs the desired <code><a></code> tag for the clicked button!</p>
<p>This code can be improved one step further by <a href="http://api.jquery.com/on/#example-7">passing a selector argument</a> to jQuery’s <code>on</code> method. jQuery will ensure that the event handler function is only called if the selector matches the event’s current target; in our case – we only want it to trigger when it hits an <code><a></code> tag, so we can write:</p>
<div class="highlight"><pre><span class="nx">$</span><span class="p">(</span><span class="s1">'#screen-selector'</span><span class="p">).</span><span class="nx">on</span><span class="p">(</span><span class="s1">'click'</span><span class="p">,</span> <span class="s1">'a'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">button</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">target</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">"You clicked on:"</span><span class="p">,</span> <span class="nx">button</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
<p>The last piece of the puzzle comes from creating a mapping between the button the user clicked on and the action we want to take. Again, Flash provided a really easy way to do this in the form of the DisplayObject.name property which your button handler could read.</p>
<div class="highlight"><pre><span class="kd">function</span> <span class="nx">onButtonClicked</span><span class="p">(</span><span class="nx">event</span> <span class="o">:</span> <span class="nx">MouseEvent</span><span class="p">)</span> <span class="o">:</span> <span class="k">void</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">button</span> <span class="o">:</span> <span class="nx">DisplayObject</span> <span class="o">=</span> <span class="nx">event</span><span class="p">.</span><span class="nx">target</span> <span class="nx">as</span> <span class="nx">DisplayObject</span><span class="p">;</span>
<span class="nx">trace</span><span class="p">(</span><span class="s2">"You clicked on:"</span><span class="p">,</span> <span class="nx">button</span><span class="p">.</span><span class="nx">name</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
<p>The buttons created by jQuery mobile don't offer any form of name identifier; one simple solution would be to simply add an id attribute to the <code><a></code> tag; however <a href="http://www.w3.org/TR/html401/struct/global.html#h-7.5.2">element id's must always be unique</a> which isn't really want we are after (we just want to identify this button group apart, rather than having to ensure these buttons have a unique id across the entire DOM). The option I've settled on is to add a <a href="http://ejohn.org/blog/html-5-data-attributes/">custom data attribute</a> to each <code><a></code> tag in the form of a data-name attribute:</p>
<div class="highlight"><pre><span class="nt"><div</span> <span class="na">id=</span><span class="s">"screen-selector"</span> <span class="na">data-role=</span><span class="s">"navbar"</span><span class="nt">></span>
<span class="nt"><ul></span>
<span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">class=</span><span class="s">"ui-btn-active"</span> <span class="na">data-name=</span><span class="s">"applications"</span><span class="nt">></span>Applications<span class="nt"></a></li></span>
<span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">data-name=</span><span class="s">"properties"</span><span class="nt">></span>Properties<span class="nt"></a></li></span>
<span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">data-name=</span><span class="s">"events"</span><span class="nt">></span>Events<span class="nt"></a></li></span>
<span class="nt"></ul></span>
<span class="nt"></div></span>
</pre></div>
<p>We can now modify our click event handler to read the data-name attribute from the clicked <code><a></code> element:</p>
<div class="highlight"><pre><span class="nx">$</span><span class="p">(</span><span class="s1">'#screen-selector'</span><span class="p">).</span><span class="nx">on</span><span class="p">(</span><span class="s1">'click'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// Retrieve the 'name' data attribute of the <a/> tag that the user clicked.</span>
<span class="kd">var</span> <span class="nx">name</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">target</span><span class="p">).</span><span class="nx">closest</span><span class="p">(</span><span class="s1">'a'</span><span class="p">).</span><span class="nx">data</span><span class="p">(</span><span class="s1">'name'</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">"You clicked on:"</span><span class="p">,</span> <span class="nx">name</span><span class="p">);</span>
<span class="p">});</span>
</pre></div>
<p>Which gives us our desired effect! :)</p>
<p><img alt="Alt Text" src="http://jonnyreeves.co.uk/images/jquery-a-single-click-handler-for-multiple-buttons/button-click-handler.png" /></p>
</div>
<hr />
</article>
<article>
<header>
<h2><a href="http://jonnyreeves.co.uk/2012/using-external-templates-with-mustachejs-and-jquery/#using-external-templates-with-mustachejs-and-jquery">Using External Templates with Mustache.js and jQuery</a></h2>
<p>
Posted on Sun 12 February 2012 in <a href="http://jonnyreeves.co.uk/category/javascript.html">JavaScript</a> •
</p>
</header>
<div>
<p><a href="http://mustache.github.com/">Mustache</a> is a language independent, logicless <a href="http://en.wikipedia.org/wiki/Template_engine_(web)">templating engine</a> which, in the context of a JavaScript / HTML5 style web application, means you can use it to separate your logic (javascript code) from your view (HTML Markup). Mustache comes in a variety of flavours; this article will be focusing on the <a href="https://github.com/janl/mustache.js">JavaScript implementation</a>.</p>
<h3>Why Bother With Templating At All?</h3>
<p>Fair question; when it comes simple JavaScript powered sites it’s pretty easy to just build up your HTML inline:</p>
<div class="highlight"><pre><span class="nx">$</span><span class="p">(</span><span class="s1">'body'</span><span class="p">).</span><span class="nx">append</span><span class="p">(</span><span class="s1">'<p>Hello John, it is 11:19.</p>'</span><span class="p">);</span>
</pre></div>
<p>However, it starts getting a bit messy when we start replacing hard-coded values with variables, for example:</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">date</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">();</span>
<span class="kd">var</span> <span class="nx">name</span> <span class="o">=</span> <span class="s1">'Jonny'</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">timeNow</span> <span class="o">=</span> <span class="nx">date</span><span class="p">.</span><span class="nx">getHours</span><span class="p">()</span> <span class="o">+</span> <span class="s1">':'</span> <span class="o">+</span> <span class="nx">date</span><span class="p">.</span><span class="nx">getMinutes</span><span class="p">();</span>
</pre></div>
<div class="highlight"><pre><span class="nx">$</span><span class="p">(</span><span class="s1">'body'</span><span class="p">).</span><span class="nx">append</span><span class="p">(</span><span class="s1">'<p>Hello '</span> <span class="o">+</span> <span class="nx">name</span> <span class="o">+</span> <span class="s1">', it is '</span> <span class="o">+</span> <span class="nx">timeNow</span> <span class="o">+</span> <span class="s1">'.</p>'</span><span class="p">);</span>
</pre></div>
<p>Things get even more ugly when we want to start build up complex, nested HTML elements, for example:</p>
<div class="highlight"><pre><span class="nx">$</span><span class="p">(</span><span class="s1">'body'</span><span class="p">).</span><span class="nx">append</span><span class="p">(</span><span class="s1">'<dl><dt>Name</dt><dd>'</span> <span class="o">+</span> <span class="nx">name</span> <span class="o">+</span> <span class="s1">'</dd><dt>Time</dt><dd>'</span> <span class="o">+</span> <span class="nx">timeNow</span> <span class="o">+</span> <span class="s1">'</dd></dl>'</span><span class="p">);</span>
</pre></div>
<p>As JavaScript doesn’t support <a href="http://en.wikipedia.org/wiki/Here_document">heredoc</a>, the only way to sort out this nasty one-liner is to escape the new line literal by using a backslash; however I’m not convinced that this really helps with readability.</p>
<div class="highlight"><pre><span class="nx">$</span><span class="p">(</span><span class="s1">'body'</span><span class="p">).</span><span class="nx">append</span><span class="p">(</span><span class="s1">'<dl>\</span>
<span class="s1"> <dt>Name</dt>\</span>
<span class="s1"> <dd>'</span> <span class="o">+</span> <span class="nx">name</span> <span class="o">+</span> <span class="s1">'</dd>\</span>
<span class="s1"> <dt>Time</dt>\</span>
<span class="s1"> <dd>'</span> <span class="o">+</span> <span class="nx">timeNow</span> <span class="o">+</span> <span class="s1">'</dd>\</span>
<span class="s1"></dl>'</span><span class="p">);</span>
</pre></div>
<h2>Enter the Templating Engine</h2>
<p>Templating engines help us solve half the problem by allowing us to move the logic out of the HTML string. The basic premise is fairly simple; instead of having to break out of the String, we can just drop in tokens which the templating engine will replace for us. So instead of having to concatenate lots of Strings together we can simply express our template like this:</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">date</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">();</span>
<span class="c1">// Contains all the values that we want to use in place of the tokens in</span>
<span class="c1">// the template</span>
<span class="kd">var</span> <span class="nx">templateData</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">name</span><span class="o">:</span> <span class="s2">"Jonny"</span><span class="p">,</span>
<span class="nx">timeNow</span><span class="o">:</span> <span class="nx">date</span><span class="p">.</span><span class="nx">getHours</span><span class="p">()</span> <span class="o">+</span> <span class="s1">':'</span> <span class="o">+</span> <span class="nx">date</span><span class="p">.</span><span class="nx">getMinutes</span><span class="p">()</span>
<span class="p">};</span>
<span class="c1">// Define our HTML template, note the tokens match up to the properties</span>
<span class="c1">// of the templateData object.</span>
<span class="kd">var</span> <span class="nx">template</span> <span class="o">=</span> <span class="s1">'<p>Hello {{name}}, it is {{timeNow}}.</p>'</span><span class="p">;</span>
<span class="c1">// Use Mustache.js to render the template (replace the tokens with the values</span>
<span class="c1">// in the templateData object).</span>
<span class="kd">var</span> <span class="nx">renderedTemplate</span> <span class="o">=</span> <span class="nx">Mustache</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span><span class="nx">template</span><span class="p">,</span> <span class="nx">templateData</span><span class="p">);</span>
<span class="c1">// And attach the rendered template HTML to the DOM.</span>
<span class="nx">$</span><span class="p">(</span><span class="s1">'body'</span><span class="p">).</span><span class="nx">append</span><span class="p">(</span><span class="nx">renderedTemplate</span><span class="p">);</span>
</pre></div>
<p>Nice, now we have a clear separation between our template HTML and our data Object which supplies the values; however, we are still stuck when it comes to rendering more complex templates…</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">template</span> <span class="o">=</span> <span class="s1">'<dl>\</span>
<span class="s1"> <dt>Name</dt>\</span>
<span class="s1"> <dd>{{name}}</dd>\</span>
<span class="s1"> <dt>Time</dt>\</span>
<span class="s1"> <dd>{{timeNow}}</dd>\</span>
<span class="s1"></dl>'</span><span class="p">;</span>
</pre></div>
<h3>Would you declare your JavaScript in HTML?</h3>
<p>So we have managed to simplify our code by replacing String concatenation with token substiution (templating); but we are still having to declare our template’s HTML in JavaScript which is far from ideal. What we really want is to be able to write our template in raw HTML as opposed to a String literal – time for some external templates. John Resig is widely regarded as having coined the concept of <a href="https://web.archive.org/web/20120406204734/http://ejohn.org/blog/javascript-micro-templating/">declaring templates in script blocks</a>; ie:</p>
<div class="highlight"><pre><span class="c"><!-- Our Template is declared in a script block, but we</span>
<span class="c"> can just use regular HTML markup --></span>
<span class="nt"><script </span><span class="na">id=</span><span class="s">"tpl-greeting"</span> <span class="na">type=</span><span class="s">"text/html"</span><span class="nt">></span>
<span class="o"><</span><span class="nx">dl</span><span class="o">></span>
<span class="o"><</span><span class="nx">dt</span><span class="o">></span><span class="nx">Name</span><span class="o"><</span><span class="err">/dt></span>
<span class="o"><</span><span class="nx">dd</span><span class="o">></span><span class="p">{{</span><span class="nx">name</span><span class="p">}}</span><span class="o"><</span><span class="err">/dd></span>
<span class="o"><</span><span class="nx">dt</span><span class="o">></span><span class="nx">Time</span><span class="o"><</span><span class="err">/dt></span>
<span class="o"><</span><span class="nx">dd</span><span class="o">></span><span class="p">{{</span><span class="nx">timeNow</span><span class="p">}}</span><span class="o"><</span><span class="err">/dd></span>
<span class="o"><</span><span class="err">/dl></span>
<span class="nt"></script></span>
<span class="nt"><script </span><span class="na">type=</span><span class="s">"text/javascript"</span><span class="nt">></span>
<span class="kd">var</span> <span class="nx">date</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">();</span>
<span class="kd">var</span> <span class="nx">templateData</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">name</span><span class="o">:</span> <span class="s2">"Jonny"</span><span class="p">,</span>
<span class="nx">timeNow</span><span class="o">:</span> <span class="nx">date</span><span class="p">.</span><span class="nx">getHours</span><span class="p">()</span> <span class="o">+</span> <span class="s1">':'</span> <span class="o">+</span> <span class="nx">date</span><span class="p">.</span><span class="nx">getMinutes</span><span class="p">()</span>
<span class="p">};</span>
<span class="c1">// Use jQuery to reference our 'tpl-greeting' script block</span>
<span class="c1">// and grab the HTML contents it contains.</span>
<span class="kd">var</span> <span class="nx">template</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="s1">'#tpl-greeting'</span><span class="p">).</span><span class="nx">html</span><span class="p">();</span>
<span class="c1">// Render this template as before.</span>
<span class="nx">$</span><span class="p">(</span><span class="s1">'body'</span><span class="p">).</span><span class="nx">append</span><span class="p">(</span><span class="nx">Mustache</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span><span class="nx">template</span><span class="p">,</span> <span class="nx">templateData</span><span class="p">));</span>
<span class="nt"></script></span>
</pre></div>
<p>Much nicer! Now we are able to write our template in HTML as opposed to simply mashing Strings together; however, this method still isn’t ideal; in order for it to work we have to define our template in the parent HTML Document; this is fine for a simple example, but in a real world web application you won’t be writing your JavaScript in a script block, you’ll be using external .js files instead – and you don’t really want to have to send all the HTML Templates down in the original page – let’s externalise those templates and load them in as we need them.</p>
<h3>Loading External HTML Templates</h3>
<p>jQuery makes it really easy to load external content via its <code>jQuery.get()</code> method. We can use this to load an external HTML file which contains our template:</p>
<div class="highlight"><pre><span class="c"><!-- You can define as many templates as you like in a single</span>
<span class="c"> .htm file; just add additional <script /> blocks with</span>
<span class="c"> unique ids. --></span>
<span class="nt"><script </span><span class="na">id=</span><span class="s">"tpl-greeting"</span> <span class="na">type=</span><span class="s">"text/html"</span><span class="nt">></span>
<span class="o"><</span><span class="nx">dl</span><span class="o">></span>
<span class="o"><</span><span class="nx">dt</span><span class="o">></span><span class="nx">Name</span><span class="o"><</span><span class="err">/dt></span>
<span class="o"><</span><span class="nx">dd</span><span class="o">></span><span class="p">{{</span><span class="nx">name</span><span class="p">}}</span><span class="o"><</span><span class="err">/dd></span>
<span class="o"><</span><span class="nx">dt</span><span class="o">></span><span class="nx">Time</span><span class="o"><</span><span class="err">/dt></span>
<span class="o"><</span><span class="nx">dd</span><span class="o">></span><span class="p">{{</span><span class="nx">timeNow</span><span class="p">}}</span><span class="o"><</span><span class="err">/dd></span>
<span class="o"><</span><span class="err">/dl></span>
<span class="nt"></script></span>
</pre></div>
<div class="highlight"><pre><span class="nx">$</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">'greetings.htm'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">templates</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// Fetch the <script /> block from the loaded external</span>
<span class="c1">// template file which contains our greetings template.</span>
<span class="kd">var</span> <span class="nx">template</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="nx">templates</span><span class="p">).</span><span class="nx">filter</span><span class="p">(</span><span class="s1">'#tpl-greeting'</span><span class="p">).</span><span class="nx">html</span><span class="p">();</span>
<span class="nx">$</span><span class="p">(</span><span class="s1">'body'</span><span class="p">).</span><span class="nx">append</span><span class="p">(</span><span class="nx">Mustache</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span><span class="nx">template</span><span class="p">,</span> <span class="nx">templateData</span><span class="p">));</span>
<span class="p">});</span>
</pre></div>
<p>Now we’re talking! Finally, we are able to define our templates in external HTML files which can easily be loaded and rendered in our application’s JavaScript code. However, the above is only a proof of concept and doesn’t really stand up in the real world; what if we want to render our greetings template more than once? If we are going to have to load the template file each time our code is going to be littered with callback functions – again, not pretty and not easy to maintain – what we need is some kind of plugin…</p>
<h3>jQuery-Mustache Plugin</h3>
<p>To make working with Mustache in jQuery nice and easy I knocked together my first jQuery Plugin, <a href="https://github.com/jonnyreeves/jquery-Mustache">jquery-mustache.js</a>. This makes it really easy to load all your external templates at the start and then render them as required.</p>
<div class="highlight"><pre><span class="nx">$</span><span class="p">.</span><span class="nx">Mustache</span><span class="p">.</span><span class="nx">load</span><span class="p">(</span><span class="s1">'greetings.htm'</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">$</span><span class="p">(</span><span class="s1">'body'</span><span class="p">).</span><span class="nx">mustache</span><span class="p">(</span><span class="s1">'tpl-greeting'</span><span class="p">,</span> <span class="nx">templateData</span><span class="p">);</span>
<span class="p">});</span>
</pre></div>
<p>Sweet!</p>
</div>
<hr />
</article>
<article>
<header>
<h2><a href="http://jonnyreeves.co.uk/2011/getting-started-with-as3-vanilla/#getting-started-with-as3-vanilla">Getting Started with AS3 Vanilla</a></h2>
<p>
Posted on Sun 14 August 2011 in <a href="http://jonnyreeves.co.uk/category/actionscript.html">ActionScript</a> •
</p>
</header>
<div>
<p>A lot of people are excited about the news that Native JSON support is coming with <a href="https://web.archive.org/web/20120104112810/http://www.bytearray.org/?p=3066">Flash Player 11</a>; however, I’ve also seen a lot of people get a bit confused by what this actually means – if you were hoping that Flash would be able to magically convert your parsed JSON Strings into your own Model objects then you’re going to be left a touch disappointed – until now!</p>
<h3>That’s Just Weak...</h3>
<p>Let’s start by using the new native JSON methods to parse some JSON and see what we get back, for this example I will be making use of the Yahoo! Weather API to get the forcast for London.</p>
<div class="highlight"><pre><span class="kd">public</span> <span class="kd">class</span> <span class="nx">Main</span> <span class="kd">extends</span> <span class="nb">Sprite</span> <span class="p">{</span>
<span class="kd">private</span> <span class="k">var</span> <span class="nx">loader</span> <span class="o">:</span> <span class="nb">URLLoader</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">URLLoader</span><span class="p">();</span>
<span class="kd">public</span> <span class="kd">function</span> <span class="nx">Main</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">loader</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="nb">Event</span><span class="p">.</span><span class="nx">COMPLETE</span><span class="o">,</span> <span class="nx">onLoaderComplete</span><span class="p">);</span>
<span class="c1">// Look up the weather in London (probably raining...)</span>
<span class="nx">loader</span><span class="p">.</span><span class="nx">load</span><span class="p">(</span><span class="k">new</span> <span class="nb">URLRequest</span><span class="p">(</span><span class="s2">"http://weather.yahooapis.com/forecastjson?w=44418&u=c"</span><span class="p">));</span>
<span class="p">}</span>
<span class="kd">private</span> <span class="kd">function</span> <span class="nx">onLoaderComplete</span><span class="p">(</span><span class="nx">event</span> <span class="o">:</span> <span class="nb">Event</span><span class="p">)</span> <span class="o">:</span> <span class="nx">void</span> <span class="p">{</span>
<span class="kd">const</span> <span class="nx">rawJson</span> <span class="o">:</span> <span class="nb">String</span> <span class="o">=</span> <span class="nx">loader</span><span class="p">.</span><span class="nx">data</span><span class="o">;</span>
<span class="c1">// Use a JSON decoder to convert the rawJson String into an Object.</span>
<span class="kd">const</span> <span class="nx">jsonObject</span> <span class="o">:</span> <span class="nb">Object</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">decode</span><span class="p">(</span><span class="nx">rawJson</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
<p>The above code given provides me with a <code>jsonObject</code> property, however, it’s completely dynmaic; this means I won’t gain any of the benefits of Strong Typing such as code hinting – if I want to access the properties, I have to know their names, eg:</p>
<div class="highlight"><pre><span class="nf">trace</span><span class="p">(</span><span class="s2">"The weather in "</span> <span class="o">+</span> <span class="nx">jsonObject</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">city</span> <span class="o">+</span> <span class="s2">" is "</span> <span class="o">+</span> <span class="nx">jsonObject</span><span class="p">.</span><span class="nx">forecast</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">condition</span> <span class="o">+</span> <span class="s2">" "</span> <span class="o">+</span> <span class="nx">jsonObject</span><span class="p">.</span><span class="nx">forecast</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">day</span><span class="p">);</span>
</pre></div>
<h3>Getting Harder...</h3>
<p>If you plan on passing the forecast data around in your application then you are going to start wishing you were making use of Strongly typed Model objects (for example, if you rely on using dyanmic objects then a simple typo in another class may cause you a headache) – ok, not a problem, the first step is to create a couple: (note I am not representing the entire Object Graph here to save space.</p>
<div class="highlight"><pre><span class="c1">// Use a JSON decoder to convert the rawJson String into an Object.</span>
<span class="kd">const</span> <span class="nx">jsonObject</span> <span class="o">:</span> <span class="nb">Object</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">decode</span><span class="p">(</span><span class="nx">rawJson</span><span class="p">);</span>
<span class="c1">// Copy of the fields from the jsonObject into our strongly typed Model.</span>
<span class="kd">const</span> <span class="nx">weatherResult</span> <span class="o">:</span> <span class="nx">WeatherResult</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">WeatherResult</span><span class="p">();</span>
<span class="nx">weatherResult</span><span class="p">.</span><span class="nx">url</span> <span class="o">=</span> <span class="nx">jsonObject</span><span class="p">[</span><span class="s2">"url"</span><span class="p">];</span>
<span class="nx">weatherResult</span><span class="p">.</span><span class="nx">location</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Location</span><span class="p">();</span>
<span class="nx">weatherResult</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">city</span> <span class="o">=</span> <span class="nx">jsonObject</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">city</span><span class="o">;</span>
<span class="nx">weatherResult</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">locationId</span> <span class="o">=</span> <span class="nx">jsonObject</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">location_id</span><span class="o">;</span>
<span class="nx">weatherResult</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">stateAbbreviation</span> <span class="o">=</span> <span class="nx">jsonObject</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">state_abbreviation</span><span class="o">;</span>
<span class="nx">weatherResult</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">countryAbbreviation</span> <span class="o">=</span> <span class="nx">jsonObject</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">state_abbreviation</span><span class="o">;</span>
<span class="nx">weatherResult</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">elevation</span> <span class="o">=</span> <span class="nx">jsonObject</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">elevation</span><span class="o">;</span>
<span class="nx">weatherResult</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">latitude</span> <span class="o">=</span> <span class="nx">jsonObject</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">latitude</span><span class="o">;</span>
<span class="nx">weatherResult</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">longitude</span> <span class="o">=</span> <span class="nx">jsonObject</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">longitude</span><span class="o">;</span>
<span class="nx">weatherResult</span><span class="p">.</span><span class="nx">forecast</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Vector</span><span class="p">.</span><span class="o"><</span><span class="nx">Forecast</span><span class="o">></span><span class="p">();</span>
<span class="k">for</span> <span class="k">each</span> <span class="p">(</span><span class="k">var</span> <span class="nx">forecastJson</span> <span class="o">:</span> <span class="nb">Object</span> <span class="k">in</span> <span class="nx">jsonObject</span><span class="p">.</span><span class="nx">forecast</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">const</span> <span class="nx">forecast</span> <span class="o">:</span> <span class="nx">Forecast</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Forecast</span><span class="p">();</span>
<span class="nx">forecast</span><span class="p">.</span><span class="nx">day</span> <span class="o">=</span> <span class="nx">forecastJson</span><span class="p">.</span><span class="nx">day</span><span class="o">;</span>
<span class="nx">forecast</span><span class="p">.</span><span class="nx">condition</span> <span class="o">=</span> <span class="nx">forecastJson</span><span class="p">.</span><span class="nx">condition</span><span class="o">;</span>
<span class="nx">forecast</span><span class="p">.</span><span class="nx">highTemperature</span> <span class="o">=</span> <span class="nx">forecastJson</span><span class="p">.</span><span class="nx">high_temperature</span><span class="o">;</span>
<span class="nx">forecast</span><span class="p">.</span><span class="nx">lowTemperature</span> <span class="o">=</span> <span class="nx">forecastJson</span><span class="p">.</span><span class="nx">low_temperature</span><span class="o">;</span>
<span class="nx">weatherResult</span><span class="p">.</span><span class="nx">forecast</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">forecast</span><span class="p">);</span>
<span class="p">}</span>
<span class="nf">trace</span><span class="p">(</span><span class="s2">"The weather in "</span> <span class="o">+</span> <span class="nx">weatherResult</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">city</span> <span class="o">+</span> <span class="s2">" is "</span> <span class="o">+</span> <span class="nx">weatherResult</span><span class="p">.</span><span class="nx">forecast</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">condition</span> <span class="o">+</span> <span class="s2">" "</span> <span class="o">+</span> <span class="nx">weatherResult</span><span class="p">.</span><span class="nx">forecast</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">day</span><span class="p">);</span>
</pre></div>
<p>Crikey, that’s an awful lot of a lot of code; well – at least now if we’ve made a typo anywhere, or if Yahoo decide to change their API at least we only have to make our changes in a single place – there must be an easier way of doing this?!</p>
<h2>Adding some Vanilla Extract</h2>
<p>Enter <a href="https://github.com/jonnyreeves/as3-vanilla">AS3 Vanilla</a>. Vanilla is an open source AS3 library whose sole purpose it to make converting untyped objects (such as the result of calling JSON.decode) into strongly typed Model objects a breeze, let’s see it in action:</p>
<div class="highlight"><pre><span class="c1">// Use a JSON decoder to convert the rawJson String into an Object.</span>
<span class="kd">const</span> <span class="nx">jsonObject</span> <span class="o">:</span> <span class="nb">Object</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">decode</span><span class="p">(</span><span class="nx">rawJson</span><span class="p">);</span>
<span class="c1">// Use Vanilla to extract the properties into our model objects.</span>
<span class="kd">const</span> <span class="nx">weatherResult</span> <span class="o">:</span> <span class="nx">WeatherResult</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Vanilla</span><span class="p">().</span><span class="nx">extract</span><span class="p">(</span><span class="nx">jsonObject</span><span class="o">,</span> <span class="nx">WeatherResult</span><span class="p">);</span>
<span class="nf">trace</span><span class="p">(</span><span class="s2">"The weather in "</span> <span class="o">+</span> <span class="nx">weatherResult</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">city</span> <span class="o">+</span> <span class="s2">" is "</span> <span class="o">+</span> <span class="nx">weatherResult</span><span class="p">.</span><span class="nx">forecast</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">condition</span> <span class="o">+</span> <span class="s2">" "</span> <span class="o">+</span> <span class="nx">weatherResult</span><span class="p">.</span><span class="nx">forecast</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">day</span><span class="p">);</span>
</pre></div>
<p>Yep, that’s it; 20 lines of tedious, error prone code replaced with a single call to Vanilla’s <code>extract()</code> method; pretty neat eh? So, let’s have a look at how it works.</p>
<p>The main design goal of Vanilla was to make the extraction process as simple as possible – infact, if your JSON object matches up perfectly to your Model object then you don’t need to do a thing, for example, here’s our WeatherResult model object’s class definition:</p>
<div class="highlight"><pre><span class="kd">public</span> <span class="kd">class</span> <span class="nx">WeatherResult</span> <span class="p">{</span>
<span class="kd">public</span> <span class="k">var</span> <span class="nx">url</span> <span class="o">:</span> <span class="nb">String</span><span class="o">;</span>
<span class="kd">public</span> <span class="k">var</span> <span class="nx">location</span> <span class="o">:</span> <span class="nx">Location</span><span class="o">;</span>
<span class="kd">public</span> <span class="k">var</span> <span class="nx">forecast</span> <span class="o">:</span> <span class="nx">Vector</span><span class="p">.</span><span class="o"><</span><span class="nx">Forecast</span><span class="o">>;</span>
<span class="p">}</span>
</pre></div>
<p>Let’s compare that to a cross section of the JSON object we get back from the Yahoo weather api:</p>
<div class="highlight"><pre><span class="p">{</span>
<span class="s2">"location"</span><span class="o">:</span><span class="p">{</span>
<span class="s2">"location_id"</span><span class="o">:</span><span class="s2">"UKXX0085"</span><span class="p">,</span>
<span class="s2">"city"</span><span class="o">:</span><span class="s2">"London"</span><span class="p">,</span>
<span class="s2">"state_abbreviation"</span><span class="o">:</span><span class="s2">"ENG"</span><span class="p">,</span>
<span class="s2">"country_abbreviation"</span><span class="o">:</span><span class="s2">"UK"</span><span class="p">,</span>
<span class="s2">"elevation"</span><span class="o">:</span><span class="mi">56</span><span class="p">,</span>
<span class="s2">"latitude"</span><span class="o">:</span><span class="mf">51.51000000000000</span><span class="p">,</span>
<span class="s2">"longitude"</span><span class="o">:</span><span class="s2">"-.08"</span>
<span class="p">},</span>
<span class="s2">"url"</span><span class="o">:</span><span class="s2">"http://weather.yahoo.com/forecast/UKXX0085.html"</span><span class="p">,</span>
<span class="s2">"forecast"</span><span class="o">:</span><span class="p">[</span>
<span class="p">{</span>
<span class="s2">"day"</span><span class="o">:</span><span class="s2">"Today"</span><span class="p">,</span>
<span class="s2">"condition"</span><span class="o">:</span><span class="s2">"Partly Cloudy"</span><span class="p">,</span>
<span class="s2">"high_temperature"</span><span class="o">:</span><span class="s2">"70"</span><span class="p">,</span>
<span class="s2">"low_temperature"</span><span class="o">:</span><span class="s2">"52"</span>
<span class="p">},</span>
<span class="p">{</span>
<span class="s2">"day"</span><span class="o">:</span><span class="s2">"Tomorrow"</span><span class="p">,</span>
<span class="s2">"condition"</span><span class="o">:</span><span class="s2">"Partly Cloudy"</span><span class="p">,</span>
<span class="s2">"high_temperature"</span><span class="o">:</span><span class="s2">"72"</span><span class="p">,</span>
<span class="s2">"low_temperature"</span><span class="o">:</span><span class="s2">"58"</span>
<span class="p">}</span>
<span class="p">]</span>
<span class="p">}</span>
</pre></div>
<p>As you can see, the three fields in the WeatherResult model object, <em>location</em>, <em>url</em> and <em>forecast</em> all map exactly to those fields in the JSON object – Vanilla exploits this and guesses that you probably want to map to those fields; however, not everything is always so clear – what if your model object doesn’t map up exactly to the JSON result? Let’s have a look at our Location model:</p>
<div class="highlight"><pre><span class="kd">public</span> <span class="kd">class</span> <span class="nx">Location</span> <span class="p">{</span>
<span class="kd">public</span> <span class="k">var</span> <span class="nx">locationId</span> <span class="o">:</span> <span class="nb">String</span><span class="o">;</span>
<span class="kd">public</span> <span class="k">var</span> <span class="nx">city</span> <span class="o">:</span> <span class="nb">String</span><span class="o">;</span>
<span class="kd">public</span> <span class="k">var</span> <span class="nx">stateAbbreviation</span> <span class="o">:</span> <span class="nb">String</span><span class="o">;</span>
<span class="kd">public</span> <span class="k">var</span> <span class="nx">countryAbbreviation</span> <span class="o">:</span> <span class="nb">String</span><span class="o">;</span>
<span class="kd">public</span> <span class="k">var</span> <span class="nx">elevation</span> <span class="o">:</span> <span class="nb">Number</span><span class="o">;</span>
<span class="kd">public</span> <span class="k">var</span> <span class="nx">latitude</span> <span class="o">:</span> <span class="nb">Number</span><span class="o">;</span>
<span class="kd">public</span> <span class="k">var</span> <span class="nx">longitude</span> <span class="o">:</span> <span class="nb">String</span><span class="o">;</span>
<span class="p">}</span>
</pre></div>
<p>If you look closely you will notice how some of the field names do not map to the JSON, for example, the field “country_abbreviation” in the JSON is not present in the Model (I’ve named the field countryAbbreviation, as per the AS3 camelCase convention), so how does Vanilla know what to do? Simple answer, it doesn’t – nothing will be mapped and Location.country Abbreviation will be null. </p>
<h3>Using Metadata to define Marshalling Rules</h3>
<p>In the above example the JSON field <code>country_abbreviation</code> was not being mapped to our model’s “countryAbbreviation” property because Vanilla didn’t know that these two were related – so how can we tell Vanilla about that relationship? Like this:</p>
<div class="highlight"><pre><span class="kd">public</span> <span class="kd">class</span> <span class="nx">Location</span> <span class="p">{</span>
<span class="p">[</span><span class="nx">Marshall</span> <span class="p">(</span><span class="nx">field</span><span class="o">=</span><span class="s2">"location_id"</span><span class="p">)]</span> <span class="kd">public</span> <span class="k">var</span> <span class="nx">locationId</span> <span class="o">:</span> <span class="nb">String</span><span class="o">;</span>
<span class="kd">public</span> <span class="k">var</span> <span class="nx">city</span> <span class="o">:</span> <span class="nb">String</span><span class="o">;</span>
<span class="p">[</span><span class="nx">Marshall</span> <span class="p">(</span><span class="nx">field</span><span class="o">=</span><span class="s2">"state_abbreviation"</span><span class="p">)]</span> <span class="kd">public</span> <span class="k">var</span> <span class="nx">stateAbbreviation</span> <span class="o">:</span> <span class="nb">String</span><span class="o">;</span>
<span class="p">[</span><span class="nx">Marshall</span> <span class="p">(</span><span class="nx">field</span><span class="o">=</span><span class="s2">"country_abbreviation"</span><span class="p">)]</span> <span class="kd">public</span> <span class="k">var</span> <span class="nx">countryAbbreviation</span> <span class="o">:</span> <span class="nb">String</span><span class="o">;</span>
<span class="kd">public</span> <span class="k">var</span> <span class="nx">elevation</span> <span class="o">:</span> <span class="nb">Number</span><span class="o">;</span>
<span class="kd">public</span> <span class="k">var</span> <span class="nx">latitude</span> <span class="o">:</span> <span class="nb">Number</span><span class="o">;</span>
<span class="kd">public</span> <span class="k">var</span> <span class="nx">longitude</span> <span class="o">:</span> <span class="nb">String</span><span class="o">;</span>
<span class="p">}</span>
</pre></div>
<p>Here we have annotated the public fields of the Location model object with the [Marshall] Metadata tag – this tells Vanilla that if we see a field named ‘country_abbreviation’ on the source (JSON) object, then we should copy that value to the annotated filed.</p>
<h3>Have It Your Way</h3>
<p>Although Vanilla aims to be as easy to use as possible, it also tries to be flexible to adapt to different ways of working – lots of teams make use of explicit getter/setter methods instead of using fields; don’t worry – Vanilla can detect metadata on these methods too!</p>
</div>
<hr />
</article>
<article>
<header>
<h2><a href="http://jonnyreeves.co.uk/2011/maven-and-ant-managing-your-flash-projects-build-dependencies/#maven-and-ant-managing-your-flash-projects-build-dependencies">Maven and ANT – Managing Your Flash Project’s Build Dependencies</a></h2>
<p>
Posted on Sat 02 April 2011 in <a href="http://jonnyreeves.co.uk/category/actionscript.html">ActionScript</a> •
</p>
</header>
<div>
<p>Project build dependency management and resolution is one of the more difficult problems you’ll face as your project grows in size; however even the smallest of projects (and teams) can benefit greatly from getting automatic dependency resolution in place.</p>
<h3>What Are My Project’s Build Dependencies?</h3>
<p>Most of us are aware of dependencies in object orientated programming – these are the objects that our class in question needs to operate and most of us know the design patterns which we can use to externalise these dependency. Project build dependencies aren’t radically different; instead of referring to objects and instances; we are talking about the source code files (.as) that your project needs when it compiles. Any source code that you haven’t directly written for your project is a build dependency.</p>
<p>Imagine a simple project which makes use of TweenLite and where the source files (.as) for the TwenLite library have been copied into the source folder (src). Now if this were a real project it would result in the greensock code also being committed to our source repository. So, what’s the problem with this? Here’s a couple of potential issues:</p>
<ul>
<li>The project compilation time will be increased as MXMLC will be forced to recompile all the greensock code</li>
<li>Developers need to checkout all the source code for TweenLite even tho they will never be editing it – furthermore, some developers may get over excited and decide to start making modifications to this code (at which point it stops being a 3rd party library!)</li>
<li>If your project consists of multiple modules (ie: Other SWFs which are loaded at runtime) you will need to make sure they all have exactly the same copy of the TweenLite source code available on the source-path due to the way Flash manages loaded <a href="https://web.archive.org/web/20120406204734/http://www.senocular.com/flash/tutorials/contentdomains/?page=2#ChildDomainsDefinitionVersioning">Class Definitions in LoaderContexts</a>.</li>
</ul>
<h2>Using Linked Resource Folders To Share Dependencies Across Projects</h2>
<p>Most IDEs allow you to create <a href="http://help.eclipse.org/juno/index.jsp?topic=%2Forg.eclipse.platform.doc.user%2Fconcepts%2Fconcepts-13.htm">Linked Resource Folders</a>; the concept is simple – projects can import other projects source folders to allow them to share code, similar to unix symlinks – sounds great – however in practice it can cause lots of headaches!</p>
<p>Imagine a workspace that includes three folders/libraries which are linked:</p>
<ul>
<li>
<p>3rdparty – This project doesn’t compile or create anything, it simply serves as a dumping ground for all application’s shared dependencies, in this case, TweenLite.</p>
</li>
<li>
<p>main – This is our application’s Main project, this makes use of TweenLite and also loads in other module SWFs at runtime.</p>
</li>
<li>
<p>module – This is a module which the Main application will load in at runtime – it also makes use of TweenLite (let’s face it, what Flash app doesn’t!)</p>
</li>
</ul>
<p>Both the ‘main’ project and the ‘module’ project make use of a Linked Resource named ‘ThirdParty’ which in turn resolves to the location of the ’3rdparty’ project in our workspace. This allows them to include the TweenLite source code without having to copy/paste it into each project. This solves one of the major problems we’ve outlined above – all our application’s projects (including the modules) will now make use of the exact same version of their dependencies thanks to the ‘ThirdParty’ Linked Resource folder – also, when we want to update to a newer version of a library we just have to update the library in a single place and recompile everything – easy.</p>
<p>However, apart from not solving the other two issues (slower compilation and the fact we are checking in raw source code that we don’t wish to maintain) we have also just created a new, much uglier problem with our project – it’s no longer easy to build!</p>
<p>When creating a large project you should always strive to make the build as simple and easy as possible; I try and keep the following things in mind:</p>
<ul>
<li>
<p>You should be able to check the entire application’s source out of version control with a single command; no more.</p>
</li>
<li>
<p>You should be able to create a fresh build of the application (including all modules) with a single command (eg: by issuing ant package from a fresh checkout of the source code</p>
</li>
<li>
<p>Developers should be able to work on the project using whichever IDE or tool they wish; don’t rely on a particular environment use, such as FlashBuilder or FDT</p>
</li>
</ul>
<p>By using linked resources we have broken these rules – the whole Linked Resource concept is tightly coupled to a given IDE; even if you check in all your .project and .settings files it isn’t going to work if someone decides they want to give IntelliJ a spin.</p>
<h3>SWCs To The Rescue!</h3>
<p>When ActionScript 3 became available, Adobe provided Flash developers with a new tool, the SWC. SWCs are just zip files in disguise (if you don’t believe me, rename the extension from .swc to .swc.zip and then open it) which contain a SWF file and an XML catalouge which allows your IDE to parse all the class definitions the SWF contains. All the major Actionscript IDEs provide tools for working with SWC files.</p>
<p>SWCs are preferable to just dumping the source code into your project for a number of reasons – infact they solve nearly all the points we listed above.</p>
<ul>
<li>
<p>Compilation becomes faster as SWCs are already pre-compiled</p>
</li>
<li>
<p>Instead of checking the entire source tree of the 3rd party library into SVN we are now only checking a single, compressed file – this makes checkout faster and also means that developers won’t be able to start modifying the library.</p>
</li>
</ul>
<p>But one thing is not checked off – what about projects which make use of multiple modules – it would appear we still have the same problem that all of our modules must use the exact same version of the library – now you could just solve this by making use of a LinkedResource which points to a bunch of SWCs but that’s still not great; and when it really comes down to it – should these SWCs really be in version control at all – after all you are in not in control of their development and you don’t decide when they get updated.</p>
<h2>Automatically Managing Your SWCs with Maven</h2>
<p>So, it’s now becoming clear that you and your application have some serious dependency issues when it comes to 3rd Party SWCs; don’t worry, the first step is admission – let’s start by declaring them. This article is going to focus on using Maven to declare and resolve your project’s dependencies – other solutions are available :)</p>
<p>Maven’s dependency management work on the simple premise that the dependencies your application relies upon (in our case, SWCs) exist out on the Internet on a special type of file server, known to Maven as a <a href="https://web.archive.org/web/20120406204734/http://maven.apache.org/guides/introduction/introduction-to-repositories.html">Maven Repository</a>. Maven Repositories can either be public facing (in the case of the <a href="https://web.archive.org/web/20120406204734/http://repo1.maven.org/maven2/">Central Maven Repo</a>.) or internal on a company’s own Intranet. Maven Repositories sole purpose is to house and catalogue build artefacts so that they can be fetched (resolved) during a project’s build. Instead of checking your applications dependencies into version control, you instead just list the dependencies in your project and then Maven will fetch them when required.</p>
<p>So, let’s start with a very simple application which consists of a single project which has a single build dependency on <a href="https://web.archive.org/web/20120406204734/http://www.as3commons.org/as3-commons-logging/index.html">AS3Commons Logging</a>. (I would have used TweenLite as an example, but it’s not available on any public Maven repositories at the time of writing). The first thing we need to do is get a simple build script on the go – I’m going to use ANT to perform the build (Maven, which describes itself as a project management tool is more than capable of both compiling and managing your project’s dependencies, but this article is is just focuses on using Maven for managing dependencies). Maven and ANT get along just fine (although their user’s pdon't always see eye to eye](https://web.archive.org/web/20120406204734/http://java.dzone.com/news/maven-or-ant) on the Internet!); all we need to do is grab a copy of the <a href="https://web.archive.org/web/20120406204734/http://maven.apache.org/ant-tasks/index.html">Maven ANT Tasks JAR</a>, add it to our project and reference it in our ANT Script:</p>
<p>A Skeleton ANT Build Script Which Makes Use Of the Maven ANT Tasks</p>
<div class="highlight"><pre><span class="nt"><project</span> <span class="na">name=</span><span class="s">"maven-dependencies"</span> <span class="na">xmlns:artifact=</span><span class="s">"antlib:org.apache.maven.artifact.ant"</span><span class="nt">></span>
<span class="c"><!-- Inclde the Maven ANT Tasks --></span>
<span class="nt"><path</span> <span class="na">id=</span><span class="s">"maven-ant-tasks.classpath"</span> <span class="na">path=</span><span class="s">"maven-ant-tasks-2.1.1.jar"</span> <span class="nt">/></span>
<span class="nt"><typedef</span> <span class="na">resource=</span><span class="s">"org/apache/maven/artifact/ant/antlib.xml"</span>
<span class="na">uri=</span><span class="s">"antlib:org.apache.maven.artifact.ant"</span>
<span class="na">classpathref=</span><span class="s">"maven-ant-tasks.classpath"</span> <span class="nt">/></span>
<span class="c"><!-- Include the FlexSDK ANT Tasks --></span>
<span class="nt"><taskdef</span> <span class="na">resource=</span><span class="s">"flexTasks.tasks"</span> <span class="na">classpath=</span><span class="s">"${FLEX_HOME}/ant/lib/flexTasks.jar"</span> <span class="nt">/></span>
<span class="nt"></project></span>
</pre></div>
<p>In the example above I have copied the maven-ant-tasks.jar file into my project; however another approach is to copy the maven-ant-tasks.jar file into your ANT_HOME folder (if you’re on Windows this will be Users{username}.antlib). For more information on getting the Maven ANT Tasks setup on your machine, please refer to the <a href="https://web.archive.org/web/20120406204734/http://maven.apache.org/ant-tasks/installation.html">Maven ANT Tasks Installation Documentation</a>.</p>
<p>Now that we have access to the Maven ANT Tasks in our application’s build, the next thing we want to do is list, and resolve our dependencies. This is accomplished by in the “resolve” target shown below:</p>
<p>The Resolve ANT Target which Lists and Pulls Down Dependencies</p>
<div class="highlight"><pre><span class="c"><!-- =================================</span>
<span class="c"> target: resolve</span>
<span class="c"> Uses the Maven ANT Tasks to define and resolve all the dependencies require to build</span>
<span class="c"> this application.</span>
<span class="c"> ================================= --></span>
<span class="nt"><target</span> <span class="na">name=</span><span class="s">"resolve"</span> <span class="na">description=</span><span class="s">"Resolve the project's dependencies"</span><span class="nt">></span>
<span class="c"><!-- The pathId value 'resolves.swcs.classpath' will be an ANT FileSet which points to all the</span>
<span class="c"> SWC files we are about to define --></span>
<span class="nt"><artifact:dependencies</span> <span class="na">filesetId=</span><span class="s">"resolved.swcs.classpath"</span> <span class="na">versionsId=</span><span class="s">"resolved.swcs.versions"</span><span class="nt">></span>
<span class="c"><!-- This is where we list our dependency on as3commons-logging version 2.0; by adding this</span>
<span class="c"> line here, we are telling Maven that our application depends upon this SWC --></span>
<span class="nt"><dependency</span> <span class="na">groupId=</span><span class="s">"org.as3commons"</span> <span class="na">artifactId=</span><span class="s">"as3commons-logging"</span> <span class="na">type=</span><span class="s">"swc"</span> <span class="na">version=</span><span class="s">"1.2"</span> <span class="nt">/></span>
<span class="c"><!-- This is where we provide Maven with the URL of the remote repository where some, or all of</span>
<span class="c"> our dependencies can be retrieved from - if you work with a team you will probably want to</span>
<span class="c"> setup your own Maven Repository in house --></span>
<span class="nt"><remoteRepository</span> <span class="na">id=</span><span class="s">"adobe-opensource"</span> <span class="na">url=</span><span class="s">"http://opensource.adobe.com/svn/opensource/cairngorm3/maven-repository"</span> <span class="nt">/></span>
<span class="nt"></artifact:dependencies></span>
<span class="c"><!-- Copies all the files resolved in the task above into the "libs" folder --></span>
<span class="nt"><copy</span> <span class="na">todir=</span><span class="s">"libs"</span><span class="nt">></span>
<span class="nt"><fileset</span> <span class="na">refid=</span><span class="s">"resolved.swcs.classpath"</span> <span class="nt">/></span>
<span class="c"><!-- This Mapper will remove all the folder heirarchy and version numbers from the resolved SWCs --></span>
<span class="nt"><mapper</span> <span class="na">classpathref=</span><span class="s">"maven-ant-tasks.classpath"</span> <span class="na">classname=</span><span class="s">"org.apache.maven.artifact.ant.VersionMapper"</span>
<span class="na">from=</span><span class="s">"${resolved.swcs.versions}"</span> <span class="na">to=</span><span class="s">"flatten"</span> <span class="nt">/></span>
<span class="nt"></copy></span>
<span class="nt"></target></span>
</pre></div>
<p>The above target breaks down into two major parts – the <a href="https://web.archive.org/web/20120406204734/http://maven.apache.org/ant-tasks/reference.html#dependencies"><code>artifact:dependencies</code> task</a> lists and resolves the project’s dependencies and the copy task then copies these dependencies into the “libs” folder in the project. The two interesting lines int he artifact:dependenciestask are the dependency line which lists as3commons-logging as a dependency (note how we specify the type as “swc” (Maven defaults the type to “jar”) and the version at 1.2). and the remoteRepository line which tells Maven which Maven Repository the dependency should be resolved from – in this project’s case we are using <a href="https://web.archive.org/web/20120406204734/http://opensource.adobe.com/svn/opensource/cairngorm3/maven-repository/">Adobe’s OpenSource Maven Repository</a>; however as mentioned in the comments, you will probably want to create and maintain your own Maven Repo to house your project’s artifacts in (I’m hoping to cover how to setup your own Repo in another post).</p>
<h3>Next Steps</h3>
<p>The above is really just the tip of the iceberg; if you want to really get to grips with dependency management through Maven then you are going to want to start listing your dependencies (and the Maven Repositories they can be resolved from) in a <a href="https://web.archive.org/web/20120406204734/http://maven.apache.org/pom.html#What_is_the_POM">POM file</a> (Project Object Model). POM files not only serve as a place to list dependencies and the URLs of Repositories, but they can define the entire build cycle of the project when using Maven (and in the case of Flash, <a href="https://web.archive.org/web/20120406204734/http://flexmojos.sonatype.org/">FlexMojos</a>) to compile. POM files include an <a href="https://web.archive.org/web/20120406204734/http://maven.apache.org/pom.html#Inheritance">inheritance model</a> (so a Modules’ POM file can extend the main Project’s POM file) allowing you to keep all your dependency definitions in a central place.</p>
<p>Also, this tutorial hasn’t touched on one of the most powerful feature of Maven, <a href="https://web.archive.org/web/20120406204734/http://www.sonatype.com/books/mvnref-book/reference/pom-relationships-sect-transitive.html">transitive dependency resolution</a>. A quick example would be if your project depends on the RobotLegs Framework; from the example above you can see how you could define a dependency on RobotLegs:</p>
<p>Now, you would expect Maven to pull down RobotLegs.swc for you – but those of you familiar with RobotLegs will remember that RobotLegs itself has a dependency upon SwiftSuspenders.swc – Maven will automatically pull down both RobotLegs.swc AND the required version of the SwiftSuspenders.swc for you, even tho you only listed RobotLegs as a dependency! However, in order for this to work, RobotLegs needs to be uploaded to a Maven Repo along with a POM file which lists SwiftSuspenders as a dependency (and where it can be fetched from in turn) – The Java community is all over this and it works like magic – unfortunatley the Flash community is lagging quite far behind – it would be amazing if FlashDevs started pushing their SWCs up to the Central Maven Repo (it would certainly save people from having to setup and maintain their own local repos!)</p>
</div>
</article>
<div class="pagination">
<a class="btn" href="http://jonnyreeves.co.uk/index3.html">
<i class="fa fa-angle-left"></i> Older Posts
</a>
<a class="btn float-right" href="http://jonnyreeves.co.uk/index.html">
Newer Posts <i class="fa fa-angle-right"></i>
</a>
</div>
<footer>
<p>© Jonny Reeves </p>
<p>Built using <a href="http://getpelican.com" target="_blank">Pelican</a> - <a href="https://github.com/alexandrevicenzi/flex" target="_blank">Flex</a> theme by <a href="http://alexandrevicenzi.com" target="_blank">Alexandre Vicenzi</a></p> </footer>
</main>
<script type="text/javascript">
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-30309890-1', 'auto');
ga('send', 'pageview');
</script>
<script type="application/ld+json">
{
"@context" : "http://schema.org",
"@type" : "Blog",
"name": " Jonny Reeves ",
"url" : "http://jonnyreeves.co.uk",
"image": "/images/avatar.jpg",
"description": ""
}
</script></body>
</html>