You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@royale.apache.org by Yishay Weiss <yi...@hotmail.com> on 2020/05/17 16:02:53 UTC

Script Loading Order (Continuing Heads-Up thread from Users)

>Is the script tag from inject_script going before or after the script tag for the application (should be before, >IMO)?

It’s going before but the network shows it’s loaded after.

>Make sure the script tag has the same settings as the script tags google closure uses in js-debug.  I think they set some options so the scripts load in order.

I see type being specified in the gcl script elements, while inject ones don’t. I suppose it’s worth seeing if that makes a difference, though I couldn’t find evidence for that on the web.

Re: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Carlos Rovira <ca...@apache.org>.
Hi Yishay,

sorry to benign late here. I'm just with few time these days.

I think we should not mix concepts. One thing is, a @extern should work as
alway (using the inject_XXX we finally choose), for various reasons: we
want the stub to be related in that part to the js library that's mirroring
(so that's the sense of that class), and for PAYG reasons (we can't add the
need to all @externs code to have a Facade).

Other thing is we want to show the use of static initializers, that's ok
for me, but not as a need for @externs, so just as a developers option to
use in the case they want.

So sorry, but I'm not aligned with the Facade option, we need to keep the
declaration in the same @externs stub for sure



El mar., 19 may. 2020 a las 19:34, Yishay Weiss (<yi...@hotmail.com>)
escribió:

> Hi Carlos,
>
> Sorry for not responding earlier, I missed this post.
>
> I haven’t been able to replicate this in debug mode, so it’s interesting
> you’re seeing that.
>
> I agree the façade solution is a bit cumbersome, but it works and maybe
> it’s worth having it out there as an example of using static initializers
> instead of injected code.
>
> What do you think?
>
> From: Carlos Rovira<ma...@apache.org>
> Sent: Monday, May 18, 2020 7:34 PM
> To: Apache Royale Development<ma...@royale.apache.org>
> Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
>
> Hi Yishay,
>
> I'm confused. The problem I reported was this;
>
> ReferenceError: dialogPolyfill is not defined at
>
> /Users/carlosrovira/Dev/Royale/Source/royale-asjs/examples/jewel/TourDeJewel/target/javascript/bin/js-debug/App.js:10:1
>
> And just as I'm copying here I'm seeing that while I'm running
> "js-release", notice that the link refers to "js-debug", so I think there's
> some wrong path involved here
>
> I just updated with your latest change about hljs but I don't think we have
> a problems with it. A part from that I don't like the solution to make a
> Facade for a script, since that involves to create 2 classes instead of
> one. The solution should be just make 1 as3 file (instead of two) and that
> have the proper inject reference.
>
> Please can you revert the hljsFacade?
>
> thanks
>
>
>
>
> El lun., 18 may. 2020 a las 17:44, Yishay Weiss (<yi...@hotmail.com>)
> escribió:
>
> > Unless I missed something that’s what it’s doing right now after my fix.
> > I’ll try to explain the scenario as I see it (no modules).
> >
> > Suppose we have an app that compiles to the following html.
> >
> > <html>
> >                 <head>
> >                                 <script type="text/javascript">
> >                                                 var script =
> > document.createElement("script");
> >
>  script.setAttribute("src",
> > "hljs.min.js");
> >
> > document.head.appendChild(script);
> >                                 </script>
> >                                 <script type=”text/JavaScript”
> > src=”App.js”></script>
> >                 </head>
> >                 <body></body>
> > </html>
> >
> > After the first script element is loaded, the dom will look like:
> >
> > <html>
> >                 <head>
> >                                 <script type="text/javascript">
> >                                                 var script =
> > document.createElement("script");
> >
>  script.setAttribute("src",
> > "hljs.min.js");
> >
> > document.head.appendChild(script);
> >                                 </script>
> >                                 <script type=”text/JavaScript”
> > src=”hljs.min.js”></script>
> >                                 <script type=”text/JavaScript”
> > src=”App.js”></script>
> >                 </head>
> >                 <body></body>
> > </html>
> >
> > However, App.js will still be loaded before hljs.min.js because it was
> not
> > created dynamically. App.js will fail because it depends on hljs.
> >
> > From: Alex Harui<ma...@adobe.com.INVALID>
> > Sent: Monday, May 18, 2020 6:21 PM
> > To: dev@royale.apache.org<ma...@royale.apache.org>
> > Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
> >
> > I don't think we have to inject these scripts into the main .js file.
> The
> > compiler knows when it is compiling the main app or a module.  When
> > compiling the main app, it should inject the script in the HEAD of the
> html
> > wrapper.  For modules, it can inject the script into a separate file.
> The
> > ModuleLoader already loads extra files before loading the module.  It can
> > load one more file.
> >
> > Of course, I could be wrong...
> > -Alex
> >
> > On 5/18/20, 7:38 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
> >
> >     From what I’ve read [1] scripts injected dynamically will always load
> > after static script elements. So I don’t think there’s a good way to
> ensure
> > the proper order in run-time unless we do something like
> > 99a8c8356573ff16b668f2d39a447355c673fee3 , but that’s verbose and working
> > with libs should be simple.
> >
> >     Any ideas?
> >
> >     [1]
> >
> https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.html5rocks.com%2Fen%2Ftutorials%2Fspeed%2Fscript-loading%2F%23disqus_thread&amp;data=02%7C01%7Caharui%40adobe.com%7C89b59cc20eff4f34398308d7fb39180f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637254094944356465&amp;sdata=8BCjJ8oV6h2U2wxgorysLU8Sm5tTGwAP7XBEL7yhca4%3D&amp;reserved=0
> >
> >     From: Alex Harui<ma...@adobe.com.INVALID>
> >     Sent: Monday, May 18, 2020 8:03 AM
> >     To: dev@royale.apache.org<ma...@royale.apache.org>
> >
> >
> >     Subject: Re: Script Loading Order (Continuing Heads-Up thread from
> > Users)
> >
> >     Every time I look, closure seems to change how it works.  It looks
> > like they are using callbacks and UIDs.  I assume they can't use await or
> > Promise because of IE support.  I haven't looked at the code you
> generate,
> > but might have to do something similar, IOW, wait for the callback or
> known
> > value before continuing.
> >
> >     I think that if we create the script during the running of another
> > script that we have to find a way to wait for that created script.
> >
> >     It might help to know what kind of initialization code needed the
> > definition so early.  One alternative is that such code needs to be
> > responsible for waiting.
> >
> >     Most of our Application classes have a wait mechanism.  We could
> > leverage that, but that's also pretty late.
> >
> >     It could be that for Applications we generate the script in the head,
> > and for modules we generate a separate script that is preloaded.
> >
> >     HTH,
> >     -Alex
> >
> >     On 5/17/20, 9:03 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
> >
> >
> >         >Is the script tag from inject_script going before or after the
> > script tag for the application (should be before, >IMO)?
> >
> >         It’s going before but the network shows it’s loaded after.
> >
> >         >Make sure the script tag has the same settings as the script
> tags
> > google closure uses in js-debug.  I think they set some options so the
> > scripts load in order.
> >
> >         I see type being specified in the gcl script elements, while
> > inject ones don’t. I suppose it’s worth seeing if that makes a
> difference,
> > though I couldn’t find evidence for that on the web.
> >
> >
> >
> >
> >
>
> --
> Carlos Rovira
> http://about.me/carlosrovira
>
>

-- 
Carlos Rovira
http://about.me/carlosrovira

Re: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Alex Harui <ah...@adobe.com.INVALID>.
IOW, IIRC, dialogPolyFill is an extern and I don't think externs should be referenced like that, so I'm wondering if dialogPolyFill isn't being configured/picked up as an extern or we have a bug in what we output for externs.

HTH,
-Alex

