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 +2/−1
- frontend-src/Miso.hs +1/−1
- frontend-src/Miso/Effect.hs +6/−3
- frontend-src/Miso/Effect/Storage.hs +2/−2
- frontend-src/Miso/String.hs +60/−12
- frontend-src/Miso/Subscription/WebSocket.hs +22/−2
- frontend-src/Miso/Types.hs +4/−3
- ghc-src/Miso/String.hs +34/−12
- ghcjs-ffi/Miso/FFI.hs +32/−7
- ghcjs-ffi/Miso/FFI/WebSocket.hs +4/−0
- jsaddle-ffi/Miso/FFI.hs +32/−7
- jsaddle-ffi/Miso/FFI/WebSocket.hs +6/−0
- jsbits/delegate.js +15/−18
- jsbits/diff.js +5/−6
- miso.cabal +1/−1
- src/Miso/Event/Decoder.hs +4/−4
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, ..}