Using external javascript libraries in Apache Royale

Using external javascript libraries in Apache Royale

Using external javascript libraries in Apache Royale 762 622 Carlos Rovira

This example shows you how to use external JavaScript libraries in your Apache Royale application. This will be very useful to add quick functionality to your application by adding code that is not part of Apache Royale itself or is even not written in ActionScript.

In this way you get lots of libraries available for free in The Internet to use easily in your Apache Royale Application.

It also allows an IDE to provide code completion, type checking, etc.

The example itself will show a Jewel Card with a code text zone that loads an ActionScript code example. You can click the “highlight block” button to show it in a beautiful colored way through highlight code library processing. The highlight library used in this example is in fact an external JavaScript library.

The JavaScript library used to show this feature is highlightjs. In JavaScript this library creates the hljs object that will be referenced later.

How to use JavaScript external libraries

We have two solutions available for using external Javascript libraries in Apache Royale. We’ll focus first on the better and recommended way, which is using the @externs compiler directive.

These means you can have robust access to JavaScript methods though ActionScript with “dot access” syntax (and get code hinting in your IDE). But if you need to prototype something quickly, you still have dynamic syntax with “bracket access” notation.

Dot access

This is the recommended way. You get all advantages of an object oriented language like ActionScript 3: type checking, compiler errors and warnings and code hinting and code completion in your favorite IDEs.

The following code for this hljs as3 stub code is located in the Jewel library and is an @externs class definition for hljs:

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
////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      //www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
package
{
    /**
     * @externs
     */

    public class hljs
    {
        /**
         * <inject_html>
         * <script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
         * <link rel="stylesheet" title="Atom One Dark" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css">
         * </inject_html>
         */

        public function hljs(){}

        COMPILE::JS
        public static function highlightBlock(block:Element):void {}
    }
}

You can see two main things in this code:

  1. An “inject_html” directive declared in the constructor that will add the lines inside to the html template. In this way you do not need to add the lines manually. You leave this task to the compiler that will handle it for you. So if you use this library, Royale will add these references automatically, while if you remove all references, Royale will remove the dependencies to the JavaScript library and nothing will be output in the html file.
    Note: Currently the inject_html injection only works if your @externs class is located in a Royale library. It will not work if is located in the application project.
  2. The highlightBlock static function is the one you want to use and you can access it as a normal method in the AS3 hljs class.

Bracket access

If you need to prototype something quick you can use this way, but remember: we don’t recommend that you use this in a normal Apache Royale project.

First you need to reference the JavaScript library (and/or css if exists) in your html template. For hljs you can copy the following lines:

1
2
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
<link rel="stylesheet" title="Atom One Dark" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css">

Then you can start using that library in your code. An example with the highlightjs hljs object is as follows:

1
2
var hljs:Object = window["hljs"];
hljs["highlightBlock"](block);

As you can see, this avoids using a more structured language like ActionScript 3 and you will lose type checking and the compiler will not help you if you write something wrong. Plus, if some change are done in the API, that code will not be able to warn you about the change.

The example

The example uses HTTPService to retrieve a code sample text data and shows it in an html:Code component. When the application loads, it fires the “initialize” event and we use this to order the HTTPService to load the text file. When the file finishes loading, HTTPService fires a “complete” event that we use to add the text file content to the code_txt String variable.

Note: Since the code_txt variable uses data binding (it’s marked with the “Bindable” metadata and we prepared the application to handle data binding with the ApplicationDataBinding bead), the application will fill the html:Code sourceCodeMXMLText with the loaded text.

This is the code for this example:

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
<?xml version="1.0" encoding="UTF-8"?>
<!--

 Licensed to the Apache Software Foundation (ASF) under one or more
 contributor license agreements.  See the NOTICE file distributed with
 this work for additional information regarding copyright ownership.
 The ASF licenses this file to You under the Apache License, Version 2.0
 (the "License"); you may not use this file except in compliance with
 the License.  You may obtain a copy of the License at

     //www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.

-->

<j:Application xmlns:fx="//ns.adobe.com/mxml/2009"
              xmlns:j="library://ns.apache.org/royale/jewel"
              xmlns:js="library://ns.apache.org/royale/basic"
              xmlns:html="library://ns.apache.org/royale/html"
              initialize="codeTextLoader.send();">

    <fx:Script>
        <![CDATA[
           [Bindable]
           public var code_txt:String;

           public function highLightContent():void
           {
                COMPILE::JS
                {
                    hljs.highlightBlock(sourceCodeMXMLText.element);  
                }
           }
        ]]>
    </fx:Script>
   
    <j:beads>
        <js:ApplicationDataBinding />
        <js:HTTPService id="codeTextLoader" url="as3code.txt" complete="code_txt = codeTextLoader.data;"/>
    </j:beads>

    <j:initialView>
        <j:View>
            <js:beads>
                <j:HorizontalCenteredLayout/>
            </js:beads>

            <j:Card percentWidth="90">
                <html:H3 text="Using external Javascript Libraries"/>
               
                 <j:Label html="This example uses hljs library to highligh a piece of code"/>

                <html:Pre height="300" percentWidth="100" style="background-color: white">
                    <js:beads>
                        <j:ScrollingViewport/>
                    </js:beads>
                    <html:Code id="sourceCodeMXMLText" text="{code_txt}"/>
                </html:Pre>
               
                <j:Button text="highlight Block" emphasis="primary" click="highLightContent()"/>
             </j:Card>
        </j:View>
    </j:initialView>
</j:Application>

In the example code you can see how we call the hljs.highlightBlock method through the recommended dot syntax as with any other ActionScript code, creating a seamless integration between your project code and the external JavaScript code.

Conclusion

Notice how simple and elegant it can be to use external JS code, while not compromising the safe syntax you have when using the MXML and AS3 languages, to give you other dynamic alternatives that you’re free to use.

Where to go from here

The result of this code snippet is the following:

(We’re using an iframe to host the compiled results of this example. To see the example in a separate window click this link.)

The full project with source code can be found here:

Join Us!

You can be part of Apache Royale and start using and contributing to this project. We need your skills to make this great technology reach the next step. You can start by joining us in our mailing list.