2010-12-14 10 views
5

Simplemente quiero cargar una aplicación GWT agregando una etiqueta de script al DOM, sin embargo, debido a que el enlazador GWT usa document.write() no puedo encontrar ninguna buena manera de hacerlo asi que. He encontrado algunos hacks para hacerlo en varias publicaciones de blog, pero todos parecen fallar con la última versión de GWT. ¿Alguna aproximación razonablemente no invasiva para hacer esto viene a la mente?GWT bookmarket o GWT como una biblioteca externa

Aclaración:

manera normal para poner en marcha una aplicación GWT, en su página HTML anfitrión:

<script type="text/javascript" language="javascript" src="myapp.nocache.js"></script> 

Esto, por supuesto, se pone en marcha tan pronto como se carga la página. Quiero hacerlo en un momento posterior:

function startapp() { 
    var head = document.getElementsByTagName('head'); 
    var s = document.createElement('script'); 
    s.setAttribute('type', 'text/javascript'); 
    s.setAttribute('src', 'myapp.nocache.js'); 
    head[0].appendChild(s); 
} 
+0

Estoy muy lo siento, pero podría por favor reformular. Un ejemplo ayudaría. – Amey

+0

@Amey finaliza la actualización anterior. ¡Gracias! –

+0

Su fragmento de código debería funcionar siempre que lo esté ejecutando en su sitio. 'nocache.js' carga un archivo' cache.html' según sea necesario basándose en el enlace diferido, y probablemente no use una URL absoluta. –

Respuesta

5

Esto es lo que parece funcionar hasta el momento:

añadir esto a la parte superior de su App.gwt.xml:

<!-- Cross site linker --> 
<inherits name="com.google.gwt.core.Core" /> 
<add-linker name="xs" /> 

Después de compilar su aplicación con la configuración anterior, modificar (o copiar) los app.nocache.js generó como sigue:

1) Comentarios $doc.write... la última declaración

2) Copia de esta porción de la $doc.write sta tement que acabas de comentar y evaluarlo. Ejemplo:

eval('window.__gwtStatsEvent && window.__gwtStatsEvent({' + 'moduleName:"app", sessionId:window.__gwtStatsSessionId, subSystem:"startup",' + 'evtGroup: "loadExternalRefs", millis:(new Date()).getTime(),' + 'type: "end"});' + 'window.__gwtStatsEvent && window.__gwtStatsEvent({' + 'moduleName:"app", sessionId:window.__gwtStatsSessionId, subSystem:"startup",' + 'evtGroup: "moduleStartup", millis:(new Date()).getTime(),' + 'type: "moduleRequested"});'); 

3) Agregue esta línea inmediatamente después.

document.body.appendChild(document.createElement('script')).src=base + strongName + ".cache.js"; 

Así que básicamente está reemplazando el $doc.write con esas dos líneas.

Ahora, su bookmarklet se verá algo como:

<a href="javascript:(function(){document.body.appendChild(document.createElement('script')).src='http://abc.com/app.nocache.js';})();">My App</a> 
+0

Actualización: parece que en realidad puedes evitar todo esto ahora simplemente usando el enlazador xsiframe. –

+0

Excelente pregunta y discusión Abdullah! Intento hacer exactamente lo mismo que usted, agregue un JS generado por GWT de un bookmarklet. ¿Puede darme algún consejo sobre el enlazador xsiframe que menciona ... mientras salgo y pruebo su solución documentada anteriormente? ¡Gracias! –

+0

Aquí está el código para el enlazador xsiframe: http://code.google.com/p/google-web-toolkit/source/browse/trunk/dev/core/src/com/google/gwt/core/linker/CrossSiteIframeLinker .java? r = 9161 –

0

Cada vez que un navegador carga un archivo JavaScript, su también ejecutar cada línea de la misma finde para construir las tablas de símbolos etc.

En su caso, la aplicación cargas en el navegador y después de que se cargue dom, se carga su módulo GWT js. En este punto, el navegador intentará ejecutar cada línea del javascript del módulo GWT, posiblemente causando que su DOM cargado previamente vaya a lanzar.

¿Cuál es exactamente tu caso de uso? Si su requerimiento es condicionalmente cargando al módulo de GWT entonces su podría intentar algo como esto: incluir esto en la cabeza:

<script src="gwtmoduleloader.js"></script> 

Aquí, gwtmoduleloader.js es de hecho un servlet que llevará a cabo la lógica de averiguar si el módulo de GWT es para ser cargado

Si el módulo de GWT se va a cargar, el sevlet puede imprimir una

document.write('<script src="myapp.nocache.js"></script>') 

o bien regresar en silencio.

Cuando el navegador evalúa el contenido de gwtmoduleloader.js, puede encontrar un document.write para otro script (en su caso, el módulo gwt), que cargará y evaluará. Esta es una carga condicional y se puede lograr antes de que el cuerpo comience a cargar.

¿Esto es lo que estabas buscando?

+0

No sé cuánto más puedo aclarar mi pregunta, ¿entiendes lo que es un bookmarklet? Inyecta javascript en su página waaaaaaaaay después de que la página ya se haya cargado. Ejemplo: en esta página de stackoverflow estoy leyendo y mirando alrededor, y ahora decido que quiero ejecutar mi bookmarklet. Necesito inyectar javascript en la página. El cargador de GWT no funcionará porque el evento de carga ha desaparecido hace eones, y document.write() ya no funcionará. –

1

Supongo que ya está utilizando el enlazador de dominios cruzados y esto no resuelve su problema con document.write. Si no es así, podría ser digno de una mirada (lo siento, no hay suficiente experiencia con que diga.)

Un enfoque que estoy bastante seguro de que podría ser hecho para trabajar es la siguiente:

su bookmarklet añade una etiqueta de script a la página (como ahora)

Este script no es salida del compilador GWT. Es un javascript simple que agrega un IFrame a la página, y el src de ese IFrame apunta a una página HTML en su servidor que carga su módulo GWT.

Presumiblemente, el objetivo es que su módulo GWT saque cosas de la página en la que se cargó. Por supuesto, no puede hacer esto directamente en este caso porque el IFrame proviene de un dominio diferente al de la página principal.

Para hacer esto, debería usar la ventana.postMessage y window.addEventListener para comunicarse entre su módulo GWT en el IFrame y su apéndice javascript en el padre (usando JSNI en el lado GWT)

Si tiene que admitir navegadores más antiguos, postMessage no funcionará, pero usted podría ser capaz de salirse con la manipulación de hash, pero es probable que este sea el punto donde trazaré una línea sobre la practicidad.

+0

Buenos comentarios gracias. De hecho, he encontrado una solución que parece funcionar (estaba usando el enlazador xs). Básicamente reemplacé un par de líneas en el .nocache.js generado para insertar dinámicamente una etiqueta de script en lugar de hacer lo de doc.write. Voy a probarlo un poco más antes de estar seguro de que esto funciona ... –

+0

Genial. Parece que la solución "correcta" para este problema sería escribir un enlazador GWT que haga las cosas correctas, pero parece que esa capacidad aún existe en el futuro. –