Javascript placement in GWT HTML - java

What is the difference of placing a Javascript (.js) library on before the GWT application nocache.js and after nocache.js in a GWT application which uses the JS library in JSNI methods.
Does it affect wether a JSNI method will be functional or not?

That really depends on when the JSNI method is loaded.
To be safe - always check to see if the JS lib you are using has been loaded. eg
public native static boolean isJqueryMethodLoaded(String method) /*-{
if ($wnd.jQuery && $wnd.jQuery[method]) {
return true;
} else {
return false;
}
}-*/;
(edited - thanks to the other answers for clarifying the load sequence)

Normal <script> tag are blocking, but the GWT script tag is not, since it is fetched asynchronously (i.e., non-blocking). The onModuleLoad() is called only when the body has been parsed (i.e., scripts have been fetched). Hence:
put it as the very first script in your list: you will save time;
<script> tags will always be loaded when onModuleLoad() is called.
Have a look at here.

onModuleLoad is always called at or after DOMContentLoaded, and this will always happen after your scripts have loaded (because they could do document.write()), unless you loaded them with async or defer.
So, unless you load your "other JS" with async or defer, it really shouldn't matter in which order you load them, as onModuleLoad should always be called after both are loaded.

Related

Hard Refresh in GWT

Using Google Web Toolkit, I'd like to code the equivalent of a hard refresh (control + F5).
I don't believe (or know) if GWT's Window.Location will work.
import com.google.gwt.user.client.Window.Location;
Window.Location = currentPage; // I don't think it'll be hard refresh
For reloading the current page you need to call Window.Location.reload() method.
Reloads the current browser window. All GWT state will be lost.
Or you can even specify your own JSNI (below how todo), because by default force reload is false :
public static native void forceReload() /*-{
$wnd.location.reload(true);
}-*/;
According to https://developer.mozilla.org/en-US/docs/DOM/window.location#Methods you would need to call window.location.reload(true) to force the reload of the current page.
Unfortunately GWT wraps only the window.location.reload() via Window.Location.reload(), and it is up to the browser to retrieve the page from the cache or from another get. This is done to achieve the most cross-browser solution.
Never tried but you should be able to use the following.
public static native void reload(boolean force) /*-{
$wnd.location.reload(force);
}-*/;
For reload gwt page, you have two options:
1) Window.Location.reload();
Reloads the current browser window. All GWT state will be lost.
2) Window.Location.replace("newurl");
Replaces the current URL with a new one. All GWT state will be lost. In the browser's history, the current URL will be replaced by the new URL.

how to access javascript variables from applet

I have implemented small applet on the jsp page in web app which works although I need to set PARAM tag of applet with javascript vars defined on the jsp page. Is it possible? I can see its possible the other way around: to read in javascript variables from applet. I cant find solution for reverse action.
Have the JavaScript write the applet element. Or in this day and age, use deployJava.js to write the applet element, and assign the JS variable to one of the parts of the parameters.
If userFontSize is the custom variable, then E.G.
var parameters = {
fontSize:16,
jnlp_href:'java2d.jnlp'
}
..might become..
var parameters = {
fontSize:userFontSize,
jnlp_href:'java2d.jnlp'
}

Handling self-refreshing pages from selenium

