Dojo addOnLoad, but is Dojo loaded? - dom

I've encountered what seems like a chicken & egg problem, and have what I think is a logical solution. However, it occurred to me that others must have encountered something similar, so I figured I'd float it out there for the masses.
The situation is that I want to use dojo's addOnLoad function to queue up a number of callbacks which should be executed after the DOM has completed rendering on the client side. So what I'm doing is as follows:
<html>
<head>
<script type="text/javascript" src="dojo.xd.js"></script>
...
</head>
<body>
...
<script type="text/javascript">
dojo.addOnLoad( ... );
dojo.addOnLoad( ... );
...
</script>
</body>
</html>
Now, the issue is that I seem to be calling dojo.addOnLoad before the entire Dojo library has been downloaded the browser. This makes sense in a way, because the inline SCRIPT contents should be executed before the entire DOM is loaded (and the normal body onload callback is triggered).
My question is this - is my approach sound, or would it make more sense to register a normal/standard body onload JavaScript callback to call a function, which does the same work that each of the dojo.addOnLoads is doing in the SCRIPT block. Of course, this begs the question, why would you ever then use dojo.addOnLoad if you're not guaranteed that the Dojo library will be loaded prior to using the library?
Hopefully this situation makes sense to someone other than me. Seems like someone else may have encountered this situation.
Thoughts?
Best Regards,
Adam Rice

You're doing it correctly. External Javascript files are loaded and executed synchronously in order, so by the time it reaches your dojo.addOnLoad( ... ); Dojo has loaded. Use dojo.addOnLoad instead of window.onload for two reasons:
it fires earlier, because it utilizes DOMContentLoaded
it handles asynchronous loading of dojo.require by postponing the execution until all required scripts have been read
Explained in DojoCampus as (dojo.addOnLoad):
dojo.addOnLoad is a fundamental aspect
of using Dojo. Passing addOnLoad a
function will register the function to
run when the Dom is ready. This
differs slightly from document.ready
and body.onload in that addOnLoad
waits until all dojo.require() (and
their recursive dependencies) have
loaded before firing.

This might have nothing to do with your problem, but ive just had a case where I had the same symptoms. For me everything worked fine for Firefox, Chrome etc, but not IE8.
I was getting what looked like dojo not being loaded, an error in IE8 saying that dojo was undefined (but not all the time) and i could strip everything down to just style sheets and importing dojo and still get the error.
I was running a local google app engine development server. This looks to be based on pythons SimpleHTTPServer which in turn uses SocketServer.BaseServer. This has BaseServer.request_queue_size which defaults to 5 - i couldn't find anything in app engine which overrode this value so i guess the development google app engine server has an upper limit of 5 connections.
Using regedit and going to HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings
“MaxConnectionsPerServer”=dword:00000010
“MaxConnectionsPer1_0Server”=dword:0000010
This shows that IE was going to try and open up to 10 simultaneous connections. I edited these two keys and made them 2 and restarted the computer, the problem went away.

Related

Jekyll compilation: Process completed with exit code 1 on Github

I am using cayman theme for github for writing scientific articles which i can host on Github pages. I am using mathjax to render equations.
I have pasted the following lines inside the cayman/_includes/head-custom.html file.
<script type="text/javascript" id="MathJax-script" async
src="https://cdn.jsdelivr.net/npm/mathjax#3/es5/tex-mml-chtml.js">
</script>
Mathjax renders the math equations correctly (local and remote), but it produces an error on Github (image attached). I can not make anything out of this error, I am a little concerned that it may create bigger issue later on.
Any guesses why this error and how to fix it.
It appears that your html-proofer test script implementation is set to check for CORS/SRI on external js resources and thus is throwing a validation error because it's expecting a couple of additional attributes on all <script> tags (that aren't there currently on the tags in question), crossorigin="anonymous" and integrity="...insert-sha256-value-here..."
My understanding is that SRI needs to be supported by the developer and therefore the integrity value should be coming from them.
If MathJax hasn't provided an integrity value along with their CDN script code then I think you may need to disable checking for CORS/SRI to eliminate the error.
Do you have access to the script that contains the command that runs html-proofer, and if so, can you see if it's checking for SRI? Might look something like this:
htmlproofer --check-sri ...
According to the html-proofer docs, --check-sri defaults to false, so if this option is being set and you can disable it, I'd give that a try.

