GWT auto generate the JavaScript code.
I could not understand the generated code event mechanism.
for instance, which function run when I click on a button?
I would love to see the javascript that GWT generates for button with explanations
For event handling, GWT attaches a EventListener (generally, your widget) as an expando property (called __listener) of the elements. The events are then all handled by a single dispatch method that looks at the __listener expando of the event's target and dispatches the event to it. Of course, the dispatch method does a bit more (event previewing, entry/finally scheduled commands, etc.)
This dance is (or at least was) required to avoid memory leaks in browsers (mainly IE). You can find more details in the GWT wiki: https://code.google.com/p/google-web-toolkit/wiki/DomEventsAndMemoryLeaks
When you develop in GWT, you don't care about JavaScript.
You should look at the Java code, and search for a function that handles the click event for your button.
When you compile the code Compiler will generate the autoamted Javascript functions ...And that too in compressed (thats depends on your compile type).
It is very hard to find the corresponding function and widget id because those are generated by compiler ..So its better to debug your gwt code is hosted mode ..
Even you want to read the generated code while compiling give the compilation type to
DETAILED, which improves on PRETTY with even more detail (such as very verbose variable names)
Still more details available here .
You should use GWT Compiler options STYLE whenever you need to understand the GWT's output js. GWT by default compresses and obfuscates the javascript output as it uses OBF as default value for STYLE.
To prevent compression and obfuscation you can use PRETTY or DETAILED as the parameter to STYLE argument.
NOTE: You should always use OBF mode for production as it ensures smallest bandwidth usage along with obfuscation.
Reference - https://developers.google.com/web-toolkit/doc/latest/DevGuideCompilingAndDebugging#DevGuideCompilerOptions
Related
I am using WebIde of SAPUI5 development.
If I write a console.log or alert it shows error of unexpected Alert and so on inside of the editor.
While the code works and I prefer to not see these errors inside of the editor.
How can I customize WebIde to not show these kind of errors.
While it is discouraged to use console.log and alert statements in your code because
[...] such messages are considered to be for debugging purposes and therefore not suitable to ship to the client [...]
http://eslint.org/docs/rules/no-console
and
[...] JavaScripts’ alert, confirm, and prompt functions are widely considered to be obtrusive as UI elements and should be replaced by a more appropriate custom UI implementation [...]
http://eslint.org/docs/rules/no-alert
you can have your Linter configured to bypass these checks (although I would not recommend to do so)
But keep in mind these checks are not specific to SAPUI5 or Web IDE, rather for every Javascript project!
Anyway, since Web IDE uses ESLint, to disable the check, add the following on top of the affected Javascript file:
/*eslint-disable no-console, no-alert */
Beginner / Intermediate developer here and trying to get a grasp on tracking down event listeners, but finding myself confused and frustrated because it always point to the library that handles the event, not the user's script. Example from the Event Listeners accordion on a select element that has the "keyup" event bound:
keyup
div.select
handler: function (e){return typeof b===i||e&&b.event.triggered===e.typet:b.event.dispatch.apply(f.elem,arguments)}
isAttribute: false
lineNumber: 3
listenerBody: "function (e){return typeof b===i||e&&b.event.triggered===e.type?t:b.event.dispatch.apply(f.elem,arguments)}"
node: div.select
sourceName: "https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"
type: "keyup"
useCapture: false
Obviously they are using jQuery, and they're doing a damn good job of it by using jQuery's $.extend method, but I still don't understand why the events accordion (in dev tools) would point to the library rather than the customized script?
Is there something really basic I missed in class? What methods are there for tracking these types of things down aside from CTRL+F in the Resources tab, which, btw did not yield any search results for "select" in the file that ACTUALLY extends/adds this listener - very odd is it not?
Update: So I feel pretty dumb about this, but the answer was right in front of my eyes - or so I think. At the top of their custom script they begin with,
define(["jquery"], function($) {
Could this be the beginning of the answer? Really what I'd like to understand is why the event would still trace back to the library when the event listener is bound within the above code,
$el.textHolder.click(function(e){
... do stuff ...
}
As far as I understand, this is because when jQuery binds an event, it doesn't bind it directly to your code, but instead to jQuery code that then dispatches the event to your code.
The Chrome devtools don't know (at this point, it seems to be in development) how jQuery binds the event, so only shows the first handler (jQuery).
The define call is part of the CommonJS Modules Standard I believe. See also RequireJS
In GWT web/production mode, Java code is complied into Javascript code that is rendered in the browser.
Also,I have always thought that in GWT development mode, GWT developer plugin compiles my Java code into JavaScript to render it in the browser. But after reading on some site, I came to know that there's no compiling of code to JavaScript to view it in the browser in development mode.
So, I wonder: What are all these widgets I see in the browser during this mode if they aren't JavaScript code?. I don't understand it.
Please help understanding this.
The crux of the Dev Mode is that your code runs in Java. This is a prerequisite if you can use a standard Java debugger. You'll find a high-level overview in the GWT documentation.
The magic happens with JSNI methods and overlay types: when a class is loaded, all its JSNI methods are extracted and their JS body is sent to the browser, ready to be executed (as JavaScript then), and the class is rewritten on the fly to reimplement the JSNI method to make a call to the browser (via the Dev Plugin you installed there and is triggered by ?gwt.codesvr= in the URL) to execute the corresponding JS function. This is the reason why Java objects are seen as opaque handles in JSNI methods; they're assigned a numeric ID to pair the Java object with a dummy JS object on the server-side. A similar though more complex rewriting is done for overlay types, and the same ID mapping is used when JS objects are passed to Java code (as overlay types).
BTW, Super Dev Mode compiles to JavaScript (almost) on the fly.
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?)
A bit confounded here, coming up dry on Google, and yet afraid some simple answer is right under my nose: What is/are the best way/ways to get a GWT control to render an OpenX invocation tag? I've tried placing either OpenX's "JavaScript" or "iFrame" invocation types (for a zone) within GWT InnerHTML or HTML tags using UiBinder, and it's a no go. Do I need to get some eval()-ish execution of this OpenX invocation code happening? Just stuck, and any suggestions/brief example would be appreciated. (Note: Use of UiBinder layout not a requirement... Happy to switch back to programmatic syntax.). Thank you so much.
What worked for me was to use an InlineHTML control in UiBinder, and declare it as a named ui:field. In code, referencing that ui:field, I first set a string to the "IFrame"-style invocation tag for the ad, as provided by OpenX, and after adding some random numbers to it (to head off browser-cacheing), I then apply the .setHTML(openx_iframe_invocation_tag_string) method to the reference, and the ad shows up in the space designated for the InnerHTML control.
As regards executing a JavaScript-style tag, some may want to try (I myself didn't go to far with it), execution of it within GWT via something like this script eval technique shown on http://snippets.dzone.com/posts/show/7052.