Skip to content

Instantly share code, notes, and snippets.

@nojaf
Last active June 19, 2019 17:27
Show Gist options
  • Save nojaf/0aa082d66f8b4d3a39864bbfbee1e4c1 to your computer and use it in GitHub Desktop.
Save nojaf/0aa082d66f8b4d3a39864bbfbee1e4c1 to your computer and use it in GitHub Desktop.
Fable Hello world in 2019
#load ".paket/load/main.group.fsx"
printfn "Fable compiled this"
#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();
}
}
]
});
yarn init --yes
yarn add -D fable-compiler fable-splitter
yarn add -D browser-sync
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment