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" <yishayj...@hotmail.com> wrote: Good, thanks. Out of curiosity, what special handling do externs need? From: Josh Tynjala<mailto:joshtynj...@bowlerhat.dev> Sent: Monday, June 1, 2020 2:01 AM To: Apache Royale Development<mailto:dev@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&data=02%7C01%7Caharui%40adobe.com%7C161a52e6f1e743d8046a08d805f745e1%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265906882631155&sdata=XaR6WYJSBgMUQfWQDc3wOD2TXSi1QqjpP1%2FcljV3IUc%3D&reserved=0> 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="https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fns.adobe.com%2Fmxml%2F2009&data=02%7C01%7Caharui%40adobe.com%7C161a52e6f1e743d8046a08d805f745e1%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265906882631155&sdata=wkyh88Lwwhzu8%2BNcM6RMODIUfBF0vWlkFNUm6Mx8Wjs%3D&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&data=02%7C01%7Caharui%40adobe.com%7C161a52e6f1e743d8046a08d805f745e1%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265906882631155&sdata=aOqz6hScb3UxeTWM3XJ%2FTerQnGc6B8QEuJgKR0eO9f8%3D&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<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://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fhighlight.js%2F9.12.0%2Fhighlight.min.js&data=02%7C01%7Caharui%40adobe.com%7C161a52e6f1e743d8046a08d805f745e1%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265906882641150&sdata=jRqEz2TAUdYDkRobaBUJHdAgxJ%2FajTNHNuaXyBhc0so%3D&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" <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&data=02%7C01%7Caharui%40adobe.com%7C161a52e6f1e743d8046a08d805f745e1%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265906882641150&sdata=jRqEz2TAUdYDkRobaBUJHdAgxJ%2FajTNHNuaXyBhc0so%3D&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&data=02%7C01%7Caharui%40adobe.com%7C161a52e6f1e743d8046a08d805f745e1%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265906882641150&sdata=8%2F0ZUXlSGJfB8c1wW6a9qenM9CLzcFqBUe7GLYfCnxQ%3D&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&data=02%7C01%7Caharui%40adobe.com%7C161a52e6f1e743d8046a08d805f745e1%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637265906882641150&sdata=79WbNRkoyomf6bCvL4TnduvU8vInlwya2QocLTGLV3E%3D&reserved=0 > > > > > > > >