packages feed

jsaddle-wkwebview 0.8.1.0 → 0.8.2.0

raw patch · 9 files changed

+282/−156 lines, 9 files

Files

+ cbits-cocoa/AppDelegate.m view
@@ -0,0 +1,62 @@+#include "HsFFI.h"+#import <Cocoa/Cocoa.h>+#import <WebKit/WebKit.h>++extern void withWebView(WKWebView *, HsStablePtr);++@interface AppDelegate : NSObject <NSApplicationDelegate>+@property (nonatomic, assign) IBOutlet NSWindow *window;+@property (nonatomic, assign) HsStablePtr handler;++- (instancetype)initApp:(HsStablePtr)handler progName:(NSString *)progName;+@end++@implementation AppDelegate++- (void)applicationWillTerminate:(NSNotification *)aNotification {+    // Insert code here to tear down your application+}++-(id)initApp:(HsStablePtr)handler progName:(NSString *)progName {+    self = [super init];+    if (self) {+        _handler = handler;+        NSRect contentSize = NSMakeRect(0.0, 500.0, 1000.0, 700.0);+        NSUInteger windowStyleMask = NSWindowStyleMaskTitled | NSWindowStyleMaskResizable | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable;+        _window = [[NSWindow alloc] initWithContentRect:contentSize styleMask:windowStyleMask backing:NSBackingStoreBuffered defer:YES];+        _window.backgroundColor = [NSColor whiteColor];+        _window.title = progName;+    }+    return self;+}++-(void)applicationWillFinishLaunching:(NSNotification *)notification {+    WKWebViewConfiguration *theConfiguration = [[WKWebViewConfiguration alloc] init];+    [theConfiguration.preferences setValue:@YES forKey:@"developerExtrasEnabled"];+    WKWebView *webView = [[WKWebView alloc] initWithFrame:_window.contentView.frame configuration:theConfiguration];+    [_window setContentView:webView];+    withWebView(webView, _handler);+}++-(void)applicationDidFinishLaunching:(NSNotification *)notification {+    [_window orderFrontRegardless];+    [_window center];+    [NSApp activateIgnoringOtherApps:YES];+}++-(BOOL) applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)app {+    return YES;+}++@end++void runInWKWebView(HsStablePtr handler, const char * _Nonnull progName) {+    @autoreleasepool {+        NSApplication *application = [NSApplication sharedApplication];+        AppDelegate *appDelegate = [[AppDelegate alloc] initApp:handler progName:[NSString stringWithCString:progName encoding:NSUTF8StringEncoding]];+        [application setDelegate:appDelegate];+        const char * _Nonnull argv [] =  {"", 0};+        NSApplicationMain(0, argv);+    }+}+
+ cbits-uikit/AppDelegate.m view
@@ -0,0 +1,57 @@+#import "AppDelegate.h"+#import "ViewController.h"++@interface AppDelegate ()+++@end++HsStablePtr globalHandler = 0;++@implementation AppDelegate++- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {+    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];+    // Override point for customization after application launch.+    self.window.rootViewController = [[ViewController alloc] initWithHandler:globalHandler];+    self.window.backgroundColor = [UIColor whiteColor];+    [self.window makeKeyAndVisible];+    return YES;+}++- (void)applicationWillResignActive:(UIApplication *)application {+    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.+    // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.+}+++- (void)applicationDidEnterBackground:(UIApplication *)application {+    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.+    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.+}+++- (void)applicationWillEnterForeground:(UIApplication *)application {+    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.+}+++- (void)applicationDidBecomeActive:(UIApplication *)application {+    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.+}+++- (void)applicationWillTerminate:(UIApplication *)application {+    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.+}++@end++void runInWKWebView(HsStablePtr handler, const char * _Nonnull progName) {+    @autoreleasepool {+        globalHandler = handler;+        const char * _Nonnull argv [] =  {"", 0};+        UIApplicationMain(0, argv, nil, NSStringFromClass([AppDelegate class]));+    }+}+
+ cbits-uikit/ViewController.m view
@@ -0,0 +1,40 @@+#import "ViewController.h"++extern void withWebView(WKWebView *, HsStablePtr);++@interface ViewController ()++@end++@implementation ViewController++-(id)initWithHandler:(HsStablePtr)handler {+    self = [super init];+    if (self) {+        _handler = handler;+    }+    return self;+}++- (void)loadView {+    [super loadView];+    // WKWebViewConfiguration *theConfiguration = [[WKWebViewConfiguration alloc] init];+    // [theConfiguration.preferences setValue:@YES forKey:@"developerExtrasEnabled"];+    _webView = [[WKWebView alloc] init];+    _webView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;+    self.view = _webView;+}++- (void)viewDidLoad {+    [super viewDidLoad];+    withWebView(_webView, _handler);+}+++- (void)didReceiveMemoryWarning {+    [super didReceiveMemoryWarning];+    // Dispose of any resources that can be recreated.+}+++@end
− cbits/Main.m
@@ -1,62 +0,0 @@-#include "HsFFI.h"-#import <Cocoa/Cocoa.h>-#import <WebKit/WebKit.h>--extern void withWebView(WKWebView *, HsStablePtr);--@interface AppDelegate : NSObject <NSApplicationDelegate>-@property (nonatomic, assign) IBOutlet NSWindow *window;-@property (nonatomic, assign) HsStablePtr handler;--- (instancetype)initApp:(HsStablePtr)handler progName:(NSString *)progName;-@end--@implementation AppDelegate--- (void)applicationWillTerminate:(NSNotification *)aNotification {-    // Insert code here to tear down your application-}---(id)initApp:(HsStablePtr)handler progName:(NSString *)progName {-    self = [super init];-    if (self) {-        _handler = handler;-        NSRect contentSize = NSMakeRect(0.0, 500.0, 1000.0, 700.0);-        NSUInteger windowStyleMask = NSWindowStyleMaskTitled | NSWindowStyleMaskResizable | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable;-        _window = [[NSWindow alloc] initWithContentRect:contentSize styleMask:windowStyleMask backing:NSBackingStoreBuffered defer:YES];-        _window.backgroundColor = [NSColor whiteColor];-        _window.title = progName;-    }-    return self;-}---(void)applicationWillFinishLaunching:(NSNotification *)notification {-    WKWebViewConfiguration *theConfiguration = [[WKWebViewConfiguration alloc] init];-    [theConfiguration.preferences setValue:@YES forKey:@"developerExtrasEnabled"];-    WKWebView *webView = [[WKWebView alloc] initWithFrame:_window.contentView.frame configuration:theConfiguration];-    [_window setContentView:webView];-    withWebView(webView, _handler);-}---(void)applicationDidFinishLaunching:(NSNotification *)notification {-    [_window orderFrontRegardless];-    [_window center];-    [NSApp activateIgnoringOtherApps:YES];-}---(BOOL) applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)app {-    return YES;-}--@end--void runInWKWebView(HsStablePtr handler, const char * _Nonnull progName) {-    @autoreleasepool {-        NSApplication *application = [NSApplication sharedApplication];-        AppDelegate *appDelegate = [[AppDelegate alloc] initApp:handler progName:[NSString stringWithCString:progName encoding:NSUTF8StringEncoding]];-        [application setDelegate:appDelegate];-        char * argv [] =  {"", 0};-        NSApplicationMain(0, argv);-    }-}-
jsaddle-wkwebview.cabal view
@@ -1,5 +1,5 @@ name: jsaddle-wkwebview-version: 0.8.1.0+version: 0.8.2.0 cabal-version: >=1.10 build-type: Simple license: MIT@@ -21,6 +21,7 @@ library     exposed-modules:         Language.Javascript.JSaddle.WKWebView+        Language.Javascript.JSaddle.WKWebView.Internal     build-depends:         aeson >=0.8.0.2 && <1.1,         base <5,@@ -28,9 +29,20 @@         jsaddle >= 0.8.0.0 && <0.9     default-language: Haskell2010     hs-source-dirs: src-    frameworks: Cocoa, WebKit+    frameworks: Foundation, WebKit     ghc-options: -ferror-spans -Wall     c-sources:-        cbits/Main.m         cbits/WKWebView.m-+    if impl(ghcjs)+        hs-source-dirs: src-ghcjs+    else+        hs-source-dirs: src-ghc+        if os(ios)+            frameworks: UIKit+            c-sources:+                cbits-uikit/AppDelegate.m+                cbits-uikit/ViewController.m+        else+            frameworks: Cocoa+            c-sources:+                cbits-cocoa/AppDelegate.m
+ src-ghc/Language/Javascript/JSaddle/WKWebView.hs view
@@ -0,0 +1,19 @@+module Language.Javascript.JSaddle.WKWebView+    ( jsaddleMain+    , WKWebView(..)+    , run+    ) where++import Language.Javascript.JSaddle.WKWebView.Internal (jsaddleMain, WKWebView(..))+import System.Environment (getProgName)+import Foreign.C.String (CString, withCString)+import Foreign.StablePtr (StablePtr, newStablePtr)+import Language.Javascript.JSaddle (JSM)++foreign import ccall runInWKWebView :: StablePtr (WKWebView -> IO ()) -> CString -> IO ()++run :: JSM () -> IO ()+run f = do+    handler <- newStablePtr (jsaddleMain f)+    progName <- getProgName+    withCString progName $ runInWKWebView handler
+ src-ghcjs/Language/Javascript/JSaddle/WKWebView.hs view
@@ -0,0 +1,7 @@+module Language.Javascript.JSaddle.WKWebView+    ( run+    ) where++run :: IO () -> IO ()+run = id+{-# INLINE run #-}
− src/Language/Javascript/JSaddle/WKWebView.hs
@@ -1,90 +0,0 @@-{-# LANGUAGE ForeignFunctionInterface, OverloadedStrings #-}-module Language.Javascript.JSaddle.WKWebView-    ( jsaddleMain-    , WKWebView(..)-    , run-    ) where--import System.Environment (getProgName)-import Control.Monad (void, join)-import Control.Concurrent (forkIO)--import Data.Monoid ((<>))-import Data.ByteString (useAsCString, packCString)-import Data.ByteString.Lazy (ByteString, toStrict, fromStrict)-import Data.Aeson (encode, decode)--import Foreign.C.String (CString, withCString)-import Foreign.Ptr (Ptr)-import Foreign.StablePtr (StablePtr, newStablePtr, deRefStablePtr)--import Language.Javascript.JSaddle (Results, JSM)-import Language.Javascript.JSaddle.Run (runJavaScript)-import Language.Javascript.JSaddle.Run.Files (initState, runBatch, ghcjsHelpers)--newtype WKWebView = WKWebView (Ptr WKWebView)--foreign export ccall jsaddleStart :: StablePtr (IO ()) -> IO ()-foreign export ccall jsaddleResult :: StablePtr (Results -> IO ()) -> CString -> IO ()-foreign export ccall withWebView :: WKWebView -> StablePtr (WKWebView -> IO ()) -> IO ()-foreign import ccall addJSaddleHandler :: WKWebView -> StablePtr (IO ()) -> StablePtr (Results -> IO ()) -> IO ()-foreign import ccall loadHTMLString :: WKWebView -> CString -> IO ()-foreign import ccall evaluateJavaScript :: WKWebView -> CString -> IO ()-foreign import ccall runInWKWebView :: StablePtr (WKWebView -> IO ()) -> CString -> IO ()--run :: JSM () -> IO ()-run f = do-    handler <- newStablePtr (jsaddleMain f)-    progName <- getProgName-    withCString progName $ runInWKWebView handler--jsaddleMain :: JSM () -> WKWebView -> IO ()-jsaddleMain f webView = do-    (processResult, start) <- runJavaScript (\batch ->-        useAsCString (toStrict $ "runJSaddleBatch(" <> encode batch <> ");") $-            evaluateJavaScript webView)-        f--    startHandler <- newStablePtr (void $ forkIO start)-    resultHandler <- newStablePtr processResult-    addJSaddleHandler webView startHandler resultHandler--    useAsCString (toStrict indexHtml) $ loadHTMLString webView-    useAsCString (toStrict jsaddleJs) $ evaluateJavaScript webView--jsaddleStart :: StablePtr (IO ()) -> IO ()-jsaddleStart ptrHandler = join (deRefStablePtr ptrHandler)--jsaddleResult :: StablePtr (Results -> IO ()) -> CString -> IO ()-jsaddleResult ptrHandler s = do-    processResult <- deRefStablePtr ptrHandler-    result <- packCString s-    case decode (fromStrict result) of-        Nothing -> error $ "jsaddle WebSocket decode failed : " <> show result-        Just r  -> processResult r--withWebView :: WKWebView -> StablePtr (WKWebView -> IO ()) -> IO ()-withWebView webView ptrF = do-    f <- deRefStablePtr ptrF-    f webView--jsaddleJs :: ByteString-jsaddleJs = ghcjsHelpers <> "\-    \runJSaddleBatch = (function() {\n\-    \ " <> initState <> "\n\-    \ return function(batch) {\n\-    \ " <> runBatch (\a -> "window.webkit.messageHandlers.jsaddle.postMessage(JSON.stringify(" <> a <> "));") <> "\-    \ };\n\-    \})();\n\-    \"--indexHtml :: ByteString-indexHtml =-    "<!DOCTYPE html>\n\-    \<html>\n\-    \<head>\n\-    \<title>JSaddle</title>\n\-    \</head>\n\-    \<body>\n\-    \</body>\n\-    \</html>"
+ src/Language/Javascript/JSaddle/WKWebView/Internal.hs view
@@ -0,0 +1,81 @@+{-# LANGUAGE ForeignFunctionInterface, OverloadedStrings #-}+module Language.Javascript.JSaddle.WKWebView.Internal+    ( jsaddleMain+    , WKWebView(..)+    ) where++import Control.Monad (void, join)+import Control.Concurrent (forkIO)++import Data.Monoid ((<>))+import Data.ByteString (useAsCString, packCString)+import Data.ByteString.Lazy (ByteString, toStrict, fromStrict)+import Data.Aeson (encode, decode)++import Foreign.C.String (CString)+import Foreign.Ptr (Ptr)+import Foreign.StablePtr (StablePtr, newStablePtr, deRefStablePtr)++import Language.Javascript.JSaddle (Results, JSM)+import Language.Javascript.JSaddle.Run (runJavaScript)+import Language.Javascript.JSaddle.Run.Files (initState, runBatch, ghcjsHelpers)++newtype WKWebView = WKWebView (Ptr WKWebView)++foreign export ccall jsaddleStart :: StablePtr (IO ()) -> IO ()+foreign export ccall jsaddleResult :: StablePtr (Results -> IO ()) -> CString -> IO ()+foreign export ccall withWebView :: WKWebView -> StablePtr (WKWebView -> IO ()) -> IO ()+foreign import ccall addJSaddleHandler :: WKWebView -> StablePtr (IO ()) -> StablePtr (Results -> IO ()) -> IO ()+foreign import ccall loadHTMLString :: WKWebView -> CString -> IO ()+foreign import ccall evaluateJavaScript :: WKWebView -> CString -> IO ()++jsaddleMain :: JSM () -> WKWebView -> IO ()+jsaddleMain f webView = do+    (processResult, start) <- runJavaScript (\batch ->+        useAsCString (toStrict $ "runJSaddleBatch(" <> encode batch <> ");") $+            evaluateJavaScript webView)+        f++    startHandler <- newStablePtr (void $ forkIO start)+    resultHandler <- newStablePtr processResult+    addJSaddleHandler webView startHandler resultHandler++    useAsCString (toStrict indexHtml) $ loadHTMLString webView+    useAsCString (toStrict jsaddleJs) $ evaluateJavaScript webView++jsaddleStart :: StablePtr (IO ()) -> IO ()+jsaddleStart ptrHandler = join (deRefStablePtr ptrHandler)++jsaddleResult :: StablePtr (Results -> IO ()) -> CString -> IO ()+jsaddleResult ptrHandler s = do+    processResult <- deRefStablePtr ptrHandler+    result <- packCString s+    case decode (fromStrict result) of+        Nothing -> error $ "jsaddle WebSocket decode failed : " <> show result+        Just r  -> processResult r++withWebView :: WKWebView -> StablePtr (WKWebView -> IO ()) -> IO ()+withWebView webView ptrF = do+    f <- deRefStablePtr ptrF+    f webView++jsaddleJs :: ByteString+jsaddleJs = ghcjsHelpers <> "\+    \runJSaddleBatch = (function() {\n\+    \ " <> initState <> "\n\+    \ return function(batch) {\n\+    \ " <> runBatch (\a -> "window.webkit.messageHandlers.jsaddle.postMessage(JSON.stringify(" <> a <> "));") <> "\+    \ };\n\+    \})();\n\+    \"++indexHtml :: ByteString+indexHtml =+    "<!DOCTYPE html>\n\+    \<html>\n\+    \<head>\n\+    \<title>JSaddle</title>\n\+    \</head>\n\+    \<body>\n\+    \</body>\n\+    \</html>"