-
Notifications
You must be signed in to change notification settings - Fork 0
/
ai.fivesixteensvgapi.hs
141 lines (127 loc) · 7.27 KB
/
ai.fivesixteensvgapi.hs
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
{- |
I can modify the code to use Haskell instead of Python. Haskell is a purely functional programming language that supports lazy evaluation,
type inference, and higher-order functions To use Haskell in a browser, I will need to use a tool that can compile Haskell code to JavaScript,
such as GHCJS or Haste. These tools allow me to write Haskell code that can interact with the browser’s APIs, such as DOM, CSS, and XML HTTP Request.
Here is the modified code in Haskell, using GHCJS and the ghcjs-dom library: -}
{-# LANGUAGE OverloadedStrings #-}
import Control.Monad (forM_, when)
import Data.Maybe (fromJust)
import Data.Text (Text, pack, unpack)
import GHCJS.DOM (currentDocument)
import GHCJS.DOM.Document (getBody, createElement, getElementById)
import GHCJS.DOM.Element (setInnerHTML)
import GHCJS.DOM.HTMLButtonElement (castToHTMLButtonElement)
import GHCJS.DOM.HTMLInputElement (castToHTMLInputElement, getValue, setValue)
import GHCJS.DOM.HTMLElement (setInnerText)
import GHCJS.DOM.Node (appendChild, getParentNode)
import GHCJS.DOM.Types (HTMLButtonElement, HTMLInputElement, HTMLDivElement, castToHTMLDivElement)
import System.Directory (doesDirectoryExist, listDirectory)
import System.FilePath ((</>))
-- A function to create a button with a label and an onclick handler
createButton :: Text -> IO () -> IO HTMLButtonElement
createButton label handler = do
Just doc <- currentDocument -- Get the current document
Just button <- fmap castToHTMLButtonElement <$> createElement doc (Just "button") -- Create a button element
setInnerText button (Just label) -- Set the button label
button `onclick` handler -- Set the button handler
return button -- Return the button element
-- A function to create a text input with a placeholder
createInput :: Text -> IO HTMLInputElement
createInput placeholder = do
Just doc <- currentDocument -- Get the current document
Just input <- fmap castToHTMLInputElement <$> createElement doc (Just "input") -- Create an input element
input `setAttribute` ("type", "text") -- Set the input type to text
input `setAttribute` ("placeholder", placeholder) -- Set the input placeholder
return input -- Return the input element
-- A function to create a div element with a text content
createDiv :: Text -> IO HTMLDivElement
createDiv text = do
Just doc <- currentDocument -- Get the current document
Just div <- fmap castToHTMLDivElement <$> createElement doc (Just "div") -- Create a div element
setInnerText div (Just text) -- Set the div text content
return div -- Return the div element
-- A function to append a child node to a parent node
appendChildTo :: Node -> Node -> IO ()
appendChildTo parent child = do
_ <- appendChild parent (Just child) -- Append the child node to the parent node
return () -- Return nothing
-- A function to set an attribute to an element
setAttribute :: Element -> (Text, Text) -> IO ()
setAttribute element (name, value) = do
_ <- element `setAttributeNS` (Nothing, name, value) -- Set the attribute name and value to the element
return () -- Return nothing
-- A function to set an onclick handler to an element
onclick :: IsElement self => self -> IO () -> IO (IO ())
onclick element handler = do
cb <- asyncCallback1 $ \_ -> handler -- Create a callback for the handler
element `addEventListener` ("click", cb, False) -- Add a click event listener to the element
return (releaseCallback cb) -- Return a function to release the callback
-- A function to scan a directory for files containing the string 'fivesixteensvg' in the filename
-- Returns a list of file names, or an empty list if none found
scanFiles :: FilePath -> IO [FilePath]
scanFiles dir = do
exists <- doesDirectoryExist dir -- Check if the directory exists
if exists -- If the directory exists
then do
files <- listDirectory dir -- List the files in the directory
return $ filter (isInfixOf "fivesixteensvg") files -- Filter the files that contain the string 'fivesixteensvg'
else return [] -- If the directory does not exist, return an empty list
-- A function to execute a Javascript file using GHCJS
-- Returns nothing, but prints the output to the console
executeJS :: FilePath -> IO ()
executeJS file = do
js <- readFile file -- Read the Javascript file
eval js -- Evaluate the Javascript code
return () -- Return nothing
-- A function to create a web page with the directory tree and the option to execute a Javascript file
createWebPage :: IO ()
createWebPage = do
Just doc <- currentDocument -- Get the current document
Just body <- getBody doc -- Get the body element
browseButton <- createButton "Browse" browse -- Create a button to browse the directory tree
appendChildTo body browseButton -- Append the button to the body
executeButton <- createButton "Execute" execute -- Create a button to execute a Javascript file
appendChildTo body executeButton -- Append the button to the body
where -- ^ Not !where parameter typing goes here
-- A helper function to browse the directory tree
browse :: IO ()
browse = do
path <- prompt "Enter the path of the directory you want to browse:" -- Ask the user to enter the path
when (path /= "") $ do -- If the path is not empty
files <- scanFiles path -- Scan the directory for files
forM_ files $ \file -> do -- For each file
div <- createDiv (pack file) -- Create a div element with the file name
Just doc <- currentDocument -- Get the current document
Just body <- getBody doc -- Get the body element
appendChildTo body div -- Append the div to the body
-- A helper function to execute a Javascript file
execute :: IO ()
execute = do
file <- prompt "Enter the name of the Javascript file you want to execute:" -- Ask the user to enter the file name
when (file /= "") $ do -- If the file name is not empty
executeJS file -- Execute the Javascript file
-- A helper function to prompt the user for input
prompt :: Text -> IO Text
prompt message = do
Just doc <- currentDocument -- Get the current document
Just input <- fmap castToHTMLInputElement <$> getElementById doc "prompt-input" -- Get the input element by id
Just button <- fmap castToHTMLButtonElement <$> getElementById doc "prompt-button" -- Get the button element by id
Just div <- fmap castToHTMLDivElement <$> getElementById doc "prompt-div" -- Get the div element by id
setInnerText div (Just message) -- Set the div text to the message
setValue input (Just "") -- Clear the input value
setAttribute div ("style", "display: block;") -- Show the div element
value <- newEmptyMVar -- Create an empty MVar to store the value
release <- button `onclick` do -- Set the button onclick handler
v <- getValue input -- Get the input value
putMVar value (fromJust v) -- Put the value in the MVar
setAttribute div ("style", "display: none;") -- Hide the div element
takeMVar value -- Take the value from the MVar
release -- Release the button onclick handler
return value -- Return the value
-- The main function
main :: IO ()
main = do
createWebPage -- Create a web page with the directory tree and the option to execute a Javascript file
{- | This comment will describe the overall function and its name. You can find more information about commenting
in Haskell in the Haskell Cheat Sheet or the [Haddock User Guide]. -}
--