on master help sign in
Add run function for Mac OS
a279a35Hamish Mackenzie
jsaddle-wkwebview/cbits/Main.mnew file+62
@@ -0,0 +1,62 @@
1+#include "HsFFI.h"
2+#import <Cocoa/Cocoa.h>
3+#import <WebKit/WebKit.h>
4+
5+extern void withWebView(WKWebView *, HsStablePtr);
6+
7+@interface AppDelegate : NSObject <NSApplicationDelegate>
8+@property (nonatomic, assign) IBOutlet NSWindow *window;
9+@property (nonatomic, assign) HsStablePtr handler;
10+
11+- (instancetype)initApp:(HsStablePtr)handler progName:(NSString *)progName;
12+@end
13+
14+@implementation AppDelegate
15+
16+- (void)applicationWillTerminate:(NSNotification *)aNotification {
17+ // Insert code here to tear down your application
18+}
19+
20+-(id)initApp:(HsStablePtr)handler progName:(NSString *)progName {
21+ self = [super init];
22+ if (self) {
23+ _handler = handler;
24+ NSRect contentSize = NSMakeRect(0.0, 500.0, 1000.0, 700.0);
25+ NSUInteger windowStyleMask = NSWindowStyleMaskTitled | NSWindowStyleMaskResizable | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable;
26+ _window = [[NSWindow alloc] initWithContentRect:contentSize styleMask:windowStyleMask backing:NSBackingStoreBuffered defer:YES];
27+ _window.backgroundColor = [NSColor whiteColor];
28+ _window.title = progName;
29+ }
30+ return self;
31+}
32+
33+-(void)applicationWillFinishLaunching:(NSNotification *)notification {
34+ WKWebViewConfiguration *theConfiguration = [[WKWebViewConfiguration alloc] init];
35+ [theConfiguration.preferences setValue:@YES forKey:@"developerExtrasEnabled"];
36+ WKWebView *webView = [[WKWebView alloc] initWithFrame:_window.contentView.frame configuration:theConfiguration];
37+ [_window setContentView:webView];
38+ withWebView(webView, _handler);
39+}
40+
41+-(void)applicationDidFinishLaunching:(NSNotification *)notification {
42+ [_window orderFrontRegardless];
43+ [_window center];
44+ [NSApp activateIgnoringOtherApps:YES];
45+}
46+
47+-(BOOL) applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)app {
48+ return YES;
49+}
50+
51+@end
52+
53+void runInWKWebView(HsStablePtr handler, const char * _Nonnull progName) {
54+ @autoreleasepool {
55+ NSApplication *application = [NSApplication sharedApplication];
56+ AppDelegate *appDelegate = [[AppDelegate alloc] initApp:handler progName:[NSString stringWithCString:progName encoding:NSUTF8StringEncoding]];
57+ [application setDelegate:appDelegate];
58+ char * argv [] = {"", 0};
59+ NSApplicationMain(0, argv);
60+ }
61+}
62+
jsaddle-wkwebview/cbits/WKWebView.m+1−1
@@ -39,7 +39,7 @@ extern void jsaddleResult(HsStablePtr, const char * _Nonnull result);
39
39
40@end
40@end
41
41
42−void addJSaddleHandler(WKWebView *webView, HsStablePtr startHandler, HsStablePtr resultHandler) {
42+void addJSaddleHandler(WKWebView *webView, HsStablePtr startHandler, HsStablePtr resultHandler) {
43 JSaddleHandler * handler = [[JSaddleHandler alloc] initHandler:startHandler resultHandler:resultHandler];
43 JSaddleHandler * handler = [[JSaddleHandler alloc] initHandler:startHandler resultHandler:resultHandler];
44 [[[webView configuration] userContentController] addScriptMessageHandler:handler name:@"jsaddle"];
44 [[[webView configuration] userContentController] addScriptMessageHandler:handler name:@"jsaddle"];
45 webView.navigationDelegate = handler;
45 webView.navigationDelegate = handler;
jsaddle-wkwebview/jsaddle-wkwebview.cabal+5−2
@@ -1,5 +1,5 @@
1name: jsaddle-wkwebview
1name: jsaddle-wkwebview
2−version: 0.8.0.0
2+version: 0.8.1.0
3cabal-version: >=1.10
3cabal-version: >=1.10
4build-type: Simple
4build-type: Simple
5license: MIT
5license: MIT
@@ -28,6 +28,9 @@ library
28 jsaddle >= 0.8.0.0 && <0.9
28 jsaddle >= 0.8.0.0 && <0.9
29 default-language: Haskell2010
29 default-language: Haskell2010
30 hs-source-dirs: src
30 hs-source-dirs: src
31+ frameworks: Cocoa, WebKit
31 ghc-options: -ferror-spans -Wall
32 ghc-options: -ferror-spans -Wall
33+ c-sources:
34+ cbits/Main.m
32− c-sources: cbits/WKWebView.m
35+ cbits/WKWebView.m
33
36
jsaddle-wkwebview/src/Language/Javascript/JSaddle/WKWebView.hs+20−6
@@ -2,8 +2,10 @@
2module Language.Javascript.JSaddle.WKWebView
2module Language.Javascript.JSaddle.WKWebView
3 ( jsaddleMain
3 ( jsaddleMain
4 , WKWebView(..)
4 , WKWebView(..)
5+ , run
5 ) where
6 ) where
6
7
8+import System.Environment (getProgName)
7import Control.Monad (void, join)
9import Control.Monad (void, join)
8import Control.Concurrent (forkIO)
10import Control.Concurrent (forkIO)
9
11
@@ -12,22 +14,29 @@ import Data.ByteString (useAsCString, packCString)
12import Data.ByteString.Lazy (ByteString, toStrict, fromStrict)
14import Data.ByteString.Lazy (ByteString, toStrict, fromStrict)
13import Data.Aeson (encode, decode)
15import Data.Aeson (encode, decode)
14
16
15−import Foreign.C.String (CString)
17+import Foreign.C.String (CString, withCString)
16import Foreign.Ptr (Ptr)
18import Foreign.Ptr (Ptr)
17import Foreign.StablePtr (StablePtr, newStablePtr, deRefStablePtr)
19import Foreign.StablePtr (StablePtr, newStablePtr, deRefStablePtr)
18
20
19−import Language.Javascript.JSaddle (Result, JSM)
21+import Language.Javascript.JSaddle (Results, JSM)
20−import Language.Javascript.JSaddle.Types (Batch(..))
21import Language.Javascript.JSaddle.Run (runJavaScript)
22import Language.Javascript.JSaddle.Run (runJavaScript)
22import Language.Javascript.JSaddle.Run.Files (initState, runBatch, ghcjsHelpers)
23import Language.Javascript.JSaddle.Run.Files (initState, runBatch, ghcjsHelpers)
23
24
24newtype WKWebView = WKWebView (Ptr WKWebView)
25newtype WKWebView = WKWebView (Ptr WKWebView)
25
26
26foreign export ccall jsaddleStart :: StablePtr (IO ()) -> IO ()
27foreign export ccall jsaddleStart :: StablePtr (IO ()) -> IO ()
27−foreign export ccall jsaddleResult :: StablePtr (Result -> IO ()) -> CString -> IO ()
28+foreign export ccall jsaddleResult :: StablePtr (Results -> IO ()) -> CString -> IO ()
29+foreign export ccall withWebView :: WKWebView -> StablePtr (WKWebView -> IO ()) -> IO ()
28−foreign import ccall addJSaddleHandler :: WKWebView -> StablePtr (IO ()) -> StablePtr (Result -> IO ()) -> IO ()
30+foreign import ccall addJSaddleHandler :: WKWebView -> StablePtr (IO ()) -> StablePtr (Results -> IO ()) -> IO ()
29foreign import ccall loadHTMLString :: WKWebView -> CString -> IO ()
31foreign import ccall loadHTMLString :: WKWebView -> CString -> IO ()
30foreign import ccall evaluateJavaScript :: WKWebView -> CString -> IO ()
32foreign import ccall evaluateJavaScript :: WKWebView -> CString -> IO ()
33+foreign import ccall runInWKWebView :: StablePtr (WKWebView -> IO ()) -> CString -> IO ()
34+
35+run :: JSM () -> IO ()
36+run f = do
37+ handler <- newStablePtr (jsaddleMain f)
38+ progName <- getProgName
39+ withCString progName $ runInWKWebView handler
31
40
32jsaddleMain :: JSM () -> WKWebView -> IO ()
41jsaddleMain :: JSM () -> WKWebView -> IO ()
33jsaddleMain f webView = do
42jsaddleMain f webView = do
@@ -46,7 +55,7 @@ jsaddleMain f webView = do
46jsaddleStart :: StablePtr (IO ()) -> IO ()
55jsaddleStart :: StablePtr (IO ()) -> IO ()
47jsaddleStart ptrHandler = join (deRefStablePtr ptrHandler)
56jsaddleStart ptrHandler = join (deRefStablePtr ptrHandler)
48
57
49−jsaddleResult :: StablePtr (Result -> IO ()) -> CString -> IO ()
58+jsaddleResult :: StablePtr (Results -> IO ()) -> CString -> IO ()
50jsaddleResult ptrHandler s = do
59jsaddleResult ptrHandler s = do
51 processResult <- deRefStablePtr ptrHandler
60 processResult <- deRefStablePtr ptrHandler
52 result <- packCString s
61 result <- packCString s
@@ -54,6 +63,11 @@ jsaddleResult ptrHandler s = do
54 Nothing -> error $ "jsaddle WebSocket decode failed : " <> show result
63 Nothing -> error $ "jsaddle WebSocket decode failed : " <> show result
55 Just r -> processResult r
64 Just r -> processResult r
56
65
66+withWebView :: WKWebView -> StablePtr (WKWebView -> IO ()) -> IO ()
67+withWebView webView ptrF = do
68+ f <- deRefStablePtr ptrF
69+ f webView
70+
57jsaddleJs :: ByteString
71jsaddleJs :: ByteString
58jsaddleJs = ghcjsHelpers <> "\
72jsaddleJs = ghcjsHelpers <> "\
59 \runJSaddleBatch = (function() {\n\
73 \runJSaddleBatch = (function() {\n\