GWT bookmarket или GWT как внешняя библиотека - PullRequest
5 голосов
/ 14 декабря 2010

Я просто хочу загрузить приложение GWT (Google Web Toolkit), добавив тег сценария в DOM, однако, поскольку компоновщик GWT использует document.write() Я не могу найти какой-либо хороший способ сделать это.Я нашел несколько хаков для этого на разных постах в блогах, но все они, похоже, не работают с последней версией GWT.Любой разумно неинвазивный подход для этого приходит на ум?

Разъяснение:

Нормальный способ запустить приложение GWT на html-странице вашего хоста:

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

Это, конечно, запускается, как только страница загружается.Я хочу сделать это позже:

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);
}

Ответы [ 3 ]

5 голосов
/ 22 декабря 2010

Вот что, похоже, работает до сих пор:

Добавьте это в начало вашего App.gwt.xml:

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

После компиляции приложения с вышеуказанными настройками измените (или скопируйте) сгенерированный файл app.nocache.js следующим образом:

1) Прокомментируйте последний $doc.write... оператор

2) Скопируйте эту часть из оператора $doc.write, который вы только что прокомментировали, иОцените это.Пример:

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) Добавьте эту строку сразу после.

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

Таким образом, вы в основном заменяете $doc.write этими двумя строками.

Теперь ваш букмарклет будет выглядеть примерно так:

<a href="javascript:(function(){document.body.appendChild(document.createElement('script')).src='http://abc.com/app.nocache.js';})();">My App</a>
1 голос
/ 17 декабря 2010

Я предполагаю, что вы уже используете междоменный компоновщик, и это не решает вашу проблему с document.write.Если нет, то, возможно, стоит взглянуть (извините, недостаточно опыта, чтобы сказать это.)

Один из подходов, который, я уверен, можно было бы применить, заключается в следующем:

Ваш букмарклетдобавляет тег страницы на страницу (как сейчас)

Этот сценарий не выводится компилятором GWT.Это обычный старый javascript, который добавляет IFrame на страницу, а src этого IFrame указывает на HTML-страницу вашего сервера, которая загружает ваш модуль GWT.

Предположительно, целью является ваш модуль GWT.чтобы убрать вещи со страницы, в которую они были загружены.Конечно, он не может сделать это напрямую в этом случае, потому что IFrame происходит из домена, отличного от родительской страницы.

Для того, чтобы сделать эту работу, вам придется использовать window.postMessage и window.addEventListenerдля обмена данными между вашим модулем GWT в IFrame и вашей заглушкой javascript в родительском (используя JSNI на стороне GWT.)

Если вам нужно поддерживать более старые браузеры, postMessage не будет работать - но вы можетеизбавиться от манипуляций с хешем - но, возможно, именно здесь я подведу черту о практичности.

0 голосов
/ 14 декабря 2010

Всякий раз, когда браузер загружает файл javascript, он также выполняет каждую строку в нем, чтобы создавать таблицы символов и т. Д.

В вашем случае приложение загружается в браузер, и после загрузки dom вашGWT модуль JS загружается.На этом этапе браузер попытается выполнить каждую строку JavaScript-кода модуля GWT, что может привести к тому, что ваш ранее загруженный DOM попытается выполнить бросок.

Каков именно ваш вариант использования?Если ваше требование условно загружает модуль GWT, то вы можете попробовать что-то вроде этого: Включите это в свою голову:

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

Здесь gwtmoduleloader.js - это действительный сервлет, который будет содержать логику, чтобы выяснить,Модуль gwt должен быть загружен.

Если модуль GWT должен быть загружен, то сервлет может распечатать

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

или иначе вернуть без вывода сообщений.

Когда браузер выполняет оценкусодержимое gwtmoduleloader.js может найти document.write для другого скрипта (в вашем случае это модуль gwt), который он загрузит и оценит.Таким образом, это условная нагрузка, и ее можно достичь до того, как тело начнет загружаться.

Это то, что вы искали?

...