I have been running into intermittent errors with some java selenium-rc tests which I think are related to a page which has an ajax poll and automatically refreshes when some condition is reached on the server. In this scenario, I have no way of asking selenium to wait for the page to load, and so I run into a bunch of random "Couldn't access document.body" errors.
So, is there some way I can cause selenium to gracefully handle this situation? If not, is there some way I could detect whether the user is selenium from the page's javascript, and disable the automatic refresh?
If it helps at all, the javascript code in the page looks something like...
var ajax = new Ajax(url, {
update: state,
method: 'get',
onComplete: function(message) {
if (some_condition) {
window.location.replace(unescape(window.location));
}
}
});
One solution might be to always use a waitForCondition using isElementPresent before attempting to interact with the application under test. You could put the following method in a superclass to keep your tests more readable. Alternatively you could create helper methods for common Selenium commands that perform this wait.
/** Waits for an element to be present */
public static void waitForElementToBePresent(String locator) {
session().waitForCondition("var value = selenium.isElementPresent('" + locator.replace("'", "\\'") + "'); value == true", "60000");
}
You may also want to wait for the element to be visible, as waiting for it to just be present isn't always enough (imagine a textbox that is always present but hidden until a certain condition). You can combine this with the above method:
/** Waits for an element to be visible */
public static void waitForElementToBeVisible(String locator) {
waitForElementToBePresent(locator);
session().waitForCondition("var value = selenium.isVisible('" + locator.replace("'", "\\'") + "'); value == true", TIMEOUT);
}
Incidentally, the WebDriver (Selenium 2) team are working on having implicit waits, specifically to address AJAX issues where elements are not present immediately.
My solution was to disable the refresh in javascript by wrapping it in something like the following...
var isSeleniumActive = parent.seleniumAlert;
if (isSeleniumActive) {
alert("Selenium");
} else {
alert("Not selenium");
}
I'm not sure if the seleniumAlert function here is likely to sick around forever, so be aware if you're taking this that you may be relying on internal selenium implementation details of selenium.
There i was facing the same problem and i use a single line of code and it helps.
i was getting the error about the page is getting auto refresh
plus this warning:
-1490472087141 Marionette WARN Using deprecated data structure for setting timeouts
all i use is
Thread.sleep(2000)
and it worked for me.
I think that you can pause, or use a click and wait. There are a few good articles on the google. Good luck.
Edit for your comment:
How about the waitFor command?

GWT inter project communication

We have a large GWT project and many smaller GWT sub-projects
basically the large controller project invokes the smaller projects
via many means such as some are incorporated into iframes that are shown in page,
some are shown by clicking a URL and opening the project into a new window.
The requirement is to change the Css on the fly, this is possible in the main project,
by simply changing, on the fly, the href of the link tag containing stylesheet url
is it possible to propogate this change to the sub-projects too ?
or asking in more broader terms,
how do i achieve inter - project communication in GWT ?
A browse allows you to call Javascript code across IFrames if the domains of the different GWT applications are the same.
Using JSNI you can register methods on the window object which call back into the GWT application and using JSNI the other project can invoke this method.
If all the apps are served from the same domain you could store the name of the stylesheet in a cookie. Each app would then use the cookie to select the appropriate stylesheet.
String theme = Cookies.getCookie("THEME");
if (theme == null) {
theme = "default";
}
Element e = DOM.createElement("link");
DOM.setElementProperty(e, "rel", "stylesheet");
DOM.setElementProperty(e, "href", GWT.getModuleBaseURL() + currentTheme +
".css");
DOM.appendChild(getHead(), e);
private native Element getHead() /*-{
return $doc.getElementsByTagName('head')[0];
}-*/;

jQuery and Java applets

I'm working on a project where we're using a Java applet for part of the UI (a map, specifically), but building the rest of the UI around the applet in HTML/JavaScript, communicating with the applet through LiveConnect/NPAPI. A little bizarre, I know, but let's presume that setup is not under discussion. I started out planning on using jQuery as my JavaScript framework, but I've run into two issues.
Issue the first:
Selecting the applet doesn't provide access to the applet's methods.
Java:
public class MyApplet extends JApplet {
// ...
public String foo() { return "foo!"; }
}
JavaScript:
var applet = $("#applet-id");
alert(applet.foo());
Running the above JavaScript results in
$("#applet-id").foo is not a function
This is in contrast to Prototype, where the analogous code does work:
var applet = $("applet-id");
alert(applet.foo());
So...where'd the applet methods go?
Issue the second:
There's a known problem with jQuery and applets in Firefox 2: http://www.pengoworks.com/workshop/jquery/bug_applet/jquery_applet_bug.htm
It's a long shot, but does anybody know of a workaround? I suspect this problem isn't fixable, which will mean switching to Prototype.
Thanks for the help!
For the first issue, how about trying
alert( $("#applet-id")[0].foo() );
For the second issue here is a thread with a possible workaround.
Quoting the workaround
// Prevent memory leaks in IE
// And prevent errors on refresh with events like mouseover in other browsers
// Window isn't included so as not to unbind existing unload events
jQuery(window).bind("unload",
function() {
jQuery("*").add(document).unbind();
});
change that code to:
// Window isn't included so as not to unbind existing unload events
jQuery(window).bind("unload",
function() {
jQuery("*:not('applet, object')").add(document).unbind();
});

Categories