WebPageTest :: How can Start Render be after the load event?

What can cause the start render to be delayed even after the load event has fired?
Look at this webpagetest result
This is most probably a bug. For the moment, the iPhone instance on WebPageTest is quite recent and the author is still improving it:
The iOS support is just becoming stable though it's still under VERY active development so don't be surprised if there are a few rough edges (and a lot more limitations than the android testing).
- Patrick Meenan, 09-09-2015
The android tests are much more reliable.
If you check the page you tested without javascript (F1 > Disable Javascript in Chrome DevTools), you can see that most images are lazy-loaded, which mean they are loaded via a JS script checking if the images are in the viewport. As you can see, without JS the load time line is well after all assets loaded.
Also for other assets, like JS, you can add an async or defer attribute to de-synchronize your scripts loads.
Finally, some scripts can be even deliberately loaded after the load event using an attachment on the window load event to write <script> tags in the body when it's triggered as loadJS do for example.
You should read that by the way to better understand how rendering and events timing work.

How do I stop prism.js from processing automatically

I want to call Prism.highlightElement or Prism.highlightAll after doing some other javascript processing on my code blocks. I can somewhat control the moment that Prism processes by where I place the <script src="prism.js"></script> but I don't see a way to disable automated processing.
Super kludgy answer:
Even though I asked for the development, not minified, version of prism.js when I download, what I got is kind of minified. Anyway, I found this bit of code:
var a=document.getElementsByTagName("script")
and changed it to this:
var a=document.getElementsByTagName("scriptxx")
So, nothing gets highlighted now, until I explicitly call Prism.highlightAll().

GWT 2.7: Warn users they are using an unsupported browser

