Chandra
view release on metacpan or search on metacpan
include/webview-cocoa.c view on Meta::CPAN
/*
* MIT License
*
* Copyright (c) 2017 Serge Zaitsev
* Copyright (c) 2023 Badr Ghanem
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Badr Ghanem made modifications on 03/12/2023 to support Mac OS.
*/
#define NSUTF8StringEncoding 4
#define NSAlertStyleWarning 0
#define NSAlertStyleCritical 2
#define NSWindowStyleMaskResizable 8
#define NSWindowStyleMaskMiniaturizable 4
#define NSWindowStyleMaskTitled 1
#define NSWindowStyleMaskClosable 2
#define NSWindowStyleMaskFullScreen (1 << 14)
#define NSViewWidthSizable 2
#define NSViewHeightSizable 16
#define NSBackingStoreBuffered 2
#define NSEventMaskAny ULONG_MAX
#define NSEventModifierFlagCommand (1 << 20)
#define NSEventModifierFlagOption (1 << 19)
#define NSAlertStyleInformational 1
#define NSAlertFirstButtonReturn 1000
#define WKNavigationActionPolicyDownload 2
#define NSModalResponseOK 1
#define WKNavigationActionPolicyDownload 2
#define WKNavigationResponsePolicyAllow 1
#define WKUserScriptInjectionTimeAtDocumentStart 0
#define NSApplicationActivationPolicyRegular 0
static id get_nsstring(const char *c_str) {
return ((id(*)(id, SEL, const char *c_str))objc_msgSend)((id)objc_getClass("NSString"),
sel_registerName("stringWithUTF8String:"), c_str);
}
static id create_menu_item(id title, const char *action, const char *key) {
id item = ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSMenuItem"), sel_registerName("alloc"));
((void(*)(id, SEL, id, SEL, id))objc_msgSend)(item, sel_registerName("initWithTitle:action:keyEquivalent:"), title, sel_registerName(action), get_nsstring(key));
((void(*)(id, SEL))objc_msgSend)(item, sel_registerName("autorelease"));
return item;
}
static void webview_window_will_close(id self, SEL cmd, id notification) {
struct webview *w = (struct webview *)objc_getAssociatedObject(self, "webview");
webview_terminate(w);
}
static void webview_external_invoke(id self, SEL cmd, id contentController,
id message) {
struct webview *w = (struct webview *)objc_getAssociatedObject(contentController, "webview");
if (w == NULL || w->external_invoke_cb == NULL) {
return;
}
w->external_invoke_cb(w, ((const char *(*)(id, SEL))objc_msgSend)(
((id(*)(id, SEL))objc_msgSend)(message, sel_registerName("body")),
sel_registerName("UTF8String")));
}
static void run_open_panel(id self, SEL cmd, id webView, id parameters,
id frame, void (^completionHandler)(id)) {
id openPanel = ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSOpenPanel"),
sel_registerName("openPanel"));
((void(*)(id, SEL, id))objc_msgSend)(
openPanel, sel_registerName("setAllowsMultipleSelection:"),
((id(*)(id, SEL))objc_msgSend)(parameters, sel_registerName("allowsMultipleSelection")));
((void(*)(id, SEL, int))objc_msgSend)(openPanel, sel_registerName("setCanChooseFiles:"), 1);
((id(*)(id, SEL, void (^)(id)))objc_msgSend)(
openPanel, sel_registerName("beginWithCompletionHandler:"), ^(id result) {
if (result == (id)NSModalResponseOK) {
id urls = ((id(*)(id, SEL))objc_msgSend)(openPanel, sel_registerName("URLs"));
completionHandler(urls);
} else {
completionHandler(nil);
}
});
}
static void run_save_panel(id self, SEL cmd, id download, id filename,
void (^completionHandler)(int allowOverwrite,
id destination)) {
id savePanel = ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSSavePanel"),
sel_registerName("savePanel"));
((void(*)(id, SEL, int))objc_msgSend)(savePanel, sel_registerName("setCanCreateDirectories:"), 1);
((void(*)(id, SEL, id))objc_msgSend)(savePanel, sel_registerName("setNameFieldStringValue:"),
filename);
((void(*)(id, SEL, void (^)(id)))objc_msgSend)(savePanel, sel_registerName("beginWithCompletionHandler:"),
include/webview-cocoa.c view on Meta::CPAN
__WKNavigationDelegate,
sel_registerName(
"webView:decidePolicyForNavigationResponse:decisionHandler:"),
(IMP)make_nav_policy_decision, "v@:@@?");
objc_registerClassPair(__WKNavigationDelegate);
id navDel = ((id(*)(id, SEL))objc_msgSend)((id)__WKNavigationDelegate, sel_registerName("new"));
w->priv.webview = ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("WKWebView"), sel_registerName("alloc"));
((void(*)(id, SEL, CGRect, id))objc_msgSend)(w->priv.webview,
sel_registerName("initWithFrame:configuration:"), r, config);
((void(*)(id, SEL, id))objc_msgSend)(w->priv.webview, sel_registerName("setUIDelegate:"), uiDel);
((void(*)(id, SEL, id))objc_msgSend)(w->priv.webview, sel_registerName("setNavigationDelegate:"), navDel);
int comma_index;
const char *MIMEType = parse_data_URI_content_type(w->url, &comma_index);
if (MIMEType != NULL) {
id NSString = get_nsstring(w->url + (comma_index+1));
id NSData = ((id(*)(id, SEL, int))objc_msgSend)(NSString, sel_registerName("dataUsingEncoding:"), NSUTF8StringEncoding);
((void(*)(id, SEL, id, id, id, void *))objc_msgSend)(w->priv.webview,
sel_registerName("loadData:MIMEType:characterEncodingName:baseURL:"),
NSData, get_nsstring(MIMEType),get_nsstring("UTF-8"),NULL);
free((void *)MIMEType);
} else {
id nsURL = ((id(*)(id, SEL, id))objc_msgSend)((id)objc_getClass("NSURL"),
sel_registerName("URLWithString:"),
get_nsstring(webview_check_url(w->url)));
((void(*)(id, SEL, id))objc_msgSend)(w->priv.webview, sel_registerName("loadRequest:"),
((id(*)(id, SEL, id))objc_msgSend)((id)objc_getClass("NSURLRequest"),
sel_registerName("requestWithURL:"), nsURL));
}
((void(*)(id, SEL, int))objc_msgSend)(w->priv.webview, sel_registerName("setAutoresizesSubviews:"), 1);
((void(*)(id, SEL, int))objc_msgSend)(w->priv.webview, sel_registerName("setAutoresizingMask:"),
(NSViewWidthSizable | NSViewHeightSizable));
((void(*)(id, SEL, id))objc_msgSend)(((id(*)(id, SEL))objc_msgSend)(w->priv.window, sel_registerName("contentView")),
sel_registerName("addSubview:"), w->priv.webview);
((void(*)(id, SEL))objc_msgSend)(w->priv.window, sel_registerName("orderFrontRegardless"));
((void(*)(id, SEL, int))objc_msgSend)(((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSApplication"),
sel_registerName("sharedApplication")),
sel_registerName("setActivationPolicy:"),
NSApplicationActivationPolicyRegular);
((void(*)(id, SEL))objc_msgSend)(((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSApplication"),
sel_registerName("sharedApplication")),
sel_registerName("finishLaunching"));
((void(*)(id, SEL, int))objc_msgSend)(((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSApplication"),
sel_registerName("sharedApplication")),
sel_registerName("activateIgnoringOtherApps:"), 1);
id menubar = ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSMenu"), sel_registerName("alloc"));
((void(*)(id, SEL, id))objc_msgSend)(menubar, sel_registerName("initWithTitle:"), get_nsstring(""));
((void(*)(id, SEL))objc_msgSend)(menubar, sel_registerName("autorelease"));
id appName = ((id(*)(id, SEL))objc_msgSend)(((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSProcessInfo"),
sel_registerName("processInfo")),
sel_registerName("processName"));
id appMenuItem = ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSMenuItem"), sel_registerName("alloc"));
((void(*)(id, SEL, id, void *, id))objc_msgSend)(appMenuItem,
sel_registerName("initWithTitle:action:keyEquivalent:"), appName,
NULL, get_nsstring(""));
id appMenu = ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSMenu"), sel_registerName("alloc"));
((void(*)(id, SEL, id))objc_msgSend)(appMenu, sel_registerName("initWithTitle:"), appName);
((void(*)(id, SEL))objc_msgSend)(appMenu, sel_registerName("autorelease"));
((void(*)(id, SEL, id))objc_msgSend)(appMenuItem, sel_registerName("setSubmenu:"), appMenu);
((void(*)(id, SEL, id))objc_msgSend)(menubar, sel_registerName("addItem:"), appMenuItem);
id title =
((id(*)(id, SEL, id))objc_msgSend)(get_nsstring("Hide "),
sel_registerName("stringByAppendingString:"), appName);
id item = create_menu_item(title, "hide:", "h");
((void(*)(id, SEL, id))objc_msgSend)(appMenu, sel_registerName("addItem:"), item);
item = create_menu_item(get_nsstring("Hide Others"),
"hideOtherApplications:", "h");
((void(*)(id, SEL, int))objc_msgSend)(item, sel_registerName("setKeyEquivalentModifierMask:"),
(NSEventModifierFlagOption | NSEventModifierFlagCommand));
((void(*)(id, SEL, id))objc_msgSend)(appMenu, sel_registerName("addItem:"), item);
item =
create_menu_item(get_nsstring("Show All"), "unhideAllApplications:", "");
((void(*)(id, SEL, id))objc_msgSend)(appMenu, sel_registerName("addItem:"), item);
((void(*)(id, SEL, id))objc_msgSend)(appMenu, sel_registerName("addItem:"),
((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSMenuItem"),
sel_registerName("separatorItem")));
title = ((id(*)(id, SEL, id))objc_msgSend)(get_nsstring("Quit "),
sel_registerName("stringByAppendingString:"), appName);
item = create_menu_item(title, "terminate:", "q");
((void(*)(id, SEL, id))objc_msgSend)(appMenu, sel_registerName("addItem:"), item);
((void(*)(id, SEL, id))objc_msgSend)(((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSApplication"),
sel_registerName("sharedApplication")),
sel_registerName("setMainMenu:"), menubar);
w->priv.should_exit = 0;
return 0;
}
WEBVIEW_API int webview_loop(struct webview *w, int blocking) {
id until = (blocking ? ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSDate"),
sel_registerName("distantFuture"))
: ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSDate"),
sel_registerName("distantPast")));
id event = ((id(*)(id, SEL, unsigned long, id, id, int))objc_msgSend)(
((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSApplication"),
sel_registerName("sharedApplication")),
sel_registerName("nextEventMatchingMask:untilDate:inMode:dequeue:"),
ULONG_MAX, until,
((id(*)(id, SEL, char*))objc_msgSend)((id)objc_getClass("NSString"),
sel_registerName("stringWithUTF8String:"),
"kCFRunLoopDefaultMode"),
true);
if (event) {
((void(*)(id, SEL, id))objc_msgSend)(((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSApplication"),
sel_registerName("sharedApplication")),
sel_registerName("sendEvent:"), event);
}
return w->priv.should_exit;
}
WEBVIEW_API int webview_eval(struct webview *w, const char *js) {
((void(*)(id, SEL, id, void *))objc_msgSend)(w->priv.webview,
sel_registerName("evaluateJavaScript:completionHandler:"),
get_nsstring(js), NULL);
return 0;
}
WEBVIEW_API void webview_set_title(struct webview *w, const char *title) {
((void(*)(id, SEL, id))objc_msgSend)(w->priv.window, sel_registerName("setTitle:"),
get_nsstring(title));
}
WEBVIEW_API void webview_set_size(struct webview *w, int width, int height) {
CGSize size = {width, height};
((void(*)(id, SEL, CGSize))objc_msgSend)(
w->priv.window, sel_registerName("setContentSize:"), size);
w->width = width;
w->height = height;
}
WEBVIEW_API void webview_set_fullscreen(struct webview *w, int fullscreen) {
unsigned long windowStyleMask = ((unsigned long(*)(id, SEL))objc_msgSend)(
w->priv.window, sel_registerName("styleMask"));
int b = (((windowStyleMask & NSWindowStyleMaskFullScreen) ==
NSWindowStyleMaskFullScreen)
? 1
: 0);
if (b != fullscreen) {
((void(*)(id, SEL, void *))objc_msgSend)(w->priv.window, sel_registerName("toggleFullScreen:"), NULL);
( run in 0.960 second using v1.01-cache-2.11-cpan-39bf76dae61 )