[iPhone SDK] UIWebViewでクリックしたノードを取得する
ご存じの通り,UIWebViewはほとんどの機能が隠蔽されている.
今回のハックは,UIWebViewでクリックしたときに反応する要素(エレメント)を取得する方法である.(これでtarget="_blank"問題に対応しようと思ったのだが,もっと簡単な方法がある.これは後日また別エントリで.)たとえば,Aタグのhref,target,alignment,id,classなどを取得できる.
UIWebViewに対して,UIWebView?(不明)から以下のundocumentedなデリゲートメッセージがUIWebViewのリンクがクリックされたときに飛んでくる.
- (void)webView:(UIWebView *)sender willClickElement:(id)element;
この第2引数は,undocumentedのUIThreadSafeNodeというクラスになっている.
UIThreadSafeNodeは,DOMNodeというこれまたundocumentedのクラスをカプセル化したものである.どうやら,UIThreadSafeNodeのデリゲート先が,内部で持っているDOMNodeのなっているらしい.UIThreadSafeNodeは,スレッドセーフでクリックした対象のDOMの情報を取得できるようにするものと考える.(詳しい各クラスの説明?データ?はErica女史のヘッダファイルを参考にされたい)
DOMNodeから,DOMNamedNodeMapを取得する.
DOMNode - (id)attributes; - (BOOL)hasAttributes;
さらに,DOMNamedNodeMapの要素としてDOMAttrがある.これは,以下のAPIを使って取得できる.当然,これらもundocumentedである.
DOMNamedNodeMap - (id)item:(int)fp4;
これをまとめると,以下のようにクリックした対象をhookできる.
- (void)webView:(UIWebView *)sender willClickElement:(id)element { NSString* nodeName = [element nodeName]; NSString* hrefURL = [element hrefURL]; NSString* textContent = [element textContent]; id attributes = [element attributes]; int length = [attributes length]; int i; for( i = 0; i < length; i++ ) { id item = [attributes item:i]; NSString* name = [item name]; NSString* value = [item value]; NSLog( @"%@=\"%@\"", name, value ); } }
審査通るのかな?コレ.