packages feed

jsaddle-wkwebview 0.8.2.0 → 0.8.3.0

raw patch · 6 files changed

+118/−12 lines, 6 filesdep ~aeson

Dependency ranges changed: aeson

Files

cbits-cocoa/AppDelegate.m view
@@ -22,7 +22,8 @@     if (self) {         _handler = handler;         NSRect contentSize = NSMakeRect(0.0, 500.0, 1000.0, 700.0);-        NSUInteger windowStyleMask = NSWindowStyleMaskTitled | NSWindowStyleMaskResizable | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable;+        // TODO replace with once nix has newer Cocoa NSUInteger windowStyleMask = NSWindowStyleMaskTitled | NSWindowStyleMaskResizable | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable;+        NSUInteger windowStyleMask = NSTitledWindowMask | NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask;         _window = [[NSWindow alloc] initWithContentRect:contentSize styleMask:windowStyleMask backing:NSBackingStoreBuffered defer:YES];         _window.backgroundColor = [NSColor whiteColor];         _window.title = progName;@@ -60,3 +61,7 @@     } } +BOOL openApp(NSURL * url) {+    NSWorkspace *workspace = [NSWorkspace sharedWorkspace];+    return [workspace openURL:url];+}
cbits-uikit/AppDelegate.m view
@@ -55,3 +55,11 @@     } } +BOOL openApp(NSURL * url) {+    UIApplication *app = [UIApplication sharedApplication];+    if ([app canOpenURL:url]) {+        [app openURL:url];+        return true;+    }+    return false;+}
cbits/WKWebView.m view
@@ -2,6 +2,8 @@ #import <Foundation/Foundation.h> #import <WebKit/WebKit.h> +BOOL openApp(NSURL * url);+ extern void jsaddleStart(HsStablePtr); extern void jsaddleResult(HsStablePtr, const char *  _Nonnull result); @@ -37,6 +39,20 @@     jsaddleResult(self.resultHandler, [s UTF8String]); } +- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler+{+    NSURL *url = navigationAction.request.URL;++    if(!navigationAction.targetFrame && ![url.scheme isEqualToString:@"file"]) {+        if(openApp(url))+		    decisionHandler(WKNavigationActionPolicyCancel);+		else+		    decisionHandler(WKNavigationActionPolicyAllow);+    }+    else+        decisionHandler(WKNavigationActionPolicyAllow);+}+ @end  void addJSaddleHandler(WKWebView *webView, HsStablePtr startHandler, HsStablePtr resultHandler) {@@ -46,10 +62,39 @@ }  void evaluateJavaScript(WKWebView *webView, const char * _Nonnull js) {-    [webView evaluateJavaScript:[NSString stringWithCString:js encoding:NSUTF8StringEncoding] completionHandler:NULL];+    NSString *jsString = [[NSString alloc] initWithCString:js encoding:NSUTF8StringEncoding];+    dispatch_async(dispatch_get_main_queue(), ^{+        [webView evaluateJavaScript:jsString completionHandler:NULL];+        [jsString release];+    }); }  void loadHTMLString(WKWebView *webView, const char * _Nonnull html) {-    [webView loadHTMLString:[NSString stringWithCString:html encoding:NSUTF8StringEncoding] baseURL:NULL];+    NSString *htmlString = [NSString stringWithCString:html encoding:NSUTF8StringEncoding];+    dispatch_async(dispatch_get_main_queue(), ^{+        [webView loadHTMLString:htmlString baseURL:NULL];+    }); }++const char * mainBundleResourcePathC() {+    NSBundle *main = [NSBundle mainBundle];+    if(!main) return NULL;+    NSString *path = main.resourcePath;+    if(!path) return NULL;+    return [path UTF8String];+}++void loadBundleFile(WKWebView *webView, const char * _Nonnull file, const char * _Nonnull allowing) {+    NSBundle *main = [NSBundle mainBundle];+    if(main) {+        NSString *path = main.resourcePath;+        if(path) {+            NSURL *fileUrl = [NSURL fileURLWithPath:[NSString stringWithFormat: @"%@/%@", path, [NSString stringWithCString:file encoding:NSUTF8StringEncoding]]];+            NSURL *allowingUrl = [NSURL fileURLWithPath:[NSString stringWithFormat: @"%@/%@", path, [NSString stringWithCString:allowing encoding:NSUTF8StringEncoding]]];+            [webView loadFileURL:fileUrl allowingReadAccessToURL:allowingUrl];+        }+    }+}++ 
jsaddle-wkwebview.cabal view
@@ -1,5 +1,5 @@ name: jsaddle-wkwebview-version: 0.8.2.0+version: 0.8.3.0 cabal-version: >=1.10 build-type: Simple license: MIT@@ -23,7 +23,7 @@         Language.Javascript.JSaddle.WKWebView         Language.Javascript.JSaddle.WKWebView.Internal     build-depends:-        aeson >=0.8.0.2 && <1.1,+        aeson >=0.8.0.2 && <1.2,         base <5,         bytestring >=0.10.6.0 && <0.11,         jsaddle >= 0.8.0.0 && <0.9
src-ghc/Language/Javascript/JSaddle/WKWebView.hs view
@@ -1,10 +1,14 @@ module Language.Javascript.JSaddle.WKWebView     ( jsaddleMain+    , jsaddleMainFile     , WKWebView(..)     , run+    , runFile+    , mainBundleResourcePath     ) where -import Language.Javascript.JSaddle.WKWebView.Internal (jsaddleMain, WKWebView(..))+import Data.ByteString (ByteString)+import Language.Javascript.JSaddle.WKWebView.Internal (jsaddleMain, jsaddleMainFile, WKWebView(..), mainBundleResourcePath) import System.Environment (getProgName) import Foreign.C.String (CString, withCString) import Foreign.StablePtr (StablePtr, newStablePtr)@@ -12,8 +16,19 @@  foreign import ccall runInWKWebView :: StablePtr (WKWebView -> IO ()) -> CString -> IO () +-- | Run JSaddle in a WKWebView run :: JSM () -> IO () run f = do     handler <- newStablePtr (jsaddleMain f)+    progName <- getProgName+    withCString progName $ runInWKWebView handler++-- | Run JSaddle in a WKWebView first loading the specified file+--   from the mainBundle (relative to the resourcePath).+runFile :: ByteString -- ^ The file to navigate to.+        -> ByteString -- ^ The path to allow read access to.+        -> JSM () -> IO ()+runFile url allowing f = do+    handler <- newStablePtr (jsaddleMainFile url allowing f)     progName <- getProgName     withCString progName $ runInWKWebView handler
src/Language/Javascript/JSaddle/WKWebView/Internal.hs view
@@ -1,19 +1,23 @@ {-# LANGUAGE ForeignFunctionInterface, OverloadedStrings #-} module Language.Javascript.JSaddle.WKWebView.Internal     ( jsaddleMain+    , jsaddleMainFile     , WKWebView(..)+    , mainBundleResourcePath     ) where  import Control.Monad (void, join)-import Control.Concurrent (forkIO)+import Control.Concurrent (forkIO, forkOS)+import Control.Concurrent.MVar (newEmptyMVar, putMVar, takeMVar)  import Data.Monoid ((<>)) import Data.ByteString (useAsCString, packCString)+import qualified Data.ByteString as BS (ByteString) import Data.ByteString.Lazy (ByteString, toStrict, fromStrict) import Data.Aeson (encode, decode)  import Foreign.C.String (CString)-import Foreign.Ptr (Ptr)+import Foreign.Ptr (Ptr, nullPtr) import Foreign.StablePtr (StablePtr, newStablePtr, deRefStablePtr)  import Language.Javascript.JSaddle (Results, JSM)@@ -27,21 +31,43 @@ 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 loadBundleFile :: WKWebView -> CString -> CString -> IO () foreign import ccall evaluateJavaScript :: WKWebView -> CString -> IO ()+foreign import ccall mainBundleResourcePathC :: IO CString +-- | Run JSaddle in WKWebView jsaddleMain :: JSM () -> WKWebView -> IO () jsaddleMain f webView = do+    jsaddleMain' f webView $+        useAsCString (toStrict indexHtml) $ loadHTMLString webView++-- | Run JSaddle in a WKWebView first loading the specified file+--   from the mainBundle (relative to the resourcePath).+jsaddleMainFile :: BS.ByteString -- ^ The file to navigate to.+                -> BS.ByteString -- ^ The path to allow read access to.+                -> JSM () -> WKWebView -> IO ()+jsaddleMainFile url allowing f webView = do+    jsaddleMain' f webView $+        useAsCString url $ \u ->+            useAsCString allowing $ \a ->+                loadBundleFile webView u a++jsaddleMain' :: JSM () -> WKWebView -> IO () -> IO ()+jsaddleMain' f webView loadHtml = do+    ready <- newEmptyMVar+     (processResult, start) <- runJavaScript (\batch ->         useAsCString (toStrict $ "runJSaddleBatch(" <> encode batch <> ");") $             evaluateJavaScript webView)         f -    startHandler <- newStablePtr (void $ forkIO start)+    startHandler <- newStablePtr (putMVar ready ())     resultHandler <- newStablePtr processResult     addJSaddleHandler webView startHandler resultHandler--    useAsCString (toStrict indexHtml) $ loadHTMLString webView-    useAsCString (toStrict jsaddleJs) $ evaluateJavaScript webView+    loadHtml+    void . forkOS $ do+        takeMVar ready+        useAsCString (toStrict jsaddleJs) (evaluateJavaScript webView) >> void (forkIO start)  jsaddleStart :: StablePtr (IO ()) -> IO () jsaddleStart ptrHandler = join (deRefStablePtr ptrHandler)@@ -79,3 +105,10 @@     \<body>\n\     \</body>\n\     \</html>"++mainBundleResourcePath :: IO (Maybe BS.ByteString)+mainBundleResourcePath = do+    bs <- mainBundleResourcePathC+    if bs == nullPtr+        then return Nothing+        else Just <$> packCString bs