Fable Hello world in 2019
#load ".paket/load/main.group.fsx" | |
open Fable.Core | |
open Fable.Core.JS | |
open Browser.Dom | |
open Browser.Types | |
let [<Literal>] CurrentSecond = "CurrentSecond" | |
let [<Literal>] TotalSeconds = "TotalSeconds" | |
let [<Literal>] IntervalKey = "IntervalKey" | |
[<Emit("document.querySelector($0)")>] | |
let bySelector<'t> selector : 't option = jsNative | |
let private parseInt (value:string) = | |
match System.Int32.TryParse(value) with | |
| true, v -> Some v | |
| _ -> None | |
let private getFromLocalStorage key = | |
window.localStorage.getItem key | |
|> parseInt | |
let private putInLocalStorage key value = | |
window.localStorage.setItem(key, sprintf "%d" value) | |
let private updateClock () = | |
printfn "not implemented yet!" | |
match bySelector<HTMLButtonElement> "button", bySelector<HTMLInputElement> "input" with | |
| Some button, Some input -> | |
button.addEventListener("click", (fun _ -> | |
parseInt input.value | |
|> Option.iter (fun v -> | |
putInLocalStorage TotalSeconds v | |
putInLocalStorage CurrentSecond 0 | |
setInterval updateClock 1000 | |
|> putInLocalStorage IntervalKey | |
) | |
)) | |
| _ -> | |
printfn "The button and/or the input could not be found in the DOM." |
#load ".paket/load/main.group.fsx" | |
open Fable.Core | |
open Fable.Core.JS | |
open Browser.Dom | |
open Browser.Types | |
let [<Literal>] CurrentSecond = "CurrentSecond" | |
let [<Literal>] TotalSeconds = "TotalSeconds" | |
let [<Literal>] IntervalKey = "IntervalKey" | |
[<Emit("document.querySelector($0)")>] | |
let bySelector<'t> selector : 't option = jsNative | |
let private parseInt (value:string) = | |
match System.Int32.TryParse(value) with | |
| true, v -> Some v | |
| _ -> None | |
let private getFromLocalStorage key = | |
window.localStorage.getItem key | |
|> parseInt | |
let private putInLocalStorage key value = | |
window.localStorage.setItem(key, sprintf "%d" value) | |
let private getClock() = bySelector<HTMLDivElement> ".clock" | |
let private printSeconds secondes = | |
let minutes = secondes / 60 | |
let remainingSeconds = secondes % 60 | |
sprintf "%02d:%02d" minutes remainingSeconds | |
let private updateClock () = | |
match getFromLocalStorage TotalSeconds, getFromLocalStorage CurrentSecond with | |
| Some total, Some current -> | |
let updatedCurrent = current + 1 | |
updatedCurrent | |
|> putInLocalStorage CurrentSecond | |
getClock() | |
|> Option.iter(fun clock -> clock.textContent <- (printSeconds updatedCurrent)) | |
if total = updatedCurrent then | |
getClock() | |
|> Option.iter(fun clock -> clock.classList.add [|"done"|]) | |
getFromLocalStorage IntervalKey | |
|> Option.iter(clearInterval) | |
| _ -> | |
printfn "The total and/or the current second could not be found in the localStorage" | |
match bySelector<HTMLButtonElement> "button", bySelector<HTMLInputElement> "input" with | |
| Some button, Some input -> | |
button.addEventListener("click", (fun _ -> | |
parseInt input.value | |
|> Option.iter (fun v -> | |
putInLocalStorage TotalSeconds v | |
putInLocalStorage CurrentSecond 0 | |
setInterval updateClock 1000 | |
|> putInLocalStorage IntervalKey | |
) | |
)) | |
| _ -> | |
printfn "The button and/or the input could not be found in the DOM." |
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<meta http-equiv="X-UA-Compatible" content="ie=edge"> | |
<title>Fable Exercise</title> | |
</head> | |
<body> | |
<script src="/dist/App.js" type="module"></script> | |
</body> | |
</html> |
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<meta http-equiv="X-UA-Compatible" content="ie=edge"> | |
<title>Fable Exercise</title> | |
<style> | |
input, button { | |
width: 50px; | |
} | |
input { | |
margin-left: 50px; | |
} | |
.clock { | |
border-radius: 100%; | |
background-color: cornflowerblue; | |
text-align: center; | |
width: 200px; | |
height: 120px; | |
margin-top: 15px; | |
padding-top: 80px; | |
font-size: 40px; | |
line-height: 40px; | |
font-family: sans-serif; | |
} | |
.clock.done { | |
background-color:indianred; | |
} | |
</style> | |
</head> | |
<body> | |
<main> | |
<input type="text"> <button>Start</button> | |
<div class="clock"> | |
00:00 | |
</div> | |
</main> | |
<script src="/dist/App.js" type="module"></script> | |
</body> | |
</html> |
dotnet tool install --global Paket |
namespace PaketLoadScripts | |
#r "C:\\Users\\nojaf\\.nuget\\packages\\fable.core\\3.0.0\\lib\\netstandard2.0\\Fable.Core.dll" | |
#r "C:\\Users\\nojaf\\.nuget\\packages\\fable.browser.blob\\1.0.0\\lib\\netstandard2.0\\Browser.Blob.dll" | |
#r "C:\\Users\\nojaf\\.nuget\\packages\\fable.browser.event\\1.0.0\\lib\\netstandard2.0\\Browser.Event.dll" | |
#r "C:\\Users\\nojaf\\.nuget\\packages\\fable.browser.webstorage\\1.0.0\\lib\\netstandard2.0\\Browser.WebStorage.dll" | |
#r "C:\\Users\\nojaf\\.nuget\\packages\\fable.browser.dom\\1.0.0\\lib\\netstandard2.0\\Browser.Dom.dll" |
{ | |
"name": "fable-hello-world-2019", | |
"version": "1.0.0", | |
"main": "index.js", | |
"license": "MIT", | |
"devDependencies": { | |
"browser-sync": "^2.26.7", | |
"fable-compiler": "^2.3.12", | |
"fable-splitter": "^2.1.10" | |
}, | |
"scripts": { | |
"postinstall": "paket restore & paket generate-load-scripts -t fsx", | |
"compile": "fable-splitter App.fsx -o dist -w", | |
"sync": "node server.js" | |
} | |
} |
storage: none | |
framework: netstandard2.0 | |
nuget Fable.Browser.Dom |
const fs = require("fs"); | |
const path = require("path"); | |
const bs = require("browser-sync").create(); | |
function isModuleRequest(url) { | |
const pieces = url.split("/"); | |
return pieces && pieces[pieces.length - 1].indexOf(".") === -1; | |
} | |
bs.init({ | |
server: "./", | |
open: false, | |
watch: true, | |
middleware: [ | |
function (req, res, next) { | |
if (isModuleRequest(req.url) && req.url !== "/") { | |
const content = fs.readFileSync(path.join(__dirname, `${req.url}.js`), 'utf8'); | |
res.writeHead(200, {'Content-Type': 'application/javascript'}); | |
res.write(content); | |
res.end(); | |
} else { | |
next(); | |
} | |
} | |
] | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment