packages feed

reflex-dom 0.6.1.1 → 0.6.2.0

raw patch · 7 files changed

+119/−12 lines, 7 filesdep ~aeson

Dependency ranges changed: aeson

Files

ChangeLog.md view
@@ -1,5 +1,14 @@ # Revision history for reflex-dom +## 0.6.2.0++* [#452](https://github.com/reflex-frp/reflex-dom/pull/452) Allow file access on newer android, following usage recommended by the [official docs](https://developer.android.com/reference/androidx/webkit/WebViewAssetLoader)+* [#453](https://github.com/reflex-frp/reflex-dom/pull/453) History management for android++## 0.6.1.1-r1++* Loosen reflex-dom-core version bounds to allow reflex-dom-core 0.7.*+ ## 0.6.1.1  * Compile with -fPIC
cbits/MainWidget.c view
@@ -53,6 +53,40 @@   (*env)->PopLocalFrame(env, 0); } +void Reflex_Dom_Android_MainWidget_back(jobject jsExecutor) {+  JNIEnv *env;+  jint attachResult = (*HaskellActivity_jvm)->AttachCurrentThread(HaskellActivity_jvm, &env, NULL);+  assert (attachResult == JNI_OK);++  (*env)->PushLocalFrame(env, 5);++  //TODO: Don't search for this method every time+  jclass cls = (*env)->GetObjectClass(env, jsExecutor);+  assert(cls);+  jmethodID evaluateJavascript = (*env)->GetMethodID(env, cls, "goBack", "()V");+  assert(evaluateJavascript);+  (*env)->CallVoidMethod(env, jsExecutor, evaluateJavascript);++  (*env)->PopLocalFrame(env, 0);+}++void Reflex_Dom_Android_MainWidget_clearHistory(jobject jsExecutor) {+  JNIEnv *env;+  jint attachResult = (*HaskellActivity_jvm)->AttachCurrentThread(HaskellActivity_jvm, &env, NULL);+  assert (attachResult == JNI_OK);++  (*env)->PushLocalFrame(env, 5);++  //TODO: Don't search for this method every time+  jclass cls = (*env)->GetObjectClass(env, jsExecutor);+  assert(cls);+  jmethodID evaluateJavascript = (*env)->GetMethodID(env, cls, "clearHistory", "()V");+  assert(evaluateJavascript);+  (*env)->CallVoidMethod(env, jsExecutor, evaluateJavascript);++  (*env)->PopLocalFrame(env, 0);+}+ JNIEXPORT void JNICALL Java_org_reflexfrp_reflexdom_MainWidget_00024JSaddleCallbacks_startProcessing (JNIEnv *env, jobject thisObj, jlong callbacksLong) {   const JSaddleCallbacks *callbacks = (const JSaddleCallbacks *)callbacksLong;   (*(callbacks->jsaddleStart))();
java/org/reflexfrp/reflexdom/MainWidget.java view
@@ -41,8 +41,6 @@     a.setContentView(wv);     final WebSettings ws = wv.getSettings();     ws.setJavaScriptEnabled(true);-    ws.setAllowFileAccessFromFileURLs(true);-    ws.setAllowUniversalAccessFromFileURLs(true);     ws.setDomStorageEnabled(true);     wv.setWebContentsDebuggingEnabled(true);     // allow video to play without user interaction@@ -64,7 +62,8 @@         @Override         public WebResourceResponse shouldInterceptRequest (WebView view, WebResourceRequest request) {             Uri uri = request.getUrl();-            if(!uri.getScheme().equals("file"))+	    Log.i("reflex", uri.toString());+            if(!uri.getScheme().equals("file") && !uri.getEncodedAuthority().equals("appassets.androidplatform.net"))                 return null;              String path = uri.getPath();@@ -87,7 +86,7 @@          @Override         public boolean shouldOverrideUrlLoading(WebView view, String url) {-            if( url != null && !url.startsWith("http://") && !url.startsWith("https://") && !url.startsWith("file://")) {+            if( url != null && !url.startsWith("http://appassets.androidplatform.net") && !url.startsWith("https://appassets.androidplatform.net") && !url.startsWith("file://")) {                 try {                     view.getContext().startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));                 }@@ -144,6 +143,18 @@               wv.evaluateJavascript(jsStr, null);             }           });+      }+      public final void goBack() {+        hnd.post(new Runnable() {+          @Override+	  public void run() {+            if(wv.canGoBack()) {+              wv.goBack();+            } else {+              a.defaultOnBackPressed();+            }+	  }+	});       }     };   }
reflex-dom.cabal view
@@ -1,6 +1,6 @@ cabal-version: 1.24 Name: reflex-dom-Version: 0.6.1.1+Version: 0.6.2.0 Synopsis: Functional Reactive Web Apps with Reflex Description:   Web applications without callbacks or side-effects.@@ -61,7 +61,7 @@     hs-source-dirs: src-android     other-modules: Reflex.Dom.Android.MainWidget     build-depends:-      aeson >= 1.4 && < 1.6,+      aeson >= 1.4 && < 2.2,       android-activity == 0.1.*,       data-default == 0.7.*,       jsaddle >= 0.9.6 && < 0.10@@ -73,8 +73,8 @@   build-depends:     base >= 4.7 && < 4.15,     bytestring == 0.10.*,-    reflex >= 0.8 && < 0.9,-    reflex-dom-core >= 0.6.1.0 && <0.7,+    reflex >= 0.8 && < 1,+    reflex-dom-core >= 0.6.1.0 && <0.9,     text == 1.2.*   if !impl(ghcjs)     if flag(use-warp)@@ -104,6 +104,7 @@   exposed-modules:     Reflex.Dom     Reflex.Dom.Internal+    Reflex.Dom.Location.Platform   reexported-modules:       Foreign.JavaScript.Orphans     , Foreign.JavaScript.TH
src-android/Reflex/Dom/Android/MainWidget.hsc view
@@ -2,11 +2,15 @@ {-# LANGUAGE OverloadedStrings #-} module Reflex.Dom.Android.MainWidget   ( startMainWidget+  , goBack+  , JSExecutor(..)+  , withGlobalJSExecutor   ) where  import Android.HaskellActivity import Control.Concurrent import Control.Monad+import Control.Monad.IO.Class import Data.Aeson import Data.ByteString (ByteString) import qualified Data.ByteString as BS@@ -23,10 +27,10 @@ import Language.Javascript.JSaddle (JSM) import Language.Javascript.JSaddle.Run (runJavaScript) import Language.Javascript.JSaddle.Run.Files (initState, runBatch, ghcjsHelpers)+import System.IO.Unsafe  #include "MainWidget.h" - startMainWidget :: HaskellActivity -> ByteString -> JSM () -> IO () startMainWidget a url jsm = do   --TODO: Find a way to eventually release this@@ -57,13 +61,27 @@         \jsaddle.postReady();\n"     }   BS.useAsCString url $ \curl -> do-    writeIORef executorRef =<< startMainWidget_ a curl callbacks+    executor <- startMainWidget_ a curl callbacks+    writeIORef executorRef executor+    writeIORef globalJSExecutor $ Just executor  newtype JSExecutor = JSExecutor { unJSExecutor :: Ptr JSExecutor } +-- Ugh. But not doing this is also unfortunate for being able to clear the history so that the "back" list is good.+globalJSExecutor :: IORef (Maybe JSExecutor)+globalJSExecutor = unsafePerformIO $ newIORef Nothing++withGlobalJSExecutor :: MonadIO m => (JSExecutor -> IO ()) -> m ()+withGlobalJSExecutor f = liftIO $ do+  executor <- readIORef globalJSExecutor+  case executor of+    Just e -> f e+    _ -> pure ()+ foreign import ccall safe "Reflex_Dom_Android_MainWidget_start" startMainWidget_ :: HaskellActivity -> CString -> Ptr JSaddleCallbacksPtrs -> IO JSExecutor  foreign import ccall safe "Reflex_Dom_Android_MainWidget_runJS" runJS :: JSExecutor -> CString -> CSize -> IO ()+foreign import ccall safe "Reflex_Dom_Android_MainWidget_back" goBack :: JSExecutor -> IO ()  data JSaddleCallbacks = JSaddleCallbacks   { _jsaddleCallbacks_jsaddleStart :: IO ()
src/Reflex/Dom/Internal.hs view
@@ -38,6 +38,7 @@   port <- maybe 3003 read <$> lookupEnv "JSADDLE_WARP_PORT"   putStrLn $ "Running jsaddle-warp server on port " <> show port   JW.run port jsm+ #elif defined(MIN_VERSION_jsaddle_wkwebview) #if defined(ios_HOST_OS) import Data.Default@@ -56,18 +57,24 @@       return ""     Just p -> return $ "file://" <> p <> "/index.html"   run' def $ jsaddleMainHTMLWithBaseURL indexHtml baseUrl jsm+ #else import Language.Javascript.JSaddle.WKWebView (run) #endif #elif defined(ANDROID) import Android.HaskellActivity import Control.Monad+import Control.Monad.IO.Class (liftIO, MonadIO) import Control.Concurrent+import Language.Javascript.JSaddle (JSM) import Data.Default+import Data.IORef+import Data.Maybe import Data.String import Reflex.Dom.Android.MainWidget import System.IO-import Language.Javascript.JSaddle (JSM)+import System.IO.Unsafe+import Language.Javascript.JSaddle (JSM, eval)  run :: JSM () -> IO () run jsm = do@@ -76,17 +83,24 @@   continueWithCallbacks $ def     { _activityCallbacks_onCreate = \_ -> do         a <- getHaskellActivity-        let startPage = fromString "file:///android_asset/index.html"+        let startPage = fromString "https://appassets.androidplatform.net/index.html"         startMainWidget a startPage jsm+    , _activityCallbacks_onBackPressed = triggerBackButton     }   forever $ threadDelay 1000000000++triggerBackButton :: MonadIO m => m ()+triggerBackButton = withGlobalJSExecutor goBack+ #elif defined(wasm32_HOST_ARCH) import qualified Language.Javascript.JSaddle.Wasm as Wasm (run) import Language.Javascript.JSaddle (JSM) run :: JSM () -> IO () run = Wasm.run 0+ #else import Language.Javascript.JSaddle.WebKitGTK (run)+ #endif  mainWidget :: (forall x. Widget x ()) -> IO ()
+ src/Reflex/Dom/Location/Platform.hs view
@@ -0,0 +1,20 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE FlexibleContexts #-}+#if defined(ANDROID)+module Reflex.Dom.Location.Platform where++import Reflex+import Control.Monad.IO.Class+import Reflex.Dom.Android.MainWidget++popHistoryState+  :: (PerformEvent t m, MonadIO (Performable m))+  => Event t ()+  -> m ()+popHistoryState evt = performEvent_ $ withGlobalJSExecutor goBack <$ evt+#else+module Reflex.Dom.Location.Platform (Reflex.Dom.Location.popHistoryState) where+import qualified Reflex.Dom.Location++#endif+