新しく開いたウインドウ(またはタブ)のアドレスバーに、Wicketが生成した動的なURLを貼られた場合に検知したい
はじめに
何かについて調べていたら、以下のissueを発見しました。
「このissue、実装されているけど、どんな機能なんだろう」と思って使ってみたのでメモ。
機能は、「新しく開いたウインドウ(またはタブ)のアドレスバーに、Wicketが生成した動的なURLを貼られた場合に検知出来る」というものでした。
無いよりは、あった方がいい機能だと思います。
最近のブラウザは、ウインドウ(及びタブ)でセッションを共有してしまいますから、こういう機能が生まれたのだと思います。
環境
- wicket 1.5.7以降
使い方
以下のようにorg.apache.wicket.ajax.AjaxNewWindowNotifyingBehaviorの派生クラスを作成します。
public class MyAjaxNewWindowNotifyingBehavior extends AjaxNewWindowNotifyingBehavior { /** serialVersionUID */ private static final long serialVersionUID = 1L; @Override protected void onNewWindow(AjaxRequestTarget target) { //新しく開いたウインドウ(またはタブ)のアドレスバーに、Wicketが生成した動的なURLを貼られた場合にする処理 System.out.println("new"); } }
「新しく開いたウインドウ(またはタブ)のアドレスバーに、Wicketが生成した動的なURLを貼られた」ことを検知したいページにorg.apache.wicket.ajax.AjaxNewWindowNotifyingBehaviorの派生クラスをaddします。
各ページにいちいちaddをするのはあまり現実的で無いと思うので、実際には、上位のPageクラスを用意し、そちらにaddするのでしょう。
public class SecondPage extends WebPage { private static final long serialVersionUID = 1L; public SecondPage() { super(); MyAjaxNewWindowNotifyingBehavior myAjaxNewWindowNotifyingBehavior = new MyAjaxNewWindowNotifyingBehavior(); add(myAjaxNewWindowNotifyingBehavior); } }
動きの仕掛け
動きの仕掛けは「ページのインスタンスが初めてレンダリングされたときに、JavaScriptでウインドウ名を設定する。以降、期待と異なるウインドウ名のウインドウに表示されたら、Ajaxで通知をする」というものです。
「『ページのインスタンスが初めてレンダリングされたとき』とか、そんな拡張ポイントあったっけ?」と思う人も居ると思うのですが、わりと強引な方法で実現しています。
以下にに、org.apache.wicket.ajax.AjaxNewWindowNotifyingBehaviorのソースを抜粋します。
public void renderHead(Component component, IHeaderResponse response) { super.renderHead(component, response); if (hasBeenRendered == false) { hasBeenRendered = true; response.renderOnDomReadyJavaScript(String.format("window.name='%s'", windowName)); } CharSequence callbackScript = JavaScriptUtils.escapeQuotes(getCallbackScript()); response.renderOnLoadJavaScript("setTimeout('" + callbackScript + "', 30);"); }
hasBeenRendered変数で判定していることが分かると思います。
さいごに
仕組みの都合上、リンクを右クリックして「新しいウインドウ(タブ)で開く」で開いた場合は、検知できません。
リンクをクリックした際に、ページのインスタンスが普通は新しく作られるので。
その仕様を「あり」と考えるか、「無し」と考えるかで、この機能の評価が分かれるのかな、という気がします。