GWT Popups erscheinen seit Chrome 61 an der falschen Stelle

Seit Chrome 61 kommt es mit dem derzeit aktuellen Release von GWT 2.8.1 zu Problemen mit der Positionierung von Popups. Dieses Problem äußert sich wie im folgenden Bild zu sehen ist, wenn die Webseite gescrollt ist. Dieses Problem betrifft u.a. auch die häufig eingesetzten GWT Widgets Suggestbox und DateBox.

Im Folgenden zeigen wir Lösungsansätze und stellen eine funktionierende Lösung mit Sourcecode vor.

Chrome hatte bislang die Scrollposition an document.body gesetzt, jetzt wird diese hingegen an document.documentElement gesetzt. Hiermit wird das Verhalten umgesetzt, welches IE (seit 8), Opera 11 und Firefox (seit 16) aufweisen. Da die Chrome Entwickler hierdurch ihrer Ansicht nach keinen Bug erzeugt haben, sondern einen langfristigen Bug korrigiert haben, ist nicht damit zu rechnen, dass dieses Problem seitens Chrome gelöst wird.

Derzeitige Optionen

  • Im Branch für das kommende GWT 2.8.2 ist dieser Bug bereits behoben. Leider gibt es jedoch noch kein fertiges Release und zudem kann es je nach Projektumfeld ein erhebliches Problem darstellen mal eben schnell GWT auf eine nicht offizielle Version zu ändern.
  • Alternativ kann der offizielle Patch auf die aktuell eingesetzte Version rückportiert werden. Leider bedeutet dies jedoch auch in diesem Fall, dass man nicht die offiziellen GWT Releases benutzten kann, sondern angepasste Artefakte bauen muss.
  • Austausch der DOMImpl durch Deferred-Binding-Regeln. Dies ermöglicht den Austausch der problematischen Implementierung durch den Compiler ohne Anpassung der GWT Artefakte.

Unsere Lösung im Detail

Wir haben uns den dritten Ansatz genauer angeschaut und für GWT 2.8.1 einen funktionierenden Workaround entwickelt. Hiermit lässt sich angenehm die Zeit überbrücken bis 2.8.2 releast wird und man darauf upgraden kann.

Die DOMImpl regelt in GWT, wie Aufrufe an die DOM API des Browsers ausgeführt werden. Für die verschiedenen Browser gibt es verschiedene Implementierungen (z.B. DOMImplIE8, DOMImplMozilla), diese werden per Deferred Binding vom Compiler ausgewählt.

Wir haben angepasste Varianten der DOMImpl Unterklassen erstellt, welche auf den Quellen von GWT 2.8.1 basieren und den Patch enthalten. Hierfür wurde eine Klasse DOMImplPatched erstellt, welche von DOMImpl erbt und die Änderungen der DOMImpl umsetzt. Alle anderen Klassen erben von dieser.

Mithilfe einer angepassten gwt.xml fügen wir nun neue Ersetzungsreglen für Compiler hinzu, welche unsere gepatchte Implementierung gegenüber der normalen bevorzugen. (Um eine Auswahl zu erzwingen, wurde ein DummyProperty hinzugefügt, damit die Ersetzungen konkreter sind als die normalen.)

Workaround benutzen

Die Klassen aus dem angehängen Zip (sieh unten) müssen in das Package “com.google.gwt.dom.client”  im eigenen Projekt abgelegt werden. Dies ist notwendig, damit die Sichtbarkeiten bzgl. der DOMImpl stimmen.

Die DOMPatch.gwt.xml muss auf selbige Weise in das Package “com.google.gwt.dom” kopiert werden.

Dannach muss lediglich in den eigenen *.gwt.xml Dateien nur noch folgende Zeile hinzugefügt werden:

<inherits name=”com.google.gwt.dom.DOMPatch” />

Hiermit wird der Workaround für das aktuelle Modul aktiviert.

Für ältere GWT Versionen muss dieses Vorgehen auf Basis der spezifischen Implementierung reproduziert werden.

Die benötigen Sourcecode Dateien für den Workaround finden Sie hier:

GWT-Chrome-61.zip

Short URL for this post: https://wp.me/p4nxik-2To
This entry was posted in Java Web Frameworks and tagged , , , . Bookmark the permalink.

Leave a Reply