InlineFrameがILinkListenerを実装している件
はじめに
org.apache.wicket.markup.html.link.InlineFrameがorg.apache.wicket.markup.html.link.ILinkListenerを実装していることに気づきました。InlineFrameクラスはIFRAMEに対応するクラスです。
で、ILinkListenerはonLinkClicked()というクリックに応答するメソッドを持っています。
不思議に思いませんか。「なぜIFRAMEにクリックに応答するメソッドが必要なのか」と。
私は思いました。これはそんなメモ。
オチを言いますと
IFRAMEを含むページを表示した際に、「クリックされたとみなして、ページを読み込む」という仕組みになっていることが解析の結果わかりました。
生成されたHTMLを見てみます。下記はIFRAMEを含むページのレンダリング例です。
<html> <head> <title>Wicket Quickstart Archetype Homepage</title> </head> <body> <iframe src=";jsessionid=79F45E054A51CA810886D135F7690789?wicket:interface=:0:iframe::ILinkListener::" wicket:id="iframe"></iframe> </body> </html>
src属性内の正確な書式は知らないのですが、「iframeコンポーネントのILinkListenerに要求を投げる」と言うことをこのsrc属性は指示しています。
Wicketは、org.apache.wicket.request.AbstractRequestCycleProcessorクラスのresolveRenderedPageメソッドでこのURLをJavaの世界にマッピングします。
今回はrequestParameters.getInterfaceName()(呼び出しタイミングは下記ソースを参照)を実行した際に、「ILinkListener」という文字列が取得できます。
その結果生成されるIRequestTargetインターフェースのインスタンスが、イベント(今回はonLinkClicked)の処理の仕方を知っているインスタンスとなります。
このインスタンスを後工程で使用し、イベントに応答する仕組みになっています。
resolveRenderedPageメソッドが、どのようなメソッドなのか引用します。
protected IRequestTarget resolveRenderedPage(final RequestCycle requestCycle, final RequestParameters requestParameters) { final String componentPath = requestParameters.getComponentPath(); final Session session = requestCycle.getSession(); final Page page = session.getPage(requestParameters.getPageMapName(), componentPath, requestParameters.getVersionNumber()); // Does page exist? if (page != null) { // Set page on request requestCycle.getRequest().setPage(page); // see whether this resolves to a component call or just the page final String interfaceName = requestParameters.getInterfaceName(); if (interfaceName != null) { return resolveListenerInterfaceTarget(requestCycle, page, componentPath, interfaceName, requestParameters); } else { return new PageRequestTarget(page); } } // just return null here and let it be handled further down the road. return null; }