Created
July 27, 2011 10:27
-
-
Save hetima/1109104 to your computer and use it in GitHub Desktop.
WebKit2 context menu hack
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
コンテクストメニューの representedObject からリンク要素を得るサンプル | |
WebKit2.framework をリンクする必要がある。 | |
うまくリンクできない場合は WebKit2.framework を /Developer/SDKs/xx.sdk/System/Library/PrivateFrameworks | |
にコピーすればよさげ | |
正直 WKRelease() は正しく使えているか自信がない | |
*/ | |
enum Type { //from WebKit2/Shared/APIObject.h | |
TypeNull = 0, | |
TypeArray = 1, | |
TypeData = 7, | |
TypeDictionary = 8, | |
TypeString = 15, | |
TypeURL = 16 | |
} | |
extern void* WKRetain(void* type); | |
extern void WKRelease(void* type); | |
extern uint32_t WKGetTypeID(void* typeRef); | |
extern void* WKDictionaryGetItemForKey(void* dictionary, void* key); | |
extern void* WKStringCreateWithUTF8CString(const char* string); | |
extern size_t WKStringGetMaximumUTF8CStringSize(void* string); | |
extern size_t WKStringGetUTF8CString(void* string, char* buffer, size_t bufferSize); | |
extern void* WKURLCopyString(void* url); | |
NSString* htWKNSStringFromWKString(void* wkStr){ | |
if(!wkStr || WKGetTypeID(wkStr)!=TypeString)return nil; | |
size_t len=WKStringGetMaximumUTF8CStringSize(wkStr); | |
void* buf; | |
buf=malloc(len); | |
//終端のNULL付きです | |
len=WKStringGetUTF8CString(wkStr, buf, len); | |
NSString* keyStr=[[NSString alloc]initWithBytes:buf length:len-1 encoding:NSUTF8StringEncoding]; | |
free(buf); | |
return [keyStr autorelease]; | |
} | |
NSString* htWKNSStringFromWKURL(void* wkURL){ | |
if(!wkURL || WKGetTypeID(wkURL)!=TypeURL)return nil; | |
void* wkStr=WKURLCopyString(wkURL); | |
NSString* result=htWKNSStringFromWKString(wkStr); | |
WKRelease(wkStr); | |
return result; | |
} | |
//TypeString と TypeURL に対応。TypeURL の場合も NSString を返す | |
NSString* htWKDictionaryStringForKey(void*dic, NSString* key){ | |
void* wkStr=WKStringCreateWithUTF8CString([key cStringUsingEncoding:NSUTF8StringEncoding]); | |
void* val=WKDictionaryGetItemForKey(dic, wkStr); | |
WKRelease(wkStr); | |
if(val){ | |
uint32_t type=WKGetTypeID(val); | |
if(type==TypeString) return htWKNSStringFromWKString(val); | |
if(type==TypeURL) return htWKNSStringFromWKURL(val); | |
} | |
return nil; | |
} | |
// ここまでライブラリ的なやつ | |
// action の例 | |
/* | |
メニュー項目の action から呼ばれる | |
representedObject には「リンクをコピー」から横取りした WebUserDataWrapper を入れておく | |
WKDictionary には以下のキーが含まれている | |
"ImageURL", "IsLinkDataLocal", "LinkLabel", "CanHandleLinkURL", "ElementIsSelected", | |
"LinkURL", "AllowsFollowingLinkURL", "Frame", "LinkTitle", "SelectionString", "MediaURL" | |
*/ | |
-(void)copyLinkAndTitleMenuAction:(id)sender{ | |
id webUserDataWrapper=[sender representedObject]; | |
void* apiObject=[webUserDataWrapper userData]; //struct APIObject | |
uint32_t type=WKGetTypeID(apiObject); | |
if(type==TypeDictionary){ //8==TypeDictionary | |
NSString* linkStr=htWKDictionaryStringForKey(apiObject, @"LinkURL"); | |
NSString* titleStr=htWKDictionaryStringForKey(apiObject, @"LinkLabel"); | |
if(!linkStr)linkStr=@""; | |
if(!titleStr)titleStr=@""; | |
NSString* result=[NSString stringWithFormat:@"%@\n%@", titleStr, linkStr]; | |
NSPasteboard*pb=[NSPasteboard generalPasteboard]; | |
[pb clearContents]; | |
[pb setString:result forType:NSStringPboardType]; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
WKStringGetUTF8CString() の返り値はヌル文字付き。NSStringを作るなら initWithBytes:length:encoding: で1バイト少なく指定するか initWithUTF8String: にそのまま渡すか