open Webapi.Dom (* Set up inputs for the ingredients *) type ingredient = { quantity : float; element : Dom.element } let ingredients : ingredient Js.Array.t = document |> Document.querySelectorAll ".g-Recipe__Content ul > li" |> NodeList.toArray |> ArrayUtils.flatMap (fun node -> Belt.Option.map (Element.ofNode node) (fun e -> ("li", e))) |> Js.Array.concat ( match Document.querySelector ".g-Recipe__Content h1" document with | Some element -> [| ("h1", element) |] | _ -> [||] ) |> ArrayUtils.flatMap (fun (tag, element) -> Belt.Option.map (Number.parseInsideText (Element.innerHTML element)) (fun parsed -> let created = Number.createElement tag parsed in let () = DomUtils.replace element created.element in { quantity = parsed.number; element = created.numberInput })) (* Update ingredients amounts *) let () = ingredients |> Js.Array.forEach (fun ingredient -> Element.addEventListener "input" (fun e -> Belt.Option.forEach (DomUtils.value (Event.target e)) (fun numberStr -> Belt.Option.forEach (Number.parse numberStr) (fun parsed -> let factor = parsed.number /. ingredient.quantity in ingredients |> Js.Array.forEach (fun otherIngredient -> if ingredient.element != otherIngredient.element then DomUtils.setValue otherIngredient.element (Number.prettyPrint (factor *. otherIngredient.quantity)) else ())))) ingredient.element) (* Set up done marks for steps *) let () = document |> Document.querySelectorAll ".g-Recipe__Content ol > li" |> NodeList.toArray |> Js.Array.forEach (fun node -> match Element.ofNode node with | Some element -> Element.addEventListener "click" (fun e -> let () = DomUtils.toggleClassName element "g-Recipe__Completed" in Event.stopPropagation e) element | _ -> ())