On 5/31/20, 8:42 AM, "Alex Harui" <ah...@adobe.com.INVALID> wrote:

    I won't have time to set this up for a while.  What is the unminified JS for "u('dialogPolyfill',dialogPolyfill)"?
    
    -Alex
    
    On 5/31/20, 8:13 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
    
        Here’s the minimal test case I came up with for demonstrating the problem.
        
        <?xml version="1.0" encoding="utf-8"?>
        <js:Application xmlns:fx="https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fns.adobe.com%2Fmxml%2F2009&amp;data=02%7C01%7Caharui%40adobe.com%7C23a0ae2fda4e44c8a55a08d805792eb1%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265365333525875&amp;sdata=fT6D7lUCWbaaV4AvUdFQCiYJlVdFzNFDIWf0NigwLSI%3D&amp;reserved=0"
                        xmlns:js="library://ns.apache.org/royale/basic"
                        >
               <fx:Script>
                               <![CDATA[
                        private function dummy():void
                        {
                                        dialogPolyfill;
                        }
                               ]]>
               </fx:Script>
        </js:Application>
        
        Where dialogPolyfill is
        
        package
        {
                        /**
                        * @externs
                        */
                        COMPILE::JS
                        public class dialogPolyfill
                        {
                        /**
                 * <inject_script>
                 * var script = document.createElement("script");
                 * script.setAttribute("src", "https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fdialog-polyfill%2F0.4.9%2Fdialog-polyfill.min.js&amp;data=02%7C01%7Caharui%40adobe.com%7C23a0ae2fda4e44c8a55a08d805792eb1%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265365333525875&amp;sdata=o4W9MEMI8b%2FWHUSt5uPZbl39ZTuVCQOXLNVSqbwHDA8%3D&amp;reserved=0");
                 * document.head.appendChild(script)
                 * </inject_script>
                        */
                                        public function dialogPolyfill(){}
                        }
        }
        
        In release I get a ‘ReferenceError: dialogPolyfill is not defined’
        
        u('dialogPolyfill',dialogPolyfill) of Examples.js, which is run before start()
        
        So in order to fix this scenario we would need Examples.js to wait for dialogPolyfill.min.js, not for start() to wait.
        
        From: Alex Harui<ma...@adobe.com.INVALID>
        Sent: Wednesday, May 20, 2020 8:09 PM
        To: dev@royale.apache.org<ma...@royale.apache.org>
        Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
        
        When I mentioned static initializers in my earlier post, it was about the timing of when some code would first access hljs.  Most externs will probably be first used from code that runs after application.start().  But if someone did:
        
        public static var HLJSClass:Class = hljs;
        
        Then that would fail before we can run application.start(), except that the compiler auto-converts static vars to lazy getters.
        
        However, the hljs usage is not wrapped, so there really aren't any static initializers to use, so it doesn’t matter if they are lazy or not.  I haven't looked at the other uses of inject_script, but if a class wraps the dependency, then it can implement its own waiting strategy unless the API has to be synchronous.  IOW, if I created a Highlighter class that used hljs internally, then if the "highlight" API returns a void, the wrapping implementation would load hljs.js and make the call when it is ready, which is essentially building in the façade you wrote.
        
        You could implement a map of injected scripts, but after thinking about it overnight, my first thought is to require that folks publish a var or uid as follows:
        
                 * <inject_script var="hljs_loaded">
                        * var scriptLoaded = function() { hljs_loaded = true) };
                        * var script = document.createElement("script");
                        * script.setAttribute("src", "https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fhighlight.js%2F9.12.0%2Fhighlight.min.js&amp;data=02%7C01%7Caharui%40adobe.com%7C23a0ae2fda4e44c8a55a08d805792eb1%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265365333535869&amp;sdata=NuO%2Fsmma%2Bw8cY3aq8ReC2MR8XgivCssSnolDnaMCbDk%3D&amp;reserved=0");
                        * script.addEventListener("load", scriptLoaded);
                        * document.head.appendChild(script);
                    * </inject_script>
        
        Then the compiler may not need so much as a map, but can gather a list of variables to watch for in the setInterval before calling application.start();
        
        Of course, I could be wrong...
        -Alex
        
        On 5/20/20, 12:19 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
        
            Several questions/comments:
        
        
              1.  When you say static initializers should be lazy, do you mean load on the first lib api call? If so, wouldn’t that force async calls?
              2.  Do you have a way of using static initializers for externs files, which is how hljs was originally used?
              3.  To generate the script that waits for dynamically loaded scripts (I guess we don’t mind async css, though I’m not sure) we would need to have a map of injected scripts. So it looks like we’ll need to parse the injected_sctipt tag in any case.
        
            Thanks.
        
        
        
            From: Alex Harui<ma...@adobe.com.INVALID>
            Sent: Wednesday, May 20, 2020 9:52 AM
            To: dev@royale.apache.org<ma...@royale.apache.org>
            Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
        
            OK, I looked at the commit for hljs, and the code it replaced.  AFAICT, that is an instantiation phase dependency and not a initialization phase dependency, so it should not matter if it loads before or after app.js (unless someone does use it in a non-lazy static initializer, which should be hard to do in Royale).  It should only matter that it is loaded before anybody calls it.  Other than static initializers, which should all be lazy, nobody should really call hljs until after the application.start() is called in the index.html.
        
            Here is the index.html for HelloWorld:
            <html>
            <head>
                    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
                    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
                    <link rel="stylesheet" type="text/css" href="HelloWorld.min.css">
                    <script type="text/javascript" src="./HelloWorld.js"></script>
            </head>
            <body>
                    <script type="text/javascript">
                            new HelloWorld().start();
                    </script>
            </body>
        
            IMO, for applications that use inject_script (modules will use the _deps file), we should generate code before the start() call that waits for any dynamic scripts to load.  So if HelloWorld needed hljs, the index.html would look more like:
        
            <head>
                    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
                    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
                    <link rel="stylesheet" type="text/css" href="HelloWorld.min.css">
                    <script type="text/javascript" src="https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fhighlight.js%2F9.12.0%2Fhighlight.min.js&amp;data=02%7C01%7Caharui%40adobe.com%7C23a0ae2fda4e44c8a55a08d805792eb1%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265365333535869&amp;sdata=NuO%2Fsmma%2Bw8cY3aq8ReC2MR8XgivCssSnolDnaMCbDk%3D&amp;reserved=0"
                                    onload="highlight.min.js.loaded=true;"></script>
                    <script type="text/javascript" src="./HelloWorld.js"></script>
            </head>
            <body>
                    <script type="text/javascript">
                            var appInterval = setInterval(function() { if (highlight.min.js.loaded) {
                                                                                                                      clearInterval(appInterval);
                                                                                                                      new HelloWorld().start();
                                                                                                                }, 200);
                    </script>
            </body>
        
            Closure seems to use a hash of the URL instead of part of the URL to avoid collisions in case two different scripts are called main.js or something like that.  And there might be some better way than using setInterval, but the idea is to wait until the JS is loaded before calling start().
        
            HTH,
            -Alex
        
            On 5/19/20, 12:18 PM, "Yishay Weiss" <yi...@hotmail.com> wrote:
        
                See 99a8c8356573ff16b668f2d39a447355c673fee3
        
                Note that hljs is an externs file so I couldn’t implement static initializers there.
        
                There’s also a sort of a queue there for calls made before lib is loaded. I realize this doesn’t scale as a pattern, which is why I proposed to simplify annotations instead.
        
                It could be of course there’s a simpler solution I’m missing.
        
                From: Alex Harui<ma...@adobe.com.INVALID>
                Sent: Tuesday, May 19, 2020 10:03 PM
                To: dev@royale.apache.org<ma...@royale.apache.org>
                Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
        
                Yishay,
        
                I didn't think static initializers would require a façade or other fancy mechanism.  What kind of AS code ends up requiring this more complex solution?
        
                -Alex
        
                On 5/19/20, 10:34 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
        
                    Hi Carlos,
        
                    Sorry for not responding earlier, I missed this post.
        
                    I haven’t been able to replicate this in debug mode, so it’s interesting you’re seeing that.
        
                    I agree the façade solution is a bit cumbersome, but it works and maybe it’s worth having it out there as an example of using static initializers instead of injected code.
        
                    What do you think?
        
                    From: Carlos Rovira<ma...@apache.org>
                    Sent: Monday, May 18, 2020 7:34 PM
                    To: Apache Royale Development<ma...@royale.apache.org>
                    Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
        
                    Hi Yishay,
        
                    I'm confused. The problem I reported was this;
        
                    ReferenceError: dialogPolyfill is not defined at
                    /Users/carlosrovira/Dev/Royale/Source/royale-asjs/examples/jewel/TourDeJewel/target/javascript/bin/js-debug/App.js:10:1
        
                    And just as I'm copying here I'm seeing that while I'm running
                    "js-release", notice that the link refers to "js-debug", so I think there's
                    some wrong path involved here
        
                    I just updated with your latest change about hljs but I don't think we have
                    a problems with it. A part from that I don't like the solution to make a
                    Facade for a script, since that involves to create 2 classes instead of
                    one. The solution should be just make 1 as3 file (instead of two) and that
                    have the proper inject reference.
        
                    Please can you revert the hljsFacade?
        
                    thanks
        
        
        
        
                    El lun., 18 may. 2020 a las 17:44, Yishay Weiss (<yi...@hotmail.com>)
                    escribió:
        
                    > Unless I missed something that’s what it’s doing right now after my fix.
                    > I’ll try to explain the scenario as I see it (no modules).
                    >
                    > Suppose we have an app that compiles to the following html.
                    >
                    > <html>
                    >                 <head>
                    >                                 <script type="text/javascript">
                    >                                                 var script =
                    > document.createElement("script");
                    >                                                 script.setAttribute("src",
                    > "hljs.min.js");
                    >
                    > document.head.appendChild(script);
                    >                                 </script>
                    >                                 <script type=”text/JavaScript”
                    > src=”App.js”></script>
                    >                 </head>
                    >                 <body></body>
                    > </html>
                    >
                    > After the first script element is loaded, the dom will look like:
                    >
                    > <html>
                    >                 <head>
                    >                                 <script type="text/javascript">
                    >                                                 var script =
                    > document.createElement("script");
                    >                                                 script.setAttribute("src",
                    > "hljs.min.js");
                    >
                    > document.head.appendChild(script);
                    >                                 </script>
                    >                                 <script type=”text/JavaScript”
                    > src=”hljs.min.js”></script>
                    >                                 <script type=”text/JavaScript”
                    > src=”App.js”></script>
                    >                 </head>
                    >                 <body></body>
                    > </html>
                    >
                    > However, App.js will still be loaded before hljs.min.js because it was not
                    > created dynamically. App.js will fail because it depends on hljs.
                    >
                    > From: Alex Harui<ma...@adobe.com.INVALID>
                    > Sent: Monday, May 18, 2020 6:21 PM
                    > To: dev@royale.apache.org<ma...@royale.apache.org>
                    > Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
                    >
                    > I don't think we have to inject these scripts into the main .js file.  The
                    > compiler knows when it is compiling the main app or a module.  When
                    > compiling the main app, it should inject the script in the HEAD of the html
                    > wrapper.  For modules, it can inject the script into a separate file.  The
                    > ModuleLoader already loads extra files before loading the module.  It can
                    > load one more file.
                    >
                    > Of course, I could be wrong...
                    > -Alex
                    >
                    > On 5/18/20, 7:38 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
                    >
                    >     From what I’ve read [1] scripts injected dynamically will always load
                    > after static script elements. So I don’t think there’s a good way to ensure
                    > the proper order in run-time unless we do something like
                    > 99a8c8356573ff16b668f2d39a447355c673fee3 , but that’s verbose and working
                    > with libs should be simple.
                    >
                    >     Any ideas?
                    >
                    >     [1]
                    > https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.html5rocks.com%2Fen%2Ftutorials%2Fspeed%2Fscript-loading%2F%23disqus_thread&amp;data=02%7C01%7Caharui%40adobe.com%7C23a0ae2fda4e44c8a55a08d805792eb1%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265365333535869&amp;sdata=56kF%2Fof%2FpiXUO6c3N4vUok4aZHSHOvQI3%2FFwDnKx7E8%3D&amp;reserved=0
                    >
                    >     From: Alex Harui<ma...@adobe.com.INVALID>
                    >     Sent: Monday, May 18, 2020 8:03 AM
                    >     To: dev@royale.apache.org<ma...@royale.apache.org>
                    >
                    >
                    >     Subject: Re: Script Loading Order (Continuing Heads-Up thread from
                    > Users)
                    >
                    >     Every time I look, closure seems to change how it works.  It looks
                    > like they are using callbacks and UIDs.  I assume they can't use await or
                    > Promise because of IE support.  I haven't looked at the code you generate,
                    > but might have to do something similar, IOW, wait for the callback or known
                    > value before continuing.
                    >
                    >     I think that if we create the script during the running of another
                    > script that we have to find a way to wait for that created script.
                    >
                    >     It might help to know what kind of initialization code needed the
                    > definition so early.  One alternative is that such code needs to be
                    > responsible for waiting.
                    >
                    >     Most of our Application classes have a wait mechanism.  We could
                    > leverage that, but that's also pretty late.
                    >
                    >     It could be that for Applications we generate the script in the head,
                    > and for modules we generate a separate script that is preloaded.
                    >
                    >     HTH,
                    >     -Alex
                    >
                    >     On 5/17/20, 9:03 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
                    >
                    >
                    >         >Is the script tag from inject_script going before or after the
                    > script tag for the application (should be before, >IMO)?
                    >
                    >         It’s going before but the network shows it’s loaded after.
                    >
                    >         >Make sure the script tag has the same settings as the script tags
                    > google closure uses in js-debug.  I think they set some options so the
                    > scripts load in order.
                    >
                    >         I see type being specified in the gcl script elements, while
                    > inject ones don’t. I suppose it’s worth seeing if that makes a difference,
                    > though I couldn’t find evidence for that on the web.
                    >
                    >
                    >
                    >
                    >
        
                    --
                    Carlos Rovira
                    https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fabout.me%2Fcarlosrovira&amp;data=02%7C01%7Caharui%40adobe.com%7C23a0ae2fda4e44c8a55a08d805792eb1%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265365333535869&amp;sdata=BMRPAwlpASNFIqcO7jwZ1qFvbbNnu1vhxAy2dxZTpzg%3D&amp;reserved=0
        
        
        
        
        
        
        
        
    
    


RE: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Yishay Weiss <yi...@hotmail.com>.
There is no unminified parallel. I think this u’s function definition.

function u(a,b){a=a.split('.');var c=r;a[0]in c||!c.execScript||c.execScript('var '+a[0]);for(var d;a.length&&(d=a.shift());)a.length||void 0===b?c=c[d]&&c[d]!==Object.prototype[d]?c[d]:c[d]={}:c[d]=b}

It’s also run on no-externs functions, e.g.

u('org.apache.royale.core.ElementWrapper.converterMap',I.converterMap)




From: Alex Harui <ah...@adobe.com.INVALID>
Sent: Sunday, May 31, 2020 6:41:50 PM
To: dev@royale.apache.org <de...@royale.apache.org>
Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

I won't have time to set this up for a while.  What is the unminified JS for "u('dialogPolyfill',dialogPolyfill)"?

-Alex

On 5/31/20, 8:13 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:

    Here’s the minimal test case I came up with for demonstrating the problem.

    <?xml version="1.0" encoding="utf-8"?>
    <js:Application xmlns:fx="https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fns.adobe.com%2Fmxml%2F2009&amp;data=02%7C01%7Caharui%40adobe.com%7Cec801390b4cf4c871bf808d805752003%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265347898256902&amp;sdata=oH2k6NU1gkobR7kfjAIz9AdSUU%2FgFWymxx825V8FA%2Fs%3D&amp;reserved=0"
                    xmlns:js="library://ns.apache.org/royale/basic"
                    >
           <fx:Script>
                           <![CDATA[
                    private function dummy():void
                    {
                                    dialogPolyfill;
                    }
                           ]]>
           </fx:Script>
    </js:Application>

    Where dialogPolyfill is

    package
    {
                    /**
                    * @externs
                    */
                    COMPILE::JS
                    public class dialogPolyfill
                    {
                    /**
             * <inject_script>
             * var script = document.createElement("script");
             * script.setAttribute("src", "https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fdialog-polyfill%2F0.4.9%2Fdialog-polyfill.min.js&amp;data=02%7C01%7Caharui%40adobe.com%7Cec801390b4cf4c871bf808d805752003%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265347898256902&amp;sdata=c0hmaL92qAobKVMziFvF2cMBbXDkAbzF2%2BaQwDuls84%3D&amp;reserved=0");
             * document.head.appendChild(script)
             * </inject_script>
                    */
                                    public function dialogPolyfill(){}
                    }
    }

    In release I get a ‘ReferenceError: dialogPolyfill is not defined’

    u('dialogPolyfill',dialogPolyfill) of Examples.js, which is run before start()

    So in order to fix this scenario we would need Examples.js to wait for dialogPolyfill.min.js, not for start() to wait.

    From: Alex Harui<ma...@adobe.com.INVALID>
    Sent: Wednesday, May 20, 2020 8:09 PM
    To: dev@royale.apache.org<ma...@royale.apache.org>
    Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

    When I mentioned static initializers in my earlier post, it was about the timing of when some code would first access hljs.  Most externs will probably be first used from code that runs after application.start().  But if someone did:

    public static var HLJSClass:Class = hljs;

    Then that would fail before we can run application.start(), except that the compiler auto-converts static vars to lazy getters.

    However, the hljs usage is not wrapped, so there really aren't any static initializers to use, so it doesn’t matter if they are lazy or not.  I haven't looked at the other uses of inject_script, but if a class wraps the dependency, then it can implement its own waiting strategy unless the API has to be synchronous.  IOW, if I created a Highlighter class that used hljs internally, then if the "highlight" API returns a void, the wrapping implementation would load hljs.js and make the call when it is ready, which is essentially building in the façade you wrote.

    You could implement a map of injected scripts, but after thinking about it overnight, my first thought is to require that folks publish a var or uid as follows:

             * <inject_script var="hljs_loaded">
                    * var scriptLoaded = function() { hljs_loaded = true) };
                    * var script = document.createElement("script");
                    * script.setAttribute("src", "https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fhighlight.js%2F9.12.0%2Fhighlight.min.js&amp;data=02%7C01%7Caharui%40adobe.com%7Cec801390b4cf4c871bf808d805752003%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265347898256902&amp;sdata=Nh9vUvssX%2Bnwqo3RYhecC0DSwG3ohSGfGGN1NH0LF6M%3D&amp;reserved=0");
                    * script.addEventListener("load", scriptLoaded);
                    * document.head.appendChild(script);
                * </inject_script>

    Then the compiler may not need so much as a map, but can gather a list of variables to watch for in the setInterval before calling application.start();

    Of course, I could be wrong...
    -Alex

    On 5/20/20, 12:19 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:

        Several questions/comments:


          1.  When you say static initializers should be lazy, do you mean load on the first lib api call? If so, wouldn’t that force async calls?
          2.  Do you have a way of using static initializers for externs files, which is how hljs was originally used?
          3.  To generate the script that waits for dynamically loaded scripts (I guess we don’t mind async css, though I’m not sure) we would need to have a map of injected scripts. So it looks like we’ll need to parse the injected_sctipt tag in any case.

        Thanks.



        From: Alex Harui<ma...@adobe.com.INVALID>
        Sent: Wednesday, May 20, 2020 9:52 AM
        To: dev@royale.apache.org<ma...@royale.apache.org>
        Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

        OK, I looked at the commit for hljs, and the code it replaced.  AFAICT, that is an instantiation phase dependency and not a initialization phase dependency, so it should not matter if it loads before or after app.js (unless someone does use it in a non-lazy static initializer, which should be hard to do in Royale).  It should only matter that it is loaded before anybody calls it.  Other than static initializers, which should all be lazy, nobody should really call hljs until after the application.start() is called in the index.html.

        Here is the index.html for HelloWorld:
        <html>
        <head>
                <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
                <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
                <link rel="stylesheet" type="text/css" href="HelloWorld.min.css">
                <script type="text/javascript" src="./HelloWorld.js"></script>
        </head>
        <body>
                <script type="text/javascript">
                        new HelloWorld().start();
                </script>
        </body>

        IMO, for applications that use inject_script (modules will use the _deps file), we should generate code before the start() call that waits for any dynamic scripts to load.  So if HelloWorld needed hljs, the index.html would look more like:

        <head>
                <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
                <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
                <link rel="stylesheet" type="text/css" href="HelloWorld.min.css">
                <script type="text/javascript" src="https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fhighlight.js%2F9.12.0%2Fhighlight.min.js&amp;data=02%7C01%7Caharui%40adobe.com%7Cec801390b4cf4c871bf808d805752003%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265347898256902&amp;sdata=Nh9vUvssX%2Bnwqo3RYhecC0DSwG3ohSGfGGN1NH0LF6M%3D&amp;reserved=0"
                                onload="highlight.min.js.loaded=true;"></script>
                <script type="text/javascript" src="./HelloWorld.js"></script>
        </head>
        <body>
                <script type="text/javascript">
                        var appInterval = setInterval(function() { if (highlight.min.js.loaded) {
                                                                                                                  clearInterval(appInterval);
                                                                                                                  new HelloWorld().start();
                                                                                                            }, 200);
                </script>
        </body>

        Closure seems to use a hash of the URL instead of part of the URL to avoid collisions in case two different scripts are called main.js or something like that.  And there might be some better way than using setInterval, but the idea is to wait until the JS is loaded before calling start().

        HTH,
        -Alex

        On 5/19/20, 12:18 PM, "Yishay Weiss" <yi...@hotmail.com> wrote:

            See 99a8c8356573ff16b668f2d39a447355c673fee3

            Note that hljs is an externs file so I couldn’t implement static initializers there.

            There’s also a sort of a queue there for calls made before lib is loaded. I realize this doesn’t scale as a pattern, which is why I proposed to simplify annotations instead.

            It could be of course there’s a simpler solution I’m missing.

            From: Alex Harui<ma...@adobe.com.INVALID>
            Sent: Tuesday, May 19, 2020 10:03 PM
            To: dev@royale.apache.org<ma...@royale.apache.org>
            Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

            Yishay,

            I didn't think static initializers would require a façade or other fancy mechanism.  What kind of AS code ends up requiring this more complex solution?

            -Alex

            On 5/19/20, 10:34 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:

                Hi Carlos,

                Sorry for not responding earlier, I missed this post.

                I haven’t been able to replicate this in debug mode, so it’s interesting you’re seeing that.

                I agree the façade solution is a bit cumbersome, but it works and maybe it’s worth having it out there as an example of using static initializers instead of injected code.

                What do you think?

                From: Carlos Rovira<ma...@apache.org>
                Sent: Monday, May 18, 2020 7:34 PM
                To: Apache Royale Development<ma...@royale.apache.org>
                Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

                Hi Yishay,

                I'm confused. The problem I reported was this;

                ReferenceError: dialogPolyfill is not defined at
                /Users/carlosrovira/Dev/Royale/Source/royale-asjs/examples/jewel/TourDeJewel/target/javascript/bin/js-debug/App.js:10:1

                And just as I'm copying here I'm seeing that while I'm running
                "js-release", notice that the link refers to "js-debug", so I think there's
                some wrong path involved here

                I just updated with your latest change about hljs but I don't think we have
                a problems with it. A part from that I don't like the solution to make a
                Facade for a script, since that involves to create 2 classes instead of
                one. The solution should be just make 1 as3 file (instead of two) and that
                have the proper inject reference.

                Please can you revert the hljsFacade?

                thanks




                El lun., 18 may. 2020 a las 17:44, Yishay Weiss (<yi...@hotmail.com>)
                escribió:

                > Unless I missed something that’s what it’s doing right now after my fix.
                > I’ll try to explain the scenario as I see it (no modules).
                >
                > Suppose we have an app that compiles to the following html.
                >
                > <html>
                >                 <head>
                >                                 <script type="text/javascript">
                >                                                 var script =
                > document.createElement("script");
                >                                                 script.setAttribute("src",
                > "hljs.min.js");
                >
                > document.head.appendChild(script);
                >                                 </script>
                >                                 <script type=”text/JavaScript”
                > src=”App.js”></script>
                >                 </head>
                >                 <body></body>
                > </html>
                >
                > After the first script element is loaded, the dom will look like:
                >
                > <html>
                >                 <head>
                >                                 <script type="text/javascript">
                >                                                 var script =
                > document.createElement("script");
                >                                                 script.setAttribute("src",
                > "hljs.min.js");
                >
                > document.head.appendChild(script);
                >                                 </script>
                >                                 <script type=”text/JavaScript”
                > src=”hljs.min.js”></script>
                >                                 <script type=”text/JavaScript”
                > src=”App.js”></script>
                >                 </head>
                >                 <body></body>
                > </html>
                >
                > However, App.js will still be loaded before hljs.min.js because it was not
                > created dynamically. App.js will fail because it depends on hljs.
                >
                > From: Alex Harui<ma...@adobe.com.INVALID>
                > Sent: Monday, May 18, 2020 6:21 PM
                > To: dev@royale.apache.org<ma...@royale.apache.org>
                > Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
                >
                > I don't think we have to inject these scripts into the main .js file.  The
                > compiler knows when it is compiling the main app or a module.  When
                > compiling the main app, it should inject the script in the HEAD of the html
                > wrapper.  For modules, it can inject the script into a separate file.  The
                > ModuleLoader already loads extra files before loading the module.  It can
                > load one more file.
                >
                > Of course, I could be wrong...
                > -Alex
                >
                > On 5/18/20, 7:38 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
                >
                >     From what I’ve read [1] scripts injected dynamically will always load
                > after static script elements. So I don’t think there’s a good way to ensure
                > the proper order in run-time unless we do something like
                > 99a8c8356573ff16b668f2d39a447355c673fee3 , but that’s verbose and working
                > with libs should be simple.
                >
                >     Any ideas?
                >
                >     [1]
                > https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.html5rocks.com%2Fen%2Ftutorials%2Fspeed%2Fscript-loading%2F%23disqus_thread&amp;data=02%7C01%7Caharui%40adobe.com%7Cec801390b4cf4c871bf808d805752003%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265347898256902&amp;sdata=vjy8naUvGHBq3Yk3P45nJbnh8BmoT337jsFMtUbgYA4%3D&amp;reserved=0
                >
                >     From: Alex Harui<ma...@adobe.com.INVALID>
                >     Sent: Monday, May 18, 2020 8:03 AM
                >     To: dev@royale.apache.org<ma...@royale.apache.org>
                >
                >
                >     Subject: Re: Script Loading Order (Continuing Heads-Up thread from
                > Users)
                >
                >     Every time I look, closure seems to change how it works.  It looks
                > like they are using callbacks and UIDs.  I assume they can't use await or
                > Promise because of IE support.  I haven't looked at the code you generate,
                > but might have to do something similar, IOW, wait for the callback or known
                > value before continuing.
                >
                >     I think that if we create the script during the running of another
                > script that we have to find a way to wait for that created script.
                >
                >     It might help to know what kind of initialization code needed the
                > definition so early.  One alternative is that such code needs to be
                > responsible for waiting.
                >
                >     Most of our Application classes have a wait mechanism.  We could
                > leverage that, but that's also pretty late.
                >
                >     It could be that for Applications we generate the script in the head,
                > and for modules we generate a separate script that is preloaded.
                >
                >     HTH,
                >     -Alex
                >
                >     On 5/17/20, 9:03 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
                >
                >
                >         >Is the script tag from inject_script going before or after the
                > script tag for the application (should be before, >IMO)?
                >
                >         It’s going before but the network shows it’s loaded after.
                >
                >         >Make sure the script tag has the same settings as the script tags
                > google closure uses in js-debug.  I think they set some options so the
                > scripts load in order.
                >
                >         I see type being specified in the gcl script elements, while
                > inject ones don’t. I suppose it’s worth seeing if that makes a difference,
                > though I couldn’t find evidence for that on the web.
                >
                >
                >
                >
                >

                --
                Carlos Rovira
                https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fabout.me%2Fcarlosrovira&amp;data=02%7C01%7Caharui%40adobe.com%7Cec801390b4cf4c871bf808d805752003%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265347898256902&amp;sdata=0CBDia%2F8dmS%2BxW6WyKTmg6KsalMdCub2J9HuADqNyKE%3D&amp;reserved=0








From: Alex Harui<ma...@adobe.com.INVALID>
Sent: Sunday, May 31, 2020 6:42 PM
To: dev@royale.apache.org<ma...@royale.apache.org>
Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

I won't have time to set this up for a while.  What is the unminified JS for "u('dialogPolyfill',dialogPolyfill)"?

-Alex

On 5/31/20, 8:13 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:

    Here’s the minimal test case I came up with for demonstrating the problem.

    <?xml version="1.0" encoding="utf-8"?>
    <js:Application xmlns:fx="https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fns.adobe.com%2Fmxml%2F2009&amp;data=02%7C01%7Caharui%40adobe.com%7Cec801390b4cf4c871bf808d805752003%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265347898256902&amp;sdata=oH2k6NU1gkobR7kfjAIz9AdSUU%2FgFWymxx825V8FA%2Fs%3D&amp;reserved=0"
                    xmlns:js="library://ns.apache.org/royale/basic"
                    >
           <fx:Script>
                           <![CDATA[
                    private function dummy():void
                    {
                                    dialogPolyfill;
                    }
                           ]]>
           </fx:Script>
    </js:Application>

    Where dialogPolyfill is

    package
    {
                    /**
                    * @externs
                    */
                    COMPILE::JS
                    public class dialogPolyfill
                    {
                    /**
             * <inject_script>
             * var script = document.createElement("script");
             * script.setAttribute("src", "https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fdialog-polyfill%2F0.4.9%2Fdialog-polyfill.min.js&amp;data=02%7C01%7Caharui%40adobe.com%7Cec801390b4cf4c871bf808d805752003%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265347898256902&amp;sdata=c0hmaL92qAobKVMziFvF2cMBbXDkAbzF2%2BaQwDuls84%3D&amp;reserved=0");
             * document.head.appendChild(script)
             * </inject_script>
                    */
                                    public function dialogPolyfill(){}
                    }
    }

    In release I get a ‘ReferenceError: dialogPolyfill is not defined’

    u('dialogPolyfill',dialogPolyfill) of Examples.js, which is run before start()

    So in order to fix this scenario we would need Examples.js to wait for dialogPolyfill.min.js, not for start() to wait.

    From: Alex Harui<ma...@adobe.com.INVALID>
    Sent: Wednesday, May 20, 2020 8:09 PM
    To: dev@royale.apache.org<ma...@royale.apache.org>
    Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

    When I mentioned static initializers in my earlier post, it was about the timing of when some code would first access hljs.  Most externs will probably be first used from code that runs after application.start().  But if someone did:

    public static var HLJSClass:Class = hljs;

    Then that would fail before we can run application.start(), except that the compiler auto-converts static vars to lazy getters.

    However, the hljs usage is not wrapped, so there really aren't any static initializers to use, so it doesn’t matter if they are lazy or not.  I haven't looked at the other uses of inject_script, but if a class wraps the dependency, then it can implement its own waiting strategy unless the API has to be synchronous.  IOW, if I created a Highlighter class that used hljs internally, then if the "highlight" API returns a void, the wrapping implementation would load hljs.js and make the call when it is ready, which is essentially building in the façade you wrote.

    You could implement a map of injected scripts, but after thinking about it overnight, my first thought is to require that folks publish a var or uid as follows:

             * <inject_script var="hljs_loaded">
                    * var scriptLoaded = function() { hljs_loaded = true) };
                    * var script = document.createElement("script");
                    * script.setAttribute("src", "https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fhighlight.js%2F9.12.0%2Fhighlight.min.js&amp;data=02%7C01%7Caharui%40adobe.com%7Cec801390b4cf4c871bf808d805752003%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265347898256902&amp;sdata=Nh9vUvssX%2Bnwqo3RYhecC0DSwG3ohSGfGGN1NH0LF6M%3D&amp;reserved=0");
                    * script.addEventListener("load", scriptLoaded);
                    * document.head.appendChild(script);
                * </inject_script>

    Then the compiler may not need so much as a map, but can gather a list of variables to watch for in the setInterval before calling application.start();

    Of course, I could be wrong...
    -Alex

    On 5/20/20, 12:19 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:

        Several questions/comments:


          1.  When you say static initializers should be lazy, do you mean load on the first lib api call? If so, wouldn’t that force async calls?
          2.  Do you have a way of using static initializers for externs files, which is how hljs was originally used?
          3.  To generate the script that waits for dynamically loaded scripts (I guess we don’t mind async css, though I’m not sure) we would need to have a map of injected scripts. So it looks like we’ll need to parse the injected_sctipt tag in any case.

        Thanks.



        From: Alex Harui<ma...@adobe.com.INVALID>
        Sent: Wednesday, May 20, 2020 9:52 AM
        To: dev@royale.apache.org<ma...@royale.apache.org>
        Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

        OK, I looked at the commit for hljs, and the code it replaced.  AFAICT, that is an instantiation phase dependency and not a initialization phase dependency, so it should not matter if it loads before or after app.js (unless someone does use it in a non-lazy static initializer, which should be hard to do in Royale).  It should only matter that it is loaded before anybody calls it.  Other than static initializers, which should all be lazy, nobody should really call hljs until after the application.start() is called in the index.html.

        Here is the index.html for HelloWorld:
        <html>
        <head>
                <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
                <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
                <link rel="stylesheet" type="text/css" href="HelloWorld.min.css">
                <script type="text/javascript" src="./HelloWorld.js"></script>
        </head>
        <body>
                <script type="text/javascript">
                        new HelloWorld().start();
                </script>
        </body>

        IMO, for applications that use inject_script (modules will use the _deps file), we should generate code before the start() call that waits for any dynamic scripts to load.  So if HelloWorld needed hljs, the index.html would look more like:

        <head>
                <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
                <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
                <link rel="stylesheet" type="text/css" href="HelloWorld.min.css">
                <script type="text/javascript" src="https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fhighlight.js%2F9.12.0%2Fhighlight.min.js&amp;data=02%7C01%7Caharui%40adobe.com%7Cec801390b4cf4c871bf808d805752003%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265347898256902&amp;sdata=Nh9vUvssX%2Bnwqo3RYhecC0DSwG3ohSGfGGN1NH0LF6M%3D&amp;reserved=0"
                                onload="highlight.min.js.loaded=true;"></script>
                <script type="text/javascript" src="./HelloWorld.js"></script>
        </head>
        <body>
                <script type="text/javascript">
                        var appInterval = setInterval(function() { if (highlight.min.js.loaded) {
                                                                                                                  clearInterval(appInterval);
                                                                                                                  new HelloWorld().start();
                                                                                                            }, 200);
                </script>
        </body>

        Closure seems to use a hash of the URL instead of part of the URL to avoid collisions in case two different scripts are called main.js or something like that.  And there might be some better way than using setInterval, but the idea is to wait until the JS is loaded before calling start().

        HTH,
        -Alex

        On 5/19/20, 12:18 PM, "Yishay Weiss" <yi...@hotmail.com> wrote:

            See 99a8c8356573ff16b668f2d39a447355c673fee3

            Note that hljs is an externs file so I couldn’t implement static initializers there.

            There’s also a sort of a queue there for calls made before lib is loaded. I realize this doesn’t scale as a pattern, which is why I proposed to simplify annotations instead.

            It could be of course there’s a simpler solution I’m missing.

            From: Alex Harui<ma...@adobe.com.INVALID>
            Sent: Tuesday, May 19, 2020 10:03 PM
            To: dev@royale.apache.org<ma...@royale.apache.org>
            Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

            Yishay,

            I didn't think static initializers would require a façade or other fancy mechanism.  What kind of AS code ends up requiring this more complex solution?

            -Alex

            On 5/19/20, 10:34 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:

                Hi Carlos,

                Sorry for not responding earlier, I missed this post.

                I haven’t been able to replicate this in debug mode, so it’s interesting you’re seeing that.

                I agree the façade solution is a bit cumbersome, but it works and maybe it’s worth having it out there as an example of using static initializers instead of injected code.

                What do you think?

                From: Carlos Rovira<ma...@apache.org>
                Sent: Monday, May 18, 2020 7:34 PM
                To: Apache Royale Development<ma...@royale.apache.org>
                Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

                Hi Yishay,

                I'm confused. The problem I reported was this;

                ReferenceError: dialogPolyfill is not defined at
                /Users/carlosrovira/Dev/Royale/Source/royale-asjs/examples/jewel/TourDeJewel/target/javascript/bin/js-debug/App.js:10:1

                And just as I'm copying here I'm seeing that while I'm running
                "js-release", notice that the link refers to "js-debug", so I think there's
                some wrong path involved here

                I just updated with your latest change about hljs but I don't think we have
                a problems with it. A part from that I don't like the solution to make a
                Facade for a script, since that involves to create 2 classes instead of
                one. The solution should be just make 1 as3 file (instead of two) and that
                have the proper inject reference.

                Please can you revert the hljsFacade?

                thanks




                El lun., 18 may. 2020 a las 17:44, Yishay Weiss (<yi...@hotmail.com>)
                escribió:

                > Unless I missed something that’s what it’s doing right now after my fix.
                > I’ll try to explain the scenario as I see it (no modules).
                >
                > Suppose we have an app that compiles to the following html.
                >
                > <html>
                >                 <head>
                >                                 <script type="text/javascript">
                >                                                 var script =
                > document.createElement("script");
                >                                                 script.setAttribute("src",
                > "hljs.min.js");
                >
                > document.head.appendChild(script);
                >                                 </script>
                >                                 <script type=”text/JavaScript”
                > src=”App.js”></script>
                >                 </head>
                >                 <body></body>
                > </html>
                >
                > After the first script element is loaded, the dom will look like:
                >
                > <html>
                >                 <head>
                >                                 <script type="text/javascript">
                >                                                 var script =
                > document.createElement("script");
                >                                                 script.setAttribute("src",
                > "hljs.min.js");
                >
                > document.head.appendChild(script);
                >                                 </script>
                >                                 <script type=”text/JavaScript”
                > src=”hljs.min.js”></script>
                >                                 <script type=”text/JavaScript”
                > src=”App.js”></script>
                >                 </head>
                >                 <body></body>
                > </html>
                >
                > However, App.js will still be loaded before hljs.min.js because it was not
                > created dynamically. App.js will fail because it depends on hljs.
                >
                > From: Alex Harui<ma...@adobe.com.INVALID>
                > Sent: Monday, May 18, 2020 6:21 PM
                > To: dev@royale.apache.org<ma...@royale.apache.org>
                > Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
                >
                > I don't think we have to inject these scripts into the main .js file.  The
                > compiler knows when it is compiling the main app or a module.  When
                > compiling the main app, it should inject the script in the HEAD of the html
                > wrapper.  For modules, it can inject the script into a separate file.  The
                > ModuleLoader already loads extra files before loading the module.  It can
                > load one more file.
                >
                > Of course, I could be wrong...
                > -Alex
                >
                > On 5/18/20, 7:38 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
                >
                >     From what I’ve read [1] scripts injected dynamically will always load
                > after static script elements. So I don’t think there’s a good way to ensure
                > the proper order in run-time unless we do something like
                > 99a8c8356573ff16b668f2d39a447355c673fee3 , but that’s verbose and working
                > with libs should be simple.
                >
                >     Any ideas?
                >
                >     [1]
                > https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.html5rocks.com%2Fen%2Ftutorials%2Fspeed%2Fscript-loading%2F%23disqus_thread&amp;data=02%7C01%7Caharui%40adobe.com%7Cec801390b4cf4c871bf808d805752003%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265347898256902&amp;sdata=vjy8naUvGHBq3Yk3P45nJbnh8BmoT337jsFMtUbgYA4%3D&amp;reserved=0
                >
                >     From: Alex Harui<ma...@adobe.com.INVALID>
                >     Sent: Monday, May 18, 2020 8:03 AM
                >     To: dev@royale.apache.org<ma...@royale.apache.org>
                >
                >
                >     Subject: Re: Script Loading Order (Continuing Heads-Up thread from
                > Users)
                >
                >     Every time I look, closure seems to change how it works.  It looks
                > like they are using callbacks and UIDs.  I assume they can't use await or
                > Promise because of IE support.  I haven't looked at the code you generate,
                > but might have to do something similar, IOW, wait for the callback or known
                > value before continuing.
                >
                >     I think that if we create the script during the running of another
                > script that we have to find a way to wait for that created script.
                >
                >     It might help to know what kind of initialization code needed the
                > definition so early.  One alternative is that such code needs to be
                > responsible for waiting.
                >
                >     Most of our Application classes have a wait mechanism.  We could
                > leverage that, but that's also pretty late.
                >
                >     It could be that for Applications we generate the script in the head,
                > and for modules we generate a separate script that is preloaded.
                >
                >     HTH,
                >     -Alex
                >
                >     On 5/17/20, 9:03 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
                >
                >
                >         >Is the script tag from inject_script going before or after the
                > script tag for the application (should be before, >IMO)?
                >
                >         It’s going before but the network shows it’s loaded after.
                >
                >         >Make sure the script tag has the same settings as the script tags
                > google closure uses in js-debug.  I think they set some options so the
                > scripts load in order.
                >
                >         I see type being specified in the gcl script elements, while
                > inject ones don’t. I suppose it’s worth seeing if that makes a difference,
                > though I couldn’t find evidence for that on the web.
                >
                >
                >
                >
                >

                --
                Carlos Rovira
                https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fabout.me%2Fcarlosrovira&amp;data=02%7C01%7Caharui%40adobe.com%7Cec801390b4cf4c871bf808d805752003%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265347898256902&amp;sdata=0CBDia%2F8dmS%2BxW6WyKTmg6KsalMdCub2J9HuADqNyKE%3D&amp;reserved=0










Re: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Alex Harui <ah...@adobe.com.INVALID>.
I won't have time to set this up for a while.  What is the unminified JS for "u('dialogPolyfill',dialogPolyfill)"?

-Alex

On 5/31/20, 8:13 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:

    Here’s the minimal test case I came up with for demonstrating the problem.
    
    <?xml version="1.0" encoding="utf-8"?>
    <js:Application xmlns:fx="https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fns.adobe.com%2Fmxml%2F2009&amp;data=02%7C01%7Caharui%40adobe.com%7Cec801390b4cf4c871bf808d805752003%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265347898256902&amp;sdata=oH2k6NU1gkobR7kfjAIz9AdSUU%2FgFWymxx825V8FA%2Fs%3D&amp;reserved=0"
                    xmlns:js="library://ns.apache.org/royale/basic"
                    >
           <fx:Script>
                           <![CDATA[
                    private function dummy():void
                    {
                                    dialogPolyfill;
                    }
                           ]]>
           </fx:Script>
    </js:Application>
    
    Where dialogPolyfill is
    
    package
    {
                    /**
                    * @externs
                    */
                    COMPILE::JS
                    public class dialogPolyfill
                    {
                    /**
             * <inject_script>
             * var script = document.createElement("script");
             * script.setAttribute("src", "https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fdialog-polyfill%2F0.4.9%2Fdialog-polyfill.min.js&amp;data=02%7C01%7Caharui%40adobe.com%7Cec801390b4cf4c871bf808d805752003%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265347898256902&amp;sdata=c0hmaL92qAobKVMziFvF2cMBbXDkAbzF2%2BaQwDuls84%3D&amp;reserved=0");
             * document.head.appendChild(script)
             * </inject_script>
                    */
                                    public function dialogPolyfill(){}
                    }
    }
    
    In release I get a ‘ReferenceError: dialogPolyfill is not defined’
    
    u('dialogPolyfill',dialogPolyfill) of Examples.js, which is run before start()
    
    So in order to fix this scenario we would need Examples.js to wait for dialogPolyfill.min.js, not for start() to wait.
    
    From: Alex Harui<ma...@adobe.com.INVALID>
    Sent: Wednesday, May 20, 2020 8:09 PM
    To: dev@royale.apache.org<ma...@royale.apache.org>
    Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
    
    When I mentioned static initializers in my earlier post, it was about the timing of when some code would first access hljs.  Most externs will probably be first used from code that runs after application.start().  But if someone did:
    
    public static var HLJSClass:Class = hljs;
    
    Then that would fail before we can run application.start(), except that the compiler auto-converts static vars to lazy getters.
    
    However, the hljs usage is not wrapped, so there really aren't any static initializers to use, so it doesn’t matter if they are lazy or not.  I haven't looked at the other uses of inject_script, but if a class wraps the dependency, then it can implement its own waiting strategy unless the API has to be synchronous.  IOW, if I created a Highlighter class that used hljs internally, then if the "highlight" API returns a void, the wrapping implementation would load hljs.js and make the call when it is ready, which is essentially building in the façade you wrote.
    
    You could implement a map of injected scripts, but after thinking about it overnight, my first thought is to require that folks publish a var or uid as follows:
    
             * <inject_script var="hljs_loaded">
                    * var scriptLoaded = function() { hljs_loaded = true) };
                    * var script = document.createElement("script");
                    * script.setAttribute("src", "https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fhighlight.js%2F9.12.0%2Fhighlight.min.js&amp;data=02%7C01%7Caharui%40adobe.com%7Cec801390b4cf4c871bf808d805752003%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265347898256902&amp;sdata=Nh9vUvssX%2Bnwqo3RYhecC0DSwG3ohSGfGGN1NH0LF6M%3D&amp;reserved=0");
                    * script.addEventListener("load", scriptLoaded);
                    * document.head.appendChild(script);
                * </inject_script>
    
    Then the compiler may not need so much as a map, but can gather a list of variables to watch for in the setInterval before calling application.start();
    
    Of course, I could be wrong...
    -Alex
    
    On 5/20/20, 12:19 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
    
        Several questions/comments:
    
    
          1.  When you say static initializers should be lazy, do you mean load on the first lib api call? If so, wouldn’t that force async calls?
          2.  Do you have a way of using static initializers for externs files, which is how hljs was originally used?
          3.  To generate the script that waits for dynamically loaded scripts (I guess we don’t mind async css, though I’m not sure) we would need to have a map of injected scripts. So it looks like we’ll need to parse the injected_sctipt tag in any case.
    
        Thanks.
    
    
    
        From: Alex Harui<ma...@adobe.com.INVALID>
        Sent: Wednesday, May 20, 2020 9:52 AM
        To: dev@royale.apache.org<ma...@royale.apache.org>
        Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
    
        OK, I looked at the commit for hljs, and the code it replaced.  AFAICT, that is an instantiation phase dependency and not a initialization phase dependency, so it should not matter if it loads before or after app.js (unless someone does use it in a non-lazy static initializer, which should be hard to do in Royale).  It should only matter that it is loaded before anybody calls it.  Other than static initializers, which should all be lazy, nobody should really call hljs until after the application.start() is called in the index.html.
    
        Here is the index.html for HelloWorld:
        <html>
        <head>
                <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
                <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
                <link rel="stylesheet" type="text/css" href="HelloWorld.min.css">
                <script type="text/javascript" src="./HelloWorld.js"></script>
        </head>
        <body>
                <script type="text/javascript">
                        new HelloWorld().start();
                </script>
        </body>
    
        IMO, for applications that use inject_script (modules will use the _deps file), we should generate code before the start() call that waits for any dynamic scripts to load.  So if HelloWorld needed hljs, the index.html would look more like:
    
        <head>
                <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
                <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
                <link rel="stylesheet" type="text/css" href="HelloWorld.min.css">
                <script type="text/javascript" src="https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fhighlight.js%2F9.12.0%2Fhighlight.min.js&amp;data=02%7C01%7Caharui%40adobe.com%7Cec801390b4cf4c871bf808d805752003%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265347898256902&amp;sdata=Nh9vUvssX%2Bnwqo3RYhecC0DSwG3ohSGfGGN1NH0LF6M%3D&amp;reserved=0"
                                onload="highlight.min.js.loaded=true;"></script>
                <script type="text/javascript" src="./HelloWorld.js"></script>
        </head>
        <body>
                <script type="text/javascript">
                        var appInterval = setInterval(function() { if (highlight.min.js.loaded) {
                                                                                                                  clearInterval(appInterval);
                                                                                                                  new HelloWorld().start();
                                                                                                            }, 200);
                </script>
        </body>
    
        Closure seems to use a hash of the URL instead of part of the URL to avoid collisions in case two different scripts are called main.js or something like that.  And there might be some better way than using setInterval, but the idea is to wait until the JS is loaded before calling start().
    
        HTH,
        -Alex
    
        On 5/19/20, 12:18 PM, "Yishay Weiss" <yi...@hotmail.com> wrote:
    
            See 99a8c8356573ff16b668f2d39a447355c673fee3
    
            Note that hljs is an externs file so I couldn’t implement static initializers there.
    
            There’s also a sort of a queue there for calls made before lib is loaded. I realize this doesn’t scale as a pattern, which is why I proposed to simplify annotations instead.
    
            It could be of course there’s a simpler solution I’m missing.
    
            From: Alex Harui<ma...@adobe.com.INVALID>
            Sent: Tuesday, May 19, 2020 10:03 PM
            To: dev@royale.apache.org<ma...@royale.apache.org>
            Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
    
            Yishay,
    
            I didn't think static initializers would require a façade or other fancy mechanism.  What kind of AS code ends up requiring this more complex solution?
    
            -Alex
    
            On 5/19/20, 10:34 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
    
                Hi Carlos,
    
                Sorry for not responding earlier, I missed this post.
    
                I haven’t been able to replicate this in debug mode, so it’s interesting you’re seeing that.
    
                I agree the façade solution is a bit cumbersome, but it works and maybe it’s worth having it out there as an example of using static initializers instead of injected code.
    
                What do you think?
    
                From: Carlos Rovira<ma...@apache.org>
                Sent: Monday, May 18, 2020 7:34 PM
                To: Apache Royale Development<ma...@royale.apache.org>
                Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
    
                Hi Yishay,
    
                I'm confused. The problem I reported was this;
    
                ReferenceError: dialogPolyfill is not defined at
                /Users/carlosrovira/Dev/Royale/Source/royale-asjs/examples/jewel/TourDeJewel/target/javascript/bin/js-debug/App.js:10:1
    
                And just as I'm copying here I'm seeing that while I'm running
                "js-release", notice that the link refers to "js-debug", so I think there's
                some wrong path involved here
    
                I just updated with your latest change about hljs but I don't think we have
                a problems with it. A part from that I don't like the solution to make a
                Facade for a script, since that involves to create 2 classes instead of
                one. The solution should be just make 1 as3 file (instead of two) and that
                have the proper inject reference.
    
                Please can you revert the hljsFacade?
    
                thanks
    
    
    
    
                El lun., 18 may. 2020 a las 17:44, Yishay Weiss (<yi...@hotmail.com>)
                escribió:
    
                > Unless I missed something that’s what it’s doing right now after my fix.
                > I’ll try to explain the scenario as I see it (no modules).
                >
                > Suppose we have an app that compiles to the following html.
                >
                > <html>
                >                 <head>
                >                                 <script type="text/javascript">
                >                                                 var script =
                > document.createElement("script");
                >                                                 script.setAttribute("src",
                > "hljs.min.js");
                >
                > document.head.appendChild(script);
                >                                 </script>
                >                                 <script type=”text/JavaScript”
                > src=”App.js”></script>
                >                 </head>
                >                 <body></body>
                > </html>
                >
                > After the first script element is loaded, the dom will look like:
                >
                > <html>
                >                 <head>
                >                                 <script type="text/javascript">
                >                                                 var script =
                > document.createElement("script");
                >                                                 script.setAttribute("src",
                > "hljs.min.js");
                >
                > document.head.appendChild(script);
                >                                 </script>
                >                                 <script type=”text/JavaScript”
                > src=”hljs.min.js”></script>
                >                                 <script type=”text/JavaScript”
                > src=”App.js”></script>
                >                 </head>
                >                 <body></body>
                > </html>
                >
                > However, App.js will still be loaded before hljs.min.js because it was not
                > created dynamically. App.js will fail because it depends on hljs.
                >
                > From: Alex Harui<ma...@adobe.com.INVALID>
                > Sent: Monday, May 18, 2020 6:21 PM
                > To: dev@royale.apache.org<ma...@royale.apache.org>
                > Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
                >
                > I don't think we have to inject these scripts into the main .js file.  The
                > compiler knows when it is compiling the main app or a module.  When
                > compiling the main app, it should inject the script in the HEAD of the html
                > wrapper.  For modules, it can inject the script into a separate file.  The
                > ModuleLoader already loads extra files before loading the module.  It can
                > load one more file.
                >
                > Of course, I could be wrong...
                > -Alex
                >
                > On 5/18/20, 7:38 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
                >
                >     From what I’ve read [1] scripts injected dynamically will always load
                > after static script elements. So I don’t think there’s a good way to ensure
                > the proper order in run-time unless we do something like
                > 99a8c8356573ff16b668f2d39a447355c673fee3 , but that’s verbose and working
                > with libs should be simple.
                >
                >     Any ideas?
                >
                >     [1]
                > https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.html5rocks.com%2Fen%2Ftutorials%2Fspeed%2Fscript-loading%2F%23disqus_thread&amp;data=02%7C01%7Caharui%40adobe.com%7Cec801390b4cf4c871bf808d805752003%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265347898256902&amp;sdata=vjy8naUvGHBq3Yk3P45nJbnh8BmoT337jsFMtUbgYA4%3D&amp;reserved=0
                >
                >     From: Alex Harui<ma...@adobe.com.INVALID>
                >     Sent: Monday, May 18, 2020 8:03 AM
                >     To: dev@royale.apache.org<ma...@royale.apache.org>
                >
                >
                >     Subject: Re: Script Loading Order (Continuing Heads-Up thread from
                > Users)
                >
                >     Every time I look, closure seems to change how it works.  It looks
                > like they are using callbacks and UIDs.  I assume they can't use await or
                > Promise because of IE support.  I haven't looked at the code you generate,
                > but might have to do something similar, IOW, wait for the callback or known
                > value before continuing.
                >
                >     I think that if we create the script during the running of another
                > script that we have to find a way to wait for that created script.
                >
                >     It might help to know what kind of initialization code needed the
                > definition so early.  One alternative is that such code needs to be
                > responsible for waiting.
                >
                >     Most of our Application classes have a wait mechanism.  We could
                > leverage that, but that's also pretty late.
                >
                >     It could be that for Applications we generate the script in the head,
                > and for modules we generate a separate script that is preloaded.
                >
                >     HTH,
                >     -Alex
                >
                >     On 5/17/20, 9:03 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
                >
                >
                >         >Is the script tag from inject_script going before or after the
                > script tag for the application (should be before, >IMO)?
                >
                >         It’s going before but the network shows it’s loaded after.
                >
                >         >Make sure the script tag has the same settings as the script tags
                > google closure uses in js-debug.  I think they set some options so the
                > scripts load in order.
                >
                >         I see type being specified in the gcl script elements, while
                > inject ones don’t. I suppose it’s worth seeing if that makes a difference,
                > though I couldn’t find evidence for that on the web.
                >
                >
                >
                >
                >
    
                --
                Carlos Rovira
                https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fabout.me%2Fcarlosrovira&amp;data=02%7C01%7Caharui%40adobe.com%7Cec801390b4cf4c871bf808d805752003%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265347898256902&amp;sdata=0CBDia%2F8dmS%2BxW6WyKTmg6KsalMdCub2J9HuADqNyKE%3D&amp;reserved=0
    
    
    
    
    
    
    
    


Re: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Josh Tynjala <jo...@bowlerhat.dev>.
Yes, that's right.

And in other cases, externs need to be treated similarly to classes added
to the external-library-path, even if they are on the source-path.

--
Josh Tynjala
Bowler Hat LLC <https://bowlerhat.dev>


On Mon, Jun 1, 2020 at 12:02 AM Alex Harui <ah...@adobe.com.invalid> wrote:

> AIUI, in this particular case, externs should not have @export or
> exportSymbol calls.  The 'u' function is exportSymbol.
>
> Of course, I could be wrong,
> -Alex
>
> On 5/31/20, 11:44 PM, "Yishay Weiss" <yi...@hotmail.com> wrote:
>
>     Good, thanks. Out of curiosity, what special handling do externs need?
>
>     From: Josh Tynjala<ma...@bowlerhat.dev>
>     Sent: Monday, June 1, 2020 2:01 AM
>     To: Apache Royale Development<ma...@royale.apache.org>
>     Subject: Re: Script Loading Order (Continuing Heads-Up thread from
> Users)
>
>     This appears to be related to my export/rename refactoring. As Alex
>     mentioned, externs need special handling, and I was treating them like
>     regular symbols. I should be able to get that fixed this week.
>
>     --
>     Josh Tynjala
>     Bowler Hat LLC <
> https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbowlerhat.dev%2F&amp;data=02%7C01%7Caharui%40adobe.com%7C161a52e6f1e743d8046a08d805f745e1%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265906882631155&amp;sdata=XaR6WYJSBgMUQfWQDc3wOD2TXSi1QqjpP1%2FcljV3IUc%3D&amp;reserved=0
> >
>
>
>     On Sun, May 31, 2020 at 8:13 AM Yishay Weiss <yi...@hotmail.com>
> wrote:
>
>     > Here’s the minimal test case I came up with for demonstrating the
> problem.
>     >
>     > <?xml version="1.0" encoding="utf-8"?>
>     > <js:Application xmlns:fx="
> https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fns.adobe.com%2Fmxml%2F2009&amp;data=02%7C01%7Caharui%40adobe.com%7C161a52e6f1e743d8046a08d805f745e1%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265906882631155&amp;sdata=wkyh88Lwwhzu8%2BNcM6RMODIUfBF0vWlkFNUm6Mx8Wjs%3D&amp;reserved=0
> "
>     >                 xmlns:js="library://ns.apache.org/royale/basic"
>     >                 >
>     >        <fx:Script>
>     >                        <![CDATA[
>     >                 private function dummy():void
>     >                 {
>     >                                 dialogPolyfill;
>     >                 }
>     >                        ]]>
>     >        </fx:Script>
>     > </js:Application>
>     >
>     > Where dialogPolyfill is
>     >
>     > package
>     > {
>     >                 /**
>     >                 * @externs
>     >                 */
>     >                 COMPILE::JS
>     >                 public class dialogPolyfill
>     >                 {
>     >                 /**
>     >          * <inject_script>
>     >          * var script = document.createElement("script");
>     >          * script.setAttribute("src", "
>     >
> https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fdialog-polyfill%2F0.4.9%2Fdialog-polyfill.min.js&amp;data=02%7C01%7Caharui%40adobe.com%7C161a52e6f1e743d8046a08d805f745e1%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265906882631155&amp;sdata=aOqz6hScb3UxeTWM3XJ%2FTerQnGc6B8QEuJgKR0eO9f8%3D&amp;reserved=0
>     > ");
>     >          * document.head.appendChild(script)
>     >          * </inject_script>
>     >                 */
>     >                                 public function dialogPolyfill(){}
>     >                 }
>     > }
>     >
>     > In release I get a ‘ReferenceError: dialogPolyfill is not defined’
>     >
>     > u('dialogPolyfill',dialogPolyfill) of Examples.js, which is run
> before
>     > start()
>     >
>     > So in order to fix this scenario we would need Examples.js to wait
> for
>     > dialogPolyfill.min.js, not for start() to wait.
>     >
>     > From: Alex Harui<ma...@adobe.com.INVALID>
>     > Sent: Wednesday, May 20, 2020 8:09 PM
>     > To: dev@royale.apache.org<ma...@royale.apache.org>
>     > Subject: Re: Script Loading Order (Continuing Heads-Up thread from
> Users)
>     >
>     > When I mentioned static initializers in my earlier post, it was
> about the
>     > timing of when some code would first access hljs.  Most externs will
>     > probably be first used from code that runs after
> application.start().  But
>     > if someone did:
>     >
>     > public static var HLJSClass:Class = hljs;
>     >
>     > Then that would fail before we can run application.start(), except
> that
>     > the compiler auto-converts static vars to lazy getters.
>     >
>     > However, the hljs usage is not wrapped, so there really aren't any
> static
>     > initializers to use, so it doesn’t matter if they are lazy or not.  I
>     > haven't looked at the other uses of inject_script, but if a class
> wraps the
>     > dependency, then it can implement its own waiting strategy unless
> the API
>     > has to be synchronous.  IOW, if I created a Highlighter class that
> used
>     > hljs internally, then if the "highlight" API returns a void, the
> wrapping
>     > implementation would load hljs.js and make the call when it is
> ready, which
>     > is essentially building in the façade you wrote.
>     >
>     > You could implement a map of injected scripts, but after thinking
> about it
>     > overnight, my first thought is to require that folks publish a var
> or uid
>     > as follows:
>     >
>     >          * <inject_script var="hljs_loaded">
>     >                 * var scriptLoaded = function() { hljs_loaded =
> true) };
>     >                 * var script = document.createElement("script");
>     >                 * script.setAttribute("src", "
>     >
> https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fhighlight.js%2F9.12.0%2Fhighlight.min.js&amp;data=02%7C01%7Caharui%40adobe.com%7C161a52e6f1e743d8046a08d805f745e1%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265906882641150&amp;sdata=jRqEz2TAUdYDkRobaBUJHdAgxJ%2FajTNHNuaXyBhc0so%3D&amp;reserved=0
>     > ");
>     >                 * script.addEventListener("load", scriptLoaded);
>     >                 * document.head.appendChild(script);
>     >             * </inject_script>
>     >
>     > Then the compiler may not need so much as a map, but can gather a
> list of
>     > variables to watch for in the setInterval before calling
>     > application.start();
>     >
>     > Of course, I could be wrong...
>     > -Alex
>     >
>     > On 5/20/20, 12:19 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
>     >
>     >     Several questions/comments:
>     >
>     >
>     >       1.  When you say static initializers should be lazy, do you
> mean
>     > load on the first lib api call? If so, wouldn’t that force async
> calls?
>     >       2.  Do you have a way of using static initializers for externs
>     > files, which is how hljs was originally used?
>     >       3.  To generate the script that waits for dynamically loaded
> scripts
>     > (I guess we don’t mind async css, though I’m not sure) we would need
> to
>     > have a map of injected scripts. So it looks like we’ll need to parse
> the
>     > injected_sctipt tag in any case.
>     >
>     >     Thanks.
>     >
>     >
>     >
>     >     From: Alex Harui<ma...@adobe.com.INVALID>
>     >     Sent: Wednesday, May 20, 2020 9:52 AM
>     >     To: dev@royale.apache.org<ma...@royale.apache.org>
>     >     Subject: Re: Script Loading Order (Continuing Heads-Up thread
> from
>     > Users)
>     >
>     >     OK, I looked at the commit for hljs, and the code it replaced.
>     > AFAICT, that is an instantiation phase dependency and not a
> initialization
>     > phase dependency, so it should not matter if it loads before or after
>     > app.js (unless someone does use it in a non-lazy static initializer,
> which
>     > should be hard to do in Royale).  It should only matter that it is
> loaded
>     > before anybody calls it.  Other than static initializers, which
> should all
>     > be lazy, nobody should really call hljs until after the
> application.start()
>     > is called in the index.html.
>     >
>     >     Here is the index.html for HelloWorld:
>     >     <html>
>     >     <head>
>     >             <meta http-equiv="X-UA-Compatible"
> content="IE=edge,chrome=1">
>     >             <meta http-equiv="Content-Type" content="text/html;
>     > charset=utf-8">
>     >             <link rel="stylesheet" type="text/css"
>     > href="HelloWorld.min.css">
>     >             <script type="text/javascript"
> src="./HelloWorld.js"></script>
>     >     </head>
>     >     <body>
>     >             <script type="text/javascript">
>     >                     new HelloWorld().start();
>     >             </script>
>     >     </body>
>     >
>     >     IMO, for applications that use inject_script (modules will use
> the
>     > _deps file), we should generate code before the start() call that
> waits for
>     > any dynamic scripts to load.  So if HelloWorld needed hljs, the
> index.html
>     > would look more like:
>     >
>     >     <head>
>     >             <meta http-equiv="X-UA-Compatible"
> content="IE=edge,chrome=1">
>     >             <meta http-equiv="Content-Type" content="text/html;
>     > charset=utf-8">
>     >             <link rel="stylesheet" type="text/css"
>     > href="HelloWorld.min.css">
>     >             <script type="text/javascript" src="
>     >
> https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fhighlight.js%2F9.12.0%2Fhighlight.min.js&amp;data=02%7C01%7Caharui%40adobe.com%7C161a52e6f1e743d8046a08d805f745e1%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265906882641150&amp;sdata=jRqEz2TAUdYDkRobaBUJHdAgxJ%2FajTNHNuaXyBhc0so%3D&amp;reserved=0
>     > "
>     >
>     > onload="highlight.min.js.loaded=true;"></script>
>     >             <script type="text/javascript"
> src="./HelloWorld.js"></script>
>     >     </head>
>     >     <body>
>     >             <script type="text/javascript">
>     >                     var appInterval = setInterval(function() { if
>     > (highlight.min.js.loaded) {
>     >
>     >                                     clearInterval(appInterval);
>     >
>     >                                     new HelloWorld().start();
>     >
>     >                               }, 200);
>     >             </script>
>     >     </body>
>     >
>     >     Closure seems to use a hash of the URL instead of part of the
> URL to
>     > avoid collisions in case two different scripts are called main.js or
>     > something like that.  And there might be some better way than using
>     > setInterval, but the idea is to wait until the JS is loaded before
> calling
>     > start().
>     >
>     >     HTH,
>     >     -Alex
>     >
>     >     On 5/19/20, 12:18 PM, "Yishay Weiss" <yi...@hotmail.com>
> wrote:
>     >
>     >         See 99a8c8356573ff16b668f2d39a447355c673fee3
>     >
>     >         Note that hljs is an externs file so I couldn’t implement
> static
>     > initializers there.
>     >
>     >         There’s also a sort of a queue there for calls made before
> lib is
>     > loaded. I realize this doesn’t scale as a pattern, which is why I
> proposed
>     > to simplify annotations instead.
>     >
>     >         It could be of course there’s a simpler solution I’m missing.
>     >
>     >         From: Alex Harui<ma...@adobe.com.INVALID>
>     >         Sent: Tuesday, May 19, 2020 10:03 PM
>     >         To: dev@royale.apache.org<ma...@royale.apache.org>
>     >         Subject: Re: Script Loading Order (Continuing Heads-Up
> thread from
>     > Users)
>     >
>     >         Yishay,
>     >
>     >         I didn't think static initializers would require a façade or
> other
>     > fancy mechanism.  What kind of AS code ends up requiring this more
> complex
>     > solution?
>     >
>     >         -Alex
>     >
>     >         On 5/19/20, 10:34 AM, "Yishay Weiss" <yishayjobs@hotmail.com
> >
>     > wrote:
>     >
>     >             Hi Carlos,
>     >
>     >             Sorry for not responding earlier, I missed this post.
>     >
>     >             I haven’t been able to replicate this in debug mode, so
> it’s
>     > interesting you’re seeing that.
>     >
>     >             I agree the façade solution is a bit cumbersome, but it
> works
>     > and maybe it’s worth having it out there as an example of using
> static
>     > initializers instead of injected code.
>     >
>     >             What do you think?
>     >
>     >             From: Carlos Rovira<ma...@apache.org>
>     >             Sent: Monday, May 18, 2020 7:34 PM
>     >             To: Apache Royale Development<mailto:
> dev@royale.apache.org>
>     >             Subject: Re: Script Loading Order (Continuing Heads-Up
> thread
>     > from Users)
>     >
>     >             Hi Yishay,
>     >
>     >             I'm confused. The problem I reported was this;
>     >
>     >             ReferenceError: dialogPolyfill is not defined at
>     >
>     >
> /Users/carlosrovira/Dev/Royale/Source/royale-asjs/examples/jewel/TourDeJewel/target/javascript/bin/js-debug/App.js:10:1
>     >
>     >             And just as I'm copying here I'm seeing that while I'm
> running
>     >             "js-release", notice that the link refers to "js-debug",
> so I
>     > think there's
>     >             some wrong path involved here
>     >
>     >             I just updated with your latest change about hljs but I
> don't
>     > think we have
>     >             a problems with it. A part from that I don't like the
> solution
>     > to make a
>     >             Facade for a script, since that involves to create 2
> classes
>     > instead of
>     >             one. The solution should be just make 1 as3 file
> (instead of
>     > two) and that
>     >             have the proper inject reference.
>     >
>     >             Please can you revert the hljsFacade?
>     >
>     >             thanks
>     >
>     >
>     >
>     >
>     >             El lun., 18 may. 2020 a las 17:44, Yishay Weiss (<
>     > yishayjobs@hotmail.com>)
>     >             escribió:
>     >
>     >             > Unless I missed something that’s what it’s doing right
> now
>     > after my fix.
>     >             > I’ll try to explain the scenario as I see it (no
> modules).
>     >             >
>     >             > Suppose we have an app that compiles to the following
> html.
>     >             >
>     >             > <html>
>     >             >                 <head>
>     >             >                                 <script
>     > type="text/javascript">
>     >             >                                                 var
> script =
>     >             > document.createElement("script");
>     >             >
>     >  script.setAttribute("src",
>     >             > "hljs.min.js");
>     >             >
>     >             > document.head.appendChild(script);
>     >             >                                 </script>
>     >             >                                 <script
>     > type=”text/JavaScript”
>     >             > src=”App.js”></script>
>     >             >                 </head>
>     >             >                 <body></body>
>     >             > </html>
>     >             >
>     >             > After the first script element is loaded, the dom will
> look
>     > like:
>     >             >
>     >             > <html>
>     >             >                 <head>
>     >             >                                 <script
>     > type="text/javascript">
>     >             >                                                 var
> script =
>     >             > document.createElement("script");
>     >             >
>     >  script.setAttribute("src",
>     >             > "hljs.min.js");
>     >             >
>     >             > document.head.appendChild(script);
>     >             >                                 </script>
>     >             >                                 <script
>     > type=”text/JavaScript”
>     >             > src=”hljs.min.js”></script>
>     >             >                                 <script
>     > type=”text/JavaScript”
>     >             > src=”App.js”></script>
>     >             >                 </head>
>     >             >                 <body></body>
>     >             > </html>
>     >             >
>     >             > However, App.js will still be loaded before hljs.min.js
>     > because it was not
>     >             > created dynamically. App.js will fail because it
> depends on
>     > hljs.
>     >             >
>     >             > From: Alex Harui<ma...@adobe.com.INVALID>
>     >             > Sent: Monday, May 18, 2020 6:21 PM
>     >             > To: dev@royale.apache.org<mailto:dev@royale.apache.org
> >
>     >             > Subject: Re: Script Loading Order (Continuing Heads-Up
>     > thread from Users)
>     >             >
>     >             > I don't think we have to inject these scripts into the
> main
>     > .js file.  The
>     >             > compiler knows when it is compiling the main app or a
>     > module.  When
>     >             > compiling the main app, it should inject the script in
> the
>     > HEAD of the html
>     >             > wrapper.  For modules, it can inject the script into a
>     > separate file.  The
>     >             > ModuleLoader already loads extra files before loading
> the
>     > module.  It can
>     >             > load one more file.
>     >             >
>     >             > Of course, I could be wrong...
>     >             > -Alex
>     >             >
>     >             > On 5/18/20, 7:38 AM, "Yishay Weiss" <
> yishayjobs@hotmail.com>
>     > wrote:
>     >             >
>     >             >     From what I’ve read [1] scripts injected
> dynamically
>     > will always load
>     >             > after static script elements. So I don’t think there’s
> a
>     > good way to ensure
>     >             > the proper order in run-time unless we do something
> like
>     >             > 99a8c8356573ff16b668f2d39a447355c673fee3 , but that’s
>     > verbose and working
>     >             > with libs should be simple.
>     >             >
>     >             >     Any ideas?
>     >             >
>     >             >     [1]
>     >             >
>     >
> https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.html5rocks.com%2Fen%2Ftutorials%2Fspeed%2Fscript-loading%2F%23disqus_thread&amp;data=02%7C01%7Caharui%40adobe.com%7C161a52e6f1e743d8046a08d805f745e1%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265906882641150&amp;sdata=8%2F0ZUXlSGJfB8c1wW6a9qenM9CLzcFqBUe7GLYfCnxQ%3D&amp;reserved=0
>     >             >
>     >             >     From: Alex Harui<ma...@adobe.com.INVALID>
>     >             >     Sent: Monday, May 18, 2020 8:03 AM
>     >             >     To: dev@royale.apache.org<mailto:
> dev@royale.apache.org>
>     >             >
>     >             >
>     >             >     Subject: Re: Script Loading Order (Continuing
> Heads-Up
>     > thread from
>     >             > Users)
>     >             >
>     >             >     Every time I look, closure seems to change how it
>     > works.  It looks
>     >             > like they are using callbacks and UIDs.  I assume they
> can't
>     > use await or
>     >             > Promise because of IE support.  I haven't looked at
> the code
>     > you generate,
>     >             > but might have to do something similar, IOW, wait for
> the
>     > callback or known
>     >             > value before continuing.
>     >             >
>     >             >     I think that if we create the script during the
> running
>     > of another
>     >             > script that we have to find a way to wait for that
> created
>     > script.
>     >             >
>     >             >     It might help to know what kind of initialization
> code
>     > needed the
>     >             > definition so early.  One alternative is that such code
>     > needs to be
>     >             > responsible for waiting.
>     >             >
>     >             >     Most of our Application classes have a wait
> mechanism.
>     > We could
>     >             > leverage that, but that's also pretty late.
>     >             >
>     >             >     It could be that for Applications we generate the
> script
>     > in the head,
>     >             > and for modules we generate a separate script that is
>     > preloaded.
>     >             >
>     >             >     HTH,
>     >             >     -Alex
>     >             >
>     >             >     On 5/17/20, 9:03 AM, "Yishay Weiss" <
>     > yishayjobs@hotmail.com> wrote:
>     >             >
>     >             >
>     >             >         >Is the script tag from inject_script going
> before
>     > or after the
>     >             > script tag for the application (should be before,
> >IMO)?
>     >             >
>     >             >         It’s going before but the network shows it’s
> loaded
>     > after.
>     >             >
>     >             >         >Make sure the script tag has the same
> settings as
>     > the script tags
>     >             > google closure uses in js-debug.  I think they set some
>     > options so the
>     >             > scripts load in order.
>     >             >
>     >             >         I see type being specified in the gcl script
>     > elements, while
>     >             > inject ones don’t. I suppose it’s worth seeing if that
> makes
>     > a difference,
>     >             > though I couldn’t find evidence for that on the web.
>     >             >
>     >             >
>     >             >
>     >             >
>     >             >
>     >
>     >             --
>     >             Carlos Rovira
>     >
>     >
> https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fabout.me%2Fcarlosrovira&amp;data=02%7C01%7Caharui%40adobe.com%7C161a52e6f1e743d8046a08d805f745e1%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265906882641150&amp;sdata=79WbNRkoyomf6bCvL4TnduvU8vInlwya2QocLTGLV3E%3D&amp;reserved=0
>     >
>     >
>     >
>     >
>     >
>     >
>     >
>     >
>
>
>
>

Re: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Alex Harui <ah...@adobe.com.INVALID>.
AIUI, in this particular case, externs should not have @export or exportSymbol calls.  The 'u' function is exportSymbol.

Of course, I could be wrong,
-Alex

On 5/31/20, 11:44 PM, "Yishay Weiss" <yi...@hotmail.com> wrote:

    Good, thanks. Out of curiosity, what special handling do externs need?
    
    From: Josh Tynjala<ma...@bowlerhat.dev>
    Sent: Monday, June 1, 2020 2:01 AM
    To: Apache Royale Development<ma...@royale.apache.org>
    Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
    
    This appears to be related to my export/rename refactoring. As Alex
    mentioned, externs need special handling, and I was treating them like
    regular symbols. I should be able to get that fixed this week.
    
    --
    Josh Tynjala
    Bowler Hat LLC <https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbowlerhat.dev%2F&amp;data=02%7C01%7Caharui%40adobe.com%7C161a52e6f1e743d8046a08d805f745e1%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265906882631155&amp;sdata=XaR6WYJSBgMUQfWQDc3wOD2TXSi1QqjpP1%2FcljV3IUc%3D&amp;reserved=0>
    
    
    On Sun, May 31, 2020 at 8:13 AM Yishay Weiss <yi...@hotmail.com> wrote:
    
    > Here’s the minimal test case I came up with for demonstrating the problem.
    >
    > <?xml version="1.0" encoding="utf-8"?>
    > <js:Application xmlns:fx="https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fns.adobe.com%2Fmxml%2F2009&amp;data=02%7C01%7Caharui%40adobe.com%7C161a52e6f1e743d8046a08d805f745e1%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265906882631155&amp;sdata=wkyh88Lwwhzu8%2BNcM6RMODIUfBF0vWlkFNUm6Mx8Wjs%3D&amp;reserved=0"
    >                 xmlns:js="library://ns.apache.org/royale/basic"
    >                 >
    >        <fx:Script>
    >                        <![CDATA[
    >                 private function dummy():void
    >                 {
    >                                 dialogPolyfill;
    >                 }
    >                        ]]>
    >        </fx:Script>
    > </js:Application>
    >
    > Where dialogPolyfill is
    >
    > package
    > {
    >                 /**
    >                 * @externs
    >                 */
    >                 COMPILE::JS
    >                 public class dialogPolyfill
    >                 {
    >                 /**
    >          * <inject_script>
    >          * var script = document.createElement("script");
    >          * script.setAttribute("src", "
    > https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fdialog-polyfill%2F0.4.9%2Fdialog-polyfill.min.js&amp;data=02%7C01%7Caharui%40adobe.com%7C161a52e6f1e743d8046a08d805f745e1%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265906882631155&amp;sdata=aOqz6hScb3UxeTWM3XJ%2FTerQnGc6B8QEuJgKR0eO9f8%3D&amp;reserved=0
    > ");
    >          * document.head.appendChild(script)
    >          * </inject_script>
    >                 */
    >                                 public function dialogPolyfill(){}
    >                 }
    > }
    >
    > In release I get a ‘ReferenceError: dialogPolyfill is not defined’
    >
    > u('dialogPolyfill',dialogPolyfill) of Examples.js, which is run before
    > start()
    >
    > So in order to fix this scenario we would need Examples.js to wait for
    > dialogPolyfill.min.js, not for start() to wait.
    >
    > From: Alex Harui<ma...@adobe.com.INVALID>
    > Sent: Wednesday, May 20, 2020 8:09 PM
    > To: dev@royale.apache.org<ma...@royale.apache.org>
    > Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
    >
    > When I mentioned static initializers in my earlier post, it was about the
    > timing of when some code would first access hljs.  Most externs will
    > probably be first used from code that runs after application.start().  But
    > if someone did:
    >
    > public static var HLJSClass:Class = hljs;
    >
    > Then that would fail before we can run application.start(), except that
    > the compiler auto-converts static vars to lazy getters.
    >
    > However, the hljs usage is not wrapped, so there really aren't any static
    > initializers to use, so it doesn’t matter if they are lazy or not.  I
    > haven't looked at the other uses of inject_script, but if a class wraps the
    > dependency, then it can implement its own waiting strategy unless the API
    > has to be synchronous.  IOW, if I created a Highlighter class that used
    > hljs internally, then if the "highlight" API returns a void, the wrapping
    > implementation would load hljs.js and make the call when it is ready, which
    > is essentially building in the façade you wrote.
    >
    > You could implement a map of injected scripts, but after thinking about it
    > overnight, my first thought is to require that folks publish a var or uid
    > as follows:
    >
    >          * <inject_script var="hljs_loaded">
    >                 * var scriptLoaded = function() { hljs_loaded = true) };
    >                 * var script = document.createElement("script");
    >                 * script.setAttribute("src", "
    > https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fhighlight.js%2F9.12.0%2Fhighlight.min.js&amp;data=02%7C01%7Caharui%40adobe.com%7C161a52e6f1e743d8046a08d805f745e1%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265906882641150&amp;sdata=jRqEz2TAUdYDkRobaBUJHdAgxJ%2FajTNHNuaXyBhc0so%3D&amp;reserved=0
    > ");
    >                 * script.addEventListener("load", scriptLoaded);
    >                 * document.head.appendChild(script);
    >             * </inject_script>
    >
    > Then the compiler may not need so much as a map, but can gather a list of
    > variables to watch for in the setInterval before calling
    > application.start();
    >
    > Of course, I could be wrong...
    > -Alex
    >
    > On 5/20/20, 12:19 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
    >
    >     Several questions/comments:
    >
    >
    >       1.  When you say static initializers should be lazy, do you mean
    > load on the first lib api call? If so, wouldn’t that force async calls?
    >       2.  Do you have a way of using static initializers for externs
    > files, which is how hljs was originally used?
    >       3.  To generate the script that waits for dynamically loaded scripts
    > (I guess we don’t mind async css, though I’m not sure) we would need to
    > have a map of injected scripts. So it looks like we’ll need to parse the
    > injected_sctipt tag in any case.
    >
    >     Thanks.
    >
    >
    >
    >     From: Alex Harui<ma...@adobe.com.INVALID>
    >     Sent: Wednesday, May 20, 2020 9:52 AM
    >     To: dev@royale.apache.org<ma...@royale.apache.org>
    >     Subject: Re: Script Loading Order (Continuing Heads-Up thread from
    > Users)
    >
    >     OK, I looked at the commit for hljs, and the code it replaced.
    > AFAICT, that is an instantiation phase dependency and not a initialization
    > phase dependency, so it should not matter if it loads before or after
    > app.js (unless someone does use it in a non-lazy static initializer, which
    > should be hard to do in Royale).  It should only matter that it is loaded
    > before anybody calls it.  Other than static initializers, which should all
    > be lazy, nobody should really call hljs until after the application.start()
    > is called in the index.html.
    >
    >     Here is the index.html for HelloWorld:
    >     <html>
    >     <head>
    >             <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    >             <meta http-equiv="Content-Type" content="text/html;
    > charset=utf-8">
    >             <link rel="stylesheet" type="text/css"
    > href="HelloWorld.min.css">
    >             <script type="text/javascript" src="./HelloWorld.js"></script>
    >     </head>
    >     <body>
    >             <script type="text/javascript">
    >                     new HelloWorld().start();
    >             </script>
    >     </body>
    >
    >     IMO, for applications that use inject_script (modules will use the
    > _deps file), we should generate code before the start() call that waits for
    > any dynamic scripts to load.  So if HelloWorld needed hljs, the index.html
    > would look more like:
    >
    >     <head>
    >             <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    >             <meta http-equiv="Content-Type" content="text/html;
    > charset=utf-8">
    >             <link rel="stylesheet" type="text/css"
    > href="HelloWorld.min.css">
    >             <script type="text/javascript" src="
    > https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fhighlight.js%2F9.12.0%2Fhighlight.min.js&amp;data=02%7C01%7Caharui%40adobe.com%7C161a52e6f1e743d8046a08d805f745e1%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265906882641150&amp;sdata=jRqEz2TAUdYDkRobaBUJHdAgxJ%2FajTNHNuaXyBhc0so%3D&amp;reserved=0
    > "
    >
    > onload="highlight.min.js.loaded=true;"></script>
    >             <script type="text/javascript" src="./HelloWorld.js"></script>
    >     </head>
    >     <body>
    >             <script type="text/javascript">
    >                     var appInterval = setInterval(function() { if
    > (highlight.min.js.loaded) {
    >
    >                                     clearInterval(appInterval);
    >
    >                                     new HelloWorld().start();
    >
    >                               }, 200);
    >             </script>
    >     </body>
    >
    >     Closure seems to use a hash of the URL instead of part of the URL to
    > avoid collisions in case two different scripts are called main.js or
    > something like that.  And there might be some better way than using
    > setInterval, but the idea is to wait until the JS is loaded before calling
    > start().
    >
    >     HTH,
    >     -Alex
    >
    >     On 5/19/20, 12:18 PM, "Yishay Weiss" <yi...@hotmail.com> wrote:
    >
    >         See 99a8c8356573ff16b668f2d39a447355c673fee3
    >
    >         Note that hljs is an externs file so I couldn’t implement static
    > initializers there.
    >
    >         There’s also a sort of a queue there for calls made before lib is
    > loaded. I realize this doesn’t scale as a pattern, which is why I proposed
    > to simplify annotations instead.
    >
    >         It could be of course there’s a simpler solution I’m missing.
    >
    >         From: Alex Harui<ma...@adobe.com.INVALID>
    >         Sent: Tuesday, May 19, 2020 10:03 PM
    >         To: dev@royale.apache.org<ma...@royale.apache.org>
    >         Subject: Re: Script Loading Order (Continuing Heads-Up thread from
    > Users)
    >
    >         Yishay,
    >
    >         I didn't think static initializers would require a façade or other
    > fancy mechanism.  What kind of AS code ends up requiring this more complex
    > solution?
    >
    >         -Alex
    >
    >         On 5/19/20, 10:34 AM, "Yishay Weiss" <yi...@hotmail.com>
    > wrote:
    >
    >             Hi Carlos,
    >
    >             Sorry for not responding earlier, I missed this post.
    >
    >             I haven’t been able to replicate this in debug mode, so it’s
    > interesting you’re seeing that.
    >
    >             I agree the façade solution is a bit cumbersome, but it works
    > and maybe it’s worth having it out there as an example of using static
    > initializers instead of injected code.
    >
    >             What do you think?
    >
    >             From: Carlos Rovira<ma...@apache.org>
    >             Sent: Monday, May 18, 2020 7:34 PM
    >             To: Apache Royale Development<ma...@royale.apache.org>
    >             Subject: Re: Script Loading Order (Continuing Heads-Up thread
    > from Users)
    >
    >             Hi Yishay,
    >
    >             I'm confused. The problem I reported was this;
    >
    >             ReferenceError: dialogPolyfill is not defined at
    >
    > /Users/carlosrovira/Dev/Royale/Source/royale-asjs/examples/jewel/TourDeJewel/target/javascript/bin/js-debug/App.js:10:1
    >
    >             And just as I'm copying here I'm seeing that while I'm running
    >             "js-release", notice that the link refers to "js-debug", so I
    > think there's
    >             some wrong path involved here
    >
    >             I just updated with your latest change about hljs but I don't
    > think we have
    >             a problems with it. A part from that I don't like the solution
    > to make a
    >             Facade for a script, since that involves to create 2 classes
    > instead of
    >             one. The solution should be just make 1 as3 file (instead of
    > two) and that
    >             have the proper inject reference.
    >
    >             Please can you revert the hljsFacade?
    >
    >             thanks
    >
    >
    >
    >
    >             El lun., 18 may. 2020 a las 17:44, Yishay Weiss (<
    > yishayjobs@hotmail.com>)
    >             escribió:
    >
    >             > Unless I missed something that’s what it’s doing right now
    > after my fix.
    >             > I’ll try to explain the scenario as I see it (no modules).
    >             >
    >             > Suppose we have an app that compiles to the following html.
    >             >
    >             > <html>
    >             >                 <head>
    >             >                                 <script
    > type="text/javascript">
    >             >                                                 var script =
    >             > document.createElement("script");
    >             >
    >  script.setAttribute("src",
    >             > "hljs.min.js");
    >             >
    >             > document.head.appendChild(script);
    >             >                                 </script>
    >             >                                 <script
    > type=”text/JavaScript”
    >             > src=”App.js”></script>
    >             >                 </head>
    >             >                 <body></body>
    >             > </html>
    >             >
    >             > After the first script element is loaded, the dom will look
    > like:
    >             >
    >             > <html>
    >             >                 <head>
    >             >                                 <script
    > type="text/javascript">
    >             >                                                 var script =
    >             > document.createElement("script");
    >             >
    >  script.setAttribute("src",
    >             > "hljs.min.js");
    >             >
    >             > document.head.appendChild(script);
    >             >                                 </script>
    >             >                                 <script
    > type=”text/JavaScript”
    >             > src=”hljs.min.js”></script>
    >             >                                 <script
    > type=”text/JavaScript”
    >             > src=”App.js”></script>
    >             >                 </head>
    >             >                 <body></body>
    >             > </html>
    >             >
    >             > However, App.js will still be loaded before hljs.min.js
    > because it was not
    >             > created dynamically. App.js will fail because it depends on
    > hljs.
    >             >
    >             > From: Alex Harui<ma...@adobe.com.INVALID>
    >             > Sent: Monday, May 18, 2020 6:21 PM
    >             > To: dev@royale.apache.org<ma...@royale.apache.org>
    >             > Subject: Re: Script Loading Order (Continuing Heads-Up
    > thread from Users)
    >             >
    >             > I don't think we have to inject these scripts into the main
    > .js file.  The
    >             > compiler knows when it is compiling the main app or a
    > module.  When
    >             > compiling the main app, it should inject the script in the
    > HEAD of the html
    >             > wrapper.  For modules, it can inject the script into a
    > separate file.  The
    >             > ModuleLoader already loads extra files before loading the
    > module.  It can
    >             > load one more file.
    >             >
    >             > Of course, I could be wrong...
    >             > -Alex
    >             >
    >             > On 5/18/20, 7:38 AM, "Yishay Weiss" <yi...@hotmail.com>
    > wrote:
    >             >
    >             >     From what I’ve read [1] scripts injected dynamically
    > will always load
    >             > after static script elements. So I don’t think there’s a
    > good way to ensure
    >             > the proper order in run-time unless we do something like
    >             > 99a8c8356573ff16b668f2d39a447355c673fee3 , but that’s
    > verbose and working
    >             > with libs should be simple.
    >             >
    >             >     Any ideas?
    >             >
    >             >     [1]
    >             >
    > https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.html5rocks.com%2Fen%2Ftutorials%2Fspeed%2Fscript-loading%2F%23disqus_thread&amp;data=02%7C01%7Caharui%40adobe.com%7C161a52e6f1e743d8046a08d805f745e1%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265906882641150&amp;sdata=8%2F0ZUXlSGJfB8c1wW6a9qenM9CLzcFqBUe7GLYfCnxQ%3D&amp;reserved=0
    >             >
    >             >     From: Alex Harui<ma...@adobe.com.INVALID>
    >             >     Sent: Monday, May 18, 2020 8:03 AM
    >             >     To: dev@royale.apache.org<ma...@royale.apache.org>
    >             >
    >             >
    >             >     Subject: Re: Script Loading Order (Continuing Heads-Up
    > thread from
    >             > Users)
    >             >
    >             >     Every time I look, closure seems to change how it
    > works.  It looks
    >             > like they are using callbacks and UIDs.  I assume they can't
    > use await or
    >             > Promise because of IE support.  I haven't looked at the code
    > you generate,
    >             > but might have to do something similar, IOW, wait for the
    > callback or known
    >             > value before continuing.
    >             >
    >             >     I think that if we create the script during the running
    > of another
    >             > script that we have to find a way to wait for that created
    > script.
    >             >
    >             >     It might help to know what kind of initialization code
    > needed the
    >             > definition so early.  One alternative is that such code
    > needs to be
    >             > responsible for waiting.
    >             >
    >             >     Most of our Application classes have a wait mechanism.
    > We could
    >             > leverage that, but that's also pretty late.
    >             >
    >             >     It could be that for Applications we generate the script
    > in the head,
    >             > and for modules we generate a separate script that is
    > preloaded.
    >             >
    >             >     HTH,
    >             >     -Alex
    >             >
    >             >     On 5/17/20, 9:03 AM, "Yishay Weiss" <
    > yishayjobs@hotmail.com> wrote:
    >             >
    >             >
    >             >         >Is the script tag from inject_script going before
    > or after the
    >             > script tag for the application (should be before, >IMO)?
    >             >
    >             >         It’s going before but the network shows it’s loaded
    > after.
    >             >
    >             >         >Make sure the script tag has the same settings as
    > the script tags
    >             > google closure uses in js-debug.  I think they set some
    > options so the
    >             > scripts load in order.
    >             >
    >             >         I see type being specified in the gcl script
    > elements, while
    >             > inject ones don’t. I suppose it’s worth seeing if that makes
    > a difference,
    >             > though I couldn’t find evidence for that on the web.
    >             >
    >             >
    >             >
    >             >
    >             >
    >
    >             --
    >             Carlos Rovira
    >
    > https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fabout.me%2Fcarlosrovira&amp;data=02%7C01%7Caharui%40adobe.com%7C161a52e6f1e743d8046a08d805f745e1%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265906882641150&amp;sdata=79WbNRkoyomf6bCvL4TnduvU8vInlwya2QocLTGLV3E%3D&amp;reserved=0
    >
    >
    >
    >
    >
    >
    >
    >
    
    


RE: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Yishay Weiss <yi...@hotmail.com>.
Good, thanks. Out of curiosity, what special handling do externs need?

From: Josh Tynjala<ma...@bowlerhat.dev>
Sent: Monday, June 1, 2020 2:01 AM
To: Apache Royale Development<ma...@royale.apache.org>
Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

This appears to be related to my export/rename refactoring. As Alex
mentioned, externs need special handling, and I was treating them like
regular symbols. I should be able to get that fixed this week.

--
Josh Tynjala
Bowler Hat LLC <https://bowlerhat.dev>


On Sun, May 31, 2020 at 8:13 AM Yishay Weiss <yi...@hotmail.com> wrote:

> Here’s the minimal test case I came up with for demonstrating the problem.
>
> <?xml version="1.0" encoding="utf-8"?>
> <js:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
>                 xmlns:js="library://ns.apache.org/royale/basic"
>                 >
>        <fx:Script>
>                        <![CDATA[
>                 private function dummy():void
>                 {
>                                 dialogPolyfill;
>                 }
>                        ]]>
>        </fx:Script>
> </js:Application>
>
> Where dialogPolyfill is
>
> package
> {
>                 /**
>                 * @externs
>                 */
>                 COMPILE::JS
>                 public class dialogPolyfill
>                 {
>                 /**
>          * <inject_script>
>          * var script = document.createElement("script");
>          * script.setAttribute("src", "
> https://cdnjs.cloudflare.com/ajax/libs/dialog-polyfill/0.4.9/dialog-polyfill.min.js
> ");
>          * document.head.appendChild(script)
>          * </inject_script>
>                 */
>                                 public function dialogPolyfill(){}
>                 }
> }
>
> In release I get a ‘ReferenceError: dialogPolyfill is not defined’
>
> u('dialogPolyfill',dialogPolyfill) of Examples.js, which is run before
> start()
>
> So in order to fix this scenario we would need Examples.js to wait for
> dialogPolyfill.min.js, not for start() to wait.
>
> From: Alex Harui<ma...@adobe.com.INVALID>
> Sent: Wednesday, May 20, 2020 8:09 PM
> To: dev@royale.apache.org<ma...@royale.apache.org>
> Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
>
> When I mentioned static initializers in my earlier post, it was about the
> timing of when some code would first access hljs.  Most externs will
> probably be first used from code that runs after application.start().  But
> if someone did:
>
> public static var HLJSClass:Class = hljs;
>
> Then that would fail before we can run application.start(), except that
> the compiler auto-converts static vars to lazy getters.
>
> However, the hljs usage is not wrapped, so there really aren't any static
> initializers to use, so it doesn’t matter if they are lazy or not.  I
> haven't looked at the other uses of inject_script, but if a class wraps the
> dependency, then it can implement its own waiting strategy unless the API
> has to be synchronous.  IOW, if I created a Highlighter class that used
> hljs internally, then if the "highlight" API returns a void, the wrapping
> implementation would load hljs.js and make the call when it is ready, which
> is essentially building in the façade you wrote.
>
> You could implement a map of injected scripts, but after thinking about it
> overnight, my first thought is to require that folks publish a var or uid
> as follows:
>
>          * <inject_script var="hljs_loaded">
>                 * var scriptLoaded = function() { hljs_loaded = true) };
>                 * var script = document.createElement("script");
>                 * script.setAttribute("src", "
> https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js
> ");
>                 * script.addEventListener("load", scriptLoaded);
>                 * document.head.appendChild(script);
>             * </inject_script>
>
> Then the compiler may not need so much as a map, but can gather a list of
> variables to watch for in the setInterval before calling
> application.start();
>
> Of course, I could be wrong...
> -Alex
>
> On 5/20/20, 12:19 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
>
>     Several questions/comments:
>
>
>       1.  When you say static initializers should be lazy, do you mean
> load on the first lib api call? If so, wouldn’t that force async calls?
>       2.  Do you have a way of using static initializers for externs
> files, which is how hljs was originally used?
>       3.  To generate the script that waits for dynamically loaded scripts
> (I guess we don’t mind async css, though I’m not sure) we would need to
> have a map of injected scripts. So it looks like we’ll need to parse the
> injected_sctipt tag in any case.
>
>     Thanks.
>
>
>
>     From: Alex Harui<ma...@adobe.com.INVALID>
>     Sent: Wednesday, May 20, 2020 9:52 AM
>     To: dev@royale.apache.org<ma...@royale.apache.org>
>     Subject: Re: Script Loading Order (Continuing Heads-Up thread from
> Users)
>
>     OK, I looked at the commit for hljs, and the code it replaced.
> AFAICT, that is an instantiation phase dependency and not a initialization
> phase dependency, so it should not matter if it loads before or after
> app.js (unless someone does use it in a non-lazy static initializer, which
> should be hard to do in Royale).  It should only matter that it is loaded
> before anybody calls it.  Other than static initializers, which should all
> be lazy, nobody should really call hljs until after the application.start()
> is called in the index.html.
>
>     Here is the index.html for HelloWorld:
>     <html>
>     <head>
>             <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
>             <meta http-equiv="Content-Type" content="text/html;
> charset=utf-8">
>             <link rel="stylesheet" type="text/css"
> href="HelloWorld.min.css">
>             <script type="text/javascript" src="./HelloWorld.js"></script>
>     </head>
>     <body>
>             <script type="text/javascript">
>                     new HelloWorld().start();
>             </script>
>     </body>
>
>     IMO, for applications that use inject_script (modules will use the
> _deps file), we should generate code before the start() call that waits for
> any dynamic scripts to load.  So if HelloWorld needed hljs, the index.html
> would look more like:
>
>     <head>
>             <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
>             <meta http-equiv="Content-Type" content="text/html;
> charset=utf-8">
>             <link rel="stylesheet" type="text/css"
> href="HelloWorld.min.css">
>             <script type="text/javascript" src="
> https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fhighlight.js%2F9.12.0%2Fhighlight.min.js&amp;data=02%7C01%7Caharui%40adobe.com%7C5db4fc1f0ed844113a9d08d7fc8e131f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255559454859456&amp;sdata=hoREedwRG%2BXVsuvx5zymqNpNPH3FlptAyChhInwZ%2F6E%3D&amp;reserved=0
> "
>
> onload="highlight.min.js.loaded=true;"></script>
>             <script type="text/javascript" src="./HelloWorld.js"></script>
>     </head>
>     <body>
>             <script type="text/javascript">
>                     var appInterval = setInterval(function() { if
> (highlight.min.js.loaded) {
>
>                                     clearInterval(appInterval);
>
>                                     new HelloWorld().start();
>
>                               }, 200);
>             </script>
>     </body>
>
>     Closure seems to use a hash of the URL instead of part of the URL to
> avoid collisions in case two different scripts are called main.js or
> something like that.  And there might be some better way than using
> setInterval, but the idea is to wait until the JS is loaded before calling
> start().
>
>     HTH,
>     -Alex
>
>     On 5/19/20, 12:18 PM, "Yishay Weiss" <yi...@hotmail.com> wrote:
>
>         See 99a8c8356573ff16b668f2d39a447355c673fee3
>
>         Note that hljs is an externs file so I couldn’t implement static
> initializers there.
>
>         There’s also a sort of a queue there for calls made before lib is
> loaded. I realize this doesn’t scale as a pattern, which is why I proposed
> to simplify annotations instead.
>
>         It could be of course there’s a simpler solution I’m missing.
>
>         From: Alex Harui<ma...@adobe.com.INVALID>
>         Sent: Tuesday, May 19, 2020 10:03 PM
>         To: dev@royale.apache.org<ma...@royale.apache.org>
>         Subject: Re: Script Loading Order (Continuing Heads-Up thread from
> Users)
>
>         Yishay,
>
>         I didn't think static initializers would require a façade or other
> fancy mechanism.  What kind of AS code ends up requiring this more complex
> solution?
>
>         -Alex
>
>         On 5/19/20, 10:34 AM, "Yishay Weiss" <yi...@hotmail.com>
> wrote:
>
>             Hi Carlos,
>
>             Sorry for not responding earlier, I missed this post.
>
>             I haven’t been able to replicate this in debug mode, so it’s
> interesting you’re seeing that.
>
>             I agree the façade solution is a bit cumbersome, but it works
> and maybe it’s worth having it out there as an example of using static
> initializers instead of injected code.
>
>             What do you think?
>
>             From: Carlos Rovira<ma...@apache.org>
>             Sent: Monday, May 18, 2020 7:34 PM
>             To: Apache Royale Development<ma...@royale.apache.org>
>             Subject: Re: Script Loading Order (Continuing Heads-Up thread
> from Users)
>
>             Hi Yishay,
>
>             I'm confused. The problem I reported was this;
>
>             ReferenceError: dialogPolyfill is not defined at
>
> /Users/carlosrovira/Dev/Royale/Source/royale-asjs/examples/jewel/TourDeJewel/target/javascript/bin/js-debug/App.js:10:1
>
>             And just as I'm copying here I'm seeing that while I'm running
>             "js-release", notice that the link refers to "js-debug", so I
> think there's
>             some wrong path involved here
>
>             I just updated with your latest change about hljs but I don't
> think we have
>             a problems with it. A part from that I don't like the solution
> to make a
>             Facade for a script, since that involves to create 2 classes
> instead of
>             one. The solution should be just make 1 as3 file (instead of
> two) and that
>             have the proper inject reference.
>
>             Please can you revert the hljsFacade?
>
>             thanks
>
>
>
>
>             El lun., 18 may. 2020 a las 17:44, Yishay Weiss (<
> yishayjobs@hotmail.com>)
>             escribió:
>
>             > Unless I missed something that’s what it’s doing right now
> after my fix.
>             > I’ll try to explain the scenario as I see it (no modules).
>             >
>             > Suppose we have an app that compiles to the following html.
>             >
>             > <html>
>             >                 <head>
>             >                                 <script
> type="text/javascript">
>             >                                                 var script =
>             > document.createElement("script");
>             >
>  script.setAttribute("src",
>             > "hljs.min.js");
>             >
>             > document.head.appendChild(script);
>             >                                 </script>
>             >                                 <script
> type=”text/JavaScript”
>             > src=”App.js”></script>
>             >                 </head>
>             >                 <body></body>
>             > </html>
>             >
>             > After the first script element is loaded, the dom will look
> like:
>             >
>             > <html>
>             >                 <head>
>             >                                 <script
> type="text/javascript">
>             >                                                 var script =
>             > document.createElement("script");
>             >
>  script.setAttribute("src",
>             > "hljs.min.js");
>             >
>             > document.head.appendChild(script);
>             >                                 </script>
>             >                                 <script
> type=”text/JavaScript”
>             > src=”hljs.min.js”></script>
>             >                                 <script
> type=”text/JavaScript”
>             > src=”App.js”></script>
>             >                 </head>
>             >                 <body></body>
>             > </html>
>             >
>             > However, App.js will still be loaded before hljs.min.js
> because it was not
>             > created dynamically. App.js will fail because it depends on
> hljs.
>             >
>             > From: Alex Harui<ma...@adobe.com.INVALID>
>             > Sent: Monday, May 18, 2020 6:21 PM
>             > To: dev@royale.apache.org<ma...@royale.apache.org>
>             > Subject: Re: Script Loading Order (Continuing Heads-Up
> thread from Users)
>             >
>             > I don't think we have to inject these scripts into the main
> .js file.  The
>             > compiler knows when it is compiling the main app or a
> module.  When
>             > compiling the main app, it should inject the script in the
> HEAD of the html
>             > wrapper.  For modules, it can inject the script into a
> separate file.  The
>             > ModuleLoader already loads extra files before loading the
> module.  It can
>             > load one more file.
>             >
>             > Of course, I could be wrong...
>             > -Alex
>             >
>             > On 5/18/20, 7:38 AM, "Yishay Weiss" <yi...@hotmail.com>
> wrote:
>             >
>             >     From what I’ve read [1] scripts injected dynamically
> will always load
>             > after static script elements. So I don’t think there’s a
> good way to ensure
>             > the proper order in run-time unless we do something like
>             > 99a8c8356573ff16b668f2d39a447355c673fee3 , but that’s
> verbose and working
>             > with libs should be simple.
>             >
>             >     Any ideas?
>             >
>             >     [1]
>             >
> https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.html5rocks.com%2Fen%2Ftutorials%2Fspeed%2Fscript-loading%2F%23disqus_thread&amp;data=02%7C01%7Caharui%40adobe.com%7C5db4fc1f0ed844113a9d08d7fc8e131f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255559454869451&amp;sdata=2EjRCIfbjT1okBPUCGBvDVvvv%2FYESige0uaJHppreo8%3D&amp;reserved=0
>             >
>             >     From: Alex Harui<ma...@adobe.com.INVALID>
>             >     Sent: Monday, May 18, 2020 8:03 AM
>             >     To: dev@royale.apache.org<ma...@royale.apache.org>
>             >
>             >
>             >     Subject: Re: Script Loading Order (Continuing Heads-Up
> thread from
>             > Users)
>             >
>             >     Every time I look, closure seems to change how it
> works.  It looks
>             > like they are using callbacks and UIDs.  I assume they can't
> use await or
>             > Promise because of IE support.  I haven't looked at the code
> you generate,
>             > but might have to do something similar, IOW, wait for the
> callback or known
>             > value before continuing.
>             >
>             >     I think that if we create the script during the running
> of another
>             > script that we have to find a way to wait for that created
> script.
>             >
>             >     It might help to know what kind of initialization code
> needed the
>             > definition so early.  One alternative is that such code
> needs to be
>             > responsible for waiting.
>             >
>             >     Most of our Application classes have a wait mechanism.
> We could
>             > leverage that, but that's also pretty late.
>             >
>             >     It could be that for Applications we generate the script
> in the head,
>             > and for modules we generate a separate script that is
> preloaded.
>             >
>             >     HTH,
>             >     -Alex
>             >
>             >     On 5/17/20, 9:03 AM, "Yishay Weiss" <
> yishayjobs@hotmail.com> wrote:
>             >
>             >
>             >         >Is the script tag from inject_script going before
> or after the
>             > script tag for the application (should be before, >IMO)?
>             >
>             >         It’s going before but the network shows it’s loaded
> after.
>             >
>             >         >Make sure the script tag has the same settings as
> the script tags
>             > google closure uses in js-debug.  I think they set some
> options so the
>             > scripts load in order.
>             >
>             >         I see type being specified in the gcl script
> elements, while
>             > inject ones don’t. I suppose it’s worth seeing if that makes
> a difference,
>             > though I couldn’t find evidence for that on the web.
>             >
>             >
>             >
>             >
>             >
>
>             --
>             Carlos Rovira
>
> https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fabout.me%2Fcarlosrovira&amp;data=02%7C01%7Caharui%40adobe.com%7C5db4fc1f0ed844113a9d08d7fc8e131f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255559454869451&amp;sdata=nuAIneqbkZeykwL3eG1ylsgJ9Xf%2FZXDSejyg4CJywhg%3D&amp;reserved=0
>
>
>
>
>
>
>
>


Re: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Josh Tynjala <jo...@bowlerhat.dev>.
This appears to be related to my export/rename refactoring. As Alex
mentioned, externs need special handling, and I was treating them like
regular symbols. I should be able to get that fixed this week.

--
Josh Tynjala
Bowler Hat LLC <https://bowlerhat.dev>


On Sun, May 31, 2020 at 8:13 AM Yishay Weiss <yi...@hotmail.com> wrote:

> Here’s the minimal test case I came up with for demonstrating the problem.
>
> <?xml version="1.0" encoding="utf-8"?>
> <js:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
>                 xmlns:js="library://ns.apache.org/royale/basic"
>                 >
>        <fx:Script>
>                        <![CDATA[
>                 private function dummy():void
>                 {
>                                 dialogPolyfill;
>                 }
>                        ]]>
>        </fx:Script>
> </js:Application>
>
> Where dialogPolyfill is
>
> package
> {
>                 /**
>                 * @externs
>                 */
>                 COMPILE::JS
>                 public class dialogPolyfill
>                 {
>                 /**
>          * <inject_script>
>          * var script = document.createElement("script");
>          * script.setAttribute("src", "
> https://cdnjs.cloudflare.com/ajax/libs/dialog-polyfill/0.4.9/dialog-polyfill.min.js
> ");
>          * document.head.appendChild(script)
>          * </inject_script>
>                 */
>                                 public function dialogPolyfill(){}
>                 }
> }
>
> In release I get a ‘ReferenceError: dialogPolyfill is not defined’
>
> u('dialogPolyfill',dialogPolyfill) of Examples.js, which is run before
> start()
>
> So in order to fix this scenario we would need Examples.js to wait for
> dialogPolyfill.min.js, not for start() to wait.
>
> From: Alex Harui<ma...@adobe.com.INVALID>
> Sent: Wednesday, May 20, 2020 8:09 PM
> To: dev@royale.apache.org<ma...@royale.apache.org>
> Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
>
> When I mentioned static initializers in my earlier post, it was about the
> timing of when some code would first access hljs.  Most externs will
> probably be first used from code that runs after application.start().  But
> if someone did:
>
> public static var HLJSClass:Class = hljs;
>
> Then that would fail before we can run application.start(), except that
> the compiler auto-converts static vars to lazy getters.
>
> However, the hljs usage is not wrapped, so there really aren't any static
> initializers to use, so it doesn’t matter if they are lazy or not.  I
> haven't looked at the other uses of inject_script, but if a class wraps the
> dependency, then it can implement its own waiting strategy unless the API
> has to be synchronous.  IOW, if I created a Highlighter class that used
> hljs internally, then if the "highlight" API returns a void, the wrapping
> implementation would load hljs.js and make the call when it is ready, which
> is essentially building in the façade you wrote.
>
> You could implement a map of injected scripts, but after thinking about it
> overnight, my first thought is to require that folks publish a var or uid
> as follows:
>
>          * <inject_script var="hljs_loaded">
>                 * var scriptLoaded = function() { hljs_loaded = true) };
>                 * var script = document.createElement("script");
>                 * script.setAttribute("src", "
> https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js
> ");
>                 * script.addEventListener("load", scriptLoaded);
>                 * document.head.appendChild(script);
>             * </inject_script>
>
> Then the compiler may not need so much as a map, but can gather a list of
> variables to watch for in the setInterval before calling
> application.start();
>
> Of course, I could be wrong...
> -Alex
>
> On 5/20/20, 12:19 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
>
>     Several questions/comments:
>
>
>       1.  When you say static initializers should be lazy, do you mean
> load on the first lib api call? If so, wouldn’t that force async calls?
>       2.  Do you have a way of using static initializers for externs
> files, which is how hljs was originally used?
>       3.  To generate the script that waits for dynamically loaded scripts
> (I guess we don’t mind async css, though I’m not sure) we would need to
> have a map of injected scripts. So it looks like we’ll need to parse the
> injected_sctipt tag in any case.
>
>     Thanks.
>
>
>
>     From: Alex Harui<ma...@adobe.com.INVALID>
>     Sent: Wednesday, May 20, 2020 9:52 AM
>     To: dev@royale.apache.org<ma...@royale.apache.org>
>     Subject: Re: Script Loading Order (Continuing Heads-Up thread from
> Users)
>
>     OK, I looked at the commit for hljs, and the code it replaced.
> AFAICT, that is an instantiation phase dependency and not a initialization
> phase dependency, so it should not matter if it loads before or after
> app.js (unless someone does use it in a non-lazy static initializer, which
> should be hard to do in Royale).  It should only matter that it is loaded
> before anybody calls it.  Other than static initializers, which should all
> be lazy, nobody should really call hljs until after the application.start()
> is called in the index.html.
>
>     Here is the index.html for HelloWorld:
>     <html>
>     <head>
>             <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
>             <meta http-equiv="Content-Type" content="text/html;
> charset=utf-8">
>             <link rel="stylesheet" type="text/css"
> href="HelloWorld.min.css">
>             <script type="text/javascript" src="./HelloWorld.js"></script>
>     </head>
>     <body>
>             <script type="text/javascript">
>                     new HelloWorld().start();
>             </script>
>     </body>
>
>     IMO, for applications that use inject_script (modules will use the
> _deps file), we should generate code before the start() call that waits for
> any dynamic scripts to load.  So if HelloWorld needed hljs, the index.html
> would look more like:
>
>     <head>
>             <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
>             <meta http-equiv="Content-Type" content="text/html;
> charset=utf-8">
>             <link rel="stylesheet" type="text/css"
> href="HelloWorld.min.css">
>             <script type="text/javascript" src="
> https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fhighlight.js%2F9.12.0%2Fhighlight.min.js&amp;data=02%7C01%7Caharui%40adobe.com%7C5db4fc1f0ed844113a9d08d7fc8e131f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255559454859456&amp;sdata=hoREedwRG%2BXVsuvx5zymqNpNPH3FlptAyChhInwZ%2F6E%3D&amp;reserved=0
> "
>
> onload="highlight.min.js.loaded=true;"></script>
>             <script type="text/javascript" src="./HelloWorld.js"></script>
>     </head>
>     <body>
>             <script type="text/javascript">
>                     var appInterval = setInterval(function() { if
> (highlight.min.js.loaded) {
>
>                                     clearInterval(appInterval);
>
>                                     new HelloWorld().start();
>
>                               }, 200);
>             </script>
>     </body>
>
>     Closure seems to use a hash of the URL instead of part of the URL to
> avoid collisions in case two different scripts are called main.js or
> something like that.  And there might be some better way than using
> setInterval, but the idea is to wait until the JS is loaded before calling
> start().
>
>     HTH,
>     -Alex
>
>     On 5/19/20, 12:18 PM, "Yishay Weiss" <yi...@hotmail.com> wrote:
>
>         See 99a8c8356573ff16b668f2d39a447355c673fee3
>
>         Note that hljs is an externs file so I couldn’t implement static
> initializers there.
>
>         There’s also a sort of a queue there for calls made before lib is
> loaded. I realize this doesn’t scale as a pattern, which is why I proposed
> to simplify annotations instead.
>
>         It could be of course there’s a simpler solution I’m missing.
>
>         From: Alex Harui<ma...@adobe.com.INVALID>
>         Sent: Tuesday, May 19, 2020 10:03 PM
>         To: dev@royale.apache.org<ma...@royale.apache.org>
>         Subject: Re: Script Loading Order (Continuing Heads-Up thread from
> Users)
>
>         Yishay,
>
>         I didn't think static initializers would require a façade or other
> fancy mechanism.  What kind of AS code ends up requiring this more complex
> solution?
>
>         -Alex
>
>         On 5/19/20, 10:34 AM, "Yishay Weiss" <yi...@hotmail.com>
> wrote:
>
>             Hi Carlos,
>
>             Sorry for not responding earlier, I missed this post.
>
>             I haven’t been able to replicate this in debug mode, so it’s
> interesting you’re seeing that.
>
>             I agree the façade solution is a bit cumbersome, but it works
> and maybe it’s worth having it out there as an example of using static
> initializers instead of injected code.
>
>             What do you think?
>
>             From: Carlos Rovira<ma...@apache.org>
>             Sent: Monday, May 18, 2020 7:34 PM
>             To: Apache Royale Development<ma...@royale.apache.org>
>             Subject: Re: Script Loading Order (Continuing Heads-Up thread
> from Users)
>
>             Hi Yishay,
>
>             I'm confused. The problem I reported was this;
>
>             ReferenceError: dialogPolyfill is not defined at
>
> /Users/carlosrovira/Dev/Royale/Source/royale-asjs/examples/jewel/TourDeJewel/target/javascript/bin/js-debug/App.js:10:1
>
>             And just as I'm copying here I'm seeing that while I'm running
>             "js-release", notice that the link refers to "js-debug", so I
> think there's
>             some wrong path involved here
>
>             I just updated with your latest change about hljs but I don't
> think we have
>             a problems with it. A part from that I don't like the solution
> to make a
>             Facade for a script, since that involves to create 2 classes
> instead of
>             one. The solution should be just make 1 as3 file (instead of
> two) and that
>             have the proper inject reference.
>
>             Please can you revert the hljsFacade?
>
>             thanks
>
>
>
>
>             El lun., 18 may. 2020 a las 17:44, Yishay Weiss (<
> yishayjobs@hotmail.com>)
>             escribió:
>
>             > Unless I missed something that’s what it’s doing right now
> after my fix.
>             > I’ll try to explain the scenario as I see it (no modules).
>             >
>             > Suppose we have an app that compiles to the following html.
>             >
>             > <html>
>             >                 <head>
>             >                                 <script
> type="text/javascript">
>             >                                                 var script =
>             > document.createElement("script");
>             >
>  script.setAttribute("src",
>             > "hljs.min.js");
>             >
>             > document.head.appendChild(script);
>             >                                 </script>
>             >                                 <script
> type=”text/JavaScript”
>             > src=”App.js”></script>
>             >                 </head>
>             >                 <body></body>
>             > </html>
>             >
>             > After the first script element is loaded, the dom will look
> like:
>             >
>             > <html>
>             >                 <head>
>             >                                 <script
> type="text/javascript">
>             >                                                 var script =
>             > document.createElement("script");
>             >
>  script.setAttribute("src",
>             > "hljs.min.js");
>             >
>             > document.head.appendChild(script);
>             >                                 </script>
>             >                                 <script
> type=”text/JavaScript”
>             > src=”hljs.min.js”></script>
>             >                                 <script
> type=”text/JavaScript”
>             > src=”App.js”></script>
>             >                 </head>
>             >                 <body></body>
>             > </html>
>             >
>             > However, App.js will still be loaded before hljs.min.js
> because it was not
>             > created dynamically. App.js will fail because it depends on
> hljs.
>             >
>             > From: Alex Harui<ma...@adobe.com.INVALID>
>             > Sent: Monday, May 18, 2020 6:21 PM
>             > To: dev@royale.apache.org<ma...@royale.apache.org>
>             > Subject: Re: Script Loading Order (Continuing Heads-Up
> thread from Users)
>             >
>             > I don't think we have to inject these scripts into the main
> .js file.  The
>             > compiler knows when it is compiling the main app or a
> module.  When
>             > compiling the main app, it should inject the script in the
> HEAD of the html
>             > wrapper.  For modules, it can inject the script into a
> separate file.  The
>             > ModuleLoader already loads extra files before loading the
> module.  It can
>             > load one more file.
>             >
>             > Of course, I could be wrong...
>             > -Alex
>             >
>             > On 5/18/20, 7:38 AM, "Yishay Weiss" <yi...@hotmail.com>
> wrote:
>             >
>             >     From what I’ve read [1] scripts injected dynamically
> will always load
>             > after static script elements. So I don’t think there’s a
> good way to ensure
>             > the proper order in run-time unless we do something like
>             > 99a8c8356573ff16b668f2d39a447355c673fee3 , but that’s
> verbose and working
>             > with libs should be simple.
>             >
>             >     Any ideas?
>             >
>             >     [1]
>             >
> https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.html5rocks.com%2Fen%2Ftutorials%2Fspeed%2Fscript-loading%2F%23disqus_thread&amp;data=02%7C01%7Caharui%40adobe.com%7C5db4fc1f0ed844113a9d08d7fc8e131f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255559454869451&amp;sdata=2EjRCIfbjT1okBPUCGBvDVvvv%2FYESige0uaJHppreo8%3D&amp;reserved=0
>             >
>             >     From: Alex Harui<ma...@adobe.com.INVALID>
>             >     Sent: Monday, May 18, 2020 8:03 AM
>             >     To: dev@royale.apache.org<ma...@royale.apache.org>
>             >
>             >
>             >     Subject: Re: Script Loading Order (Continuing Heads-Up
> thread from
>             > Users)
>             >
>             >     Every time I look, closure seems to change how it
> works.  It looks
>             > like they are using callbacks and UIDs.  I assume they can't
> use await or
>             > Promise because of IE support.  I haven't looked at the code
> you generate,
>             > but might have to do something similar, IOW, wait for the
> callback or known
>             > value before continuing.
>             >
>             >     I think that if we create the script during the running
> of another
>             > script that we have to find a way to wait for that created
> script.
>             >
>             >     It might help to know what kind of initialization code
> needed the
>             > definition so early.  One alternative is that such code
> needs to be
>             > responsible for waiting.
>             >
>             >     Most of our Application classes have a wait mechanism.
> We could
>             > leverage that, but that's also pretty late.
>             >
>             >     It could be that for Applications we generate the script
> in the head,
>             > and for modules we generate a separate script that is
> preloaded.
>             >
>             >     HTH,
>             >     -Alex
>             >
>             >     On 5/17/20, 9:03 AM, "Yishay Weiss" <
> yishayjobs@hotmail.com> wrote:
>             >
>             >
>             >         >Is the script tag from inject_script going before
> or after the
>             > script tag for the application (should be before, >IMO)?
>             >
>             >         It’s going before but the network shows it’s loaded
> after.
>             >
>             >         >Make sure the script tag has the same settings as
> the script tags
>             > google closure uses in js-debug.  I think they set some
> options so the
>             > scripts load in order.
>             >
>             >         I see type being specified in the gcl script
> elements, while
>             > inject ones don’t. I suppose it’s worth seeing if that makes
> a difference,
>             > though I couldn’t find evidence for that on the web.
>             >
>             >
>             >
>             >
>             >
>
>             --
>             Carlos Rovira
>
> https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fabout.me%2Fcarlosrovira&amp;data=02%7C01%7Caharui%40adobe.com%7C5db4fc1f0ed844113a9d08d7fc8e131f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255559454869451&amp;sdata=nuAIneqbkZeykwL3eG1ylsgJ9Xf%2FZXDSejyg4CJywhg%3D&amp;reserved=0
>
>
>
>
>
>
>
>

Re: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Carlos Rovira <ca...@apache.org>.
Thanks Josh,
TDJ error now seems to be gone :)

El mar., 2 jun. 2020 a las 9:13, Yishay Weiss (<yi...@hotmail.com>)
escribió:

> Looks good, thanks.
>
> ________________________________
> From: Josh Tynjala <jo...@bowlerhat.dev>
> Sent: Monday, June 1, 2020 6:59:07 PM
> To: Apache Royale Development <de...@royale.apache.org>
> Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
>
> Please give my latest royale-compiler commit a try. It should fix this
> ReferenceError.
>
> --
> Josh Tynjala
> Bowler Hat LLC <https://bowlerhat.dev>
>
>
> On Sun, May 31, 2020 at 8:13 AM Yishay Weiss <yi...@hotmail.com>
> wrote:
>
> > Here’s the minimal test case I came up with for demonstrating the
> problem.
> >
> > <?xml version="1.0" encoding="utf-8"?>
> > <js:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
> >                 xmlns:js="library://ns.apache.org/royale/basic"
> >                 >
> >        <fx:Script>
> >                        <![CDATA[
> >                 private function dummy():void
> >                 {
> >                                 dialogPolyfill;
> >                 }
> >                        ]]>
> >        </fx:Script>
> > </js:Application>
> >
> > Where dialogPolyfill is
> >
> > package
> > {
> >                 /**
> >                 * @externs
> >                 */
> >                 COMPILE::JS
> >                 public class dialogPolyfill
> >                 {
> >                 /**
> >          * <inject_script>
> >          * var script = document.createElement("script");
> >          * script.setAttribute("src", "
> >
> https://cdnjs.cloudflare.com/ajax/libs/dialog-polyfill/0.4.9/dialog-polyfill.min.js
> > ");
> >          * document.head.appendChild(script)
> >          * </inject_script>
> >                 */
> >                                 public function dialogPolyfill(){}
> >                 }
> > }
> >
> > In release I get a ‘ReferenceError: dialogPolyfill is not defined’
> >
> > u('dialogPolyfill',dialogPolyfill) of Examples.js, which is run before
> > start()
> >
> > So in order to fix this scenario we would need Examples.js to wait for
> > dialogPolyfill.min.js, not for start() to wait.
> >
> > From: Alex Harui<ma...@adobe.com.INVALID>
> > Sent: Wednesday, May 20, 2020 8:09 PM
> > To: dev@royale.apache.org<ma...@royale.apache.org>
> > Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
> >
> > When I mentioned static initializers in my earlier post, it was about the
> > timing of when some code would first access hljs.  Most externs will
> > probably be first used from code that runs after application.start().
> But
> > if someone did:
> >
> > public static var HLJSClass:Class = hljs;
> >
> > Then that would fail before we can run application.start(), except that
> > the compiler auto-converts static vars to lazy getters.
> >
> > However, the hljs usage is not wrapped, so there really aren't any static
> > initializers to use, so it doesn’t matter if they are lazy or not.  I
> > haven't looked at the other uses of inject_script, but if a class wraps
> the
> > dependency, then it can implement its own waiting strategy unless the API
> > has to be synchronous.  IOW, if I created a Highlighter class that used
> > hljs internally, then if the "highlight" API returns a void, the wrapping
> > implementation would load hljs.js and make the call when it is ready,
> which
> > is essentially building in the façade you wrote.
> >
> > You could implement a map of injected scripts, but after thinking about
> it
> > overnight, my first thought is to require that folks publish a var or uid
> > as follows:
> >
> >          * <inject_script var="hljs_loaded">
> >                 * var scriptLoaded = function() { hljs_loaded = true) };
> >                 * var script = document.createElement("script");
> >                 * script.setAttribute("src", "
> >
> https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js
> > ");
> >                 * script.addEventListener("load", scriptLoaded);
> >                 * document.head.appendChild(script);
> >             * </inject_script>
> >
> > Then the compiler may not need so much as a map, but can gather a list of
> > variables to watch for in the setInterval before calling
> > application.start();
> >
> > Of course, I could be wrong...
> > -Alex
> >
> > On 5/20/20, 12:19 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
> >
> >     Several questions/comments:
> >
> >
> >       1.  When you say static initializers should be lazy, do you mean
> > load on the first lib api call? If so, wouldn’t that force async calls?
> >       2.  Do you have a way of using static initializers for externs
> > files, which is how hljs was originally used?
> >       3.  To generate the script that waits for dynamically loaded
> scripts
> > (I guess we don’t mind async css, though I’m not sure) we would need to
> > have a map of injected scripts. So it looks like we’ll need to parse the
> > injected_sctipt tag in any case.
> >
> >     Thanks.
> >
> >
> >
> >     From: Alex Harui<ma...@adobe.com.INVALID>
> >     Sent: Wednesday, May 20, 2020 9:52 AM
> >     To: dev@royale.apache.org<ma...@royale.apache.org>
> >     Subject: Re: Script Loading Order (Continuing Heads-Up thread from
> > Users)
> >
> >     OK, I looked at the commit for hljs, and the code it replaced.
> > AFAICT, that is an instantiation phase dependency and not a
> initialization
> > phase dependency, so it should not matter if it loads before or after
> > app.js (unless someone does use it in a non-lazy static initializer,
> which
> > should be hard to do in Royale).  It should only matter that it is loaded
> > before anybody calls it.  Other than static initializers, which should
> all
> > be lazy, nobody should really call hljs until after the
> application.start()
> > is called in the index.html.
> >
> >     Here is the index.html for HelloWorld:
> >     <html>
> >     <head>
> >             <meta http-equiv="X-UA-Compatible"
> content="IE=edge,chrome=1">
> >             <meta http-equiv="Content-Type" content="text/html;
> > charset=utf-8">
> >             <link rel="stylesheet" type="text/css"
> > href="HelloWorld.min.css">
> >             <script type="text/javascript"
> src="./HelloWorld.js"></script>
> >     </head>
> >     <body>
> >             <script type="text/javascript">
> >                     new HelloWorld().start();
> >             </script>
> >     </body>
> >
> >     IMO, for applications that use inject_script (modules will use the
> > _deps file), we should generate code before the start() call that waits
> for
> > any dynamic scripts to load.  So if HelloWorld needed hljs, the
> index.html
> > would look more like:
> >
> >     <head>
> >             <meta http-equiv="X-UA-Compatible"
> content="IE=edge,chrome=1">
> >             <meta http-equiv="Content-Type" content="text/html;
> > charset=utf-8">
> >             <link rel="stylesheet" type="text/css"
> > href="HelloWorld.min.css">
> >             <script type="text/javascript" src="
> >
> https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fhighlight.js%2F9.12.0%2Fhighlight.min.js&amp;data=02%7C01%7Caharui%40adobe.com%7C5db4fc1f0ed844113a9d08d7fc8e131f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255559454859456&amp;sdata=hoREedwRG%2BXVsuvx5zymqNpNPH3FlptAyChhInwZ%2F6E%3D&amp;reserved=0
> > "
> >
> > onload="highlight.min.js.loaded=true;"></script>
> >             <script type="text/javascript"
> src="./HelloWorld.js"></script>
> >     </head>
> >     <body>
> >             <script type="text/javascript">
> >                     var appInterval = setInterval(function() { if
> > (highlight.min.js.loaded) {
> >
> >                                     clearInterval(appInterval);
> >
> >                                     new HelloWorld().start();
> >
> >                               }, 200);
> >             </script>
> >     </body>
> >
> >     Closure seems to use a hash of the URL instead of part of the URL to
> > avoid collisions in case two different scripts are called main.js or
> > something like that.  And there might be some better way than using
> > setInterval, but the idea is to wait until the JS is loaded before
> calling
> > start().
> >
> >     HTH,
> >     -Alex
> >
> >     On 5/19/20, 12:18 PM, "Yishay Weiss" <yi...@hotmail.com> wrote:
> >
> >         See 99a8c8356573ff16b668f2d39a447355c673fee3
> >
> >         Note that hljs is an externs file so I couldn’t implement static
> > initializers there.
> >
> >         There’s also a sort of a queue there for calls made before lib is
> > loaded. I realize this doesn’t scale as a pattern, which is why I
> proposed
> > to simplify annotations instead.
> >
> >         It could be of course there’s a simpler solution I’m missing.
> >
> >         From: Alex Harui<ma...@adobe.com.INVALID>
> >         Sent: Tuesday, May 19, 2020 10:03 PM
> >         To: dev@royale.apache.org<ma...@royale.apache.org>
> >         Subject: Re: Script Loading Order (Continuing Heads-Up thread
> from
> > Users)
> >
> >         Yishay,
> >
> >         I didn't think static initializers would require a façade or
> other
> > fancy mechanism.  What kind of AS code ends up requiring this more
> complex
> > solution?
> >
> >         -Alex
> >
> >         On 5/19/20, 10:34 AM, "Yishay Weiss" <yi...@hotmail.com>
> > wrote:
> >
> >             Hi Carlos,
> >
> >             Sorry for not responding earlier, I missed this post.
> >
> >             I haven’t been able to replicate this in debug mode, so it’s
> > interesting you’re seeing that.
> >
> >             I agree the façade solution is a bit cumbersome, but it works
> > and maybe it’s worth having it out there as an example of using static
> > initializers instead of injected code.
> >
> >             What do you think?
> >
> >             From: Carlos Rovira<ma...@apache.org>
> >             Sent: Monday, May 18, 2020 7:34 PM
> >             To: Apache Royale Development<ma...@royale.apache.org>
> >             Subject: Re: Script Loading Order (Continuing Heads-Up thread
> > from Users)
> >
> >             Hi Yishay,
> >
> >             I'm confused. The problem I reported was this;
> >
> >             ReferenceError: dialogPolyfill is not defined at
> >
> >
> /Users/carlosrovira/Dev/Royale/Source/royale-asjs/examples/jewel/TourDeJewel/target/javascript/bin/js-debug/App.js:10:1
> >
> >             And just as I'm copying here I'm seeing that while I'm
> running
> >             "js-release", notice that the link refers to "js-debug", so I
> > think there's
> >             some wrong path involved here
> >
> >             I just updated with your latest change about hljs but I don't
> > think we have
> >             a problems with it. A part from that I don't like the
> solution
> > to make a
> >             Facade for a script, since that involves to create 2 classes
> > instead of
> >             one. The solution should be just make 1 as3 file (instead of
> > two) and that
> >             have the proper inject reference.
> >
> >             Please can you revert the hljsFacade?
> >
> >             thanks
> >
> >
> >
> >
> >             El lun., 18 may. 2020 a las 17:44, Yishay Weiss (<
> > yishayjobs@hotmail.com>)
> >             escribió:
> >
> >             > Unless I missed something that’s what it’s doing right now
> > after my fix.
> >             > I’ll try to explain the scenario as I see it (no modules).
> >             >
> >             > Suppose we have an app that compiles to the following html.
> >             >
> >             > <html>
> >             >                 <head>
> >             >                                 <script
> > type="text/javascript">
> >             >                                                 var script
> =
> >             > document.createElement("script");
> >             >
> >  script.setAttribute("src",
> >             > "hljs.min.js");
> >             >
> >             > document.head.appendChild(script);
> >             >                                 </script>
> >             >                                 <script
> > type=”text/JavaScript”
> >             > src=”App.js”></script>
> >             >                 </head>
> >             >                 <body></body>
> >             > </html>
> >             >
> >             > After the first script element is loaded, the dom will look
> > like:
> >             >
> >             > <html>
> >             >                 <head>
> >             >                                 <script
> > type="text/javascript">
> >             >                                                 var script
> =
> >             > document.createElement("script");
> >             >
> >  script.setAttribute("src",
> >             > "hljs.min.js");
> >             >
> >             > document.head.appendChild(script);
> >             >                                 </script>
> >             >                                 <script
> > type=”text/JavaScript”
> >             > src=”hljs.min.js”></script>
> >             >                                 <script
> > type=”text/JavaScript”
> >             > src=”App.js”></script>
> >             >                 </head>
> >             >                 <body></body>
> >             > </html>
> >             >
> >             > However, App.js will still be loaded before hljs.min.js
> > because it was not
> >             > created dynamically. App.js will fail because it depends on
> > hljs.
> >             >
> >             > From: Alex Harui<ma...@adobe.com.INVALID>
> >             > Sent: Monday, May 18, 2020 6:21 PM
> >             > To: dev@royale.apache.org<ma...@royale.apache.org>
> >             > Subject: Re: Script Loading Order (Continuing Heads-Up
> > thread from Users)
> >             >
> >             > I don't think we have to inject these scripts into the main
> > .js file.  The
> >             > compiler knows when it is compiling the main app or a
> > module.  When
> >             > compiling the main app, it should inject the script in the
> > HEAD of the html
> >             > wrapper.  For modules, it can inject the script into a
> > separate file.  The
> >             > ModuleLoader already loads extra files before loading the
> > module.  It can
> >             > load one more file.
> >             >
> >             > Of course, I could be wrong...
> >             > -Alex
> >             >
> >             > On 5/18/20, 7:38 AM, "Yishay Weiss" <
> yishayjobs@hotmail.com>
> > wrote:
> >             >
> >             >     From what I’ve read [1] scripts injected dynamically
> > will always load
> >             > after static script elements. So I don’t think there’s a
> > good way to ensure
> >             > the proper order in run-time unless we do something like
> >             > 99a8c8356573ff16b668f2d39a447355c673fee3 , but that’s
> > verbose and working
> >             > with libs should be simple.
> >             >
> >             >     Any ideas?
> >             >
> >             >     [1]
> >             >
> >
> https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.html5rocks.com%2Fen%2Ftutorials%2Fspeed%2Fscript-loading%2F%23disqus_thread&amp;data=02%7C01%7Caharui%40adobe.com%7C5db4fc1f0ed844113a9d08d7fc8e131f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255559454869451&amp;sdata=2EjRCIfbjT1okBPUCGBvDVvvv%2FYESige0uaJHppreo8%3D&amp;reserved=0
> >             >
> >             >     From: Alex Harui<ma...@adobe.com.INVALID>
> >             >     Sent: Monday, May 18, 2020 8:03 AM
> >             >     To: dev@royale.apache.org<mailto:dev@royale.apache.org
> >
> >             >
> >             >
> >             >     Subject: Re: Script Loading Order (Continuing Heads-Up
> > thread from
> >             > Users)
> >             >
> >             >     Every time I look, closure seems to change how it
> > works.  It looks
> >             > like they are using callbacks and UIDs.  I assume they
> can't
> > use await or
> >             > Promise because of IE support.  I haven't looked at the
> code
> > you generate,
> >             > but might have to do something similar, IOW, wait for the
> > callback or known
> >             > value before continuing.
> >             >
> >             >     I think that if we create the script during the running
> > of another
> >             > script that we have to find a way to wait for that created
> > script.
> >             >
> >             >     It might help to know what kind of initialization code
> > needed the
> >             > definition so early.  One alternative is that such code
> > needs to be
> >             > responsible for waiting.
> >             >
> >             >     Most of our Application classes have a wait mechanism.
> > We could
> >             > leverage that, but that's also pretty late.
> >             >
> >             >     It could be that for Applications we generate the
> script
> > in the head,
> >             > and for modules we generate a separate script that is
> > preloaded.
> >             >
> >             >     HTH,
> >             >     -Alex
> >             >
> >             >     On 5/17/20, 9:03 AM, "Yishay Weiss" <
> > yishayjobs@hotmail.com> wrote:
> >             >
> >             >
> >             >         >Is the script tag from inject_script going before
> > or after the
> >             > script tag for the application (should be before, >IMO)?
> >             >
> >             >         It’s going before but the network shows it’s loaded
> > after.
> >             >
> >             >         >Make sure the script tag has the same settings as
> > the script tags
> >             > google closure uses in js-debug.  I think they set some
> > options so the
> >             > scripts load in order.
> >             >
> >             >         I see type being specified in the gcl script
> > elements, while
> >             > inject ones don’t. I suppose it’s worth seeing if that
> makes
> > a difference,
> >             > though I couldn’t find evidence for that on the web.
> >             >
> >             >
> >             >
> >             >
> >             >
> >
> >             --
> >             Carlos Rovira
> >
> >
> https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fabout.me%2Fcarlosrovira&amp;data=02%7C01%7Caharui%40adobe.com%7C5db4fc1f0ed844113a9d08d7fc8e131f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255559454869451&amp;sdata=nuAIneqbkZeykwL3eG1ylsgJ9Xf%2FZXDSejyg4CJywhg%3D&amp;reserved=0
> >
> >
> >
> >
> >
> >
> >
> >
>


-- 
Carlos Rovira
http://about.me/carlosrovira

RE: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Yishay Weiss <yi...@hotmail.com>.
Looks good, thanks.

________________________________
From: Josh Tynjala <jo...@bowlerhat.dev>
Sent: Monday, June 1, 2020 6:59:07 PM
To: Apache Royale Development <de...@royale.apache.org>
Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

Please give my latest royale-compiler commit a try. It should fix this
ReferenceError.

--
Josh Tynjala
Bowler Hat LLC <https://bowlerhat.dev>


On Sun, May 31, 2020 at 8:13 AM Yishay Weiss <yi...@hotmail.com> wrote:

> Here’s the minimal test case I came up with for demonstrating the problem.
>
> <?xml version="1.0" encoding="utf-8"?>
> <js:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
>                 xmlns:js="library://ns.apache.org/royale/basic"
>                 >
>        <fx:Script>
>                        <![CDATA[
>                 private function dummy():void
>                 {
>                                 dialogPolyfill;
>                 }
>                        ]]>
>        </fx:Script>
> </js:Application>
>
> Where dialogPolyfill is
>
> package
> {
>                 /**
>                 * @externs
>                 */
>                 COMPILE::JS
>                 public class dialogPolyfill
>                 {
>                 /**
>          * <inject_script>
>          * var script = document.createElement("script");
>          * script.setAttribute("src", "
> https://cdnjs.cloudflare.com/ajax/libs/dialog-polyfill/0.4.9/dialog-polyfill.min.js
> ");
>          * document.head.appendChild(script)
>          * </inject_script>
>                 */
>                                 public function dialogPolyfill(){}
>                 }
> }
>
> In release I get a ‘ReferenceError: dialogPolyfill is not defined’
>
> u('dialogPolyfill',dialogPolyfill) of Examples.js, which is run before
> start()
>
> So in order to fix this scenario we would need Examples.js to wait for
> dialogPolyfill.min.js, not for start() to wait.
>
> From: Alex Harui<ma...@adobe.com.INVALID>
> Sent: Wednesday, May 20, 2020 8:09 PM
> To: dev@royale.apache.org<ma...@royale.apache.org>
> Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
>
> When I mentioned static initializers in my earlier post, it was about the
> timing of when some code would first access hljs.  Most externs will
> probably be first used from code that runs after application.start().  But
> if someone did:
>
> public static var HLJSClass:Class = hljs;
>
> Then that would fail before we can run application.start(), except that
> the compiler auto-converts static vars to lazy getters.
>
> However, the hljs usage is not wrapped, so there really aren't any static
> initializers to use, so it doesn’t matter if they are lazy or not.  I
> haven't looked at the other uses of inject_script, but if a class wraps the
> dependency, then it can implement its own waiting strategy unless the API
> has to be synchronous.  IOW, if I created a Highlighter class that used
> hljs internally, then if the "highlight" API returns a void, the wrapping
> implementation would load hljs.js and make the call when it is ready, which
> is essentially building in the façade you wrote.
>
> You could implement a map of injected scripts, but after thinking about it
> overnight, my first thought is to require that folks publish a var or uid
> as follows:
>
>          * <inject_script var="hljs_loaded">
>                 * var scriptLoaded = function() { hljs_loaded = true) };
>                 * var script = document.createElement("script");
>                 * script.setAttribute("src", "
> https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js
> ");
>                 * script.addEventListener("load", scriptLoaded);
>                 * document.head.appendChild(script);
>             * </inject_script>
>
> Then the compiler may not need so much as a map, but can gather a list of
> variables to watch for in the setInterval before calling
> application.start();
>
> Of course, I could be wrong...
> -Alex
>
> On 5/20/20, 12:19 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
>
>     Several questions/comments:
>
>
>       1.  When you say static initializers should be lazy, do you mean
> load on the first lib api call? If so, wouldn’t that force async calls?
>       2.  Do you have a way of using static initializers for externs
> files, which is how hljs was originally used?
>       3.  To generate the script that waits for dynamically loaded scripts
> (I guess we don’t mind async css, though I’m not sure) we would need to
> have a map of injected scripts. So it looks like we’ll need to parse the
> injected_sctipt tag in any case.
>
>     Thanks.
>
>
>
>     From: Alex Harui<ma...@adobe.com.INVALID>
>     Sent: Wednesday, May 20, 2020 9:52 AM
>     To: dev@royale.apache.org<ma...@royale.apache.org>
>     Subject: Re: Script Loading Order (Continuing Heads-Up thread from
> Users)
>
>     OK, I looked at the commit for hljs, and the code it replaced.
> AFAICT, that is an instantiation phase dependency and not a initialization
> phase dependency, so it should not matter if it loads before or after
> app.js (unless someone does use it in a non-lazy static initializer, which
> should be hard to do in Royale).  It should only matter that it is loaded
> before anybody calls it.  Other than static initializers, which should all
> be lazy, nobody should really call hljs until after the application.start()
> is called in the index.html.
>
>     Here is the index.html for HelloWorld:
>     <html>
>     <head>
>             <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
>             <meta http-equiv="Content-Type" content="text/html;
> charset=utf-8">
>             <link rel="stylesheet" type="text/css"
> href="HelloWorld.min.css">
>             <script type="text/javascript" src="./HelloWorld.js"></script>
>     </head>
>     <body>
>             <script type="text/javascript">
>                     new HelloWorld().start();
>             </script>
>     </body>
>
>     IMO, for applications that use inject_script (modules will use the
> _deps file), we should generate code before the start() call that waits for
> any dynamic scripts to load.  So if HelloWorld needed hljs, the index.html
> would look more like:
>
>     <head>
>             <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
>             <meta http-equiv="Content-Type" content="text/html;
> charset=utf-8">
>             <link rel="stylesheet" type="text/css"
> href="HelloWorld.min.css">
>             <script type="text/javascript" src="
> https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fhighlight.js%2F9.12.0%2Fhighlight.min.js&amp;data=02%7C01%7Caharui%40adobe.com%7C5db4fc1f0ed844113a9d08d7fc8e131f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255559454859456&amp;sdata=hoREedwRG%2BXVsuvx5zymqNpNPH3FlptAyChhInwZ%2F6E%3D&amp;reserved=0
> "
>
> onload="highlight.min.js.loaded=true;"></script>
>             <script type="text/javascript" src="./HelloWorld.js"></script>
>     </head>
>     <body>
>             <script type="text/javascript">
>                     var appInterval = setInterval(function() { if
> (highlight.min.js.loaded) {
>
>                                     clearInterval(appInterval);
>
>                                     new HelloWorld().start();
>
>                               }, 200);
>             </script>
>     </body>
>
>     Closure seems to use a hash of the URL instead of part of the URL to
> avoid collisions in case two different scripts are called main.js or
> something like that.  And there might be some better way than using
> setInterval, but the idea is to wait until the JS is loaded before calling
> start().
>
>     HTH,
>     -Alex
>
>     On 5/19/20, 12:18 PM, "Yishay Weiss" <yi...@hotmail.com> wrote:
>
>         See 99a8c8356573ff16b668f2d39a447355c673fee3
>
>         Note that hljs is an externs file so I couldn’t implement static
> initializers there.
>
>         There’s also a sort of a queue there for calls made before lib is
> loaded. I realize this doesn’t scale as a pattern, which is why I proposed
> to simplify annotations instead.
>
>         It could be of course there’s a simpler solution I’m missing.
>
>         From: Alex Harui<ma...@adobe.com.INVALID>
>         Sent: Tuesday, May 19, 2020 10:03 PM
>         To: dev@royale.apache.org<ma...@royale.apache.org>
>         Subject: Re: Script Loading Order (Continuing Heads-Up thread from
> Users)
>
>         Yishay,
>
>         I didn't think static initializers would require a façade or other
> fancy mechanism.  What kind of AS code ends up requiring this more complex
> solution?
>
>         -Alex
>
>         On 5/19/20, 10:34 AM, "Yishay Weiss" <yi...@hotmail.com>
> wrote:
>
>             Hi Carlos,
>
>             Sorry for not responding earlier, I missed this post.
>
>             I haven’t been able to replicate this in debug mode, so it’s
> interesting you’re seeing that.
>
>             I agree the façade solution is a bit cumbersome, but it works
> and maybe it’s worth having it out there as an example of using static
> initializers instead of injected code.
>
>             What do you think?
>
>             From: Carlos Rovira<ma...@apache.org>
>             Sent: Monday, May 18, 2020 7:34 PM
>             To: Apache Royale Development<ma...@royale.apache.org>
>             Subject: Re: Script Loading Order (Continuing Heads-Up thread
> from Users)
>
>             Hi Yishay,
>
>             I'm confused. The problem I reported was this;
>
>             ReferenceError: dialogPolyfill is not defined at
>
> /Users/carlosrovira/Dev/Royale/Source/royale-asjs/examples/jewel/TourDeJewel/target/javascript/bin/js-debug/App.js:10:1
>
>             And just as I'm copying here I'm seeing that while I'm running
>             "js-release", notice that the link refers to "js-debug", so I
> think there's
>             some wrong path involved here
>
>             I just updated with your latest change about hljs but I don't
> think we have
>             a problems with it. A part from that I don't like the solution
> to make a
>             Facade for a script, since that involves to create 2 classes
> instead of
>             one. The solution should be just make 1 as3 file (instead of
> two) and that
>             have the proper inject reference.
>
>             Please can you revert the hljsFacade?
>
>             thanks
>
>
>
>
>             El lun., 18 may. 2020 a las 17:44, Yishay Weiss (<
> yishayjobs@hotmail.com>)
>             escribió:
>
>             > Unless I missed something that’s what it’s doing right now
> after my fix.
>             > I’ll try to explain the scenario as I see it (no modules).
>             >
>             > Suppose we have an app that compiles to the following html.
>             >
>             > <html>
>             >                 <head>
>             >                                 <script
> type="text/javascript">
>             >                                                 var script =
>             > document.createElement("script");
>             >
>  script.setAttribute("src",
>             > "hljs.min.js");
>             >
>             > document.head.appendChild(script);
>             >                                 </script>
>             >                                 <script
> type=”text/JavaScript”
>             > src=”App.js”></script>
>             >                 </head>
>             >                 <body></body>
>             > </html>
>             >
>             > After the first script element is loaded, the dom will look
> like:
>             >
>             > <html>
>             >                 <head>
>             >                                 <script
> type="text/javascript">
>             >                                                 var script =
>             > document.createElement("script");
>             >
>  script.setAttribute("src",
>             > "hljs.min.js");
>             >
>             > document.head.appendChild(script);
>             >                                 </script>
>             >                                 <script
> type=”text/JavaScript”
>             > src=”hljs.min.js”></script>
>             >                                 <script
> type=”text/JavaScript”
>             > src=”App.js”></script>
>             >                 </head>
>             >                 <body></body>
>             > </html>
>             >
>             > However, App.js will still be loaded before hljs.min.js
> because it was not
>             > created dynamically. App.js will fail because it depends on
> hljs.
>             >
>             > From: Alex Harui<ma...@adobe.com.INVALID>
>             > Sent: Monday, May 18, 2020 6:21 PM
>             > To: dev@royale.apache.org<ma...@royale.apache.org>
>             > Subject: Re: Script Loading Order (Continuing Heads-Up
> thread from Users)
>             >
>             > I don't think we have to inject these scripts into the main
> .js file.  The
>             > compiler knows when it is compiling the main app or a
> module.  When
>             > compiling the main app, it should inject the script in the
> HEAD of the html
>             > wrapper.  For modules, it can inject the script into a
> separate file.  The
>             > ModuleLoader already loads extra files before loading the
> module.  It can
>             > load one more file.
>             >
>             > Of course, I could be wrong...
>             > -Alex
>             >
>             > On 5/18/20, 7:38 AM, "Yishay Weiss" <yi...@hotmail.com>
> wrote:
>             >
>             >     From what I’ve read [1] scripts injected dynamically
> will always load
>             > after static script elements. So I don’t think there’s a
> good way to ensure
>             > the proper order in run-time unless we do something like
>             > 99a8c8356573ff16b668f2d39a447355c673fee3 , but that’s
> verbose and working
>             > with libs should be simple.
>             >
>             >     Any ideas?
>             >
>             >     [1]
>             >
> https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.html5rocks.com%2Fen%2Ftutorials%2Fspeed%2Fscript-loading%2F%23disqus_thread&amp;data=02%7C01%7Caharui%40adobe.com%7C5db4fc1f0ed844113a9d08d7fc8e131f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255559454869451&amp;sdata=2EjRCIfbjT1okBPUCGBvDVvvv%2FYESige0uaJHppreo8%3D&amp;reserved=0
>             >
>             >     From: Alex Harui<ma...@adobe.com.INVALID>
>             >     Sent: Monday, May 18, 2020 8:03 AM
>             >     To: dev@royale.apache.org<ma...@royale.apache.org>
>             >
>             >
>             >     Subject: Re: Script Loading Order (Continuing Heads-Up
> thread from
>             > Users)
>             >
>             >     Every time I look, closure seems to change how it
> works.  It looks
>             > like they are using callbacks and UIDs.  I assume they can't
> use await or
>             > Promise because of IE support.  I haven't looked at the code
> you generate,
>             > but might have to do something similar, IOW, wait for the
> callback or known
>             > value before continuing.
>             >
>             >     I think that if we create the script during the running
> of another
>             > script that we have to find a way to wait for that created
> script.
>             >
>             >     It might help to know what kind of initialization code
> needed the
>             > definition so early.  One alternative is that such code
> needs to be
>             > responsible for waiting.
>             >
>             >     Most of our Application classes have a wait mechanism.
> We could
>             > leverage that, but that's also pretty late.
>             >
>             >     It could be that for Applications we generate the script
> in the head,
>             > and for modules we generate a separate script that is
> preloaded.
>             >
>             >     HTH,
>             >     -Alex
>             >
>             >     On 5/17/20, 9:03 AM, "Yishay Weiss" <
> yishayjobs@hotmail.com> wrote:
>             >
>             >
>             >         >Is the script tag from inject_script going before
> or after the
>             > script tag for the application (should be before, >IMO)?
>             >
>             >         It’s going before but the network shows it’s loaded
> after.
>             >
>             >         >Make sure the script tag has the same settings as
> the script tags
>             > google closure uses in js-debug.  I think they set some
> options so the
>             > scripts load in order.
>             >
>             >         I see type being specified in the gcl script
> elements, while
>             > inject ones don’t. I suppose it’s worth seeing if that makes
> a difference,
>             > though I couldn’t find evidence for that on the web.
>             >
>             >
>             >
>             >
>             >
>
>             --
>             Carlos Rovira
>
> https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fabout.me%2Fcarlosrovira&amp;data=02%7C01%7Caharui%40adobe.com%7C5db4fc1f0ed844113a9d08d7fc8e131f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255559454869451&amp;sdata=nuAIneqbkZeykwL3eG1ylsgJ9Xf%2FZXDSejyg4CJywhg%3D&amp;reserved=0
>
>
>
>
>
>
>
>

Re: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Josh Tynjala <jo...@bowlerhat.dev>.
Please give my latest royale-compiler commit a try. It should fix this
ReferenceError.

--
Josh Tynjala
Bowler Hat LLC <https://bowlerhat.dev>


On Sun, May 31, 2020 at 8:13 AM Yishay Weiss <yi...@hotmail.com> wrote:

> Here’s the minimal test case I came up with for demonstrating the problem.
>
> <?xml version="1.0" encoding="utf-8"?>
> <js:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
>                 xmlns:js="library://ns.apache.org/royale/basic"
>                 >
>        <fx:Script>
>                        <![CDATA[
>                 private function dummy():void
>                 {
>                                 dialogPolyfill;
>                 }
>                        ]]>
>        </fx:Script>
> </js:Application>
>
> Where dialogPolyfill is
>
> package
> {
>                 /**
>                 * @externs
>                 */
>                 COMPILE::JS
>                 public class dialogPolyfill
>                 {
>                 /**
>          * <inject_script>
>          * var script = document.createElement("script");
>          * script.setAttribute("src", "
> https://cdnjs.cloudflare.com/ajax/libs/dialog-polyfill/0.4.9/dialog-polyfill.min.js
> ");
>          * document.head.appendChild(script)
>          * </inject_script>
>                 */
>                                 public function dialogPolyfill(){}
>                 }
> }
>
> In release I get a ‘ReferenceError: dialogPolyfill is not defined’
>
> u('dialogPolyfill',dialogPolyfill) of Examples.js, which is run before
> start()
>
> So in order to fix this scenario we would need Examples.js to wait for
> dialogPolyfill.min.js, not for start() to wait.
>
> From: Alex Harui<ma...@adobe.com.INVALID>
> Sent: Wednesday, May 20, 2020 8:09 PM
> To: dev@royale.apache.org<ma...@royale.apache.org>
> Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
>
> When I mentioned static initializers in my earlier post, it was about the
> timing of when some code would first access hljs.  Most externs will
> probably be first used from code that runs after application.start().  But
> if someone did:
>
> public static var HLJSClass:Class = hljs;
>
> Then that would fail before we can run application.start(), except that
> the compiler auto-converts static vars to lazy getters.
>
> However, the hljs usage is not wrapped, so there really aren't any static
> initializers to use, so it doesn’t matter if they are lazy or not.  I
> haven't looked at the other uses of inject_script, but if a class wraps the
> dependency, then it can implement its own waiting strategy unless the API
> has to be synchronous.  IOW, if I created a Highlighter class that used
> hljs internally, then if the "highlight" API returns a void, the wrapping
> implementation would load hljs.js and make the call when it is ready, which
> is essentially building in the façade you wrote.
>
> You could implement a map of injected scripts, but after thinking about it
> overnight, my first thought is to require that folks publish a var or uid
> as follows:
>
>          * <inject_script var="hljs_loaded">
>                 * var scriptLoaded = function() { hljs_loaded = true) };
>                 * var script = document.createElement("script");
>                 * script.setAttribute("src", "
> https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js
> ");
>                 * script.addEventListener("load", scriptLoaded);
>                 * document.head.appendChild(script);
>             * </inject_script>
>
> Then the compiler may not need so much as a map, but can gather a list of
> variables to watch for in the setInterval before calling
> application.start();
>
> Of course, I could be wrong...
> -Alex
>
> On 5/20/20, 12:19 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
>
>     Several questions/comments:
>
>
>       1.  When you say static initializers should be lazy, do you mean
> load on the first lib api call? If so, wouldn’t that force async calls?
>       2.  Do you have a way of using static initializers for externs
> files, which is how hljs was originally used?
>       3.  To generate the script that waits for dynamically loaded scripts
> (I guess we don’t mind async css, though I’m not sure) we would need to
> have a map of injected scripts. So it looks like we’ll need to parse the
> injected_sctipt tag in any case.
>
>     Thanks.
>
>
>
>     From: Alex Harui<ma...@adobe.com.INVALID>
>     Sent: Wednesday, May 20, 2020 9:52 AM
>     To: dev@royale.apache.org<ma...@royale.apache.org>
>     Subject: Re: Script Loading Order (Continuing Heads-Up thread from
> Users)
>
>     OK, I looked at the commit for hljs, and the code it replaced.
> AFAICT, that is an instantiation phase dependency and not a initialization
> phase dependency, so it should not matter if it loads before or after
> app.js (unless someone does use it in a non-lazy static initializer, which
> should be hard to do in Royale).  It should only matter that it is loaded
> before anybody calls it.  Other than static initializers, which should all
> be lazy, nobody should really call hljs until after the application.start()
> is called in the index.html.
>
>     Here is the index.html for HelloWorld:
>     <html>
>     <head>
>             <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
>             <meta http-equiv="Content-Type" content="text/html;
> charset=utf-8">
>             <link rel="stylesheet" type="text/css"
> href="HelloWorld.min.css">
>             <script type="text/javascript" src="./HelloWorld.js"></script>
>     </head>
>     <body>
>             <script type="text/javascript">
>                     new HelloWorld().start();
>             </script>
>     </body>
>
>     IMO, for applications that use inject_script (modules will use the
> _deps file), we should generate code before the start() call that waits for
> any dynamic scripts to load.  So if HelloWorld needed hljs, the index.html
> would look more like:
>
>     <head>
>             <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
>             <meta http-equiv="Content-Type" content="text/html;
> charset=utf-8">
>             <link rel="stylesheet" type="text/css"
> href="HelloWorld.min.css">
>             <script type="text/javascript" src="
> https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fhighlight.js%2F9.12.0%2Fhighlight.min.js&amp;data=02%7C01%7Caharui%40adobe.com%7C5db4fc1f0ed844113a9d08d7fc8e131f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255559454859456&amp;sdata=hoREedwRG%2BXVsuvx5zymqNpNPH3FlptAyChhInwZ%2F6E%3D&amp;reserved=0
> "
>
> onload="highlight.min.js.loaded=true;"></script>
>             <script type="text/javascript" src="./HelloWorld.js"></script>
>     </head>
>     <body>
>             <script type="text/javascript">
>                     var appInterval = setInterval(function() { if
> (highlight.min.js.loaded) {
>
>                                     clearInterval(appInterval);
>
>                                     new HelloWorld().start();
>
>                               }, 200);
>             </script>
>     </body>
>
>     Closure seems to use a hash of the URL instead of part of the URL to
> avoid collisions in case two different scripts are called main.js or
> something like that.  And there might be some better way than using
> setInterval, but the idea is to wait until the JS is loaded before calling
> start().
>
>     HTH,
>     -Alex
>
>     On 5/19/20, 12:18 PM, "Yishay Weiss" <yi...@hotmail.com> wrote:
>
>         See 99a8c8356573ff16b668f2d39a447355c673fee3
>
>         Note that hljs is an externs file so I couldn’t implement static
> initializers there.
>
>         There’s also a sort of a queue there for calls made before lib is
> loaded. I realize this doesn’t scale as a pattern, which is why I proposed
> to simplify annotations instead.
>
>         It could be of course there’s a simpler solution I’m missing.
>
>         From: Alex Harui<ma...@adobe.com.INVALID>
>         Sent: Tuesday, May 19, 2020 10:03 PM
>         To: dev@royale.apache.org<ma...@royale.apache.org>
>         Subject: Re: Script Loading Order (Continuing Heads-Up thread from
> Users)
>
>         Yishay,
>
>         I didn't think static initializers would require a façade or other
> fancy mechanism.  What kind of AS code ends up requiring this more complex
> solution?
>
>         -Alex
>
>         On 5/19/20, 10:34 AM, "Yishay Weiss" <yi...@hotmail.com>
> wrote:
>
>             Hi Carlos,
>
>             Sorry for not responding earlier, I missed this post.
>
>             I haven’t been able to replicate this in debug mode, so it’s
> interesting you’re seeing that.
>
>             I agree the façade solution is a bit cumbersome, but it works
> and maybe it’s worth having it out there as an example of using static
> initializers instead of injected code.
>
>             What do you think?
>
>             From: Carlos Rovira<ma...@apache.org>
>             Sent: Monday, May 18, 2020 7:34 PM
>             To: Apache Royale Development<ma...@royale.apache.org>
>             Subject: Re: Script Loading Order (Continuing Heads-Up thread
> from Users)
>
>             Hi Yishay,
>
>             I'm confused. The problem I reported was this;
>
>             ReferenceError: dialogPolyfill is not defined at
>
> /Users/carlosrovira/Dev/Royale/Source/royale-asjs/examples/jewel/TourDeJewel/target/javascript/bin/js-debug/App.js:10:1
>
>             And just as I'm copying here I'm seeing that while I'm running
>             "js-release", notice that the link refers to "js-debug", so I
> think there's
>             some wrong path involved here
>
>             I just updated with your latest change about hljs but I don't
> think we have
>             a problems with it. A part from that I don't like the solution
> to make a
>             Facade for a script, since that involves to create 2 classes
> instead of
>             one. The solution should be just make 1 as3 file (instead of
> two) and that
>             have the proper inject reference.
>
>             Please can you revert the hljsFacade?
>
>             thanks
>
>
>
>
>             El lun., 18 may. 2020 a las 17:44, Yishay Weiss (<
> yishayjobs@hotmail.com>)
>             escribió:
>
>             > Unless I missed something that’s what it’s doing right now
> after my fix.
>             > I’ll try to explain the scenario as I see it (no modules).
>             >
>             > Suppose we have an app that compiles to the following html.
>             >
>             > <html>
>             >                 <head>
>             >                                 <script
> type="text/javascript">
>             >                                                 var script =
>             > document.createElement("script");
>             >
>  script.setAttribute("src",
>             > "hljs.min.js");
>             >
>             > document.head.appendChild(script);
>             >                                 </script>
>             >                                 <script
> type=”text/JavaScript”
>             > src=”App.js”></script>
>             >                 </head>
>             >                 <body></body>
>             > </html>
>             >
>             > After the first script element is loaded, the dom will look
> like:
>             >
>             > <html>
>             >                 <head>
>             >                                 <script
> type="text/javascript">
>             >                                                 var script =
>             > document.createElement("script");
>             >
>  script.setAttribute("src",
>             > "hljs.min.js");
>             >
>             > document.head.appendChild(script);
>             >                                 </script>
>             >                                 <script
> type=”text/JavaScript”
>             > src=”hljs.min.js”></script>
>             >                                 <script
> type=”text/JavaScript”
>             > src=”App.js”></script>
>             >                 </head>
>             >                 <body></body>
>             > </html>
>             >
>             > However, App.js will still be loaded before hljs.min.js
> because it was not
>             > created dynamically. App.js will fail because it depends on
> hljs.
>             >
>             > From: Alex Harui<ma...@adobe.com.INVALID>
>             > Sent: Monday, May 18, 2020 6:21 PM
>             > To: dev@royale.apache.org<ma...@royale.apache.org>
>             > Subject: Re: Script Loading Order (Continuing Heads-Up
> thread from Users)
>             >
>             > I don't think we have to inject these scripts into the main
> .js file.  The
>             > compiler knows when it is compiling the main app or a
> module.  When
>             > compiling the main app, it should inject the script in the
> HEAD of the html
>             > wrapper.  For modules, it can inject the script into a
> separate file.  The
>             > ModuleLoader already loads extra files before loading the
> module.  It can
>             > load one more file.
>             >
>             > Of course, I could be wrong...
>             > -Alex
>             >
>             > On 5/18/20, 7:38 AM, "Yishay Weiss" <yi...@hotmail.com>
> wrote:
>             >
>             >     From what I’ve read [1] scripts injected dynamically
> will always load
>             > after static script elements. So I don’t think there’s a
> good way to ensure
>             > the proper order in run-time unless we do something like
>             > 99a8c8356573ff16b668f2d39a447355c673fee3 , but that’s
> verbose and working
>             > with libs should be simple.
>             >
>             >     Any ideas?
>             >
>             >     [1]
>             >
> https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.html5rocks.com%2Fen%2Ftutorials%2Fspeed%2Fscript-loading%2F%23disqus_thread&amp;data=02%7C01%7Caharui%40adobe.com%7C5db4fc1f0ed844113a9d08d7fc8e131f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255559454869451&amp;sdata=2EjRCIfbjT1okBPUCGBvDVvvv%2FYESige0uaJHppreo8%3D&amp;reserved=0
>             >
>             >     From: Alex Harui<ma...@adobe.com.INVALID>
>             >     Sent: Monday, May 18, 2020 8:03 AM
>             >     To: dev@royale.apache.org<ma...@royale.apache.org>
>             >
>             >
>             >     Subject: Re: Script Loading Order (Continuing Heads-Up
> thread from
>             > Users)
>             >
>             >     Every time I look, closure seems to change how it
> works.  It looks
>             > like they are using callbacks and UIDs.  I assume they can't
> use await or
>             > Promise because of IE support.  I haven't looked at the code
> you generate,
>             > but might have to do something similar, IOW, wait for the
> callback or known
>             > value before continuing.
>             >
>             >     I think that if we create the script during the running
> of another
>             > script that we have to find a way to wait for that created
> script.
>             >
>             >     It might help to know what kind of initialization code
> needed the
>             > definition so early.  One alternative is that such code
> needs to be
>             > responsible for waiting.
>             >
>             >     Most of our Application classes have a wait mechanism.
> We could
>             > leverage that, but that's also pretty late.
>             >
>             >     It could be that for Applications we generate the script
> in the head,
>             > and for modules we generate a separate script that is
> preloaded.
>             >
>             >     HTH,
>             >     -Alex
>             >
>             >     On 5/17/20, 9:03 AM, "Yishay Weiss" <
> yishayjobs@hotmail.com> wrote:
>             >
>             >
>             >         >Is the script tag from inject_script going before
> or after the
>             > script tag for the application (should be before, >IMO)?
>             >
>             >         It’s going before but the network shows it’s loaded
> after.
>             >
>             >         >Make sure the script tag has the same settings as
> the script tags
>             > google closure uses in js-debug.  I think they set some
> options so the
>             > scripts load in order.
>             >
>             >         I see type being specified in the gcl script
> elements, while
>             > inject ones don’t. I suppose it’s worth seeing if that makes
> a difference,
>             > though I couldn’t find evidence for that on the web.
>             >
>             >
>             >
>             >
>             >
>
>             --
>             Carlos Rovira
>
> https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fabout.me%2Fcarlosrovira&amp;data=02%7C01%7Caharui%40adobe.com%7C5db4fc1f0ed844113a9d08d7fc8e131f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255559454869451&amp;sdata=nuAIneqbkZeykwL3eG1ylsgJ9Xf%2FZXDSejyg4CJywhg%3D&amp;reserved=0
>
>
>
>
>
>
>
>

RE: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Yishay Weiss <yi...@hotmail.com>.
Here’s the minimal test case I came up with for demonstrating the problem.

<?xml version="1.0" encoding="utf-8"?>
<js:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
                xmlns:js="library://ns.apache.org/royale/basic"
                >
       <fx:Script>
                       <![CDATA[
                private function dummy():void
                {
                                dialogPolyfill;
                }
                       ]]>
       </fx:Script>
</js:Application>

Where dialogPolyfill is

package
{
                /**
                * @externs
                */
                COMPILE::JS
                public class dialogPolyfill
                {
                /**
         * <inject_script>
         * var script = document.createElement("script");
         * script.setAttribute("src", "https://cdnjs.cloudflare.com/ajax/libs/dialog-polyfill/0.4.9/dialog-polyfill.min.js");
         * document.head.appendChild(script)
         * </inject_script>
                */
                                public function dialogPolyfill(){}
                }
}

In release I get a ‘ReferenceError: dialogPolyfill is not defined’

u('dialogPolyfill',dialogPolyfill) of Examples.js, which is run before start()

So in order to fix this scenario we would need Examples.js to wait for dialogPolyfill.min.js, not for start() to wait.

From: Alex Harui<ma...@adobe.com.INVALID>
Sent: Wednesday, May 20, 2020 8:09 PM
To: dev@royale.apache.org<ma...@royale.apache.org>
Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

When I mentioned static initializers in my earlier post, it was about the timing of when some code would first access hljs.  Most externs will probably be first used from code that runs after application.start().  But if someone did:

public static var HLJSClass:Class = hljs;

Then that would fail before we can run application.start(), except that the compiler auto-converts static vars to lazy getters.

However, the hljs usage is not wrapped, so there really aren't any static initializers to use, so it doesn’t matter if they are lazy or not.  I haven't looked at the other uses of inject_script, but if a class wraps the dependency, then it can implement its own waiting strategy unless the API has to be synchronous.  IOW, if I created a Highlighter class that used hljs internally, then if the "highlight" API returns a void, the wrapping implementation would load hljs.js and make the call when it is ready, which is essentially building in the façade you wrote.

You could implement a map of injected scripts, but after thinking about it overnight, my first thought is to require that folks publish a var or uid as follows:

         * <inject_script var="hljs_loaded">
                * var scriptLoaded = function() { hljs_loaded = true) };
                * var script = document.createElement("script");
                * script.setAttribute("src", "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js");
                * script.addEventListener("load", scriptLoaded);
                * document.head.appendChild(script);
            * </inject_script>

Then the compiler may not need so much as a map, but can gather a list of variables to watch for in the setInterval before calling application.start();

Of course, I could be wrong...
-Alex

On 5/20/20, 12:19 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:

    Several questions/comments:


      1.  When you say static initializers should be lazy, do you mean load on the first lib api call? If so, wouldn’t that force async calls?
      2.  Do you have a way of using static initializers for externs files, which is how hljs was originally used?
      3.  To generate the script that waits for dynamically loaded scripts (I guess we don’t mind async css, though I’m not sure) we would need to have a map of injected scripts. So it looks like we’ll need to parse the injected_sctipt tag in any case.

    Thanks.



    From: Alex Harui<ma...@adobe.com.INVALID>
    Sent: Wednesday, May 20, 2020 9:52 AM
    To: dev@royale.apache.org<ma...@royale.apache.org>
    Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

    OK, I looked at the commit for hljs, and the code it replaced.  AFAICT, that is an instantiation phase dependency and not a initialization phase dependency, so it should not matter if it loads before or after app.js (unless someone does use it in a non-lazy static initializer, which should be hard to do in Royale).  It should only matter that it is loaded before anybody calls it.  Other than static initializers, which should all be lazy, nobody should really call hljs until after the application.start() is called in the index.html.

    Here is the index.html for HelloWorld:
    <html>
    <head>
            <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
            <link rel="stylesheet" type="text/css" href="HelloWorld.min.css">
            <script type="text/javascript" src="./HelloWorld.js"></script>
    </head>
    <body>
            <script type="text/javascript">
                    new HelloWorld().start();
            </script>
    </body>

    IMO, for applications that use inject_script (modules will use the _deps file), we should generate code before the start() call that waits for any dynamic scripts to load.  So if HelloWorld needed hljs, the index.html would look more like:

    <head>
            <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
            <link rel="stylesheet" type="text/css" href="HelloWorld.min.css">
            <script type="text/javascript" src="https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fhighlight.js%2F9.12.0%2Fhighlight.min.js&amp;data=02%7C01%7Caharui%40adobe.com%7C5db4fc1f0ed844113a9d08d7fc8e131f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255559454859456&amp;sdata=hoREedwRG%2BXVsuvx5zymqNpNPH3FlptAyChhInwZ%2F6E%3D&amp;reserved=0"
                            onload="highlight.min.js.loaded=true;"></script>
            <script type="text/javascript" src="./HelloWorld.js"></script>
    </head>
    <body>
            <script type="text/javascript">
                    var appInterval = setInterval(function() { if (highlight.min.js.loaded) {
                                                                                                              clearInterval(appInterval);
                                                                                                              new HelloWorld().start();
                                                                                                        }, 200);
            </script>
    </body>

    Closure seems to use a hash of the URL instead of part of the URL to avoid collisions in case two different scripts are called main.js or something like that.  And there might be some better way than using setInterval, but the idea is to wait until the JS is loaded before calling start().

    HTH,
    -Alex

    On 5/19/20, 12:18 PM, "Yishay Weiss" <yi...@hotmail.com> wrote:

        See 99a8c8356573ff16b668f2d39a447355c673fee3

        Note that hljs is an externs file so I couldn’t implement static initializers there.

        There’s also a sort of a queue there for calls made before lib is loaded. I realize this doesn’t scale as a pattern, which is why I proposed to simplify annotations instead.

        It could be of course there’s a simpler solution I’m missing.

        From: Alex Harui<ma...@adobe.com.INVALID>
        Sent: Tuesday, May 19, 2020 10:03 PM
        To: dev@royale.apache.org<ma...@royale.apache.org>
        Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

        Yishay,

        I didn't think static initializers would require a façade or other fancy mechanism.  What kind of AS code ends up requiring this more complex solution?

        -Alex

        On 5/19/20, 10:34 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:

            Hi Carlos,

            Sorry for not responding earlier, I missed this post.

            I haven’t been able to replicate this in debug mode, so it’s interesting you’re seeing that.

            I agree the façade solution is a bit cumbersome, but it works and maybe it’s worth having it out there as an example of using static initializers instead of injected code.

            What do you think?

            From: Carlos Rovira<ma...@apache.org>
            Sent: Monday, May 18, 2020 7:34 PM
            To: Apache Royale Development<ma...@royale.apache.org>
            Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

            Hi Yishay,

            I'm confused. The problem I reported was this;

            ReferenceError: dialogPolyfill is not defined at
            /Users/carlosrovira/Dev/Royale/Source/royale-asjs/examples/jewel/TourDeJewel/target/javascript/bin/js-debug/App.js:10:1

            And just as I'm copying here I'm seeing that while I'm running
            "js-release", notice that the link refers to "js-debug", so I think there's
            some wrong path involved here

            I just updated with your latest change about hljs but I don't think we have
            a problems with it. A part from that I don't like the solution to make a
            Facade for a script, since that involves to create 2 classes instead of
            one. The solution should be just make 1 as3 file (instead of two) and that
            have the proper inject reference.

            Please can you revert the hljsFacade?

            thanks




            El lun., 18 may. 2020 a las 17:44, Yishay Weiss (<yi...@hotmail.com>)
            escribió:

            > Unless I missed something that’s what it’s doing right now after my fix.
            > I’ll try to explain the scenario as I see it (no modules).
            >
            > Suppose we have an app that compiles to the following html.
            >
            > <html>
            >                 <head>
            >                                 <script type="text/javascript">
            >                                                 var script =
            > document.createElement("script");
            >                                                 script.setAttribute("src",
            > "hljs.min.js");
            >
            > document.head.appendChild(script);
            >                                 </script>
            >                                 <script type=”text/JavaScript”
            > src=”App.js”></script>
            >                 </head>
            >                 <body></body>
            > </html>
            >
            > After the first script element is loaded, the dom will look like:
            >
            > <html>
            >                 <head>
            >                                 <script type="text/javascript">
            >                                                 var script =
            > document.createElement("script");
            >                                                 script.setAttribute("src",
            > "hljs.min.js");
            >
            > document.head.appendChild(script);
            >                                 </script>
            >                                 <script type=”text/JavaScript”
            > src=”hljs.min.js”></script>
            >                                 <script type=”text/JavaScript”
            > src=”App.js”></script>
            >                 </head>
            >                 <body></body>
            > </html>
            >
            > However, App.js will still be loaded before hljs.min.js because it was not
            > created dynamically. App.js will fail because it depends on hljs.
            >
            > From: Alex Harui<ma...@adobe.com.INVALID>
            > Sent: Monday, May 18, 2020 6:21 PM
            > To: dev@royale.apache.org<ma...@royale.apache.org>
            > Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
            >
            > I don't think we have to inject these scripts into the main .js file.  The
            > compiler knows when it is compiling the main app or a module.  When
            > compiling the main app, it should inject the script in the HEAD of the html
            > wrapper.  For modules, it can inject the script into a separate file.  The
            > ModuleLoader already loads extra files before loading the module.  It can
            > load one more file.
            >
            > Of course, I could be wrong...
            > -Alex
            >
            > On 5/18/20, 7:38 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
            >
            >     From what I’ve read [1] scripts injected dynamically will always load
            > after static script elements. So I don’t think there’s a good way to ensure
            > the proper order in run-time unless we do something like
            > 99a8c8356573ff16b668f2d39a447355c673fee3 , but that’s verbose and working
            > with libs should be simple.
            >
            >     Any ideas?
            >
            >     [1]
            > https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.html5rocks.com%2Fen%2Ftutorials%2Fspeed%2Fscript-loading%2F%23disqus_thread&amp;data=02%7C01%7Caharui%40adobe.com%7C5db4fc1f0ed844113a9d08d7fc8e131f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255559454869451&amp;sdata=2EjRCIfbjT1okBPUCGBvDVvvv%2FYESige0uaJHppreo8%3D&amp;reserved=0
            >
            >     From: Alex Harui<ma...@adobe.com.INVALID>
            >     Sent: Monday, May 18, 2020 8:03 AM
            >     To: dev@royale.apache.org<ma...@royale.apache.org>
            >
            >
            >     Subject: Re: Script Loading Order (Continuing Heads-Up thread from
            > Users)
            >
            >     Every time I look, closure seems to change how it works.  It looks
            > like they are using callbacks and UIDs.  I assume they can't use await or
            > Promise because of IE support.  I haven't looked at the code you generate,
            > but might have to do something similar, IOW, wait for the callback or known
            > value before continuing.
            >
            >     I think that if we create the script during the running of another
            > script that we have to find a way to wait for that created script.
            >
            >     It might help to know what kind of initialization code needed the
            > definition so early.  One alternative is that such code needs to be
            > responsible for waiting.
            >
            >     Most of our Application classes have a wait mechanism.  We could
            > leverage that, but that's also pretty late.
            >
            >     It could be that for Applications we generate the script in the head,
            > and for modules we generate a separate script that is preloaded.
            >
            >     HTH,
            >     -Alex
            >
            >     On 5/17/20, 9:03 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
            >
            >
            >         >Is the script tag from inject_script going before or after the
            > script tag for the application (should be before, >IMO)?
            >
            >         It’s going before but the network shows it’s loaded after.
            >
            >         >Make sure the script tag has the same settings as the script tags
            > google closure uses in js-debug.  I think they set some options so the
            > scripts load in order.
            >
            >         I see type being specified in the gcl script elements, while
            > inject ones don’t. I suppose it’s worth seeing if that makes a difference,
            > though I couldn’t find evidence for that on the web.
            >
            >
            >
            >
            >

            --
            Carlos Rovira
            https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fabout.me%2Fcarlosrovira&amp;data=02%7C01%7Caharui%40adobe.com%7C5db4fc1f0ed844113a9d08d7fc8e131f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255559454869451&amp;sdata=nuAIneqbkZeykwL3eG1ylsgJ9Xf%2FZXDSejyg4CJywhg%3D&amp;reserved=0








Re: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Alex Harui <ah...@adobe.com.INVALID>.
When I mentioned static initializers in my earlier post, it was about the timing of when some code would first access hljs.  Most externs will probably be first used from code that runs after application.start().  But if someone did:

public static var HLJSClass:Class = hljs;

Then that would fail before we can run application.start(), except that the compiler auto-converts static vars to lazy getters.

However, the hljs usage is not wrapped, so there really aren't any static initializers to use, so it doesn’t matter if they are lazy or not.  I haven't looked at the other uses of inject_script, but if a class wraps the dependency, then it can implement its own waiting strategy unless the API has to be synchronous.  IOW, if I created a Highlighter class that used hljs internally, then if the "highlight" API returns a void, the wrapping implementation would load hljs.js and make the call when it is ready, which is essentially building in the façade you wrote.

You could implement a map of injected scripts, but after thinking about it overnight, my first thought is to require that folks publish a var or uid as follows:

         * <inject_script var="hljs_loaded">
                * var scriptLoaded = function() { hljs_loaded = true) };
                * var script = document.createElement("script");
                * script.setAttribute("src", "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js");
                * script.addEventListener("load", scriptLoaded);
                * document.head.appendChild(script);
            * </inject_script>

Then the compiler may not need so much as a map, but can gather a list of variables to watch for in the setInterval before calling application.start();

Of course, I could be wrong...
-Alex

On 5/20/20, 12:19 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:

    Several questions/comments:
    
    
      1.  When you say static initializers should be lazy, do you mean load on the first lib api call? If so, wouldn’t that force async calls?
      2.  Do you have a way of using static initializers for externs files, which is how hljs was originally used?
      3.  To generate the script that waits for dynamically loaded scripts (I guess we don’t mind async css, though I’m not sure) we would need to have a map of injected scripts. So it looks like we’ll need to parse the injected_sctipt tag in any case.
    
    Thanks.
    
    
    
    From: Alex Harui<ma...@adobe.com.INVALID>
    Sent: Wednesday, May 20, 2020 9:52 AM
    To: dev@royale.apache.org<ma...@royale.apache.org>
    Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
    
    OK, I looked at the commit for hljs, and the code it replaced.  AFAICT, that is an instantiation phase dependency and not a initialization phase dependency, so it should not matter if it loads before or after app.js (unless someone does use it in a non-lazy static initializer, which should be hard to do in Royale).  It should only matter that it is loaded before anybody calls it.  Other than static initializers, which should all be lazy, nobody should really call hljs until after the application.start() is called in the index.html.
    
    Here is the index.html for HelloWorld:
    <html>
    <head>
            <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
            <link rel="stylesheet" type="text/css" href="HelloWorld.min.css">
            <script type="text/javascript" src="./HelloWorld.js"></script>
    </head>
    <body>
            <script type="text/javascript">
                    new HelloWorld().start();
            </script>
    </body>
    
    IMO, for applications that use inject_script (modules will use the _deps file), we should generate code before the start() call that waits for any dynamic scripts to load.  So if HelloWorld needed hljs, the index.html would look more like:
    
    <head>
            <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
            <link rel="stylesheet" type="text/css" href="HelloWorld.min.css">
            <script type="text/javascript" src="https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fhighlight.js%2F9.12.0%2Fhighlight.min.js&amp;data=02%7C01%7Caharui%40adobe.com%7C5db4fc1f0ed844113a9d08d7fc8e131f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255559454859456&amp;sdata=hoREedwRG%2BXVsuvx5zymqNpNPH3FlptAyChhInwZ%2F6E%3D&amp;reserved=0"
                            onload="highlight.min.js.loaded=true;"></script>
            <script type="text/javascript" src="./HelloWorld.js"></script>
    </head>
    <body>
            <script type="text/javascript">
                    var appInterval = setInterval(function() { if (highlight.min.js.loaded) {
                                                                                                              clearInterval(appInterval);
                                                                                                              new HelloWorld().start();
                                                                                                        }, 200);
            </script>
    </body>
    
    Closure seems to use a hash of the URL instead of part of the URL to avoid collisions in case two different scripts are called main.js or something like that.  And there might be some better way than using setInterval, but the idea is to wait until the JS is loaded before calling start().
    
    HTH,
    -Alex
    
    On 5/19/20, 12:18 PM, "Yishay Weiss" <yi...@hotmail.com> wrote:
    
        See 99a8c8356573ff16b668f2d39a447355c673fee3
    
        Note that hljs is an externs file so I couldn’t implement static initializers there.
    
        There’s also a sort of a queue there for calls made before lib is loaded. I realize this doesn’t scale as a pattern, which is why I proposed to simplify annotations instead.
    
        It could be of course there’s a simpler solution I’m missing.
    
        From: Alex Harui<ma...@adobe.com.INVALID>
        Sent: Tuesday, May 19, 2020 10:03 PM
        To: dev@royale.apache.org<ma...@royale.apache.org>
        Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
    
        Yishay,
    
        I didn't think static initializers would require a façade or other fancy mechanism.  What kind of AS code ends up requiring this more complex solution?
    
        -Alex
    
        On 5/19/20, 10:34 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
    
            Hi Carlos,
    
            Sorry for not responding earlier, I missed this post.
    
            I haven’t been able to replicate this in debug mode, so it’s interesting you’re seeing that.
    
            I agree the façade solution is a bit cumbersome, but it works and maybe it’s worth having it out there as an example of using static initializers instead of injected code.
    
            What do you think?
    
            From: Carlos Rovira<ma...@apache.org>
            Sent: Monday, May 18, 2020 7:34 PM
            To: Apache Royale Development<ma...@royale.apache.org>
            Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
    
            Hi Yishay,
    
            I'm confused. The problem I reported was this;
    
            ReferenceError: dialogPolyfill is not defined at
            /Users/carlosrovira/Dev/Royale/Source/royale-asjs/examples/jewel/TourDeJewel/target/javascript/bin/js-debug/App.js:10:1
    
            And just as I'm copying here I'm seeing that while I'm running
            "js-release", notice that the link refers to "js-debug", so I think there's
            some wrong path involved here
    
            I just updated with your latest change about hljs but I don't think we have
            a problems with it. A part from that I don't like the solution to make a
            Facade for a script, since that involves to create 2 classes instead of
            one. The solution should be just make 1 as3 file (instead of two) and that
            have the proper inject reference.
    
            Please can you revert the hljsFacade?
    
            thanks
    
    
    
    
            El lun., 18 may. 2020 a las 17:44, Yishay Weiss (<yi...@hotmail.com>)
            escribió:
    
            > Unless I missed something that’s what it’s doing right now after my fix.
            > I’ll try to explain the scenario as I see it (no modules).
            >
            > Suppose we have an app that compiles to the following html.
            >
            > <html>
            >                 <head>
            >                                 <script type="text/javascript">
            >                                                 var script =
            > document.createElement("script");
            >                                                 script.setAttribute("src",
            > "hljs.min.js");
            >
            > document.head.appendChild(script);
            >                                 </script>
            >                                 <script type=”text/JavaScript”
            > src=”App.js”></script>
            >                 </head>
            >                 <body></body>
            > </html>
            >
            > After the first script element is loaded, the dom will look like:
            >
            > <html>
            >                 <head>
            >                                 <script type="text/javascript">
            >                                                 var script =
            > document.createElement("script");
            >                                                 script.setAttribute("src",
            > "hljs.min.js");
            >
            > document.head.appendChild(script);
            >                                 </script>
            >                                 <script type=”text/JavaScript”
            > src=”hljs.min.js”></script>
            >                                 <script type=”text/JavaScript”
            > src=”App.js”></script>
            >                 </head>
            >                 <body></body>
            > </html>
            >
            > However, App.js will still be loaded before hljs.min.js because it was not
            > created dynamically. App.js will fail because it depends on hljs.
            >
            > From: Alex Harui<ma...@adobe.com.INVALID>
            > Sent: Monday, May 18, 2020 6:21 PM
            > To: dev@royale.apache.org<ma...@royale.apache.org>
            > Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
            >
            > I don't think we have to inject these scripts into the main .js file.  The
            > compiler knows when it is compiling the main app or a module.  When
            > compiling the main app, it should inject the script in the HEAD of the html
            > wrapper.  For modules, it can inject the script into a separate file.  The
            > ModuleLoader already loads extra files before loading the module.  It can
            > load one more file.
            >
            > Of course, I could be wrong...
            > -Alex
            >
            > On 5/18/20, 7:38 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
            >
            >     From what I’ve read [1] scripts injected dynamically will always load
            > after static script elements. So I don’t think there’s a good way to ensure
            > the proper order in run-time unless we do something like
            > 99a8c8356573ff16b668f2d39a447355c673fee3 , but that’s verbose and working
            > with libs should be simple.
            >
            >     Any ideas?
            >
            >     [1]
            > https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.html5rocks.com%2Fen%2Ftutorials%2Fspeed%2Fscript-loading%2F%23disqus_thread&amp;data=02%7C01%7Caharui%40adobe.com%7C5db4fc1f0ed844113a9d08d7fc8e131f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255559454869451&amp;sdata=2EjRCIfbjT1okBPUCGBvDVvvv%2FYESige0uaJHppreo8%3D&amp;reserved=0
            >
            >     From: Alex Harui<ma...@adobe.com.INVALID>
            >     Sent: Monday, May 18, 2020 8:03 AM
            >     To: dev@royale.apache.org<ma...@royale.apache.org>
            >
            >
            >     Subject: Re: Script Loading Order (Continuing Heads-Up thread from
            > Users)
            >
            >     Every time I look, closure seems to change how it works.  It looks
            > like they are using callbacks and UIDs.  I assume they can't use await or
            > Promise because of IE support.  I haven't looked at the code you generate,
            > but might have to do something similar, IOW, wait for the callback or known
            > value before continuing.
            >
            >     I think that if we create the script during the running of another
            > script that we have to find a way to wait for that created script.
            >
            >     It might help to know what kind of initialization code needed the
            > definition so early.  One alternative is that such code needs to be
            > responsible for waiting.
            >
            >     Most of our Application classes have a wait mechanism.  We could
            > leverage that, but that's also pretty late.
            >
            >     It could be that for Applications we generate the script in the head,
            > and for modules we generate a separate script that is preloaded.
            >
            >     HTH,
            >     -Alex
            >
            >     On 5/17/20, 9:03 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
            >
            >
            >         >Is the script tag from inject_script going before or after the
            > script tag for the application (should be before, >IMO)?
            >
            >         It’s going before but the network shows it’s loaded after.
            >
            >         >Make sure the script tag has the same settings as the script tags
            > google closure uses in js-debug.  I think they set some options so the
            > scripts load in order.
            >
            >         I see type being specified in the gcl script elements, while
            > inject ones don’t. I suppose it’s worth seeing if that makes a difference,
            > though I couldn’t find evidence for that on the web.
            >
            >
            >
            >
            >
    
            --
            Carlos Rovira
            https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fabout.me%2Fcarlosrovira&amp;data=02%7C01%7Caharui%40adobe.com%7C5db4fc1f0ed844113a9d08d7fc8e131f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255559454869451&amp;sdata=nuAIneqbkZeykwL3eG1ylsgJ9Xf%2FZXDSejyg4CJywhg%3D&amp;reserved=0
    
    
    
    
    
    


RE: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Yishay Weiss <yi...@hotmail.com>.
Several questions/comments:


  1.  When you say static initializers should be lazy, do you mean load on the first lib api call? If so, wouldn’t that force async calls?
  2.  Do you have a way of using static initializers for externs files, which is how hljs was originally used?
  3.  To generate the script that waits for dynamically loaded scripts (I guess we don’t mind async css, though I’m not sure) we would need to have a map of injected scripts. So it looks like we’ll need to parse the injected_sctipt tag in any case.

Thanks.



From: Alex Harui<ma...@adobe.com.INVALID>
Sent: Wednesday, May 20, 2020 9:52 AM
To: dev@royale.apache.org<ma...@royale.apache.org>
Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

OK, I looked at the commit for hljs, and the code it replaced.  AFAICT, that is an instantiation phase dependency and not a initialization phase dependency, so it should not matter if it loads before or after app.js (unless someone does use it in a non-lazy static initializer, which should be hard to do in Royale).  It should only matter that it is loaded before anybody calls it.  Other than static initializers, which should all be lazy, nobody should really call hljs until after the application.start() is called in the index.html.

Here is the index.html for HelloWorld:
<html>
<head>
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <link rel="stylesheet" type="text/css" href="HelloWorld.min.css">
        <script type="text/javascript" src="./HelloWorld.js"></script>
</head>
<body>
        <script type="text/javascript">
                new HelloWorld().start();
        </script>
</body>

IMO, for applications that use inject_script (modules will use the _deps file), we should generate code before the start() call that waits for any dynamic scripts to load.  So if HelloWorld needed hljs, the index.html would look more like:

<head>
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <link rel="stylesheet" type="text/css" href="HelloWorld.min.css">
        <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"
                        onload="highlight.min.js.loaded=true;"></script>
        <script type="text/javascript" src="./HelloWorld.js"></script>
</head>
<body>
        <script type="text/javascript">
                var appInterval = setInterval(function() { if (highlight.min.js.loaded) {
                                                                                                          clearInterval(appInterval);
                                                                                                          new HelloWorld().start();
                                                                                                    }, 200);
        </script>
</body>

Closure seems to use a hash of the URL instead of part of the URL to avoid collisions in case two different scripts are called main.js or something like that.  And there might be some better way than using setInterval, but the idea is to wait until the JS is loaded before calling start().

HTH,
-Alex

On 5/19/20, 12:18 PM, "Yishay Weiss" <yi...@hotmail.com> wrote:

    See 99a8c8356573ff16b668f2d39a447355c673fee3

    Note that hljs is an externs file so I couldn’t implement static initializers there.

    There’s also a sort of a queue there for calls made before lib is loaded. I realize this doesn’t scale as a pattern, which is why I proposed to simplify annotations instead.

    It could be of course there’s a simpler solution I’m missing.

    From: Alex Harui<ma...@adobe.com.INVALID>
    Sent: Tuesday, May 19, 2020 10:03 PM
    To: dev@royale.apache.org<ma...@royale.apache.org>
    Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

    Yishay,

    I didn't think static initializers would require a façade or other fancy mechanism.  What kind of AS code ends up requiring this more complex solution?

    -Alex

    On 5/19/20, 10:34 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:

        Hi Carlos,

        Sorry for not responding earlier, I missed this post.

        I haven’t been able to replicate this in debug mode, so it’s interesting you’re seeing that.

        I agree the façade solution is a bit cumbersome, but it works and maybe it’s worth having it out there as an example of using static initializers instead of injected code.

        What do you think?

        From: Carlos Rovira<ma...@apache.org>
        Sent: Monday, May 18, 2020 7:34 PM
        To: Apache Royale Development<ma...@royale.apache.org>
        Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

        Hi Yishay,

        I'm confused. The problem I reported was this;

        ReferenceError: dialogPolyfill is not defined at
        /Users/carlosrovira/Dev/Royale/Source/royale-asjs/examples/jewel/TourDeJewel/target/javascript/bin/js-debug/App.js:10:1

        And just as I'm copying here I'm seeing that while I'm running
        "js-release", notice that the link refers to "js-debug", so I think there's
        some wrong path involved here

        I just updated with your latest change about hljs but I don't think we have
        a problems with it. A part from that I don't like the solution to make a
        Facade for a script, since that involves to create 2 classes instead of
        one. The solution should be just make 1 as3 file (instead of two) and that
        have the proper inject reference.

        Please can you revert the hljsFacade?

        thanks




        El lun., 18 may. 2020 a las 17:44, Yishay Weiss (<yi...@hotmail.com>)
        escribió:

        > Unless I missed something that’s what it’s doing right now after my fix.
        > I’ll try to explain the scenario as I see it (no modules).
        >
        > Suppose we have an app that compiles to the following html.
        >
        > <html>
        >                 <head>
        >                                 <script type="text/javascript">
        >                                                 var script =
        > document.createElement("script");
        >                                                 script.setAttribute("src",
        > "hljs.min.js");
        >
        > document.head.appendChild(script);
        >                                 </script>
        >                                 <script type=”text/JavaScript”
        > src=”App.js”></script>
        >                 </head>
        >                 <body></body>
        > </html>
        >
        > After the first script element is loaded, the dom will look like:
        >
        > <html>
        >                 <head>
        >                                 <script type="text/javascript">
        >                                                 var script =
        > document.createElement("script");
        >                                                 script.setAttribute("src",
        > "hljs.min.js");
        >
        > document.head.appendChild(script);
        >                                 </script>
        >                                 <script type=”text/JavaScript”
        > src=”hljs.min.js”></script>
        >                                 <script type=”text/JavaScript”
        > src=”App.js”></script>
        >                 </head>
        >                 <body></body>
        > </html>
        >
        > However, App.js will still be loaded before hljs.min.js because it was not
        > created dynamically. App.js will fail because it depends on hljs.
        >
        > From: Alex Harui<ma...@adobe.com.INVALID>
        > Sent: Monday, May 18, 2020 6:21 PM
        > To: dev@royale.apache.org<ma...@royale.apache.org>
        > Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
        >
        > I don't think we have to inject these scripts into the main .js file.  The
        > compiler knows when it is compiling the main app or a module.  When
        > compiling the main app, it should inject the script in the HEAD of the html
        > wrapper.  For modules, it can inject the script into a separate file.  The
        > ModuleLoader already loads extra files before loading the module.  It can
        > load one more file.
        >
        > Of course, I could be wrong...
        > -Alex
        >
        > On 5/18/20, 7:38 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
        >
        >     From what I’ve read [1] scripts injected dynamically will always load
        > after static script elements. So I don’t think there’s a good way to ensure
        > the proper order in run-time unless we do something like
        > 99a8c8356573ff16b668f2d39a447355c673fee3 , but that’s verbose and working
        > with libs should be simple.
        >
        >     Any ideas?
        >
        >     [1]
        > https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.html5rocks.com%2Fen%2Ftutorials%2Fspeed%2Fscript-loading%2F%23disqus_thread&amp;data=02%7C01%7Caharui%40adobe.com%7C755ef15c598f4953e07808d7fc296336%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255126994735409&amp;sdata=ROGX%2BP%2Bm9Lln49Bml7HcXd4Ws0HM2nwM9UZfxCzR3oU%3D&amp;reserved=0
        >
        >     From: Alex Harui<ma...@adobe.com.INVALID>
        >     Sent: Monday, May 18, 2020 8:03 AM
        >     To: dev@royale.apache.org<ma...@royale.apache.org>
        >
        >
        >     Subject: Re: Script Loading Order (Continuing Heads-Up thread from
        > Users)
        >
        >     Every time I look, closure seems to change how it works.  It looks
        > like they are using callbacks and UIDs.  I assume they can't use await or
        > Promise because of IE support.  I haven't looked at the code you generate,
        > but might have to do something similar, IOW, wait for the callback or known
        > value before continuing.
        >
        >     I think that if we create the script during the running of another
        > script that we have to find a way to wait for that created script.
        >
        >     It might help to know what kind of initialization code needed the
        > definition so early.  One alternative is that such code needs to be
        > responsible for waiting.
        >
        >     Most of our Application classes have a wait mechanism.  We could
        > leverage that, but that's also pretty late.
        >
        >     It could be that for Applications we generate the script in the head,
        > and for modules we generate a separate script that is preloaded.
        >
        >     HTH,
        >     -Alex
        >
        >     On 5/17/20, 9:03 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
        >
        >
        >         >Is the script tag from inject_script going before or after the
        > script tag for the application (should be before, >IMO)?
        >
        >         It’s going before but the network shows it’s loaded after.
        >
        >         >Make sure the script tag has the same settings as the script tags
        > google closure uses in js-debug.  I think they set some options so the
        > scripts load in order.
        >
        >         I see type being specified in the gcl script elements, while
        > inject ones don’t. I suppose it’s worth seeing if that makes a difference,
        > though I couldn’t find evidence for that on the web.
        >
        >
        >
        >
        >

        --
        Carlos Rovira
        https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fabout.me%2Fcarlosrovira&amp;data=02%7C01%7Caharui%40adobe.com%7C755ef15c598f4953e07808d7fc296336%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255126994735409&amp;sdata=K3j%2Fs5ztpCNBrEWl8M981ZgHZw4wCNWOXiRvYXbFJPE%3D&amp;reserved=0






Re: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Alex Harui <ah...@adobe.com.INVALID>.
OK, I looked at the commit for hljs, and the code it replaced.  AFAICT, that is an instantiation phase dependency and not a initialization phase dependency, so it should not matter if it loads before or after app.js (unless someone does use it in a non-lazy static initializer, which should be hard to do in Royale).  It should only matter that it is loaded before anybody calls it.  Other than static initializers, which should all be lazy, nobody should really call hljs until after the application.start() is called in the index.html.

Here is the index.html for HelloWorld:
<html>
<head>
	<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
	<link rel="stylesheet" type="text/css" href="HelloWorld.min.css">
	<script type="text/javascript" src="./HelloWorld.js"></script>
</head>
<body>
	<script type="text/javascript">
		new HelloWorld().start();
	</script>
</body>

IMO, for applications that use inject_script (modules will use the _deps file), we should generate code before the start() call that waits for any dynamic scripts to load.  So if HelloWorld needed hljs, the index.html would look more like:

<head>
	<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
	<link rel="stylesheet" type="text/css" href="HelloWorld.min.css">
	<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"
                        onload="highlight.min.js.loaded=true;"></script>
	<script type="text/javascript" src="./HelloWorld.js"></script>
</head>
<body>
	<script type="text/javascript">
		var appInterval = setInterval(function() { if (highlight.min.js.loaded) {
                                                                                                          clearInterval(appInterval);
                                                                                                          new HelloWorld().start();
                                                                                                    }, 200);
	</script>
</body>

Closure seems to use a hash of the URL instead of part of the URL to avoid collisions in case two different scripts are called main.js or something like that.  And there might be some better way than using setInterval, but the idea is to wait until the JS is loaded before calling start().

HTH,
-Alex

On 5/19/20, 12:18 PM, "Yishay Weiss" <yi...@hotmail.com> wrote:

    See 99a8c8356573ff16b668f2d39a447355c673fee3
    
    Note that hljs is an externs file so I couldn’t implement static initializers there.
    
    There’s also a sort of a queue there for calls made before lib is loaded. I realize this doesn’t scale as a pattern, which is why I proposed to simplify annotations instead.
    
    It could be of course there’s a simpler solution I’m missing.
    
    From: Alex Harui<ma...@adobe.com.INVALID>
    Sent: Tuesday, May 19, 2020 10:03 PM
    To: dev@royale.apache.org<ma...@royale.apache.org>
    Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
    
    Yishay,
    
    I didn't think static initializers would require a façade or other fancy mechanism.  What kind of AS code ends up requiring this more complex solution?
    
    -Alex
    
    On 5/19/20, 10:34 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
    
        Hi Carlos,
    
        Sorry for not responding earlier, I missed this post.
    
        I haven’t been able to replicate this in debug mode, so it’s interesting you’re seeing that.
    
        I agree the façade solution is a bit cumbersome, but it works and maybe it’s worth having it out there as an example of using static initializers instead of injected code.
    
        What do you think?
    
        From: Carlos Rovira<ma...@apache.org>
        Sent: Monday, May 18, 2020 7:34 PM
        To: Apache Royale Development<ma...@royale.apache.org>
        Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
    
        Hi Yishay,
    
        I'm confused. The problem I reported was this;
    
        ReferenceError: dialogPolyfill is not defined at
        /Users/carlosrovira/Dev/Royale/Source/royale-asjs/examples/jewel/TourDeJewel/target/javascript/bin/js-debug/App.js:10:1
    
        And just as I'm copying here I'm seeing that while I'm running
        "js-release", notice that the link refers to "js-debug", so I think there's
        some wrong path involved here
    
        I just updated with your latest change about hljs but I don't think we have
        a problems with it. A part from that I don't like the solution to make a
        Facade for a script, since that involves to create 2 classes instead of
        one. The solution should be just make 1 as3 file (instead of two) and that
        have the proper inject reference.
    
        Please can you revert the hljsFacade?
    
        thanks
    
    
    
    
        El lun., 18 may. 2020 a las 17:44, Yishay Weiss (<yi...@hotmail.com>)
        escribió:
    
        > Unless I missed something that’s what it’s doing right now after my fix.
        > I’ll try to explain the scenario as I see it (no modules).
        >
        > Suppose we have an app that compiles to the following html.
        >
        > <html>
        >                 <head>
        >                                 <script type="text/javascript">
        >                                                 var script =
        > document.createElement("script");
        >                                                 script.setAttribute("src",
        > "hljs.min.js");
        >
        > document.head.appendChild(script);
        >                                 </script>
        >                                 <script type=”text/JavaScript”
        > src=”App.js”></script>
        >                 </head>
        >                 <body></body>
        > </html>
        >
        > After the first script element is loaded, the dom will look like:
        >
        > <html>
        >                 <head>
        >                                 <script type="text/javascript">
        >                                                 var script =
        > document.createElement("script");
        >                                                 script.setAttribute("src",
        > "hljs.min.js");
        >
        > document.head.appendChild(script);
        >                                 </script>
        >                                 <script type=”text/JavaScript”
        > src=”hljs.min.js”></script>
        >                                 <script type=”text/JavaScript”
        > src=”App.js”></script>
        >                 </head>
        >                 <body></body>
        > </html>
        >
        > However, App.js will still be loaded before hljs.min.js because it was not
        > created dynamically. App.js will fail because it depends on hljs.
        >
        > From: Alex Harui<ma...@adobe.com.INVALID>
        > Sent: Monday, May 18, 2020 6:21 PM
        > To: dev@royale.apache.org<ma...@royale.apache.org>
        > Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
        >
        > I don't think we have to inject these scripts into the main .js file.  The
        > compiler knows when it is compiling the main app or a module.  When
        > compiling the main app, it should inject the script in the HEAD of the html
        > wrapper.  For modules, it can inject the script into a separate file.  The
        > ModuleLoader already loads extra files before loading the module.  It can
        > load one more file.
        >
        > Of course, I could be wrong...
        > -Alex
        >
        > On 5/18/20, 7:38 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
        >
        >     From what I’ve read [1] scripts injected dynamically will always load
        > after static script elements. So I don’t think there’s a good way to ensure
        > the proper order in run-time unless we do something like
        > 99a8c8356573ff16b668f2d39a447355c673fee3 , but that’s verbose and working
        > with libs should be simple.
        >
        >     Any ideas?
        >
        >     [1]
        > https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.html5rocks.com%2Fen%2Ftutorials%2Fspeed%2Fscript-loading%2F%23disqus_thread&amp;data=02%7C01%7Caharui%40adobe.com%7C755ef15c598f4953e07808d7fc296336%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255126994735409&amp;sdata=ROGX%2BP%2Bm9Lln49Bml7HcXd4Ws0HM2nwM9UZfxCzR3oU%3D&amp;reserved=0
        >
        >     From: Alex Harui<ma...@adobe.com.INVALID>
        >     Sent: Monday, May 18, 2020 8:03 AM
        >     To: dev@royale.apache.org<ma...@royale.apache.org>
        >
        >
        >     Subject: Re: Script Loading Order (Continuing Heads-Up thread from
        > Users)
        >
        >     Every time I look, closure seems to change how it works.  It looks
        > like they are using callbacks and UIDs.  I assume they can't use await or
        > Promise because of IE support.  I haven't looked at the code you generate,
        > but might have to do something similar, IOW, wait for the callback or known
        > value before continuing.
        >
        >     I think that if we create the script during the running of another
        > script that we have to find a way to wait for that created script.
        >
        >     It might help to know what kind of initialization code needed the
        > definition so early.  One alternative is that such code needs to be
        > responsible for waiting.
        >
        >     Most of our Application classes have a wait mechanism.  We could
        > leverage that, but that's also pretty late.
        >
        >     It could be that for Applications we generate the script in the head,
        > and for modules we generate a separate script that is preloaded.
        >
        >     HTH,
        >     -Alex
        >
        >     On 5/17/20, 9:03 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
        >
        >
        >         >Is the script tag from inject_script going before or after the
        > script tag for the application (should be before, >IMO)?
        >
        >         It’s going before but the network shows it’s loaded after.
        >
        >         >Make sure the script tag has the same settings as the script tags
        > google closure uses in js-debug.  I think they set some options so the
        > scripts load in order.
        >
        >         I see type being specified in the gcl script elements, while
        > inject ones don’t. I suppose it’s worth seeing if that makes a difference,
        > though I couldn’t find evidence for that on the web.
        >
        >
        >
        >
        >
    
        --
        Carlos Rovira
        https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fabout.me%2Fcarlosrovira&amp;data=02%7C01%7Caharui%40adobe.com%7C755ef15c598f4953e07808d7fc296336%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255126994735409&amp;sdata=K3j%2Fs5ztpCNBrEWl8M981ZgHZw4wCNWOXiRvYXbFJPE%3D&amp;reserved=0
    
    
    
    


RE: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Yishay Weiss <yi...@hotmail.com>.
See 99a8c8356573ff16b668f2d39a447355c673fee3

Note that hljs is an externs file so I couldn’t implement static initializers there.

There’s also a sort of a queue there for calls made before lib is loaded. I realize this doesn’t scale as a pattern, which is why I proposed to simplify annotations instead.

It could be of course there’s a simpler solution I’m missing.

From: Alex Harui<ma...@adobe.com.INVALID>
Sent: Tuesday, May 19, 2020 10:03 PM
To: dev@royale.apache.org<ma...@royale.apache.org>
Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

Yishay,

I didn't think static initializers would require a façade or other fancy mechanism.  What kind of AS code ends up requiring this more complex solution?

-Alex

On 5/19/20, 10:34 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:

    Hi Carlos,

    Sorry for not responding earlier, I missed this post.

    I haven’t been able to replicate this in debug mode, so it’s interesting you’re seeing that.

    I agree the façade solution is a bit cumbersome, but it works and maybe it’s worth having it out there as an example of using static initializers instead of injected code.

    What do you think?

    From: Carlos Rovira<ma...@apache.org>
    Sent: Monday, May 18, 2020 7:34 PM
    To: Apache Royale Development<ma...@royale.apache.org>
    Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

    Hi Yishay,

    I'm confused. The problem I reported was this;

    ReferenceError: dialogPolyfill is not defined at
    /Users/carlosrovira/Dev/Royale/Source/royale-asjs/examples/jewel/TourDeJewel/target/javascript/bin/js-debug/App.js:10:1

    And just as I'm copying here I'm seeing that while I'm running
    "js-release", notice that the link refers to "js-debug", so I think there's
    some wrong path involved here

    I just updated with your latest change about hljs but I don't think we have
    a problems with it. A part from that I don't like the solution to make a
    Facade for a script, since that involves to create 2 classes instead of
    one. The solution should be just make 1 as3 file (instead of two) and that
    have the proper inject reference.

    Please can you revert the hljsFacade?

    thanks




    El lun., 18 may. 2020 a las 17:44, Yishay Weiss (<yi...@hotmail.com>)
    escribió:

    > Unless I missed something that’s what it’s doing right now after my fix.
    > I’ll try to explain the scenario as I see it (no modules).
    >
    > Suppose we have an app that compiles to the following html.
    >
    > <html>
    >                 <head>
    >                                 <script type="text/javascript">
    >                                                 var script =
    > document.createElement("script");
    >                                                 script.setAttribute("src",
    > "hljs.min.js");
    >
    > document.head.appendChild(script);
    >                                 </script>
    >                                 <script type=”text/JavaScript”
    > src=”App.js”></script>
    >                 </head>
    >                 <body></body>
    > </html>
    >
    > After the first script element is loaded, the dom will look like:
    >
    > <html>
    >                 <head>
    >                                 <script type="text/javascript">
    >                                                 var script =
    > document.createElement("script");
    >                                                 script.setAttribute("src",
    > "hljs.min.js");
    >
    > document.head.appendChild(script);
    >                                 </script>
    >                                 <script type=”text/JavaScript”
    > src=”hljs.min.js”></script>
    >                                 <script type=”text/JavaScript”
    > src=”App.js”></script>
    >                 </head>
    >                 <body></body>
    > </html>
    >
    > However, App.js will still be loaded before hljs.min.js because it was not
    > created dynamically. App.js will fail because it depends on hljs.
    >
    > From: Alex Harui<ma...@adobe.com.INVALID>
    > Sent: Monday, May 18, 2020 6:21 PM
    > To: dev@royale.apache.org<ma...@royale.apache.org>
    > Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
    >
    > I don't think we have to inject these scripts into the main .js file.  The
    > compiler knows when it is compiling the main app or a module.  When
    > compiling the main app, it should inject the script in the HEAD of the html
    > wrapper.  For modules, it can inject the script into a separate file.  The
    > ModuleLoader already loads extra files before loading the module.  It can
    > load one more file.
    >
    > Of course, I could be wrong...
    > -Alex
    >
    > On 5/18/20, 7:38 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
    >
    >     From what I’ve read [1] scripts injected dynamically will always load
    > after static script elements. So I don’t think there’s a good way to ensure
    > the proper order in run-time unless we do something like
    > 99a8c8356573ff16b668f2d39a447355c673fee3 , but that’s verbose and working
    > with libs should be simple.
    >
    >     Any ideas?
    >
    >     [1]
    > https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.html5rocks.com%2Fen%2Ftutorials%2Fspeed%2Fscript-loading%2F%23disqus_thread&amp;data=02%7C01%7Caharui%40adobe.com%7Cd1f300255d7f46f3472808d7fc1aefad%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255064930991098&amp;sdata=LVleS2MHLv4Pjb9M5QcrsjkgxM00hstfuLdBrr8vCz0%3D&amp;reserved=0
    >
    >     From: Alex Harui<ma...@adobe.com.INVALID>
    >     Sent: Monday, May 18, 2020 8:03 AM
    >     To: dev@royale.apache.org<ma...@royale.apache.org>
    >
    >
    >     Subject: Re: Script Loading Order (Continuing Heads-Up thread from
    > Users)
    >
    >     Every time I look, closure seems to change how it works.  It looks
    > like they are using callbacks and UIDs.  I assume they can't use await or
    > Promise because of IE support.  I haven't looked at the code you generate,
    > but might have to do something similar, IOW, wait for the callback or known
    > value before continuing.
    >
    >     I think that if we create the script during the running of another
    > script that we have to find a way to wait for that created script.
    >
    >     It might help to know what kind of initialization code needed the
    > definition so early.  One alternative is that such code needs to be
    > responsible for waiting.
    >
    >     Most of our Application classes have a wait mechanism.  We could
    > leverage that, but that's also pretty late.
    >
    >     It could be that for Applications we generate the script in the head,
    > and for modules we generate a separate script that is preloaded.
    >
    >     HTH,
    >     -Alex
    >
    >     On 5/17/20, 9:03 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
    >
    >
    >         >Is the script tag from inject_script going before or after the
    > script tag for the application (should be before, >IMO)?
    >
    >         It’s going before but the network shows it’s loaded after.
    >
    >         >Make sure the script tag has the same settings as the script tags
    > google closure uses in js-debug.  I think they set some options so the
    > scripts load in order.
    >
    >         I see type being specified in the gcl script elements, while
    > inject ones don’t. I suppose it’s worth seeing if that makes a difference,
    > though I couldn’t find evidence for that on the web.
    >
    >
    >
    >
    >

    --
    Carlos Rovira
    https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fabout.me%2Fcarlosrovira&amp;data=02%7C01%7Caharui%40adobe.com%7Cd1f300255d7f46f3472808d7fc1aefad%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255064930991098&amp;sdata=kvSg4mPijs4ZcZwXSObM12iY6r9iuDM%2F8YPlO9E%2FO7I%3D&amp;reserved=0




Re: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Alex Harui <ah...@adobe.com.INVALID>.
Yishay,

I didn't think static initializers would require a façade or other fancy mechanism.  What kind of AS code ends up requiring this more complex solution?

-Alex

On 5/19/20, 10:34 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:

    Hi Carlos,
    
    Sorry for not responding earlier, I missed this post.
    
    I haven’t been able to replicate this in debug mode, so it’s interesting you’re seeing that.
    
    I agree the façade solution is a bit cumbersome, but it works and maybe it’s worth having it out there as an example of using static initializers instead of injected code.
    
    What do you think?
    
    From: Carlos Rovira<ma...@apache.org>
    Sent: Monday, May 18, 2020 7:34 PM
    To: Apache Royale Development<ma...@royale.apache.org>
    Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
    
    Hi Yishay,
    
    I'm confused. The problem I reported was this;
    
    ReferenceError: dialogPolyfill is not defined at
    /Users/carlosrovira/Dev/Royale/Source/royale-asjs/examples/jewel/TourDeJewel/target/javascript/bin/js-debug/App.js:10:1
    
    And just as I'm copying here I'm seeing that while I'm running
    "js-release", notice that the link refers to "js-debug", so I think there's
    some wrong path involved here
    
    I just updated with your latest change about hljs but I don't think we have
    a problems with it. A part from that I don't like the solution to make a
    Facade for a script, since that involves to create 2 classes instead of
    one. The solution should be just make 1 as3 file (instead of two) and that
    have the proper inject reference.
    
    Please can you revert the hljsFacade?
    
    thanks
    
    
    
    
    El lun., 18 may. 2020 a las 17:44, Yishay Weiss (<yi...@hotmail.com>)
    escribió:
    
    > Unless I missed something that’s what it’s doing right now after my fix.
    > I’ll try to explain the scenario as I see it (no modules).
    >
    > Suppose we have an app that compiles to the following html.
    >
    > <html>
    >                 <head>
    >                                 <script type="text/javascript">
    >                                                 var script =
    > document.createElement("script");
    >                                                 script.setAttribute("src",
    > "hljs.min.js");
    >
    > document.head.appendChild(script);
    >                                 </script>
    >                                 <script type=”text/JavaScript”
    > src=”App.js”></script>
    >                 </head>
    >                 <body></body>
    > </html>
    >
    > After the first script element is loaded, the dom will look like:
    >
    > <html>
    >                 <head>
    >                                 <script type="text/javascript">
    >                                                 var script =
    > document.createElement("script");
    >                                                 script.setAttribute("src",
    > "hljs.min.js");
    >
    > document.head.appendChild(script);
    >                                 </script>
    >                                 <script type=”text/JavaScript”
    > src=”hljs.min.js”></script>
    >                                 <script type=”text/JavaScript”
    > src=”App.js”></script>
    >                 </head>
    >                 <body></body>
    > </html>
    >
    > However, App.js will still be loaded before hljs.min.js because it was not
    > created dynamically. App.js will fail because it depends on hljs.
    >
    > From: Alex Harui<ma...@adobe.com.INVALID>
    > Sent: Monday, May 18, 2020 6:21 PM
    > To: dev@royale.apache.org<ma...@royale.apache.org>
    > Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
    >
    > I don't think we have to inject these scripts into the main .js file.  The
    > compiler knows when it is compiling the main app or a module.  When
    > compiling the main app, it should inject the script in the HEAD of the html
    > wrapper.  For modules, it can inject the script into a separate file.  The
    > ModuleLoader already loads extra files before loading the module.  It can
    > load one more file.
    >
    > Of course, I could be wrong...
    > -Alex
    >
    > On 5/18/20, 7:38 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
    >
    >     From what I’ve read [1] scripts injected dynamically will always load
    > after static script elements. So I don’t think there’s a good way to ensure
    > the proper order in run-time unless we do something like
    > 99a8c8356573ff16b668f2d39a447355c673fee3 , but that’s verbose and working
    > with libs should be simple.
    >
    >     Any ideas?
    >
    >     [1]
    > https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.html5rocks.com%2Fen%2Ftutorials%2Fspeed%2Fscript-loading%2F%23disqus_thread&amp;data=02%7C01%7Caharui%40adobe.com%7Cd1f300255d7f46f3472808d7fc1aefad%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255064930991098&amp;sdata=LVleS2MHLv4Pjb9M5QcrsjkgxM00hstfuLdBrr8vCz0%3D&amp;reserved=0
    >
    >     From: Alex Harui<ma...@adobe.com.INVALID>
    >     Sent: Monday, May 18, 2020 8:03 AM
    >     To: dev@royale.apache.org<ma...@royale.apache.org>
    >
    >
    >     Subject: Re: Script Loading Order (Continuing Heads-Up thread from
    > Users)
    >
    >     Every time I look, closure seems to change how it works.  It looks
    > like they are using callbacks and UIDs.  I assume they can't use await or
    > Promise because of IE support.  I haven't looked at the code you generate,
    > but might have to do something similar, IOW, wait for the callback or known
    > value before continuing.
    >
    >     I think that if we create the script during the running of another
    > script that we have to find a way to wait for that created script.
    >
    >     It might help to know what kind of initialization code needed the
    > definition so early.  One alternative is that such code needs to be
    > responsible for waiting.
    >
    >     Most of our Application classes have a wait mechanism.  We could
    > leverage that, but that's also pretty late.
    >
    >     It could be that for Applications we generate the script in the head,
    > and for modules we generate a separate script that is preloaded.
    >
    >     HTH,
    >     -Alex
    >
    >     On 5/17/20, 9:03 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
    >
    >
    >         >Is the script tag from inject_script going before or after the
    > script tag for the application (should be before, >IMO)?
    >
    >         It’s going before but the network shows it’s loaded after.
    >
    >         >Make sure the script tag has the same settings as the script tags
    > google closure uses in js-debug.  I think they set some options so the
    > scripts load in order.
    >
    >         I see type being specified in the gcl script elements, while
    > inject ones don’t. I suppose it’s worth seeing if that makes a difference,
    > though I couldn’t find evidence for that on the web.
    >
    >
    >
    >
    >
    
    --
    Carlos Rovira
    https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fabout.me%2Fcarlosrovira&amp;data=02%7C01%7Caharui%40adobe.com%7Cd1f300255d7f46f3472808d7fc1aefad%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255064930991098&amp;sdata=kvSg4mPijs4ZcZwXSObM12iY6r9iuDM%2F8YPlO9E%2FO7I%3D&amp;reserved=0
    
    


RE: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Yishay Weiss <yi...@hotmail.com>.
Hi Carlos,

Sorry for not responding earlier, I missed this post.

I haven’t been able to replicate this in debug mode, so it’s interesting you’re seeing that.

I agree the façade solution is a bit cumbersome, but it works and maybe it’s worth having it out there as an example of using static initializers instead of injected code.

What do you think?

From: Carlos Rovira<ma...@apache.org>
Sent: Monday, May 18, 2020 7:34 PM
To: Apache Royale Development<ma...@royale.apache.org>
Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

Hi Yishay,

I'm confused. The problem I reported was this;

ReferenceError: dialogPolyfill is not defined at
/Users/carlosrovira/Dev/Royale/Source/royale-asjs/examples/jewel/TourDeJewel/target/javascript/bin/js-debug/App.js:10:1

And just as I'm copying here I'm seeing that while I'm running
"js-release", notice that the link refers to "js-debug", so I think there's
some wrong path involved here

I just updated with your latest change about hljs but I don't think we have
a problems with it. A part from that I don't like the solution to make a
Facade for a script, since that involves to create 2 classes instead of
one. The solution should be just make 1 as3 file (instead of two) and that
have the proper inject reference.

Please can you revert the hljsFacade?

thanks




El lun., 18 may. 2020 a las 17:44, Yishay Weiss (<yi...@hotmail.com>)
escribió:

> Unless I missed something that’s what it’s doing right now after my fix.
> I’ll try to explain the scenario as I see it (no modules).
>
> Suppose we have an app that compiles to the following html.
>
> <html>
>                 <head>
>                                 <script type="text/javascript">
>                                                 var script =
> document.createElement("script");
>                                                 script.setAttribute("src",
> "hljs.min.js");
>
> document.head.appendChild(script);
>                                 </script>
>                                 <script type=”text/JavaScript”
> src=”App.js”></script>
>                 </head>
>                 <body></body>
> </html>
>
> After the first script element is loaded, the dom will look like:
>
> <html>
>                 <head>
>                                 <script type="text/javascript">
>                                                 var script =
> document.createElement("script");
>                                                 script.setAttribute("src",
> "hljs.min.js");
>
> document.head.appendChild(script);
>                                 </script>
>                                 <script type=”text/JavaScript”
> src=”hljs.min.js”></script>
>                                 <script type=”text/JavaScript”
> src=”App.js”></script>
>                 </head>
>                 <body></body>
> </html>
>
> However, App.js will still be loaded before hljs.min.js because it was not
> created dynamically. App.js will fail because it depends on hljs.
>
> From: Alex Harui<ma...@adobe.com.INVALID>
> Sent: Monday, May 18, 2020 6:21 PM
> To: dev@royale.apache.org<ma...@royale.apache.org>
> Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
>
> I don't think we have to inject these scripts into the main .js file.  The
> compiler knows when it is compiling the main app or a module.  When
> compiling the main app, it should inject the script in the HEAD of the html
> wrapper.  For modules, it can inject the script into a separate file.  The
> ModuleLoader already loads extra files before loading the module.  It can
> load one more file.
>
> Of course, I could be wrong...
> -Alex
>
> On 5/18/20, 7:38 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
>
>     From what I’ve read [1] scripts injected dynamically will always load
> after static script elements. So I don’t think there’s a good way to ensure
> the proper order in run-time unless we do something like
> 99a8c8356573ff16b668f2d39a447355c673fee3 , but that’s verbose and working
> with libs should be simple.
>
>     Any ideas?
>
>     [1]
> https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.html5rocks.com%2Fen%2Ftutorials%2Fspeed%2Fscript-loading%2F%23disqus_thread&amp;data=02%7C01%7Caharui%40adobe.com%7C89b59cc20eff4f34398308d7fb39180f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637254094944356465&amp;sdata=8BCjJ8oV6h2U2wxgorysLU8Sm5tTGwAP7XBEL7yhca4%3D&amp;reserved=0
>
>     From: Alex Harui<ma...@adobe.com.INVALID>
>     Sent: Monday, May 18, 2020 8:03 AM
>     To: dev@royale.apache.org<ma...@royale.apache.org>
>
>
>     Subject: Re: Script Loading Order (Continuing Heads-Up thread from
> Users)
>
>     Every time I look, closure seems to change how it works.  It looks
> like they are using callbacks and UIDs.  I assume they can't use await or
> Promise because of IE support.  I haven't looked at the code you generate,
> but might have to do something similar, IOW, wait for the callback or known
> value before continuing.
>
>     I think that if we create the script during the running of another
> script that we have to find a way to wait for that created script.
>
>     It might help to know what kind of initialization code needed the
> definition so early.  One alternative is that such code needs to be
> responsible for waiting.
>
>     Most of our Application classes have a wait mechanism.  We could
> leverage that, but that's also pretty late.
>
>     It could be that for Applications we generate the script in the head,
> and for modules we generate a separate script that is preloaded.
>
>     HTH,
>     -Alex
>
>     On 5/17/20, 9:03 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
>
>
>         >Is the script tag from inject_script going before or after the
> script tag for the application (should be before, >IMO)?
>
>         It’s going before but the network shows it’s loaded after.
>
>         >Make sure the script tag has the same settings as the script tags
> google closure uses in js-debug.  I think they set some options so the
> scripts load in order.
>
>         I see type being specified in the gcl script elements, while
> inject ones don’t. I suppose it’s worth seeing if that makes a difference,
> though I couldn’t find evidence for that on the web.
>
>
>
>
>

--
Carlos Rovira
http://about.me/carlosrovira


Re: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Carlos Rovira <ca...@apache.org>.
Hi Yishay,

I'm confused. The problem I reported was this;

ReferenceError: dialogPolyfill is not defined at
/Users/carlosrovira/Dev/Royale/Source/royale-asjs/examples/jewel/TourDeJewel/target/javascript/bin/js-debug/App.js:10:1

And just as I'm copying here I'm seeing that while I'm running
"js-release", notice that the link refers to "js-debug", so I think there's
some wrong path involved here

I just updated with your latest change about hljs but I don't think we have
a problems with it. A part from that I don't like the solution to make a
Facade for a script, since that involves to create 2 classes instead of
one. The solution should be just make 1 as3 file (instead of two) and that
have the proper inject reference.

Please can you revert the hljsFacade?

thanks




El lun., 18 may. 2020 a las 17:44, Yishay Weiss (<yi...@hotmail.com>)
escribió:

> Unless I missed something that’s what it’s doing right now after my fix.
> I’ll try to explain the scenario as I see it (no modules).
>
> Suppose we have an app that compiles to the following html.
>
> <html>
>                 <head>
>                                 <script type="text/javascript">
>                                                 var script =
> document.createElement("script");
>                                                 script.setAttribute("src",
> "hljs.min.js");
>
> document.head.appendChild(script);
>                                 </script>
>                                 <script type=”text/JavaScript”
> src=”App.js”></script>
>                 </head>
>                 <body></body>
> </html>
>
> After the first script element is loaded, the dom will look like:
>
> <html>
>                 <head>
>                                 <script type="text/javascript">
>                                                 var script =
> document.createElement("script");
>                                                 script.setAttribute("src",
> "hljs.min.js");
>
> document.head.appendChild(script);
>                                 </script>
>                                 <script type=”text/JavaScript”
> src=”hljs.min.js”></script>
>                                 <script type=”text/JavaScript”
> src=”App.js”></script>
>                 </head>
>                 <body></body>
> </html>
>
> However, App.js will still be loaded before hljs.min.js because it was not
> created dynamically. App.js will fail because it depends on hljs.
>
> From: Alex Harui<ma...@adobe.com.INVALID>
> Sent: Monday, May 18, 2020 6:21 PM
> To: dev@royale.apache.org<ma...@royale.apache.org>
> Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
>
> I don't think we have to inject these scripts into the main .js file.  The
> compiler knows when it is compiling the main app or a module.  When
> compiling the main app, it should inject the script in the HEAD of the html
> wrapper.  For modules, it can inject the script into a separate file.  The
> ModuleLoader already loads extra files before loading the module.  It can
> load one more file.
>
> Of course, I could be wrong...
> -Alex
>
> On 5/18/20, 7:38 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
>
>     From what I’ve read [1] scripts injected dynamically will always load
> after static script elements. So I don’t think there’s a good way to ensure
> the proper order in run-time unless we do something like
> 99a8c8356573ff16b668f2d39a447355c673fee3 , but that’s verbose and working
> with libs should be simple.
>
>     Any ideas?
>
>     [1]
> https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.html5rocks.com%2Fen%2Ftutorials%2Fspeed%2Fscript-loading%2F%23disqus_thread&amp;data=02%7C01%7Caharui%40adobe.com%7C89b59cc20eff4f34398308d7fb39180f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637254094944356465&amp;sdata=8BCjJ8oV6h2U2wxgorysLU8Sm5tTGwAP7XBEL7yhca4%3D&amp;reserved=0
>
>     From: Alex Harui<ma...@adobe.com.INVALID>
>     Sent: Monday, May 18, 2020 8:03 AM
>     To: dev@royale.apache.org<ma...@royale.apache.org>
>
>
>     Subject: Re: Script Loading Order (Continuing Heads-Up thread from
> Users)
>
>     Every time I look, closure seems to change how it works.  It looks
> like they are using callbacks and UIDs.  I assume they can't use await or
> Promise because of IE support.  I haven't looked at the code you generate,
> but might have to do something similar, IOW, wait for the callback or known
> value before continuing.
>
>     I think that if we create the script during the running of another
> script that we have to find a way to wait for that created script.
>
>     It might help to know what kind of initialization code needed the
> definition so early.  One alternative is that such code needs to be
> responsible for waiting.
>
>     Most of our Application classes have a wait mechanism.  We could
> leverage that, but that's also pretty late.
>
>     It could be that for Applications we generate the script in the head,
> and for modules we generate a separate script that is preloaded.
>
>     HTH,
>     -Alex
>
>     On 5/17/20, 9:03 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
>
>
>         >Is the script tag from inject_script going before or after the
> script tag for the application (should be before, >IMO)?
>
>         It’s going before but the network shows it’s loaded after.
>
>         >Make sure the script tag has the same settings as the script tags
> google closure uses in js-debug.  I think they set some options so the
> scripts load in order.
>
>         I see type being specified in the gcl script elements, while
> inject ones don’t. I suppose it’s worth seeing if that makes a difference,
> though I couldn’t find evidence for that on the web.
>
>
>
>
>

-- 
Carlos Rovira
http://about.me/carlosrovira

Re: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Alex Harui <ah...@adobe.com.INVALID>.
IMO, a SpectrumApplication should either have a custom HTML template that loads the Spectrum css or a wait mechanism to allow the individual components to load the CSS.

I feel like we are trying to solve multiple problems at the same time.  Let's try to focus on just one.

A component's "initialization" is the code that run while the APIs are set up, such as:

org.apache.royale.Foo = function()
{
}

org.apache.royale.foo.prototype.bar = function()
{
}

The instantiation of constructor/method functions and assigning them to these slots should be CSS and PNG/SVG independent.  Static initializers should be lazy in most cases.

Next is the "instantiation" phase when some code actually runs "new Foo()".

IMO, the challenge is that some scripts may not be loaded by the time "new Foo()" runs.  But that is a different problem than having code around during the initialization phase.  What are the patterns that require external code for initialization?  And then what are the patterns for "instantiation"?

Most/All of the Application classes support deferred startup to allow for things needed for instantiation phase.  I think this thread is about the "initialization" phase and I still don't understand the use cases.

Then there is Spectrum and its CSS usage.  If Spectrum has one single CSS file it should be loaded as is.  If Spectrum has multiple CSS files then they must have some mechanism to order them and we should be trying to replicate that mechanism instead of creating a new one.  If the goal is to come up with a mechanism to divide up a single CSS file and make it PAYG per component, that is a subject for a new thread.

My 2 cents,
-Alex

On 5/19/20, 12:26 PM, "Harbs" <ha...@gmail.com> wrote:

    Comments inline.
    
    > On May 19, 2020, at 7:47 PM, Alex Harui <ah...@adobe.com.INVALID> wrote:
    > 
    > IMO, we want to avoid overuse of this feature such that we should not need specifying order.  There should be very few places where this is truly needed.  It is tempting to use it for other things, but it really should only be used when the initialization of the class and prototype requires it.
    
    I totally agree that we want to avoid this as much as possible in Royale code, but I’ve needed extensive use of including CSS for my work with Spectrum.
    
    Spectrum is particular on the order of the loaded CSS, hence the need to specify order. https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fadobe%2Fspectrum-css%2Fissues%2F481&amp;data=02%7C01%7Caharui%40adobe.com%7C2010efb914374d0d290208d7fc2a7a7d%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255131709815050&amp;sdata=dRGOGtlcLQnq10apvYSX64CJoOH8RaKJBotBwLA7R%2BA%3D&amp;reserved=0 <https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fadobe%2Fspectrum-css%2Fissues%2F481&amp;data=02%7C01%7Caharui%40adobe.com%7C2010efb914374d0d290208d7fc2a7a7d%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255131709820030&amp;sdata=gPFQ7N0h2YXQnrmXmBw7JUM632CGCpCZpkcHnkFwsOk%3D&amp;reserved=0>
    
    I’m currently using inject_html in Spectrum, but it’s not a very good solution and I need to reorder the included CSS.
    
    > What would be a scenario where a PNG or SVG file is required to initialize a class?
    
    Skinning and icon sets of libraries come to mind.
    
    For example: Spectrum has its set of required icons which are saved as SVG. Including that in a SWC simplifies library use.
    
    


Re: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Harbs <ha...@gmail.com>.
Comments inline.

> On May 19, 2020, at 7:47 PM, Alex Harui <ah...@adobe.com.INVALID> wrote:
> 
> IMO, we want to avoid overuse of this feature such that we should not need specifying order.  There should be very few places where this is truly needed.  It is tempting to use it for other things, but it really should only be used when the initialization of the class and prototype requires it.

I totally agree that we want to avoid this as much as possible in Royale code, but I’ve needed extensive use of including CSS for my work with Spectrum.

Spectrum is particular on the order of the loaded CSS, hence the need to specify order. https://github.com/adobe/spectrum-css/issues/481 <https://github.com/adobe/spectrum-css/issues/481>

I’m currently using inject_html in Spectrum, but it’s not a very good solution and I need to reorder the included CSS.

> What would be a scenario where a PNG or SVG file is required to initialize a class?

Skinning and icon sets of libraries come to mind.

For example: Spectrum has its set of required icons which are saved as SVG. Including that in a SWC simplifies library use.


Re: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Alex Harui <ah...@adobe.com.INVALID>.
IMO, we want to avoid overuse of this feature such that we should not need specifying order.  There should be very few places where this is truly needed.  It is tempting to use it for other things, but it really should only be used when the initialization of the class and prototype requires it.

What would be a scenario where a PNG or SVG file is required to initialize a class?

We will probably be better off not parsing anything as part of this feature.  Just copy stuff into a known place.  If that requires the developer to write both an html and js version, that still may be simpler than dealing with parsing issues.

And again, without knowing the circumstances for why DialogPolyFill was required, we don't know that we are trying to solve an edge case that we don't really need to solve.  If we're requiring folks to write injection directives it might be easier to tell them to rewrite some initialization pattern in a lazy way.

My 2 cents,
-Alex

On 5/19/20, 9:23 AM, "Harbs" <ha...@gmail.com> wrote:

    > @inject_script path/to/script.js
    > @inject_styles path/to/styles.css
    
    +1 to this (or something along the lines).
    
    While we’re at it, some way to specify order of files would be in order.
    
    We really need a full solution of including (i.e. png,svg) files as well.
    
    > On May 19, 2020, at 7:19 PM, Josh Tynjala <jo...@bowlerhat.dev> wrote:
    > 
    > I'm not a fan of this syntax. It's a weird mix between HTML/XML and... some
    > kind of flat configuration file?
    > 
    > I'd rather use a separate <inject_script> for each JS file and a separate
    > <inject_styles> for each CSS file.
    > 
    > Or maybe something like this:
    > 
    > @inject_script path/to/script.js
    > @inject_styles path/to/styles.css
    > 
    > --
    > Josh Tynjala
    > Bowler Hat LLC <https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbowlerhat.dev%2F&amp;data=02%7C01%7Caharui%40adobe.com%7Ca1a4a474384a481640d208d7fc10ff72%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255022261904839&amp;sdata=7eXHLu4D3W4opNUO6NXtfymsvUkuXHzsBLpjNZbUwY4%3D&amp;reserved=0>
    > 
    > 
    > On Tue, May 19, 2020 at 12:22 AM Yishay Weiss <yi...@hotmail.com>
    > wrote:
    > 
    >> I propose to change the syntax to
    >> 
    >> <inject_sources>
    >>                js=https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fjs1.js%2F&amp;data=02%7C01%7Caharui%40adobe.com%7Ca1a4a474384a481640d208d7fc10ff72%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255022261904839&amp;sdata=QP181by1EjNrfTgAVQ0qsbaTtFhEN3Bp4ik9nvyTf2A%3D&amp;reserved=0
    >>                js=https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fjs2.js%2F&amp;data=02%7C01%7Caharui%40adobe.com%7Ca1a4a474384a481640d208d7fc10ff72%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255022261904839&amp;sdata=tSEf4Ly4%2BceB7pakD%2B6NZivSZswdCJOe72CCrG9JY8Y%3D&amp;reserved=0
    >>                css=https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fcss1.js%2F&amp;data=02%7C01%7Caharui%40adobe.com%7Ca1a4a474384a481640d208d7fc10ff72%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255022261904839&amp;sdata=sDT97lo77XqeiW2flaY%2BHcHNTiKh8nSiYhyg0wgX0f4%3D&amp;reserved=0
    >> <inject_sources>
    >> 
    >> If it’s in the main app the compiler will parse this and inject html, same
    >> way it did before. Injected html is ensured to load serially, so it should
    >> load before App.js.
    >> 
    >> If it’s in a module the compiler will parse this and inject a script to
    >> the __deps file we create for modules, similar to what’s being done now. It
    >> may be that we’ll need to add to the script some mechanism to ensure serial
    >> loading, similar to what gcl does.
    >> 
    >> I can explore this when I have more time, probably next week, or someone
    >> else is welcome to fix this differently.
    >> 
    >> Thanks.
    >> 
    >> 
    >> 
    >> From: Alex Harui<ma...@adobe.com.INVALID>
    >> Sent: Monday, May 18, 2020 7:53 PM
    >> To: dev@royale.apache.org<ma...@royale.apache.org>
    >> Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
    >> 
    >> Ah, ok.  I thought that closure was injecting the main app's script block
    >> so the dynamic script would be in front of it but it makes sense that
    >> wouldn't happen at release time.
    >> 
    >> IIRC, we control the launch of the app.  I thought there is one more
    >> script somewhere that calls app.start() that is generated by the compiler.
    >> IMO, that script can be altered to wait for scripts to load.
    >> 
    >> HTH,
    >> -Alex
    >> 
    >> 
    >> On 5/18/20, 8:44 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
    >> 
    >>    Unless I missed something that’s what it’s doing right now after my
    >> fix. I’ll try to explain the scenario as I see it (no modules).
    >> 
    >>    Suppose we have an app that compiles to the following html.
    >> 
    >>    <html>
    >>                    <head>
    >>                                    <script type="text/javascript">
    >>                                                    var script =
    >> document.createElement("script");
    >> 
    >> script.setAttribute("src", "hljs.min.js");
    >> 
    >> document.head.appendChild(script);
    >>                                    </script>
    >>                                    <script type=”text/JavaScript”
    >> src=”App.js”></script>
    >>                    </head>
    >>                    <body></body>
    >>    </html>
    >> 
    >>    After the first script element is loaded, the dom will look like:
    >> 
    >>    <html>
    >>                    <head>
    >>                                    <script type="text/javascript">
    >>                                                    var script =
    >> document.createElement("script");
    >> 
    >> script.setAttribute("src", "hljs.min.js");
    >> 
    >> document.head.appendChild(script);
    >>                                    </script>
    >>                                    <script type=”text/JavaScript”
    >> src=”hljs.min.js”></script>
    >>                                    <script type=”text/JavaScript”
    >> src=”App.js”></script>
    >>                    </head>
    >>                    <body></body>
    >>    </html>
    >> 
    >>    However, App.js will still be loaded before hljs.min.js because it was
    >> not created dynamically. App.js will fail because it depends on hljs.
    >> 
    >>    From: Alex Harui<ma...@adobe.com.INVALID>
    >>    Sent: Monday, May 18, 2020 6:21 PM
    >>    To: dev@royale.apache.org<ma...@royale.apache.org>
    >>    Subject: Re: Script Loading Order (Continuing Heads-Up thread from
    >> Users)
    >> 
    >>    I don't think we have to inject these scripts into the main .js file.
    >> The compiler knows when it is compiling the main app or a module.  When
    >> compiling the main app, it should inject the script in the HEAD of the html
    >> wrapper.  For modules, it can inject the script into a separate file.  The
    >> ModuleLoader already loads extra files before loading the module.  It can
    >> load one more file.
    >> 
    >>    Of course, I could be wrong...
    >>    -Alex
    >> 
    >>    On 5/18/20, 7:38 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
    >> 
    >>        From what I’ve read [1] scripts injected dynamically will always
    >> load after static script elements. So I don’t think there’s a good way to
    >> ensure the proper order in run-time unless we do something like
    >> 99a8c8356573ff16b668f2d39a447355c673fee3 , but that’s verbose and working
    >> with libs should be simple.
    >> 
    >>        Any ideas?
    >> 
    >>        [1]
    >> https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.html5rocks.com%2Fen%2Ftutorials%2Fspeed%2Fscript-loading%2F%23disqus_thread&amp;data=02%7C01%7Caharui%40adobe.com%7Ca1a4a474384a481640d208d7fc10ff72%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637255022261904839&amp;sdata=fW6MMmTf3afTeHbntw%2BdKpNHEfUTUcpPKyMO8DpsUck%3D&amp;reserved=0
    >> 
    >>        From: Alex Harui<ma...@adobe.com.INVALID>
    >>        Sent: Monday, May 18, 2020 8:03 AM
    >>        To: dev@royale.apache.org<ma...@royale.apache.org>
    >> 
    >> 
    >>        Subject: Re: Script Loading Order (Continuing Heads-Up thread from
    >> Users)
    >> 
    >>        Every time I look, closure seems to change how it works.  It looks
    >> like they are using callbacks and UIDs.  I assume they can't use await or
    >> Promise because of IE support.  I haven't looked at the code you generate,
    >> but might have to do something similar, IOW, wait for the callback or known
    >> value before continuing.
    >> 
    >>        I think that if we create the script during the running of another
    >> script that we have to find a way to wait for that created script.
    >> 
    >>        It might help to know what kind of initialization code needed the
    >> definition so early.  One alternative is that such code needs to be
    >> responsible for waiting.
    >> 
    >>        Most of our Application classes have a wait mechanism.  We could
    >> leverage that, but that's also pretty late.
    >> 
    >>        It could be that for Applications we generate the script in the
    >> head, and for modules we generate a separate script that is preloaded.
    >> 
    >>        HTH,
    >>        -Alex
    >> 
    >>        On 5/17/20, 9:03 AM, "Yishay Weiss" <yi...@hotmail.com>
    >> wrote:
    >> 
    >> 
    >>> Is the script tag from inject_script going before or after
    >> the script tag for the application (should be before, >IMO)?
    >> 
    >>            It’s going before but the network shows it’s loaded after.
    >> 
    >>> Make sure the script tag has the same settings as the script
    >> tags google closure uses in js-debug.  I think they set some options so the
    >> scripts load in order.
    >> 
    >>            I see type being specified in the gcl script elements, while
    >> inject ones don’t. I suppose it’s worth seeing if that makes a difference,
    >> though I couldn’t find evidence for that on the web.
    >> 
    >> 
    >> 
    >> 
    >> 
    >> 
    >> 
    
    


Re: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Harbs <ha...@gmail.com>.
> @inject_script path/to/script.js
> @inject_styles path/to/styles.css

+1 to this (or something along the lines).

While we’re at it, some way to specify order of files would be in order.

We really need a full solution of including (i.e. png,svg) files as well.

> On May 19, 2020, at 7:19 PM, Josh Tynjala <jo...@bowlerhat.dev> wrote:
> 
> I'm not a fan of this syntax. It's a weird mix between HTML/XML and... some
> kind of flat configuration file?
> 
> I'd rather use a separate <inject_script> for each JS file and a separate
> <inject_styles> for each CSS file.
> 
> Or maybe something like this:
> 
> @inject_script path/to/script.js
> @inject_styles path/to/styles.css
> 
> --
> Josh Tynjala
> Bowler Hat LLC <https://bowlerhat.dev>
> 
> 
> On Tue, May 19, 2020 at 12:22 AM Yishay Weiss <yi...@hotmail.com>
> wrote:
> 
>> I propose to change the syntax to
>> 
>> <inject_sources>
>>                js=http://js1.js
>>                js=http://js2.js
>>                css=http://css1.js
>> <inject_sources>
>> 
>> If it’s in the main app the compiler will parse this and inject html, same
>> way it did before. Injected html is ensured to load serially, so it should
>> load before App.js.
>> 
>> If it’s in a module the compiler will parse this and inject a script to
>> the __deps file we create for modules, similar to what’s being done now. It
>> may be that we’ll need to add to the script some mechanism to ensure serial
>> loading, similar to what gcl does.
>> 
>> I can explore this when I have more time, probably next week, or someone
>> else is welcome to fix this differently.
>> 
>> Thanks.
>> 
>> 
>> 
>> From: Alex Harui<ma...@adobe.com.INVALID>
>> Sent: Monday, May 18, 2020 7:53 PM
>> To: dev@royale.apache.org<ma...@royale.apache.org>
>> Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
>> 
>> Ah, ok.  I thought that closure was injecting the main app's script block
>> so the dynamic script would be in front of it but it makes sense that
>> wouldn't happen at release time.
>> 
>> IIRC, we control the launch of the app.  I thought there is one more
>> script somewhere that calls app.start() that is generated by the compiler.
>> IMO, that script can be altered to wait for scripts to load.
>> 
>> HTH,
>> -Alex
>> 
>> 
>> On 5/18/20, 8:44 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
>> 
>>    Unless I missed something that’s what it’s doing right now after my
>> fix. I’ll try to explain the scenario as I see it (no modules).
>> 
>>    Suppose we have an app that compiles to the following html.
>> 
>>    <html>
>>                    <head>
>>                                    <script type="text/javascript">
>>                                                    var script =
>> document.createElement("script");
>> 
>> script.setAttribute("src", "hljs.min.js");
>> 
>> document.head.appendChild(script);
>>                                    </script>
>>                                    <script type=”text/JavaScript”
>> src=”App.js”></script>
>>                    </head>
>>                    <body></body>
>>    </html>
>> 
>>    After the first script element is loaded, the dom will look like:
>> 
>>    <html>
>>                    <head>
>>                                    <script type="text/javascript">
>>                                                    var script =
>> document.createElement("script");
>> 
>> script.setAttribute("src", "hljs.min.js");
>> 
>> document.head.appendChild(script);
>>                                    </script>
>>                                    <script type=”text/JavaScript”
>> src=”hljs.min.js”></script>
>>                                    <script type=”text/JavaScript”
>> src=”App.js”></script>
>>                    </head>
>>                    <body></body>
>>    </html>
>> 
>>    However, App.js will still be loaded before hljs.min.js because it was
>> not created dynamically. App.js will fail because it depends on hljs.
>> 
>>    From: Alex Harui<ma...@adobe.com.INVALID>
>>    Sent: Monday, May 18, 2020 6:21 PM
>>    To: dev@royale.apache.org<ma...@royale.apache.org>
>>    Subject: Re: Script Loading Order (Continuing Heads-Up thread from
>> Users)
>> 
>>    I don't think we have to inject these scripts into the main .js file.
>> The compiler knows when it is compiling the main app or a module.  When
>> compiling the main app, it should inject the script in the HEAD of the html
>> wrapper.  For modules, it can inject the script into a separate file.  The
>> ModuleLoader already loads extra files before loading the module.  It can
>> load one more file.
>> 
>>    Of course, I could be wrong...
>>    -Alex
>> 
>>    On 5/18/20, 7:38 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
>> 
>>        From what I’ve read [1] scripts injected dynamically will always
>> load after static script elements. So I don’t think there’s a good way to
>> ensure the proper order in run-time unless we do something like
>> 99a8c8356573ff16b668f2d39a447355c673fee3 , but that’s verbose and working
>> with libs should be simple.
>> 
>>        Any ideas?
>> 
>>        [1]
>> https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.html5rocks.com%2Fen%2Ftutorials%2Fspeed%2Fscript-loading%2F%23disqus_thread&amp;data=02%7C01%7Caharui%40adobe.com%7C11eca28410ab4d377cb408d7fb4254da%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637254134629069170&amp;sdata=NuGReT8L9tH9K1VQNxgN%2BctVG3WDACYxMsaSywrTOSc%3D&amp;reserved=0
>> 
>>        From: Alex Harui<ma...@adobe.com.INVALID>
>>        Sent: Monday, May 18, 2020 8:03 AM
>>        To: dev@royale.apache.org<ma...@royale.apache.org>
>> 
>> 
>>        Subject: Re: Script Loading Order (Continuing Heads-Up thread from
>> Users)
>> 
>>        Every time I look, closure seems to change how it works.  It looks
>> like they are using callbacks and UIDs.  I assume they can't use await or
>> Promise because of IE support.  I haven't looked at the code you generate,
>> but might have to do something similar, IOW, wait for the callback or known
>> value before continuing.
>> 
>>        I think that if we create the script during the running of another
>> script that we have to find a way to wait for that created script.
>> 
>>        It might help to know what kind of initialization code needed the
>> definition so early.  One alternative is that such code needs to be
>> responsible for waiting.
>> 
>>        Most of our Application classes have a wait mechanism.  We could
>> leverage that, but that's also pretty late.
>> 
>>        It could be that for Applications we generate the script in the
>> head, and for modules we generate a separate script that is preloaded.
>> 
>>        HTH,
>>        -Alex
>> 
>>        On 5/17/20, 9:03 AM, "Yishay Weiss" <yi...@hotmail.com>
>> wrote:
>> 
>> 
>>> Is the script tag from inject_script going before or after
>> the script tag for the application (should be before, >IMO)?
>> 
>>            It’s going before but the network shows it’s loaded after.
>> 
>>> Make sure the script tag has the same settings as the script
>> tags google closure uses in js-debug.  I think they set some options so the
>> scripts load in order.
>> 
>>            I see type being specified in the gcl script elements, while
>> inject ones don’t. I suppose it’s worth seeing if that makes a difference,
>> though I couldn’t find evidence for that on the web.
>> 
>> 
>> 
>> 
>> 
>> 
>> 


RE: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Yishay Weiss <yi...@hotmail.com>.
I have no special preference regarding syntax as long as it’s simple to use and easy to parse.

From: Josh Tynjala<ma...@bowlerhat.dev>
Sent: Tuesday, May 19, 2020 7:20 PM
To: Apache Royale Development<ma...@royale.apache.org>
Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

I'm not a fan of this syntax. It's a weird mix between HTML/XML and... some
kind of flat configuration file?

I'd rather use a separate <inject_script> for each JS file and a separate
<inject_styles> for each CSS file.

Or maybe something like this:

@inject_script path/to/script.js
@inject_styles path/to/styles.css

--
Josh Tynjala
Bowler Hat LLC <https://bowlerhat.dev>


On Tue, May 19, 2020 at 12:22 AM Yishay Weiss <yi...@hotmail.com>
wrote:

> I propose to change the syntax to
>
> <inject_sources>
>                 js=http://js1.js
>                 js=http://js2.js
>                 css=http://css1.js
> <inject_sources>
>
> If it’s in the main app the compiler will parse this and inject html, same
> way it did before. Injected html is ensured to load serially, so it should
> load before App.js.
>
> If it’s in a module the compiler will parse this and inject a script to
> the __deps file we create for modules, similar to what’s being done now. It
> may be that we’ll need to add to the script some mechanism to ensure serial
> loading, similar to what gcl does.
>
> I can explore this when I have more time, probably next week, or someone
> else is welcome to fix this differently.
>
> Thanks.
>
>
>
> From: Alex Harui<ma...@adobe.com.INVALID>
> Sent: Monday, May 18, 2020 7:53 PM
> To: dev@royale.apache.org<ma...@royale.apache.org>
> Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
>
> Ah, ok.  I thought that closure was injecting the main app's script block
> so the dynamic script would be in front of it but it makes sense that
> wouldn't happen at release time.
>
> IIRC, we control the launch of the app.  I thought there is one more
> script somewhere that calls app.start() that is generated by the compiler.
> IMO, that script can be altered to wait for scripts to load.
>
> HTH,
> -Alex
>
>
> On 5/18/20, 8:44 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
>
>     Unless I missed something that’s what it’s doing right now after my
> fix. I’ll try to explain the scenario as I see it (no modules).
>
>     Suppose we have an app that compiles to the following html.
>
>     <html>
>                     <head>
>                                     <script type="text/javascript">
>                                                     var script =
> document.createElement("script");
>
> script.setAttribute("src", "hljs.min.js");
>
> document.head.appendChild(script);
>                                     </script>
>                                     <script type=”text/JavaScript”
> src=”App.js”></script>
>                     </head>
>                     <body></body>
>     </html>
>
>     After the first script element is loaded, the dom will look like:
>
>     <html>
>                     <head>
>                                     <script type="text/javascript">
>                                                     var script =
> document.createElement("script");
>
> script.setAttribute("src", "hljs.min.js");
>
> document.head.appendChild(script);
>                                     </script>
>                                     <script type=”text/JavaScript”
> src=”hljs.min.js”></script>
>                                     <script type=”text/JavaScript”
> src=”App.js”></script>
>                     </head>
>                     <body></body>
>     </html>
>
>     However, App.js will still be loaded before hljs.min.js because it was
> not created dynamically. App.js will fail because it depends on hljs.
>
>     From: Alex Harui<ma...@adobe.com.INVALID>
>     Sent: Monday, May 18, 2020 6:21 PM
>     To: dev@royale.apache.org<ma...@royale.apache.org>
>     Subject: Re: Script Loading Order (Continuing Heads-Up thread from
> Users)
>
>     I don't think we have to inject these scripts into the main .js file.
> The compiler knows when it is compiling the main app or a module.  When
> compiling the main app, it should inject the script in the HEAD of the html
> wrapper.  For modules, it can inject the script into a separate file.  The
> ModuleLoader already loads extra files before loading the module.  It can
> load one more file.
>
>     Of course, I could be wrong...
>     -Alex
>
>     On 5/18/20, 7:38 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
>
>         From what I’ve read [1] scripts injected dynamically will always
> load after static script elements. So I don’t think there’s a good way to
> ensure the proper order in run-time unless we do something like
> 99a8c8356573ff16b668f2d39a447355c673fee3 , but that’s verbose and working
> with libs should be simple.
>
>         Any ideas?
>
>         [1]
> https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.html5rocks.com%2Fen%2Ftutorials%2Fspeed%2Fscript-loading%2F%23disqus_thread&amp;data=02%7C01%7Caharui%40adobe.com%7C11eca28410ab4d377cb408d7fb4254da%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637254134629069170&amp;sdata=NuGReT8L9tH9K1VQNxgN%2BctVG3WDACYxMsaSywrTOSc%3D&amp;reserved=0
>
>         From: Alex Harui<ma...@adobe.com.INVALID>
>         Sent: Monday, May 18, 2020 8:03 AM
>         To: dev@royale.apache.org<ma...@royale.apache.org>
>
>
>         Subject: Re: Script Loading Order (Continuing Heads-Up thread from
> Users)
>
>         Every time I look, closure seems to change how it works.  It looks
> like they are using callbacks and UIDs.  I assume they can't use await or
> Promise because of IE support.  I haven't looked at the code you generate,
> but might have to do something similar, IOW, wait for the callback or known
> value before continuing.
>
>         I think that if we create the script during the running of another
> script that we have to find a way to wait for that created script.
>
>         It might help to know what kind of initialization code needed the
> definition so early.  One alternative is that such code needs to be
> responsible for waiting.
>
>         Most of our Application classes have a wait mechanism.  We could
> leverage that, but that's also pretty late.
>
>         It could be that for Applications we generate the script in the
> head, and for modules we generate a separate script that is preloaded.
>
>         HTH,
>         -Alex
>
>         On 5/17/20, 9:03 AM, "Yishay Weiss" <yi...@hotmail.com>
> wrote:
>
>
>             >Is the script tag from inject_script going before or after
> the script tag for the application (should be before, >IMO)?
>
>             It’s going before but the network shows it’s loaded after.
>
>             >Make sure the script tag has the same settings as the script
> tags google closure uses in js-debug.  I think they set some options so the
> scripts load in order.
>
>             I see type being specified in the gcl script elements, while
> inject ones don’t. I suppose it’s worth seeing if that makes a difference,
> though I couldn’t find evidence for that on the web.
>
>
>
>
>
>
>


Re: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Josh Tynjala <jo...@bowlerhat.dev>.
I'm not a fan of this syntax. It's a weird mix between HTML/XML and... some
kind of flat configuration file?

I'd rather use a separate <inject_script> for each JS file and a separate
<inject_styles> for each CSS file.

Or maybe something like this:

@inject_script path/to/script.js
@inject_styles path/to/styles.css

--
Josh Tynjala
Bowler Hat LLC <https://bowlerhat.dev>


On Tue, May 19, 2020 at 12:22 AM Yishay Weiss <yi...@hotmail.com>
wrote:

> I propose to change the syntax to
>
> <inject_sources>
>                 js=http://js1.js
>                 js=http://js2.js
>                 css=http://css1.js
> <inject_sources>
>
> If it’s in the main app the compiler will parse this and inject html, same
> way it did before. Injected html is ensured to load serially, so it should
> load before App.js.
>
> If it’s in a module the compiler will parse this and inject a script to
> the __deps file we create for modules, similar to what’s being done now. It
> may be that we’ll need to add to the script some mechanism to ensure serial
> loading, similar to what gcl does.
>
> I can explore this when I have more time, probably next week, or someone
> else is welcome to fix this differently.
>
> Thanks.
>
>
>
> From: Alex Harui<ma...@adobe.com.INVALID>
> Sent: Monday, May 18, 2020 7:53 PM
> To: dev@royale.apache.org<ma...@royale.apache.org>
> Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
>
> Ah, ok.  I thought that closure was injecting the main app's script block
> so the dynamic script would be in front of it but it makes sense that
> wouldn't happen at release time.
>
> IIRC, we control the launch of the app.  I thought there is one more
> script somewhere that calls app.start() that is generated by the compiler.
> IMO, that script can be altered to wait for scripts to load.
>
> HTH,
> -Alex
>
>
> On 5/18/20, 8:44 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
>
>     Unless I missed something that’s what it’s doing right now after my
> fix. I’ll try to explain the scenario as I see it (no modules).
>
>     Suppose we have an app that compiles to the following html.
>
>     <html>
>                     <head>
>                                     <script type="text/javascript">
>                                                     var script =
> document.createElement("script");
>
> script.setAttribute("src", "hljs.min.js");
>
> document.head.appendChild(script);
>                                     </script>
>                                     <script type=”text/JavaScript”
> src=”App.js”></script>
>                     </head>
>                     <body></body>
>     </html>
>
>     After the first script element is loaded, the dom will look like:
>
>     <html>
>                     <head>
>                                     <script type="text/javascript">
>                                                     var script =
> document.createElement("script");
>
> script.setAttribute("src", "hljs.min.js");
>
> document.head.appendChild(script);
>                                     </script>
>                                     <script type=”text/JavaScript”
> src=”hljs.min.js”></script>
>                                     <script type=”text/JavaScript”
> src=”App.js”></script>
>                     </head>
>                     <body></body>
>     </html>
>
>     However, App.js will still be loaded before hljs.min.js because it was
> not created dynamically. App.js will fail because it depends on hljs.
>
>     From: Alex Harui<ma...@adobe.com.INVALID>
>     Sent: Monday, May 18, 2020 6:21 PM
>     To: dev@royale.apache.org<ma...@royale.apache.org>
>     Subject: Re: Script Loading Order (Continuing Heads-Up thread from
> Users)
>
>     I don't think we have to inject these scripts into the main .js file.
> The compiler knows when it is compiling the main app or a module.  When
> compiling the main app, it should inject the script in the HEAD of the html
> wrapper.  For modules, it can inject the script into a separate file.  The
> ModuleLoader already loads extra files before loading the module.  It can
> load one more file.
>
>     Of course, I could be wrong...
>     -Alex
>
>     On 5/18/20, 7:38 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
>
>         From what I’ve read [1] scripts injected dynamically will always
> load after static script elements. So I don’t think there’s a good way to
> ensure the proper order in run-time unless we do something like
> 99a8c8356573ff16b668f2d39a447355c673fee3 , but that’s verbose and working
> with libs should be simple.
>
>         Any ideas?
>
>         [1]
> https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.html5rocks.com%2Fen%2Ftutorials%2Fspeed%2Fscript-loading%2F%23disqus_thread&amp;data=02%7C01%7Caharui%40adobe.com%7C11eca28410ab4d377cb408d7fb4254da%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637254134629069170&amp;sdata=NuGReT8L9tH9K1VQNxgN%2BctVG3WDACYxMsaSywrTOSc%3D&amp;reserved=0
>
>         From: Alex Harui<ma...@adobe.com.INVALID>
>         Sent: Monday, May 18, 2020 8:03 AM
>         To: dev@royale.apache.org<ma...@royale.apache.org>
>
>
>         Subject: Re: Script Loading Order (Continuing Heads-Up thread from
> Users)
>
>         Every time I look, closure seems to change how it works.  It looks
> like they are using callbacks and UIDs.  I assume they can't use await or
> Promise because of IE support.  I haven't looked at the code you generate,
> but might have to do something similar, IOW, wait for the callback or known
> value before continuing.
>
>         I think that if we create the script during the running of another
> script that we have to find a way to wait for that created script.
>
>         It might help to know what kind of initialization code needed the
> definition so early.  One alternative is that such code needs to be
> responsible for waiting.
>
>         Most of our Application classes have a wait mechanism.  We could
> leverage that, but that's also pretty late.
>
>         It could be that for Applications we generate the script in the
> head, and for modules we generate a separate script that is preloaded.
>
>         HTH,
>         -Alex
>
>         On 5/17/20, 9:03 AM, "Yishay Weiss" <yi...@hotmail.com>
> wrote:
>
>
>             >Is the script tag from inject_script going before or after
> the script tag for the application (should be before, >IMO)?
>
>             It’s going before but the network shows it’s loaded after.
>
>             >Make sure the script tag has the same settings as the script
> tags google closure uses in js-debug.  I think they set some options so the
> scripts load in order.
>
>             I see type being specified in the gcl script elements, while
> inject ones don’t. I suppose it’s worth seeing if that makes a difference,
> though I couldn’t find evidence for that on the web.
>
>
>
>
>
>
>

RE: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Yishay Weiss <yi...@hotmail.com>.
In

<inject_sources>
js=js1
js=js2
</inject_sources>

js=js1 loads js1 and js=js2 loads js2. No difference, just an example of loading more than one dependency in the same inject tag.

I don’t think supporting both inject_html and inject_js is much simpler than parsing the above syntax and generating the required js/html, and it would be simpler in my opinion for the user, and for the fw developer.

I didn’t figure out why in release dialogPolyfill causes a failure on startup. Interestingly, there’s no such failure in debug mode, even if I remove the inject_script.

It maybe possible to dynamically load App.js but I didn’t investigate that.

I think having a simple syntax and avoiding making the user think too much when using a 3rd party lib is important. I tried to address that too in my proposal.

From: Alex Harui<ma...@adobe.com.INVALID>
Sent: Tuesday, May 19, 2020 6:06 PM
To: dev@royale.apache.org<ma...@royale.apache.org>
Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

I don’t think I understand the proposal.  What is the difference between the two "js" definitions?

I think we could support both inject_html and inject_script and require inject_script for modules, so framework usage would have to have both inject_html and inject_script equivalents and report an error if compiling a module and inject_html is found but not inject_script.

Did we ever figure out what code would fail if DialogPolyFill wasn't loaded before App.js?  I'm hoping we're not doing all of this work for an edge case with a simple workaround.

Is another option to dynamically load App.js?

-Alex

On 5/19/20, 12:22 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:

    I propose to change the syntax to

    <inject_sources>
                    js=https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fjs1.js%2F&amp;data=02%7C01%7Caharui%40adobe.com%7Cb1259c69852b4f53b37f08d7fbc56837%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637254697587653756&amp;sdata=NpxmSDXB8KCIBR4dpCV5PsZneS5nTjgyZ%2FO3AZSkgFc%3D&amp;reserved=0
                    js=https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fjs2.js%2F&amp;data=02%7C01%7Caharui%40adobe.com%7Cb1259c69852b4f53b37f08d7fbc56837%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637254697587653756&amp;sdata=Wp%2BG2aFd%2BRcN5FruFAZEDT36PK0zfRCDEDolggrhQBM%3D&amp;reserved=0
                    css=https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fcss1.js%2F&amp;data=02%7C01%7Caharui%40adobe.com%7Cb1259c69852b4f53b37f08d7fbc56837%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637254697587653756&amp;sdata=xLOMEC4Fcxwbv1JBa8WU2%2Fgx%2BAhAbF1B731IxNZIspI%3D&amp;reserved=0
    <inject_sources>

    If it’s in the main app the compiler will parse this and inject html, same way it did before. Injected html is ensured to load serially, so it should load before App.js.

    If it’s in a module the compiler will parse this and inject a script to the __deps file we create for modules, similar to what’s being done now. It may be that we’ll need to add to the script some mechanism to ensure serial loading, similar to what gcl does.

    I can explore this when I have more time, probably next week, or someone else is welcome to fix this differently.

    Thanks.



    From: Alex Harui<ma...@adobe.com.INVALID>
    Sent: Monday, May 18, 2020 7:53 PM
    To: dev@royale.apache.org<ma...@royale.apache.org>
    Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

    Ah, ok.  I thought that closure was injecting the main app's script block so the dynamic script would be in front of it but it makes sense that wouldn't happen at release time.

    IIRC, we control the launch of the app.  I thought there is one more script somewhere that calls app.start() that is generated by the compiler.  IMO, that script can be altered to wait for scripts to load.

    HTH,
    -Alex


    On 5/18/20, 8:44 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:

        Unless I missed something that’s what it’s doing right now after my fix. I’ll try to explain the scenario as I see it (no modules).

        Suppose we have an app that compiles to the following html.

        <html>
                        <head>
                                        <script type="text/javascript">
                                                        var script = document.createElement("script");
                                                        script.setAttribute("src", "hljs.min.js");
                                                        document.head.appendChild(script);
                                        </script>
                                        <script type=”text/JavaScript” src=”App.js”></script>
                        </head>
                        <body></body>
        </html>

        After the first script element is loaded, the dom will look like:

        <html>
                        <head>
                                        <script type="text/javascript">
                                                        var script = document.createElement("script");
                                                        script.setAttribute("src", "hljs.min.js");
                                                        document.head.appendChild(script);
                                        </script>
                                        <script type=”text/JavaScript” src=”hljs.min.js”></script>
                                        <script type=”text/JavaScript” src=”App.js”></script>
                        </head>
                        <body></body>
        </html>

        However, App.js will still be loaded before hljs.min.js because it was not created dynamically. App.js will fail because it depends on hljs.

        From: Alex Harui<ma...@adobe.com.INVALID>
        Sent: Monday, May 18, 2020 6:21 PM
        To: dev@royale.apache.org<ma...@royale.apache.org>
        Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

        I don't think we have to inject these scripts into the main .js file.  The compiler knows when it is compiling the main app or a module.  When compiling the main app, it should inject the script in the HEAD of the html wrapper.  For modules, it can inject the script into a separate file.  The ModuleLoader already loads extra files before loading the module.  It can load one more file.

        Of course, I could be wrong...
        -Alex

        On 5/18/20, 7:38 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:

            From what I’ve read [1] scripts injected dynamically will always load after static script elements. So I don’t think there’s a good way to ensure the proper order in run-time unless we do something like 99a8c8356573ff16b668f2d39a447355c673fee3 , but that’s verbose and working with libs should be simple.

            Any ideas?

            [1] https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.html5rocks.com%2Fen%2Ftutorials%2Fspeed%2Fscript-loading%2F%23disqus_thread&amp;data=02%7C01%7Caharui%40adobe.com%7Cb1259c69852b4f53b37f08d7fbc56837%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637254697587653756&amp;sdata=KKBA2grWRQsVSj6Ykq2Sx3UJEPFo8yD7VuK4KF2FaRY%3D&amp;reserved=0

            From: Alex Harui<ma...@adobe.com.INVALID>
            Sent: Monday, May 18, 2020 8:03 AM
            To: dev@royale.apache.org<ma...@royale.apache.org>


            Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

            Every time I look, closure seems to change how it works.  It looks like they are using callbacks and UIDs.  I assume they can't use await or Promise because of IE support.  I haven't looked at the code you generate, but might have to do something similar, IOW, wait for the callback or known value before continuing.

            I think that if we create the script during the running of another script that we have to find a way to wait for that created script.

            It might help to know what kind of initialization code needed the definition so early.  One alternative is that such code needs to be responsible for waiting.

            Most of our Application classes have a wait mechanism.  We could leverage that, but that's also pretty late.

            It could be that for Applications we generate the script in the head, and for modules we generate a separate script that is preloaded.

            HTH,
            -Alex

            On 5/17/20, 9:03 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:


                >Is the script tag from inject_script going before or after the script tag for the application (should be before, >IMO)?

                It’s going before but the network shows it’s loaded after.

                >Make sure the script tag has the same settings as the script tags google closure uses in js-debug.  I think they set some options so the scripts load in order.

                I see type being specified in the gcl script elements, while inject ones don’t. I suppose it’s worth seeing if that makes a difference, though I couldn’t find evidence for that on the web.









Re: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Alex Harui <ah...@adobe.com.INVALID>.
I don’t think I understand the proposal.  What is the difference between the two "js" definitions?

I think we could support both inject_html and inject_script and require inject_script for modules, so framework usage would have to have both inject_html and inject_script equivalents and report an error if compiling a module and inject_html is found but not inject_script.

Did we ever figure out what code would fail if DialogPolyFill wasn't loaded before App.js?  I'm hoping we're not doing all of this work for an edge case with a simple workaround.

Is another option to dynamically load App.js?

-Alex

On 5/19/20, 12:22 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:

    I propose to change the syntax to
    
    <inject_sources>
                    js=https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fjs1.js%2F&amp;data=02%7C01%7Caharui%40adobe.com%7Cb1259c69852b4f53b37f08d7fbc56837%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637254697587653756&amp;sdata=NpxmSDXB8KCIBR4dpCV5PsZneS5nTjgyZ%2FO3AZSkgFc%3D&amp;reserved=0
                    js=https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fjs2.js%2F&amp;data=02%7C01%7Caharui%40adobe.com%7Cb1259c69852b4f53b37f08d7fbc56837%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637254697587653756&amp;sdata=Wp%2BG2aFd%2BRcN5FruFAZEDT36PK0zfRCDEDolggrhQBM%3D&amp;reserved=0
                    css=https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fcss1.js%2F&amp;data=02%7C01%7Caharui%40adobe.com%7Cb1259c69852b4f53b37f08d7fbc56837%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637254697587653756&amp;sdata=xLOMEC4Fcxwbv1JBa8WU2%2Fgx%2BAhAbF1B731IxNZIspI%3D&amp;reserved=0
    <inject_sources>
    
    If it’s in the main app the compiler will parse this and inject html, same way it did before. Injected html is ensured to load serially, so it should load before App.js.
    
    If it’s in a module the compiler will parse this and inject a script to the __deps file we create for modules, similar to what’s being done now. It may be that we’ll need to add to the script some mechanism to ensure serial loading, similar to what gcl does.
    
    I can explore this when I have more time, probably next week, or someone else is welcome to fix this differently.
    
    Thanks.
    
    
    
    From: Alex Harui<ma...@adobe.com.INVALID>
    Sent: Monday, May 18, 2020 7:53 PM
    To: dev@royale.apache.org<ma...@royale.apache.org>
    Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
    
    Ah, ok.  I thought that closure was injecting the main app's script block so the dynamic script would be in front of it but it makes sense that wouldn't happen at release time.
    
    IIRC, we control the launch of the app.  I thought there is one more script somewhere that calls app.start() that is generated by the compiler.  IMO, that script can be altered to wait for scripts to load.
    
    HTH,
    -Alex
    
    
    On 5/18/20, 8:44 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
    
        Unless I missed something that’s what it’s doing right now after my fix. I’ll try to explain the scenario as I see it (no modules).
    
        Suppose we have an app that compiles to the following html.
    
        <html>
                        <head>
                                        <script type="text/javascript">
                                                        var script = document.createElement("script");
                                                        script.setAttribute("src", "hljs.min.js");
                                                        document.head.appendChild(script);
                                        </script>
                                        <script type=”text/JavaScript” src=”App.js”></script>
                        </head>
                        <body></body>
        </html>
    
        After the first script element is loaded, the dom will look like:
    
        <html>
                        <head>
                                        <script type="text/javascript">
                                                        var script = document.createElement("script");
                                                        script.setAttribute("src", "hljs.min.js");
                                                        document.head.appendChild(script);
                                        </script>
                                        <script type=”text/JavaScript” src=”hljs.min.js”></script>
                                        <script type=”text/JavaScript” src=”App.js”></script>
                        </head>
                        <body></body>
        </html>
    
        However, App.js will still be loaded before hljs.min.js because it was not created dynamically. App.js will fail because it depends on hljs.
    
        From: Alex Harui<ma...@adobe.com.INVALID>
        Sent: Monday, May 18, 2020 6:21 PM
        To: dev@royale.apache.org<ma...@royale.apache.org>
        Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
    
        I don't think we have to inject these scripts into the main .js file.  The compiler knows when it is compiling the main app or a module.  When compiling the main app, it should inject the script in the HEAD of the html wrapper.  For modules, it can inject the script into a separate file.  The ModuleLoader already loads extra files before loading the module.  It can load one more file.
    
        Of course, I could be wrong...
        -Alex
    
        On 5/18/20, 7:38 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
    
            From what I’ve read [1] scripts injected dynamically will always load after static script elements. So I don’t think there’s a good way to ensure the proper order in run-time unless we do something like 99a8c8356573ff16b668f2d39a447355c673fee3 , but that’s verbose and working with libs should be simple.
    
            Any ideas?
    
            [1] https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.html5rocks.com%2Fen%2Ftutorials%2Fspeed%2Fscript-loading%2F%23disqus_thread&amp;data=02%7C01%7Caharui%40adobe.com%7Cb1259c69852b4f53b37f08d7fbc56837%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637254697587653756&amp;sdata=KKBA2grWRQsVSj6Ykq2Sx3UJEPFo8yD7VuK4KF2FaRY%3D&amp;reserved=0
    
            From: Alex Harui<ma...@adobe.com.INVALID>
            Sent: Monday, May 18, 2020 8:03 AM
            To: dev@royale.apache.org<ma...@royale.apache.org>
    
    
            Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
    
            Every time I look, closure seems to change how it works.  It looks like they are using callbacks and UIDs.  I assume they can't use await or Promise because of IE support.  I haven't looked at the code you generate, but might have to do something similar, IOW, wait for the callback or known value before continuing.
    
            I think that if we create the script during the running of another script that we have to find a way to wait for that created script.
    
            It might help to know what kind of initialization code needed the definition so early.  One alternative is that such code needs to be responsible for waiting.
    
            Most of our Application classes have a wait mechanism.  We could leverage that, but that's also pretty late.
    
            It could be that for Applications we generate the script in the head, and for modules we generate a separate script that is preloaded.
    
            HTH,
            -Alex
    
            On 5/17/20, 9:03 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
    
    
                >Is the script tag from inject_script going before or after the script tag for the application (should be before, >IMO)?
    
                It’s going before but the network shows it’s loaded after.
    
                >Make sure the script tag has the same settings as the script tags google closure uses in js-debug.  I think they set some options so the scripts load in order.
    
                I see type being specified in the gcl script elements, while inject ones don’t. I suppose it’s worth seeing if that makes a difference, though I couldn’t find evidence for that on the web.
    
    
    
    
    
    
    


RE: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Yishay Weiss <yi...@hotmail.com>.
I propose to change the syntax to

<inject_sources>
                js=http://js1.js
                js=http://js2.js
                css=http://css1.js
<inject_sources>

If it’s in the main app the compiler will parse this and inject html, same way it did before. Injected html is ensured to load serially, so it should load before App.js.

If it’s in a module the compiler will parse this and inject a script to the __deps file we create for modules, similar to what’s being done now. It may be that we’ll need to add to the script some mechanism to ensure serial loading, similar to what gcl does.

I can explore this when I have more time, probably next week, or someone else is welcome to fix this differently.

Thanks.



From: Alex Harui<ma...@adobe.com.INVALID>
Sent: Monday, May 18, 2020 7:53 PM
To: dev@royale.apache.org<ma...@royale.apache.org>
Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

Ah, ok.  I thought that closure was injecting the main app's script block so the dynamic script would be in front of it but it makes sense that wouldn't happen at release time.

IIRC, we control the launch of the app.  I thought there is one more script somewhere that calls app.start() that is generated by the compiler.  IMO, that script can be altered to wait for scripts to load.

HTH,
-Alex


On 5/18/20, 8:44 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:

    Unless I missed something that’s what it’s doing right now after my fix. I’ll try to explain the scenario as I see it (no modules).

    Suppose we have an app that compiles to the following html.

    <html>
                    <head>
                                    <script type="text/javascript">
                                                    var script = document.createElement("script");
                                                    script.setAttribute("src", "hljs.min.js");
                                                    document.head.appendChild(script);
                                    </script>
                                    <script type=”text/JavaScript” src=”App.js”></script>
                    </head>
                    <body></body>
    </html>

    After the first script element is loaded, the dom will look like:

    <html>
                    <head>
                                    <script type="text/javascript">
                                                    var script = document.createElement("script");
                                                    script.setAttribute("src", "hljs.min.js");
                                                    document.head.appendChild(script);
                                    </script>
                                    <script type=”text/JavaScript” src=”hljs.min.js”></script>
                                    <script type=”text/JavaScript” src=”App.js”></script>
                    </head>
                    <body></body>
    </html>

    However, App.js will still be loaded before hljs.min.js because it was not created dynamically. App.js will fail because it depends on hljs.

    From: Alex Harui<ma...@adobe.com.INVALID>
    Sent: Monday, May 18, 2020 6:21 PM
    To: dev@royale.apache.org<ma...@royale.apache.org>
    Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

    I don't think we have to inject these scripts into the main .js file.  The compiler knows when it is compiling the main app or a module.  When compiling the main app, it should inject the script in the HEAD of the html wrapper.  For modules, it can inject the script into a separate file.  The ModuleLoader already loads extra files before loading the module.  It can load one more file.

    Of course, I could be wrong...
    -Alex

    On 5/18/20, 7:38 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:

        From what I’ve read [1] scripts injected dynamically will always load after static script elements. So I don’t think there’s a good way to ensure the proper order in run-time unless we do something like 99a8c8356573ff16b668f2d39a447355c673fee3 , but that’s verbose and working with libs should be simple.

        Any ideas?

        [1] https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.html5rocks.com%2Fen%2Ftutorials%2Fspeed%2Fscript-loading%2F%23disqus_thread&amp;data=02%7C01%7Caharui%40adobe.com%7C11eca28410ab4d377cb408d7fb4254da%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637254134629069170&amp;sdata=NuGReT8L9tH9K1VQNxgN%2BctVG3WDACYxMsaSywrTOSc%3D&amp;reserved=0

        From: Alex Harui<ma...@adobe.com.INVALID>
        Sent: Monday, May 18, 2020 8:03 AM
        To: dev@royale.apache.org<ma...@royale.apache.org>


        Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

        Every time I look, closure seems to change how it works.  It looks like they are using callbacks and UIDs.  I assume they can't use await or Promise because of IE support.  I haven't looked at the code you generate, but might have to do something similar, IOW, wait for the callback or known value before continuing.

        I think that if we create the script during the running of another script that we have to find a way to wait for that created script.

        It might help to know what kind of initialization code needed the definition so early.  One alternative is that such code needs to be responsible for waiting.

        Most of our Application classes have a wait mechanism.  We could leverage that, but that's also pretty late.

        It could be that for Applications we generate the script in the head, and for modules we generate a separate script that is preloaded.

        HTH,
        -Alex

        On 5/17/20, 9:03 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:


            >Is the script tag from inject_script going before or after the script tag for the application (should be before, >IMO)?

            It’s going before but the network shows it’s loaded after.

            >Make sure the script tag has the same settings as the script tags google closure uses in js-debug.  I think they set some options so the scripts load in order.

            I see type being specified in the gcl script elements, while inject ones don’t. I suppose it’s worth seeing if that makes a difference, though I couldn’t find evidence for that on the web.







Re: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Alex Harui <ah...@adobe.com.INVALID>.
Ah, ok.  I thought that closure was injecting the main app's script block so the dynamic script would be in front of it but it makes sense that wouldn't happen at release time.

IIRC, we control the launch of the app.  I thought there is one more script somewhere that calls app.start() that is generated by the compiler.  IMO, that script can be altered to wait for scripts to load.

HTH,
-Alex


On 5/18/20, 8:44 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:

    Unless I missed something that’s what it’s doing right now after my fix. I’ll try to explain the scenario as I see it (no modules).
    
    Suppose we have an app that compiles to the following html.
    
    <html>
                    <head>
                                    <script type="text/javascript">
                                                    var script = document.createElement("script");
                                                    script.setAttribute("src", "hljs.min.js");
                                                    document.head.appendChild(script);
                                    </script>
                                    <script type=”text/JavaScript” src=”App.js”></script>
                    </head>
                    <body></body>
    </html>
    
    After the first script element is loaded, the dom will look like:
    
    <html>
                    <head>
                                    <script type="text/javascript">
                                                    var script = document.createElement("script");
                                                    script.setAttribute("src", "hljs.min.js");
                                                    document.head.appendChild(script);
                                    </script>
                                    <script type=”text/JavaScript” src=”hljs.min.js”></script>
                                    <script type=”text/JavaScript” src=”App.js”></script>
                    </head>
                    <body></body>
    </html>
    
    However, App.js will still be loaded before hljs.min.js because it was not created dynamically. App.js will fail because it depends on hljs.
    
    From: Alex Harui<ma...@adobe.com.INVALID>
    Sent: Monday, May 18, 2020 6:21 PM
    To: dev@royale.apache.org<ma...@royale.apache.org>
    Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
    
    I don't think we have to inject these scripts into the main .js file.  The compiler knows when it is compiling the main app or a module.  When compiling the main app, it should inject the script in the HEAD of the html wrapper.  For modules, it can inject the script into a separate file.  The ModuleLoader already loads extra files before loading the module.  It can load one more file.
    
    Of course, I could be wrong...
    -Alex
    
    On 5/18/20, 7:38 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
    
        From what I’ve read [1] scripts injected dynamically will always load after static script elements. So I don’t think there’s a good way to ensure the proper order in run-time unless we do something like 99a8c8356573ff16b668f2d39a447355c673fee3 , but that’s verbose and working with libs should be simple.
    
        Any ideas?
    
        [1] https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.html5rocks.com%2Fen%2Ftutorials%2Fspeed%2Fscript-loading%2F%23disqus_thread&amp;data=02%7C01%7Caharui%40adobe.com%7C11eca28410ab4d377cb408d7fb4254da%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637254134629069170&amp;sdata=NuGReT8L9tH9K1VQNxgN%2BctVG3WDACYxMsaSywrTOSc%3D&amp;reserved=0
    
        From: Alex Harui<ma...@adobe.com.INVALID>
        Sent: Monday, May 18, 2020 8:03 AM
        To: dev@royale.apache.org<ma...@royale.apache.org>
    
    
        Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
    
        Every time I look, closure seems to change how it works.  It looks like they are using callbacks and UIDs.  I assume they can't use await or Promise because of IE support.  I haven't looked at the code you generate, but might have to do something similar, IOW, wait for the callback or known value before continuing.
    
        I think that if we create the script during the running of another script that we have to find a way to wait for that created script.
    
        It might help to know what kind of initialization code needed the definition so early.  One alternative is that such code needs to be responsible for waiting.
    
        Most of our Application classes have a wait mechanism.  We could leverage that, but that's also pretty late.
    
        It could be that for Applications we generate the script in the head, and for modules we generate a separate script that is preloaded.
    
        HTH,
        -Alex
    
        On 5/17/20, 9:03 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
    
    
            >Is the script tag from inject_script going before or after the script tag for the application (should be before, >IMO)?
    
            It’s going before but the network shows it’s loaded after.
    
            >Make sure the script tag has the same settings as the script tags google closure uses in js-debug.  I think they set some options so the scripts load in order.
    
            I see type being specified in the gcl script elements, while inject ones don’t. I suppose it’s worth seeing if that makes a difference, though I couldn’t find evidence for that on the web.
    
    
    
    
    


RE: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Yishay Weiss <yi...@hotmail.com>.
Unless I missed something that’s what it’s doing right now after my fix. I’ll try to explain the scenario as I see it (no modules).

Suppose we have an app that compiles to the following html.

<html>
                <head>
                                <script type="text/javascript">
                                                var script = document.createElement("script");
                                                script.setAttribute("src", "hljs.min.js");
                                                document.head.appendChild(script);
                                </script>
                                <script type=”text/JavaScript” src=”App.js”></script>
                </head>
                <body></body>
</html>

After the first script element is loaded, the dom will look like:

<html>
                <head>
                                <script type="text/javascript">
                                                var script = document.createElement("script");
                                                script.setAttribute("src", "hljs.min.js");
                                                document.head.appendChild(script);
                                </script>
                                <script type=”text/JavaScript” src=”hljs.min.js”></script>
                                <script type=”text/JavaScript” src=”App.js”></script>
                </head>
                <body></body>
</html>

However, App.js will still be loaded before hljs.min.js because it was not created dynamically. App.js will fail because it depends on hljs.

From: Alex Harui<ma...@adobe.com.INVALID>
Sent: Monday, May 18, 2020 6:21 PM
To: dev@royale.apache.org<ma...@royale.apache.org>
Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

I don't think we have to inject these scripts into the main .js file.  The compiler knows when it is compiling the main app or a module.  When compiling the main app, it should inject the script in the HEAD of the html wrapper.  For modules, it can inject the script into a separate file.  The ModuleLoader already loads extra files before loading the module.  It can load one more file.

Of course, I could be wrong...
-Alex

On 5/18/20, 7:38 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:

    From what I’ve read [1] scripts injected dynamically will always load after static script elements. So I don’t think there’s a good way to ensure the proper order in run-time unless we do something like 99a8c8356573ff16b668f2d39a447355c673fee3 , but that’s verbose and working with libs should be simple.

    Any ideas?

    [1] https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.html5rocks.com%2Fen%2Ftutorials%2Fspeed%2Fscript-loading%2F%23disqus_thread&amp;data=02%7C01%7Caharui%40adobe.com%7C89b59cc20eff4f34398308d7fb39180f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637254094944356465&amp;sdata=8BCjJ8oV6h2U2wxgorysLU8Sm5tTGwAP7XBEL7yhca4%3D&amp;reserved=0

    From: Alex Harui<ma...@adobe.com.INVALID>
    Sent: Monday, May 18, 2020 8:03 AM
    To: dev@royale.apache.org<ma...@royale.apache.org>


    Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

    Every time I look, closure seems to change how it works.  It looks like they are using callbacks and UIDs.  I assume they can't use await or Promise because of IE support.  I haven't looked at the code you generate, but might have to do something similar, IOW, wait for the callback or known value before continuing.

    I think that if we create the script during the running of another script that we have to find a way to wait for that created script.

    It might help to know what kind of initialization code needed the definition so early.  One alternative is that such code needs to be responsible for waiting.

    Most of our Application classes have a wait mechanism.  We could leverage that, but that's also pretty late.

    It could be that for Applications we generate the script in the head, and for modules we generate a separate script that is preloaded.

    HTH,
    -Alex

    On 5/17/20, 9:03 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:


        >Is the script tag from inject_script going before or after the script tag for the application (should be before, >IMO)?

        It’s going before but the network shows it’s loaded after.

        >Make sure the script tag has the same settings as the script tags google closure uses in js-debug.  I think they set some options so the scripts load in order.

        I see type being specified in the gcl script elements, while inject ones don’t. I suppose it’s worth seeing if that makes a difference, though I couldn’t find evidence for that on the web.





Re: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Alex Harui <ah...@adobe.com.INVALID>.
I don't think we have to inject these scripts into the main .js file.  The compiler knows when it is compiling the main app or a module.  When compiling the main app, it should inject the script in the HEAD of the html wrapper.  For modules, it can inject the script into a separate file.  The ModuleLoader already loads extra files before loading the module.  It can load one more file.

Of course, I could be wrong...
-Alex

On 5/18/20, 7:38 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:

    From what I’ve read [1] scripts injected dynamically will always load after static script elements. So I don’t think there’s a good way to ensure the proper order in run-time unless we do something like 99a8c8356573ff16b668f2d39a447355c673fee3 , but that’s verbose and working with libs should be simple.
    
    Any ideas?
    
    [1] https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.html5rocks.com%2Fen%2Ftutorials%2Fspeed%2Fscript-loading%2F%23disqus_thread&amp;data=02%7C01%7Caharui%40adobe.com%7C89b59cc20eff4f34398308d7fb39180f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637254094944356465&amp;sdata=8BCjJ8oV6h2U2wxgorysLU8Sm5tTGwAP7XBEL7yhca4%3D&amp;reserved=0
    
    From: Alex Harui<ma...@adobe.com.INVALID>
    Sent: Monday, May 18, 2020 8:03 AM
    To: dev@royale.apache.org<ma...@royale.apache.org>
    
    
    Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)
    
    Every time I look, closure seems to change how it works.  It looks like they are using callbacks and UIDs.  I assume they can't use await or Promise because of IE support.  I haven't looked at the code you generate, but might have to do something similar, IOW, wait for the callback or known value before continuing.
    
    I think that if we create the script during the running of another script that we have to find a way to wait for that created script.
    
    It might help to know what kind of initialization code needed the definition so early.  One alternative is that such code needs to be responsible for waiting.
    
    Most of our Application classes have a wait mechanism.  We could leverage that, but that's also pretty late.
    
    It could be that for Applications we generate the script in the head, and for modules we generate a separate script that is preloaded.
    
    HTH,
    -Alex
    
    On 5/17/20, 9:03 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
    
    
        >Is the script tag from inject_script going before or after the script tag for the application (should be before, >IMO)?
    
        It’s going before but the network shows it’s loaded after.
    
        >Make sure the script tag has the same settings as the script tags google closure uses in js-debug.  I think they set some options so the scripts load in order.
    
        I see type being specified in the gcl script elements, while inject ones don’t. I suppose it’s worth seeing if that makes a difference, though I couldn’t find evidence for that on the web.
    
    
    


RE: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Yishay Weiss <yi...@hotmail.com>.
From what I’ve read [1] scripts injected dynamically will always load after static script elements. So I don’t think there’s a good way to ensure the proper order in run-time unless we do something like 99a8c8356573ff16b668f2d39a447355c673fee3 , but that’s verbose and working with libs should be simple.

Any ideas?

[1] https://www.html5rocks.com/en/tutorials/speed/script-loading/#disqus_thread

From: Alex Harui<ma...@adobe.com.INVALID>
Sent: Monday, May 18, 2020 8:03 AM
To: dev@royale.apache.org<ma...@royale.apache.org>


Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

Every time I look, closure seems to change how it works.  It looks like they are using callbacks and UIDs.  I assume they can't use await or Promise because of IE support.  I haven't looked at the code you generate, but might have to do something similar, IOW, wait for the callback or known value before continuing.

I think that if we create the script during the running of another script that we have to find a way to wait for that created script.

It might help to know what kind of initialization code needed the definition so early.  One alternative is that such code needs to be responsible for waiting.

Most of our Application classes have a wait mechanism.  We could leverage that, but that's also pretty late.

It could be that for Applications we generate the script in the head, and for modules we generate a separate script that is preloaded.

HTH,
-Alex

On 5/17/20, 9:03 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:


    >Is the script tag from inject_script going before or after the script tag for the application (should be before, >IMO)?

    It’s going before but the network shows it’s loaded after.

    >Make sure the script tag has the same settings as the script tags google closure uses in js-debug.  I think they set some options so the scripts load in order.

    I see type being specified in the gcl script elements, while inject ones don’t. I suppose it’s worth seeing if that makes a difference, though I couldn’t find evidence for that on the web.



RE: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Yishay Weiss <yi...@hotmail.com>.
Scratch all that. I was loading dialog and testing hljs…

________________________________
From: Yishay Weiss <yi...@hotmail.com>
Sent: Monday, May 18, 2020 9:09:45 AM
To: dev@royale.apache.org <de...@royale.apache.org>
Subject: RE: Script Loading Order (Continuing Heads-Up thread from Users)

Replacing

                                <script type="text/javascript" src="./my.js"></script>
With

                                <script defer type="text/javascript" src="./my.js"></script>

Results in network tab showing my.js loaded after dialog-polyfill.js, but I’m still getting the same failure. It looks like at least for dialog stuff we just need to be smart about when we use it, and check for the object being defined.

From: Yishay Weiss<ma...@hotmail.com>
Sent: Monday, May 18, 2020 9:05 AM
To: dev@royale.apache.org<ma...@royale.apache.org>
Subject: RE: Script Loading Order (Continuing Heads-Up thread from Users)

This code fails for me with and undefined hljs message:

<!DOCTYPE html>
<html>
                <head>
                                <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/dialog-polyfill/0.4.9/dialog-polyfill.min.js"></script<https://cdnjs.cloudflare.com/ajax/libs/dialog-polyfill/0.4.9/dialog-polyfill.min.js%22%3e%3c/script>>
                                <script type="text/javascript" src="./my.js"></script>
                </head>
<body></body>
</html>

my.js is

console.log(hljs.highlightBlock);

There are no generated scripts here. Network is again showing that my.js is loaded after dialog-polyfill.min.js. Could it be that Chrome is prioritizing local resources?

From: Alex Harui<ma...@adobe.com.INVALID>
Sent: Monday, May 18, 2020 8:03 AM
To: dev@royale.apache.org<ma...@royale.apache.org>
Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

Every time I look, closure seems to change how it works.  It looks like they are using callbacks and UIDs.  I assume they can't use await or Promise because of IE support.  I haven't looked at the code you generate, but might have to do something similar, IOW, wait for the callback or known value before continuing.

I think that if we create the script during the running of another script that we have to find a way to wait for that created script.

It might help to know what kind of initialization code needed the definition so early.  One alternative is that such code needs to be responsible for waiting.

Most of our Application classes have a wait mechanism.  We could leverage that, but that's also pretty late.

It could be that for Applications we generate the script in the head, and for modules we generate a separate script that is preloaded.

HTH,
-Alex

On 5/17/20, 9:03 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:


    >Is the script tag from inject_script going before or after the script tag for the application (should be before, >IMO)?

    It’s going before but the network shows it’s loaded after.

    >Make sure the script tag has the same settings as the script tags google closure uses in js-debug.  I think they set some options so the scripts load in order.

    I see type being specified in the gcl script elements, while inject ones don’t. I suppose it’s worth seeing if that makes a difference, though I couldn’t find evidence for that on the web.



RE: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Yishay Weiss <yi...@hotmail.com>.
Replacing

                                <script type="text/javascript" src="./my.js"></script>
With

                                <script defer type="text/javascript" src="./my.js"></script>

Results in network tab showing my.js loaded after dialog-polyfill.js, but I’m still getting the same failure. It looks like at least for dialog stuff we just need to be smart about when we use it, and check for the object being defined.

From: Yishay Weiss<ma...@hotmail.com>
Sent: Monday, May 18, 2020 9:05 AM
To: dev@royale.apache.org<ma...@royale.apache.org>
Subject: RE: Script Loading Order (Continuing Heads-Up thread from Users)

This code fails for me with and undefined hljs message:

<!DOCTYPE html>
<html>
                <head>
                                <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/dialog-polyfill/0.4.9/dialog-polyfill.min.js"></script<https://cdnjs.cloudflare.com/ajax/libs/dialog-polyfill/0.4.9/dialog-polyfill.min.js%22%3e%3c/script>>
                                <script type="text/javascript" src="./my.js"></script>
                </head>
<body></body>
</html>

my.js is

console.log(hljs.highlightBlock);

There are no generated scripts here. Network is again showing that my.js is loaded after dialog-polyfill.min.js. Could it be that Chrome is prioritizing local resources?

From: Alex Harui<ma...@adobe.com.INVALID>
Sent: Monday, May 18, 2020 8:03 AM
To: dev@royale.apache.org<ma...@royale.apache.org>
Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

Every time I look, closure seems to change how it works.  It looks like they are using callbacks and UIDs.  I assume they can't use await or Promise because of IE support.  I haven't looked at the code you generate, but might have to do something similar, IOW, wait for the callback or known value before continuing.

I think that if we create the script during the running of another script that we have to find a way to wait for that created script.

It might help to know what kind of initialization code needed the definition so early.  One alternative is that such code needs to be responsible for waiting.

Most of our Application classes have a wait mechanism.  We could leverage that, but that's also pretty late.

It could be that for Applications we generate the script in the head, and for modules we generate a separate script that is preloaded.

HTH,
-Alex

On 5/17/20, 9:03 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:


    >Is the script tag from inject_script going before or after the script tag for the application (should be before, >IMO)?

    It’s going before but the network shows it’s loaded after.

    >Make sure the script tag has the same settings as the script tags google closure uses in js-debug.  I think they set some options so the scripts load in order.

    I see type being specified in the gcl script elements, while inject ones don’t. I suppose it’s worth seeing if that makes a difference, though I couldn’t find evidence for that on the web.



RE: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Yishay Weiss <yi...@hotmail.com>.
This code fails for me with and undefined hljs message:

<!DOCTYPE html>
<html>
                <head>
                                <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/dialog-polyfill/0.4.9/dialog-polyfill.min.js"></script>
                                <script type="text/javascript" src="./my.js"></script>
                </head>
<body></body>
</html>

my.js is

console.log(hljs.highlightBlock);

There are no generated scripts here. Network is again showing that my.js is loaded after dialog-polyfill.min.js. Could it be that Chrome is prioritizing local resources?

From: Alex Harui<ma...@adobe.com.INVALID>
Sent: Monday, May 18, 2020 8:03 AM
To: dev@royale.apache.org<ma...@royale.apache.org>
Subject: Re: Script Loading Order (Continuing Heads-Up thread from Users)

Every time I look, closure seems to change how it works.  It looks like they are using callbacks and UIDs.  I assume they can't use await or Promise because of IE support.  I haven't looked at the code you generate, but might have to do something similar, IOW, wait for the callback or known value before continuing.

I think that if we create the script during the running of another script that we have to find a way to wait for that created script.

It might help to know what kind of initialization code needed the definition so early.  One alternative is that such code needs to be responsible for waiting.

Most of our Application classes have a wait mechanism.  We could leverage that, but that's also pretty late.

It could be that for Applications we generate the script in the head, and for modules we generate a separate script that is preloaded.

HTH,
-Alex

On 5/17/20, 9:03 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:


    >Is the script tag from inject_script going before or after the script tag for the application (should be before, >IMO)?

    It’s going before but the network shows it’s loaded after.

    >Make sure the script tag has the same settings as the script tags google closure uses in js-debug.  I think they set some options so the scripts load in order.

    I see type being specified in the gcl script elements, while inject ones don’t. I suppose it’s worth seeing if that makes a difference, though I couldn’t find evidence for that on the web.



Re: Script Loading Order (Continuing Heads-Up thread from Users)

Posted by Alex Harui <ah...@adobe.com.INVALID>.
Every time I look, closure seems to change how it works.  It looks like they are using callbacks and UIDs.  I assume they can't use await or Promise because of IE support.  I haven't looked at the code you generate, but might have to do something similar, IOW, wait for the callback or known value before continuing.

I think that if we create the script during the running of another script that we have to find a way to wait for that created script.

It might help to know what kind of initialization code needed the definition so early.  One alternative is that such code needs to be responsible for waiting.

Most of our Application classes have a wait mechanism.  We could leverage that, but that's also pretty late.

It could be that for Applications we generate the script in the head, and for modules we generate a separate script that is preloaded.

HTH,
-Alex

On 5/17/20, 9:03 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:

    
    >Is the script tag from inject_script going before or after the script tag for the application (should be before, >IMO)?
    
    It’s going before but the network shows it’s loaded after.
    
    >Make sure the script tag has the same settings as the script tags google closure uses in js-debug.  I think they set some options so the scripts load in order.
    
    I see type being specified in the gcl script elements, while inject ones don’t. I suppose it’s worth seeing if that makes a difference, though I couldn’t find evidence for that on the web.