diff --git a/mostrami/README.md b/mostrami/README.md deleted file mode 100644 index 393aef4..0000000 --- a/mostrami/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Mostrami - -Mostrami - "Show me" in Italian - is a GUI presentation package analagous to PowerPoint but for web-based editing and delivery. It is _not_ a PowerPoint clone, nor does it seek to be compatible in any way. It provides an editing environment that maintains a live view of the presentation at the step being edited. All editing is done by typing values; mouse-based editing may be added later. - -Mostrami differs from PowerPoint in being step-based rather than slide-based. A step is any change to what is currently showing on the screen. If you wish to retain the notion of 'slides' you can regard a slide as an accumulation of a number of steps. Every slide consists of at least one step but there is no upper limit to the number. - -PowerPoint includes a rich set of graphical elements. Mostrami relies more on _actions_, the simplest of which is a cut from one piece of content to another. Mostrami presentations tend to be dynamic, with smooth transitions from one step to the next. The program is modular and permits the addition of plugins to perform any desired effect. Its architecture separates structure and content to allow either to be changed independently of the other. - -Mostrami creates files in the JSON::Presenter format, allowing them to be delivered using that engine. - -Mostrami runs in any browser and is usable on a PC or a mobile devices. - -This project is under development. \ No newline at end of file diff --git a/mostrami/demo.html b/mostrami/demo.html deleted file mode 100644 index 9f3fd1c..0000000 --- a/mostrami/demo.html +++ /dev/null @@ -1,20 +0,0 @@ -<html> - <head> - <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - </head> - - <body> - - <div id="jp-container" style="text-align:center;width:100%"> - <b>JSON::Presenter</b><br> - Click/Tap or key Space/RightArrow to start in manual mode<br> - Click/Tap or key Space/RightArrow to advance<br> - Key Enter to start in auto mode<br> - Click/Tap to exit auto mode - </div> - <pre id="jp-script" style="display:none">resources/json/test.json</pre> - <script src="resources/js/mostrami.js"></script> - - </body> -</html> diff --git a/mostrami/favicon.gif b/mostrami/favicon.gif deleted file mode 100644 index e69de29..0000000 diff --git a/mostrami/favicon.ico b/mostrami/favicon.ico deleted file mode 100644 index ed89efe..0000000 Binary files a/mostrami/favicon.ico and /dev/null differ diff --git a/mostrami/index.html b/mostrami/index.html deleted file mode 100644 index 73f153c..0000000 --- a/mostrami/index.html +++ /dev/null @@ -1,22 +0,0 @@ -<html> - <head> - <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <!--script src='https://cdn.jsdelivr.net/gh/easycoder/easycoder.github.io/dist/easycoder.js?v=2.7.1'></script--> - <script src='dist/easycoder.js?v=2.7.1'></script> - </head> - - <body> - - <pre id="easycoder-rest" style="display:none">rest.php</pre> - <pre id="easycoder-script" style="display:none"> - ! Mostrami Pro - - script Launcher - - variable Script - rest get Script from `/resources/ecs/main.txt?v=` cat now - run Script - - </body> -</html> diff --git a/mostrami/properties.txt b/mostrami/properties.txt deleted file mode 100644 index 82915a9..0000000 --- a/mostrami/properties.txt +++ /dev/null @@ -1 +0,0 @@ -password=$2y$10$Kazqoaw6fGfV22bp3otJeO6Xra4bCsBJXq6JVAV07qOkHNDIFevWG diff --git a/mostrami/resources/README.md b/mostrami/resources/README.md deleted file mode 100644 index e277613..0000000 --- a/mostrami/resources/README.md +++ /dev/null @@ -1,3 +0,0 @@ - # JSON::Presenter resources - - These are all the resources - scripts, images and text files - called for by the website. diff --git a/mostrami/resources/ecs/blocks.txt b/mostrami/resources/ecs/blocks.txt deleted file mode 100644 index 327c604..0000000 --- a/mostrami/resources/ecs/blocks.txt +++ /dev/null @@ -1,208 +0,0 @@ -! Blocks - - script Blocks - - import div Panel and variable Presentation - - div Editor - div Row - div Cell - div Title - table Table - tr TR - td TD - span BlockNameSpan - input BlockNameInput - input PropertyValue - button EditButton - img AddBlock - img DeleteBlock - a Link - variable Blocks - variable Block - variable BlockNames - variable BlockName - variable PropertyNames - variable PropertyName - variable Properties - variable SelectedBlock - variable Action - variable N - variable B - - put -1 into SelectedBlock - - rest get Properties from `/resources/json/properties.json` - put the json keys of Properties into PropertyNames - - on message go to Start - set ready - stop - -Start: - if the message is `save` - begin - gosub to SaveSelectedBlock - stop - end - -Restart: - put property `blocks` of Presentation into Blocks - put the json keys of Blocks into BlockNames - - clear Panel - create Row in Panel - set the style of Row to `display:flex;margin-top:0.5em` - create Title in Row - set the style of Title to - `flex:1;font-size:110%;font-weight:bold;background:lightgray;text-align:center` - set the content of Title to `Blocks` - create Cell in Row - set the style of Cell to `width:1.4em;text-align:center` - create Link in Cell - create AddBlock in Link - set the style of AddBlock to `width:1em;margin-top:0.1em` - set attribute `src` of AddBlock to `resources/icon/plus.png` - on click AddBlock - begin - put prompt `Name of new block:` with `new block` into BlockName - set Block to object - put 0 into N - while N is less than the json count of PropertyNames - begin - put element N of PropertyNames into PropertyName - set property PropertyName of Block to property PropertyName of Properties - add 1 to N - end - set property BlockName of Blocks to Block - set property `blocks` of Presentation to Blocks - go to Restart - end - - put the json count of BlockNames into N - set the elements of BlockNameSpan to N - set the elements of BlockNameInput to N - set the elements of EditButton to N - set the elements of Editor to N - set the elements of DeleteBlock to N - create Table in Panel - if N is greater than 0 set the style of Table to `width:100%;border:1px solid black` - put 0 into B - while B is less than the elements of EditButton - begin - put element B of BlockNames into BlockName - create TR in Table - create TD in TR - set the style of TD to `width:8em;border:1px solid black;padding-left:0.5em` - create BlockNameSpan in TD - set the content of BlockNameSpan to BlockName - create BlockNameInput in TD - set the style of BlockNameInput to `width:100%;display:none` - set the content of BlockNameInput to BlockName - create TD in TR - set the style of TD to `border:1px solid black` - index EditButton to B - index DeleteBlock to B - index Editor to B - create Row in TD - set the style of Row to `display:flex` - create EditButton in Row - set the style of EditButton to `flex:1` - set the text of EditButton to `Edit` - create Cell in Row - set the style of Cell to `width:1.4em;text-align:center` - create Link in Cell - create DeleteBlock in Link - set the style of DeleteBlock to `width:1em;margin-top:0.1em` - set attribute `src` of DeleteBlock to `/resources/icon/stop.png` - create Editor in TD - set the style of Editor to `display:none` - add 1 to B - end - on click EditButton - begin - gosub to SaveSelectedBlock - put the index of EditButton into SelectedBlock - put the text of EditButton into Action - put 0 into N - while N is less than the json count of BlockNames - begin - index EditButton to N - set style `background` of EditButton to `` - set the text of EditButton to `Edit` - index BlockNameSpan to N - index BlockNameInput to N - set the content of BlockNameSpan to the text of BlockNameInput - set style `display` of BlockNameSpan to `inline` - set style `display` of BlockNameInput to `none` - index Editor to N - set style `display` of Editor to `none` - add 1 to N - end - index EditButton to SelectedBlock - if Action is `Edit` - begin - set style `background` of EditButton to `lightgray` - set the text of EditButton to `Properties` - index BlockNameSpan to SelectedBlock - index BlockNameInput to SelectedBlock - set style `display` of BlockNameSpan to `none` - set style `display` of BlockNameInput to `inline` - index Editor to SelectedBlock - set style `display` of Editor to `block` - clear Editor - put element SelectedBlock of BlockNames into BlockName - put property BlockName of Blocks into Block - put the json count of PropertyNames into N - set the elements of PropertyValue to N - put 0 into N - while N is less than the json count of PropertyNames - begin - create Row in Editor - set the style of Row to `display:flex` - put element N of PropertyNames into PropertyName - create Cell in Row - set the style of Cell to `width:8em;padding-left:0.5em` - set the content of Cell to PropertyName - index PropertyValue to N - create PropertyValue in Row - set the style of PropertyValue to `flex:1` - set the content of PropertyValue to property PropertyName of Block - add 1 to N - end - end - else gosub to SaveSelectedBlock - end - on click DeleteBlock - begin - put the index of DeleteBlock into N - put element N of BlockNames into BlockName - put property `blocks` of Presentation into Blocks - json delete property BlockName of Blocks - set property `blocks` of Presentation to Blocks - go to Restart - end - stop - -! Save the seleced block -SaveSelectedBlock: - if SelectedBlock is -1 return - put 0 into N - while N is less than the json count of PropertyNames - begin - put element N of PropertyNames into PropertyName - index PropertyValue to N - set property PropertyName of Block to PropertyValue - add 1 to N - end - set property BlockName of Blocks to Block - index BlockNameInput to SelectedBlock - if BlockNameInput is not BlockName - begin - json delete property BlockName of Blocks - put BlockNameInput into BlockName - set element SelectedBlock of BlockNames to BlockName - set property BlockName of Blocks to Block - end - set property `blocks` of Presentation to Blocks - return \ No newline at end of file diff --git a/mostrami/resources/ecs/container.txt b/mostrami/resources/ecs/container.txt deleted file mode 100644 index 4e2276d..0000000 --- a/mostrami/resources/ecs/container.txt +++ /dev/null @@ -1,12 +0,0 @@ -! Container - - script Container - - import div Panel and variable Presentation - - on message go to Start - set ready - stop - -Start: - stop \ No newline at end of file diff --git a/mostrami/resources/ecs/content.txt b/mostrami/resources/ecs/content.txt deleted file mode 100644 index 1d5e54b..0000000 --- a/mostrami/resources/ecs/content.txt +++ /dev/null @@ -1,196 +0,0 @@ -! Content - - script Content - - import div Panel and variable Presentation - - div Editor - div Row - div Cell - div Title - table Table - tr TR - td TD - span ItemNameSpan - span Span - input ItemNameInput - select TypeSelect - textarea TextArea - button EditButton - img AddItem - img DeleteItem - a Link - variable Items - variable Item - variable ItemNames - variable ItemName - variable TypeNames - variable Content - variable SelectedItem - variable Action - variable N - variable B - - put -1 into SelectedItem - - set TypeNames to array - json add `text` to TypeNames - json add `image` to TypeNames - - on message go to Start - set ready - stop - -Start: - if the message is `save` - begin - if SelectedItem is -1 stop - go to SaveSelectedItem - end - -Restart: - put property `content` of Presentation into Items - put the json keys of Items into ItemNames - - clear Panel - create Row in Panel - set the style of Row to `display:flex;margin-top:0.5em` - create Title in Row - set the style of Title to - `flex:1;font-size:110%;font-weight:bold;background:lightgray;text-align:center` - set the content of Title to `Content Items` - create Cell in Row - set the style of Cell to `width:1.4em;text-align:center` - create Link in Cell - create AddItem in Link - set the style of AddItem to `width:1em;margin-top:0.1em` - set attribute `src` of AddItem to `resources/icon/plus.png` - on click AddItem - begin - put prompt `Name of new content item:` with `new content` into ItemName - set Item to object - set property ItemName of Items to Item - set property `content` of Presentation to Items - go to Restart - end - - put the json count of ItemNames into N - set the elements of EditButton to N - set the elements of Editor to N - set the elements of DeleteItem to N - set the elements of TypeSelect to N - set the elements of TextArea to N - create Table in Panel - if N is greater than 0 set the style of Table to `width:100%;border:1px solid black` - put 0 into B - while B is less than the elements of EditButton - begin - put element B of ItemNames into ItemName - create TR in Table - create TD in TR - set the style of TD to `width:8em;border:1px solid black` - create ItemNameSpan in TD - set the content of ItemNameSpan to ItemName - create ItemNameInput in TD - set the style of ItemNameInput to `width:100%;display:none` - set the content of ItemNameInput to ItemName - create TD in TR - set the style of TD to `border:1px solid black` - index EditButton to B - index DeleteItem to B - index Editor to B - create Row in TD - set the style of Row to `display:flex` - create EditButton in Row - set the style of EditButton to `flex:1` - set the text of EditButton to `Edit` - create Cell in Row - set the style of Cell to `width:1.4em;text-align:center` - create Link in Cell - create DeleteItem in Link - set the style of DeleteItem to `width:1em;margin-top:0.1em` - set attribute `src` of DeleteItem to `/resources/icon/stop.png` - create Editor in TD - set the style of Editor to `display:none` - add 1 to B - end - on click EditButton - begin - put the index of EditButton into SelectedItem - put the text of EditButton into Action - put 0 into N - while N is less than the json count of ItemNames - begin - index EditButton to N - set style `background` of EditButton to `` - set the text of EditButton to `Edit` - index ItemNameSpan to N - index ItemNameInput to N - set the content of ItemNameSpan to the text of ItemNameInput - set style `display` of ItemNameSpan to `inline` - set style `display` of ItemNameInput to `none` - index Editor to N - set style `display` of Editor to `none` - add 1 to N - end - index EditButton to SelectedItem - if Action is `Edit` - begin - set style `background` of EditButton to `lightgray` - set the text of EditButton to `Content` - index ItemNameSpan to SelectedItem - index ItemNameInput to SelectedItem - index TypeSelect to SelectedItem - index TextArea to SelectedItem - set style `display` of ItemNameSpan to `none` - set style `display` of ItemNameInput to `inline` - index Editor to SelectedItem - set style `display` of Editor to `block` - clear Editor - put property ItemName of Items into Item - create Row in Editor - set the style of Row to `width:100%;display:flex` - create Span in Row - set the style of Span to `flex:1` - set the content of Span to `Type:` - create TypeSelect in Row - set the style of TypeSelect to `flex:1` - set TypeSelect from TypeNames as property `type` of Item - create TextArea in Editor - set the style of TextArea to `width:100%;max-width:100%;height:8em` - put element SelectedItem of ItemNames into ItemName - put property `content` of Item into Content - replace `%0a` with newline in Content - set the content of TextArea to Content - put property ItemName of Items into Item - end - else go to SaveSelectedItem - end - on click DeleteItem - begin - put the index of DeleteItem into N - put element N of ItemNames into ItemName - put property `content` of Presentation into Items - json delete property ItemName of Items - set property `content` of Presentation to Items - go to Restart - end - stop - -! Save the seleced content -SaveSelectedItem: - set property `type` of Item to TypeSelect - put the content of TextArea into Content - replace newline with `%0a` in Content - set property `content` of Item to Content - set property ItemName of Items to Item - index ItemNameInput to SelectedItem - if ItemNameInput is not ItemName - begin - json delete property ItemName of Items - put ItemNameInput into ItemName - set element SelectedItem of ItemNames to ItemName - set property ItemName of Items to Item - end - set property `content` of Presentation to Items - stop \ No newline at end of file diff --git a/mostrami/resources/ecs/defaults.txt b/mostrami/resources/ecs/defaults.txt deleted file mode 100644 index de42204..0000000 --- a/mostrami/resources/ecs/defaults.txt +++ /dev/null @@ -1,157 +0,0 @@ -! Defaults - - script Defaults - - import div Panel and variable Presentation - - div GlobalTitle - div GlobalPanel - div ContainerTitle - div ContainerPanel - div DefaultsTitle - div DefaultsPanel - div Row - div Label - input GlobalInput - input ContainerInput - input DefaultsInput - variable Globals - variable Container - variable Defaults - variable GlobalItems - variable ContainerItems - variable DefaultsItems - variable Name - variable Value - variable N - - on message go to Start - set ready - stop - -Start: - if the message is `save` - begin - stop - end - - clear Panel - - set style `display` of Panel to `flex` - set style `flex-direction` of Panel to `column` - - create GlobalTitle in Panel - set the style of GlobalTitle to `font-weight:bold;font-size:110%;background:lightgray;` - cat `padding:0.2em;text-align:center;margin-top:0.5em` - - create GlobalPanel in Panel - set the style of GlobalPanel to - `height:auto;max-height:25%;overflow-y:scroll;margin-top:0.5em` - - create ContainerTitle in Panel - set the style of ContainerTitle to `font-weight:bold;font-size:110%;background:lightgray;` - cat `padding:0.2em;text-align:center;margin-top:1em` - - create ContainerPanel in Panel - set the style of ContainerPanel to - `height:auto;max-height:20%;overflow-y:scroll;margin-top:0.5em` - - create DefaultsTitle in Panel - set the style of DefaultsTitle to `font-weight:bold;font-size:110%;background:lightgray;` - cat `padding:0.2em;text-align:center;margin-top:1em` - - create DefaultsPanel in Panel - set the style of DefaultsPanel to - `flex:1;max-height:60%;overflow-y:scroll;margin-top:0.5em` - - set GlobalItems to array - json add `title` to GlobalItems - json add `description` to GlobalItems - json add `aspectW` to GlobalItems - json add `aspectH` to GlobalItems - - set ContainerItems to array - json add `background` to ContainerItems - json add `border` to ContainerItems - - set DefaultsItems to array - json add `fontFamily` to DefaultsItems - json add `fontSize` to DefaultsItems - json add `fontWeight` to DefaultsItems - json add `fontStyle` to DefaultsItems - json add `fontColor` to DefaultsItems - json add `textAlign` to DefaultsItems - json add `textMarginLeft` to DefaultsItems - json add `textMarginTop` to DefaultsItems - json add `blockLeft` to DefaultsItems - json add `blockTop` to DefaultsItems - json add `blockWidth` to DefaultsItems - json add `blockBackground` to DefaultsItems - json add `blockBorder` to DefaultsItems - json add `blockBorderRadius` to DefaultsItems - - put property `global` of Presentation into Globals - put property `container` of Presentation into Container - put property `defaults` of Presentation into Defaults - - clear GlobalPanel - clear ContainerPanel - clear DefaultsPanel - set the content of GlobalTitle to `Global defaults` - set the content of ContainerTitle to `Container defaults` - set the content of DefaultsTitle to `Block defaults` - - put the json count of GlobalItems into N - set the elements of GlobalInput to N - put 0 into N - while N is less than the elements of GlobalInput - begin - create Row in GlobalPanel - set the style of Row to `display:flex;margin-top:0.2em` - create Label in Row - set the style of Label to `width:10em` - put element N of GlobalItems into Name - set the content of Label to Name - create GlobalInput in Row - set the style of GlobalInput to `flex:1;margin-right:0.5em` - put property Name of Globals into Value - set the text of GlobalInput to Value - add 1 to N - end - - put the json count of ContainerItems into N - set the elements of ContainerInput to N - put 0 into N - while N is less than the elements of ContainerInput - begin - create Row in ContainerPanel - set the style of Row to `display:flex;margin-top:0.2em` - create Label in Row - set the style of Label to `width:10em` - put element N of ContainerItems into Name - set the content of Label to Name - create ContainerInput in Row - set the style of ContainerInput to `flex:1;margin-right:0.5em` - put property Name of Container into Value - set the text of ContainerInput to Value - add 1 to N - end - - put the json count of DefaultsItems into N - set the elements of DefaultsInput to N - put 0 into N - while N is less than the elements of DefaultsInput - begin - create Row in DefaultsPanel - set the style of Row to `display:flex;margin-top:0.2em` - create Label in Row - set the style of Label to `width:10em` - put element N of DefaultsItems into Name - set the content of Label to Name - create DefaultsInput in Row - set the style of DefaultsInput to `flex:1;margin-right:0.5em` - put property Name of Defaults into Value - set the text of DefaultsInput to Value - add 1 to N - end - stop \ No newline at end of file diff --git a/mostrami/resources/ecs/globals.txt b/mostrami/resources/ecs/globals.txt deleted file mode 100644 index 41d4d8f..0000000 --- a/mostrami/resources/ecs/globals.txt +++ /dev/null @@ -1,12 +0,0 @@ -! Globals - - script Globals - - import div Panel and variable Presentation - - on message go to Start - set ready - stop - -Start: - stop \ No newline at end of file diff --git a/mostrami/resources/ecs/main.txt b/mostrami/resources/ecs/main.txt deleted file mode 100644 index 7d89664..0000000 --- a/mostrami/resources/ecs/main.txt +++ /dev/null @@ -1,548 +0,0 @@ -! Mostrami - - script Mostrami - - div Body - div Left - div Right - div Controls - div ContentDiv - div Buttons - div Tabs - div Tab - div ScriptName - div StepsPanel - div BlocksPanel - div ContentPanel - span Status - span Span - input NameEditor - button SectionButton - img New - img Open - img Save - img RunStop - img Delete - img Cycle - a Link - module StepsModule - module BlocksModule - module ContentModule - variable Mobile - variable LastSavedState - variable Content - variable Script - variable Presentation - variable Name - variable CurrentName - variable PasswordValid - variable ShowRun - variable ReadOnly - variable PasswordRequested - variable Password - variable CallStack - variable Message - variable Section - variable Item - variable CurrentScriptName - variable N - - ! The browser - div Overlay - div Scroller - div Media - div FileListing - div FileRow - div LowerPanel - button CloseButton - a FileName - variable Alpha - variable List - variable FileList - variable FileCount - variable File - variable Files - variable FileIsOpen - -! Test if site is on a static host - clear ReadOnly - rest get List from `_list/scripts` - or begin - print `Static site` - set ReadOnly - go to L2 - end -L2: - clear PasswordRequested - put empty into CallStack - history set - on restore - begin - put the json count of CallStack into N - end - if portrait - begin - if mobile set Mobile else clear Mobile - end - - set the title to `Mostrami Pro` - create Body - if Mobile - set the style of Body to `width:100%;height:100%` - else - set the style of Body to `width:100%;height:100%;display:flex` - - create Left in Body - set the style of Left to `flex:1;height:100%;display:flex;flex-direction:column;overflow:hidden` - - create Right in Body - set the style of Right to `flex:1;height:100%;display:flex;flex-direction: column` - - create Controls in Left - set the style of Controls to `flex:1;background:lightgray;padding:0 0.5em` - - create Buttons in Controls - set the style of Buttons to `width:100%;padding:0.5em 0` - - create ContentDiv in Left - set the style of ContentDiv to `width:100%;height:100%;position:relative` - - create Link in Buttons - create New in Link - set the style of New to `width:40px;margin-right:0.5em` - set attribute `src` of New to `resources/icon/new.png` - set attribute `title` of New to `New` - create Open in Link - set the style of Open to `width:40px;margin-right:0.5em` - set attribute `src` of Open to `resources/icon/open.png` - set attribute `title` of Open to `Open` - create Link in Buttons - create Save in Link - set the style of Save to `width:40px;margin-right:1.5em` - set attribute `src` of Save to `resources/icon/save.png` - set attribute `title` of Save to `Save` - create Link in Buttons - create Delete in Link - set the style of Delete to `width:40px;margin-right:1.5em` - set attribute `src` of Delete to `resources/icon/trash.png` - set attribute `title` of Delete to `Delete` - create Link in Buttons - create RunStop in Link - set the style of RunStop to `width:40px;margin-right:1.5em` - set attribute `src` of RunStop to `resources/icon/run.png` - set attribute `title` of RunStop to `Run` - create Link in Buttons - create Cycle in Link - set the style of Cycle to `width:40px` - set attribute `src` of Cycle to `resources/icon/cycle.png` - set attribute `title` of Cycle to `Cycle screens` - - create Status in Buttons - if Mobile set the style of Status to `height:1em` - else set the style of Status to `float:right;margin:0.5em 0 0 0;color:green` - - create ScriptName in Controls - set the style of ScriptName to `display:flex` - if Mobile set style `display` of ScriptName to `none` - create Span in ScriptName - set the style of Span to `flex:15` - set the content of Span to `Script name: ` - create NameEditor in ScriptName - set the style of NameEditor to `flex:85;display:inline-block` - - create Tabs in Controls - set the style of Tabs to `width:100%;padding:0.5em 0;text-align:center` - put the width of Tabs into N - divide N by 3 - set the elements of SectionButton to 3 - create Tab in Tabs - set the style of Tab to `display:inline-block;width:` cat N cat `px` - index SectionButton to 0 - create SectionButton in Tab - set the style of SectionButton to `width:100%` - set the content of SectionButton to `Steps` - create StepsPanel in ContentDiv - set the style of StepsPanel to `position:absolute;left:0;top:0;width:100%;height:100%;` - create Tab in Tabs - set the style of Tab to `display:inline-block;width:` cat N cat `px` - index SectionButton to 1 - create SectionButton in Tab - set the style of SectionButton to `width:100%` - set the content of SectionButton to `Blocks` - create BlocksPanel in ContentDiv - set the style of BlocksPanel to `position:absolute;left:0;top:0;width:100%;height:100%;` - create Tab in Tabs - set the style of Tab to `display:inline-block;width:` cat N cat `px` - index SectionButton to 2 - create SectionButton in Tab - set the style of SectionButton to `width:100%` - set the content of SectionButton to `Content` - create ContentPanel in ContentDiv - set the style of ContentPanel to `position:absolute;left:0;top:0;width:100%;height:100%;` - create Tab in Tabs - set the style of Tab to `display:inline-block;width:` cat N cat `px` - - put 0 into Section - index SectionButton to 0 - on click SectionButton - begin - put the index of SectionButton into N - gosub to SelectSection - end - -! Create the file browser - create Overlay in Body - set the style of Overlay to - `position:absolute;top:0;left:0;width:100vw;height:100vh;background:rgba(0,0,0,0.0);display:none` - - create Media in Overlay - set style of Media to `display:none;width:100%;height:100%;text-align:center` - - create FileListing in Media - set the style of FileListing to - `display:none;width:50%;height:75%;margin:auto;background-color:white;` - cat `padding:2em 2em 3em 2em;text-align:center;position: absolute;top: 50%;left: 50%;` - cat `transform: translateX(-50%) translateY(-50%)` - - create Scroller in FileListing - set the style of Scroller to `height:100%;overflow:scroll;text-align:left` - - create LowerPanel in FileListing - - create CloseButton in LowerPanel - set the style of CloseButton to `margin-left:2em` - set the text of CloseButton to `Close` - - put empty into LastSavedState - - on click New - begin -! gosub to StopTestModule - if Presentation is not LastSavedState - begin - if confirm `Content has changed. Do you want to save it?` - begin - put the content of NameEditor into Name - if Name is empty - begin - gosub to SetStatusRed - set the content of Status to `No script name has been given` - go to ResetStatus - end - if PasswordValid rest post Presentation to `_save/json/` cat Name - else put Presentation into storage as CurrentName - end - end - clear FileIsOpen - set the content of NameEditor to empty - put empty into CurrentScriptName - gosub to CreateNewPresentation - put Presentation into LastSavedState - gosub to UpdateCurrentSection - end - - on click Open go to DoOpen - - on click Save - begin - gosub to SaveChanges - gosub to GetPassword - put the content of NameEditor into Name - if Name is empty - begin - gosub to SetStatusRed - set the content of Status to `No script name has been given` - go to ResetStatus - end - if the position of `.json` in Name is -1 put Name cat `.json` into Name - replace ` ` with `_` in Name - set the content of NameEditor to Name - if Name is not CurrentScriptName put empty into LastSavedState - if Presentation is not LastSavedState - begin - if PasswordValid rest post Presentation to `_save/json/` cat Name - else put Presentation into storage as Name - put Presentation into LastSavedState - gosub to SetStatusGreen - set the content of Status to `Presentation '` cat Name cat `' saved` - put Name into CurrentScriptName - fork to ResetStatus - end - else - begin - gosub to SetStatusGreen - set the content of Status to `Nothing has changed` - fork to ResetStatus - end - end - - on click Delete - begin - gosub to GetPassword - put the content of NameEditor into Name - if Name is empty - begin - gosub to SetStatusGreen - set the content of Status to `Nothing to delete` - go to ResetStatus - end - if confirm `Are you sure you want to delete "` cat Name cat `"?` - begin - if PasswordValid rest post to `_delete/json/` cat Name - else remove Name from storage - gosub to SetStatusGreen - set the content of Status to `Script "` cat Name cat `" deleted` - set the content of NameEditor to empty - put empty into CurrentScriptName - put empty into Presentation - put Presentation into LastSavedState - go to ResetStatus - end - end - - gosub to CreateNewPresentation - put Presentation into LastSavedState - gosub to SetupSteps - gosub to SetupBlocks - gosub to SetupContent - put 0 into N - gosub to SelectSection - stop - -CreateNewPresentation: - set Presentation to object - set Item to object - set property `blocks` of Presentation to Item - set property `content` of Presentation to Item - set Item to array - set property `steps` of Presentation to Item - return - -SetupSteps: - if StepsModule is not running - begin - rest get Script from `/resources/ecs/steps.txt` - run Script with StepsPanel and Presentation as StepsModule - end - return - -SetupBlocks: - if BlocksModule is not running - begin - rest get Script from `/resources/ecs/blocks.txt` - run Script with BlocksPanel and Presentation as BlocksModule - end - return - -SetupContent: - if ContentModule is not running - begin - rest get Script from `/resources/ecs/content.txt` - run Script with ContentPanel and Presentation as ContentModule - end - return - -! Select one of the 3 sections -SelectSection: - gosub to SaveChanges - index SectionButton to Section - set style `background` of SectionButton to `` - put N into Section - index SectionButton to Section - set style `background` of SectionButton to `lightgray` - -! Update the current section -UpdateCurrentSection: - set style `display` of StepsPanel to `none` - set style `display` of BlocksPanel to `none` - set style `display` of ContentPanel to `none` - if Section is 0 - begin - set style `display` of StepsPanel to `block` - send to StepsModule - end - else if Section is 1 - begin - set style `display` of BlocksPanel to `block` - send to BlocksModule - end - else if Section is 2 - begin - set style `display` of ContentPanel to `block` - send to ContentModule - end - return - -SaveChanges: - send `save` to StepsModule - send `save` to BlocksModule - send `save` to ContentModule - return - -DoOpen: -! gosub to StopTestModule - gosub to GetPassword - - clear FileIsOpen - if Presentation is not LastSavedState - begin - if confirm `Content has changed. Do you want to save it?` - begin - if PasswordValid rest post Content to `_save/json/` cat Name - else put Content into storage as Name - end - end - - ! Animate the background - set style `display` of Overlay to `block` - put 0 into Alpha - while Alpha is less than 8 - begin - set style `background-color` of Overlay to `rgba(0,0,0,0.` cat Alpha cat `)` - wait 4 ticks - add 1 to Alpha - end - wait 10 ticks - - ! Make the browser panel visible - set style `display` of Media to `block` - set style `display` of FileListing to `inline-block` - - ! Fill the browser with content from the server - if PasswordValid - begin - rest get Files from `_list/json` - put the json count of Files into FileCount - put empty into Content - put 0 into N - while N is less than FileCount - begin - put element N of Files into Item - if property `type` of Item is `json` json add property `name` of Item to Content - add 1 to N - end - end - else - begin - get Files from storage - put the json count of Files into FileCount - put empty into Content - put 0 into N - while N is less than FileCount - begin - put element N of Files into Item - if left 1 of Item is not `.` json add Item to Content - add 1 to N - end - end - json sort Content - put empty into FileList - put the json count of Content into FileCount - set the elements of File to FileCount - set the elements of FileName to FileCount - ! Add a row for each file - put 0 into N - while N is less than FileCount - begin - index File to N - index FileName to N - put `<div id="ec-file-row-INDEX" style="clear:both;padding:0.25em 0;">` - cat `<a id="ec-file-name-INDEX" href="#"></a></div>` into File - replace `INDEX` with N in File - if N is even replace `ODDEVEN` with `ec-even` in File - else replace `ODDEVEN` with `ec-odd` in File - put FileList cat File into FileList - add 1 to N - end - - set the content of Scroller to FileList - ! Add the document names - put 0 into N - while N is less than FileCount - begin - index File to N - index FileName to N - put element N of Content into File - attach FileRow to `ec-file-row-` cat N - attach FileName to `ec-file-name-` cat N - set the content of FileName to File - if N is even set style `background` of FileRow to `lightgray` - on click FileName go to SelectFile - add 1 to N - end - on click CloseButton - begin - put LastSavedState into Content - go to CloseBrowser - end - stop - -SelectFile: - index File to the index of FileName - set the content of NameEditor to File - put File into CurrentScriptName - if PasswordValid rest get Presentation from `/resources/json/` cat File - else get Presentation from storage as File - put Presentation into LastSavedState - gosub to UpdateCurrentSection - set the content of Status to `Presentation '` cat File cat `' loaded` - fork to ResetStatus - set ShowRun - -CloseBrowser: - set style `background-color` of Overlay to `rgba(0,0,0,0.0)` - set style `display` of Overlay to `none` - set style `display` of Media to `none` - stop - -SetStatusRed: - set style `color` of Status to `red` - return - -SetStatusGreen: - set style `color` of Status to `green` - return - -ResetStatus: - wait 2 - set the content of Status to `` - stop - -GetPassword: - if ReadOnly - begin - clear PasswordValid - return - end - if the hostname is `localhost` go to SetPasswordValid - if the hostname is `127.0.0.1` go to SetPasswordValid - - if not PasswordRequested - begin - set PasswordRequested - if hostname is `localhost` goto SetPasswordValid - if hostname is `127.0.0.1` goto SetPasswordValid - get Password from storage as `.password` - if Password is empty - begin - put `Please provide the admin password` cat newline - cat `or click OK to use private browser storage.` into Message - put prompt Message with `` into Password - end - rest get PasswordValid from `_verify/` cat Password - or begin - clear PasswordValid - return - end - if PasswordValid is `yes` - begin - put Password into storage as `.password` - set PasswordValid - end - else clear PasswordValid - end - return - -SetPasswordValid: - set PasswordValid - return \ No newline at end of file diff --git a/mostrami/resources/ecs/mostrami.txt b/mostrami/resources/ecs/mostrami.txt deleted file mode 100644 index 2cbb885..0000000 --- a/mostrami/resources/ecs/mostrami.txt +++ /dev/null @@ -1,560 +0,0 @@ -! Mostrami - - script Mostrami - - div Body - div Left - div Right - div Controls - div ContentDiv - div Buttons - div Tabs - div Tab - div ScriptName - div StepsPanel - div BlocksPanel - div ContentPanel - div DefaultsPanel - span Status - span Span - input NameEditor - button SectionButton - img New - img Open - img Save - img RunStop - img Delete - img Cycle - a Link - module StepsModule - module BlocksModule - module ContentModule - module DefaultsModule - variable Mobile - variable Current - variable Content - variable Script - variable Presentation - variable Name - variable CurrentName - variable PasswordValid - variable ShowRun - variable ReadOnly - variable PasswordRequested - variable Password - variable CallStack - variable Message - variable Section - variable Item - variable CurrentScriptName - variable N - - ! The browser - div Overlay - div Scroller - div Media - div FileListing - div FileRow - div LowerPanel - button CloseButton - a FileName - variable Alpha - variable List - variable FileList - variable FileCount - variable File - variable Files - variable FileIsOpen - -! Test if site is on a static host - clear ReadOnly - rest get List from `_list/scripts` - or begin - print `Static site` - set ReadOnly - go to L2 - end -L2: - clear PasswordRequested - put empty into CallStack - history set - on restore - begin - put the json count of CallStack into N - end - if portrait - begin - if mobile set Mobile else clear Mobile - end - - set the title to `Mostrami Pro` - create Body - if Mobile - set the style of Body to `width:100%;height:100%` - else - set the style of Body to `width:100%;height:100%;display:flex` - - create Left in Body - set the style of Left to `flex:1;height:100%;display:flex;flex-direction:column;overflow:hidden` - - create Right in Body - set the style of Right to `flex:1;height:100%;display:flex;flex-direction: column` - - create Controls in Left - set the style of Controls to `flex:1;background:lightgray;padding:0 0.5em` - - create Buttons in Controls - set the style of Buttons to `width:100%;padding:0.5em 0` - - create ContentDiv in Left - set the style of ContentDiv to `width:100%;height:100%;position:relative` - - create Link in Buttons - create New in Link - set the style of New to `width:40px;margin-right:0.5em` - set attribute `src` of New to `resources/icon/new.png` - set attribute `title` of New to `New` - create Open in Link - set the style of Open to `width:40px;margin-right:0.5em` - set attribute `src` of Open to `resources/icon/open.png` - set attribute `title` of Open to `Open` - create Link in Buttons - create Save in Link - set the style of Save to `width:40px;margin-right:1.5em` - set attribute `src` of Save to `resources/icon/save.png` - set attribute `title` of Save to `Save` - create Link in Buttons - create Delete in Link - set the style of Delete to `width:40px;margin-right:1.5em` - set attribute `src` of Delete to `resources/icon/trash.png` - set attribute `title` of Delete to `Delete` - create Link in Buttons - create RunStop in Link - set the style of RunStop to `width:40px;margin-right:1.5em` - set attribute `src` of RunStop to `resources/icon/run.png` - set attribute `title` of RunStop to `Run` - create Link in Buttons - create Cycle in Link - set the style of Cycle to `width:40px` - set attribute `src` of Cycle to `resources/icon/cycle.png` - set attribute `title` of Cycle to `Cycle screens` - - create Status in Buttons - if Mobile set the style of Status to `height:1em` - else set the style of Status to `float:right;margin:0.5em 0 0 0;color:green` - - create ScriptName in Controls - set the style of ScriptName to `display:flex` - if Mobile set style `display` of ScriptName to `none` - create Span in ScriptName - set the style of Span to `flex:15` - set the content of Span to `Script name: ` - create NameEditor in ScriptName - set the style of NameEditor to `flex:85;display:inline-block` - - create Tabs in Controls - set the style of Tabs to `width:100%;padding:0.5em 0;text-align:center` - put the width of Tabs into N - divide N by 4 - set the elements of SectionButton to 4 - create Tab in Tabs - set the style of Tab to `display:inline-block;width:` cat N cat `px` - index SectionButton to 0 - create SectionButton in Tab - set the style of SectionButton to `width:100%` - set the content of SectionButton to `Steps` - create StepsPanel in ContentDiv - set the style of StepsPanel to `position:absolute;left:0;top:0;width:100%;height:100%;` - create Tab in Tabs - set the style of Tab to `display:inline-block;width:` cat N cat `px` - index SectionButton to 1 - create SectionButton in Tab - set the style of SectionButton to `width:100%` - set the content of SectionButton to `Blocks` - create BlocksPanel in ContentDiv - set the style of BlocksPanel to `position:absolute;left:0;top:0;width:100%;height:100%;` - create Tab in Tabs - set the style of Tab to `display:inline-block;width:` cat N cat `px` - index SectionButton to 2 - create SectionButton in Tab - set the style of SectionButton to `width:100%` - set the content of SectionButton to `Content` - create ContentPanel in ContentDiv - set the style of ContentPanel to `position:absolute;left:0;top:0;width:100%;height:100%;` - create Tab in Tabs - set the style of Tab to `display:inline-block;width:` cat N cat `px` - index SectionButton to 3 - create SectionButton in Tab - set the style of SectionButton to `width:100%` - set the content of SectionButton to `Defaults` - create DefaultsPanel in ContentDiv - set the style of DefaultsPanel to `position:absolute;left:0;top:0;width:100%;height:100%;` - - put 0 into Section - index SectionButton to 0 - on click SectionButton gosub to SelectSection - -! Create the file browser - create Overlay in Body - set the style of Overlay to - `position:absolute;top:0;left:0;width:100vw;height:100vh;background:rgba(0,0,0,0.0);display:none` - - create Media in Overlay - set style of Media to `display:none;width:100%;height:100%;text-align:center` - - create FileListing in Media - set the style of FileListing to - `display:none;width:50%;height:75%;margin:auto;background-color:white;` - cat `padding:2em 2em 3em 2em;text-align:center;position: absolute;top: 50%;left: 50%;` - cat `transform: translateX(-50%) translateY(-50%)` - - create Scroller in FileListing - set the style of Scroller to `height:100%;overflow:scroll;text-align:left` - - create LowerPanel in FileListing - - create CloseButton in LowerPanel - set the style of CloseButton to `margin-left:2em` - set the text of CloseButton to `Close` - - put empty into Current - - on click New - begin -! gosub to StopTestModule - if Presentation is not Current - begin - if confirm `Content has changed. Do you want to save it?` - begin - put the content of NameEditor into Name - if Name is empty - begin - gosub to SetStatusRed - set the content of Status to `No script name has been given` - go to ResetStatus - end - if PasswordValid rest post Presentation to `_save/json/` cat Name - else put Presentation into storage as CurrentName - end - end - clear FileIsOpen - set the content of NameEditor to empty - put empty into CurrentScriptName - gosub to CreateNewPresentation - put Presentation into Current - gosub to UpdateCurrentSection - end - - on click Open go to DoOpen - - on click Save - begin - gosub to GetPassword - put the content of NameEditor into Name - if Name is empty - begin - gosub to SetStatusRed - set the content of Status to `No script name has been given` - go to ResetStatus - end - if the position of `.json` in Name is -1 put Name cat `.json` into Name - replace ` ` with `_` in Name - set the content of NameEditor to Name - if Name is not CurrentScriptName put empty into Current - if Presentation is not Current - begin - if PasswordValid rest post Presentation to `_save/json/` cat Name - else put Presentation into storage as Name - put Presentation into Current - gosub to SetStatusGreen - set the content of Status to `Presentation '` cat Name cat `' saved` - put Name into CurrentScriptName - fork to ResetStatus - end - else - begin - gosub to SetStatusGreen - set the content of Status to `Nothing has changed` - fork to ResetStatus - end - end - - on click Delete - begin - gosub to GetPassword - put the content of NameEditor into Name - if Name is empty - begin - gosub to SetStatusGreen - set the content of Status to `Nothing to delete` - go to ResetStatus - end - if confirm `Are you sure you want to delete "` cat Name cat `"?` - begin - if PasswordValid rest post to `_delete/json/` cat Name - else remove Name from storage - gosub to SetStatusGreen - set the content of Status to `Script "` cat Name cat `" deleted` - set the content of NameEditor to empty - put empty into CurrentScriptName - put empty into Presentation - put Presentation into Current - go to ResetStatus - end - end - - gosub to CreateNewPresentation - gosub to SetupSteps - gosub to SetupBlocks - gosub to SetupContent - gosub to SetupDefaults - gosub to SelectSection - put Presentation into Current - stop - -CreateNewPresentation: - set Presentation to object - set Item to object - set property `global` of Presentation to Item - set property `container` of Presentation to Item - set property `defaults` of Presentation to Item - set property `blocks` of Presentation to Item - set property `content` of Presentation to Item - set Item to array - set property `steps` of Presentation to Item - return - -SetupSteps: - if StepsModule is not running - begin - rest get Script from `/resources/ecs/steps.txt` - run Script with StepsPanel and Presentation as StepsModule - end - return - -SetupBlocks: - if BlocksModule is not running - begin - rest get Script from `/resources/ecs/blocks.txt` - run Script with BlocksPanel and Presentation as BlocksModule - end - return - -SetupContent: - if ContentModule is not running - begin - rest get Script from `/resources/ecs/content.txt` - run Script with ContentPanel and Presentation as ContentModule - end - return - -SetupDefaults: - if DefaultsModule is not running - begin - rest get Script from `/resources/ecs/defaults.txt` - run Script with DefaultsPanel and Presentation as DefaultsModule - end - return - -SelectSection: - put the index of SectionButton into N - index SectionButton to Section - set style `background` of SectionButton to `` - put N into Section - index SectionButton to Section - set style `background` of SectionButton to `lightgray` - -UpdateCurrentSection: - set style `display` of StepsPanel to `none` - set style `display` of BlocksPanel to `none` - set style `display` of ContentPanel to `none` - set style `display` of DefaultsPanel to `none` - if Section is 0 - begin - set style `display` of StepsPanel to `block` - send to StepsModule - end - else if Section is 1 - begin - set style `display` of BlocksPanel to `block` - send to BlocksModule - end - else if Section is 2 - begin - set style `display` of ContentPanel to `block` - send to ContentModule - end - else if Section is 3 - begin - set style `display` of DefaultsPanel to `block` - send to DefaultsModule - end - return - -DoOpen: -! gosub to StopTestModule - gosub to GetPassword - - clear FileIsOpen - if Presentation is not Current - begin - if confirm `Content has changed. Do you want to save it?` - begin - if PasswordValid rest post Content to `_save/json/` cat Name - else put Content into storage as Name - end - end - - ! Animate the background - set style `display` of Overlay to `block` - put 0 into Alpha - while Alpha is less than 8 - begin - set style `background-color` of Overlay to `rgba(0,0,0,0.` cat Alpha cat `)` - wait 4 ticks - add 1 to Alpha - end - wait 10 ticks - - ! Make the browser panel visible - set style `display` of Media to `block` - set style `display` of FileListing to `inline-block` - - ! Fill the browser with content from the server - if PasswordValid - begin - rest get Files from `_list/json` - put the json count of Files into FileCount - put empty into Content - put 0 into N - while N is less than FileCount - begin - put element N of Files into Item - if property `type` of Item is `json` json add property `name` of Item to Content - add 1 to N - end - end - else - begin - get Files from storage - put the json count of Files into FileCount - put empty into Content - put 0 into N - while N is less than FileCount - begin - put element N of Files into Item - if left 1 of Item is not `.` json add Item to Content - add 1 to N - end - end - json sort Content - put empty into FileList - put the json count of Content into FileCount - set the elements of File to FileCount - set the elements of FileName to FileCount - ! Add a row for each file - put 0 into N - while N is less than FileCount - begin - index File to N - index FileName to N - put `<div id="ec-file-row-INDEX" style="clear:both;padding:0.25em 0;">` - cat `<a id="ec-file-name-INDEX" href="#"></a></div>` into File - replace `INDEX` with N in File - if N is even replace `ODDEVEN` with `ec-even` in File - else replace `ODDEVEN` with `ec-odd` in File - put FileList cat File into FileList - add 1 to N - end - - set the content of Scroller to FileList - ! Add the document names - put 0 into N - while N is less than FileCount - begin - index File to N - index FileName to N - put element N of Content into File - attach FileRow to `ec-file-row-` cat N - attach FileName to `ec-file-name-` cat N - set the content of FileName to File - if N is even set style `background` of FileRow to `lightgray` - on click FileName go to SelectFile - add 1 to N - end - on click CloseButton - begin - put Current into Content - go to CloseBrowser - end - stop - -SelectFile: - index File to the index of FileName - set the content of NameEditor to File - put File into CurrentScriptName - if PasswordValid rest get Presentation from `/resources/json/` cat File - else get Presentation from storage as File - put Presentation into Current - gosub to UpdateCurrentSection - set the content of Status to `Presentation '` cat File cat `' loaded` - fork to ResetStatus - set ShowRun - -CloseBrowser: - set style `background-color` of Overlay to `rgba(0,0,0,0.0)` - set style `display` of Overlay to `none` - set style `display` of Media to `none` - stop - -SetStatusRed: - set style `color` of Status to `red` - return - -SetStatusGreen: - set style `color` of Status to `green` - return - -ResetStatus: - wait 2 - set the content of Status to `` - stop - -GetPassword: - if ReadOnly - begin - clear PasswordValid - return - end - if the hostname is `localhost` go to SetPasswordValid - if the hostname is `127.0.0.1` go to SetPasswordValid - - if not PasswordRequested - begin - set PasswordRequested - if hostname is `localhost` goto SetPasswordValid - if hostname is `127.0.0.1` goto SetPasswordValid - get Password from storage as `.password` - if Password is empty - begin - put `Please provide the admin password` cat newline - cat `or click OK to use private browser storage.` into Message - put prompt Message with `` into Password - end - rest get PasswordValid from `_verify/` cat Password - or begin - clear PasswordValid - return - end - if PasswordValid is `yes` - begin - put Password into storage as `.password` - set PasswordValid - end - else clear PasswordValid - end - return - -SetPasswordValid: - set PasswordValid - return \ No newline at end of file diff --git a/mostrami/resources/ecs/scripted.txt b/mostrami/resources/ecs/scripted.txt deleted file mode 100644 index 79bbbcc..0000000 --- a/mostrami/resources/ecs/scripted.txt +++ /dev/null @@ -1,279 +0,0 @@ -! Script editor - - script ScriptEditor - - div Body - div Container - div Buttons - div ScriptName - div ContentDiv - input NameEditor - textarea ContentEditor - span Status - span Span - button Open - button Save - button Delete - variable Name - variable CurrentName - variable Content - variable Current - variable Password - variable Valid - -! The browser - div Overlay - div Scroller - div Media - div FileListing - div FileRow - button CloseButton - a FileName - variable Alpha - variable FileList - variable FileCount - variable File - variable Files - variable N - variable FileIsOpen - variable Item - - set the title to `Script Editor` - - get Password from storage as `.password` - if Password is empty - put prompt `Please type the admin password` with `` into Password - rest get Valid from `_verify/` cat Password - or begin - print Valid - alert `Unable to verify password.` - put empty into storage as `.password` - end - if Valid is `yes` put Password into storage as `.password` - - create Body - create Container in Body - set the style of Container to `width:70%;margin:0 auto;background #ffe` - - create Buttons in Container - set the style of Buttons to `text-align:center` - - create Open in Buttons - set the style of Open to `margin-right:0.5em` - set the text of Open to `Open` - create Save in Buttons - set the text of Save to `Save` - set the style of Save to `margin-right:4em` - create Delete in Buttons - set the text of Delete to `Delete` - create Status in Buttons - set the style of Status to `position:absolute;float:right;padding-left:2em;color:green` - - create ScriptName in Container - set the style of ScriptName to `display:flex;margin:0.5em 0` - create Span in ScriptName - set the style of Span to `flex:15` - set the content of Span to `Script name: ` - create NameEditor in ScriptName - set the style of NameEditor to `flex:85;display:inline-block` - set the size of NameEditor to 40 - - create ContentDiv in Container - set the style of ContentDiv to `width:100%;height:85%;border:1px solid lightgray` - - create ContentEditor in ContentDiv - set the style of ContentEditor to `width:100%;height:100%` - - codemirror init basic profile `https://cdn.jsdelivr.net/gh/easycoder/easycoder.github.io/dist/plugins/codemirror-ecs.js` - require css `https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.46.0/addon/dialog/dialog.css` - require js `https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.46.0/addon/dialog/dialog.js` - require js `https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.46.0/addon/search/search.js` - require js `https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.46.0/addon/search/searchcursor.js` - require js `https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.46.0/addon/search/jump-to-line.js` - - create Overlay in Body - set the style of Overlay to - `position:absolute;top:0;left:0;width:100vw;height:100vh;background:rgba(0,0,0,0.0);display:none` - - create Media in Overlay - set style of Media to `display:none;width:100%;height:100%;text-align:center` - - create FileListing in Media - set the style of FileListing to - `display:none;width:50%;height:75%;margin:auto;background-color:white;` - cat `padding:2em 2em 3em 2em;text-align:center;position: absolute;top: 50%;left: 50%;` - cat `transform: translateX(-50%) translateY(-50%)` - - create Scroller in FileListing - set the style of Scroller to `height:100%;overflow:scroll;text-align:left` - - create CloseButton in FileListing - set the text of CloseButton to `Close` - - codemirror attach to ContentEditor - codemirror set content of ContentEditor to Content - set FileIsOpen - - put empty into Current - - on click Save - begin - put the content of NameEditor into Name - if Name is empty - begin - set the content of Status to `No script name has been given` - go to ResetStatus - end - replace ` ` with `_` in Name - if the position of `.txt` in Name is -1 put Name cat `.txt` into Name - codemirror close ContentEditor - put the content of ContentEditor into Content - if Content is not Current - begin - rest post Content to `_save/ecs/` cat Name - put Content into Current - set the content of Status to `Script '` cat Name cat `' saved` - fork to ResetStatus - end - else - begin - set the content of Status to `Nothing has changed` - fork to ResetStatus - end - codemirror attach to ContentEditor - end - - on click Open go to DoOpen - - on click Delete - begin - put the content of NameEditor into Name - if Name is empty - begin - alert `Nothing to delete.` - stop - end - if confirm `Are you sure you want to delete '` cat Name cat `'?` - begin - codemirror close ContentEditor - rest post to `_delete/ecs/` cat Name - set the content of Status to `Script '` cat Name cat `' deleted` - set the content of NameEditor to empty - put empty into Content - set the content of ContentEditor to Content - put Content into Current - go to ResetStatus - end - end - stop - -DoOpen: - if FileIsOpen codemirror close ContentEditor - put the content of ContentEditor into Content - if Content is not Current - begin - if confirm `Content has changed. Do you want to save it?` - begin - rest post Content to `_save/ecs/' cat CurrentName - codemirror attach to ContentEditor - codemirror set content of ContentEditor to Content - end - else - begin - codemirror attach to ContentEditor - codemirror set content of ContentEditor to Content - stop - end - end - -! Animate the background - set style `display` of Overlay to `block` - put 0 into Alpha - while Alpha is less than 8 - begin - set style `background-color` of Overlay to `rgba(0,0,0,0.` cat Alpha cat `)` - wait 4 ticks - add 1 to Alpha - end - wait 10 ticks - -! Make the browser panel visible - set style `display` of Media to `block` - set style `display` of FileListing to `inline-block` - -! Fill the browser with content from the server - rest get Files from `_list/ecs?v=` cat now - put the json count of Files into FileCount - put empty into Content - put 0 into N - while N is less than FileCount - begin - put element N of Files into Item - if property `type` of Item is `txt` json add Item to Content - add 1 to N - end - json sort Content - put empty into FileList - put the json count of Content into FileCount - set the elements of File to FileCount - set the elements of FileName to FileCount -! Add a row for each file - put empty into FileList - put 0 into N - while N is less than FileCount - begin - index File to N - index FileName to N - put `<div id="ec-file-row-INDEX" style="clear:both;padding:0.25em 0;">` - cat `<a id="ec-file-name-INDEX" href="#"></a></div>` into File - replace `INDEX` with N in File - if N is even replace `ODDEVEN` with `ec-even` in File - else replace `ODDEVEN` with `ec-odd` in File - put FileList cat File into FileList - add 1 to N - end - - set the content of Scroller to FileList -! Add the document names - put 0 into N - while N is less than FileCount - begin - index File to N - index FileName to N - put element N of Content into File - attach FileRow to `ec-file-row-` cat N - attach FileName to `ec-file-name-` cat N - put property `name` of File into File - set the content of FileName to File - if N is even set style `background` of FileRow to `lightgray` - on click FileName go to SelectFile - add 1 to N - end - on click CloseButton - begin - put Current into Content - go to CloseBrowser - end - stop - -SelectFile: - index File to the index of FileName - set the content of NameEditor to File - rest get Content from `/resources/ecs/` cat File cat `?v=` cat now - put Content into Current - set the content of Status to `Script '` cat File cat `' loaded` - fork to ResetStatus - set the title to `Script Editor - ` cat File - -CloseBrowser: - set style `background-color` of Overlay to `rgba(0,0,0,0.0)` - set style `display` of Overlay to `none` - set style `display` of Media to `none` - codemirror attach to ContentEditor - codemirror set content of ContentEditor to Content - stop - -ResetStatus: - wait 2 - set the content of Status to `` - stop \ No newline at end of file diff --git a/mostrami/resources/ecs/steps.txt b/mostrami/resources/ecs/steps.txt deleted file mode 100644 index 1509a88..0000000 --- a/mostrami/resources/ecs/steps.txt +++ /dev/null @@ -1,910 +0,0 @@ -! Steps - - script Steps - - import div Panel and variable Presentation - - div StepsPanel - div BlockTable - div BlockRow - div BlockData - div Row - div Row1 - div Cell - div Editor - div Title - button StepButton - button Header - button InsertBefore - button InsertAfter - table Table - tr TR - td TD - select ActionSelect - select BlockSelect - select ContentSelect - select TargetSelect - select TransitionSelect - select ContinueSelect - input InitInput - input TitleInput - input LabelInput - input DurationInput - input TargetInput - input URLInput - img AddStep - img PlusIcon - img DeleteIcon - img DeleteStep - a Link - variable Steps - variable SelectedStep - variable CurrentStep - variable Action - variable Blocks - variable Block - variable Contents - variable Content - variable Target - variable Types - variable Duration - variable URL - variable Names - variable ActionNames - variable InitProperties - variable InitProperty - variable BlockNames - variable ContentNames - variable TransitionTypes - variable TransitionType - variable ContinueTypes - variable TrueFalse - variable Response - variable N - variable B - - put -1 into SelectedStep - - create StepsPanel in Panel - set the style of StepsPanel to `flex:1;overflow-y:scroll;margin-top:0.5em` - - on message go to Start - set ready - stop - -Start: - if the message is `save` - begin - if SelectedStep is not -1 - begin - gosub to SaveCurrentStep - put -1 into SelectedStep - end - stop - end - - set style `display` of Panel to `flex` - set style `flex-direction` of Panel to `column` - -Restart: - clear StepsPanel - create Row in StepsPanel - set the style of Row to `display:flex` - create Title in Row - set the style of Title to - `flex:1;font-size:110%;font-weight:bold;background:lightgray;text-align:center` - set the content of Title to `Steps` - create Cell in Row - set the style of Cell to `width:1.4em;text-align:center` - create Link in Cell - create AddStep in Link - set the style of AddStep to `width:1em;margin-top:0.1em` - set attribute `src` of AddStep to `resources/icon/plus.png` - on click AddStep go to AddNewStep - - put property `steps` of Presentation into Steps - put the json count of Steps into N - set the elements of StepButton to N - set the elements of DeleteStep to N - set the elements of TitleInput to N - set the elements of LabelInput to N - set the elements of Editor to N - put 0 into N - while N is less than the elements of StepButton - begin - index StepButton to N - create Row in StepsPanel - set the style of Row to `width:100%` - create Row1 in Row - set the style of Row1 to `display:flex;margin:0.2em 0` - create StepButton in Row1 - set the style of StepButton to `flex:1` - put element N of Steps into CurrentStep - set the text of StepButton to property `comment` of CurrentStep - create Cell in Row1 - set the style of Cell to `width:1.4em;text-align:center` - index DeleteStep to N - create Link in Cell - create DeleteStep in Link - set the style of DeleteStep to `width:1em;margin-top:0.1em` - set attribute `src` of DeleteStep to `resources/icon/stop.png` - index Editor to N - create Editor in Row - add 1 to N - end - on click StepButton - begin - gosub to SaveCurrentStep - put SelectedStep into N - put the index of StepButton into SelectedStep - if SelectedStep is N - begin - index Editor to N - set style `display` of Editor to `none` - index StepButton to N - set style `background` of StepButton to `` - gosub to SaveCurrentStep - put -1 into SelectedStep - end - else - begin - if N is not -1 - begin - gosub to SaveCurrentStep - put 0 into N - while N is less than the elements of StepButton - begin - index Editor to N - set style `display` of Editor to `none` - index StepButton to N - set style `background` of StepButton to `` - add 1 to N - end - end - index StepButton to SelectedStep - set style `background` of StepButton to `lightgray` - index Editor to SelectedStep - set style `display` of Editor to `block` - put element SelectedStep of Steps into CurrentStep - go to EditStep - end - end - on click DeleteStep - begin - put the index of DeleteStep into N - json delete element N of Steps - set property `steps` of Presentation to Steps - go to Restart - end - -! Set up the fixed lists - set ActionNames to array - json add `init` to ActionNames - json add `set content` to ActionNames - json add `show` to ActionNames - json add `hide` to ActionNames - json add `pause` to ActionNames - json add `hold` to ActionNames - json add `fade up` to ActionNames - json add `fade down` to ActionNames - json add `crossfade` to ActionNames - json add `transition` to ActionNames - json add `goto` to ActionNames - json add `load` to ActionNames - set InitProperties to array - json add `title` to InitProperties - json add `aspect ratio` to InitProperties - json add `background` to InitProperties - json add `border` to InitProperties - set TransitionTypes to array - json add `block position` to TransitionTypes - json add `block size` to TransitionTypes - json add `font color` to TransitionTypes - json add `font size` to TransitionTypes - set ContinueTypes to array - json add `true` to ContinueTypes - json add `false` to ContinueTypes - - put property `steps` of Presentation into Steps - - stop - -! Add a new step to the list -AddNewStep: - gosub to CreateNewStep - json add CurrentStep to Steps - go to ASA3 - -! Add a step before the current one -AddStepBefore: - put the json count of Steps into N - set CurrentStep to object - json add CurrentStep to Steps - go to ASA2 - -! Add a step after the current one -AddStepAfter: - put the json count of Steps into N - set CurrentStep to object - json add CurrentStep to Steps - add 1 to SelectedStep -ASA2: - while N is greater than SelectedStep - begin - take 1 from N - put element N of Steps into CurrentStep - add 1 to N - set element N of Steps to CurrentStep - take 1 from N - end - gosub to CreateNewStep - set element N of Steps to CurrentStep -ASA3: - put -1 into SelectedStep - set property `steps` of Presentation to Steps - go to Restart - -CreateNewStep: - set CurrentStep to object - set property `comment` of CurrentStep to `New step` - set property `action` of CurrentStep to `` - set property `label` of CurrentStep to `` - return - -! Edit a single step -EditStep: - put property `blocks` of Presentation into Blocks - put property `content` of Presentation into Contents - put the json keys of Blocks into BlockNames - put the json keys of Contents into ContentNames - put element SelectedStep of Steps into CurrentStep - - clear Editor - create Table in Editor - -ReloadStepEditor: - set the style of Table to `width:100%` - create TR in Table - create TD in TR - set the style of TD to `width:6em` - set the content of TD to `Title:` - create TD in TR - index TitleInput to SelectedStep - create TitleInput in TD - set the style of TitleInput to `width:100%` - set the content of TitleInput to property `comment` of CurrentStep - create TR in Table - create TD in TR - set the style of TD to `width:6em` - set the content of TD to `Label:` - create TD in TR - index LabelInput to SelectedStep - create LabelInput in TD - set the style of LabelInput to `width:100%` - set the content of LabelInput to property `label` of CurrentStep - create TR in Table - create TD in TR - set the content of TD to `Action:` - create TD in TR - create ActionSelect in TD - set the style of ActionSelect to `width:100%` - put property `action` of CurrentStep into Action - set ActionSelect from ActionNames as Action - if Action is `init` gosub to EditInit - else if Action is `set content` gosub to EditSetContent - else if Action is `show` gosub to EditShow - else if Action is `hide` gosub to EditHide - else if Action is `pause` gosub to EditPause - else if Action is `hold` gosub to EditHold - else if Action is `fade up` gosub to EditFadeUp - else if Action is `fade down` gosub to EditFadeDown - else if Action is `crossfade` gosub to EditCrossfade - else if Action is `transition` gosub to EditTransition - else if Action is `goto` gosub to EditGoto - else if Action is `load` gosub to EditLoad - else - begin - end - on change ActionSelect - begin - set Response - if Action is not empty - begin - if not confirm `Changing the action will remove all step data. Do you want to continue?` - clear Response - end - if Response - begin - index StepButton to SelectedStep - set property `comment` of CurrentStep to TitleInput - put the selected item in ActionSelect into Action - gosub to CreateNewAction - clear Table - go to ReloadStepEditor - end - else set ActionSelect from ActionNames as property `action` of CurrentStep - end - -! Add the buttons below the table - create TR in Table - create TD in TR - create TD in TR - create InsertBefore in TD - set the style of InsertBefore to `width:50%` - set the text of InsertBefore to `Add Step Before` - on click InsertBefore go to AddStepBefore - create InsertAfter in TD - set the style of InsertAfter to `width:50%` - set the text of InsertAfter to `Add Step After` - on click InsertAfter go to AddStepAfter - stop - -! Editors for the various Action types - -EditInit: - create TR in Table - create TD in TR - set the content of TD to `Properties:` - create TD in TR - create BlockTable in TD - set the style of BlockTable to `width:100%;border:1px solid gray` - put the json count of InitProperties into N - set the elements of InitInput to N - put 0 into B - while B is less than N - begin - put element B of InitProperties into InitProperty - create BlockRow in BlockTable - set the style of BlockRow to `display:flex` - create Cell in BlockRow - set the style of Cell to `width:6em;padding-left:0.2em` - set the content of Cell to InitProperty - index InitInput to B - create InitInput in BlockRow - set the style of InitInput to `flex:1` - set the content of InitInput to property InitProperty of CurrentStep - add 1 to B - end - return - -EditSetContent: - create TR in Table - create TD in TR - set the content of TD to `Blocks:` - create TD in TR - create BlockTable in TD - set the style of BlockTable to `width:100%;border:1px solid gray` - create BlockRow in BlockTable - set the style of BlockRow to `display:flex` - create Header in BlockRow - set the style of Header to `flex:1` - set the content of Header to `Blocks` - create Header in BlockRow - set the style of Header to `flex:1` - set the content of Header to `Content` - create BlockData in BlockRow - set the style of BlockData to `width:2em;text-align:center` - create Link in BlockData - create PlusIcon in Link - set the style of PlusIcon to `width:1em;margin-top:0.1em` - set attribute `src` of PlusIcon to `resources/icon/plus.png` - on click PlusIcon - begin - set Block to object - set property `block` of Block to empty - set property `content` of Block to empty - json add Block to Blocks - set property `blocks` of CurrentStep to Blocks - clear Table - go to ReloadStepEditor - end - put property `blocks` of CurrentStep into Blocks - put the json count of Blocks into N - set the elements of BlockSelect to N - set the elements of ContentSelect to N - set the elements of DeleteIcon to N - put 0 into B - while B is less than N - begin - put element B of Blocks into Block - create BlockRow in BlockTable - set the style of BlockRow to `display:flex` - index BlockSelect to B - create BlockSelect in BlockRow - set the style of BlockSelect to `flex:1` - set BlockSelect from BlockNames as property `block` of Block - index ContentSelect to B - create ContentSelect in BlockRow - set the style of ContentSelect to `flex:1` - set ContentSelect from ContentNames as property `content` of Block - create BlockData in BlockRow - set the style of BlockData to `width:2em;text-align:center` - index DeleteIcon to B - create Link in BlockData - create DeleteIcon in Link - set the style of DeleteIcon to `width:1em;margin-top:0.1em` - set attribute `src` of DeleteIcon to `resources/icon/stop.png` - add 1 to B - end - on change BlockSelect - begin - put the index of BlockSelect into N - put element N of Blocks into Block - set property `block` of Block to BlockSelect - set element N of Blocks to Block - set property `blocks` of CurrentStep to Blocks - set element SelectedStep of Steps to CurrentStep - end - on change ContentSelect - begin - put the index of ContentSelect into N - put element N of Blocks into Block - set property `content` of Block to ContentSelect - set element N of Blocks to Block - set property `blocks` of CurrentStep to Blocks - set element SelectedStep of Steps to CurrentStep - end - on click DeleteIcon - begin - put the index of DeleteIcon into N - json delete element N of Blocks - set property `blocks` of CurrentStep to Blocks - clear Table - go to ReloadStepEditor - end - return - -EditShow: -EditHide: - gosub to EditBlockList - return - -EditPause: -EditHold: - gosub to EditDuration - return - -EditFadeUp: -EditFadeDown: - gosub to EditBlockList - gosub to EditDuration - gosub to EditContinue - return - -EditCrossfade: - put ContentNames into Names - gosub to EditBlockAndTarget - return - -EditTransition: - create TR in Table - create TD in TR - set the content of TD to `Types:` - create TD in TR - create BlockTable in TD - set the style of BlockTable to `width:100%;border:1px solid gray` - create BlockRow in BlockTable - create BlockRow in BlockTable - set the style of BlockRow to `display:flex` - create Header in BlockRow - set the style of Header to `flex:1` - set the content of Header to `Transition types` - create BlockData in BlockRow - set the style of BlockData to `width:2em;text-align:center` - create Link in BlockData - create PlusIcon in Link - set the style of PlusIcon to `width:1em;margin-top:0.1em` - set attribute `src` of PlusIcon to `resources/icon/plus.png` - on click PlusIcon - begin - json add empty to Types - set property `type` of CurrentStep to Types - clear Table - go to ReloadStepEditor - end - put property `type` of CurrentStep into Types - put the json count of Types into N - set the elements of TransitionSelect to N - set the elements of DeleteIcon to N - put 0 into B - while B is less than N - begin - put element B of Types into TransitionType - create BlockRow in BlockTable - set the style of BlockRow to `display:flex` - index TransitionSelect to B - create TransitionSelect in BlockRow - set the style of TransitionSelect to `flex:1;width:100%` - set TransitionSelect from TransitionTypes as TransitionType - create BlockData in BlockRow - set the style of BlockData to `width:2em;text-align:center` - index DeleteIcon to B - create Link in BlockData - create DeleteIcon in Link - set the style of DeleteIcon to `width:1em;margin-top:0.1em` - set attribute `src` of DeleteIcon to `resources/icon/stop.png` - add 1 to B - end - on change TransitionSelect - begin - put the index of TransitionSelect into N - set element N of Types to the selected item in TransitionSelect - set property `type` of CurrentStep to Types - end - on click DeleteIcon - begin - put the index of DeleteIcon into N - json delete element N of Types - set property `type` of CurrentStep to Types - clear Table - go to ReloadStepEditor - end - put BlockNames into Names - gosub to EditBlockAndTarget - return - -EditGoto: - create TR in Table - create TD in TR - set the style of TD to `width:6em` - set the content of TD to `Target:` - create TD in TR - create TargetInput in TD - set the style of TargetInput to `width:100%` - set the content of TargetInput to property `target` of CurrentStep - return - -EditLoad: - create TR in Table - create TD in TR - set the style of TD to `width:6em` - set the content of TD to `URL:` - create TD in TR - create URLInput in TD - set the style of URLInput to `width:100%` - set the content of URLInput to property `url` of CurrentStep - return - -EditBlockList: - create TR in Table - create TD in TR - set the content of TD to `Blocks:` - create TD in TR - create BlockTable in TD - set the style of BlockTable to `width:100%;border:1px solid gray` - create BlockRow in BlockTable - set the style of BlockRow to `display:flex` - create Header in BlockRow - set the style of Header to `flex:1` - set the content of Header to `Blocks` - create BlockData in BlockRow - set the style of BlockData to `width:2em;text-align:center` - create Link in BlockData - create PlusIcon in Link - set the style of PlusIcon to `width:1em;margin-top:0.1em` - set attribute `src` of PlusIcon to `resources/icon/plus.png` - on click PlusIcon - begin - json add empty to Blocks - set property `blocks` of CurrentStep to Blocks - clear Table - go to ReloadStepEditor - end - put property `blocks` of CurrentStep into Blocks - put the json count of Blocks into N - set the elements of BlockSelect to N - set the elements of DeleteIcon to N - put 0 into B - while B is less than N - begin - put element B of Blocks into Block - create BlockRow in BlockTable - set the style of BlockRow to `display:flex` - index BlockSelect to B - create BlockSelect in BlockRow - set the style of BlockSelect to `flex:1` - set BlockSelect from BlockNames as Block - create BlockData in BlockRow - set the style of BlockData to `width:2em;text-align:center` - index DeleteIcon to B - create Link in BlockData - create DeleteIcon in Link - set the style of DeleteIcon to `width:1em;margin-top:0.1em` - set attribute `src` of DeleteIcon to `resources/icon/stop.png` - add 1 to B - end - on change BlockSelect - begin - put the index of BlockSelect into N - set element N of Blocks to the selected item in BlockSelect - set property `blocks` of CurrentStep to Blocks - end - on click DeleteIcon - begin - put the index of DeleteIcon into N - json delete element N of Blocks - set property `blocks` of CurrentStep to Blocks - clear Table - go to ReloadStepEditor - end - return - -EditBlockAndTarget: - create TR in Table - create TD in TR - set the content of TD to `Block:` - create TD in TR - set the elements of BlockSelect to 1 - put property `block` of CurrentStep into Block - create BlockRow in TD - create BlockSelect in BlockRow - set the style of BlockSelect to `width:100%` - set BlockSelect from BlockNames as Block - create TR in Table - create TD in TR - set the content of TD to `Target:` - create TD in TR - put property `target` of CurrentStep into Target - create BlockRow in TD - create TargetSelect in BlockRow - set the style of TargetSelect to `width:100%` - set TargetSelect from Names as Target - gosub to EditDuration - gosub to EditContinue - return - -EditDuration: - create TR in Table - create TD in TR - set the style of TD to `width:6em` - set the content of TD to `Duration:` - create TD in TR - create DurationInput in TD - set the style of DurationInput to `width:100%` - set the content of DurationInput to property `duration` of CurrentStep - return - -EditContinue: - create TR in Table - create TD in TR - set the style of TD to `width:6em` - set the content of TD to `Continue:` - create TD in TR - create ContinueSelect in TD - set the style of ContinueSelect to `width:100%` - put property `continue` of CurrentStep into TrueFalse - if TrueFalse put `true` into TrueFalse else put `false` into TrueFalse - set ContinueSelect from ContinueTypes as TrueFalse - return - -! Create a new action with a full set of empty properties -CreateNewAction: - index TitleInput to SelectedStep - if the text of TitleInput is empty - begin - set property `comment` of CurrentStep to `New step: ` cat Action - end - set property `action` of CurrentStep to Action - set property `label` of CurrentStep to empty - if Action is `init` - begin - put 0 into N - while N is less than the json count of InitProperties - begin - put element N of InitProperties into InitProperty - set property InitProperty of CurrentStep to empty - add 1 to N - end - set property `aspect ratio` of CurrentStep to `WW:HH` - end - else if Action is `set content` - begin - put property `blocks` of CurrentStep into Blocks - if Blocks is empty - begin - set Blocks to array - set property `blocks` of CurrentStep to Blocks - end - end - else if Action is `show` - begin - put property `blocks` of CurrentStep into Blocks - if Blocks is empty - begin - set Blocks to array - set property `blocks` of CurrentStep to Blocks - end - end - else if Action is `hide` - begin - put property `blocks` of CurrentStep into Blocks - if Blocks is empty - begin - set Blocks to object - set property `blocks` of CurrentStep to Blocks - end - end - else if Action is `pause` - begin - put property `duration` of CurrentStep into Duration - if Duration is empty set property `duration` of CurrentStep to 1 - end - else if Action is `hold` - begin - put property `duration` of CurrentStep into Duration - if Duration is empty set property `duration` of CurrentStep to 1 - end - else if Action is `fade up` - begin - put property `blocks` of CurrentStep into Blocks - if Blocks is empty - begin - set Blocks to array - set property `blocks` of CurrentStep to Blocks - end - put property `duration` of CurrentStep into Duration - if Duration is empty set property `duration` of CurrentStep to 1 - end - else if Action is `fade down` - begin - put property `blocks` of CurrentStep into Blocks - if Blocks is empty - begin - set Blocks to array - set property `blocks` of CurrentStep to Blocks - end - put property `duration` of CurrentStep into Duration - if Duration is empty set property `duration` of CurrentStep to 1 - end - else if Action is `crossfade` - begin - put property `block` of CurrentStep into Block - if Block is empty set property `block` of CurrentStep to `******` - put property `target` of CurrentStep into Target - if Target is empty set property `target` of CurrentStep to `******` - put property `duration` of CurrentStep into Duration - if Duration is empty set property `duration` of CurrentStep to 1 - end - else if Action is `transition` - begin - put property `types` of CurrentStep into Types - if Types is empty - begin - set Types to array - set property `types` of CurrentStep to Types - end - put property `target` of CurrentStep into Target - if Target is empty set property `target` of CurrentStep to `******` - put property `duration` of CurrentStep into Duration - if Duration is empty set property `duration` of CurrentStep to 1 - end - else if Action is `goto` - begin - put property `target` of CurrentStep into Target - if Target is empty set property `target` of CurrentStep to `******` - end - else if Action is `load` - begin - put property `url` of CurrentStep into URL - if URL is empty set property `url` of CurrentStep to `******` - end - set element SelectedStep of Steps to CurrentStep - set property `steps` of Presentation to Steps - return - -! Save the current step -SaveCurrentStep: - if SelectedStep is -1 return - index TitleInput to SelectedStep - put element SelectedStep of Steps into CurrentStep - set property `comment` of CurrentStep to the text of TitleInput - index StepButton to SelectedStep - set the text of StepButton to the content of TitleInput - index LabelInput to SelectedStep - set property `label` of CurrentStep to the content of LabelInput - put property `action` of CurrentStep into Action - if Action is `init` - begin - put 0 into N - while N is less than the json count of InitProperties - begin - put element N of InitProperties into InitProperty - index InitInput to N - set property InitProperty of CurrentStep to the content of InitInput - add 1 to N - end - end - else if Action is `set content` - begin - put property `blocks` of CurrentStep into Blocks - if Blocks is empty - begin - set Blocks to array - set property `blocks` of CurrentStep to Blocks - end - end - else if Action is `show` - begin - put property `blocks` of CurrentStep into Blocks - if Blocks is empty - begin - set Blocks to array - set property `blocks` of CurrentStep to Blocks - end - end - else if Action is `hide` - begin - put property `blocks` of CurrentStep into Blocks - if Blocks is empty - begin - set Blocks to object - set property `blocks` of CurrentStep to Blocks - end - end - else if Action is `pause` - begin - put property `duration` of CurrentStep into Duration - if Duration is empty set property `duration` of CurrentStep to 1 - end - else if Action is `hold` - begin - put property `duration` of CurrentStep into Duration - if Duration is empty set property `duration` of CurrentStep to 1 - end - else if Action is `fade up` - begin - put property `blocks` of CurrentStep into Blocks - if Blocks is empty - begin - set Blocks to array - set property `blocks` of CurrentStep to Blocks - end - put property `duration` of CurrentStep into Duration - if Duration is empty set property `duration` of CurrentStep to 1 - end - else if Action is `fade down` - begin - put property `blocks` of CurrentStep into Blocks - if Blocks is empty - begin - set Blocks to array - set property `blocks` of CurrentStep to Blocks - end - put property `duration` of CurrentStep into Duration - if Duration is empty set property `duration` of CurrentStep to 1 - end - else if Action is `crossfade` - begin - put property `block` of CurrentStep into Block - if Block is empty set property `block` of CurrentStep to `******` - put property `target` of CurrentStep into Target - if Target is empty set property `target` of CurrentStep to `******` - put property `duration` of CurrentStep into Duration - if Duration is empty set property `duration` of CurrentStep to 1 - end - else if Action is `transition` - begin - put property `types` of CurrentStep into Types - if Types is empty - begin - set Types to array - set property `types` of CurrentStep to Types - end - put property `target` of CurrentStep into Target - if Target is empty set property `target` of CurrentStep to `******` - put property `duration` of CurrentStep into Duration - if Duration is empty set property `duration` of CurrentStep to 1 - end - else if Action is `goto` - begin - put property `target` of CurrentStep into Target - if Target is empty set property `target` of CurrentStep to `******` - end - else if Action is `load` - begin - put property `url` of CurrentStep into URL - if URL is empty set property `url` of CurrentStep to `******` - end - set element SelectedStep of Steps to CurrentStep - set property `steps` of Presentation to Steps - return \ No newline at end of file diff --git a/mostrami/resources/icon/apple.png b/mostrami/resources/icon/apple.png deleted file mode 100644 index 8b5223d..0000000 Binary files a/mostrami/resources/icon/apple.png and /dev/null differ diff --git a/mostrami/resources/icon/arrow-back.png b/mostrami/resources/icon/arrow-back.png deleted file mode 100644 index a375adc..0000000 Binary files a/mostrami/resources/icon/arrow-back.png and /dev/null differ diff --git a/mostrami/resources/icon/arrow-forward.png b/mostrami/resources/icon/arrow-forward.png deleted file mode 100644 index 0b128a4..0000000 Binary files a/mostrami/resources/icon/arrow-forward.png and /dev/null differ diff --git a/mostrami/resources/icon/binoculars.png b/mostrami/resources/icon/binoculars.png deleted file mode 100644 index 662cb85..0000000 Binary files a/mostrami/resources/icon/binoculars.png and /dev/null differ diff --git a/mostrami/resources/icon/book.png b/mostrami/resources/icon/book.png deleted file mode 100644 index 4ab688e..0000000 Binary files a/mostrami/resources/icon/book.png and /dev/null differ diff --git a/mostrami/resources/icon/cross.png b/mostrami/resources/icon/cross.png deleted file mode 100644 index e26d0c8..0000000 Binary files a/mostrami/resources/icon/cross.png and /dev/null differ diff --git a/mostrami/resources/icon/cycle.png b/mostrami/resources/icon/cycle.png deleted file mode 100644 index 5d07d8b..0000000 Binary files a/mostrami/resources/icon/cycle.png and /dev/null differ diff --git a/mostrami/resources/icon/document.png b/mostrami/resources/icon/document.png deleted file mode 100644 index 9fff790..0000000 Binary files a/mostrami/resources/icon/document.png and /dev/null differ diff --git a/mostrami/resources/icon/down.png b/mostrami/resources/icon/down.png deleted file mode 100644 index 6ad3480..0000000 Binary files a/mostrami/resources/icon/down.png and /dev/null differ diff --git a/mostrami/resources/icon/duckthink.jpg b/mostrami/resources/icon/duckthink.jpg deleted file mode 100644 index ce8acd4..0000000 Binary files a/mostrami/resources/icon/duckthink.jpg and /dev/null differ diff --git a/mostrami/resources/icon/edit.png b/mostrami/resources/icon/edit.png deleted file mode 100644 index 06146c4..0000000 Binary files a/mostrami/resources/icon/edit.png and /dev/null differ diff --git a/mostrami/resources/icon/exit.png b/mostrami/resources/icon/exit.png deleted file mode 100644 index d62aa95..0000000 Binary files a/mostrami/resources/icon/exit.png and /dev/null differ diff --git a/mostrami/resources/icon/folder.png b/mostrami/resources/icon/folder.png deleted file mode 100644 index 812fc81..0000000 Binary files a/mostrami/resources/icon/folder.png and /dev/null differ diff --git a/mostrami/resources/icon/gear.png b/mostrami/resources/icon/gear.png deleted file mode 100644 index 6742ffd..0000000 Binary files a/mostrami/resources/icon/gear.png and /dev/null differ diff --git a/mostrami/resources/icon/heart.png b/mostrami/resources/icon/heart.png deleted file mode 100644 index 3fb40db..0000000 Binary files a/mostrami/resources/icon/heart.png and /dev/null differ diff --git a/mostrami/resources/icon/image.png b/mostrami/resources/icon/image.png deleted file mode 100644 index 30a8527..0000000 Binary files a/mostrami/resources/icon/image.png and /dev/null differ diff --git a/mostrami/resources/icon/left.png b/mostrami/resources/icon/left.png deleted file mode 100644 index 7a2e5ca..0000000 Binary files a/mostrami/resources/icon/left.png and /dev/null differ diff --git a/mostrami/resources/icon/list.png b/mostrami/resources/icon/list.png deleted file mode 100644 index 78fdf36..0000000 Binary files a/mostrami/resources/icon/list.png and /dev/null differ diff --git a/mostrami/resources/icon/media.png b/mostrami/resources/icon/media.png deleted file mode 100644 index d16c5fa..0000000 Binary files a/mostrami/resources/icon/media.png and /dev/null differ diff --git a/mostrami/resources/icon/new.png b/mostrami/resources/icon/new.png deleted file mode 100644 index 670a256..0000000 Binary files a/mostrami/resources/icon/new.png and /dev/null differ diff --git a/mostrami/resources/icon/open.png b/mostrami/resources/icon/open.png deleted file mode 100644 index a34aebb..0000000 Binary files a/mostrami/resources/icon/open.png and /dev/null differ diff --git a/mostrami/resources/icon/plus.png b/mostrami/resources/icon/plus.png deleted file mode 100644 index 6a8941c..0000000 Binary files a/mostrami/resources/icon/plus.png and /dev/null differ diff --git a/mostrami/resources/icon/reference.png b/mostrami/resources/icon/reference.png deleted file mode 100644 index d503a67..0000000 Binary files a/mostrami/resources/icon/reference.png and /dev/null differ diff --git a/mostrami/resources/icon/right.png b/mostrami/resources/icon/right.png deleted file mode 100644 index 9260b9a..0000000 Binary files a/mostrami/resources/icon/right.png and /dev/null differ diff --git a/mostrami/resources/icon/run.png b/mostrami/resources/icon/run.png deleted file mode 100644 index f48397e..0000000 Binary files a/mostrami/resources/icon/run.png and /dev/null differ diff --git a/mostrami/resources/icon/runstop.png b/mostrami/resources/icon/runstop.png deleted file mode 100644 index 46d7636..0000000 Binary files a/mostrami/resources/icon/runstop.png and /dev/null differ diff --git a/mostrami/resources/icon/save.png b/mostrami/resources/icon/save.png deleted file mode 100644 index e1ea3c2..0000000 Binary files a/mostrami/resources/icon/save.png and /dev/null differ diff --git a/mostrami/resources/icon/stop.png b/mostrami/resources/icon/stop.png deleted file mode 100644 index 3f7231c..0000000 Binary files a/mostrami/resources/icon/stop.png and /dev/null differ diff --git a/mostrami/resources/icon/teacher.png b/mostrami/resources/icon/teacher.png deleted file mode 100644 index e2a9eb8..0000000 Binary files a/mostrami/resources/icon/teacher.png and /dev/null differ diff --git a/mostrami/resources/icon/tools.png b/mostrami/resources/icon/tools.png deleted file mode 100644 index 5bb3101..0000000 Binary files a/mostrami/resources/icon/tools.png and /dev/null differ diff --git a/mostrami/resources/icon/trash.png b/mostrami/resources/icon/trash.png deleted file mode 100644 index 643fa22..0000000 Binary files a/mostrami/resources/icon/trash.png and /dev/null differ diff --git a/mostrami/resources/icon/unknown.png b/mostrami/resources/icon/unknown.png deleted file mode 100644 index dd56059..0000000 Binary files a/mostrami/resources/icon/unknown.png and /dev/null differ diff --git a/mostrami/resources/icon/up.png b/mostrami/resources/icon/up.png deleted file mode 100644 index d2ae101..0000000 Binary files a/mostrami/resources/icon/up.png and /dev/null differ diff --git a/mostrami/resources/img/flowers.jpg b/mostrami/resources/img/flowers.jpg deleted file mode 100644 index 14d90c4..0000000 Binary files a/mostrami/resources/img/flowers.jpg and /dev/null differ diff --git a/mostrami/resources/img/moon.jpg b/mostrami/resources/img/moon.jpg deleted file mode 100644 index 7859032..0000000 Binary files a/mostrami/resources/img/moon.jpg and /dev/null differ diff --git a/mostrami/resources/js/mostrami.js b/mostrami/resources/js/mostrami.js deleted file mode 100644 index 22472ef..0000000 --- a/mostrami/resources/js/mostrami.js +++ /dev/null @@ -1,826 +0,0 @@ -// Mostrami - -const Mostrami = (container, script) => { - - let mode = `manual`; - let clicked = false; - - // Initialize all the blocks - const initBlocks = () => { - const defaults = script.defaults; - const blocks = script.blocks; - for (const name in blocks) { - const block = blocks[name]; - const properties = {}; - // Set up the default properties - for (const name in defaults) { - properties[name] = defaults[name]; - } - // Override with local values - for (const name in block) { - properties[name] = block[name]; - } - block.properties = properties; - block.container = container; - } - }; - - // Preload all the images - const preloadImages = () => { - for (const item in script.content) { - if (item.type == `image`) { - item.img = document.createElement(`div`); - item.img.style[`background`] = `url("${item.url}")`; - } - } - }; - - const pause = step => { - setTimeout(() => { - step.next(); - }, script.speed === `normal` ? step.duration * 1000 : 0); - }; - - const release = step => { - container.style.cursor = 'none'; - document.removeEventListener(`click`, release); - document.onkeydown = null; - step.next(); - }; - - const doManual = step => { - container.style.cursor = 'pointer'; - document.addEventListener(`click`, release); - document.onkeydown = (event) => { - switch (event.code) { - case `Space`: - case `ArrowRight`: - document.onkeydown = null; - release(step); - break; - case `ArrowLeft`: - break; - case `Enter`: - container.style.cursor = 'none'; - document.addEventListener(`click`, onClick); - mode = `auto`; - release(step); - break; - } - return true; - }; - }; - - const onClick = () => { - clicked = true; - }; - - const hold = step => { - if (mode === `manual`) { - doManual(step); - } else { - if (clicked) { - document.removeEventListener(`click`, onClick); - clicked = false; - mode = `manual`; - doManual(step); - } else { - setTimeout(() => { - step.next(); - }, script.speed === `normal` ? step.duration * 1000 : 0); - } - } - }; - - // Create a text block. - const createTextBlock = (block) => { - const container = block.container; - if (block.element) { - container.removeChild(block.element); - } - const w = container.getBoundingClientRect().width / 1000; - const h = container.getBoundingClientRect().height / 1000; - const properties = block.properties; - const element = document.createElement(`div`); - block.element = element; - element.style[`position`] = `absolute`; - element.style[`opacity`] = `0.0`; - let val = properties.blockLeft; - if (!isNaN(val)) { - val *= w; - } - element.style[`left`] = val; - val = properties.blockTop; - if (!isNaN(val)) { - val *= h; - } - element.style[`top`] = val; - val = properties.blockWidth; - if (!isNaN(val)) { - val *= w; - } - element.style[`width`] = `${val}px`; - val = properties.blockHeight; - if (!isNaN(val)) { - val *= h; - } - element.style[`height`] = `${val}px`; - element.style[`background`] = properties.blockBackground; - element.style[`border`] = properties.blockBorder; - container.appendChild(element); - val = properties.textMarginLeft; - if (!isNaN(val)) { - val *= w; - } - const marginLeft = val; - val = properties.textMarginTop; - if (!isNaN(val)) { - val *= h; - } - const marginTop = val; - const inner = document.createElement(`div`); - inner.style[`position`] = `absolute`; - inner.style[`left`] = marginLeft; - inner.style[`top`] = marginTop; - inner.style[`width`] = `calc(100% - ${marginLeft}px - ${marginLeft}px)`; - element.appendChild(inner); - element.inner = inner; - const text = document.createElement(`div`); - text.style[`font-family`] = properties.fontFamily; - val = properties.fontSize; - if (!isNaN(val)) { - val *= h; - } - text.style[`font-size`] = `${val}px`; - text.style[`font-weight`] = properties.fontWeight; - text.style[`font-style`] = properties.fontStyle; - text.style[`color`] = properties.fontColor; - text.style[`text-align`] = properties.textAlign; - inner.appendChild(text); - inner.text = text; - if (script.speed === `scan`) { - element.style.opacity = 0; - } - }; - - // Create an image block. - const createImageBlock = (block) => { - const container = block.container; - if (block.element) { - container.removeChild(block.element); - } - const w = container.getBoundingClientRect().width / 1000; - const h = container.getBoundingClientRect().height / 1000; - const properties = block.properties; - const element = document.createElement(`div`); - block.element = element; - element.style[`position`] = `absolute`; - element.style[`opacity`] = `0.0`; - let val = properties.blockLeft; - if (!isNaN(val)) { - val *= w; - } - element.style[`left`] = val; - val = properties.blockTop; - if (!isNaN(val)) { - val *= h; - } - element.style[`top`] = val; - element.style[`top`] = val; - val = properties.blockWidth; - if (!isNaN(val)) { - val *= w; - } - element.style[`width`] = `${val}px`; - val = properties.blockHeight; - if (!isNaN(val)) { - val *= h; - } - element.style[`height`] = `${val}px`; - element.style[`background`] = properties.blockBackground; - element.style[`border`] = properties.blockBorder; - element.style[`border-radius`] = properties.blockBorderRadius; - container.appendChild(element); - if (script.speed === `scan`) { - element.style.opacity = 0; - } - }; - - // Set the content of a block - const doSetContent = (spec) => { - const block = script.blocks[spec.block]; - const contentSpec = script.content[spec.content]; - if (!block) { - throw Error(`Block '${block}' cannot be found`); - } - switch (contentSpec.type) { - case `text`: - if (!block.element) { - createTextBlock(block); - } - let content = contentSpec.content; - if (Array.isArray(content)) { - content = content.join(`<br><br>`); - } - block.element.inner.text.innerHTML = content.split(`\n`).join(`<br>`); - break; - case `image`: - if (!block.element) { - createImageBlock(block); - } - block.element.style[`background`] = `url("${contentSpec.url}")`; - block.element.style[`background-size`] = `cover`; - break; - } - }; - - // Set the content of a block - const setcontent = step => { - if (step.blocks) { - for (const spec of step.blocks) - { - doSetContent(spec); - } - } else { - doSetContent(step); - } - step.next(); - }; - - // Show or hide a block - const doShowHide = (step, showHide) => { - if (script.speed !== `scan`) { - if (Array.isArray(step.blocks)) { - for (const name of step.blocks) - { - script.blocks[name].opacity = showHide ? `1.0` : `0.0`; - script.blocks[name].element.style[`opacity`] = script.blocks[name].opacity; - } - } else { - script.blocks[step.blocks].opacity = showHide ? `1.0` : `0.0`; - script.blocks[step.blocks].element.style[`opacity`] = script.blocks[step.blocks].opacity; - } - } - step.next(); - }; - - const show = step => { - doShowHide(step, true); - }; - - const hide = step => { - doShowHide(step, false); - }; - - // Fade up or down - const doFade = (step, upDown) => { - const stepBlocks = step.blocks; - for (const b of stepBlocks) { - const block = script.blocks[b]; - if (!block.element) { - switch (block.type) { - case `text`: - createTextBlock(block); - break; - case `image`: - createImageBlock(block); - break; - } - } - } - if (script.speed === `scan`) { - if (Array.isArray(stepBlocks)) { - for (const block of stepBlocks) - { - script.blocks[block].opacity = upDown ? 1.0 : 0.0; - script.blocks[block].element.style.opacity = 0; - } - } else { - script.blocks[stepBlocks].opacity = upDown ? 1.0 : 0.0; - script.blocks[stepBlocks].element.style.opacity = 0; - } - step.next(); - } else { - const animSteps = Math.round(step.duration * 25); - const continueFlag = step.continue; - let animStep = 0; - const interval = setInterval(() => { - if (animStep < animSteps) { - const ratio = 0.5 - Math.cos(Math.PI * animStep / animSteps) / 2; - if (Array.isArray(stepBlocks)) { - let blocks = stepBlocks.length; - for (const block of stepBlocks) - { - const element = script.blocks[block].element; - element.style[`opacity`] = upDown ? ratio : 1.0 - ratio; - } - } else { - const block = script.blocks[stepBlocks]; - if (!block.element) { - clearInterval(interval); - throw Error(`I can't fade up a block with no content`); - } - block.element.style[`opacity`] = upDown ? ratio : 1.0 - ratio; - } - animStep++; - } else { - clearInterval(interval); - if (Array.isArray(stepBlocks)) { - for (const block of stepBlocks) - { - script.blocks[block].opacity = upDown ? 1.0 : 0.0; - } - } else { - script.blocks[stepBlocks].opacity = upDown ? 1.0 : 0.0; - } - if (!continueFlag) { - step.next(); - } - } - }, 40); - if (continueFlag) { - step.next(); - } - } - }; - - const fadeup = step => { - doFade(step, true); - }; - - const fadedown = step => { - doFade(step, false); - }; - - // Handle a crossfade - const crossfade = step => { - const content = script.content[step.target]; - const block = script.blocks[step.block]; - if (script.speed === `scan`) { - switch (content.type) { - case `text`: - newText = content.content; - if (Array.isArray(newText)) { - newText = newText.join(`<br><br>`); - } - newText = newText.split(`\n`).join(`<br>`); - block.element.inner.text.innerHTML = newText; - break; - case `image`: - block.element.style[`background`] = `url("${content.url}")`; - break; - } - step.next(); - } else { - const continueFlag = step.continue; - let element; - let newText; - switch (content.type) { - case `text`: - element = document.createElement(`div`); - element.style[`position`] = `absolute`; - element.style[`opacity`] = `0.0`; - element.style[`left`] = block.element.style[`left`]; - element.style[`top`] = block.element.style[`top`]; - element.style[`width`] = block.element.style[`width`]; - element.style[`height`] = block.element.style[`height`]; - element.style[`background`] = block.element.style[`background`] - element.style[`border`] = block.element.style[`border`] - element.style[`border-radius`] = block.element.style[`border-radius`] - container.appendChild(element); - const inner = document.createElement(`div`); - inner.style[`position`] = `absolute`; - inner.style[`left`] = block.element.inner.style[`left`]; - inner.style[`top`] = block.element.inner.style[`top`]; - inner.style[`width`] = block.element.inner.style[`width`]; - element.appendChild(inner); - const text = document.createElement(`div`); - text.style[`font-family`] = block.element.inner.text.style[`font-family`]; - text.style[`font-size`] = block.element.inner.text.style[`font-size`]; - text.style[`font-weight`] = block.element.inner.text.style[`font-weight`]; - text.style[`font-style`] = block.element.inner.text.style[`font-style`]; - text.style[`color`] = block.element.inner.text.style[`color`]; - text.style[`text-align`] = block.element.inner.text.style[`text-align`]; - inner.appendChild(text); - newText = content.content; - if (Array.isArray(newText)) { - newText = newText.join(`<br><br>`); - } - newText = newText.split(`\n`).join(`<br>`); - text.innerHTML = newText; - break; - case `image`: - element = document.createElement(`div`); - element.style[`position`] = `absolute`; - element.style[`opacity`] = `0.0`; - element.style[`left`] = block.element.style[`left`]; - element.style[`top`] = block.element.style[`top`]; - element.style[`width`] = block.element.style[`width`]; - element.style[`height`] = block.element.style[`height`]; - element.style[`background`] = block.element.style[`background`]; - element.style[`border`] = block.element.style[`border`]; - element.style[`border-radius`] = block.element.style[`border-radius`]; - container.appendChild(element); - element.style[`background`] = `url("${content.url}")`; - element.style[`background-size`] = `cover`; - break; - default: - throw Error(`Unknown content type: '${content.type}'`); - } - - const animSteps = Math.round(step.duration * 25); - let animStep = 0; - const interval = setInterval(() => { - if (animStep < animSteps) { - const ratio = 0.5 - Math.cos(Math.PI * animStep / animSteps) / 2; - block.element.style[`opacity`] = 1.0 - ratio; - element.style[`opacity`] = ratio; - animStep++; - } else { - clearInterval(interval); - switch (content.type) { - case `text`: - block.element.inner.text.innerHTML = newText; - break; - case `image`: - block.element.style[`background`] = `url("${content.url}")`; - block.element.style[`background-size`] = `cover`; - break; - } - block.element.style[`opacity`] = 1.0 ; - container.removeChild(element); - if (!continueFlag) { - step.next(); - } - } - }, 40); - if (continueFlag) { - step.next(); - } - } - }; - - // Compute a block size - const setComputedBlockSize = (block, target, ratio) => { - const boundingRect = block.container.getBoundingClientRect(); - const w = boundingRect.width / 1000; - const h = boundingRect.height / 1000; - let width = block.properties.blockWidth; - if (!isNaN(width)) { - width *= w; - } - let height = block.properties.blockWidth; - if (!isNaN(height)) { - height *= h; - } - let endWidth = target.properties.blockWidth; - if (!isNaN(endWidth)) { - endWidth *= w; - } - let endHeight = target.properties.blockHeight; - if (!isNaN(endHeight)) { - endHeight *= h; - } - block.element.style[`width`] = - `${width + (endWidth - width) * ratio}px`; - block.element.style[`height`] = - `${height + (endHeight - height) * ratio}px`; - }; - - // Compute a block position - const setComputedBlockPosition = (block, target, ratio) => { - const boundingRect = block.container.getBoundingClientRect(); - const w = boundingRect.width / 1000; - const h = boundingRect.height / 1000; - let left = block.properties.blockLeft; - if (!isNaN(left)) { - left *= w; - } - let top = block.properties.blockTop; - if (!isNaN(top)) { - top *= h; - } - let endLeft = target.properties.blockLeft; - if (!isNaN(endLeft)) { - endLeft *= w; - } - let endTop = target.properties.blockTop; - if (!isNaN(endTop)) { - endTop *= h; - } - block.element.style[`left`] = - left + (endLeft - left) * ratio; - block.element.style[`top`] = - top + (endTop - top) * ratio; - }; - - // Compute a font size - const setComputedFontSize = (block, target, ratio) => { - const h = Math.round(block.container.getBoundingClientRect().height) / 1000; - let size = block.properties.fontSize; - if (!isNaN(size)) { - size *= h; - } - let endSize = target.properties.fontSize; - if (!isNaN(endSize)) { - endSize *= h; - } - block.element.inner.text.style[`font-size`] = - `${size + Math.round((endSize - size) * ratio)}px`; - }; - - // Compute a font color - const setComputedFontColor = (block, target, ratio) => { - const color = block.fontColor; - const endColor = target.fontColor; - const rStart = parseInt(color.slice(1, 3), 16); - const gStart = parseInt(color.slice(3, 5), 16); - const bStart = parseInt(color.slice(5, 7), 16); - const rFinish = parseInt(endColor.slice(1, 3), 16); - const gFinish = parseInt(endColor.slice(3, 5), 16); - const bFinish = parseInt(endColor.slice(5, 7), 16); - const red = rStart + Math.round((rFinish - rStart) * ratio); - const green = gStart + Math.round((gFinish - gStart) * ratio); - const blue = bStart + Math.round((bFinish - bStart) * ratio); - const r = ("0" + red.toString(16)).slice(-2); - const g = ("0" + green.toString(16)).slice(-2); - const b = ("0" + blue.toString(16)).slice(-2); - block.element.inner.text.style[`color`] = `#${r}${g}${b}`; - }; - - // Handle a single step of a transition - const doTransitionStep = (type, block, target, ratio) => { - switch (type) { - case `block size`: - setComputedBlockSize(block, target, ratio); - break; - case `block position`: - setComputedBlockPosition(block, target, ratio); - break; - case `font size`: - setComputedFontSize(block, target, ratio); - break; - case `font color`: - setComputedFontColor(block, target, ratio); - break; - default: - throw Error(`Unknown transition type: '${type}'`); - } - }; - - // Handle a transition - const transition = step => { - const block = script.blocks[step.block]; - const stepType = step.type; - const target = script.blocks[step.target]; - if (script.speed === `scan`) { - if (Array.isArray(stepType)) { - for (const type of stepType) { - doTransitionStep(type, block, target, 1.0); - } - } else { - doTransitionStep(type, block, target, 1.0); - } - step.next(); - } else { - const animSteps = Math.round(step.duration * 25); - let animStep = 0; - const continueFlag = step.continue; - const interval = setInterval(() => { - if (animStep < animSteps) { - const ratio = 0.5 - Math.cos(Math.PI * animStep / animSteps) / 2; - if (Array.isArray(stepType)) { - for (const type of stepType) { - doTransitionStep(type, block, target, ratio); - } - } else { - doTransitionStep(type, block, target, ratio); - } - animStep++; - } else { - clearInterval(interval); - if (!continueFlag) { - step.next(); - } - } - }, 40); - if (continueFlag) { - step.next(); - } - } - }; - - // Scan the script - const scan = () => { - script.speed = `scan`; - for (const name in script.blocks) { - const block = script.blocks[name]; - if (block.element) { - container.removeChild(block.element); - block.element = null; - } - } - doStep(script.steps[0]); - }; - - // Go to a specified label - const goto = step => { - const target = script.labels[step.target]; - if (typeof target !== `undefined`) { - script.scanTarget = target; - scan(); - } else { - throw Error(`Unknown label '${step.target}`); - } - }; - - // Load a plugin action - const load = step => { - if (script.speed === `scan`) { - step.next(); - } else { - const element = document.createElement(`script`); - element.src = step.url; - element.onload = () => { - console.log(`Plugin ${element.src} loaded`); - step.next(); - }; - element.onerror = () => { - throw Error(`Can't load plugin ${step.url}`); - }; - document.head.appendChild(element); - } - }; - - // Initialize the presenttion - const init = step => { - if (step.title) { - document.title = step.title; - } - const aspect = step[`aspect ratio`]; - if (aspect) { - const colon = aspect.indexOf(`:`); - if (colon > 0) { - const aspectW = aspect.substr(0, colon); - const aspectH = aspect.substr(colon + 1); - script.container = container; - const height = Math.round(parseFloat(container.offsetWidth) * aspectH / aspectW); - container.style.height = `${Math.round(height)}px`; - container.style.position = `relative`; - container.style.overflow = `hidden`; - container.style.cursor = `none`; - container.style[`background-size`] = `cover`; - } - container.style[`border`] = step[`border`]; - container.style[`background`] = step[`background`]; - } - step.next(); - }; - - const actions = { - init, - setcontent, - show, - hide, - pause, - hold, - fadeup, - fadedown, - crossfade, - transition, - goto, - load - }; - - // Process a single step - const doStep = step => { - if (script.speed === `scan`) { - if (step.index === script.scanTarget) { - script.speed = `normal`; - for (const name in script.blocks) { - const block = script.blocks[name]; - if (block.element) { - block.element.style.opacity = block.opacity; - } - } - } - } else { - if (step.title) { - console.log(`Step ${step.index}: ${step.title}`); - } else { - console.log(`Step ${step.index}: ${step.action}`); - } - } - const actionName = step.action.split(` `).join(``); - let handler = actions[actionName]; - if (typeof handler === `undefined`) { - handler = Mostrami.plugins[actionName]; - if (typeof handler === `undefined`) { - throw Error(`Unknown action: '${step.action}'`); - } - } - handler(step); - }; - - // Initialization - const setup = () => { - container.innerHTML = ``; - document.removeEventListener(`click`, init); - if (mode === `auto`) { - document.addEventListener(`click`, onClick); - } - document.onkeydown = null; - script.container = container; - container.style.position = `relative`; - container.style.overflow = `hidden`; - container.style.cursor = 'none'; - container.style[`background-size`] = `cover`; - script.speed = `normal`; - script.labels = {}; - for (const [index, step] of script.steps.entries()) { - step.index = index; - step.script = script; - if (typeof step.label !== `undefined`) { - script.labels[step.label] = index; - } - if (index < script.steps.length - 1) { - step.next = () => { - const next = step.index + 1; - setTimeout(() => { - doStep(script.steps[next]); - }, 0); - } - } - else { - step.next = () => { - console.log(`Step ${index + 1}: Finished`); - container.style.cursor = 'pointer'; - } - }; - } - console.log(JSON.stringify(script, 0, 2)); - Mostrami.plugins = {}; - initBlocks(); - preloadImages(); - doStep(script.steps[0]); - }; - - // Wait for a click/tap or a keypress to start - document.addEventListener(`click`, init); - document.onkeydown = function (event) { - if (event.code === `Enter`) { - mode = `auto`; - } - setup(); - return true; - }; -}; - -window.onload = () => { - const createCORSRequest = (url) => { - let xhr = new XMLHttpRequest(); - if (`withCredentials` in xhr) { - - // Check if the XMLHttpRequest object has a "withCredentials" property. - // "withCredentials" only exists on XMLHTTPRequest2 objects. - xhr.open(`GET`, url, true); - - } else if (typeof XDomainRequest != `undefined`) { - - // Otherwise, check if XDomainRequest. - // XDomainRequest only exists in IE, and is IE's way of making CORS requests. - xhr = new XDomainRequest(); - xhr.open(`GET`, url); - - } else { - - // Otherwise, CORS is not supported by the browser. - xhr = null; - - } - return xhr; - }; - - const scriptElement = document.getElementById(`jp-script`); - if (scriptElement) { - const request = createCORSRequest(`${scriptElement.innerText}?v=${Math.floor(Date.now())}`); - if (!request) { - throw Error(`Unable to access the JSON script`); - } - - request.onload = () => { - if (200 <= request.status && request.status < 400) { - const script = JSON.parse(request.responseText); - Mostrami(document.getElementById(`jp-container`), script); - } else { - throw Error(`Unable to access the JSON script`); - } - }; - - request.onerror = () => { - throw Error(`Unable to access the JSON script`); - }; - - request.send(); - } -}; diff --git a/mostrami/resources/json/demo.json b/mostrami/resources/json/demo.json deleted file mode 100644 index 7b098f5..0000000 --- a/mostrami/resources/json/demo.json +++ /dev/null @@ -1,273 +0,0 @@ -{ - "global": { - "title": "JSON::Presenter", - "description": "A demo presentation that outlines some features of JSON::Presenter", - "aspectW": 160, - "aspectH": 89 - }, - "container": { - "border": "1px solid black", - "background": "black" - }, - "defaults": { - "fontFamily": "Times New Roman,serif", - "fontSize": 40, - "fontWeight": "normal", - "fontStyle": "normal", - "fontColor": "white", - "textAlign": "left", - "textMarginLeft": 0, - "textMarginTop": 0, - "blockLeft": 0, - "blockTop": 0, - "blockWidth": 1000, - "blockBackground": "none", - "blockBorder": "none", - "blockBorderRadius": 0 - }, - "blocks": { - "title": { - "blockTop": 300, - "blockHeight": 300, - "textAlign": "center", - "fontSize": 200, - "fontWeight": "bold", - "fontColor": "#800000" - }, - "title 2": { - "blockTop": 50, - "blockHeight": 150, - "textAlign": "center", - "fontSize": 100, - "fontWeight": "bold", - "fontColor": "#dddd00" - }, - "body": { - "blockLeft": 80, - "blockTop": 240, - "blockWidth": 840, - "blockHeight": 800, - "fontFamily": "Helvetica,sans-serif", - "fontColor": "#dddddd" - }, - "body right": { - "blockLeft": 500, - "blockTop": 200, - "blockWidth": 420, - "blockHeight": 800, - "fontFamily": "Helvetica,sans-serif", - "fontColor": "#dddddd" - }, - "left image": { - "blockLeft": 80, - "blockTop": 200, - "blockWidth": 370, - "blockHeight": 700, - "blockBorder": "1px solid black", - "blockBorderRadius": "1em" - } - }, - "content": { - "presenter title": { - "type": "text", - "content": "JSON::Presenter" - }, - "slide 1": { - "type": "text", - "content": [ - "JSON::Presenter is a presentation format using JSON scripts, and an engine that runs those scripts in a browser to create presentations. These may be similar to those created using PowerPoint or they can be considerably more elaborate, with extensive animation and even sound. In some cases they can take the place of video yet still offer a dynamic experience.", - - "Presentations can run from any host, including static; all you need is one CDN-hosted JavaScript file and you're good to go.", - - "The JSON::Presenter engine is pure JavaScript. It can be used with any JavaScript framework, or with none." - ] - }, - "slide 2": { - "type": "text", - "content": [ - "JSON::Presenter offers a range of block types and transitions that make it easy to create slick, effective presentations.", - - "This short demo illustrates some of the features of the system." - ] - }, - "slide 3": { - "type": "text", - "content": [ - "Text and image blocks can be manipulated in a variety of different ways.", - - "Any block can be resized or moved; text can be substituted or have its size or color change; images can be assigned to blocks. Any block can be faded or transformed using animations.", - - "The JSON::Presenter scripting language uses simple data JSON structures and is easy to read or write." - ] - }, - "flowers": { - "type": "image", - "url": "resources/img/flowers.jpg" - }, - "moon": { - "type": "image", - "url": "resources/img/moon.jpg" - } - }, - "steps": [ - { - "comment": "-------------------------------- Load the test module", - "action": "load", - "url": "resources/plugins/test.js" - }, - { - "comment": "------------------------------- Pause before we start", - "action": "pause", - "duration": 2, - "label": "start" - }, - { - "comment": "---------------------------------- Set up the content", - "action": "set content", - "blocks": [ - { - "block": "title", - "content": "presenter title" - }, - { - "block": "body", - "content": "slide 1" - }, - { - "block": "left image", - "content": "flowers" - } - ] - }, - { - "comment": "----------------------------- Fade up the intro title", - "action": "fade up", - "blocks": [ - "title" - ], - "duration": 3 - }, - { - "comment": "-------------------------------------- Wait 4 seconds", - "action": "hold", - "duration": 4 - }, - { - "comment": "-------------------------------- Transition the title", - "action": "transition", - "type": [ - "block position", - "block size", - "font color", - "font size" - ], - "block": "title", - "target": "title 2", - "duration": 1, - "continue": true - }, - { - "comment": "----------------------------- Pause for half a second", - "action": "pause", - "duration": 0.5 - }, - { - "comment": "-------------------------------- Show the first slide", - "action": "fade up", - "blocks": [ - "body" - ], - "duration": 1 - }, - { - "comment": "--------------------------------- Run the test plugin", - "action": "test", - "block": "title", - "duration": 0.5 - }, - { - "comment": "------------------------------------- Wait 10 seconds", - "action": "hold", - "duration": 10 - }, - { - "comment": "-------------------------------- Change the body text", - "action": "crossfade", - "block": "body", - "target": "slide 2", - "duration": 1, - "label": "loop" - }, - { - "comment": "-------------------------------------- Wait 5 seconds", - "action": "hold", - "duration": 5 - }, - { - "comment": "-------------------------- Move the body to the right", - "action": "transition", - "type": [ - "block position", - "block size" - ], - "block": "body", - "target": "body right", - "duration": 1 - }, - { - "comment": "----------------------------- Fade up the image block", - "action": "fade up", - "blocks": [ - "left image" - ], - "duration": 2 - }, - { - "comment": "-------------------------------------- Wait 8 seconds", - "action": "hold", - "duration": 8 - }, - { - "comment": "--------------------------------- Crossfade the image", - "action": "crossfade", - "block": "left image", - "target": "moon", - "duration": 1 - }, - { - "comment": "-------------------------------------- Wait 2 seconds", - "action": "hold", - "duration": 2 - }, - { - "comment": "-------------------------------- Change the body text", - "action": "set content", - "blocks": [ - { - "block": "body", - "content": "slide 3" - } - ] - }, - { - "comment": "------------------------------------- Wait 10 seconds", - "action": "hold", - "duration": 10 - }, - { - "comment": "------------------------ Fade down the title and body", - "action": "fade down", - "blocks": [ - "title", - "body", - "left image" - ], - "duration": 3 - }, - { - "comment": "-------------------------------- Go back to the start", - "action": "goto", - "target": "start" - } - ] -} \ No newline at end of file diff --git a/mostrami/resources/json/properties.json b/mostrami/resources/json/properties.json deleted file mode 100644 index 86e2c24..0000000 --- a/mostrami/resources/json/properties.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "left": 0, - "top": 0, - "width": "100%", - "height": "100%", - "background": "", - "border": "", - "borderRadius": "", - "fontFamily": "", - "fontSize": 30, - "fontWeight": "", - "fontStyle": "", - "fontColor": "", - "textAlign": "", - "textMarginLeft": "", - "textMarginTop": "" -} diff --git a/mostrami/resources/json/test.json b/mostrami/resources/json/test.json deleted file mode 100644 index e097c68..0000000 --- a/mostrami/resources/json/test.json +++ /dev/null @@ -1 +0,0 @@ -{"blocks":{"title":{"background":"","border":"","borderRadius":"","fontColor":"","fontFamily":"","fontSize":30,"fontStyle":"","fontWeight":"","height":"100%","left":0,"textAlign":"","textMarginLeft":"","textMarginTop":"","top":0,"width":"100%"}},"content":{"main title":{"content":"This is my title","type":"text"}},"steps":[{"comment":"Init","action":"init","label":"","aspect ratio":"16:9","background":"yellow","border":"","title":"My first presentation"},{"comment":"Setup main title","action":"set content","label":"","blocks":[{"block":"title","content":"main title"}]}]} \ No newline at end of file diff --git a/mostrami/resources/plugins/test.js b/mostrami/resources/plugins/test.js deleted file mode 100644 index cd26523..0000000 --- a/mostrami/resources/plugins/test.js +++ /dev/null @@ -1,32 +0,0 @@ -const JSON_Presenter_Test = step => { - if (step.script.speed === `scan`) { - step.next(); - } else { - const animSteps = Math.round(step.duration * 25); - let animStep = 0; - let interval = setInterval(() => { - if (animStep < animSteps) { - const ratio = 0.5 - Math.cos(Math.PI * animStep / animSteps) / 2; - const block = step.script.blocks[step.block]; - block.element.style[`opacity`] = 1.0 - ratio; - animStep++; - } else { - clearInterval(interval); - animStep = 0; - interval = setInterval(() => { - if (animStep < animSteps) { - const ratio = 0.5 - Math.cos(Math.PI * animStep / animSteps) / 2; - const block = step.script.blocks[step.block]; - block.element.style[`opacity`] = ratio; - animStep++; - } else { - clearInterval(interval); - step.next(); - } - }, 40); - } - }, step.script.speed === `normal` ? 40 : 400); - } -}; - -JSON_Presenter.plugins.test = JSON_Presenter_Test; diff --git a/mostrami/resources/properties.txt b/mostrami/resources/properties.txt deleted file mode 100644 index 82915a9..0000000 --- a/mostrami/resources/properties.txt +++ /dev/null @@ -1 +0,0 @@ -password=$2y$10$Kazqoaw6fGfV22bp3otJeO6Xra4bCsBJXq6JVAV07qOkHNDIFevWG diff --git a/mostrami/rest.php b/mostrami/rest.php deleted file mode 100644 index 4d5d87c..0000000 --- a/mostrami/rest.php +++ /dev/null @@ -1,546 +0,0 @@ -<?php - // REST server - - // This small REST server gives you the ability to manage tables - // in your site database. - - date_default_timezone_set('Europe/London'); - logger(substr($_SERVER['PATH_INFO'], 1)); - $request = explode("/", substr($_SERVER['PATH_INFO'], 1)); - $table = array_shift($request); - $method = $_SERVER['REQUEST_METHOD']; - - $props = array(); - $filename = 'resources/properties.txt'; - if (file_exists($filename)) { - $file = fopen($filename, 'r'); - while (!feof($file)) { - $ss = trim(fgets($file)); - if (!$ss || substr($ss, 0, 1) == '#') { - continue; - } - $ss = explode('=', $ss, 2); - if (count($ss) > 1) { - $props[$ss[0]] = $ss[1]; - } - } - fclose($file); - } - - // First, the commands that don't require a database connection. - switch ($method) { - case 'GET': - switch ($table) { - case '_list': - // List the contents of a directory, starting at 'resources' - // Endpoint: {site root}/rest.php/_list/[{path}] - $path = getcwd() . '/'; - if (count($request)) { - $path .= 'resources/' . join('/', $request); - } - $files = scandir($path); - print '['; - // First list all the directories - $flag = false; - foreach ($files as $file) { - if (strpos($file, '.') !== 0) { - if (is_dir("$path/$file")) { - if ($flag) { - print ','; - } else { - $flag = true; - } - print "{\"name\":\"$file\",\"type\":\"dir\"}"; - } - } - } - // Now do the ordinary files - foreach ($files as $file) { - if (strpos($file, '.') !== 0) { - if (!is_dir("$path/$file")) { - if ($flag) { - print ','; - } else { - $flag = true; - } - $type = 'file'; - $p = strrpos($file, '.'); - if ($p > 0) { - $ext = substr($file, $p + 1); - $type = $ext; - switch (strtolower($ext)) { - case 'jpg': - case 'png': - case 'gif': - $type = 'img'; - break; - } - } - print "{\"name\":\"$file\",\"type\":\"$type\"}"; - } - } - } - print ']'; - exit; - case '_hash': - // Get a hash of a value - // Endpoint: {site root}/easycoder/rest.php/_hash/{value-to-hash} - print password_hash(join('/', $request), PASSWORD_DEFAULT); - exit; - case '_verify': - // Verify a hash - // Endpoint: {site root}/easycoder/rest.php/_verify/{value-to-verify} - print password_verify(join('/', $request), $props['password']) ? 'yes' : 'no'; - exit; - case '_exists': - // Test if a file exists - // Endpoint: {site root}/easycoder/rest.php/_exists/{{path} - $path = getcwd() . '/' . join('/', $request); - print file_exists($path) ? 'Y' : ''; - exit; - case '_load': - // Load a file from the resources folder - // Endpoint: {site root}/easycoder/rest.php/_load/{path} - $path = getcwd() . '/' . join('/', $request); - print file_get_contents($path); - exit; - case '_loadall': - // Load all the files in the named folder - // Endpoint: {site root}/easycoder/rest.php/_loadall/{path} - $path = getcwd() . '/'; - if (count($request)) { - $path .= join('/', $request); - } - $files = scandir($path); - print '['; - $flag = false; - foreach ($files as $file) { - if (strpos($file, '.') !== 0) { - if (!is_dir("$path/$file")) { - if ($flag) { - print ','; - } else { - $flag = true; - } - print file_get_contents("$path/$file"); - } - } - } - print ']'; - exit; - case '_test': - // Test endpoint - // Endpoint: {site root}/easycoder/rest.php/_test/ - print $_SERVER['HTTP_HOST']; - exit; - } - break; - case 'POST': - switch ($table) { - case '_mkdir': - // Create a directory - // Endpoint: {site root}/easycoder/rest.php/_mkdir/{path} - $path = getcwd() . '/' . join('/', $request); - logger("Create directory $path"); - print("Create directory $path"); - mkdir($path); - exit; - case '_upload': - // Upload a file (an image) to the current directory - // Endpoint: {site root}/easycoder/rest.php/_upload/{path} - $path = $_POST['path']; - $path = explode("/", $path); - array_shift($path); - $path = join('/', $path); - mkdir($path, 0777, true); - logger("path: $path"); - $fileName = $_FILES['source']['name']; - $tempName = $_FILES['source']['tmp_name']; - $fileType = $_FILES['source']['type']; - $fileSize = $_FILES['source']['size']; - $fileError = $_FILES['source']['error']; - if (!move_uploaded_file($tempName, "$path/$fileName")) { - unlink($tempName); - http_response_code(400); - logger("Failed to upload $tempName to $fileName.\ntempName: $tempName\nfileType: $fileType\nfileSize:$fileSize\nfileError: $fileError"); - } else { - logger("File $fileName uploaded successfully to $path/$fileName"); - $size = getimagesize("$path/$fileName"); - logger("$path/$fileName: width:".$size[0].", height:".$size[1]); - if ($size[0] > 1024) { - logger("mogrify -resize 1024x1024 $path/$fileName"); - system("mogrify -resize 1024x1024 $path/$fileName"); - } - } - exit; - case '_save': - // Save data to a file in the resources folder - // Endpoint: {site root}/easycoder/rest.php/_save/{path} - $path = getcwd() . '/resources/' . join('/', $request); - $p = strrpos($path, '/'); - $dir = substr($path, 0, $p); - mkdir($dir, 0777, true); - header("Content-Type: application/text"); - $content = stripslashes(file_get_contents("php://input")); - $p = strrpos($path, '.'); - $root = substr($path, 0, $p); - $ext = substr($path, $p); - file_put_contents($path, $content); - exit; - case '_delete': - // Delete a file in the resources folder - // Endpoint: {site root}/easycoder/rest.php/_delete/{path} - $path = getcwd() . '/resources/' . join('/', $request); - if (is_dir($path)) { - rmdir($path); - } else { - unlink($path); - } - exit; - case '_email': - // Send an email - // Endpoint: {site root}/easycoder/rest.php/_email - header("Content-Type: application/text"); - $value = stripslashes(file_get_contents("php://input")); - $json = json_decode($value); - $from = $json->from; - $to = $json->to; - $subject = $json->subject; - $message = $json->message; - $headers = "MIME-Version: 1.0\r\n"; - $headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n"; - $headers .= "From: $from\r\n"; - mail($to, $subject, $message, "$headers\r\n"); - print "$headers\r\n$message"; - exit; - } - break; - } - - // Most of the remaining commands require use of the database. - $conn = mysqli_connect($props['sqlhost'], $props['sqluser'], - $props['sqlpassword'], $props['sqldatabase']); - if (!$conn) - { - http_response_code(404); - die("Failed to connect to MySQL: " . mysqli_connect_error()); - } - mysqli_set_charset($conn,'utf8'); - - if (!count($request)) { - http_response_code(400); - print "{\"message\":\"Incomplete REST query: ".substr($_SERVER['PATH_INFO'], 1).".\"}"; - exit; - } - - // You can have a custom extension that deals with special requests. - // These all have '_' as the table name. - switch ($method) { - - case 'GET': - if ($table == '_') { - // Endpoint: {site root}/rest.php/_/{request-and-arguments} - include_once 'rest-local.php'; - get_local($conn, $request); - return; - } else { - // Use the handler below - get($conn, $table, $request); - } - break; - - case 'POST': - if ($table == '_') { - // Endpoint: {site root}/rest.php/_/{request-and-arguments} - include_once 'rest-local.php'; - post_local($conn, $request); - return; - } else { - // Use the handler below - post($conn, $table, $request); - } - break; - - default: - http_response_code(400); - break; - } - mysqli_close(); - exit; - - ///////////////////////////////////////////////////////////////////////// - // All the other commands deal with tables having a specific format, with the following fields: - // - // id int(11) - // name varchar(40) - // value text - // ts int(11) - // - // GET - function get($conn, $table, $request) { - $action = $request[0]; - switch ($action) { - case 'count': - // Return the number of items in a table - // Endpoint: {site root}/easycoder/rest.php/table/count - $result = $conn->query("SELECT id from $table"); - //print "{\"count\":".mysqli_num_rows($result)."}"; - print mysqli_num_rows($result); - mysqli_free_result($result); - break; - - case 'list': - // List items by ID, with optional offset & count, defaulting to 0 & 10 - // Endpoint: {site root}/easycoder/rest.php/{table}/list/{offset}/{count} - switch (count($request)) { - case 2: - $offset = 0; - $count = $request[1]; - break; - case 3: - $offset = $request[1]; - $count = $request[2]; - break; - default: - $offset = 0; - $count = 10; - break; - } - $result = $conn->query("SELECT id FROM $table LIMIT $offset, $count"); - $response = '['; - while ($row = mysqli_fetch_object($result)) { - if ($response != '[') { - $response .= ','; - } - $response .= $row->id; - } - mysqli_free_result($result); - $response .= ']'; - print $response; - break; - - case 'names': - // List items by name in ascending alphabetical order, - // with optional offset & count, defaulting to 0 & 10 - // Endpoint: {site root}/easycoder/rest.php/{table}/names/{offset}/{count} - switch (count($request)) { - case 2: - $offset = 0; - $count = $request[1]; - break; - case 3: - $offset = $request[1]; - $count = $request[2]; - break; - default: - $offset = 0; - $count = 10; - break; - } - $result = $conn->query("SELECT name FROM $table ORDER BY name LIMIT $offset, $count"); - $response = '['; - while ($row = mysqli_fetch_object($result)) { - if ($response != '[') { - $response .= ','; - } - $response .= "\"$row->name\""; - } - mysqli_free_result($result); - $response .= ']'; - print $response; - break; - - case 'id': - // Get a record given its id - // Endpoint: {site root}/easycoder/rest.php/{table}/id/{id} - if (count($request) < 2) { - http_response_code(400); - print "Incomplete REST query."; - exit; - } - $id = $request[1]; - $result = $conn->query("SELECT value FROM $table WHERE id='$id'"); - if ($row = mysqli_fetch_object($result)) { - print $row->value; - } else { - http_response_code(404); - print "Cannot get item id '$id' as it does not exist."; - } - mysqli_free_result($result); - break; - - case 'name': - case 'query': - // Get a record given its name - // Endpoint: {site root}/easycoder/rest.php/{table}/name/{name} - if (count($request) < 2) { - http_response_code(400); - print "Incomplete REST query."; - exit; - } - $name = $request[1]; - $result = $conn->query("SELECT value FROM $table WHERE name='$name'"); - if ($row = mysqli_fetch_object($result)) { - print $row->value; - } else if ($action == 'name') { - http_response_code(404); - print "Cannot get item named '$name' as it does not exist."; - } - break; - - default: - http_response_code(404); - print "I don't understand this request."; - break; - } - } - - ///////////////////////////////////////////////////////////////////////// - // POST - function post($conn, $table, $request) { - $ts = time(); - $action = $request[0]; - switch ($action) { - case 'set': - // Set the value of a record - if (count($request) > 2) { - switch ($request[1]) { - case 'id': - // Set by id. The record must already exist - // Endpoint: {site root}/easycoder/rest.php/{table}/id/{id} - header("Content-Type: application/text"); - $value = stripslashes(file_get_contents("php://input")); - $id = $request[2]; - // See if there's an item with this id - $result = $conn->query("SELECT id FROM $table WHERE id=$id"); - if (mysqli_fetch_object($result)) { - // It exists, so update it - $value = urldecode($value); - logger("UPDATE $table SET value='$value',ts=$ts WHERE id=$id"); - query($conn, "UPDATE $table SET value='$value',ts=$ts WHERE id=$id"); - } else { - // Not found - http_response_code(404); - logger("{\"code\":\"404\",\"message\":\"Cannot set record $id of $table.\"}"); - print "{\"message\":\"Cannot set record $id of $table.\"}"; - } - mysqli_free_result($result); - break; - - case 'name': - // Set by name. If the record does not exist, add it - // Endpoint: {site root}/easycoder/rest.php/{table}/name/{name} - header("Content-Type: application/text"); - $value = stripslashes(file_get_contents("php://input")); - $name = $request[2]; - // See if there's an item with this name - $result = $conn->query("SELECT id FROM $table WHERE name='$name'"); - if (mysqli_fetch_object($result)) { - // It exists, so update it - query($conn, "UPDATE $table SET value='$value',ts=$ts WHERE name='$name'"); - } else { - // Add a new item - query($conn, "INSERT INTO $table (name,value,ts) VALUES ('$name','$value','$ts')"); - http_response_code(201); - } - mysqli_free_result($result); - break; - - default: - http_response_code(400); - print "{\"message\":\"Value '".$request[1]."' should be 'id' or 'name'.\"}"; - break; - } - } else { - http_response_code(400); - print "{\"message\":\"Incomplete REST query.\"}"; - } - break; - - case 'delete': - // Delete a record, by id or by name - // Endpoint: {site root}/easycoder/rest.php/{table}/delete/{id} - // Or: ...{site root}/easycoder/rest.php/table/delete/{name} - if (count($request) > 1) { - $item = $request[1]; - if (is_int($item)) { - // Delete the requested id - query($conn, "DELETE FROM $table WHERE id=$id"); - } else { - // Delete the named item - query($conn, "DELETE FROM $table WHERE name='$item'"); - } - } - break; - - case 'rename': - // Rename a record - // Endpoint: {site root}/easycoder/rest.php/{table}/rename - $value = $_POST['value']; - $id = $_POST['id']; - if (!$id && count($request) > 1) { - $id = $request[1]; - } - if ($id) { - query($conn, "UPDATE $table SET name='$name',value='$value' WHERE id=$id"); - } else { - $name = $_POST['name']; - $newname = $_POST['newname']; - // See if there's a data item with the new name - $result = $conn->query("SELECT id FROM $table WHERE name='$newname'"); - if ($row = mysqli_fetch_object($result)) { - // Conflict - http_response_code(409); - print "{\"message\":\"Cannot rename item '$name' to '$newname' as it already exists.\"}"; - } else { - // See if there's a data item with this name - $result = $conn->query("SELECT id FROM $table WHERE name='$name'"); - if ($row = mysqli_fetch_object($result)) { - // There's a data item to rename - $id = $row->id; - query($conn, "UPDATE $table SET name='$newname',value='$value' WHERE id=$id"); - } else { - // Not found - http_response_code(404); - print "{\"message\":\"Cannot rename item '$name' as it does not exist.\"}"; - } - } - mysqli_free_result($result); - } - break; - - default: - http_response_code(404); - print "{\"message\":\"Unrecognised action '$action' requested.\"}"; - break; - } - } - - ///////////////////////////////////////////////////////////////////////// - // Do an SQL query - function query($conn, $sql) - { - $result = mysqli_query($conn, $sql); - if (!$result) { - http_response_code(404); - logger('Error: '.mysqli_error($conn)); - die('Error: '.mysqli_error($conn)); - } - return $result; - } - - //////////////////////////////////////////////////////////////////////////// - // Log a message. - function logger($message) - { - $timestamp = time(); - $date = date("Y/m/d H:i", $timestamp); - if (!file_exists("log")) mkdir("log"); - $file = "log/".date("Y", $timestamp); - if (!file_exists($file)) mkdir($file); - $file.= "/".date("Ymd", $timestamp).".txt"; - $fp = fopen($file, "a+") or die("Can't open $file"); - fwrite($fp, "$date: $message\n"); - fclose($fp); - } -?> diff --git a/mostrami/scripted.html b/mostrami/scripted.html deleted file mode 100644 index 55a33d2..0000000 --- a/mostrami/scripted.html +++ /dev/null @@ -1,24 +0,0 @@ -<html lang="en"> - -<head> - <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>Script Editor</title> - <script type='text/javascript' src='https://cdn.jsdelivr.net/gh/easycoder/easycoder.github.io/dist/easycoder.js?v=2.7.1'></script> -</head> - -<body> - <pre id="easycoder-rest" style="display:none">rest.php</pre> - <pre id="easycoder-script" style="display:none"> - ! EasyCoder Script Editor - - script Launcher - - variable Script - require js `https://cdn.jsdelivr.net/gh/easycoder/easycoder.github.io/dist/plugins/codemirror.js?v=2.7.1` - rest get Script from `/resources/ecs/scripted.txt?v=` cat now - run Script - </pre> -</body> - -</html>