Commit 4b67e3b6 authored by Camil Staps's avatar Camil Staps 🍃

Merge remote-tracking branch 'origin/master' into...

Merge remote-tracking branch 'origin/master' into server-and-client-side-svg-rendering-with-abc-interpreter
parent 9f3512a4
......@@ -17,7 +17,7 @@ Start world = doTasks
,onRequest "/" (ccMain registerTasks continuousTasks alwaysOnTasks optionalTasks <<@ (Title "C2 System"))
,onRequest "/tonic" (tonicDashboard [])
,onRequest "/debug" showDebug
,onRequest "/adventure" (loginAndManageWork "Adventure")
,onRequest "/adventure" (loginAndManageWork "Adventure" Nothing Nothing False)
,onRequest "/alarm" (setSectionDetectors)
,onRequest "/log" showLog
//,onRequest "/devices" (manageDevices True)
......
......@@ -9,7 +9,7 @@ import iTasks.UI.Definition, iTasks.Extensions.Admin.UserAdmin
Start :: *World -> *World
Start world = doTasks
[onStartup (installWorkflows workflows)
,onRequest "/" (loginAndManageWork "The Taxman")
,onRequest "/" (loginAndManageWork "The Taxman" Nothing Nothing True)
] world
workflows :: [Workflow]
......
This diff was suppressed by a .gitattributes entry.
.welcome-itasks-example-collection {
background: url('/itasks.png') no-repeat top center;
padding-top: 100px;
}
.welcome-itasks-example-collection > div {
max-width: 600px;
border-radius: 5px;
padding: 5px 10px;
}
.welcome-itasks-example-collection h1 {
font-weight: normal;
font-size: 32pt;
color: #74a1d5;
}
......@@ -18,7 +18,7 @@ multiUserExample
-||-
viewInformation "and then Select \"new\" to create a new Task..." [] ""
>>| installWorkflows [wf "chat"]
>>| loginAndManageWork "Chat_4_2 Example"
>>| loginAndManageWork "Chat_4_2 Example" Nothing Nothing False
where
mkUserAccount name
= {UserAccount| credentials = {Credentials| username = Username name, password = Password name}, title = Nothing, roles = ["manager"] }
......
......@@ -21,7 +21,7 @@ multiUserExample
-||-
viewInformation "and then Select \"new\" to create a new Task..." [] ""
>>| installWorkflows [wf "Meeting date"]
>>| loginAndManageWork "Meeting_4_3 Example"
>>| loginAndManageWork "Meeting_4_3 Example" Nothing Nothing False
where
mkUserAccount name
= {UserAccount| credentials = {Credentials| username = Username name, password = Password name}, title = Nothing, roles = ["manager"] }
......
......@@ -21,7 +21,7 @@ multiUserExample
-||-
viewInformation "and then Select \"new\" to create a new Task..." [] ""
>>| installWorkflows [wf "Chat with options"]
>>| loginAndManageWork "Chat_4_2 Example"
>>| loginAndManageWork "Chat_4_2 Example" Nothing Nothing False
where
mkUserAccount name
= {UserAccount| credentials = {Credentials| username = Username name, password = Password name}, title = Nothing, roles = ["manager"] }
......
......@@ -34,19 +34,46 @@ makeExs :: [FilePath] -> [String]
makeExs i =
[ "module BasicAPIExamples\n"
, "\n"
, "import iTasks"
, "import iTasks\n"
, "import Text.HTML\n"
, "import qualified iTasks.Extensions.Admin.UserAdmin\n"
, "\n"
, join "\n" ["import qualified " +++ toDots i\\i<-i]
, "\n\n"
, "Start :: *World -> *World\n"
, "Start world = doTasks {WorkflowCollection|name=name,workflows=basicAPIExamples} world\n"
, "Start world = doTasks {WorkflowCollection|name=name,loginMessage=Just loginMessage,welcomeMessage=Just welcomeMessage,allowGuests=False,workflows=basicAPIExamples} world\n"
, "where\n"
, "\tname = \"iTasks Example Collection\"\n"
, "\tloginMessage = DivTag []\n"
, "\t\t[Text \"iTasks is a framework to create information systems from task specifications.\",BrTag []\n"
, "\t\t,Text \"Although useful for support of individual tasks, information systems add even more value when a task \"\n"
, "\t\t,Text \"requires multiple people to work together to accomplish it.\"\n"
, "\t\t,Text \"Therefore this example application is a multi-user demonstration of tasks expressed in iTasks.\",BrTag [],BrTag[]\n"
, "\t\t,Text \"You can log in with a demonstration user account:\",BrTag []\n"
, "\t\t\t,UlTag []\n"
, "\t\t\t\t[LiTag [] [Text \"Alice (username: alice, password: alice)\"]\n"
, "\t\t\t\t,LiTag [] [Text \"Bob (username: bob, password: bob)\"]\n"
, "\t\t\t\t,LiTag [] [Text \"Carol (username: carol, password: carol)\"]\n"
, "\t\t\t\t,LiTag [] [Text \"An administrator with full access (username: root, password: root)\"]\n"
, "\t\t\t\t]\n"
, "\t\t\t]\n"
, "\n"
, "\twelcomeMessage = DivTag []\n"
, "\t\t[H1Tag [] [Text \"Welcome\"],PTag []\n"
, "\t\t\t[Text \"In this generic application you can work on multiple tasks concurrently.\", BrTag []\n"
, "\t\t\t,Text \"In the list above you can see the set of ongoing tasks that you can choose to work on.\", BrTag []\n"
, "\t\t\t,Text \"Additionally you can add tasks to this list with the 'New' button. This will open a window with a collection of predefined tasks.\", BrTag []\n"
, "\t\t\t,Text \"These tasks range from simple TODO items, to complex multi-user workflows.\", BrTag []\n"
, "\t\t\t]\n"
, "\t\t]\n"
, "\n"
, "basicAPIExamples :: [Workflow]\n"
, "basicAPIExamples =\n"
, "\t[",join "\n\t," (map (\i->concat ["'", toDots i, "'.wf \"", toString (insertSpaces 0 (dropExtension i)), "\""]) i), "\n\t]\n"]
, "\t[",join "\n\t," (defaultWfs ++ exampleWfs), "\n\t]\n"]
where
defaultWfs = ["restrictedTransientWorkflow \"Users\" \"User management\" [\"admin\"] 'iTasks.Extensions.Admin.UserAdmin'.manageUsers"]
exampleWfs = map (\i->concat ["'", toDots i, "'.wf \"", toString (insertSpaces 0 (dropExtension i)), "\""]) i
toDots = join "." o split (toString pathSeparator) o dropExtension
insertSpaces i s
| i == size s = []
......
......@@ -25,7 +25,7 @@ Global
Stack: False
Dynamics: True
GenericFusion: False
DescExL: False
DescExL: True
Output
Output: NoReturnType
Font: Courier
......
......@@ -108,7 +108,7 @@ startMode executable
>>- \role = case role of
DomainServer domain -> startAuthEngine domain
>>| installWorkflows (myTasks True)
>>| loginAndManageWork "Service engineer application"
>>| loginAndManageWork "Service engineer application" Nothing Nothing False
Server domain -> startAuthEngine domain >>| loginRemote (myTasks False)
_ -> viewInformation "Welcome" [] "Chose what this iTasks instance is."
>>* [ OnAction (Action "Domain server") (always (domainServer))
......@@ -127,7 +127,7 @@ where
>>= \domain -> set (DomainServer domain) serverRoleShare
>>| startAuthEngine domain
>>| installWorkflows (myTasks True)
>>| loginAndManageWork "Service engineer application"
>>| loginAndManageWork "Service engineer application" Nothing Nothing False
loginRemote :: ![Workflow] -> Task ()
loginRemote workflows
......@@ -140,7 +140,7 @@ where
browseAuthenticated workflows {Credentials|username,password}
= remoteAuthenticateUser username password
>>= \mbUser -> case mbUser of
Just user = workAs user manageWorkOfCurrentUser
Just user = workAs user (manageWorkOfCurrentUser Nothing)
Nothing = viewInformation (Title "Login failed") [] "Your username or password is incorrect" >>| return ()
Start :: *World -> *World
......
......@@ -24,8 +24,8 @@ Global
Profile
Memory: False
MemoryMinimumHeapSize: 0
Time: True
Stack: True
Time: False
Stack: False
Dynamics: True
DescExL: True
Output
......
......@@ -3,7 +3,7 @@ import iTasks
import iTasks.Extensions.GIS.Leaflet
import iTasks.Extensions.GIS.LeafletNavalIcons
import iTasks.UI.Definition
import Data.List
import Data.List, Text.HTML
playWithMaps :: Task ()
playWithMaps = withShared {defaultValue & icons = shipIcons} (\m ->
......@@ -38,6 +38,7 @@ where
,("Polygon from current markers",addMarkerConnectingPolygon m)
,("Circle at cursor position",addCircleAtCursor m)
,("Rectangle around current perspective",addRectangleAroundCurrentPerspective m)
,("Some window",addWindow m)
]
addRandomMarker m
......@@ -93,4 +94,15 @@ where
withRectangleAroundCurrentPerspective Nothing objects = objects
withRectangleAroundCurrentPerspective (Just bounds) objects = objects ++ [Rectangle {rectangleId = LeafletObjectID "RECT_PERSPECTIVE", bounds = bounds, editable = True, style = []}]
addWindow m
= upd (\l=:{LeafletMap|objects} -> {LeafletMap| l & objects = [Window window:objects]}) m
where
window =
{ windowId = LeafletObjectID "WINDOW"
, initPosition = {x = 100, y = 100}
, title = "Test Window"
, content = H1Tag [] [Text "This is test content!"]
, relatedMarkers = [(LeafletObjectID "home", [])]
}
Start world = doTasks playWithMaps world
......@@ -4,23 +4,29 @@ module Ligretto
When creating a project, include the following paths:
(i) {Application}\Examples\iTasks\Games\
(ii) {Application}\Examples\iTasks\Graphics\
To run the example playing as two persons, do the following:
(a) first log in as root / root
(b) select the 'Manage users' task
(c) import a user community
(d) logout
(e) login as the key player who is going to invite 1, 2, or 3 players
(f) select the 'Ligretto' task
(g) select 1, 2, or 3 users to play Ligretto with
(h) open the newly created task
(i) in other browser( tab)s, login as the invited player(s) and open the task received from the key player
(j) have fun
*/
import Ligretto.Tasks
import MultiUser.Tasks
import iTasks.Extensions.Admin.WorkflowAdmin, Text.HTML
Start :: *World -> *World
Start world
= startMultiUserTasks [ workflow "Ligretto" "Play Ligretto" play_Ligretto ] [] world
Start world = doTasks
{WorkflowCollection
|name = "Ligretto"
,workflows = [ workflow "Host Ligretto" "Host a Ligretto game" play_Ligretto ]
,loginMessage = Just loginMessage
,welcomeMessage = Nothing
,allowGuests = False
} world
where
loginMessage = DivTag []
[Text "This example implements a simplified version of the card game Ligretto.", BrTag []
,Text "To play the game do the following:"
,OlTag []
[LiTag [] [Text "Log in as a demo user for example 'alice' (password alice), 'bob' (password bob) or 'carol' (password carol)"]
,LiTag [] [Text "Choose New -> 'Host Ligretto' -> 'Create task'"]
,LiTag [] [Text "Open the task in the task list and invite other players"]
,LiTag [] [Text "The others can also log in and will find the game waiting for them in their task list."]
,LiTag [] [Text "Have fun"]
]
]
definition module MultiUser.Tasks
import iTasks.Extensions.Admin.UserAdmin
startMultiUserTasks :: [Workflow] [StartableTask] *World -> *World
implementation module MultiUser.Tasks
import iTasks
import iTasks.Extensions.Admin.UserAdmin
startMultiUserTasks :: [Workflow] [StartableTask] *World -> *World
startMultiUserTasks workflows tasks world
= startTask [ workflow "Manage users" "Manage system users..." manageUsers
: workflows
] tasks world
startTask taskList tasks world
= doTasks [ onStartup (installWorkflows taskList)
, onRequest "/" browseExamples
: tasks
] world
where
browseExamples = forever (
enterInformation "Enter your credentials and login or press continue to remain anonymous" []
>>* [OnAction (Action "Login") (hasValue browseAuthenticated)
] )
browseAuthenticated {Credentials|username,password}
= authenticateUser username password
>>= \mbUser -> case mbUser of
Just user = workAs user manageWorkOfCurrentUser
Nothing = viewInformation (Title "Login failed") [] "Your username or password is incorrect" >>| return ()
module Trax
/** This example implements the two-person tile game Trax.
When creating a project, include the following paths:
{Application}\Examples\iTasks\Games\
To run the example playing as two persons, do the following:
(a) first log in as root / root
(b) select the 'Manage users' task
(c) import a user community
(d) logout
(e) login as the key player who is going to invite another player
(f) select the 'Trax' task
(g) select a user to play Trax with
(h) open the newly created task
(i) in another browser( tab), login as the invited player and open the task received from the key player
(j) have fun
*/
import Trax.UoD
import Trax.Tasks
import MultiUser.Tasks
import iTasks.Engine
import iTasks.Extensions.Admin.WorkflowAdmin, Text.HTML
Start :: *World -> *World
Start world
= startMultiUserTasks [ workflow "Trax" "Play Trax" play_trax ] [] world
Start world = doTasks
{WorkflowCollection
|name = "Trax"
,workflows = [ workflow "Host Trax" "Host a Trax game" play_trax ]
,loginMessage = Just loginMessage
,welcomeMessage = Nothing
,allowGuests = False
} world
where
loginMessage = DivTag []
[Text "This example implements the two-person tile game Trax.", BrTag []
,Text "To play the game do the following:"
,OlTag []
[LiTag [] [Text "Log in as a demo user for example 'alice' (password alice), 'bob' (password bob) or 'carol' (password carol)"]
,LiTag [] [Text "Choose New -> 'Host Trax' -> 'Create task'"]
,LiTag [] [Text "Open the task in the task list and invite another player"]
,LiTag [] [Text "The invited player can also log in and will find the game waiting for her in the task list."]
,LiTag [] [Text "Have fun"]
]
]
......@@ -24,8 +24,8 @@ Global
Profile
Memory: False
MemoryMinimumHeapSize: 0
Time: True
Stack: True
Time: False
Stack: False
Dynamics: True
GenericFusion: False
DescExL: True
......
<!DOCTYPE html>
<html style="width: 100%; height: 100%;">
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" href="/css/itasks.css" type="text/css" >
<link rel="stylesheet" href="/css/WorkflowAdmin.css" type="text/css" >
<!-- ABC interpreter -->
<script type="text/javascript" src="/js/abc-instructions.js"></script>
<script type="text/javascript" src="/js/abc-interpreter.js"></script>
<!-- iTasks framework -->
<script type="text/javascript" src="/js/itasks-core.js"></script>
<script type="text/javascript" src="/js/itasks-components-raw.js"></script>
<script type="text/javascript" src="/js/itasks-components-form.js"></script>
<script type="text/javascript" src="/js/itasks-components-display.js"></script>
<script type="text/javascript" src="/js/itasks-components-selection.js"></script>
<script type="text/javascript" src="/js/itasks-components-container.js"></script>
<!-- load iTasks viewport -->
<script type="text/javascript">
window.onload = function() {
ABC.loading_promise.finally(function(){
itasks.viewport({syncTitle: true}, document.body);
});
};
</script>
</head>
<body style="width: 100%; height: 100%">
</body>
</html>
......@@ -32,8 +32,11 @@ import iTasks
// Make the management framework startable
:: WorkflowCollection =
{ name :: !String
, workflows :: ![Workflow]
{ name :: !String
, loginMessage :: !Maybe HtmlTag
, welcomeMessage :: !Maybe HtmlTag
, allowGuests :: !Bool
, workflows :: ![Workflow]
}
instance Startable WorkflowCollection
......@@ -94,8 +97,8 @@ instance toWorkflow (ParamWorkflowContainer a b) | iTask a & iTask b
* and let's them create instances of these tasks and work on instances.
*/
installWorkflows :: ![Workflow] -> Task ()
loginAndManageWork :: !String -> Task ()
manageWorkOfCurrentUser :: Task ()
loginAndManageWork :: !String !(Maybe HtmlTag) !(Maybe HtmlTag) !Bool -> Task ()
manageWorkOfCurrentUser :: !(Maybe HtmlTag) -> Task ()
/**
* Dynamically adds a workflow to the system.
......
......@@ -9,6 +9,8 @@ from StdFunc import seq
import qualified Data.Map as DM
import Data.Map.GenJSON
import Data.List, Data.Tuple
import Text.HTML
import iTasks.UI.Definition, iTasks.UI.Editor, iTasks.UI.Editor.Controls, iTasks.UI.Editor.Common, iTasks.UI.Layout.Default, iTasks.UI.Layout.Common
import iTasks.Extensions.DateTime
// SPECIALIZATIONS
......@@ -41,7 +43,7 @@ myWork :: SDSLens () [(TaskId,WorklistRow)] ()
myWork = workList taskInstancesForCurrentUser
allWork :: SDSLens () [(TaskId,WorklistRow)] ()
allWork = workList allTaskInstances
allWork = workList detachedTaskInstances
workList instances = mapRead projection (instances |*| currentTopTask)
where
......@@ -94,49 +96,57 @@ allowedPersistentWorkflows = mapRead (\wfs -> [wf \\ wf=:{Workflow|transient} <-
instance Startable WorkflowCollection
where
toStartable {WorkflowCollection|name,workflows} =
toStartable {WorkflowCollection|name,loginMessage,welcomeMessage,allowGuests,workflows} =
[onStartup (installWorkflows workflows)
,onRequest "/" (loginAndManageWork name)
,onStartup importDemoUsersFlow
,onRequest "/" (loginAndManageWork name loginMessage welcomeMessage allowGuests)
]
installWorkflows :: ![Workflow] -> Task ()
installWorkflows [] = return ()
installWorkflows iflows
= try (get workflows) (\(StoreReadBuildVersionError _) -> return [])
>>= \flows -> case flows of
>>- \flows -> case flows of
[] = set iflows workflows @! ()
_ = return ()
loginAndManageWork :: !String -> Task ()
loginAndManageWork welcome
loginAndManageWork :: !String !(Maybe HtmlTag) !(Maybe HtmlTag) !Bool -> Task ()
loginAndManageWork applicationName loginMessage welcomeMessage allowGuests
= forever
((( viewTitle welcome
((( identifyApplication applicationName loginMessage
||-
(anyTask [
enterInformation ("Authenticated access","Enter your credentials and login") [] @ Just
>>* [OnAction (Action "Login") (hasValue return)]
,
viewInformation ("Guest access","Alternatively, you can continue anonymously as guest user") [] ()
>>| (return Nothing)
:if allowGuests
[viewInformation ("Guest access","Alternatively, you can continue anonymously as guest user") [] ()
>>| (return Nothing)
]
[]
] <<@ ArrangeHorizontal)
) <<@ ApplyLayout layout
>>- browse) //Compact layout before login, full screen afterwards
) <<@ ApplyLayout (setUIAttributes (titleAttr welcome))
) <<@ Title applicationName
where
browse (Just {Credentials|username,password})
= authenticateUser username password
>>= \mbUser -> case mbUser of
Just user = workAs user manageWorkOfCurrentUser
Nothing = viewInformation (Title "Login failed") [] "Your username or password is incorrect" >>| return ()
Just user = workAs user (manageWorkOfCurrentUser welcomeMessage)
Nothing = (viewInformation (Title "Login failed") [] "Your username or password is incorrect" >>| return ()) <<@ ApplyLayout frameCompact
browse Nothing
= workAs (AuthenticatedUser "guest" ["manager"] (Just "Guest user")) manageWorkOfCurrentUser
= workAs (AuthenticatedUser "guest" ["manager"] (Just "Guest user")) (manageWorkOfCurrentUser welcomeMessage)
identifyApplication name welcomeMessage = viewInformation () [] html
where
html = DivTag [ClassAttr cssClass] [H1Tag [] [Text name]:maybe [] (\msg -> [msg]) welcomeMessage]
cssClass = "welcome-" +++ (toLowerCase $ replaceSubString " " "-" name)
layout = sequenceLayouts [layoutSubUIs (SelectByType UIAction) (setActionIcon ('DM'.fromList [("Login","login")])) ,frameCompact]
manageWorkOfCurrentUser :: Task ()
manageWorkOfCurrentUser
manageWorkOfCurrentUser :: !(Maybe HtmlTag) -> Task ()
manageWorkOfCurrentUser welcomeMessage
= ((manageSession -||
(chooseWhatToDo >&> withSelection
(chooseWhatToDo welcomeMessage >&> withSelection
(viewInformation () [] "Welcome!")
(\wf -> unwrapWorkflowTask wf.Workflow.task)
)
......@@ -168,13 +178,13 @@ manageSession =
where
view user = "Welcome " +++ toString user
chooseWhatToDo = updateChoiceWithShared (Title "Menu") [ChooseFromList workflowTitle] (mapRead addManageWork allowedTransientTasks) manageWorkWf
chooseWhatToDo welcomeMessage = updateChoiceWithShared (Title "Menu") [ChooseFromList workflowTitle] (mapRead addManageWork allowedTransientTasks) manageWorkWf
where
addManageWork wfs = [manageWorkWf:wfs]
manageWorkWf = transientWorkflow "My work" "Manage your worklist" manageWork
manageWorkWf = transientWorkflow "My Tasks" "Manage your worklist" (manageWork welcomeMessage)
manageWork :: Task ()
manageWork = parallel [(Embedded, manageList)] [] <<@ ApplyLayout layoutManageWork @! ()
manageWork :: (Maybe HtmlTag) -> Task ()
manageWork welcomeMessage = parallel [(Embedded, manageList):maybe [] (\html -> [(Embedded, const (viewWelcomeMessage html))]) welcomeMessage] [] <<@ ApplyLayout layoutManageWork @! ()
where
manageList taskList
= get currentUser @ userRoles
......@@ -203,16 +213,19 @@ where
layoutSubUIs (SelectByDepth 1) (setUIAttributes $ 'DM'.put "fullscreenable" (JSONBool True) 'DM'.newMap)
]
viewWelcomeMessage :: HtmlTag -> Task ()
viewWelcomeMessage html = viewInformation (Title "Welcome") [] html @! ()
addNewTask :: !(SharedTaskList ()) -> Task ()
addNewTask list
= ((chooseWorkflow >&> viewWorkflowDetails) <<@ ArrangeHorizontal
>>* [OnAction (Action "Start task") (hasValue (\wf -> startWorkflow list wf @! ()))
,OnAction ActionCancel (always (return ()))
] ) <<@ Title "New work"
] ) <<@ Title "New task..."
chooseWorkflow :: Task Workflow
chooseWorkflow
= editSelectionWithShared [Att (Title "Tasks"), Att IconEdit] False (SelectInTree toTree fromTree) allowedWorkflows (const []) <<@ Title "Workflow Catalogue"
= editSelectionWithShared [Att (Title "Tasks"), Att IconEdit] False (SelectInTree toTree fromTree) allowedPersistentWorkflows (const [])
@? tvHd
where
//We assign unique negative id's to each folder and unique positive id's to each workflow in the list
......
implementation module iTasks.Extensions.Distributed._Evaluation
from iTasks.WF.Definition import :: Task(..), :: Event(ResetEvent), :: TaskEvalOpts, class iTask, :: TaskResult(..), :: TaskException, :: TaskValue(..), :: Stability, :: InstanceNo, :: TaskId
from iTasks.Internal.TaskState import :: TaskTree(TCInit,TCDestroy)
from iTasks.WF.Definition import :: Task(..), :: Event(ResetEvent,DestroyEvent), :: TaskEvalOpts, class iTask, :: TaskResult(..), :: TaskException, :: TaskValue(..), :: Stability, :: InstanceNo, :: TaskId
from iTasks.Internal.TaskState import :: TaskTree(TCInit)
import iTasks.Internal.TaskEval
import iTasks.UI.Definition
from iTasks.WF.Combinators.Common import @!, @?, whileUnchanged, ||-
......@@ -47,14 +47,14 @@ proxyTask :: (Shared sds (TaskValue a)) (*IWorld -> *IWorld) -> (Task a) | iTask
proxyTask value_share onDestroy = Task (eval value_share)
where
eval :: (Shared sds (TaskValue a)) Event TaskEvalOpts TaskTree *IWorld -> *(!TaskResult a, !*IWorld) | iTask a & RWShared sds
eval value_share DestroyEvent repAs _ iworld
# iworld = onDestroy iworld
= (DestroyedResult,iworld)
eval value_share event evalOpts tree=:(TCInit taskId ts) iworld
# (val,iworld) = readRegister taskId value_share iworld
= case val of
Ok (ReadingDone val) = (ValueResult val {TaskEvalInfo|lastEvent=ts,removedTasks=[],attributes=newMap} (rep event) tree, iworld)
Error e = (ExceptionResult e,iworld)
eval value_share event repAs (TCDestroy _) iworld
# iworld = onDestroy iworld
= (DestroyedResult,iworld)
rep ResetEvent = ReplaceUI (ui UIEmpty)
rep _ = NoChange
......
......@@ -52,9 +52,9 @@ where
initUI me world
//Setup UI component
# world = ((me .# "domTag") .= "pre") world
# world = (me .# "domTag" .= "pre") world
# (cb,world) = jsWrapFun (onAttributeChange me) me world
# world = ((me .# "onAttributeChange") .= cb) world
# world = (me .# "onAttributeChange" .= cb) world
//Load Ace javascript
# (cb,world) = jsWrapFun (\_ -> initUI` me) me world
# world = addJSFromUrl ACE_JS_URL (Just cb) world
......@@ -63,36 +63,32 @@ where
initUI` me world
//Create Ace editor linked to domEl
# (domEl,world) = me .# "domEl" .? world
# (editor,world) = jsNew "ace.edit" domEl world
# (session,world) = ((editor .# "getSession") .$ ()) world
# (selection,world) = ((session.# "getSelection") .$ ()) world
# world = ((me .# "editor") .= editor) world
# world = (domEl .# "style.width" .= "100%") world
# world = (domEl .# "style.height" .= "100%") world
# (editor,world) = (jsGlobal "ace.edit" .$ domEl) world
# (session,world) = (editor .# "getSession" .$ ()) world