packages feed

miso 1.4.0.0 → 1.5.0.0

raw patch · 16 files changed

+230/−79 lines, 16 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Miso.String: class FromMisoString t
+ Miso.String: fromMisoStringEither :: FromMisoString t => MisoString -> Either String t
+ Miso.String: instance Miso.String.FromMisoString Data.ByteString.Internal.ByteString
+ Miso.String: instance Miso.String.FromMisoString Data.ByteString.Lazy.Internal.ByteString
+ Miso.String: instance Miso.String.FromMisoString Data.Text.Internal.Lazy.Text
+ Miso.String: instance Miso.String.FromMisoString GHC.Base.String
+ Miso.String: instance Miso.String.FromMisoString GHC.Types.Double
+ Miso.String: instance Miso.String.FromMisoString GHC.Types.Float
+ Miso.String: instance Miso.String.FromMisoString GHC.Types.Int
+ Miso.String: instance Miso.String.FromMisoString GHC.Types.Word
+ Miso.String: instance Miso.String.FromMisoString Miso.String.MisoString
- Miso.String: fromMisoString :: ToMisoString str => MisoString -> str
+ Miso.String: fromMisoString :: FromMisoString a => MisoString -> a

Files

README.md view
@@ -372,7 +372,7 @@  The easiest way to build the examples is with the [`nix`](https://nixos.org/nix/) package manager ```-git clone https://github.com/dmjio/miso && cd miso && nix-build -A miso-ghcjs+git clone https://github.com/dmjio/miso && cd miso && nix-build --arg examples true ```  This will build all examples and documentation into a folder named `result`@@ -450,6 +450,7 @@ ## Commercial Users   - [Polimorphic](https://www.polimorphic.com)   - [LumiGuide](https://lumi.guide/en/)+  - [Clovyr](https://clovyr.io)  ## Contributing 
frontend-src/Miso.hs view
@@ -129,7 +129,7 @@         loop newModel   loop m --- | Runs an isomorphic miso application+-- | Runs an isomorphic miso application. -- Assumes the pre-rendered DOM is already present miso :: Eq model => (URI -> App model action) -> JSM () miso f = do
frontend-src/Miso/Effect.hs view
@@ -6,6 +6,9 @@ -- Maintainer  :  David M. Johnson <djohnson.m@gmail.com> -- Stability   :  experimental -- Portability :  non-portable+--+-- This module defines `Effect` and `Sub` types, which are used to define+-- `Miso.Types.update` function and `Miso.Types.subs` field of the `Miso.Types.App`. ---------------------------------------------------------------------------- module Miso.Effect (   module Miso.Effect.Storage@@ -37,10 +40,10 @@ -- | Type synonym for constructing event subscriptions. -- -- The 'Sink' callback is used to dispatch actions which are then fed--- back to the 'update' function.+-- back to the 'Miso.Types.update' function. type Sub action = Sink action -> JSM () --- | Function to asynchronously dispatch actions to the 'update' function.+-- | Function to asynchronously dispatch actions to the 'Miso.Types.update' function. type Sink action = action -> IO ()  -- | Turn a subscription that consumes actions of type @a@ into a subscription@@ -77,7 +80,7 @@ (#>) :: JSM action -> model -> Effect action model (#>) = flip (<#) --- | `Smart constructor for an 'Effect' with multiple actions.+-- | Smart constructor for an 'Effect' with multiple actions. batchEff :: model -> [JSM action] -> Effect action model batchEff model actions = Effect model $   map (\a sink -> liftIO . sink =<< a) actions
frontend-src/Miso/Effect/Storage.hs view
@@ -54,7 +54,7 @@         Success x -> Right x         Error y -> Left y --- | Retrieve session storage+-- | Retrieve a value stored under given key in session storage getSessionStorage :: FromJSON model => JSString -> JSM (Either String model) getSessionStorage =   getStorageCommon $ \t -> do@@ -62,7 +62,7 @@     r <- Storage.getItem s t     fromJSVal r --- | Retrieve local storage+-- | Retrieve a value stored under given key in local storage getLocalStorage :: FromJSON model => JSString -> JSM (Either String model) getLocalStorage = getStorageCommon $ \t -> do     s <- Storage.localStorage
frontend-src/Miso/String.hs view
@@ -16,6 +16,8 @@ ---------------------------------------------------------------------------- module Miso.String (     ToMisoString (..)+  , FromMisoString (..)+  , fromMisoString   , MisoString   , module Data.JSString   , module Data.Monoid@@ -24,9 +26,12 @@  #ifndef JSADDLE import           Data.Aeson+import           Data.Char+ #endif import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as BL+import           Data.Char import           Data.JSString import           Data.JSString.Text import           Data.Monoid@@ -34,13 +39,15 @@ import qualified Data.Text.Encoding as T import qualified Data.Text.Lazy as LT import qualified Data.Text.Lazy.Encoding as LT-+import           Prelude hiding (foldr) import           Miso.FFI  -- | String type swappable based on compiler type MisoString = JSString  #ifndef JSADDLE++ -- | `ToJSON` for `MisoString` instance ToJSON MisoString where   toJSON = String . textFromJSString@@ -55,39 +62,80 @@ -- | Convenience class for creating `MisoString` from other string-like types class ToMisoString str where   toMisoString :: str -> MisoString-  fromMisoString :: MisoString -> str +class FromMisoString t where+  -- -- | Reads a `MisoString` into an 'a', throws an error when+  fromMisoStringEither :: MisoString -> Either String t++-- | Reads a `MisoString` into an 'a', throws an error when decoding+-- fails. Use `fromMisoStringEither` for as a safe alternative.+fromMisoString :: FromMisoString a => MisoString -> a+fromMisoString s = case fromMisoStringEither s of+                     Left err -> error err+                     Right x  -> x+ -- | Convenience function, shorthand for `toMisoString` ms :: ToMisoString str => str -> MisoString ms = toMisoString  instance ToMisoString MisoString where   toMisoString = id-  fromMisoString = id instance ToMisoString String where   toMisoString = pack-  fromMisoString = unpack instance ToMisoString T.Text where   toMisoString = textToJSString-  fromMisoString = textFromJSString instance ToMisoString LT.Text where   toMisoString = lazyTextToJSString-  fromMisoString = lazyTextFromJSString instance ToMisoString B.ByteString where   toMisoString = toMisoString . T.decodeUtf8-  fromMisoString = T.encodeUtf8 . fromMisoString instance ToMisoString BL.ByteString where   toMisoString = toMisoString . LT.decodeUtf8-  fromMisoString = LT.encodeUtf8 . fromMisoString instance ToMisoString Float where   toMisoString = realFloatToJSString-  fromMisoString = realToFrac . jsStringToDouble instance ToMisoString Double where   toMisoString = realFloatToJSString-  fromMisoString = jsStringToDouble instance ToMisoString Int where   toMisoString = integralToJSString-  fromMisoString = round . jsStringToDouble instance ToMisoString Word where   toMisoString = integralToJSString-  fromMisoString = round . jsStringToDouble++instance FromMisoString MisoString where+  fromMisoStringEither = Right+instance FromMisoString String where+  fromMisoStringEither = Right . unpack+instance FromMisoString T.Text where+  fromMisoStringEither = Right . textFromJSString+instance FromMisoString LT.Text where+  fromMisoStringEither = Right . lazyTextFromJSString+instance FromMisoString B.ByteString where+  fromMisoStringEither = fmap T.encodeUtf8 . fromMisoStringEither+instance FromMisoString BL.ByteString where+  fromMisoStringEither = fmap LT.encodeUtf8 . fromMisoStringEither+instance FromMisoString Float where+  fromMisoStringEither = fmap realToFrac . jsStringToDoubleEither+instance FromMisoString Double where+  fromMisoStringEither = jsStringToDoubleEither+instance FromMisoString Int where+  fromMisoStringEither = parseInt+instance FromMisoString Word where+  fromMisoStringEither = parseWord++jsStringToDoubleEither :: JSString -> Either String Double+jsStringToDoubleEither s = let d = jsStringToDouble s+                           in if isNaN d then Left "jsStringToDoubleEither: parse failed"+                                         else Right d+++parseWord   :: MisoString -> Either String Word+parseWord s = case uncons s of+                Nothing     -> Left "parseWord: parse error"+                Just (c,s') -> foldl' k (pDigit c) s'+  where+    pDigit c | isDigit c = Right . fromIntegral . digitToInt $ c+             | otherwise = Left "parseWord: parse error"+    k ea c = (\a x -> 10*a + x) <$> ea <*> pDigit c++parseInt   :: MisoString -> Either String Int+parseInt s = case uncons s of+               Just ('-',s') -> ((-1)*) . fromIntegral <$> parseWord s'+               _             ->           fromIntegral <$> parseWord s
frontend-src/Miso/Subscription/WebSocket.hs view
@@ -4,6 +4,7 @@ {-# LANGUAGE RankNTypes                 #-} {-# LANGUAGE LambdaCase                 #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE CPP                        #-} ----------------------------------------------------------------------------- -- | -- Module      :  Miso.Subscription.WebSocket@@ -25,6 +26,7 @@     -- * Subscription   , websocketSub   , send+  , close   , connect   , getSocketState   ) where@@ -36,6 +38,7 @@ import           Data.IORef import           Data.Maybe import           GHCJS.Marshal+import           GHCJS.Foreign import           GHCJS.Types import           Prelude hiding (map) import           System.IO.Unsafe@@ -82,8 +85,18 @@     liftIO . sink $ f (WebSocketClose code clean reason)   WS.addEventListener socket "error" $ \v -> do     liftIO (writeIORef closedCode Nothing)-    d <- parse =<< WS.data' v-    liftIO . sink $ f (WebSocketError d)+    d' <- WS.data' v+#ifndef __GHCJS__        +    undef <- ghcjsPure (isUndefined d')+#else+    let undef = isUndefined d'+#endif+    if undef+      then do+         liftIO . sink $ f (WebSocketError mempty)+      else do+         Just d <- fromJSVal d'+         liftIO . sink $ f (WebSocketError d)   where     handleReconnect = do       liftIO (threadDelay (secs 3))@@ -102,6 +115,13 @@ send x = do   Just socket <- liftIO (readIORef websocket)   sendJson' socket x++-- | Sends message to a websocket server+close :: JSM ()+{-# INLINE close #-}+close =+  mapM_ WS.close =<<+    liftIO (readIORef websocket)  -- | Connects to a websocket server connect :: URL -> Protocols -> JSM ()
frontend-src/Miso/Types.hs view
@@ -40,18 +40,19 @@   { model :: model   -- ^ initial model   , update :: action -> model -> Effect action model-  -- ^ Function to update model, optionally provide effects.+  -- ^ Function to update model, optionally providing effects.   --   See the 'Transition' monad for succinctly expressing model transitions.   , view :: model -> View action   -- ^ Function to draw `View`   , subs :: [ Sub action ]   -- ^ List of subscriptions to run during application lifetime   , events :: M.Map MisoString Bool-  -- ^ List of delegated events that the body element will listen for+  -- ^ List of delegated events that the body element will listen for.+  --   You can start with 'Miso.Event.Types.defaultEvents' and modify as needed.   , initialAction :: action   -- ^ Initial action that is run after the application has loaded   , mountPoint :: Maybe MisoString-  -- ^ root element for DOM diff+  -- ^ Id of the root element for DOM diff. If 'Nothing' is provided, the entire document body is used as a mount point.   }  -- | A monad for succinctly expressing model transitions in the 'update' function.
ghc-src/Miso/String.hs view
@@ -12,6 +12,8 @@ ---------------------------------------------------------------------------- module Miso.String   ( ToMisoString (..)+  , FromMisoString (..)+  , fromMisoString   , MisoString   , module Data.Monoid   , module Data.Text@@ -26,45 +28,65 @@ import qualified Data.Text.Encoding      as T import qualified Data.Text.Lazy          as LT import qualified Data.Text.Lazy.Encoding as LT+import           Text.Read(readEither) + -- | String type swappable based on compiler type MisoString = Text  -- | Convenience class for creating `MisoString` from other string-like types class ToMisoString str where   toMisoString :: str -> MisoString-  fromMisoString :: MisoString -> str +class FromMisoString t where+  -- -- | Reads a `MisoString` into an 'a', throws an error when+  fromMisoStringEither :: MisoString -> Either String t++-- | Reads a `MisoString` into an 'a', throws an error when decoding+-- fails. Use `fromMisoStringEither` for as a safe alternative.+fromMisoString :: FromMisoString a => MisoString -> a+fromMisoString s = case fromMisoStringEither s of+                     Left err -> error err+                     Right x  -> x+ -- | Convenience function, shorthand for `toMisoString` ms :: ToMisoString str => str -> MisoString ms = toMisoString  instance ToMisoString MisoString where   toMisoString = id-  fromMisoString = id instance ToMisoString String where   toMisoString = T.pack-  fromMisoString = T.unpack instance ToMisoString LT.Text where   toMisoString = LT.toStrict-  fromMisoString = LT.fromStrict instance ToMisoString B.ByteString where   toMisoString = toMisoString . T.decodeUtf8-  fromMisoString = T.encodeUtf8 . fromMisoString instance ToMisoString BL.ByteString where   toMisoString = toMisoString . LT.decodeUtf8-  fromMisoString = LT.encodeUtf8 . fromMisoString instance ToMisoString Float where   toMisoString = T.pack . show-  fromMisoString = read . T.unpack instance ToMisoString Double where   toMisoString = T.pack . show-  fromMisoString = read . T.unpack instance ToMisoString Int where   toMisoString = T.pack . show-  -- Replicate frontend behavior-  fromMisoString = round . (read :: String -> Double) . T.unpack instance ToMisoString Word where   toMisoString = T.pack . show-  -- Replicate frontend behavior-  fromMisoString = round . (read :: String -> Double) . T.unpack++instance FromMisoString MisoString where+  fromMisoStringEither = Right+instance FromMisoString String where+  fromMisoStringEither = Right . T.unpack+instance FromMisoString LT.Text where+  fromMisoStringEither = Right . LT.fromStrict+instance FromMisoString B.ByteString where+  fromMisoStringEither = fmap T.encodeUtf8 . fromMisoStringEither+instance FromMisoString BL.ByteString where+  fromMisoStringEither = fmap LT.encodeUtf8 . fromMisoStringEither+instance FromMisoString Float where+  fromMisoStringEither = readEither . T.unpack+instance FromMisoString Double where+  fromMisoStringEither = readEither . T.unpack+instance FromMisoString Int where+  fromMisoStringEither = readEither . T.unpack+instance FromMisoString Word where+  fromMisoStringEither = readEither . T.unpack
ghcjs-ffi/Miso/FFI.hs view
@@ -76,6 +76,7 @@ -- resolves to the `JSM` type defined in `jsaddle`. type JSM = IO +-- | Run given `JSM` action asynchronously, in a separate thread. forkJSM :: JSM () -> JSM () forkJSM a = () <$ forkIO a @@ -88,6 +89,7 @@ ghcjsPure :: a -> JSM a ghcjsPure = pure +-- | Forces execution of pending asyncronous code syncPoint :: JSM () syncPoint = pure () @@ -95,14 +97,20 @@ set :: ToJSVal v => JSString -> v -> OI.Object -> IO () set k v obj = toJSVal v >>= \x -> OI.setProp k x obj --- | Adds event listener to window foreign import javascript unsafe "$1.addEventListener($2, $3);"   addEventListener' :: JSVal -> JSString -> Callback (JSVal -> IO ()) -> IO () -addEventListener :: JSVal -> JSString -> (JSVal -> IO ()) -> IO ()+-- | Register an event listener on given target.+addEventListener :: JSVal            -- ^ Event target on which we want to register event listener+                 -> JSString         -- ^ Type of event to listen to (e.g. "click")+                 -> (JSVal -> IO ()) -- ^ Callback which will be called when the event occurs. The event is passed as a parameter to it.+                 -> IO () addEventListener self name cb = addEventListener' self name =<< asyncCallback1 cb -windowAddEventListener :: JSString -> (JSVal -> IO ()) -> IO ()+-- | Registers an event listener on window+windowAddEventListener :: JSString           -- ^ Type of event to listen to (e.g. "click")+                       -> (JSVal -> IO ())  -- ^ Callback which will be called when the event occurs, the event will be passed to it as a parameter.+                       -> IO () windowAddEventListener name cb = do   win <- getWindow   addEventListener win name cb@@ -119,19 +127,27 @@   getWindow :: IO JSVal  --- | Retrieves inner height+-- | Retrieves the height (in pixels) of the browser window viewport including, if rendered, the horizontal scrollbar.+--+-- See <https://developer.mozilla.org/en-US/docs/Web/API/Window/innerHeight> foreign import javascript unsafe "$r = window['innerHeight'];"   windowInnerHeight :: IO Int --- | Retrieves outer height+-- | Retrieves the width (in pixels) of the browser window viewport including, if rendered, the vertical scrollbar.+--+-- See <https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth> foreign import javascript unsafe "$r = window['innerWidth'];"   windowInnerWidth :: IO Int --- | Retrieve high performance time stamp+-- | Retrieve high resolution time stamp+--+-- See <https://developer.mozilla.org/en-US/docs/Web/API/Performance/now> foreign import javascript unsafe "$r = performance.now();"   now :: IO Double --- | Console-logging+-- | Outputs a message to the web console+--+-- See <https://developer.mozilla.org/en-US/docs/Web/API/Console/log> foreign import javascript unsafe "console.log($1);"   consoleLog :: JSString -> IO () @@ -172,12 +188,21 @@     -> JSVal -- ^ object with impure references to the DOM     -> IO JSVal +-- | Retrieves a reference to the document body.+--+-- See <https://developer.mozilla.org/en-US/docs/Web/API/Document/body> foreign import javascript unsafe "$r = document.body;"   getBody :: IO JSVal +-- | Retrieves a reference to the document.+--+-- See <https://developer.mozilla.org/en-US/docs/Web/API/Document> foreign import javascript unsafe "$r = document;"   getDoc :: IO JSVal +-- | Returns an Element object representing the element whose id property matches the specified string.+--+-- See <https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById> foreign import javascript unsafe "$r = document.getElementById($1);"   getElementById :: JSString -> IO JSVal 
ghcjs-ffi/Miso/FFI/WebSocket.hs view
@@ -16,6 +16,7 @@   , create   , socketState   , send+  , close   , addEventListener   , data'   , wasClean@@ -32,6 +33,9 @@  foreign import javascript unsafe "$r = new WebSocket($1, $2);"   create :: JSString -> JSVal -> IO Socket++foreign import javascript unsafe "$1.close()"+  close :: Socket -> IO ()  foreign import javascript unsafe "$r = $1.readyState;"   socketState :: Socket -> IO Int
jsaddle-ffi/Miso/FFI.hs view
@@ -68,6 +68,7 @@ import qualified JavaScript.Object.Internal as OI import           Language.Javascript.JSaddle hiding (Success, obj, val) +-- | Run given `JSM` action asynchronously, in a separate thread. forkJSM :: JSM () -> JSM () forkJSM a = do   ctx <- askJSM@@ -92,13 +93,19 @@   v' <- toJSVal v   setProp k v' obj -addEventListener :: JSVal -> JSString -> (JSVal -> JSM ()) -> JSM ()+-- | Register an event listener on given target.+addEventListener :: JSVal             -- ^ Event target on which we want to register event listener+                 -> JSString          -- ^ Type of event to listen to (e.g. "click")+                 -> (JSVal -> JSM ()) -- ^ Callback which will be called when the event occurs, the event will be passed to it as a parameter.+                 -> JSM () addEventListener self name cb = do   _ <- self # "addEventListener" $ (name, asyncFunction (\_ _ [a] -> cb a))   pure () --- | Adds event listener to window-windowAddEventListener :: JSString -> (JSVal -> JSM ()) -> JSM ()+-- | Registers an event listener on window+windowAddEventListener :: JSString           -- ^ Type of event to listen to (e.g. "click")+                       -> (JSVal -> JSM ())  -- ^ Callback which will be called when the event occurs, the event will be passed to it as a parameter.+                       -> JSM () windowAddEventListener name cb = do   win <- jsg "window"   addEventListener win name cb@@ -113,21 +120,29 @@   _ <- e # "preventDefault" $ ()   pure () --- | Retrieves inner height+-- | Retrieves the height (in pixels) of the browser window viewport including, if rendered, the horizontal scrollbar.+--+-- See <https://developer.mozilla.org/en-US/docs/Web/API/Window/innerHeight> windowInnerHeight :: JSM Int windowInnerHeight =   fromJSValUnchecked =<< jsg "window" ! "innerHeight" --- | Retrieves outer height+-- | Retrieves the width (in pixels) of the browser window viewport including, if rendered, the vertical scrollbar.+--+-- See <https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth> windowInnerWidth :: JSM Int windowInnerWidth =   fromJSValUnchecked =<< jsg "window" ! "innerWidth" --- | Retrieve high performance time stamp+-- | Retrieve high resolution time stamp+--+-- See <https://developer.mozilla.org/en-US/docs/Web/API/Performance/now> now :: JSM Double now = fromJSValUnchecked =<< (jsg "performance" # "now" $ ()) --- | Console-logging+-- | Outputs a message to the web console+--+-- See <https://developer.mozilla.org/en-US/docs/Web/API/Console/log> consoleLog :: JSString -> JSM () consoleLog v = do   _ <- jsg "console" # "log" $ [toJSString v]@@ -167,12 +182,22 @@     -> JSM JSVal objectToJSON = jsg2 "objectToJSON" +-- | Retrieves a reference to document body.+--+-- See <https://developer.mozilla.org/en-US/docs/Web/API/Document/body> getBody :: JSM JSVal getBody = jsg "document" ! "body" ++-- | Retrieves a reference to the document.+--+-- See <https://developer.mozilla.org/en-US/docs/Web/API/Document> getDoc :: JSM JSVal getDoc = jsg "document" +-- | Returns an Element object representing the element whose id property matches the specified string.+--+-- See <https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById> getElementById :: JSString -> JSM JSVal getElementById e = getDoc # "getElementById" $ [e] 
jsaddle-ffi/Miso/FFI/WebSocket.hs view
@@ -16,6 +16,7 @@   , create   , socketState   , send+  , close   , addEventListener   , data'   , wasClean@@ -42,6 +43,11 @@ send :: Socket -> JSString -> JSM () send (Socket s) msg = do   _ <- s # ("send" :: JSString) $ [msg]+  pure ()++close :: Socket -> JSM ()+close (Socket s) = do+  _ <- s # ("close" :: JSString) $ ([] :: [JSString])   pure ()  addEventListener :: Socket -> JSString -> (JSVal -> JSM ()) -> JSM ()
jsbits/delegate.js view
@@ -44,34 +44,30 @@    /* stack not length 1, recurse */   else if (stack.length > 1) {-    if (obj['domRef'] === stack[0]) parentStack.unshift(obj);+    parentStack.unshift(obj);     for (var o = 0; o < obj.children.length; o++) {-      if (obj.children[o]['type'] === 'vtext') continue;-      delegateEvent ( event-		    , obj.children[o]-		    , stack.slice(1)-		    , parentStack-		    );-     }+      if (obj.children[o]['domRef'] === stack[1]) {+        delegateEvent( event, obj.children[o], stack.slice(1), parentStack );+        break;+      }+    }   }    /* stack.length == 1 */   else {-    if (obj['domRef'] === stack[0]) {       var eventObj = obj['events'][event.type];       if (eventObj) { 	var options = eventObj.options;-      if (options['preventDefault'])-	event.preventDefault();-      eventObj['runEvent'](event);-      if (!options['stopPropagation'])-	window['propogateWhileAble'] (parentStack, event);+        if (options['preventDefault'])+  	  event.preventDefault();+        eventObj['runEvent'](event);+        if (!options['stopPropagation'])+ 	  window['propogateWhileAble'] (parentStack, event);       } else { 	/* still propagate to parent handlers even if event not defined */ 	window['propogateWhileAble'] (parentStack, event);       }-    }-  }+   } };  window['buildTargetToElement'] = function buildTargetToElement (element, target) {@@ -109,15 +105,16 @@   for (var i in at) obj = obj[at[i]];    /* If obj is a list-like object */+  var newObj;   if (obj instanceof Array) {-    var newObj = [];+    newObj = [];     for (var i = 0; i < obj.length; i++)       newObj.push(window['objectToJSON']([], obj[i]));     return newObj;   }    /* If obj is a non-list-like object */-  var newObj = {};+  newObj = {};   for (var i in obj){     /* bug in safari, throws TypeError if the following fields are referenced on a checkbox */     /* https://stackoverflow.com/a/25569117/453261 */
jsbits/diff.js view
@@ -88,7 +88,7 @@ };  window['diffProps'] = function diffProps(cProps, nProps, node, isSvg) {-  var result, newProp;+  var newProp;   /* Is current prop in new prop list? */   for (var c in cProps) {     newProp = nProps[c];@@ -221,12 +221,11 @@        -> [ ] <- new children     */     else if (newFirstIndex > newLastIndex) {-      tmp = oldLastIndex - oldFirstIndex;-      while (tmp >= 0) {-        parent.removeChild(os[oldFirstIndex]['domRef']);-        os.splice(oldFirstIndex, 1);-        tmp--;+      tmp = oldLastIndex;+      while (oldLastIndex >= oldFirstIndex) {+        parent.removeChild(os[oldLastIndex--]['domRef']);       }+      os.splice(oldFirstIndex, tmp - oldFirstIndex + 1);       break;     }     /* happy path, everything aligns, we continue
miso.cabal view
@@ -1,5 +1,5 @@ name:                miso-version:             1.4.0.0+version:             1.5.0.0 category:            Web, Miso, Data Structures license:             BSD3 license-file:        LICENSE
src/Miso/Event/Decoder.hs view
@@ -28,10 +28,10 @@ import Miso.Event.Types import Miso.String --- | Data type for storing the target when parsing events+-- | Data type representing path (consisting of field names) within event object, where a decoder should be applied. data DecodeTarget-  = DecodeTarget [MisoString] -- ^ Decode a single object-  | DecodeTargets [[MisoString]] -- ^ Decode multiple objecjects+  = DecodeTarget [MisoString] -- ^ Specify single path within Event object, where a decoder should be applied.+  | DecodeTargets [[MisoString]] -- ^ Specify multiple paths withing Event object, where decoding should be attempted. The first path where decoding suceeds is the one taken.  -- | Decoder data type for parsing events data Decoder a = Decoder {@@ -39,7 +39,7 @@ , decodeAt :: DecodeTarget -- ^ Location in DOM of where to decode } --- | Smart constructor for building+-- | Smart constructor for building a `Decoder`. at :: [MisoString] -> (Value -> Parser a) -> Decoder a at decodeAt decoder = Decoder {decodeAt = DecodeTarget decodeAt, ..}