I recently upgraded my application to GWT 2.7 from GWT 2.5. This has caused me to drop support for IE6 and IE7.
I would like to provide users with IE6 or IE7 with a warning that their browser is outdated and will not work. At the moment if you go to the app with one of those browsers, you get a blank screen.
I know there are a couple ways that I could hack something together but I would rather use the GWT way, rather than some hack. Is there a GWT hook for unsupported browsers?
Option (hack) One
Drop this into my main.html:
if(document.documentMode === 6 || document.documentMode === 7){
myUnsupportedBrowserWarningFunction();
}
Potential problem with this is that if someone is using a browser that GWT doesn't recognise and I don't recognise (mobile opera? Some other browser), they will still get a blank page.
Option (hack) Two
GWT looks for the compiled JS here:
gwt/myApp/ASDFKLSDJFLSFDJSLDFJLSJDFSDES.cache.js
When someone is using an unsupported browser the following is requested (and is not found):
gwt/myApp/undefined.cache.js
It would be possible to create undefined.cache.js and put your unsupported browser code there. This is obviously a brittle solution and will break with future GWT updates.
Option Three
A recent patch (available in GWT 2.7) allows you to provide a default
permutation (e.g. safari) if GWT can not detect the browser and with
deferred binding you can display a warning that the provided app might not
work correctly as the browser is generally unsupported by GWT.
-- J.
Source
I don't want to set a default permutation for unsupported browsers. I want the site to not work and to display a warning. So this solution doesn't really provide what I am looking for.
Similar Questions & Posts
The same question was asked for an eariler version of GWT in 2009. I hope that GWT has added some kind of hook or best practice in the last 6 years.
More info on setting a default (fallback) permutation
You should be able to use onLoadErrorFn for that: https://code.google.com/p/google-web-toolkit/issues/detail?id=8135
<script>
function gwtLoadError(errMsg) {
// GWT app couldn't load, reason in errorMsg
}
</script>
<meta name="gwt:onLoadErrorFn" content="gwtLoadError">
or possibly onPropertyErrorFn:
<script>
function gwtPropError(propName, allowedValues, actualValue) {
if (propName == 'user.agent') {
// unsupported browser
}
}
</script>
<meta name="gwt:onPropertyErrorFn" content="gwtPropError">
(I don't think user.agent.runtimeWarning would help in this case, but maybe have a look)
There is an easy way:
Conditional Comments
<!--[if lt IE 8]>
<p>You are using an unsupportet browser. Please perform an update</p>
<![endif]-->
I think Option 3 may be the best one, but there is a problem: This will start the actual application (which still may be incompatible).
If this is an issue and you want a clear warning, you can rewrite the permutation selection script (You would need to update the script with the upcoming GWT releases)
You will need to copy this source:
https://gwt.googlesource.com/gwt/+/2.7.0/user/src/com/google/gwt/useragent/rebind/UserAgentPropertyGenerator.java
You could add something like:
$wnd.Location.replace('nosupported.html');
between line 90 and 91

body.onload and GWT onModuleLoad launch order

According to this FAQ, when GWT bootstraps, onModuleLoad is supossed to run before HTML body's onload event. The process detailed within that FAQ works like this:
1. The HTML document is fetched and parsing begins.
...
9. externalScriptOne.js completes. The document is ready, so onModuleLoad() fires.
...
12. body.onload() fires, in this case showing an alert() box.
But in my tests, i have checked that it doesnt work this way. Or at least not in every browser (oddly, Google Chrome in particular doesn't stick to this kind of behaviour). For example, I have this little test involving onModuleLoad and body.onLoad:
public void onModuleLoad() {
runTestFunction();
}
private native void runTestFunction() /*-{
console.log("GWT's onModuleLoad");
$wnd.loaded=true;
}-*/;
And:
<body onload="console.log('body.onLoad');if(loaded!=null) console.log('loaded var is set');">
If i launch firefox, and run this example, the console will show this:
GWT's onModuleLoad
body.onLoad
loaded var is set
But in Chrome:
body.onLoad
Uncaught ReferenceError: loaded is not defined
GWT's onModuleLoad
In the latter, onModuleLoad runs the last, thus "loaded" var is not yet available and body.onLoad code cant use it.
And what Im trying to achieve? I want some handwritten Javascript that runs within body.onload to interact with my GWT code. In this example i use this dummy "loaded" var, but in the future it should be able to call GWT functions written in Java. The problem is that i need to make sure that onModuleLoad runs first so it can export the variables and methods for javascript to access them.
So, what am i missing? Is this behaviour as unreliable as it looks like, or am i doing something wrong?
PS: i have a plan B to achieve this which is proved to work, but first i want to make sure that it isnt possible to do it this way since this should be the preferred method.
First, the latest version of the doc is at http://code.google.com/webtoolkit/doc/latest/DevGuideOrganizingProjects.html#DevGuideBootstrap
And it says (even the GWT 1.5 version you were looking at) that "onModuleLoad() can be called at any point after the outer document has been parsed", which includes before and after window.onload.
As the doc says, GWT loads your code in an iframe (used here as a sandbox), which is asynchronous; so your code loads when both the iframe and the "body" are loaded. Depending on the time needed to load the iframe, that can be before or after window.onload (in the example, they assume it loads right away, which could be the case when the *.cache.* file is effectively in the browser's cache).
But the rule of thumb is that GWT tries hard (at least the built-in linkers) to make things start asynchronously so that it doesn't break loading of other external resources (stylesheets and images, for instance). That implies that it cannot be guaranteed to run before the window.onload (they could have guaranteed to run after window.onload, but why wait?)