-----------------------------------------------------------------------------
-- |
-- Module      :  Miso.Diff
-- Copyright   :  (C) 2016-2018 David M. Johnson
-- License     :  BSD3-style (see the file LICENSE)
-- Maintainer  :  David M. Johnson <djohnson.m@gmail.com>
-- Stability   :  experimental
-- Portability :  non-portable
----------------------------------------------------------------------------
module Miso.Diff ( diff
                 , mountElement
                 ) where

import GHCJS.Foreign.Internal     hiding (Object)
import GHCJS.Types
import JavaScript.Object.Internal
import Miso.Html.Types
import Miso.FFI
import Miso.String

-- | Entry point for diffing / patching algorithm
diff :: Maybe MisoString -> Maybe VTree -> Maybe VTree -> JSM ()
diff :: Maybe MisoString -> Maybe VTree -> Maybe VTree -> JSM ()
diff Maybe MisoString
mayElem Maybe VTree
current Maybe VTree
new =
  case Maybe MisoString
mayElem of
    Maybe MisoString
Nothing -> do
      JSVal
body <- JSM JSVal
getBody
      JSVal -> Maybe VTree -> Maybe VTree -> JSM ()
diffElement JSVal
body Maybe VTree
current Maybe VTree
new
    Just MisoString
elemId -> do
      JSVal
e <- MisoString -> JSM JSVal
getElementById MisoString
elemId
      JSVal -> Maybe VTree -> Maybe VTree -> JSM ()
diffElement JSVal
e Maybe VTree
current Maybe VTree
new

-- | diffing / patching a given element
diffElement :: JSVal -> Maybe VTree -> Maybe VTree -> JSM ()
diffElement :: JSVal -> Maybe VTree -> Maybe VTree -> JSM ()
diffElement JSVal
mountEl Maybe VTree
current Maybe VTree
new = do
  JSVal
doc <- JSM JSVal
getDoc
  case (Maybe VTree
current, Maybe VTree
new) of
    (Maybe VTree
Nothing, Maybe VTree
Nothing) -> () -> JSM ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
    (Just (VTree Object
current'), Just (VTree Object
new')) -> do
      Object -> Object -> JSVal -> JSVal -> JSM ()
diff' Object
current' Object
new' JSVal
mountEl JSVal
doc
    (Maybe VTree
Nothing, Just (VTree Object
new')) -> do
      Object -> Object -> JSVal -> JSVal -> JSM ()
diff' (JSVal -> Object
Object JSVal
jsNull) Object
new' JSVal
mountEl JSVal
doc
    (Just (VTree Object
current'), Maybe VTree
Nothing) -> do
      Object -> Object -> JSVal -> JSVal -> JSM ()
diff' Object
current' (JSVal -> Object
Object JSVal
jsNull) JSVal
mountEl JSVal
doc

-- | return the configured mountPoint element or the body
mountElement :: Maybe MisoString -> JSM JSVal
mountElement :: Maybe MisoString -> JSM JSVal
mountElement Maybe MisoString
mayMp =
  case Maybe MisoString
mayMp of
    Maybe MisoString
Nothing -> JSM JSVal
getBody
    Just MisoString
eid -> MisoString -> JSM JSVal
getElementById MisoString
eid