Skip to content

Instantly share code, notes, and snippets.

@pauldijou
Last active May 19, 2016 21:50
Show Gist options
  • Save pauldijou/10251ce38646f473d5a689731c68d126 to your computer and use it in GitHub Desktop.
Save pauldijou/10251ce38646f473d5a689731c68d126 to your computer and use it in GitHub Desktop.
elm-dom-diff
import Html.App
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
-- This should be inside a Item.elm file, declaring it's own module
type alias ModelItem = String
type MsgItem = CloseItem
viewItem: ModelItem -> Html MsgItem
viewItem model =
div
[ itemOpenStyle, onClick CloseItem ]
[ text model ]
-- ----------------------------------------------------
-- Here starts the real Main.elm
type alias Model =
{ first: Maybe String
, second: Maybe ModelItem
, third: Maybe ModelItem
}
type ItemId = First | Second | Third
type Msg
= ItemMsg ItemId MsgItem
| Open ItemId
| Close ItemId
model =
{ first = Nothing
, second = Nothing
, third = Nothing
}
main =
Html.App.beginnerProgram
{ model = model
, view = view
, update = update
}
viewFirst first =
div
[ itemOpenStyle, onClick (Close First) ]
[ text first ]
viewSecond second =
Html.App.map (ItemMsg Second) (viewItem second)
view model =
div
[ containerStyle ]
[ h1 [] [ text "elm-dom-diff" ]
, button [ buttonStyle, onClick (Open First) ] [ text "Open first item" ]
, button [ buttonStyle, onClick (Open Second) ] [ text "Open second item" ]
, button [ buttonStyle, onClick (Open Third) ] [ text "Open third item" ]
-- Raw display from Main.elm
, Maybe.withDefault (div [ itemStyle ] []) (Maybe.map viewFirst model.first)
-- Html.map inside Maybe.withDefault
, Maybe.withDefault (div [ itemStyle ] []) (Maybe.map viewSecond model.second)
-- Maybe.withDefault inside Html.map
, Html.App.map (ItemMsg Third) (Maybe.withDefault (div [ itemStyle ] []) (Maybe.map viewItem model.third))
, div [] [ text "(click on item to close it)" ]
]
update msg model =
case msg of
Open First -> { model | first = Just "Here is the first item, with nice CSS opacity transition" }
Close First -> { model | first = Nothing }
Open Second -> { model | second = Just "Here is the second item, without any CSS transition" }
ItemMsg Second CloseItem -> { model | second = Nothing }
Open Third -> { model | third = Just "Here is the third item, also with nice CSS opacity transition" }
ItemMsg Third CloseItem -> { model | third = Nothing }
_ -> model
-- Inline CSS
containerStyle = Html.Attributes.style
[ ("padding", "20px") ]
buttonStyle = Html.Attributes.style
[ ("margin-right", "20px"), ("margin-bottom", "20px") ]
itemStyle = Html.Attributes.style
[ ("opacity", "0"), ("transition", "opacity 1000ms") ]
itemOpenStyle = Html.Attributes.style
[ ("opacity", "1"), ("transition", "opacity 1000ms"), ("margin-bottom", "20px") ]
function displayRecord(record) {
if (record.type === 'childList') {
console.log(record.target.localName + '.' + (record.target.getAttribute('class') || '').replace(/ /g, '.'));
console.log(' Added:', record.addedNodes.length, record.addedNodes);
console.log(' Removed:', record.removedNodes.length, record.removedNodes);
} else if (record.type === 'attributes') {
console.log('Attribute [' + record.attributeName + '] changed from [' + record.oldValue + '] to [' + record.target.getAttribute(record.attributeName) + '] on', record.target);
} else {
console.log(record);
}
}
var observer = new MutationObserver(function (records) {
records.forEach(displayRecord);
console.log('-----------------------------------------');
});
observer.observe(document, {
subtree: true,
childList: true,
attributes: true
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment