aboutsummaryrefslogtreecommitdiff
path: root/js/EditableNumber.purs
diff options
context:
space:
mode:
Diffstat (limited to 'js/EditableNumber.purs')
-rw-r--r--js/EditableNumber.purs72
1 files changed, 72 insertions, 0 deletions
diff --git a/js/EditableNumber.purs b/js/EditableNumber.purs
new file mode 100644
index 0000000..eb5ddb0
--- /dev/null
+++ b/js/EditableNumber.purs
@@ -0,0 +1,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