真的就是亂寫用的筆記

WebKit plug-ins

蘋果定義給 Safari 用的 Webkit Plug-in API 基本上就是一個 NSView,也就是,你自己弄一個 NSView 的 sub-class,然後丟進一個 Bundle 裡頭,然後告訴 Safari 在什麼狀況下應該要使用你的 Plugin,在用到的時候,Safari 就會在 WebView 上面透過 addSubview: 把你的 plug-in 裡頭的 view 弄上去。

因為是透過 addSubview: 加上去的,而 WebView 原本的內容呢,都是直接透過繪圖指令,繪製在 WebView 的 context 裡頭,所以,你的 plug-in 的畫面一定會疊在 WebView 所有的 web 內容的上面,而且不可能用什麼 css 把 HTML 裡頭的東西疊在 plug-in 上,因為 HTML 內容與 plug-in 裡頭的東西根本就不在同一個 view、同一個 context 裡。

最近心得

整個 Cocoa 裡頭哪一個 UI 元件最複雜?個人意見是-絕對是 WebView 啊…。

而如果你要用 WebView 做 UI,想要改一下裡頭的東西,大概都需要對 DOM 做一些操作。有兩種管道可以操作 DOM:一種是從你的 controller,透過 ObjC-Javascript bridge,叫你的 WebView 執行某一段 Javascript,另外一種方法,則是直接透過 DOM 的 ObjC interface,操作 WebView 裡頭的 DOM 物件-你用 [WebFrame DOMDocument],就可以拿到你指定的 frame 裡頭的 DOM document。

不過,操作 WebKit 的 DOM 物件,基本上物件的生成,不是照一般的 ObjC 的習慣,而是要用寫 Javascript 的想法來做事。例如,你想要生出一個新的 DOMElement,你這樣寫-

DOMElement *element = [[DOMElement alloc] init];

這樣會爆炸。而是需要像 Javascript 的 Document.createElement() 對應的方式產生-

DOMElement *element = [[[webView mainFrame] DOMDocument] createDocument];

然後呢,當你以為你在寫一個用 WebKit 的程式,所以應該去找 WebKit 的文件,但是 Webkit 關於 DOM 操作的文件等於是,嗯,沒有,所以相關的操作,還是要去找怎樣用 Javascript 操作 DOM 的文件,然後用一般的理解,就能夠翻譯回 ObjC 到底應該怎麼寫;找文件的方向呢,W3C 的文件還是有點混亂,Mozilla 的文件倒是不錯。

最後再來一個很冷的梗-

It is not difficult to catch DOM, it is impossible.

Cocoa Samurai: [Commentary] TextMate and [Tutorial] Printing the contents of WebViews

完整列印 WebView 當中內容的方法。每次都記不得怎麼寫。

NSPrintInfo *printInfo = [NSPrintInfo sharedPrintInfo];
NSPrintOperation *printOperation;
NSView *webView = [[[myWebView mainFrame] frameView] documentView];
[printInfo setTopMargin:15.0]; [printInfo setLeftMargin:10.0]; [printInfo setHorizontallyCentered:NO];
[printInfo setVerticallyCentered:NO];
printOperation = [NSPrintOperation printOperationWithView:webView printInfo:printInfo];
[printOperation setShowPanels:YES];
[printOperation runOperation];

2 years ago