JavaScript fuer Eclipse-Entwickler
darauf zugegriffen werden kann. Dazu kommt im Fall des CKEditor, dass dieser selbst auch asynchron geladen wird. Er steht also selbst nach dem Abarbeiten des "load" -Events (siehe HTML-Auszug) noch nicht zur Verfügung. Um das zu umgehen, kann man einen Script-Puffer einbauen, der JavaScript-Code grundsätzlich zwischenspeichert, bis er tatsächlich ausgeführt werden kann. Das kann auch nach der ersten Initialisierung vorkommen, wenn in JavaScript asynchron agierende Funktionen wie editor.instance.setData aufgerufen werden. Eine Hilfsmethode erleichtert die Verwendung des Puffers (Listing 3.4).
private boolean clientReady = false;
private StringBuilder scriptBuffer = null;
private void evalOnReady( String script ) {
if( clientReady ) {
browser.evaluate( script );
} else {
if( scriptBuffer == null ) {
scriptBuffer = new StringBuilder();
}
scriptBuffer.append( script );
}
}
Listing 3.4
Um das gespeicherte Skript auszuführen, erstellen wir im Konstruktor eine Browserfunktion, die vom Initialisierungsskript zum geeigneten Zeitpunkt (hier in dem "dataReady" -Event der CKEditor -Instanz) aufgerufen wird (Listing 3.5). Nun müssen wir noch setText und getText (und alle künftigen Setter und Getter) so anpassen, dass sie evalOnReady anstatt eval verwenden. Listing 3.6 zeigt die endgültige Implementierung. Damit verhält sich das Custom Widget für den Anwendungsentwickler immer wie erwartet. Es sei darauf hingewiesen, dass das Zurücksetzen des clientReady- Feldes in setText in diesem Beispiel nur notwendig ist, da editor.instance.setData selbst asynchron arbeitet und die Browserfunktion später implizit erneut aufruft. Bei sonstigen, synchron agierenden Funktionen kann das Feld auf true belassen werden.
new BrowserFunction( browser, "rap_ready" ) {
public Object function( Object[] arguments ) {
if( scriptBuffer != null ) {
browser.evaluate( scriptBuffer.toString() );
scriptBuffer = null;
}
clientReady = true;
return null;
}
};
Listing 3.5
private String text = "";
public void setText( String text ) {
checkWidget();
if( text == null ) {
SWT.error( SWT.ERROR_NULL_ARGUMENT );
}
this.text = text;
evalOnReady("editor.instance.setData( \"" + escapeText
( text ) + "\" );" );
clientReady = false; // order is important
}
public String getText() {
checkWidget();
if( clientReady ) {
text = ( String )browser.evaluate
( "return editor.instance.getData();" );
}
return text;
}
Listing 3.6
Traffic gering halten
Im Gegensatz zu gewöhnlichen RAP Widgets muss bei browserbasierten Custom Widgets für jede Interaktion zwischen Java- und JavaScript-Umgebung ein HTTP Request ausgeführt werden. Um die Performance nicht unnötig zu beeinträchtigen, sollten viele kurz aufeinanderfolgende Aufrufe der evaluate- Methode möglichst vermieden werden. Leider gibt es dafür keine allgemeingültige Lösung, die nicht das API des Custom Widgets beeinträchtigen würde. Es kann versucht werden, in möglichst vielen Situationen evaluate- Aufrufe durch einen Script-Puffer zusammenzufassen. Als Rückgabewerte können auch Arrays verwendet werden. Das Gleiche gilt für Browserfunktionen auf der JavaScript-Seite. Hier kann es helfen, diese indirekt und über einen Timer ( window.setTimeout ) aufzurufen. So lange der Timer läuft, werden weitere Aufrufe ignoriert oder starten den Timer neu. Um mehrere Informationen auf einen Schlag zum Server zu übertragen (anstatt einzelne Aufrufe für jede Informationseinheit), können Browserfunktionen mit beliebig vielen Argumenten aufgerufen werden.
Der hier vorgestellte Ansatz eignet sich nicht für alle denkbaren Custom Widgets. Ab einen gewissen Grad an Flexibilität oder Komplexität ist ein RAP-natives Custom Widget die deutlich bessere Alternative. Das Browser-Widget eignet sich vor allem für Szenarien, in denen die JavaScript-Komponente weitgehend autark agieren kann (Kasten: „Traffic gering halten“). Da viele JavaScript-Projekte für den Einsatz in traditionellen Webseiten konzipiert sind, ist das sehr oft der Fall. Weitere Beispiele wie ein Google-Maps- [5] oder ein jQuery-UI-basiertes Widget [6] zeigen, dass der Fantasie keine Grenzen gesetzt sind.
Links & Literatur
https://github.com/eclipsesource/rap-ckeditor/tree/simple
http://bit.ly/nWl1yN
http://docs.cksource.com/CKEditor_3.x/Developers_Guide/CKPackager
http://developer.yahoo.com/yui/compressor/
https://github.com/tbuschto/rap-gmap
https://github.com/eclipsesource/org.eclipse.rap.widget.carousel
4 The Web 2.0 Toolkit – Ein
Weitere Kostenlose Bücher