packages feed

reflex-dom 0.4 → 0.6.3.4

raw patch · 12 files changed

Files

+ ChangeLog.md view
@@ -0,0 +1,84 @@+# Revision history for reflex-dom++## 0.6.3.4++* Fix WASM related issues++## 0.6.3.3++* Support GHC 9.12++## 0.6.3.2-r1++* Require reflex-dom-core >= 0.8.1.0++## 0.6.3.2++* Build with GHC 9.10++## 0.6.3.1-r1++* Require reflex-dom-core >= 0.8.1.0++## 0.6.3.1++* Don't depend on webkit2gtk on android++## 0.6.3.0++* Use android-activity 0.2+* Fix bug in android back button handler++## 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++## 0.6.1.0-r1++* Loosen reflex-dom-core version bounds++## 0.6.1.0++* Update for new dependent-map and dependent-sum (after the "some" package split)++## 0.6.0.0++* ([#379](https://github.com/reflex-frp/reflex-dom/pull/379)) Re-export all modules from `reflex-dom-core`. The newly re-exported modules are:+    * `Foreign.JavaScript.Utils`+    * `Reflex.Dom.Builder.Hydratable`+    * `Reflex.Dom.Modals.Class`+    * `Reflex.Dom.Prerender`+    * `Reflex.Dom.Time`+    * `Reflex.Dom.WebSocket.Query`+    * `Reflex.Dom.Xhr.FormData`+* ([#366](https://github.com/reflex-frp/reflex-dom/pull/366)) Bump bounds for `reflex` to include 0.7.++## 0.5.3++* On Android, enable prompting the user for geolocation+  permissions on demand by default. See+  https://developer.android.com/reference/android/webkit/WebChromeClient.html#onGeolocationPermissionsShowPrompt(java.lang.String,%20android.webkit.GeolocationPermissions.Callback)+  for details.++ * Add `< 0.7` upper bound for reflex++## 0.5.2++* The default jsaddle backend on macOS when built from nix+  is now jsaddle-wkwebview, matching the behaviour of cabal+  builds.++## 0.5++* Re-export new hydration widget "mainWidget" functions.++* The use-warp flag now properly takes precedence on macOS.
LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2015, Obsidian Systems LLC+Copyright (c) 2020, Obsidian Systems LLC All rights reserved.  Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
benchmark.hs view
@@ -15,8 +15,9 @@ import Reflex.Dom import System.Random import qualified Data.Map as Map-import Data.Dependent.Map (DMap (..), DSum (..))+import Data.Dependent.Map (DMap (..)) import qualified Data.Dependent.Map as DMap+import Data.Dependent.Sum (DSum (..)) import Data.Functor.Misc import Data.Functor.Identity import Data.Functor.Compose
benchmarks/krausest.hs view
@@ -28,15 +28,15 @@   seed <- randomIO   mainWidgetWithHead' (\_ -> headW, \_ -> bodyW seed) -titleW :: MonadWidget t m => m ()+titleW :: DomBuilder t m => m () titleW = text "Reflex-dom keyed" -headW :: MonadWidget t m => m ()+headW :: DomBuilder t m => m () headW = do   el "title" titleW   elAttr "link" ("href" =: "/css/currentStyle.css" <> "rel" =: "stylesheet") blank -bodyW :: forall t m. MonadWidget t m => Entropy -> m ()+bodyW :: forall t m. (MonadFix m, MonadHold t m, DomBuilder t m) => Entropy -> m () bodyW seed = divClass "main" $ divClass "container" $ mdo   buttonEvents <- divClass "jumbotron" $ divClass "row" $ do     divClass "col-md-6" $ el "h1" titleW@@ -75,14 +75,14 @@     (m', dt) = f (m, t)     t' = applyAlways dt t -buttonW :: MonadWidget t m => Text -> Text -> a -> m (Event t a)+buttonW :: DomBuilder t m => Text -> Text -> a -> m (Event t a) buttonW id txt val = divClass "col-sm-6 smallpad" $ buttonW' ("class" =: "btn btn-primary btn-block" <> "id" =: id)   where     buttonW' attrs = do       (b, _) <- elAttr' "button" attrs $ text txt       pure $ val <$ domEvent Click b -tableW :: MonadWidget t m => Event t TableDiff -> m (Event t (IntMap Step))+tableW :: (MonadHold t m, DomBuilder t m) => Event t TableDiff -> m (Event t (IntMap Step)) tableW diff = do   elClass "table" "table table-hover table-striped test-data" $ do     el "tbody" $ do@@ -90,7 +90,7 @@       rowEvents <- holdIncremental v0 v'       return $ mergeIntIncremental rowEvents -rowW :: MonadWidget t m => Row -> m (Event t Step)+rowW :: DomBuilder t m => Row -> m (Event t Step) rowW row = elClass "tr" (if selected row then "danger" else "") $   do     elClass "td" "col-md-1" $ do@@ -102,7 +102,7 @@   where     tagClick f el = f row <$ (domEvent Click el) -deleteW :: MonadWidget t m => m ()+deleteW :: DomBuilder t m => m () deleteW = el "a" $ elAttr "span" ("aria-hidden" =: "true" <> "class" =: "glyphicon glyphicon-remove") blank  
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))();
examples/sortableList.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE OverloadedStrings #-}@@ -5,21 +6,22 @@ {-# LANGUAGE RecursiveDo #-} {-# LANGUAGE ScopedTypeVariables #-} import Control.Lens-import Control.Monad.Identity+import Control.Monad.Fix import Control.Monad.IO.Class-import Data.Dependent.Map (DMap)-import Data.Functor.Constant-import Data.Functor.Misc import Data.List import Data.Map (Map) import qualified Data.Map as Map-import Data.Monoid import Data.Ord+import Data.Patch.MapWithMove import qualified Data.Text as T import Data.Time.Clock import Reflex.Dom import System.Random +#if defined(wasm32_HOST_ARCH)+foreign export javascript "hs_start" main :: IO ()+#endif+ main :: IO () main = mainWidget $ do   let f _ (a, b, c) = el "tr" $ do@@ -71,7 +73,7 @@ simpleSortableList f m0 resortFunc resortSlowFunc = do   rec let resortPatchFast = attachWith (flip patchThatSortsMapWith) (currentIncremental m) resortFunc           redrawPatch :: Map k v -> (v -> v -> Ordering) -> PatchMapWithMove k v-          redrawPatch d cmp = unsafePatchMapWithMove $ fmap (MapEdit_Insert False) $ Map.fromList $ zip (Map.keys d) (sortBy cmp $ Map.elems d)+          redrawPatch d cmp = patchMapWithMoveInsertAll $ Map.fromList $ zip (Map.keys d) (sortBy cmp $ Map.elems d)           resortPatchSlow = attachWith redrawPatch (currentIncremental m) resortSlowFunc           resortPatch = leftmost             [ resortPatchFast
java/org/reflexfrp/reflexdom/MainWidget.java view
@@ -8,6 +8,7 @@ import android.view.ViewGroup.LayoutParams; import android.view.Window; import android.webkit.CookieManager;+import android.webkit.GeolocationPermissions; import android.webkit.JavascriptInterface; import android.webkit.MimeTypeMap; import android.webkit.PermissionRequest;@@ -22,6 +23,7 @@ import java.io.InputStream; import android.content.Intent; import android.content.ActivityNotFoundException;+import java.util.concurrent.atomic.AtomicBoolean;  import java.nio.charset.StandardCharsets; @@ -39,24 +41,29 @@     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     wv.getSettings().setMediaPlaybackRequiresUserGesture(false);+    final AtomicBoolean jsaddleLoaded = new AtomicBoolean(false);      wv.setWebViewClient(new WebViewClient() {         @Override         public void onPageFinished(WebView _view, String _url) {-          wv.evaluateJavascript(initialJS, null);+          Log.i("reflex", "onPageFinished");+          boolean alreadyLoaded = jsaddleLoaded.getAndSet(true);+          if(!alreadyLoaded) {+            Log.i("reflex", "loading jsaddle");+            wv.evaluateJavascript(initialJS, null);+          }         }          // Re-route / to /android_asset         @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();@@ -79,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)));                 }@@ -115,6 +122,11 @@         public Bitmap getDefaultVideoPoster() {             return Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888);         }++        @Override+        public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {+            callback.invoke(origin, true, false);+        }     });      wv.addJavascriptInterface(new JSaddleCallbacks(jsaddleCallbacks), "jsaddle");@@ -131,6 +143,16 @@               wv.evaluateJavascript(jsStr, null);             }           });+      }+      public final void goBack() {+        hnd.post(new Runnable() {+          @Override+	  public void run() {+            if(wv.canGoBack()) {+              wv.goBack();+            }+	  }+	});       }     };   }
reflex-dom.cabal view
@@ -1,10 +1,20 @@+cabal-version: 1.24 Name: reflex-dom-Version: 0.4+Version: 0.6.3.4 Synopsis: Functional Reactive Web Apps with Reflex Description:-  Reflex-DOM is a Functional Reactive web framework based on the Reflex FRP engine.+  Web applications without callbacks or side-effects.+  Reflex-DOM brings the power of functional reactive programming (FRP) to the web.+  Build HTML and other Document Object Model (DOM) data with a pure functional interface.   .-  For hackage documentation, please see: <https://hackage.haskell.org/package/reflex-dom-core>.+  Reflex-DOM is a Functional Reactive web framework based on the Reflex FRP engine: <https://reflex-frp.org/>.+  .+  The @reflex-dom@ package is a small wrapper around the @reflex-dom-core@ package. It pulls in the+  correct set of dependencies for each target platform (GHCJS, WebKitGTK, WASM, mobile, etc.).+  Libraries should depend on @reflex-dom-core@ and executables will usually depend on @reflex-dom@.+  All of @reflex-dom-core@'s modules are re-exported by @reflex-dom@.+  .+  For Hackage documentation, please see: <https://hackage.haskell.org/package/reflex-dom-core>. License: BSD3 License-file: LICENSE Author: Ryan Trinkle@@ -12,8 +22,9 @@ Stability: Experimental Category: FRP, Web, GUI, HTML, Javascript, Reactive, Reactivity, User Interfaces, User-interface Build-type: Simple-cabal-version: >=1.24-extra-source-files: java/org/reflexfrp/reflexdom/MainWidget.java+extra-source-files:+  java/org/reflexfrp/reflexdom/MainWidget.java+  ChangeLog.md  flag use-warp   description: Use jsaddle-warp server@@ -39,60 +50,59 @@   default: False   manual: True -flag android-  description: Build an Android app-  default: False-  manual: True- library   hs-source-dirs: src-  if flag(android)+  if os(android)     hs-source-dirs: src-android     other-modules: Reflex.Dom.Android.MainWidget     build-depends:-      aeson,-      android-activity == 0.1.*,-      data-default == 0.7.*,-      jsaddle+      aeson >= 1.4 && < 2.3,+      android-activity == 0.2.*,+      data-default >= 0.7 && < 0.9,+      jsaddle >= 0.9.6 && < 0.10     c-sources: cbits/MainWidget.c     include-dirs: cbits/include     install-includes: MainWidget.h     cpp-options: -DANDROID     build-tools: hsc2hs   build-depends:-    base >= 4.7 && < 4.12,-    bytestring == 0.10.*,-    reflex == 0.5.*,-    reflex-dom-core >=0.4 && <0.5,-    text == 1.2.*+    base >= 4.7 && < 4.22,+    bytestring >= 0.10 && < 0.13,+    reflex >= 0.8 && < 1,+    reflex-dom-core >= 0.8.1.0 && <0.9,+    text >= 1.2 && < 2.2   if !impl(ghcjs)-    if os(osx) || os(ios)+    if flag(use-warp)       build-depends:-        data-default == 0.7.*,-        jsaddle,-        jsaddle-wkwebview+        jsaddle >= 0.9.6 && < 0.10,+        jsaddle-warp >= 0.9.6 && < 0.10     else-      if flag(use-warp)+      if os(osx) || os(ios)         build-depends:-          jsaddle,-          jsaddle-warp+          data-default >= 0.7 && < 0.9,+          jsaddle >= 0.9.6 && < 0.10,+          jsaddle-wkwebview >= 0.9.6 && < 0.10       else-        if flag(webkit2gtk)+        if arch(wasm32)           build-depends:-            jsaddle-webkit2gtk+            jsaddle >= 0.9.6 && < 0.10,+            jsaddle-wasm >= 0.1 && < 0.2         else-          if !flag(android)+          if flag(webkit2gtk) && !os(android)             build-depends:-              jsaddle-webkit2gtk+              jsaddle-webkit2gtk >= 0.9.6 && < 0.10    exposed-modules:     Reflex.Dom     Reflex.Dom.Internal+    Reflex.Dom.Location.Platform   reexported-modules:-      Foreign.JavaScript.TH-    , Foreign.JavaScript.Orphans+      Foreign.JavaScript.Orphans+    , Foreign.JavaScript.TH+    , Foreign.JavaScript.Utils     , Reflex.Dom.Builder.Class     , Reflex.Dom.Builder.Class.Events+    , Reflex.Dom.Builder.Hydratable     , Reflex.Dom.Builder.Immediate     , Reflex.Dom.Builder.InputDisabled     , Reflex.Dom.Builder.Static@@ -100,15 +110,21 @@     , Reflex.Dom.Core     , Reflex.Dom.Location     , Reflex.Dom.Main+    , Reflex.Dom.Modals.Class     , Reflex.Dom.Old+    , Reflex.Dom.Prerender+    , Reflex.Dom.Time     , Reflex.Dom.WebSocket+    , Reflex.Dom.WebSocket.Query     , Reflex.Dom.Widget     , Reflex.Dom.Widget.Basic     , Reflex.Dom.Widget.Input     , Reflex.Dom.Widget.Lazy     , Reflex.Dom.Widget.Resize     , Reflex.Dom.Xhr-  ghc-options: -Wall -fwarn-tabs -funbox-strict-fields -O2 -ferror-spans+    , Reflex.Dom.Xhr.FormData+  ghc-options: -Wall -fwarn-tabs -funbox-strict-fields -O2 -ferror-spans -fPIC+  cc-options: -fPIC   if flag(expose-all-unfoldings)     ghc-options: -fexpose-all-unfoldings   if flag(use-reflex-optimizer)@@ -121,6 +137,7 @@                , dependent-map                , lens                , mtl+               , patch                , random                , reflex                , reflex-dom@@ -137,9 +154,23 @@   if flag(use-reflex-optimizer)     ghc-options: -fplugin=Reflex.Optimizer   default-language: Haskell2010+  if arch(wasm32)+    ghc-options: -no-hs-main -optl-mexec-model=reactor "-optl-Wl,--export=hs_start"  executable benchmark-  build-depends: base, reflex, reflex-dom, text, prim-uniq, dependent-map, containers, transformers, mtl, ghcjs-dom, ghc-prim, random, dependent-sum+  build-depends: base+               , containers+               , dependent-map+               , dependent-sum+               , ghc-prim+               , ghcjs-dom+               , mtl+               , prim-uniq+               , random+               , reflex+               , reflex-dom+               , text+               , transformers   hs-source-dirs: .   main-is: benchmark.hs   ghc-options: -O2 -fspecialise-aggressively@@ -148,7 +179,20 @@   default-language: Haskell2010  executable krausest-  build-depends: base, reflex, reflex-dom, text, prim-uniq, dependent-map, containers, transformers, mtl, ghcjs-dom, ghc-prim, random, dependent-sum, vector+  build-depends: base+               , containers+               , dependent-map+               , dependent-sum+               , ghc-prim+               , ghcjs-dom+               , mtl+               , prim-uniq+               , random+               , reflex+               , reflex-dom+               , text+               , transformers+               , vector   hs-source-dirs: benchmarks   main-is: krausest.hs   ghc-options: -O2 -fspecialise-aggressively
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.hs view
@@ -6,5 +6,6 @@  import Foreign.JavaScript.Orphans () import Reflex.Dom.Core as X hiding (mainWidget, mainWidgetInElementById, mainWidgetWithCss,-                             mainWidgetWithHead, mainWidgetWithHead', runApp')+                             mainWidgetWithHead, mainWidgetWithHead', runApp',+                             mainHydrationWidgetWithHead, mainHydrationWidgetWithHead') import Reflex.Dom.Internal as X
src/Reflex/Dom/Internal.hs view
@@ -4,25 +4,28 @@ {-# LANGUAGE RankNTypes #-} {-# LANGUAGE TypeFamilies #-} module Reflex.Dom.Internal-       (module Main, run, mainWidget, mainWidgetWithHead, mainWidgetWithCss,-        mainWidgetWithHead', mainWidgetInElementById, runApp') where+  ( module Main+  , run+  , mainWidget+  , mainWidgetWithHead, mainWidgetWithCss, mainWidgetWithHead', mainWidgetInElementById, runApp'+  , mainHydrationWidgetWithHead, mainHydrationWidgetWithHead'+  ) where  import Data.ByteString (ByteString) import Data.Text (Text)-import Reflex.Dom.Core (Widget) import Reflex.Dom.Main as Main hiding        (mainWidget, mainWidgetWithHead, mainWidgetWithCss,-        mainWidgetWithHead', mainWidgetInElementById, runApp')+        mainWidgetWithHead', mainWidgetInElementById, runApp',+        mainHydrationWidgetWithHead, mainHydrationWidgetWithHead') import qualified Reflex.Dom.Main as Main        (mainWidget, mainWidgetWithHead, mainWidgetWithCss,-        mainWidgetWithHead', mainWidgetInElementById, runApp')+        mainWidgetWithHead', mainWidgetInElementById, runApp',+        mainHydrationWidgetWithHead, mainHydrationWidgetWithHead')  #if defined(ghcjs_HOST_OS) run :: a -> a run = id #elif defined(MIN_VERSION_jsaddle_warp)-import Data.Maybe (maybe)-import Data.Monoid ((<>)) import Language.Javascript.JSaddle (JSM) import qualified Language.Javascript.JSaddle.Warp as JW import System.Environment (lookupEnv)@@ -32,6 +35,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@@ -50,18 +54,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@@ -70,12 +80,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+ #else import Language.Javascript.JSaddle.WebKitGTK (run)+ #endif  mainWidget :: (forall x. Widget x ()) -> IO ()@@ -101,3 +123,11 @@ runApp' :: (forall x. AppInput DomTimeline -> Widget x (AppOutput DomTimeline)) -> IO () runApp' app = run $ Main.runApp' app {-# INLINE runApp' #-}++mainHydrationWidgetWithHead :: (forall x. HydrationWidget x ()) -> (forall x. HydrationWidget x ()) -> IO ()+mainHydrationWidgetWithHead h b = run $ Main.mainHydrationWidgetWithHead h b+{-# INLINE mainHydrationWidgetWithHead #-}++mainHydrationWidgetWithHead' :: HydrationWidget () () -> HydrationWidget () () -> IO ()+mainHydrationWidgetWithHead' h b = run $ Main.mainHydrationWidgetWithHead' h b+{-# INLINE mainHydrationWidgetWithHead' #-}
+ 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+