1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
module EditableNumber
( NumberElem
, set
, formatNumber
) where
import Control.Monad.Eff (Eff)
import Data.Int (round, toNumber, pow) as Int
import Data.Maybe (Maybe(..))
import Data.String (Pattern(..), Replacement(..))
import Data.String (replace) as String
import DOM (DOM)
import DOM.HTML (window) as DOM
import DOM.HTML.Types (htmlDocumentToDocument) as DOM
import DOM.HTML.Window (document) as DOM
import DOM.Node.Document (createElement, createTextNode) as DOM
import DOM.Node.Element (setClassName, setAttribute) as DOM
import DOM.Node.Node (textContent) as DOM
import DOM.Node.Types (Element, Node)
import DOM.Node.Types (elementToNode, textToNode) as DOM
import Math (round) as Math
import Prelude
import Dom (replaceElement, appendNodes) as Dom
import Parser (TextWithNumber)
import Parser (textWithNumber) as Parser
type NumberElem =
{ elem :: Element
, number :: Number
}
set :: forall e. { tag :: String, node :: Node } -> Eff (dom :: DOM | e) (Maybe NumberElem)
set { tag, node } = do
content <- DOM.textContent node
case Parser.textWithNumber content of
Just twn -> do
textWithNumber <- textWithNumberElem tag twn
Dom.replaceElement node (DOM.elementToNode textWithNumber)
pure (Just { elem: textWithNumber, number: twn.number })
Nothing ->
pure Nothing
textWithNumberElem :: forall e. String -> TextWithNumber -> Eff (dom :: DOM | e) Element
textWithNumberElem tag { begin, number, end } = do
document <- DOM.htmlDocumentToDocument <$> (DOM.window >>= DOM.document)
elem <- DOM.createElement tag document
beginNode <- DOM.textToNode <$> DOM.createTextNode begin document
numberNode <- numberElem number
endNode <- DOM.textToNode <$> DOM.createTextNode end document
Dom.appendNodes (DOM.elementToNode elem) [ beginNode, DOM.elementToNode numberNode, endNode ]
pure elem
numberElem :: forall e. Number -> Eff (dom :: DOM | e) Element
numberElem number = do
document <- DOM.htmlDocumentToDocument <$> (DOM.window >>= DOM.document)
container <- DOM.createElement "input" document
DOM.setClassName "number" container
DOM.setAttribute "value" (formatNumber number) container
pure container
formatNumber :: Number -> String
formatNumber number =
if Math.round number == number then
show (Int.round number)
else
String.replace (Pattern ".") (Replacement ",") (show (roundAt 1 number))
roundAt :: Int -> Number -> Number
roundAt at n =
let exp = Int.toNumber (Int.pow 10 at)
in Math.round (n * exp) / exp
|