javascriptgwtecho2

How to integrate a GWT app into another Web-Framework?


I need the ability to load and start a GWT App at any time in an Echo2 environment. My first approach was to load and execute the nocache.js in a Client-Server sync using

var script = document.createElement("script");
script.setAttribute("src",javascriptURI);
script.setAttribute("type","text/javascript");
document.getElementsByTagName('body')[0].appendChild(script);

This call basically works, but when the script is executed it operates on an EMPTY document instead of the current document of the Echo2 application. Has the script to be somehow initialized first or is there any event required?

The GWT application/script works fine if it's included in the start-up HTML of the application, so I assume the GWT App to be correct. The original standalone HTML of the GWT App has the HTML script tag in the body as well.


Solution

  • The problem is, that the dowcument.write calls in the nocache.js file only works if the documents has not finished loading. Otherwise document.write will overwrite the whole document.

    Therefor the document.write calls have to be replaced by the createElement methods of DOM:

    For the first code that adds the script with the marker id:

    var script = document.createElement("script");
    script.setAttribute("id", markerId);
    $doc_0.getElementsByTagName("body")[0].appendChild(script);
    

    For the second part (nearly at the end of nocache.js). Replace the "app" with your application name:

    try {
        var script = document.createElement("script");
        script.setAttribute("defer", "defer");
        script.innerHTML = "app.onInjectionDone('app')";
        $doc_0.getElementsByTagName("body")[0].appendChild(script);
    } catch (e) {
        // Fallback if we want to use the original html page without embedding in IE
        $doc_0.write('<script defer="defer">app.onInjectionDone(\'app\')<\/script>');
    }
    

    So, that was the part that has to be patched in the gwt generated code. Now the html page that loads and starts the application when the user clicks the button:

    <html> 
      <head> 
        <!-- base url --> 
        <base href="http://localhost:8080/app/" /> 
        <meta http-equiv="content-type" content="text/html; charset=UTF-8"> 
        <link type="text/css" rel="stylesheet" href="static-gwt.css"> 
        <title>APP</title> 
        <script type="text/javascript"> 
    
        function startApp() {
            if (document.createElement && document.getElementsByTagName) {
              var script = document.createElement('script');
              script.type = 'text/javascript';
              script.src = 'app/app.nocache.js';
              var heads =document.getElementsByTagName('body');
              if (heads && heads[0]) {
                heads[0].appendChild(script);
                triggerAppStart();
              }
            }
        }
    
        function triggerAppStart(){
            try{
            app.onInjectionDone('app');
            if ( !document.createEventObject ) {
                var evt = document.createEvent("HTMLEvents");
                evt.initEvent("DOMContentLoaded", true, true);
                document.dispatchEvent(evt);
               }
            } catch ( e ) {
            window.setTimeout('triggerAppStart()', 100 );
           } 
        }
    
    </script> 
      </head> 
      <body> 
        <input type="button" onclick="startApp();return false;"> 
      </body> 
     </html> 
    

    I know that this is not the best solution but it's the only way it worked until now.