新しく開いたウインドウ(またはタブ)のアドレスバーに、Wicketが生成した動的なURLを貼られた場合に検知したい

はじめに

 何かについて調べていたら、以下のissueを発見しました。

 「このissue、実装されているけど、どんな機能なんだろう」と思って使ってみたのでメモ。
 機能は、「新しく開いたウインドウ(またはタブ)のアドレスバーに、Wicketが生成した動的なURLを貼られた場合に検知出来る」というものでした。
 無いよりは、あった方がいい機能だと思います。

 最近のブラウザは、ウインドウ(及びタブ)でセッションを共有してしまいますから、こういう機能が生まれたのだと思います。

環境

使い方

以下のように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変数で判定していることが分かると思います。

さいごに

 仕組みの都合上、リンクを右クリックして「新しいウインドウ(タブ)で開く」で開いた場合は、検知できません。
 リンクをクリックした際に、ページのインスタンスが普通は新しく作られるので。

 その仕様を「あり」と考えるか、「無し」と考えるかで、この機能の評価が分かれるのかな、という気がします。