Looks good, thanks.

________________________________
From: Josh Tynjala <joshtynj...@bowlerhat.dev>
Sent: Monday, June 1, 2020 6:59:07 PM
To: Apache Royale Development <dev@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 <yishayj...@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<mailto:aha...@adobe.com.INVALID>
> Sent: Wednesday, May 20, 2020 8:09 PM
> To: dev@royale.apache.org<mailto:dev@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" <yishayj...@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<mailto:aha...@adobe.com.INVALID>
>     Sent: Wednesday, May 20, 2020 9:52 AM
>     To: dev@royale.apache.org<mailto:dev@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" <yishayj...@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<mailto:aha...@adobe.com.INVALID>
>         Sent: Tuesday, May 19, 2020 10:03 PM
>         To: dev@royale.apache.org<mailto:dev@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" <yishayj...@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<mailto:carlosrov...@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 (<
> yishayj...@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<mailto:aha...@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" <yishayj...@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<mailto:aha...@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" <
> yishayj...@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
>
>
>
>
>
>
>
>

Reply via email to