From fed72acd290a958d9749519834bfdecdab6b30ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=96=9F=E9=85=8C=20=E9=B5=AC=E5=85=84?= Date: Fri, 14 Aug 2015 21:06:23 +0800 Subject: [PATCH] Astro Classes --- .../templates/test/Astro.Blog.AstroEdit.html | 201 +++++ .../test/Astro.Blog.Components.Calendar.html | 18 + .../test/Astro.Blog.Components.Comment.html | 101 +++ .../test/Astro.Blog.Components.Comment2.html | 150 ++++ .../Astro.Blog.Components.Notification.html | 38 + .../test/Astro.Blog.Components.SiteFile.html | 49 ++ .../test/Astro.Blog.Components.Spoiler.html | 24 + .../test/Astro.Blog.Components.Video.html | 19 + .../Astro.Blog.Layout.Article.Control.html | 28 + .../Astro.Blog.Layout.Article.Latest.html | 482 +++++++++++ .../test/Astro.Blog.Layout.ErrorPages.html | 28 + .../test/Astro.Blog.Layout.Login.html | 18 + botanjs/src/Astro/Blog/AstroEdit/Article.js | 453 +++++++++++ botanjs/src/Astro/Blog/AstroEdit/Draft.js | 158 ++++ .../src/Astro/Blog/AstroEdit/SiteLibrary.css | 367 +++++++++ .../src/Astro/Blog/AstroEdit/SiteLibrary.js | 745 ++++++++++++++++++ botanjs/src/Astro/Blog/AstroEdit/Tag.css | 27 + botanjs/src/Astro/Blog/AstroEdit/Tag.js | 197 +++++ botanjs/src/Astro/Blog/AstroEdit/Uploader.js | 241 ++++++ .../Visualizer/Snippet/AcquireLib.js | 110 +++ .../Blog/AstroEdit/Visualizer/Snippet/Code.js | 191 +++++ .../Blog/AstroEdit/Visualizer/Snippet/Html.js | 107 +++ .../AstroEdit/Visualizer/Snippet/Image.js | 157 ++++ .../Blog/AstroEdit/Visualizer/Snippet/Link.js | 131 +++ .../AstroEdit/Visualizer/Snippet/SiteFile.js | 174 ++++ .../AstroEdit/Visualizer/Snippet/Sound.js | 146 ++++ .../AstroEdit/Visualizer/Snippet/Spoiler.js | 154 ++++ .../Blog/AstroEdit/Visualizer/Snippet/Swf.js | 214 +++++ .../AstroEdit/Visualizer/Snippet/Video.js | 137 ++++ .../AstroEdit/Visualizer/Snippet/_this.js | 25 + .../Astro/Blog/AstroEdit/Visualizer/_this.css | 101 +++ .../Astro/Blog/AstroEdit/Visualizer/_this.js | 496 ++++++++++++ botanjs/src/Astro/Blog/AstroEdit/_this.css | 244 ++++++ botanjs/src/Astro/Blog/AstroEdit/_this.js | 99 +++ botanjs/src/Astro/Blog/Components/Bubble.css | 35 + botanjs/src/Astro/Blog/Components/Bubble.js | 133 ++++ .../src/Astro/Blog/Components/Calendar.css | 67 ++ botanjs/src/Astro/Blog/Components/Calendar.js | 244 ++++++ botanjs/src/Astro/Blog/Components/Comment.css | 288 +++++++ botanjs/src/Astro/Blog/Components/Comment.js | 709 +++++++++++++++++ .../Astro/Blog/Components/ControlPanel.css | 50 ++ .../src/Astro/Blog/Components/ControlPanel.js | 1 + .../src/Astro/Blog/Components/CrowdTag.css | 6 + botanjs/src/Astro/Blog/Components/CrowdTag.js | 1 + .../src/Astro/Blog/Components/Entry/Block.css | 149 ++++ .../src/Astro/Blog/Components/Entry/Block.js | 1 + .../src/Astro/Blog/Components/Entry/Blog.css | 104 +++ .../src/Astro/Blog/Components/Entry/Blog.js | 1 + .../src/Astro/Blog/Components/Entry/Home.css | 129 +++ .../src/Astro/Blog/Components/Entry/Home.js | 1 + .../src/Astro/Blog/Components/Entry/List.css | 67 ++ .../src/Astro/Blog/Components/Entry/List.js | 1 + .../src/Astro/Blog/Components/Entry/Mega.css | 139 ++++ .../src/Astro/Blog/Components/Entry/Mega.js | 1 + .../src/Astro/Blog/Components/Entry/Tag.css | 63 ++ .../src/Astro/Blog/Components/Entry/Tag.js | 1 + .../Astro/Blog/Components/Notification.css | 155 ++++ .../src/Astro/Blog/Components/Notification.js | 235 ++++++ .../src/Astro/Blog/Components/SiteFile.css | 84 ++ botanjs/src/Astro/Blog/Components/SiteFile.js | 147 ++++ .../Astro/Blog/Components/SocialButtons.css | 8 + .../Astro/Blog/Components/SocialButtons.js | 40 + botanjs/src/Astro/Blog/Components/Spoiler.css | 25 + botanjs/src/Astro/Blog/Components/Spoiler.js | 49 ++ .../src/Astro/Blog/Components/TagControl.css | 24 + .../src/Astro/Blog/Components/TagControl.js | 1 + .../Components/ToggleButton/CommentToggle.css | 42 + .../Components/ToggleButton/CommentToggle.js | 27 + .../Blog/Components/ToggleButton/_this.css | 84 ++ .../Blog/Components/ToggleButton/_this.js | 61 ++ .../Astro/Blog/Components/VerticalNote.css | 80 ++ .../src/Astro/Blog/Components/VerticalNote.js | 79 ++ botanjs/src/Astro/Blog/Components/Video.css | 32 + botanjs/src/Astro/Blog/Components/Video.js | 103 +++ botanjs/src/Astro/Blog/Config.js | 12 + botanjs/src/Astro/Blog/Element/Footer.css | 12 + botanjs/src/Astro/Blog/Element/Footer.js | 2 + botanjs/src/Astro/Blog/Element/Header.css | 89 +++ botanjs/src/Astro/Blog/Element/Header.js | 1 + botanjs/src/Astro/Blog/Element/Layer.css | 2 + botanjs/src/Astro/Blog/Element/Layer.js | 1 + .../src/Astro/Blog/Layout/Article/Control.js | 53 ++ .../src/Astro/Blog/Layout/Article/Latest.js | 6 + .../src/Astro/Blog/Layout/Article/_this.js | 3 + botanjs/src/Astro/Blog/Layout/ErrorPages.css | 99 +++ botanjs/src/Astro/Blog/Layout/ErrorPages.js | 75 ++ botanjs/src/Astro/Blog/Layout/Login.css | 63 ++ botanjs/src/Astro/Blog/Layout/Login.js | 75 ++ botanjs/src/Astro/Blog/Layout/MainFrame.css | 108 +++ botanjs/src/Astro/Blog/Layout/MainFrame.js | 256 ++++++ botanjs/src/Astro/Blog/Layout/TwoColumn.css | 102 +++ botanjs/src/Astro/Blog/Layout/TwoColumn.js | 28 + botanjs/src/Astro/Blog/Layout/_this.js | 3 + botanjs/src/Astro/Bootstrap.css | 85 ++ botanjs/src/Astro/Bootstrap.js | 71 ++ .../src/Astro/Build/Components/BuildList.css | 24 + .../src/Astro/Build/Components/BuildList.js | 1 + .../Astro/Build/Components/BuildReport.css | 67 ++ .../src/Astro/Build/Components/BuildReport.js | 55 ++ .../src/Astro/Build/Components/ItemList.css | 59 ++ .../src/Astro/Build/Components/ItemList.js | 1 + botanjs/src/Astro/Build/Element/Footer.css | 12 + botanjs/src/Astro/Build/Element/Footer.js | 2 + botanjs/src/Astro/Build/Element/Header.css | 87 ++ botanjs/src/Astro/Build/Element/Header.js | 1 + botanjs/src/Astro/Build/Layout/MainFrame.css | 86 ++ botanjs/src/Astro/Build/Layout/MainFrame.js | 88 +++ botanjs/src/Astro/Build/Page/About.css | 11 + botanjs/src/Astro/Build/Page/About.js | 1 + botanjs/src/Astro/Build/Page/Index.css | 24 + botanjs/src/Astro/Build/Page/Index.js | 1 + botanjs/src/Astro/Build/Page/_this.css | 5 + botanjs/src/Astro/Common/Element/Footer.css | 36 + botanjs/src/Astro/Common/Element/Footer.js | 1 + .../src/Astro/Mechanism/CharacterCloud.css | 7 + botanjs/src/Astro/Mechanism/CharacterCloud.js | 77 ++ botanjs/src/Astro/Mechanism/Parallax.css | 6 + botanjs/src/Astro/Mechanism/Parallax.js | 89 +++ botanjs/src/Astro/utils/Date.js | 140 ++++ botanjs/src/Astro/utils/_this.js | 3 + .../externs/Astro.Blog.AstroEdit.Article.js | 18 + .../src/externs/Astro.Blog.AstroEdit.Tag.js | 6 + ...Blog.AstroEdit.Visualizer.Snippet.Model.js | 6 + ...Astro.Blog.AstroEdit.Visualizer.Snippet.js | 6 + .../Astro.Blog.AstroEdit.Visualizer.js | 12 + botanjs/src/externs/Astro.Blog.AstroEdit.js | 2 + .../externs/Astro.Blog.Components.Bubble.js | 18 + .../externs/Astro.Blog.Components.Calendar.js | 13 + botanjs/src/externs/Astro.Blog.Components.js | 2 + botanjs/src/externs/Astro.Blog.Config.js | 5 + .../externs/Astro.Blog.Events.Responsive.js | 8 + botanjs/src/externs/Astro.Blog.Events.js | 2 + botanjs/src/externs/Astro.Blog.js | 2 + botanjs/src/externs/Astro.Bootstrap.js | 8 + .../externs/Astro.Mechanism.CharacterCloud.js | 5 + .../src/externs/Astro.Mechanism.Parallax.js | 9 + botanjs/src/externs/Astro.Mechanism.js | 2 + botanjs/src/externs/Astro.js | 2 + botanjs/src/externs/Astro.utils.Date.js | 24 + botanjs/src/externs/Astro.utils.js | 2 + botanjs/src/externs/_3rdParty_.Recaptcha.js | 12 + botanjs/src/externs/_3rdParty_.js | 2 + botanjs/src/externs/_AstConf_.Article.js | 4 + botanjs/src/externs/_AstConf_.AstroEdit.js | 20 + botanjs/src/externs/_AstConf_.Comment.js | 6 + botanjs/src/externs/_AstConf_.Control.js | 6 + botanjs/src/externs/_AstConf_.Login.js | 6 + botanjs/src/externs/_AstConf_.SiteFile.js | 21 + botanjs/src/externs/_AstConf_.UserInfo.js | 9 + botanjs/src/externs/_AstConf_.js | 2 + .../src/externs/_AstJson_.AJaxGetArticle.js | 29 + .../src/externs/_AstJson_.AJaxGetDrafts.js | 18 + .../externs/_AstJson_.AJaxGetFiles.Request.js | 13 + botanjs/src/externs/_AstJson_.AJaxGetFiles.js | 24 + botanjs/src/externs/_AstJson_.SiteFile.js | 21 + botanjs/src/externs/_AstJson_.js | 2 + settings.ini | 4 +- 157 files changed, 11676 insertions(+), 2 deletions(-) create mode 100644 botanjs/service/templates/test/Astro.Blog.AstroEdit.html create mode 100644 botanjs/service/templates/test/Astro.Blog.Components.Calendar.html create mode 100644 botanjs/service/templates/test/Astro.Blog.Components.Comment.html create mode 100644 botanjs/service/templates/test/Astro.Blog.Components.Comment2.html create mode 100644 botanjs/service/templates/test/Astro.Blog.Components.Notification.html create mode 100644 botanjs/service/templates/test/Astro.Blog.Components.SiteFile.html create mode 100644 botanjs/service/templates/test/Astro.Blog.Components.Spoiler.html create mode 100644 botanjs/service/templates/test/Astro.Blog.Components.Video.html create mode 100644 botanjs/service/templates/test/Astro.Blog.Layout.Article.Control.html create mode 100644 botanjs/service/templates/test/Astro.Blog.Layout.Article.Latest.html create mode 100644 botanjs/service/templates/test/Astro.Blog.Layout.ErrorPages.html create mode 100644 botanjs/service/templates/test/Astro.Blog.Layout.Login.html create mode 100644 botanjs/src/Astro/Blog/AstroEdit/Article.js create mode 100644 botanjs/src/Astro/Blog/AstroEdit/Draft.js create mode 100644 botanjs/src/Astro/Blog/AstroEdit/SiteLibrary.css create mode 100644 botanjs/src/Astro/Blog/AstroEdit/SiteLibrary.js create mode 100644 botanjs/src/Astro/Blog/AstroEdit/Tag.css create mode 100644 botanjs/src/Astro/Blog/AstroEdit/Tag.js create mode 100644 botanjs/src/Astro/Blog/AstroEdit/Uploader.js create mode 100644 botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/AcquireLib.js create mode 100644 botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Code.js create mode 100644 botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Html.js create mode 100644 botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Image.js create mode 100644 botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Link.js create mode 100644 botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/SiteFile.js create mode 100644 botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Sound.js create mode 100644 botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Spoiler.js create mode 100644 botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Swf.js create mode 100644 botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Video.js create mode 100644 botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/_this.js create mode 100644 botanjs/src/Astro/Blog/AstroEdit/Visualizer/_this.css create mode 100644 botanjs/src/Astro/Blog/AstroEdit/Visualizer/_this.js create mode 100644 botanjs/src/Astro/Blog/AstroEdit/_this.css create mode 100644 botanjs/src/Astro/Blog/AstroEdit/_this.js create mode 100644 botanjs/src/Astro/Blog/Components/Bubble.css create mode 100644 botanjs/src/Astro/Blog/Components/Bubble.js create mode 100644 botanjs/src/Astro/Blog/Components/Calendar.css create mode 100644 botanjs/src/Astro/Blog/Components/Calendar.js create mode 100644 botanjs/src/Astro/Blog/Components/Comment.css create mode 100644 botanjs/src/Astro/Blog/Components/Comment.js create mode 100644 botanjs/src/Astro/Blog/Components/ControlPanel.css create mode 100644 botanjs/src/Astro/Blog/Components/ControlPanel.js create mode 100644 botanjs/src/Astro/Blog/Components/CrowdTag.css create mode 100644 botanjs/src/Astro/Blog/Components/CrowdTag.js create mode 100644 botanjs/src/Astro/Blog/Components/Entry/Block.css create mode 100644 botanjs/src/Astro/Blog/Components/Entry/Block.js create mode 100644 botanjs/src/Astro/Blog/Components/Entry/Blog.css create mode 100644 botanjs/src/Astro/Blog/Components/Entry/Blog.js create mode 100644 botanjs/src/Astro/Blog/Components/Entry/Home.css create mode 100644 botanjs/src/Astro/Blog/Components/Entry/Home.js create mode 100644 botanjs/src/Astro/Blog/Components/Entry/List.css create mode 100644 botanjs/src/Astro/Blog/Components/Entry/List.js create mode 100644 botanjs/src/Astro/Blog/Components/Entry/Mega.css create mode 100644 botanjs/src/Astro/Blog/Components/Entry/Mega.js create mode 100644 botanjs/src/Astro/Blog/Components/Entry/Tag.css create mode 100644 botanjs/src/Astro/Blog/Components/Entry/Tag.js create mode 100644 botanjs/src/Astro/Blog/Components/Notification.css create mode 100644 botanjs/src/Astro/Blog/Components/Notification.js create mode 100644 botanjs/src/Astro/Blog/Components/SiteFile.css create mode 100644 botanjs/src/Astro/Blog/Components/SiteFile.js create mode 100644 botanjs/src/Astro/Blog/Components/SocialButtons.css create mode 100644 botanjs/src/Astro/Blog/Components/SocialButtons.js create mode 100644 botanjs/src/Astro/Blog/Components/Spoiler.css create mode 100644 botanjs/src/Astro/Blog/Components/Spoiler.js create mode 100644 botanjs/src/Astro/Blog/Components/TagControl.css create mode 100644 botanjs/src/Astro/Blog/Components/TagControl.js create mode 100644 botanjs/src/Astro/Blog/Components/ToggleButton/CommentToggle.css create mode 100644 botanjs/src/Astro/Blog/Components/ToggleButton/CommentToggle.js create mode 100644 botanjs/src/Astro/Blog/Components/ToggleButton/_this.css create mode 100644 botanjs/src/Astro/Blog/Components/ToggleButton/_this.js create mode 100644 botanjs/src/Astro/Blog/Components/VerticalNote.css create mode 100644 botanjs/src/Astro/Blog/Components/VerticalNote.js create mode 100644 botanjs/src/Astro/Blog/Components/Video.css create mode 100644 botanjs/src/Astro/Blog/Components/Video.js create mode 100644 botanjs/src/Astro/Blog/Config.js create mode 100644 botanjs/src/Astro/Blog/Element/Footer.css create mode 100644 botanjs/src/Astro/Blog/Element/Footer.js create mode 100644 botanjs/src/Astro/Blog/Element/Header.css create mode 100644 botanjs/src/Astro/Blog/Element/Header.js create mode 100644 botanjs/src/Astro/Blog/Element/Layer.css create mode 100644 botanjs/src/Astro/Blog/Element/Layer.js create mode 100644 botanjs/src/Astro/Blog/Layout/Article/Control.js create mode 100644 botanjs/src/Astro/Blog/Layout/Article/Latest.js create mode 100644 botanjs/src/Astro/Blog/Layout/Article/_this.js create mode 100644 botanjs/src/Astro/Blog/Layout/ErrorPages.css create mode 100644 botanjs/src/Astro/Blog/Layout/ErrorPages.js create mode 100644 botanjs/src/Astro/Blog/Layout/Login.css create mode 100644 botanjs/src/Astro/Blog/Layout/Login.js create mode 100644 botanjs/src/Astro/Blog/Layout/MainFrame.css create mode 100644 botanjs/src/Astro/Blog/Layout/MainFrame.js create mode 100644 botanjs/src/Astro/Blog/Layout/TwoColumn.css create mode 100644 botanjs/src/Astro/Blog/Layout/TwoColumn.js create mode 100644 botanjs/src/Astro/Blog/Layout/_this.js create mode 100644 botanjs/src/Astro/Bootstrap.css create mode 100644 botanjs/src/Astro/Bootstrap.js create mode 100644 botanjs/src/Astro/Build/Components/BuildList.css create mode 100644 botanjs/src/Astro/Build/Components/BuildList.js create mode 100644 botanjs/src/Astro/Build/Components/BuildReport.css create mode 100644 botanjs/src/Astro/Build/Components/BuildReport.js create mode 100644 botanjs/src/Astro/Build/Components/ItemList.css create mode 100644 botanjs/src/Astro/Build/Components/ItemList.js create mode 100644 botanjs/src/Astro/Build/Element/Footer.css create mode 100644 botanjs/src/Astro/Build/Element/Footer.js create mode 100644 botanjs/src/Astro/Build/Element/Header.css create mode 100644 botanjs/src/Astro/Build/Element/Header.js create mode 100644 botanjs/src/Astro/Build/Layout/MainFrame.css create mode 100644 botanjs/src/Astro/Build/Layout/MainFrame.js create mode 100644 botanjs/src/Astro/Build/Page/About.css create mode 100644 botanjs/src/Astro/Build/Page/About.js create mode 100644 botanjs/src/Astro/Build/Page/Index.css create mode 100644 botanjs/src/Astro/Build/Page/Index.js create mode 100644 botanjs/src/Astro/Build/Page/_this.css create mode 100644 botanjs/src/Astro/Common/Element/Footer.css create mode 100644 botanjs/src/Astro/Common/Element/Footer.js create mode 100644 botanjs/src/Astro/Mechanism/CharacterCloud.css create mode 100644 botanjs/src/Astro/Mechanism/CharacterCloud.js create mode 100644 botanjs/src/Astro/Mechanism/Parallax.css create mode 100644 botanjs/src/Astro/Mechanism/Parallax.js create mode 100644 botanjs/src/Astro/utils/Date.js create mode 100644 botanjs/src/Astro/utils/_this.js create mode 100644 botanjs/src/externs/Astro.Blog.AstroEdit.Article.js create mode 100644 botanjs/src/externs/Astro.Blog.AstroEdit.Tag.js create mode 100644 botanjs/src/externs/Astro.Blog.AstroEdit.Visualizer.Snippet.Model.js create mode 100644 botanjs/src/externs/Astro.Blog.AstroEdit.Visualizer.Snippet.js create mode 100644 botanjs/src/externs/Astro.Blog.AstroEdit.Visualizer.js create mode 100644 botanjs/src/externs/Astro.Blog.AstroEdit.js create mode 100644 botanjs/src/externs/Astro.Blog.Components.Bubble.js create mode 100644 botanjs/src/externs/Astro.Blog.Components.Calendar.js create mode 100644 botanjs/src/externs/Astro.Blog.Components.js create mode 100644 botanjs/src/externs/Astro.Blog.Config.js create mode 100644 botanjs/src/externs/Astro.Blog.Events.Responsive.js create mode 100644 botanjs/src/externs/Astro.Blog.Events.js create mode 100644 botanjs/src/externs/Astro.Blog.js create mode 100644 botanjs/src/externs/Astro.Bootstrap.js create mode 100644 botanjs/src/externs/Astro.Mechanism.CharacterCloud.js create mode 100644 botanjs/src/externs/Astro.Mechanism.Parallax.js create mode 100644 botanjs/src/externs/Astro.Mechanism.js create mode 100644 botanjs/src/externs/Astro.js create mode 100644 botanjs/src/externs/Astro.utils.Date.js create mode 100644 botanjs/src/externs/Astro.utils.js create mode 100644 botanjs/src/externs/_3rdParty_.Recaptcha.js create mode 100644 botanjs/src/externs/_3rdParty_.js create mode 100644 botanjs/src/externs/_AstConf_.Article.js create mode 100644 botanjs/src/externs/_AstConf_.AstroEdit.js create mode 100644 botanjs/src/externs/_AstConf_.Comment.js create mode 100644 botanjs/src/externs/_AstConf_.Control.js create mode 100644 botanjs/src/externs/_AstConf_.Login.js create mode 100644 botanjs/src/externs/_AstConf_.SiteFile.js create mode 100644 botanjs/src/externs/_AstConf_.UserInfo.js create mode 100644 botanjs/src/externs/_AstConf_.js create mode 100644 botanjs/src/externs/_AstJson_.AJaxGetArticle.js create mode 100644 botanjs/src/externs/_AstJson_.AJaxGetDrafts.js create mode 100644 botanjs/src/externs/_AstJson_.AJaxGetFiles.Request.js create mode 100644 botanjs/src/externs/_AstJson_.AJaxGetFiles.js create mode 100644 botanjs/src/externs/_AstJson_.SiteFile.js create mode 100644 botanjs/src/externs/_AstJson_.js diff --git a/botanjs/service/templates/test/Astro.Blog.AstroEdit.html b/botanjs/service/templates/test/Astro.Blog.AstroEdit.html new file mode 100644 index 0000000..c5a1317 --- /dev/null +++ b/botanjs/service/templates/test/Astro.Blog.AstroEdit.html @@ -0,0 +1,201 @@ + + +Botan JS - Test + + + + + + + + + +
+
+ AstroEdit + OpenBlog +
+ +
+
+
+ +
+
+
+
+
+ +
+ + +
+ + +
actions
+
+
+
Publish
+
+
+
+
Preview
+ +
+
+
+
Save(Ctrl + s)
+
+
+
Delete
+
+
+ + +
snippets
+
+
+ + +
article properties
+
+
+
Date created
+
9th December, 2014
+
+
+
Date modified
+
9th December, 2014
+
+
+
Date published
+
9th December, 2014
+
+
+
Status
+
In draft
+
+
+ + +
tags +
+
+ ×diary + ×music + ×discover + ×audio + ×as3 + ×development + ×illustration + ×blogAPI + ×windows phone 8 + ×wenku8 + ×logging + ×android + ×faq + ×project + ×bash + ×linux + ×pymo + ×3ds Max + ×drawings + ×python + ×perl + ×ruby + ×analysis + ×gaming + ×fez + ×cryptography + ×php + ×ContextMenu + ×JavaScript + ×HTML + ×c++ + ×modeling + ×node.js + ×mongodb + ×peer to peer + ×content distribution network + ×rho +
+
+ +
+
+ +
+
+
Site Library
+
+
+
+
+ + + Site Library + +
+
+
+
+
+ +
+
Upload Manager
+
+
Upload files: drag files to the browser window. (Folders are not supported.)
+
+
+
+
+
Dummy
+
+
0%
+
+
+
+
+
+
+
+ +
+
+
+ +
+
+
+
+ + + diff --git a/botanjs/service/templates/test/Astro.Blog.Components.Calendar.html b/botanjs/service/templates/test/Astro.Blog.Components.Calendar.html new file mode 100644 index 0000000..42f738b --- /dev/null +++ b/botanjs/service/templates/test/Astro.Blog.Components.Calendar.html @@ -0,0 +1,18 @@ + + +Botan JS - Test + + + + + + + + + + diff --git a/botanjs/service/templates/test/Astro.Blog.Components.Comment.html b/botanjs/service/templates/test/Astro.Blog.Components.Comment.html new file mode 100644 index 0000000..c078b2a --- /dev/null +++ b/botanjs/service/templates/test/Astro.Blog.Components.Comment.html @@ -0,0 +1,101 @@ + + +Botan JS - Test + + + + + + +
+
+ Comments + +
+ + +
+ +
+ +
+
+
Tthuhhuhetuh
+ +
+
lynn
+
3:02 AM 27 Apr, 2014
+
+ + +
Reply
+ + + +
+
+ +
+ +
+
iiueauhhuhh
+ +
+
+
+ +
3:02 AM 27 Apr, 2014
+
+
avatar
+
+
+ +
+
+ +
+ +
+ + +
+
+
+ +
Do you even comment?
+ +
+
+ website:  + +
+
Not a valid website
+
+ Email(won't be disclosed):  + +
+
Invalid email format
+
*Name: 
+
Please enter a name
+
+ +
+ +
+
+
Submit
+
+
We could be immortals
+
+ + +
+ +
+ + + diff --git a/botanjs/service/templates/test/Astro.Blog.Components.Comment2.html b/botanjs/service/templates/test/Astro.Blog.Components.Comment2.html new file mode 100644 index 0000000..a10f006 --- /dev/null +++ b/botanjs/service/templates/test/Astro.Blog.Components.Comment2.html @@ -0,0 +1,150 @@ + + +Botan JS - Test + + + + + + +
+
+ Comments + + + + + .. + + +
+ + +
+ +
+ +
+
+
iiii
+ +
+
inori
+
9:48 AM 24 Apr, 2014
+
+ + +
Reply
+ + + + + +
+
+ +
+ +
+
TestComment
+ +
+
inori
+
9:48 AM 24 Apr, 2014
+
+ +
+
+ +
+
Commenttttttt
+ +
+
+
+ +
9:48 AM 24 Apr, 2014
+
+
avatar
+
+
+ +
+
+ +
+ +
+ +
+ +
+
+
iegggeg
+ +
+
losisli
+
11:38 AM 23 Jul, 2014
+
+ + +
Reply
+ + + + + +
+
+ +
+ +
+
iiiii
+ +
+
+
+ +
11:38 AM 23 Jul, 2014
+
+
avatar
+
+
+ +
+
+ +
+ +
+ + +
+
+
+ +
Do you even comment?
+ +
+ +
+
+
Submit
+
+
no
+
+
+
+ + + diff --git a/botanjs/service/templates/test/Astro.Blog.Components.Notification.html b/botanjs/service/templates/test/Astro.Blog.Components.Notification.html new file mode 100644 index 0000000..5404324 --- /dev/null +++ b/botanjs/service/templates/test/Astro.Blog.Components.Notification.html @@ -0,0 +1,38 @@ + + +Botan JS - Test + + + + + + + + + +
+
+
+ Notifications +
+
+
+
+ +
+
+ + + diff --git a/botanjs/service/templates/test/Astro.Blog.Components.SiteFile.html b/botanjs/service/templates/test/Astro.Blog.Components.SiteFile.html new file mode 100644 index 0000000..1209709 --- /dev/null +++ b/botanjs/service/templates/test/Astro.Blog.Components.SiteFile.html @@ -0,0 +1,49 @@ + + +Botan JS - Test + + + + + +
+ + + + + + + Getting information ... +
+
+ + + + + + + Getting information ... +
+ + + diff --git a/botanjs/service/templates/test/Astro.Blog.Components.Spoiler.html b/botanjs/service/templates/test/Astro.Blog.Components.Spoiler.html new file mode 100644 index 0000000..fb19dc5 --- /dev/null +++ b/botanjs/service/templates/test/Astro.Blog.Components.Spoiler.html @@ -0,0 +1,24 @@ + + +Botan JS - Test + + + + + +
+
Test title
+ +
+
+
Test title 2
+ +
+ + + diff --git a/botanjs/service/templates/test/Astro.Blog.Components.Video.html b/botanjs/service/templates/test/Astro.Blog.Components.Video.html new file mode 100644 index 0000000..e415196 --- /dev/null +++ b/botanjs/service/templates/test/Astro.Blog.Components.Video.html @@ -0,0 +1,19 @@ + + +Botan JS - Test + + + + + + +
+
+ + + diff --git a/botanjs/service/templates/test/Astro.Blog.Layout.Article.Control.html b/botanjs/service/templates/test/Astro.Blog.Layout.Article.Control.html new file mode 100644 index 0000000..c540cc0 --- /dev/null +++ b/botanjs/service/templates/test/Astro.Blog.Layout.Article.Control.html @@ -0,0 +1,28 @@ + + + + blog - astropenguin + + + + + + + + + + + + + + diff --git a/botanjs/service/templates/test/Astro.Blog.Layout.Article.Latest.html b/botanjs/service/templates/test/Astro.Blog.Layout.Article.Latest.html new file mode 100644 index 0000000..470db35 --- /dev/null +++ b/botanjs/service/templates/test/Astro.Blog.Layout.Article.Latest.html @@ -0,0 +1,482 @@ + + + + blog - astropenguin + + + + + + + + + + + + + + + + + + +
+ +
+ + +
+ + +
+
Pending Illustrations here.
+
+
+ +
+
+
+
+ + +
+ + +
+ + +
+ +
+ + + + + + + + +
Latest
+
+ +
+ +
+ +
+
+ +
斟酌 鵬兄
+
16th June 2014
+
+
+ +
+
+
什麼都要錢啊
+
+
最近在架設,途中於到太多阻礙了。
+事情是這樣的:
+在我發現ISP擋掉了我的smtp之後,醒起以前Google 好像會提供免費個人域名的電郵服務,於是便投靠Google。
+ + + +
+
+
+ +
+
+ +
+ +
+ +
+
+ +
斟酌 鵬兄
+
12th May 2014
+
+
+ +
+
+
codename "rho"—實作p2p
+
+
終於查出來了,這是由於文庫架設的CDN再及防火牆問題。
+下圖表示當前(青藍)文庫的網絡架構:
+很可惜基於現時的協定(洋紅),我沒辦法想出有效的補救方案。這次的項目規模比較大,沒辦法就這麼「做」出來。
+ + + +
+
+
+ +
+
+ +
+ +
+ +
+
+ +
斟酌 鵬兄
+
27th April 2014
+
+
+ +
+
+
node.js
+
+
最近收到好多來信說文庫app連不上啊,於是我想是不是要替文庫做分流好呢?
+最近工作來來去去都是php + codeigniter,快要悶死了。記得當初是想做設計的,結果找的工作卻是跟前端開發相關。
+ + + +
+
+
+ +
+
+ +
+ +
+ +
+
+ +
斟酌 鵬兄
+
Comment(s) +2
+
7th February 2014
+
+
+ +
+
+
重新開始維護wenku8
+
+
之前因為工作上沒空考慮其他事,可是近來工作實在太清閒了。所以我想重新把持起維護的工作來,加上近來發現Win7的電腦其實也可以使用VS2012。於是我花了點時間架好工作台起來。
+ + + +
+
+
+ +
+
+ +
+ +
+ +
+
+ +
斟酌 鵬兄
+
7th February 2014
+
+
+ +
+
+
讓程序自動編寫程序
+
+
最近利用gcin的倉頡對照表寫了一個小程序。(簡單來說就是一個CLI的倉頡轉換器)
+為什麼要做這個東西呢?當然這是為了可以在公司寫blog而不被人發現啊!
+ + + +
+
+
+ +
+
+ +
+ +
+ +
+
+ +
Aaron
+
Comment(s) +1
+
22nd January 2014
+
+
+ +
+
+
呀! 甚麼都寫不出來!
+
+
最近消化幾套動漫, 進擊的巨人, Steins; Gate 是比較有印象
+巨人不錯, 不過還是不喜歡一堆手手腳腳在畫面上
+S; G 便和前作 Chaos; Head 差不多, 還好這次我沒有一頭霧水了...
+ + + +
+
+
+ +
+
+ +
+ +
+ +
+
+ +
斟酌 鵬兄
+
18th January 2014
+
+
+ +
+
+
給力的右鍵選單
+
+
好吧,雖然這個blog還沒做好。但製作途中還是有很多技術可以拿出來討論的。
+其中有幾點是我這近半年才發現的。
+Scope就是一般編程都必讀的一環,亦是經常讓人頭痛的東西。
+ + + +
+
+
+ +
+
+ +
+ +
+ +
+
+ +
斟酌 鵬兄
+
16th January 2014
+
+
+ +
+
+
動態組裝JS組態
+
+
有夠繞舌的,今天的主題就是動能地將不同的JS合併成一個檔案,以增加頁面載入速度及減低對伺服器的請求數。
+ + + +
+
+
+ +
+
+ + +
+ + + + + +
+ + + + +
+ + + + + + + + +
+
+ + +
+
+ +
+ +
+ + + + + + diff --git a/botanjs/service/templates/test/Astro.Blog.Layout.ErrorPages.html b/botanjs/service/templates/test/Astro.Blog.Layout.ErrorPages.html new file mode 100644 index 0000000..a031860 --- /dev/null +++ b/botanjs/service/templates/test/Astro.Blog.Layout.ErrorPages.html @@ -0,0 +1,28 @@ + + + +404 Page not found + + + + + + + + +
+
+
+
+
+
+
+
+
+ + diff --git a/botanjs/service/templates/test/Astro.Blog.Layout.Login.html b/botanjs/service/templates/test/Astro.Blog.Layout.Login.html new file mode 100644 index 0000000..29392ba --- /dev/null +++ b/botanjs/service/templates/test/Astro.Blog.Layout.Login.html @@ -0,0 +1,18 @@ + + +Botan JS - Test + + + + + + + diff --git a/botanjs/src/Astro/Blog/AstroEdit/Article.js b/botanjs/src/Astro/Blog/AstroEdit/Article.js new file mode 100644 index 0000000..2af3458 --- /dev/null +++ b/botanjs/src/Astro/Blog/AstroEdit/Article.js @@ -0,0 +1,453 @@ +(function(){ + var ns = __namespace( "Astro.Blog.AstroEdit" ); + + /** @type {System.Cycle} */ + var Cycle = __import( "System.Cycle" ); + /** @type {System.utils.EventKey} */ + var EventKey = __import( "System.utils.EventKey" ); + /** @type {System.Debug} */ + var debug = __import( "System.Debug" ); + /** @type {Components.MessageBox} */ + var MessageBox = __import( "Components.MessageBox" ); + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + /** @type {Dandelion.IDOMObject} */ + var IDOMObject = __import( "Dandelion.IDOMObject" ); + /** @type {Dandelion.IDOMElement} */ + var IDOMElement = __import( "Dandelion.IDOMElement" ); + /** @type {Astro.Blog.Config} */ + var Config = __import( "Astro.Blog.Config" ); + /** @type {Astro.Blog.Components.Bubble} */ + var Bubble = __import( "Astro.Blog.Components.Bubble" ); + + var postData = __import( "System.Net.postData" ); + var prettyDate = __import( "Astro.utils.Date.pretty" ); + + var Visualizer = ns[ NS_INVOKE ]( "Visualizer" ); + var Tag = ns[ NS_INVOKE ]( "Tag" ); + + var Article = function( processorSet ) + { + var pBubble = new Bubble(); + + var Draft = ns[ NS_INVOKE ]( "Draft" ); + + var _title = ""; + var _content = ""; + + //// Classes & obj + var _ae_tag = null; + var _visualizer = null; + var timestamp = new Date(); + + /** @type {_AstJson_.AJaxGetArticle.entry} */ + var ArticleModel = { + title: "" + , slug: "" + , content: "" + , date_modified: timestamp + , date_published: timestamp + , date_created: timestamp + , archived: false + , tags: null + , draft: true + , article_id: false + }; + + var ae_content = Dand.id( "ae_content" ); + var ae_title = Dand.id( "ae_title" ); + + // Article info + var ae_cdate = Dand.id( "ae_cdate" ); + var ae_mdate = Dand.id( "ae_mdate" ); + var ae_pdate = Dand.id( "ae_pdate" ); + var ae_status = Dand.id( "ae_status" ); + var ae_backup = Dand.id( "ae_backup_btn" ); + var ae_publish = Dand.id( "ae_publish_btn" ); + var ae_preview = Dand.id( "ae_preview" ); + + /** @type {_AstConf_.AstroEdit} */ + var a_conf = Config.get( "AstroEdit" ); + var base_path = Config.get( "BasePath" ); + + ///// preview fields + var ae_p_fields = { + mtime: set_field_name( Dand.wrap( "input" ), "date_modified" ) + , ptime: set_field_name( Dand.wrap( "input" ), "date_published" ) + , title: set_field_name( Dand.wrap( "input" ), "title" ) + , content: set_field_name( Dand.wrap( "input" ), "content" ) + , tags: set_field_name( Dand.wrap( "input" ), "tags" ) + }; + + // Initialize id + var __article_id = false; + var canSave = false; + + var temp; + + for ( var i in ae_p_fields ) ae_preview.appendChild( ae_p_fields[i] ); + //// End preview fields + + + var enableSaveFunction = function () + { + ae_backup.className = "ae_iValue ae_dodgerblue flsf"; + canSave = true; + } + + , disableSaveFunction = function () + { + ae_backup.className = "ae_iValue ae_disabled flsf"; + canSave = false; + } + + , contentUpdate = function () + { + if( !canSave ) enableSaveFunction(); + // (_visualizer.saveRaw() != _content) ? enableSaveFunction() : disableSaveFunction(); + } + + //// private methods + ////// Handlers /////// + + , saveSuccess = function (obj) + { + disableSaveFunction(); + ae_mdate.innerHTML = prettyDate( new Date( obj.date_modified ) ); + + // Replace state of the content and title + ArticleModel.title = _title; + ArticleModel.content = _content; + ArticleModel.date_modified = obj.date_modified; + + // Set article id if this is a new document + if ( obj.article_id ) + ArticleModel.article_id = __article_id = obj.article_id; + + window.history.replaceState( ArticleModel, "", base_path + "astroedit/" + __article_id + "/" ); + } + + , publishSuccess = function (obj) + { + ae_publish.innerHTML = "Done edit"; + ae_backup.innerHTML = "Backup(Ctrl + s)"; + + ArticleModel.date_published = obj.date_published; + ae_pdate.innerHTML = prettyDate( new Date( obj.date_published ) ); + + this.contentUpdate && saveSuccess(obj); + + new MessageBox("AstroEdit", "You have successfully published your article!", "Stay here", "Exit and goto article", publishAction).show(); + } + + , publishAction = function (stay) + { + if (!stay) + { + window.open( base_path + "article/view/" + ArticleModel.slug + "/") && window.close(); + } + } + + , restoreArticle = function(obj) + { + debug.Info("[Document] Looking for stored data"); + if (obj) + { + debug.Info("[Document] .. data found"); + // Set stored article id + __article_id = obj.article_id; + setArticle( obj ); + } + else + { + if (!( ArticleModel && 0 < ArticleModel.article_id )) + { + debug.Info("[Document] .. data not found"); + // This is a state of new article + var d = Math.floor(new Date().getTime()/1000); + __article_id = false; + setArticle({ + title:"" + , content:"" + , date_modified: d + , date_published: 0 + , date_created: d + , archived: false + , tags: null + , draft: true + , article_id: false + }); + window.history.replaceState( ArticleModel, "", base_path + "astroedit/new/" ); + } + } + } + /** @param {_AstJson_.AJaxGetArticle} */ + , showArticle = function( obj ) + { + if ( obj && obj.entry ) + { + debug.Info( "[Document] Article Loaded" ); + if ( obj.backup ) + { + pBubble.setColor( "royalblue" ); + pBubble.pop( "Using backup entry" ); + Cycle.delay( function () { pBubble.blurp() }, 3000 ); + } + setArticle( obj.entry ); + if ( !obj.entry.article_id ) + { + // sever will not return article_id + // since it is an UPDATE + // Store the article_id manually + obj.entry.article_id = __article_id; + } + __statePusher( obj.entry, __article_id ); + } + else + { + debug.Info( "[Document] Article: " + String( __article_id ) + " not found on server." ); + __article_id = false; + } + } + + , setArticle = function ( entry ) + { + ArticleModel = entry; + ae_title.value = _title = ArticleModel.title; + + _visualizer.visualizeData( _content = ArticleModel.content ); + + ae_mdate.innerHTML = prettyDate( new Date( ArticleModel.date_modified ) ); + ae_cdate.innerHTML = prettyDate( new Date( ArticleModel.date_created ) ); + + ae_pdate.innerHTML = ArticleModel.date_published + ? prettyDate( new Date( ArticleModel.date_published ) ) + : "Not published." + ; + + ae_status.innerHTML = + ( ArticleModel.archived ? "Archived. " : "" ) + + ( ArticleModel.draft ? "In draft" : "Published" ) + ; + + ae_publish.innerHTML = ArticleModel.draft ? "Publish" : "Done edit"; + ae_backup.innerHTML = ( ArticleModel.draft ? "Save" : "Backup" ) + "(Ctrl + s)"; + + + _ae_tag && _ae_tag.setTags( ArticleModel.tags ); + } + + , deleteDraft = function (confirmed) + { + if (confirmed) + { + var _data = { + "draft": ArticleModel.draft ? 1 : 0 + , "article_id": __article_id + , "del": 1 + }; + + postData( processorSet, _data, deleteSuccess, serverFailed ); + } + } + + , deleteSuccess = function () + { + location.reload(true); + } + + , serverFailed = function ( obj ) + { + pBubble.setColor( "red" ); + pBubble.pop( obj["mesg"] ); + Cycle.delay( function () { pBubble.blurp() }, 3000 ); + } + + , contentEmpty = function () + { + return !Boolean( ae_content.hasChildNodes() ); + } + ; + + // Bind properties + + this.saveOrBackup = function () + { + if (canSave) + { + // Store current content and title + _title = ae_title.value.trim(); + _content = _visualizer.saveRaw(); + + /** @type {_AstJson_.AJaxGetArticle.entry} */ + var _data = + { + article_id: __article_id ? __article_id : "" + , title: _title + , content: _content + , tags: _ae_tag.getTags() + , draft: ArticleModel.draft ? 1 : 0 + }; + + if (ArticleModel.draft == 0) + { + // This a published article + // action is Backup + _data.backup = 1; + } + + postData( processorSet, _data, saveSuccess, serverFailed); + } + }; + + this.load = function ( aid, statePusher ) + { + if( aid && __article_id != aid ) + { + debug.Info( "[Document] Loading article: " + aid ); + __statePusher = statePusher; + postData( + a_conf.paths.get_article + , { article_id: __article_id = aid } + , showArticle + , serverFailed + ); + } + }; + + this.getArticleId = function () { return __article_id; } + + this.preview = function () + { + ae_p_fields.title.value = ae_title.value; + ae_p_fields.content.value = _visualizer.saveRaw(); + ae_p_fields.mtime.value = ArticleModel.date_modified; + ae_p_fields.ptime.value = Number( ArticleModel.date_published ) + ? ArticleModel.date_published + : Math.floor( 0.001*( new Date().getTime() ) ) + ; + ae_p_fields.tags.value = _ae_tag.getTags(); + + ae_preview.submit(); + }; + + this.invoke = function (_class) + { + if ( _class instanceof Draft ) _ae_draft = _class; + if ( _class instanceof Visualizer ) + { + _visualizer = _class; + _visualizer.setContentDiv( ae_content ); + } + if ( _class instanceof Tag ) + { + _ae_tag = _class; + ArticleModel && ArticleModel.tags && ( _ae_tag ).setTags( ArticleModel.tags ); + } + }; + + this.saveAndPublish = function () + { + if ( contentEmpty() ) return; + + /** @type {_AstJson_.AJaxGetArticle.entry} */ + var _data = { + article_id: __article_id ? __article_id : "" + , draft: 0 + }; + + if ( !ArticleModel.draft ) + { + // This is a published article + // Do not backup + _data.backup = 0; + canSave = true; + } + + if ( canSave ) + { + // Store current content and title + _title = ae_title.value.trim(); + _content = _visualizer.saveRaw(); + + _data.title = _title; + _data.content = _content; + _data.tags = _ae_tag.getTags(); + + postData( processorSet, _data, publishSuccess.bind({ contentUpdate: true }), serverFailed ); + } + else + { + // Do not submit uneccessary data! + postData( processorSet, _data, publishSuccess, serverFailed ); + } + }; + + this.drop = function () + { + new MessageBox( + "Delete draft" + , "Are you sure you want to delete this draft? (Published article will only remove backup draft.)" + , "Delete", "No" + , deleteDraft + ).show(); + }; + + this.updateContent = contentUpdate; + + // Setting Ctrl+s functions + new IDOMObject(document).addEventListener( + new EventKey("KeyDown", function(e) + { + // key Ctrl(17) + if(e.ctrlKey == true && e.which == 83) + { + // key s (83) + this.saveOrBackup(); + e.preventDefault(); + } + /* + else if(e.which == 66) + { + // key b(66) + this.backup.bind(this)(); + return false; + } + */ + }.bind(this)) + ); + + IDOMElement( ae_backup ).addEventListener( "Click", this.saveOrBackup ); + + window.addEventListener( + "popstate" + , function( event ) + { + debug.Info( "[Document] Pop State fired" ); + restoreArticle( event.state ); + } + ); + + ae_title.oninput = function () + { + ( ae_title.value != _title ) ? enableSaveFunction() : disableSaveFunction(); + } + + temp = IDOMElement(ae_content); + + temp.addEventListener( "Input", function() { enableSaveFunction(); } ); + + document.body.appendChild( pBubble.init() ); + + return this; + }; + + var set_field_name = function ( elem, value ) + { + elem.name = value; + elem.type = "hidden"; + return elem; + }; + + ns[ NS_EXPORT ]( EX_CLASS, "Article", Article ); +})(); diff --git a/botanjs/src/Astro/Blog/AstroEdit/Draft.js b/botanjs/src/Astro/Blog/AstroEdit/Draft.js new file mode 100644 index 0000000..695d0aa --- /dev/null +++ b/botanjs/src/Astro/Blog/AstroEdit/Draft.js @@ -0,0 +1,158 @@ +(function(){ + var ns = __namespace( "Astro.Blog.AstroEdit" ); + + /** @type {System.Cycle} */ + var Cycle = __import( "System.Cycle" ); + /** @type {System.utils.IKey} */ + var IKey = __import( "System.utils.IKey" ); + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + + var postData = __import( "System.Net.postData" ); + + /** @param {Astro.Blog.AstroEdit.Article} article */ + var Draft = function ( article, draftsUri ) + { + /** @type {Astro.Blog.AstroEdit.Article} */ + var Article = ns[ NS_INVOKE ]( "Article" ); + + if ( !( article instanceof Article ) ) return; + + // Drafts Container + var ae_expand = Dand.id("ae_expand") + , ae_drafts = Dand.id("ae_user_drafts") + , ae_drafts_h = null + + ////// Draft Section + , showDrafts = function () + { + showDrafts = function() { }; + // One-time trigger only. + getDraftList({offset: 0}); + } + + , getDraftList = function ( p ) + { + postData( draftsUri, p, listDraft.bind(p), draftFailed ); + } + + /** @param {_AstJson_.AJaxGetDrafts} obj */ + , listDraft = function ( obj ) + { + var entries = obj.entries, entry; + + for ( var i in entries ) + { + /** @param {_AstJson_.AJaxGetDrafts.entry} */ + entry = entries[i]; + // Insert entries + ae_drafts.appendChild( + entry = Dand.wrapc( + "ae_dEntry" + , [ + Dand.wrapc( + "ae_dEntry_title fls" + , entry.active + ? + [ + Dand.textNode( entry.title ) + , Dand.wrap( "span", null, "ae_dActive_bubble", "\u25CF" ) + ] + : entry.title + ) + , Dand.wrapc( "ae_dEntry_content flsf", entry.content ) + , Dand.wrapc( "ae_dEntry_date fsf", entry.date ) + ] + , entry.active + ? [ new IKey ( "value", entry._id ), new IKey( "active" ) ] + : new IKey( "value", entry._id ) ) + ); + + // Register on click function + entry.addEventListener( "click", function() { + article.load( entry.getAttribute( "value" ), __pushState ); + } ); + } + + ae_drafts_h = ae_drafts.clientHeight; + ae_drafts.style.height = 0; + + Cycle.next(function(){ + // This doesn't make sense + // but we need to actually access the clientHeight + // to get the height animation working + ae_drafts.clientHeight; + ae_drafts.style.height = String( ae_drafts_h ) + "px"; + }); + } + + , draftFailed = function (obj) + { + + } + + + // Handlers + , setupExpand = function () + { + ae_expand.className = "ae_expand_btn"; + var panel = Dand.id("ae_minor_panel"); + panel.onmouseover = function() + { + ae_expand.style.height = "20px"; + } + panel.onmouseout = function() + { + ae_expand.style.height = ""; + } + panel.onclick = function() + { + ae_expand.style.height = ""; + ae_drafts.style.height = String(ae_drafts_h) + "px"; + Cycle.delay(setupCollapse , 250); + + // Disable mouse events + panel.onmouseover = panel.onmouseout = panel.onclick = null; + + showDrafts(); + } + } + + , setupCollapse = function () + { + ae_expand.className = "ae_callapse_btn"; + Cycle.delay(function() + { + ae_expand.onclick = function() + { + ae_expand.style.backgroundColor = ""; + ae_drafts.style.height = "0"; + Cycle.delay(setupExpand, 250); + + // Disable mouse events + ae_expand.onmouseover = ae_expand.onmouseout = ae_expand.onclick = null; + } + ae_expand.onmouseover = function() + { + ae_expand.style.backgroundColor = "rgba(255, 255, 255, 0.2)"; + } + ae_expand.onmouseout = function() + { + ae_expand.style.backgroundColor = ""; + } + }, 250); + } + // End Handlers + + + , __pushState = function ( obj, article_id ) + { + window.history.pushState( obj, "", "../" + article_id + "/" ); + } + + setupExpand(); + article.invoke( this ); + }; + + ns[ NS_EXPORT ]( EX_CLASS, "Draft", Draft ); +})(); diff --git a/botanjs/src/Astro/Blog/AstroEdit/SiteLibrary.css b/botanjs/src/Astro/Blog/AstroEdit/SiteLibrary.css new file mode 100644 index 0000000..e5ac4f8 --- /dev/null +++ b/botanjs/src/Astro/Blog/AstroEdit/SiteLibrary.css @@ -0,0 +1,367 @@ +#siteLibrary { + position: fixed; + width: 100%; + height: 100%; + + top: calc(-100% - 5px); +} + +#siteLibrary:hover { + top: calc(-100% + 1.5em); +} + +#asl_viewer { + width: calc(100% - 300px); + height: 100%; + + overflow-x: hidden; + overflow-y: scroll; + + float: left; + + position: relative; +} + +.asl_header { + width: 100%; + height: 20px; + + top: 100%; + margin-top: -20px; + + position: absolute; + z-index: 1; +} + +#asl_viewer > #canvasView { + position: absolute; + min-height: 100%; + width: 100%; +} + +.asl_viewer { + width: 100%; + height: 100%; + + background: #EEE; + + -moz-box-shadow: 0 7px 5px black; + -webkit-box-shadow: 0 7px 5px black; + box-shadow: 0 7px 5px black; +} + +.asl_contentMenu { + bottom: 0; + position: absolute; + padding: 1em; +} + +.asl_contentMenu > span { + margin: 0 0.2em; + padding: 0.5em 0.5em; + + cursor: default; + + color: white; + background-color: rgba(0, 0, 0, 0.6); + font-family: custom-serif; +} + +.asl_contentMenu > span:hover { + background-color: rgba(0, 0, 0, 0.8); +} + +.asl_contentMenu > span[current] { + background-color: rgba(0, 0, 0, 0.8); +} + +.asl_smask { + height: 10px; + background-color: royalblue; + + position: absolute; + bottom: -5px; + width: 100%; +} + +.asl_smask:before {content: ''; + width: 100%; + height: 20px; + + top: -10px; + position: absolute; + + z-index: -1; + background-color: transparent; +} + +.asl_smask[expand] { + background-image: url(http://file.astropenguin.net/blog/layout-images/collapse.png); + background-position: center 2.5px; + background-repeat: no-repeat; +} + +.asl_smask[expand]:hover { + height: 20px; +} + +#siteLibrary .asl_title, .asl_intitle { + font-size: 1.5em; + + font-family: custom-sans; + + overflow: hidden; + + background-color: royalblue; + color: white; +} + +#siteLibrary .asl_title { + padding: 0.3em 0.5em; +} + +.asl_contentPanel { + overflow: hidden; + position: absolute; + + height: calc(100% - 2.5em); + width: 100%; +} + +#siteLibrary .asl_title { + cursor: default; + + display: inline-block; + position: absolute;; + + right: 350px; + bottom: -1.7em; + + -moz-box-shadow: 2px 2px 5px black; + -webkit-box-shadow: 2px 2px 5px black; + box-shadow: 2px 2px 5px black; +} + +/*** ASL Canvases ***/ +.canvasImage > span { + width: 100px; + height: 100px; + float: left; + margin: 0.2em; + + background-repeat: no-repeat; + background-position: center; + + border: 1px solid transparent; + +} + +.canvasImage > span[selected] { + background-color: lightblue; + border-color: royalblue; +} + +.canvasImage > span > span { + width: 100%; + height: 100%; + display: block; +} + +.canvasImage > span > span:hover { + background-color: rgba(0, 0, 0, 0.2) !important; + border-color: #444 !important; +} + +.ci_album { + -moz-box-shadow: 2px 3px 0 0 black; + -webkit-box-shadow: 2px 3px 0 0 black; + box-shadow: 2px 3px 0 0 #666; + border: 1px solid #666 !important; +} + + +.canvasGeneral { + padding: 0.2em; + cursor: default; + + color: #444; +} + +.canvasGeneral > div { + padding: 0.2em; +} + +.canvasGeneral > div:hover { + background-color: rgba(0, 0 ,0, 0.2); +} + +.canvasGeneral > div > span { + display: inline-block; + + width: 30%; + padding: 0.2em 0; + + overflow: hidden; + text-overflow: ellipsis; +} + +.canvasGeneral > div > span:last-child { + width: 10%; +} + +.canvasGeneral > div[selected] { + background-color: orangered; + color: white; +} + +/*** End ASL Canvases ***/ + +/*** Uploader ***/ +#asl_uploader { + width: 300px; + height: 100%; + + float: right; + + font-family: custom-sans; +} + +#asl_u_head { + position: absolute; + background: #EEE; + z-index: 1; +} + +.upldr_title { + font-size: 1.5em; +} + +.asl_fwrapper { + overflow-y: scroll; + + position: absolute; + top: 0; + + width: 100%; + height: 100%; + + /* + -moz-box-shadow: inset 0 0 20px black; + -webkit-box-shadow: inset 0 0 20px black; + box-shadow: inset 0 0 20px black; + */ +} + +.asl_fileList { + font-family: sans-serif; + color: #444;; + + cursor: default; +} + +.asl_fileList > div { + /* 0.5em for fwrapper padding */ + margin-right: 50%; + padding: 0.5em; + overflow: hidden; + text-overflow: ellipsis; +} + +.asl_uItem:hover { + background-color: rgba(0, 0, 0, 0.2); +} + +.asl_uItemStat { + padding: 0 0.5em 0 0; + color: orange; +} + +.asl_split { + position: relative; + height: 80px; + overflow: hidden; +} + +.asl_split > div { + height: 100%; + padding: 0.5em; + + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.asl_left { + float: left; + width: 135px; +} + +.asl_right { + float: right; + width: calc(100% - 135px); +} + +.asl_fileName { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.asl_preview { + padding: 0.2em; + background-color: white; + height: 100%; +} + +/* Progress indicator */ +.asl_progress { + padding: 0.5em 0; +} + +.asl_ptext { + font-size: 0.8em; +} + +.asl_pbar { + background-color: white; + position: relative; + height: 1em; + margin-top: 0.2em; +} + +.asl_pbar_fill { + background: greenyellow; + position: absolute; + width: 0%; + height: 100%; +} + +.asl_go_up { + width: 0; + height: 0; + + border-top: 0 solid transparent; + border-bottom: 0.5em solid transparent; + border-left: 0.5em solid #FFF; + + position: absolute; + + left: 0; +} + +.asl_btn { + padding: 0.3em; + text-align: center; + cursor: default; +} + +.asl_btn:hover { + background-color: rgba( 0, 0, 0, 0.2); +} + +.asl_instruction { + width: 100%; + height: 100%; + + font-size: 0.8em; +} diff --git a/botanjs/src/Astro/Blog/AstroEdit/SiteLibrary.js b/botanjs/src/Astro/Blog/AstroEdit/SiteLibrary.js new file mode 100644 index 0000000..22db0f3 --- /dev/null +++ b/botanjs/src/Astro/Blog/AstroEdit/SiteLibrary.js @@ -0,0 +1,745 @@ +(function(){ + var ns = __namespace( "Astro.Blog.AstroEdit" ); + + /** @type {System.Cycle} */ + var Cycle = __import( "System.Cycle" ); + /** @type {System.Debug} */ + var debug = __import( "System.Debug" ); + /** @type {System.utils.Perf} */ + var Perf = __import( "System.utils.Perf" ); + /** @type {System.utils.IKey} */ + var IKey = __import( "System.utils.IKey" ); + /** @type {System.utils.DataKey} */ + var DataKey = __import( "System.utils.DataKey" ); + /** @type {System.utils.EventKey} */ + var EventKey = __import( "System.utils.EventKey" ); + /** @type {Components.MessageBox} */ + var MessageBox = __import( "Components.MessageBox" ); + /** @type {Components.Mouse.ContextMenu} */ + var ContextMenu = __import( "Components.Mouse.ContextMenu" ); + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + /** @type {Dandelion.IDOMObject} */ + var IDOMObject = __import( "Dandelion.IDOMObject" ); + /** @type {Dandelion.IDOMElement} */ + var IDOMElement = __import( "Dandelion.IDOMElement" ); + + var postData = __import( "System.Net.postData" ); + var prettyDate = __import( "Astro.utils.Date.pretty" ); + + var SiteLibrary = function ( basePath, processorGet, processorSet ) { + var + + view_index = [] + , currentView + , inCollection = 0 + , indexingItem + , itemSelected = false + , holdingCtrl = false + , holdingShift = false + + , contentPanel = Dand.id("asl_viewer") + , canvasView + , contextMenu + , stage = Dand.id( "siteLibrary", true ) + , asl_smask = Dand.id( "asl_smask", true ) + + + , getItemKeys = function (data) + { + return [ + new DataKey("id", data.id) + , new DataKey("title", data.name) + , new DataKey("author", data.author) + , new DataKey("hash", data.hash) + ]; + } + + , bindData = function(target, source, data) + { + IDOMElement(source).addEventListener(new EventKey("MouseDown", function (e) + { + // pass neccessary informations for contextMenu to read + target.idata = this; + + if(e.which == 1 || (e.which == 3 && !this.stage.hasAttribute("selected"))) + { + // Mousedown event will bubble up to parent node, set itemselected to true + itemSelected = true; + + if( !holdingCtrl ) deselectAllItem.bind( target )(); + + if(holdingShift) rangedSelect(); + else indexingItem = this.stage; + + + selectItem.bind(target)(); + } + }.bind( + { + stage: source + , href: data.src_location + , hash: data.hash + , author: data.author + , name: data.name + , date: data.date_created + , isCollection: 0 < data.cCount + } + ))); + } + + + ////// Canvas builders + , resetCanvas = function (name) + { + if(canvasView) + { + contentPanel.removeChild(canvasView); + contentPanel.appendChild(canvasView = Dand.wrap(null, "canvasView", name || canvasView.getAttribute("class"), null, new DataKey("name", currentView))); + } + else + { + contentPanel.appendChild(canvasView = Dand.wrap(null, "canvasView", name, null, new DataKey("name", currentView))); + } + + IDOMElement(canvasView).addEventListener( + new EventKey("Click", function (e) + { + if(e.which == 1) + { + if(!itemSelected) + { + deselectAllItem.bind(canvasView)(); + canvasView.idata = null; + } + itemSelected = false; + } + } + ) + ); + } + + , buildAudioCanvas = function (e) + { + // TODO + resetCanvas("canvasAudio"); + } + + /** @param {_AstJson_.AJaxGetFiles} */ + , buildImageCanvas = function ( e ) + { + var f = e.files; + resetCanvas( "canvasImage" ); + + for( var i in f ) + { + /** @param {_AstJson_.AJaxGetFiles.file} */ + var file = f[i]; + // id: i, name: file.name, hash: file.hash, sorce: file.src_location, date: file.date_created + var img = Number( file.cCount ) + + ////// Album item + ? Dand.wrap( + "span", "img_" + Perf.uuid, "ci_album", Dand.wrap("span") + , [ + new IKey("style", "background-image: url(" + basePath + "image/s100/" + file.hash + ".jpg);" ) + , new IKey("title" + , "Album: " + file.name + + "\n" + file.cCount + " file(s)" + + "\nDate: " + prettyDate( new Date( file.date_created ), true ) + + "\nCreated by: " + file.author + ) + , new IKey("collection", 1) + ].concat( getItemKeys( file ) ) + ) + //////// Normal filele + : Dand.wrap( + "span", "img_" + Perf.uuid, null, Dand.wrap( "span" ) + , [ + new IKey("style", "background-image: url(" + basePath + "image/s100/" + file.hash + ".jpg);" ) + , new IKey("title" + , "File: " + file.name + + "\nDate: " + prettyDate( new Date( file.date_created ), true ) + + "\nCreated by: " + file.author + ) + ].concat( getItemKeys( file ) ) + ); + + canvasView.appendChild( img ); + bindData( canvasView, img, file ); + } + + contextMenu = new ContextMenu(canvasView, [ + new EventKey("Open", openAction) + , { + name: "Copy" + , items: [ + new EventKey("Copy source link", copyItemLink) + , new EventKey("Copy hash", copyHash) + ] + } + , { + name: "Selection" + , items: [ + { + name: "Select" + , items: [ + new EventKey("all", selectAllItem) + , new EventKey("none", deselectAllItem) + , new EventKey("Invert selection", reverseSelection) + ] + } + ,{ + name: "By type" + , items: + [ + new EventKey("Only albums", selectAllCollections) + , new EventKey("Only files", selectAllFiles) + ] + } + ] + } + , { + name: "Action" + , items: [ + new EventKey("Group selected file(s)", setCollection) + , new EventKey("Add file(s) to collection", insertCollection) + // TODO: in-group file action changes + , new EventKey("Move file(s) to collection", function(){}) + , new EventKey("Remove files(s) from collection", excludeCollection) + ] + } + ,new EventKey("Refresh", refreshCanvas) + , new EventKey("Rename", popupRename) + , new EventKey("Delete", confirmDelete) + ], "RMB"); + } + + // General file, list view + /** @param {_AstJson_.AJaxGetFiles} */ + , buildGeneralCanvas = function (e) + { + var f = e.files, dateStamp; + resetCanvas("canvasGeneral"); + + for(var i in f) + { + /** @param {_AstJson_.AJaxGetFiles.file} */ + var file = f[i]; + dateStamp = Dand.wrap( "span" ); + dateStamp.innerHTML = prettyDate( new Date( file.date_created ) ) ; + + var li = Dand.wrap( + null, "g_item" + Perf.uuid, null + , [ + Dand.wrapne( "span", file.name ) + , dateStamp + , Dand.wrapne( "span", file.author ) + ] + , getItemKeys( file ) + ); + + canvasView.appendChild( li ); + bindData( canvasView, li, file ); + + } + + contextMenu = new ContextMenu(canvasView, [ + { + name: "Copy" + , items: [ + new EventKey("Copy source link", copyItemLink) + , new EventKey("Copy hash", copyHash) + ] + } + , new EventKey("Delete file", confirmDelete) + ], "RMB"); + + } + + , selHasCollection = false + + // Return the selected files + , selections = function(return_id) { + var s = []; + selHasCollection = false; + + IDOMElement(canvasView).foreach(1, function(elem) { + // Save the hashes + if(elem.hasAttribute("selected")) + { + s[s.length] = return_id ? IDOMElement(elem).getDAttribute("id") : elem; + if(elem.hasAttribute("collection")) selHasCollection = true; + } + }); + + return s; + } + + /// Menu item handlers + , confirmDelete = function () + { + + new MessageBox("Confirm delete" + , [ + Dand.wrape("Are you sure you want to delete the selected item(s)?") + , Dand.wrape("Warning: This action cannot be undone! Make sure you have de-referenced them from your articles.", new IKey("style", "color: yellow;")) + ] + , "Delete it", "No" + , requestDelete.bind({files: selections()})).show(); + } + + , popupRename = function () + { + var name_field = Dand.wrap("input", null, "v_snippet_input_single", null, new IKey("type", "text")); + new MessageBox("Rename \"" + canvasView.idata.name + "\"", name_field, "OK", "Cancel", requestRename.bind( + { + name: name_field + , stage: canvasView.idata.stage + , isCollection: canvasView.idata.isCollection + } + )).show(); + } + + , copyItemLink = function () { return "http://file.astropenguin.net/blog/site-library/" + canvasView.idata.href; } + , copyHash = function () { return canvasView.idata.hash; } + + , openAction = function () + { + if(canvasView.idata.isCollection) openCollection(IDOMElement(canvasView.idata.stage).getDAttribute("id")); + else window.open("http://file.astropenguin.net/blog/site-library/" + canvasView.idata.href); + } + + //// ContextMenu Handlers: Selections + , selectItem = function() + { + canvasView.idata.stage.hasAttribute("selected") ? canvasView.idata.stage.removeAttribute("selected") : canvasView.idata.stage.setAttribute("selected", 1); + } + + , selectAllItem = function () + { + IDOMElement(canvasView).foreach(1, function(target) + { + target.setAttribute("selected", 1); + }); + } + + , selectAllCollections = function () + { + IDOMElement(canvasView).foreach(1, function(target) + { + target.hasAttribute("collection") ? target.setAttribute("selected", 1) : target.removeAttribute("selected"); + }); + } + + , selectAllFiles = function () + { + IDOMElement(canvasView).foreach(1, function(target) + { + target.hasAttribute("collection") ? target.removeAttribute("selected") : target.setAttribute("selected", 1); + }); + } + + , rangedSelect = function () + { + var items = canvasView.childNodes; + var k = indexingItem; + if(Array.prototype.indexOf.call(items, k) < Array.prototype.indexOf.call(items, canvasView.idata.stage)) + { + while(k != canvasView.idata.stage) + { + k.setAttribute("selected", 1); + k = k.nextSibling; + } + } + else + { + while(k != canvasView.idata.stage) + { + k.setAttribute("selected", 1); + k = k.previousSibling; + } + } + } + + , deselectAllItem = function () + { + IDOMElement(canvasView).foreach(1, function(target) + { + target.removeAttribute("selected"); + }); + } + + , reverseSelection = function () + { + IDOMElement(canvasView).foreach(1, function(target) + { + target.hasAttribute("selected") ? target.removeAttribute("selected") : target.setAttribute("selected", 1); + }); + } + + //// ContextMenu Handlers: Collections + , setCollection = function () + { + var s = selections( true ) + var name_field = Dand.wrap( + "input", null + , "v_snippet_input_single", null + , new IKey( "type", "text" ) + ); + + new MessageBox( + "Collection name" + , name_field + , "OK", "Cancel" + , requestCollection.bind({ name: name_field, files: s.join(",") }) + ).show(); + } + + , openCollection = function ( id ) { + refreshCanvas( id, true ); + } + + , excludeCollection = function() { + + } + + , insertCollection = function() { + var collections = [] + , ul = Dand.wrapc( "canvasGeneral", null, new IKey( "style", "color: #BBB;" ) ) + ; + + // Get current albums to list + IDOMElement(canvasView).foreach(1, function(target) + { + if(target.hasAttribute("collection")) + { + + var t = IDOMElement(target) + // item structure + , li = Dand.wrap( + null, "g_item" + Perf.uuid, null + , [ + Dand.wrapne("span", t.getDAttribute("title"), new IKey("style", "width: 75%;")) + , Dand.wrapne("span", t.getDAttribute("author"), new IKey("style", "width: 25%;")) + ] + , new DataKey("id", t.getDAttribute("id")) + ); + + // Set selection behaviour + IDOMElement(li).addEventListener("Click", function(e) { + IDOMElement(ul).foreach(1, function(elem) { elem.hasAttribute("selected") && elem.removeAttribute("selected"); }); + this.setAttribute("selected", 1); + }.bind(li)); + + ul.appendChild(li); + } + }); + + + + new MessageBox("Select a collection", ul, "OK", "Cancel", requestInsert.bind({ albumList: ul, collection: selections(true) })).show(); + } + + //// ContextMenu Handlers: General actions + , requestRename = function( confirmed ) + { + if( confirmed ) + { + var pData = { + "name": this.name.value + , "id": IDOMElement( this.stage ).getDAttribute( "id" ) + }; + + if(this.isCollection) pData.group = "rename"; + else pData.file = "rename"; + + postData( processorSet, pData, refreshCanvas, loadFailed ); + } + } + + , requestDelete = function (confirmed) + { + if(confirmed || this.reConfirmed) + { + if(this.files.length < 2) + { + var file = this.files[0]; + if(selHasCollection) + { + new MessageBox("Also delete files?" + , "Do you also want to delete the files within the collections?" + , "Delete all files", "Only delete collection" + , delCollection.bind(file)).show(); + } + else + { + postData( + processorSet + , { "file": "remove", "hash": IDOMElement(file).getDAttribute("hash") } + , fileDeleted.bind(file), loadFailed + ); + } + } + else + { + if(!this.reConfirmed && selHasCollection) + { + // Set the reconfirmation attr + this.reConfirmed = true; + + new MessageBox("Also delete files?" + , "You have also selected collection(s), do you want to also delete files inside?" + , "Delete all files", "Only delete collection" + , requestDelete.bind(this)).show(); + return; + } + + var files = this.files; + + for(var i in files) + { + if(files[i].hasAttribute("collection")) + { + // redirect confirmation to delCollection handler + // delete all things when true + delCollection.bind(files[i])(confirmed); + } + else + { + // redirect to self + requestDelete.bind({files: [files[i]]})(true); + } + } + } + } + } + + , requestInsert = function(confirmed) + { + if(confirmed) + { + var selectedAlbum = IDOMElement(IDOMElement(this.albumList).first(1, function(elem) { return elem.hasAttribute("selected"); })).getDAttribute("id"); + postData( + processorSet + , { "group": "insert", "id": selectedAlbum , "files": this.collection.join(",") } + , refreshCanvas, loadFailed + ); + } + } + + , delCollection = function (confirmed) + { + var album_id = IDOMElement(this).getDAttribute("id"); + if(confirmed) + { + postData(processorGet, { group: "get", aid: album_id }, getFilestoDelete.bind(this), loadFailed); + } + else + { + postData(processorSet, { group: "remove", id: album_id }, refreshCanvas, loadFailed); + } + } + + , getFilestoDelete = function (e) + { + var l = Object.keys(e.files).length + , fc = 0 + , _self = this + , echoDeleted = function() + { + debug.Info("[ASL] File deleted: " + this.name); + fc ++; + if(l == fc) delCollection.bind(_self)(false); + } + , deleteFailed = function () + { + debug.Error( new Error( "[ASL] Failed to delete: " + this.name ) ); + fc ++; + if(l == fc) delCollection.bind(_self)(false); + } + ; + + for(var i in e.files) + { + postData( + processorSet + , { "file": "remove", "hash": e.files[i]}, echoDeleted.bind({ "name": i }) + , deleteFailed.bind({ "name": i }) + ); + } + } + + , fileDeleted = function () { this.parentNode.removeChild(this); } + + , requestCollection = function () + { + if(this.name.value) + { + postData( + processorSet + , { "group": "create", "name": this.name.value, "files": this.files } + , refreshCanvas, loadFailed + ); + } + } + ////// End canvas builders + + , refreshCanvas = function ( view, openCollection ) + { + if( typeof view != "string" && !openCollection ) view = null; + + // prepare postData + /** @type {_AstJson_.AJaxGetFiles.Request} */ + var pdata = {}; + + if( openCollection ) + { + // Set and remove to prevent invalid content set to currentView + inCollection = view; + view = false; + } + + currentView = view || ( currentView || "application" ); + + //// postData parameters + // if we are in collection + if( inCollection ) + { + pdata.group = "list"; + pdata.aid = inCollection; + } + // else we are in root + else pdata.listFiles = currentView; + + + switch( currentView ) + { + case "image": + postData( processorGet, pdata, buildImageCanvas, loadFailed ); + break; + case "audio": + postData( processorGet, pdata, buildAudioCanvas, loadFailed ); + break; + default: + postData( processorGet, pdata, buildGeneralCanvas, loadFailed ); + break; + } + } + + /** @param {_AstJson_.AJaxGetFiles} e */ + , panelSwitch = function ( e ) + { + if( view_index.length < 1 ) + { + var menuBar = Dand.id( "asl_contentMenu" ) + , f = e.files, first; + + // button mime/type ( counts ) + for(var i in f) + { + var elem = Dand.wrap("span", null, "asl_menuItem", (i + "(" + f[i] + ")"), new DataKey("name", i)); + + view_index[view_index.length] = [i, elem]; + menuBar.appendChild(elem); + + IDOMElement(elem).addEventListener(new EventKey("Click", switchView.bind(IDOMElement(elem)))); + + if(!first) first = [i, elem]; + } + + // begin load index + refreshCanvas(first[0]); + // Set style + first[1].setAttribute("current", 1); + } + else + { + // Should update the menu buttons + debug.Info( "Should update the menu buttons" ); + } + + } + + , switchView = function () + { + // Do nothing if current + if(this.getDAttribute("name") == currentView) return; + + + for(var i in view_index) + { + if(view_index[i][0] == currentView) + { + view_index[i][1].removeAttribute("current"); + } + } + + // switching view, reset collection + inCollection = 0; + + this.setAttribute("current", 1); + refreshCanvas(this.getDAttribute("name")); + + } + + , showLibrary = new EventKey("Click" + , function () + { + stage.style.top = "0"; + asl_smask.setAttribute( "expand", 1 ); + + // Switch behaviour + stage.removeEventListener( showLibrary ); + + Cycle.delay(function () { + Dand.id( "ae_body" ).style.display = Dand.id( "ae_panel" ).style.display = "none"; + asl_smask.addEventListener( hideLibrary ); + + // load library statistics + loadLibStats( panelSwitch, loadFailed ); + }, 500); + } + ) + + , hideLibrary = new EventKey( + "Click" + , function () + { + stage.style.top = ""; + asl_smask.removeAttribute( "expand" ); + + // Switch behaviour + asl_smask.removeEventListener( hideLibrary ); + + Dand.id("ae_body").style.display = Dand.id( "ae_panel" ).style.display = ""; + + Cycle.delay(function () { + stage.addEventListener( showLibrary ); + }, 500); + } + ) + + , loadFailed = function (e) + { + // TODO: make some notifications here + } + + , loadLibStats = function ( handler, failedHandler ) + { + postData( processorGet, { "countTypes": 1 }, handler, failedHandler ); + } + + , keyHold = function(e) { holdingCtrl = e.ctrlKey; holdingShift = e.shiftKey; } + , dKeyUp = new EventKey( "KeyUp", keyHold ) + , dKeyDown = new EventKey( "KeyDown", keyHold ) + ; + + Dand.id( "asl_homeBtn", true ).addEventListener( "click", function( e ) { refreshCanvas( 0, true ); } ); + Dand.id( "asl_refresh", true ).addEventListener( "click", function( e ) { refreshCanvas( 0 ); } ); + new IDOMObject( document ).addEventListeners([ dKeyUp, dKeyDown ]); + stage.addEventListener(showLibrary); + }; + + ns[ NS_EXPORT ]( EX_CLASS, "SiteLibrary", SiteLibrary ); +})(); diff --git a/botanjs/src/Astro/Blog/AstroEdit/Tag.css b/botanjs/src/Astro/Blog/AstroEdit/Tag.css new file mode 100644 index 0000000..10b6b7b --- /dev/null +++ b/botanjs/src/Astro/Blog/AstroEdit/Tag.css @@ -0,0 +1,27 @@ +.tag_active { + color: white; + opacity: 1 !important; +} + +.ae_tag_delete { + color: white; + padding: 0 0.5em 0 0; +} + +.ae_tag_delete:hover { + color: red; +} + +.ae_tag_add { + color: white; + cursor: default; + font-weight: 200; +} + +.ae_tag_add:hover { + color: dodgerblue; +} + +#ae_tags > span { + float: left; +} diff --git a/botanjs/src/Astro/Blog/AstroEdit/Tag.js b/botanjs/src/Astro/Blog/AstroEdit/Tag.js new file mode 100644 index 0000000..028da5b --- /dev/null +++ b/botanjs/src/Astro/Blog/AstroEdit/Tag.js @@ -0,0 +1,197 @@ +(function(){ + var ns = __namespace( "Astro.Blog.AstroEdit" ); + + /** @type {System.Debug} */ + var debug = __import( "System.Debug" ); + /** @type {Components.MessageBox} */ + var MessageBox = __import( "Components.MessageBox" ); + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + /** @type {Dandelion.IDOMElement} */ + var IDOMElement = __import( "Dandelion.IDOMElement" ); + /** @type {Astro.Blog.Config} */ + var Config = __import( "Astro.Blog.Config" ); + + var postData = __import( "System.Net.postData" ); + + /** @param {Astro.Blog.AstroEdit.Article} */ + var Tag = function ( ae_article, tagCountUri ) + { + var Article = ns[ NS_INVOKE ]( "Article" ); + + if ( !( ae_article instanceof Article ) ) + return false; + + /** @type {_AstConf_.AstroEdit} */ + var a_conf = Config.get( "AstroEdit" ); + + var ae_document = ae_article; + + var ae_addTag = Dand.id( "ae_addTags" ); + var ae_tags = Dand.id( "ae_tags" ); + + // Store tags for future use + var tags = {}; + + ////// Handlers + ae_addTag.onclick = function () + { + + // Input fields + var ae_tagInput; + + // Popup MessageBox + new MessageBox( + "Add new tag(s)" + , Dand.wrape([ + Dand.wrapc( + "v_instruction flsf" + , "Tags are separated by \\n. (existing tags will be ignored.)" + ) + , ae_tagInput = Dand.wrap( "textarea", null, "v_snippet_input" ) + ]) + , "OK", "Cancel" + , parseTags.bind( ae_tagInput ) + ).show(); + }; + + var deleteTag = function (e) + { + var p = { tag: this.nodeValue, stage: this.parentNode }; + postData( tagCountUri, p, confirmDelete.bind( p ), serverFailed ); + e.stopPropagation(); + }; + + var confirmDelete = function (obj) + { + new MessageBox( + "Delete Tag" + , [ + Dand.wrapc("ae_blockswitch", + [ + Dand.textNode( "Are you sure you want to delete " ) + , Dand.wrap( "span", null, "tag_active", Dand.textNode( this.tag ) ) + , Dand.textNode( " ?." ) + ] + ) + , obj.count > 0 + ? Dand.wrape([ + Dand.textNode( "This will affect " ) + , Dand.wrap( + "span", null, "ae_affected_count", Dand.textNode( obj.count ) + ) + , Dand.textNode(" article(s).") + ]) + : null + ] + , "Delete", "No" + , doDelete.bind(this) + ).show(); + }; + + var doDelete = function( confirmed ) + { + if ( confirmed ) + { + postData( + a_conf.paths.set_tag + , { tag: this.tag, del: 1 } + , deleteSuccess.bind( this ) + , serverFailed + ); + } + }; + + var deleteSuccess = function(obj) + { + // Remove element + this.stage.parentNode.removeChild(this.stage); + // Delete reference + delete tags[this.tag]; + }; + + var parseTags = function () + { + // Filter invalid tags + var ntags = this.value.trim().match(/[^\n]+/g), d, e; + for (var i in ntags) + { + if(!tags[(i = ntags[i]).toLowerCase()]) + { + tags[i] = Dand.wrap("span", null, "tag_active", + [d = Dand.wrap("span", null, "ae_tag_delete", "\u00D7"), e = Dand.textNode(i)] + ); + // Seperator + ae_tags.appendChild(Dand.textNode(" ")); + ae_tags.appendChild(tags[i]); + + tags[i].onclick = function() { toggleTag(this) }.bind(tags[i]); + d.onclick = deleteTag.bind(e); + + } + else + { + debug.Info("Tag exist: " + i); + // Hightlight these tags + tags[i.toLowerCase()].className = "tag_active"; + } + } + + }; + + var toggleTag = function (tag) + { + var isEnabled = tag.className == "tag_active" ? true : false; + tag.className = isEnabled ? "ae_disabled" : "tag_active"; + }; + + var serverFailed = function (obj) { }; + + + + var ctag, ae_children = ae_tags.childNodes; + for (var i in ae_children) + { + if((ctag = ae_children[i]).nodeType == 1) + { + tags[ctag.lastChild.nodeValue.toLowerCase()] = ctag; + IDOMElement( ctag ).addEventListener( "Click", function() { toggleTag( this ); }.bind( ctag ) ); + // Bind the last child (x button) to firstChild (textNode: tagname) + IDOMElement( ctag.firstChild ).addEventListener( "Click", deleteTag.bind( ctag.lastChild ) ); + } + } + + this.getTags = function () + { + // Compile tag list + var tlist = []; + + // Return names + for (var i in tags) + { + if(tags[i].className == "tag_active") + tlist[tlist.length] = tags[i].lastChild.nodeValue; + } + + return tlist.join("\n"); + } + + this.setTags = function (tagList) + { + // Disable all tags first + for (var i in tags) tags[i].className = "ae_disabled"; + + // Set tags from tagList + for (i in tagList) + if (tagList[i]) tags[tagList[i].toLowerCase()].className = "tag_active"; + } + + ae_document.invoke(this); + } + + Tag.prototype.getTags = function () { }; + Tag.prototype.setTags = function (tagList) { }; + + ns[ NS_EXPORT ]( EX_CLASS, "Tag", Tag ); + +})(); diff --git a/botanjs/src/Astro/Blog/AstroEdit/Uploader.js b/botanjs/src/Astro/Blog/AstroEdit/Uploader.js new file mode 100644 index 0000000..face003 --- /dev/null +++ b/botanjs/src/Astro/Blog/AstroEdit/Uploader.js @@ -0,0 +1,241 @@ +(function( ){ + var ns = __namespace( "Astro.Blog.AstroEdit" ); + + /** @type {System.Cycle} */ + var Cycle = __import( "System.Cycle" ); + /** @type {System.Debug} */ + var debug = __import( "System.Debug" ); + /** @type {System.utils.EventKey} */ + var EventKey = __import( "System.utils.EventKey" ); + /** @type {Components.Mouse.ContextMenu} */ + var ContextMenu = __import( "Components.Mouse.ContextMenu" ); + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + /** @type {Dandelion.IDOMObject} */ + var IDOMObject = __import( "Dandelion.IDOMObject" ); + /** @type {Astro.Blog.Config} */ + var Conf = __import( "Astro.Blog.Config" ); + /** @type {System.utils.Perf} */ + var Perf = __import( "System.utils.Perf" ); + + var postFile = __import( "System.Net.postFile" ); + + + var Uploader = function ( set_file_uri ) + { + /** @type {_AstConf_.SiteFile} */ + var config = Conf.get( "SiteFile" ); + + // linkage + var busy = false + , placedFiles = [] + , currentFile + + + // Prepare structure for dockpanel + , ptext = Dand.id( "asl_ptext" ) + , pbar = Dand.id( "asl_pbar_fill" ) + , ppreview = Dand.id( "asl_preview" ) + , pfileName = Dand.id( "asl_fileName" ) + , instruction = Dand.id( "asl_instruction" ) + , p_status = Dand.id( "asl_u_head" ) + + , fileList = Dand.id( "asl_fileList" ) + , stage = Dand.id( "asl_uploader" ) + + + , uploadProgress = function(e) + { + var done = e.position || e.loaded + , total = e.totalSize || e.total + , percentage = String( Math.floor( done / total * 1000 )/10 ) + "%"; + + // Set progress + ptext.innetText + = ptext.textContent + = pbar.style.width + = percentage; + } + + , uploadComplete = function ( response ) + { + try + { + var obj = JSON.parse( response ); + if(obj.status) + { + currentFile.setStatus( "ok", config.f_host + obj.destination ); + } + else + { + currentFile.setStatus( "error", obj.message ); + } + new ContextMenu( currentFile.stage, currentFile.menuKeys, "LMB", stage ); + } + catch ( ex ) + { + currentFile.setStatus( "error", ex.message ); + debug.Error( ex ); + } + beginUpload(); + } + + , beginUpload = function() + { + busy = true; + if( placedFiles.length ) + { + currentFile = placedFiles.pop(); + if( currentFile ) + { + var file = currentFile.file; + + pfileName.textContent = pfileName.innetText = file.name; + + var fd = new FormData(); + fd.append( "uploadFile", file ); + postFile( set_file_uri, fd, { progress: uploadProgress, complete: uploadComplete } ); + + currentFile.setStatus("active"); + instruction.style.marginTop = "-80px"; + } + else + { + // deleted file, skip it + beginUpload(); + } + } + else + { + busy = false; + instruction.style.marginTop = ""; + } + } + + , clearFileList = function () + { + while( fileList.hasChildNodes() ) + { + fileList.removeChild( fileList.firstChild ); + } + } + + , retryUpload = function () + { + this.setStatus("pending"); + placedFiles[placedFiles.length] = this; + new ContextMenu( this.stage, this.menuKeys, "RMB", stage ); + if( !busy ) beginUpload(); + } + + , removeItem = function () + { + this.stage.style.marginTop = "-2em"; + this.stage.style.opacity = "0"; + + if( placedFiles.indexOf(this) != -1 ) + { + delete placedFiles[placedFiles.indexOf(this)]; + } + + Cycle.delay(function () { + fileList.removeChild(this); + }.bind(this.stage), 250); + } + ; + + fileList.style.paddingTop = String(p_status.clientHeight) + "px"; + + + var docDom = IDOMObject( document ); + // Drag/drop handlers + docDom.addEventListener( "DragOver", function ( e ) + { + e.preventDefault(); + this.className = "dragged_over"; + } ); + docDom.addEventListener( "DragEnd", function () { this.className = ""; } ); + docDom.addEventListener( "Drop", function ( e ) + { + e.preventDefault(); + this.className = ""; + + // Push files + var list = e.dataTransfer.files; + for(var i in list) + { + if(list[i].type != undefined) + { + var fileItem = new ASLFileItem(list[i], {clear: clearFileList, remove: removeItem, retry: retryUpload}); + placedFiles[placedFiles.length] = fileItem; + + fileList.appendChild(fileItem.stage); + new ContextMenu(fileItem.stage, fileItem.menuKeys, "LMB", stage); + } + } + + if(!busy) beginUpload(); + + return false; + } ); + }; + + var ASLFileItem = function (file, callbacks) + { + var statusblob = Dand.wrap("span", null, "asl_uItemStat", "\u25CF") + , msg + , _items = [ + new EventKey("Remove this item", callbacks.remove.bind(this)) // Reserved for remove item + , null // Reserved for retry/ Open link + , null // Reserved for get Error message + , new EventKey("Clear all", callbacks.clear) + ] + + , popMessage = function () + { + new MessageBox("Upload error", msg).show(); + } + + , getFileLink = function () + { + return msg; + } + ; + + this.stage = Dand.wrap( null, "asl_item" + Perf.uuid, "asl_uItem", [ statusblob, Dand.textNode(file.name) ] ); + this.file = file; + this.menuKeys = _items; + + this.setStatus = function (st, message) + { + msg = message; + switch(st) + { + case "active": + statusblob.style.color = "cornflowerblue"; + break; + case "error": + statusblob.style.color = "red"; + + _items[1] = new EventKey( "Retry", callbacks.retry.bind(this) ); + _items[2] = new EventKey( "Whats wrong ?", popMessage ); + + break; + case "ok": + statusblob.style.color = "greenyellow"; + + _items[1] = new EventKey( "Copy file link", getFileLink ); + + break; + default:// pending + delete _items[1]; + delete _items[2]; + statusblob.style.color = ""; + } + + } + }; + + ns[ NS_EXPORT ]( EX_CLASS, "Uploader", Uploader ); + +})(); diff --git a/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/AcquireLib.js b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/AcquireLib.js new file mode 100644 index 0000000..f4d29f3 --- /dev/null +++ b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/AcquireLib.js @@ -0,0 +1,110 @@ +(function () +{ + var ns = __namespace( "Astro.Blog.AstroEdit.Visualizer.Snippet" ); + + /** @type {System.utils.IKey} */ + var IKey = __import( "System.utils.IKey" ); + /** @type {System.utils.DataKey} */ + var DataKey = __import( "System.utils.DataKey" ); + /** @type {Dandelion.IDOMElement} */ + var IDOMElement = __import( "Dandelion.IDOMElement" ); + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + /** @type {Components.MessageBox} */ + var MessageBox = __import( "Components.MessageBox" ); + + + var acquirelib = function(insertSnippet, snippetWrap, createContext, override) + { + var temp, i, j + + , handler = function () + { + // Input fields + var input_text = Dand.wrap('input', null, "v_snippet_input_single", null, new IKey("type", "text")); + + if (this._stage) + { + input_text.value = this._text; + } + + // Popup MessageBox + new MessageBox( + "Acquire library" + ( this._stage ? " (Edit)" : "" ) + , Dand.wrape([ Dand.wrapc( "v_instruction flsf", "Module" ) , input_text ]) + , "OK", "Cancel" + , visualizer.bind({ text:input_text, stage: this._stage }) + ).show(); + } + + , visualizer = function (submitted, override) + { + var src = override ? override.value : this.text.value + , stage = this.stage; + + if (submitted && src) + { + // Shared clause + + if (!stage) + { + if (!src) return; + + + // Visualize component + temp = Dand.wrap( + 'span' + , null + , "flsf" + , "AcquireLib: " + src + , [ + new DataKey( "value", src ) + , new IKey( + "style", "background-color: #444; color: white; padding: 0.2em 0.5em;" + ) + ] + ); + insertSnippet(j = snippetWrap("AcquireLib", temp, false, 'span'), Boolean(override)); + } + else + { + IDOMElement(stage).setAttribute( new DataKey("value", src) ); + + stage.removeChild(stage.firstChild); + stage.appendChild(Dand.textNode("AcquireLib: " + src)); + + // set temp back to stage + temp = stage; + } + + i = {_text: src, _stage: temp}; + + // Set context menu + createContext(i, j, handler); + } + } + ; + + if (override) + { + visualizer(true, override); + override = false; + } + else + { + return handler; + } + return true; + }; + + var compile = function (stage) + { + var element = IDOMElement(stage); + + return "[acquirelib]" + element.getDAttribute("value") + "[/acquirelib]"; + }; + + __static_method( acquirelib, "compile", compile ); + + ns[ NS_EXPORT ]( EX_CLASS, "AcquireLib", acquirelib ); +})(); diff --git a/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Code.js b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Code.js new file mode 100644 index 0000000..db78df1 --- /dev/null +++ b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Code.js @@ -0,0 +1,191 @@ +(function () +{ + var ns = __namespace( "Astro.Blog.AstroEdit.Visualizer.Snippet" ); + + /** @type {System.utils.IKey} */ + var IKey = __import( "System.utils.IKey" ); + /** @type {System.utils.DataKey} */ + var DataKey = __import( "System.utils.DataKey" ); + /** @type {Dandelion.IDOMElement} */ + var IDOMElement = __import( "Dandelion.IDOMElement" ); + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + /** @type {Components.MessageBox} */ + var MessageBox = __import( "Components.MessageBox" ); + + var escapeStr = ns[ NS_INVOKE ]( "escapeStr" ); + + var code = function ( insertSnippet, snippetWrap, createContext, override ) + { + var temp, i, j + , codeLangs = IKey.quickDef( + "Plain text" , "plain" + , "AS3" , "as3" + , "bash" , "bash" + , "C#" , "c#" + , "C/C++" , "c" + , "CSS" , "css" + , "php" , "php" + , "Python" , "python" + , "Perl" , "perl" + , "Ruby" , "ruby" + , "Html/Xml" , "html" + , "Java" , "java" + , "JavaScript" , "js" + , "SQL" , "sql" + ) + + // Private methods + , compileListItems = function () + { + var arr = []; + for ( i in codeLangs ) + { + arr[ arr.length ] = Dand.wrapne( + "option" + , codeLangs[i].keyName + , new IKey( "value", codeLangs[i].keyValue ) + ); + } + return arr; + } + + // Snippet Class structure: handler & visualizer + , handler = function () + { + // Input fields + var v_snippetInput = Dand.wrap( "textarea", null, "v_snippet_input" ) + , v_codelang = Dand.wrap( "select", null, "v_select flsf", compileListItems() ); + + if ( this._stage ) + { + if ( this._lang ) + { + for ( i = 0; i < codeLangs.length; i ++ ) + { + if ( codeLangs[i].keyValue == this._lang ) + { + v_codelang.selectedIndex = i; + } + } + } + + v_snippetInput.value = this._content || ""; + } + else + { + // Remember the last choice + if ( typeof( this.pSnippeCodeChoice ) == "number" ) + v_codelang.selectedIndex = this.pSnippeCodeChoice; + } + + // Popup MessageBox + new MessageBox( + ( this._stage ? "Edit" : "Insert" ) + " code snippet" + , Dand.wrapc( + "v_trimmer" + , [ + Dand.wrapc( "v_instruction", v_codelang ) + , v_snippetInput + ] + ) + , "OK", "Cancel" + // Switcher + , visualizer.bind({ code:v_snippetInput, lang: v_codelang, stage: this._stage }) + ).show(); + } + + + , visualizer = function ( submitted, override ) + { + var lang, code + , stage = this.stage; + + if ( override ) + { + lang = override.lang; + code = override.value; + } + else + { + lang = this.lang[this.pSnippeCodeChoice = this.lang.selectedIndex].value; + code = this.code.value; + } + + + if ( submitted && code ) + { + if (!stage) + { + // Visualize component + temp = Dand.wrapc( + "v_box" + , [ + Dand.wrapne( "pre", code ) + , Dand.wrapc( "v_description", "Script language: " + lang ) + ] + , [ + new DataKey( "value", code ) + , new DataKey( "lang", lang ) + ] + ); + insertSnippet( j = snippetWrap( "Code", temp ), Boolean( override ) ); + } + else + { + IDOMElement( stage ).setAttribute( + [ + new DataKey( "value", code ) + , new DataKey( "lang", lang ) + ] + ); + + temp = stage.firstChild; + temp.removeChild( temp.firstChild ); + stage.firstChild.appendChild( Dand.textNode( code ) ); + + temp = stage.lastChild; + temp.removeChild( temp.firstChild ); + temp.appendChild( Dand.textNode( "Script language: " + lang ) ); + + temp = stage; + + } + + i = { _lang: lang, _content: code, _stage: temp }; + + // Set context menu + createContext( i, j, handler ); + } + } + ; + + if ( override ) + { + visualizer( true, override ); + override = false; + } + else + { + return handler; + } + return true; + }; + + var compile = function ( stage ) + { + // [code lang=\"" + lang + "\"]" + code + "[/code]" + var element = IDOMElement( stage ) + , lang = element.getDAttribute( "lang" ); + + return "[code" + + (lang ? (" lang=\"" + lang + "\"") : "") + "]" + + escapeStr( element.getDAttribute( "value" ) ) + + "[/code]" + ; + }; + + __static_method( code, "compile", compile ); + + ns[ NS_EXPORT ]( EX_CLASS, "Code", code ); +})(); diff --git a/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Html.js b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Html.js new file mode 100644 index 0000000..f7b1fbd --- /dev/null +++ b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Html.js @@ -0,0 +1,107 @@ +(function () +{ + var ns = __namespace( "Astro.Blog.AstroEdit.Visualizer.Snippet" ); + + /** @type {System.utils.IKey} */ + var IKey = __import( "System.utils.IKey" ); + /** @type {System.utils.DataKey} */ + var DataKey = __import( "System.utils.DataKey" ); + /** @type {Dandelion.IDOMElement} */ + var IDOMElement = __import( "Dandelion.IDOMElement" ); + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + /** @type {Components.MessageBox} */ + var MessageBox = __import( "Components.MessageBox" ); + + var escapeStr = ns[ NS_INVOKE ]( "escapeStr" ); + + var html = function (insertSnippet, snippetWrap, createContext, override) + { + var temp, i, j + + , handler = function () + { + // Input fields + var v_snippetInput = Dand.wrap( "textarea", null, "v_snippet_input" ); + + if ( this._stage ) + { + v_snippetInput.value = this._code; + } + + // Popup MessageBox + new MessageBox( + "Insert Html snippet" + , v_snippetInput + , "OK", "Cancel" + , visualizer.bind({ code: v_snippetInput, stage: this._stage }) + ).show(); + } + + , visualizer = function (submitted, override) + { + + var code, stage = this.stage; + + code = override ? override.value : this.code.value; + + if (submitted && code) + { + if (!stage) + { + // Visualize component + temp = Dand.wrapc( + "v_box" + , [ + Dand.wrapne( "pre", code ) + , Dand.wrapc( "v_description", "Raw Html Codes" ) + ] + , [ + new DataKey( "value", code ) + , new IKey( "style", "max-height: 150px;" ) + ] + ); + insertSnippet(j = snippetWrap("Html", temp), Boolean(override)); + } + else + { + IDOMElement( stage ).setAttribute(new DataKey( "value", code )); + + temp = stage.firstChild; + temp.removeChild(temp.firstChild); + stage.firstChild.appendChild(Dand.textNode( code )); + + temp = stage; + + } + + i = { _code: code, _stage: temp }; + + // Set context menu + createContext( i, j, handler ); + } + }; + + if ( override ) + { + visualizer( true, override ); + override = false; + } + else + { + return handler; + } + return true; + + }; + + var compile = function (stage) + { + // [html][/html] + return "[html]" + escapeStr( IDOMElement(stage).getDAttribute("value") ) + "[/html]"; + }; + + __static_method( html, "compile", compile ); + + ns[ NS_EXPORT ]( EX_CLASS, "Html", html ); +})(); diff --git a/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Image.js b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Image.js new file mode 100644 index 0000000..d0ca455 --- /dev/null +++ b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Image.js @@ -0,0 +1,157 @@ +(function () +{ + var ns = __namespace( "Astro.Blog.AstroEdit.Visualizer.Snippet" ); + + /** @type {System.utils.IKey} */ + var IKey = __import( "System.utils.IKey" ); + /** @type {System.utils.DataKey} */ + var DataKey = __import( "System.utils.DataKey" ); + /** @type {Dandelion.IDOMElement} */ + var IDOMElement = __import( "Dandelion.IDOMElement" ); + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + /** @type {Components.MessageBox} */ + var MessageBox = __import( "Components.MessageBox" ); + + var image = function( insertSnippet, snippetWrap, createContext, override ) + { + var temp, i, j + + , handler = function () + { + // Input fields + var input_url = Dand.wrap( + "input", null, "v_snippet_input_single", null, new IKey( "type", "text" ) + ) + , input_a = Dand.wrap( + "input", null, "v_snippet_input_single", null, new IKey( "type", "text" ) + ); + + if (this._stage) + { + input_url.value = this._url; + input_a.value = this._href; + } + + // Popup MessageBox + new MessageBox( + ( this._stage ? "Edit" : "Insert" ) + " image snippet", + Dand.wrape([ + Dand.wrapc( "v_instruction flsf", "Link to the image:" ) + , input_url + , Dand.wrapc( "v_instruction flsf", "Ancohr link(optional):" ) + , input_a + ] + ) + , "OK", "Cancel" + , visualizer.bind({ url:input_url, href:input_a, stage: this._stage }) + ).show(); + } + + , visualizer = function ( submitted, override ) + { + var src, href + , stage = this.stage; + + if ( override ) + { + src = override.value; + href = override.href; + } + else + { + src = this.url.value; + href = this.href.value; + } + + if ( submitted && src ) + { + + // Shared clause + i = Dand.textNode(href ? ("link to: " + href): "No link"); + + if ( !stage ) + { + if ( !src ) return; + + + // Visualize component + temp = Dand.wrapc( + "v_box" + , [ + Dand.wrapna( + "img" + , [ + new IKey("src", src) + , new IKey("style", "max-width: 100%") + ] + ) + // caption + , Dand.wrapc( "v_description", i ) + ] + , [ + new DataKey("value", src) + , new DataKey("href", href) + ] + ); + insertSnippet( j = snippetWrap( "Image", temp ), Boolean( override ) ); + } + else + { + IDOMElement( stage ).setAttribute + ([ + new DataKey( "value", src ) + , new DataKey( "href", href ) + ]); + + stage.firstChild.setAttribute("src", src); + + temp = stage.lastChild; + temp.removeChild(temp.firstChild); + temp.appendChild(i); + + // set temp back to stage + temp = stage; + } + + i = { _url: src, _href: href, _stage: temp }; + + // Set context menu + createContext( i, j, handler ); + } + } + ; + + if ( override ) + { + visualizer( true, override ); + override = false; + } + else + { + return handler; + } + return true; + }; + + var compile = function ( stage ) + { + // [img href=\"" + this.href.value + "\"]" + this.url.value + "[/img] + var element = IDOMElement( stage ) + , href = element.getDAttribute( "href" ); + + return "[img" + + ( href ? (" href=\"" + href + "\"") : "" ) + + "]" + + element.getDAttribute( "value" ) + "[/img]" + ; + }; + + // Alias + var alias = "img"; + + __static_method( image, "compile", compile ); + __const( image, "alias", alias ); + + ns[ NS_EXPORT ]( EX_CLASS, "Image", image ); +})(); diff --git a/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Link.js b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Link.js new file mode 100644 index 0000000..67039c3 --- /dev/null +++ b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Link.js @@ -0,0 +1,131 @@ +(function () +{ + var ns = __namespace( "Astro.Blog.AstroEdit.Visualizer.Snippet" ); + + /** @type {System.utils.IKey} */ + var IKey = __import( "System.utils.IKey" ); + /** @type {System.utils.DataKey} */ + var DataKey = __import( "System.utils.DataKey" ); + /** @type {Dandelion.IDOMElement} */ + var IDOMElement = __import( "Dandelion.IDOMElement" ); + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + /** @type {Components.MessageBox} */ + var MessageBox = __import( "Components.MessageBox" ); + + var link = function(insertSnippet, snippetWrap, createContext, override) + { + var temp, i, j + + , handler = function () + { + // Input fields + var input_text = Dand.wrap('input', null, "v_snippet_input_single", null, new IKey("type", "text")) + , input_a = Dand.wrap('input', null, "v_snippet_input_single", null, new IKey("type", "text")); + + if (this._stage) + { + input_text.value = this._text; + input_a.value = this._href; + } + + // Popup MessageBox + new MessageBox( + (this._stage ? "Edit" : "Insert") + " link", + Dand.wrape([ + Dand.wrapc("v_instruction flsf", "Text") + , input_text + , Dand.wrapc("v_instruction flsf", "Link to:") + , input_a + ] + ) + , "OK", "Cancel", visualizer.bind({text:input_text, href:input_a, stage: this._stage})).show(); + } + + , visualizer = function (submitted, override) + { + var src, href + , stage = this.stage; + + if (override) + { + src = override.value; + href = override.href; + } + else + { + src = this.text.value; + href = this.href.value; + } + + if (submitted && src && href) + { + + // Shared clause + + if (!stage) + { + if (!src) return; + + + // Visualize component + temp = + Dand.wrapne('span', src + , [ + new DataKey("value", src) + , new DataKey("href", href) + ] + ); + insertSnippet(j = snippetWrap("Link", temp, false, 'span'), Boolean(override)); + } + else + { + IDOMElement(stage).setAttribute + ( + [ + new DataKey("value", src) + , new DataKey("href", href) + ] + ); + + stage.removeChild(stage.firstChild); + stage.appendChild(Dand.textNode(src)); + + // set temp back to stage + temp = stage; + } + + i = {_text: src, _href: href, _stage: temp}; + + // Set context menu + createContext(i, j, handler); + } + } + ; + + if (override) + { + visualizer(true, override); + override = false; + } + else + { + return handler; + } + return true; + }; + + var compile = function (stage) + { + // [link href=\"" + this.href.value + "\"]" + text + "[/link] + var element = IDOMElement(stage) + , href = element.getDAttribute("href"); + + return "[link" + (href ? (" href=\"" + href + "\"") : "") + "]" + element.getDAttribute("value") + "[/link]"; + }; + + + __static_method( link, "compile", compile ); + + ns[ NS_EXPORT ]( EX_CLASS, "Link", link ); +})(); diff --git a/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/SiteFile.js b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/SiteFile.js new file mode 100644 index 0000000..00cb176 --- /dev/null +++ b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/SiteFile.js @@ -0,0 +1,174 @@ +(function () +{ + var ns = __namespace( "Astro.Blog.AstroEdit.Visualizer.Snippet" ); + + /** @type {System.utils.IKey} */ + var IKey = __import( "System.utils.IKey" ); + /** @type {System.utils.DataKey} */ + var DataKey = __import( "System.utils.DataKey" ); + /** @type {Dandelion.IDOMElement} */ + var IDOMElement = __import( "Dandelion.IDOMElement" ); + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + /** @type {Components.MessageBox} */ + var MessageBox = __import( "Components.MessageBox" ); + /** @type {Astro.Blog.Config} */ + var Config = __import( "Astro.Blog.Config" ); + /** @type {System.utils.Perf} */ + var Perf = __import( "System.utils.Perf" ); + /** @type {Astro.utils.Date} */ + var XDate = __import( "Astro.utils.Date" ); + + + var escapeStr = ns[ NS_INVOKE ]( "escapeStr" ); + + var getData = __import( "System.Net.getData" ); + + /** @type {_AstConf_.SiteFile} */ + var config = null; + + var sitefile = function ( insertSnippet, snippetWrap, createContext, override ) + { + config = Config.get( "SiteFile" ); + if( !config ) throw new Error( "config is not defined" ); + + var temp, i, j + + , handler = function () + { + // Input fields + var v_snippetInput = Dand.wrap("input", null, "v_snippet_input_single", null, new IKey("type", "text")); + + // Popup MessageBox + new MessageBox("Insert site file", v_snippetInput, "OK", "Cancel", visualizer.bind({code: v_snippetInput})).show(); + } + + , __applyData = function (e) + { + var finfo = JSON.parse(e).file, s, m, l + , content = this.stage.firstChild + , desc = this.stage.lastChild + , _hash = this.hash; + + switch ( finfo.type ) + { + case "image": + + this.stage.removeChild(content); + // Default size is large + var _image = Dand.wrapna("img", new IKey("src", config.path.image.large + _hash + ".jpg")) + , _stage = IDOMElement(this.stage) + , keys = [ new IKey( "type", "radio" ), new IKey( "name", "size_grp" + Perf.uuid ) ] + , sid + , selectionChanged = function () + { + _stage.setAttribute(new DataKey("size", this.size)); + //// Handles the size selection + switch(this.size) + { + case "small": + _image.setAttribute("src", config.path.image.small + _hash + ".jpg"); + break; + case "medium": + _image.setAttribute("src", config.path.image.medium + _hash + ".jpg"); + break; + case "large": + _image.setAttribute("src", config.path.image.large + _hash + ".jpg"); + break; + } + }; + + this.stage.insertBefore(_image, desc); + + desc.removeChild(desc.firstChild); + desc.appendChild( + Dand.wrape([ + Dand.textNode("Size: ") + , s = Dand.wrapna("input", keys.concat( new IKey("id", sid = "size_" + Perf.uuid) )) + , Dand.wrapne("label", "small", new IKey("for", sid)) + , m = Dand.wrapna("input", keys.concat( new IKey("id", sid = "size_" + Perf.uuid) )) + , Dand.wrapne("label", "medium", new IKey("for", sid)) + , l = Dand.wrapna("input", keys.concat( new IKey("checked", "1"), new IKey("id", sid = "size_" + Perf.uuid) )) + , Dand.wrapne("label", "large (default)", new IKey("for", sid)) + ]) + ); + + // ad handlers to handles size change event + IDOMElement(s).addEventListener("Change", selectionChanged.bind({size: "small"})); + IDOMElement(m).addEventListener("Change", selectionChanged.bind({size: "medium"})); + IDOMElement(l).addEventListener("Change", selectionChanged.bind({size: "large"})); + break; + case "audio": + // TODO + break; + default: + content.firstChild.nodeValue = "Regular file: " + finfo.name; + content.style.paddingBottom = "2em"; + content.appendChild( Dand.wrap( "br" ) ); + content.appendChild( Dand.textNode( "Date: " + XDate.pretty( new Date( finfo.date_created ), true ) ) ); + } + + } + + , loadFailed = function (e) { } + + , visualizer = function (submitted, override) + { + + var hash = override ? override.value : this.code.value + , _obj = {file: hash}; + + if ( submitted && hash ) + { + // Visualize component + + temp = Dand.wrapc("v_box" + , [ + Dand.wrape("Getting information from Server ...") + , Dand.wrapc("v_description", "Site file (hash): " + hash) + ] + , [ + new DataKey("value", hash) + , new DataKey("size", "large") + , new IKey("style", "max-height: 150px;") + ] + ); + + // Get data from site library + getData( config.path.info + hash, __applyData.bind({stage: temp, hash: hash}), loadFailed ); + + insertSnippet(j = snippetWrap("SiteFile", temp), Boolean(override)); + + // Set context menu + createContext(null, j); + } + }; + + if (override) + { + visualizer(true, override); + override = false; + } + else + { + return handler; + } + return true; + + }; + + var compile = function ( stage ) + { + stage = IDOMElement( stage ); + // [html][/html] + return "[sitefile" + + " size=\"" + stage.getDAttribute( "size" ) + "\"" + "]" + + escapeStr( stage.getDAttribute( "value" ) ) + + "[/sitefile]"; + }; + + __static_method( sitefile, "compile", compile ); + + ns[ NS_EXPORT ]( EX_CLASS, "SiteFile", sitefile ); + +})(); diff --git a/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Sound.js b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Sound.js new file mode 100644 index 0000000..a654bc2 --- /dev/null +++ b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Sound.js @@ -0,0 +1,146 @@ +(function () +{ + var ns = __namespace( "Astro.Blog.AstroEdit.Visualizer.Snippet" ); + + /** @type {System.utils.IKey} */ + var IKey = __import( "System.utils.IKey" ); + /** @type {System.utils.DataKey} */ + var DataKey = __import( "System.utils.DataKey" ); + /** @type {Dandelion.IDOMElement} */ + var IDOMElement = __import( "Dandelion.IDOMElement" ); + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + /** @type {Components.MessageBox} */ + var MessageBox = __import( "Components.MessageBox" ); + + var compileProp = ns[ NS_INVOKE ]( "compileProp" ); + + var sound = function (insertSnippet, snippetWrap, createContext, override) + { + var temp, i, j + , defaultArt = "http://file.astropenguin.net/blog/layout-images/disc_s.png" + , handler = function () + { + // Input fields + var input_url = Dand.wrap('input', null, "v_snippet_input_single", null, new IKey("type", "text")) + , input_albumArt = Dand.wrap('input', null, "v_snippet_input_single", null, new IKey("type", "text")) + , input_lrc = Dand.wrap('input', null, "v_snippet_input_single", null, new IKey("type", "text")) + ; + + if (this._stage) + { + input_url.value = this._url; + input_albumArt.value = this._albumArt; + input_lrc.value = this._lrc; + } + + new MessageBox( + (this._stage ? "Edit" : "Insert") + " sound snippet" + , Dand.wrape([ + Dand.wrapc("v_instruction flsf", "Link to sound:") + , input_url + + , Dand.wrapc("v_instruction flsf", "Link to album art(optional):") + , input_albumArt + + , Dand.wrapc("v_instruction flsf", "Link to lrc(optional):") + , input_lrc + ] + ) + , "OK", "Cancel", visualizer.bind({url:input_url, albumArt:input_albumArt, lrc:input_lrc, stage: this._stage})).show(); + } + + , visualizer = function (submitted) + { + + var src, albumArt , lrc + , stage = this.stage; + + if (override) + { + src = override.url; + albumArt = override.albumArt; + lrc = override.lrc; + } + else + { + src = this.url.value; + albumArt = this.albumArt.value; + lrc = this.lrc.value; + } + + if (submitted && src) + { + + if (!stage) + { + // Visualize component + temp = Dand.wrapc('v_box' + , [ + Dand.wrape(null, new IKey + ( + "style", "height: 75px; background-size: auto 75px; background-repeat: no-repeat;" + + "background-image: url(" + (albumArt ? albumArt : defaultArt) + ")" + ) + ) + , Dand.wrapc('v_description', "Sound snippet") + ] + , [ + new DataKey("value", "") + , new DataKey("url", src) + , new DataKey("albumArt", albumArt) + , new DataKey("lrc", lrc) + ] + ); + insertSnippet(j = snippetWrap("Sound", temp), Boolean(override)); + } + else + { + // Edit properties + stage.firstChild.style.backgroundImage = "url(" + (albumArt ? albumArt : defaultArt) + ")" ; + + IDOMElement(stage).setAttribute + ( + [ + new DataKey("url", src) + , new DataKey("albumArt", albumArt) + , new DataKey("lrc", lrc) + ] + ); + + } + + i = {_url: src, _albumArt: albumArt, _lrc: lrc, _stage: temp}; + + // Set context menu + createContext(i, j, handler); + } + } + ; + + if (override) + { + visualizer(true, override); + override = false; + } + else + { + return handler; + } + return true; + }; + + var compile = function (stage) + { + // [sound url="" albumArt="" lrc="" ][/sound]"); + var element = IDOMElement(stage) + , props = ["url", "albumArt", "lrc"]; + + return "[sound" + compileProp( element, props ) + "][/sound]"; + }; + + + __static_method( sound, "compile", compile ); + + ns[ NS_EXPORT ]( EX_CLASS, "Sound", sound ); +})(); diff --git a/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Spoiler.js b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Spoiler.js new file mode 100644 index 0000000..98a3098 --- /dev/null +++ b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Spoiler.js @@ -0,0 +1,154 @@ +(function () +{ + var ns = __namespace( "Astro.Blog.AstroEdit.Visualizer.Snippet" ); + + /** @type {System.utils.IKey} */ + var IKey = __import( "System.utils.IKey" ); + /** @type {System.utils.DataKey} */ + var DataKey = __import( "System.utils.DataKey" ); + /** @type {Dandelion.IDOMElement} */ + var IDOMElement = __import( "Dandelion.IDOMElement" ); + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + /** @type {Components.MessageBox} */ + var MessageBox = __import( "Components.MessageBox" ); + + var compileProp = ns[ NS_INVOKE ]( "compileProp" ); + + var spoiler = function(insertSnippet, snippetWrap, createContext, override) + { + var temp, i, j + + , handler = function () + { + // Input fields + var v_snippetInput = Dand.wrap('textarea', null, "v_snippet_input") + , input_title = Dand.wrap('input', null, "v_snippet_input_single", null, new IKey("type", "text")) + , input_expanded = Dand.wrapna('input', new IKey("type", "checkbox")) + + if (this._stage) + { + v_snippetInput.value = this._content; + input_title.value = this._title; + input_expanded.checked = (this._expanded == "on"); + } + + // Popup MessageBox + new MessageBox("Insert spoiler content" + , Dand.wrape([ + Dand.wrapc("v_instruction flsf", "Title") + , input_title + + , Dand.wrapc("v_instruction flsf", "Content") + , v_snippetInput + + , Dand.wrape([ input_expanded, Dand.textNode( "Expanded" ) ]) + ] + ) + , "OK", "Cancel", visualizer.bind({title: input_title, content:v_snippetInput, expanded: input_expanded, stage: this._stage})).show(); + } + + , visualizer = function (submitted, override) + { + var content, title, expanded + , stage = this.stage; + + if (override) + { + content = override.value; + title = override.title; + expanded = override.expanded ? "on" : ""; + } + else + { + content = this.content.value; + title = this.title.value; + expanded = this.expanded.checked ? "on" : ""; + } + + if (submitted && content) + { + // Shared Clause + i = Dand.textNode(title || "Spoiler"); + if (!stage) + { + if (!content) return; + + // Visualize component + temp = Dand.wrapc('v_box', + [ + // caption + Dand.wrapc('v_caption', i) + , Dand.textNode(content) + ], + [ + new DataKey("value", content) + , new DataKey("title", title) + , new DataKey("expanded", expanded) + ] + ); + insertSnippet(j = snippetWrap("Spoiler", temp), Boolean(override)); + } + else + { + IDOMElement(stage).setAttribute + ( + [ + new DataKey("value", content) + , new DataKey("title", title) + , new DataKey("expanded", expanded) + ] + ); + + temp = stage.firstChild; + temp.removeChild(temp.firstChild); + temp.appendChild(i); + + stage.removeChild(stage.lastChild); + stage.appendChild(Dand.textNode(content)); + + // set temp back to stage + temp = stage; + } + + i = { + _title: title + , _content: content + , _expanded: expanded || "off" + , _stage: temp + }; + + // Set context menu + createContext(i, j, handler); + } + } + ; + + if (override) + { + visualizer(true, override); + override = false; + } + else + { + return handler; + } + return true; + }; + + var compile = function ( stage ) + { + var element = IDOMElement( stage ) + , props = ["title", "expanded"]; + + return "[spoiler" + + compileProp( element, props ) + + "]" + + element.getDAttribute( "value" ) + + "[/spoiler]"; + }; + + __static_method( spoiler, "compile", compile ); + + ns[ NS_EXPORT ]( EX_CLASS, "Spoiler", spoiler ); +})(); diff --git a/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Swf.js b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Swf.js new file mode 100644 index 0000000..4222f66 --- /dev/null +++ b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Swf.js @@ -0,0 +1,214 @@ +(function () +{ + var ns = __namespace( "Astro.Blog.AstroEdit.Visualizer.Snippet" ); + + /** @type {System.utils.IKey} */ + var IKey = __import( "System.utils.IKey" ); + /** @type {System.utils.DataKey} */ + var DataKey = __import( "System.utils.DataKey" ); + /** @type {Dandelion.IDOMElement} */ + var IDOMElement = __import( "Dandelion.IDOMElement" ); + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + /** @type {Components.MessageBox} */ + var MessageBox = __import( "Components.MessageBox" ); + + var compileProp = ns[ NS_INVOKE ]( "compileProp" ); + + var swf = function (insertSnippet, snippetWrap, createContext, override) + { + var + temp, i, j + + // Pending + , defaultArt = "" + + , handler = function () + { + // Input fields + var input_w = Dand.wrapna('input', new IKey("type", "number")) + , input_h = Dand.wrapna('input', new IKey("type", "number")) + , input_title = Dand.wrap('input', null, "v_snippet_input_single", null, [new IKey("type", "text"), new IKey("placeHolder", "optional")] ) + , input_desc = Dand.wrap('input', null, "v_snippet_input_single", null, [new IKey("type", "text"), new IKey("placeHolder", "optional")] ) + , input_api = Dand.wrapna('input', new IKey("type", "checkbox")) + , input_preview = Dand.wrap('input', null, "v_snippet_input_single", null, [new IKey("type", "text"), new IKey("placeHolder", "optional")] ) + , input_src = Dand.wrap('input', null, "v_snippet_input_single", null, new IKey("type", "text")) + , stage = this._stage; + + + if (stage) + { + input_src.value = this._src; + input_w.value = this._width; + input_h.value = this._height; + input_title.value = this._title; + input_desc.value = this._desc; + input_preview.value = this._preview; + input_api.checked = (this._extAPI == "on"); + } + + new MessageBox( + "Insert swf object", + Dand.wrape([ + Dand.wrape([Dand.textNode("Dimensions: "), input_w, Dand.textNode("\u00D7"), input_h, Dand.textNode("px")]) + + , Dand.wrapc("v_instruction flsf", "Title:") + , input_title + + , Dand.wrapc("v_instruction flsf", "Description:") + , input_desc + + , Dand.wrapc("v_instruction flsf", "Preview image:") + , input_preview + + , Dand.wrapc("v_instruction flsf", "Link to swf:") + , input_src + + , Dand.wrape([ input_api, Dand.textNode("Use external API") ] ) + ] + ) + , "OK", "Cancel", visualizer.bind({src:input_src, width:input_w, height:input_h, title: input_title, desc: input_desc, extAPI: input_api, preview: input_preview, stage: this._stage})).show(); + } + + , visualizer = function (submitted, override) + { + var src, width, height, title, desc, preview, extAPI + , stage = this.stage; + + if (override) + { + src = override.value; + width = override.width; + height = override.height; + title = override.title; + desc = override.desc; + preview = override.preview; + extAPI = override.useExtAPI; + } + else + { + src = this.src.value; + width = this.width.value; + height = this.height.value; + title = this.title.value; + desc = this.desc.value; + preview = this.preview.value; + extAPI = this.extAPI.checked ? "on" : ""; + } + + if (submitted && width && height && src) + { + + if (!stage) + { + // Visualize component + + temp = Dand.wrapc('v_box' + , Dand.wrapc('v_description' + , [ + Dand.wrap('span', null, 'fls', title) + , Dand.textNode(" ") + , Dand.wrap('span', null, 'v_caption_desc flsf', desc) + ] + , new IKey('style', 'font-size: 2em') + ) + , [ + new DataKey("value", src) + , new DataKey("width", width) + , new DataKey("height", height) + , new DataKey("title", title) + , new DataKey("desc", desc) + , new DataKey("preview", preview) + , new DataKey("useExtAPI", extAPI) + + , new IKey + ( + "style" + , "background-position: center; background-repeat: no-repeat; " + + "width: " + width +"px; height: " + height + "px; " + + "background-image: url(" + (preview ? preview : defaultArt) + ")" + ) + ] + ); + insertSnippet(j = snippetWrap("Swf", temp), Boolean(override)); + } + else + { + IDOMElement(stage).setAttribute + ( + [ + new DataKey("value", src) + , new DataKey("width", width) + , new DataKey("height", height) + , new DataKey("title", title) + , new DataKey("desc", desc) + , new DataKey("preview", preview) + , new DataKey("useExtAPI", extAPI) + ] + ); + + stage.style.width = width + "px"; + stage.style.height = height + "px"; + stage.style.backgroundImage = "url(" + (preview ? preview : defaultArt) + ")"; + + // Title + temp = stage.firstChild.firstChild; + temp.removeChild(temp.firstChild); + temp.appendChild(Dand.textNode(title)); + + // Desc + temp = stage.firstChild.lastChild; + temp.removeChild(temp.firstChild); + temp.appendChild(Dand.textNode(desc)); + + temp = stage; + } + + + i = { + _src: src + , _width: width + , _height: height + , _title: title + , _desc: desc + , _preview: preview + , _extAPI: extAPI || "off" + , _stage: temp + }; + + // Set context menu + createContext(i, j, handler); + } + } + ; + + if (override) + { + visualizer(true, override); + override = false; + } + else + { + return handler; + } + return true; + }; + + var compile = function (stage) + { + // [swf width="" height="" title="" desc="" preview="" useExtAPI="" ]src[/swf]; + var element = IDOMElement(stage) + , props = ["width", "height", "title", "desc", "preview", "useExtAPI"]; + + return "[swf" + + compileProp( element, props ) + + "]" + + element.getDAttribute("value") + + "[/swf]" + ; + }; + + __static_method( swf, "compile", compile ); + + ns[ NS_EXPORT ]( EX_CLASS, "Swf", swf ); +})(); diff --git a/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Video.js b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Video.js new file mode 100644 index 0000000..ea7437c --- /dev/null +++ b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Video.js @@ -0,0 +1,137 @@ +(function () +{ + var ns = __namespace( "Astro.Blog.AstroEdit.Visualizer.Snippet" ); + + /** @type {System.utils.IKey} */ + var IKey = __import( "System.utils.IKey" ); + /** @type {System.utils.DataKey} */ + var DataKey = __import( "System.utils.DataKey" ); + /** @type {Dandelion.IDOMElement} */ + var IDOMElement = __import( "Dandelion.IDOMElement" ); + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + /** @type {Components.MessageBox} */ + var MessageBox = __import( "Components.MessageBox" ); + + var video = function (insertSnippet, snippetWrap, createContext, override) + { + var temp, i, j + + , getVimeoThumbnail = function (vtag) + { + getData("http://vimeo.com/api/oembed.json?url=http%3A//vimeo.com/" + vtag.getAttribute("data-value"), setThumbnail.bind(vtag), noThumb.bind(vtag)); + } + + , noThumb = function () + { + + } + + , setThumbnail = function (str) + { + this.style.background = "black url(" + JSON.parse(str)["thumbnail_url"] + ") center center no-repeat"; + + } + + , handler = function () + { + // Input fields + var input_url = Dand.wrap('input', null, "v_snippet_input_single", null, new IKey("type", "text")); + + // Popup MessageBox + new MessageBox("Insert video snippet" + , Dand.wrape([ Dand.wrapc("v_instruction flsf", "Paste a vimeo/Youtube link below:"), input_url ]) + , "OK", "Cancel", visualizer.bind(input_url) + ).show(); + } + + , visualizer = function (submitted, override) + { + var t, v; + + if (override) + { + v = override.value; + i = override.type; + } + else + { + t = this.value; + // Match youtube links + v = t.match(/\/\/(www\.)?youtube\.com\/watch\?.*?v=([^\&\?\/\#]+)/) || t.match(/\/\/(www\.)?youtube\.com\/embed\/([^\&\?\/]+)/) + || t.match(/\/\/(www\.)?youtube\.com\/v\/([^\&\?\/]+)/) || t.match(/\/\/(www\.)?youtu\.be\/([^\&\?\/]+)/); + if (v) + { + i = "youtube"; + v = v[2]; + } + else + { + // match vimeo links + v = t.match(/\/\/(www\.)?vimeo.com\/(\d+)($|\/)/); + if (v) + { + i = "vimeo"; + v = v[2]; + } + else + { + // None matched, do nothing + return; + } + } + } + + if (submitted) + { + + // Visualize component + temp = Dand.wrapc('v_box', Dand.wrapc('v_description', "Video(url): " + t) + , [ + new DataKey("value", v) + , new DataKey("type", i) + , new IKey("style" + , "width: 640px; height: 390px;" + + ( (i[0] == "v") ? "" : ("background: black url(http://img.youtube.com/vi/" + v + "/hqdefault.jpg) no-repeat center center;") ) + ) + ] + ); + + if (i[0] == "v") + { + getVimeoThumbnail(temp); + } + + insertSnippet(j = snippetWrap("Video", temp), Boolean(override)); + + // Set context menu + createContext(null, j); + } + } + ; + + if (override) + { + visualizer(true, override); + override = false; + } + else + { + return handler; + } + return true; + }; + + var compile = function (stage) + { + // [video type=\"youtube\"]" + v[2] + "[/video] + var element = IDOMElement(stage) + , type = element.getDAttribute("type"); + + return "[video type=\"" + type + "\"]" + element.getDAttribute("value") + "[/video]"; + }; + + __static_method( video, "compile", compile ); + + ns[ NS_EXPORT ]( EX_CLASS, "Video", video ); +})(); diff --git a/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/_this.js b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/_this.js new file mode 100644 index 0000000..744b20b --- /dev/null +++ b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/_this.js @@ -0,0 +1,25 @@ +(function() +{ + var ns = __namespace( "Astro.Blog.AstroEdit.Visualizer.Snippet" ); + + var escapeStr = function ( str ) + { + return str.replace( /\[/g, "[" ).replace( /\]/g, "]" ); + }; + + var compileProp = function ( _iDOM, keys ) + { + var i, j = "", k; + for (i in keys) + { + if( ( k = _iDOM.getDAttribute(keys[i]) ) ) + { + j += " " + keys[i] + "=\"" + k + "\""; + } + } + return j; + }; + + ns[ NS_EXPORT ]( EX_FUNC, "escapeStr", escapeStr ); + ns[ NS_EXPORT ]( EX_FUNC, "compileProp", compileProp ); +})(); diff --git a/botanjs/src/Astro/Blog/AstroEdit/Visualizer/_this.css b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/_this.css new file mode 100644 index 0000000..0dfa89c --- /dev/null +++ b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/_this.css @@ -0,0 +1,101 @@ +.v_snippet_input { + width: 600px; + height: 350px; +} + +.v_boundary { + cursor: default; + padding: 0.2em; +} + +.v_box { + min-height: 3em; + overflow: hidden; + position: relative; +} + +.v_caption, .v_description { + background: rgba(0, 0, 0, 0.8); + padding: 0.2em; + color: white; + + width: 100%; + + font-family: sans-serif; + font-size: 1em; +} + +.v_caption { + position: relative; +} + +.v_description { + position: absolute; + left: 0; + bottom: 0; +} + +.v_caption_desc { + font-size: 60%; +} + +.v_boundary:hover { + background-color: rgba(0, 0, 0, 0.2); +} + +.v_snippet_input_single { + width: 600px; + margin-bottom: 0.5em; +} + +.v_instruction { + padding: 0.2em 0; +} + +.v_trimmer { + overflow: hidden; +} + +.v_select { + width: 100%; + background-color: #222; + font-size: 1em; + color: white; + + background-image: none; + border: none; + box-shadow: none; + -webkit-appearance: none; +} + +div[data-type="token"] { + background-color: #111; + color: #EEE; + + padding: 0.25em 0.5em; + margin-right: 100%; + + min-width: 8em; + + display: inline-block; + + position: relative; +} + +div[data-type="token"]:hover { + background-color: #444; +} + +div[data-type="token"]:after { + content: "Loading"; + position: absolute; + + color: rgba( 255, 255, 255, 0.2 ); + + right: 0; + bottom: 0; +} + +div[data-type="token"]:hover:after { + color: rgba( 255, 255, 255, 0.5 ); +} diff --git a/botanjs/src/Astro/Blog/AstroEdit/Visualizer/_this.js b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/_this.js new file mode 100644 index 0000000..b4fcced --- /dev/null +++ b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/_this.js @@ -0,0 +1,496 @@ +(function(){ + var ns = __namespace( "Astro.Blog.AstroEdit" ); + + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + /** @type {Dandelion.IDOMElement} */ + var IDOMElement = __import( "Dandelion.IDOMElement" ); + /** @type {System.Debug} */ + var debug = __import( "System.Debug" ); + /** @type {System.utils} */ + var utils = __import( "System.utils" ); + /** @type {System.utils.Perf} */ + var Perf = __import( "System.utils.Perf" ); + /** @type {System.utils.DataKey} */ + var DataKey = __import( "System.utils.DataKey" ); + /** @type {System.utils.EventKey} */ + var EventKey = __import( "System.utils.EventKey" ); + /** @type {System.utils.IKey} */ + var IKey = __import( "System.utils.IKey" ); + /** @type {System.Net.ClassLoader} */ + var Loader = __import( "System.Net.ClassLoader" ); + /** @type {Components.MessageBox} */ + var MessageBox = __import( "Components.MessageBox" ); + /** @type {Components.Mouse.ContextMenu} */ + var ContextMenu = __import( "Components.Mouse.ContextMenu" ); + /** @type {Astro.Blog.Config} */ + var Config = __import( "Astro.Blog.Config" ); + + var snippetList = IKey.quickDef( + "Code" , "background: white; color: cornflowerblue;" + , "Image" , "background: #ff0084;" + , "Sound" , "background: YellowGreen;" + , "Video" , "background: Crimson;" + , "Spoiler" , "background: cornflowerblue;" + , "Swf" , "background: #333;" + , "Link" , "background: blue;" + , "AcquireLib" , "background: black;" + , "Html" , "background: coral;" + , "SiteFile" , "background: royalblue;" + ); + + var snippetNs = "Astro.Blog.AstroEdit.Visualizer.Snippet."; + //// Document Visualizer visualize snippets, used in AstroEdit and comments + var Visualizer = function ( e_document, snippetControls, service_uri ) + { + var Article = ns[ NS_INVOKE ]( "Article" ); + var loadedModule = {}; + + //// Constants + var article; + // "[^]" does not work in IE + var stackMatch = /\[([a-z][0-9a-z]*?)([\s\S]*?)\]([\s\S]*?)\[\/\1\]/ig; + var typeMatch = /([a-z][0-9a-z]*)\=\"([^"]+)\"/ig; + + var snippetTokenQueue = {}; + + if ( e_document instanceof Article ) + { + article = e_document; + // Allow Html snippet + } + else if ( e_document instanceof CeDocument ) + { + article = e_document; + } + else return; + + ////// Variables + var contentDiv = Dand.wrap() + var selRange; + var snippetExists = false; + var lastOffset = 0; + var raw; + + ///// private methods + var snippetWrap = function( snippetType, element, editable, _with ) + { + var snippet = Dand.wrap( + _with || "div" + , Perf.uuid + , "comp v_boundary" + , element + , [ + new IKey( "contentEditable", editable ? "true" : "false" ) + , new DataKey( "type", snippetType ) + ] + ); + + return snippet; + }; + + var appendLinebreak = function () + { + this.parentNode.insertBefore(Dand.wrap("br"), this.nextSibling); + } + + var insertLinebreak = function () + { + this.parentNode.insertBefore(Dand.wrap("br"), this); + }; + + var snippetDelete = function () + { + this.parentNode.removeChild(this); + }; + + var snippetBBCode = function() + { + var snippet = IDOMElement( this ); + var type = snippet.getDAttribute( "type" ).toLowerCase(); + /** @type {Astro.Blog.AstroEdit.Visualizer.Snippet.Model} */ + var module = loadedModule[ type ]; + var title = "An error occurred"; + var message = "No such module"; + + if( module ) + { + title = "BBCode for Snippet: " + type; + message = module.compile( this.firstChild ); + } + + new MessageBox( title, Dand.wrapne( "pre", message ) ).show(); + }; + + var createSnippetMenu = function ( snippetProp, snippet, editHandler, snippetActions ) + { + var contextItems = [ + editHandler && new EventKey( "Edit", editHandler.bind( snippetProp ) ) + , new EventKey( "Insert a linebreak", insertLinebreak.bind( snippet ) ) + , new EventKey( "Append a linebreak", appendLinebreak.bind( snippet ) ) + , new EventKey( "Delete", snippetDelete.bind( snippet ) ) + , new EventKey( "View BBCode", snippetBBCode.bind( snippet ) ) + ]; + + e_document.updateContent(); + + if ( snippetActions instanceof Array ) + { + contextItems = snippetActions.concat( contextItems ); + } + + return new ContextMenu( snippet, contextItems, "RMB" ); + }; + + var _savSelection = function () + { + contentDiv.focus(); + if ( window.getSelection ) + { + var sel = window.getSelection(); + if ( sel.getRangeAt && sel.rangeCount ) + { + selRange = sel.getRangeAt(0); + } + } + else if ( document.selection && document.selection.createRange ) + { + selRange = document.selection.createRange(); + } + else + { + selRange = null; + } + }; + + var _resSelection = function () + { + if ( selRange ) + { + if ( window.getSelection ) + { + var sel = window.getSelection(); + sel.removeAllRanges(); + sel.addRange( selRange ); + } + else if ( document.selection && selRange.select ) + { + selRange.select(); + } + } + }; + + var lastLine = Dand.wrap( "br", "v_linebreak" ); + + var ensureLastLinebreak = function () + { + if( !Dand.id( "v_linebreak" ) ) + { + insertSnippet( lastLine, true ); + } + else + { + insertSnippet( contentDiv.removeChild( lastLine ), true ); + } + }; + + var insertAtCaret = function( element ) + { + var sel, range; + + sel = window.getSelection(); + if ( sel.getRangeAt && sel.rangeCount ) + { + range = sel.getRangeAt(0); + range.deleteContents(); + range.insertNode( element ); + range.setStartAfter( element ); + range.setEndAfter( element ); + range.collapse( false ); + sel.removeAllRanges(); + sel.addRange( range ); + } + + e_document.updateContent(); + ensureLastLinebreak(); + }; + + var insertSnippet = function( element, override ) + { + if ( override ) + { + contentDiv.appendChild( element ); + return; + } + + contentDiv.focus(); + _resSelection(); + insertAtCaret( element ); + }; + + var replaceToken = function( element ) + { + contentDiv.insertBefore( element, this.token ); + contentDiv.removeChild( this.token ); + }; + + var parseKeys = function ( match, name, value ) + { + this[ name ] = value; + }; + + var snippetQueue = function( type, alias ) + { + var q = snippetTokenQueue[ type ] || []; + + if( alias ) + { + if( !( alias instanceof Array ) ) alias = [ alias ]; + + for( var i in alias ) + { + q = snippetTokenQueue[ alias[i] ] || []; + if( q.length ) return q; + } + } + + return ( snippetTokenQueue[ type ] = q ); + }; + + var parseSnippet = function( match, type, properties, _value, offset ) + { + var temp, i, j; + // Texts goes first + if ( lastOffset != offset ) + { + // innerText does not work in firefox:( + temp = Dand.wrape( raw.substr( lastOffset, offset - lastOffset ) ); + // innerHTML will escape html entities, now replace linebreaks to br + temp.innerHTML = temp.innerHTML.replace(/[\r\n]/g, "
"); + IDOMElement( contentDiv ).lootChildren( temp ); + } + + lastOffset = offset + match.length; + + // Snippet Args + temp = { value: _value }; + // to ekeys + properties.replace( typeMatch, parseKeys.bind( temp ) ); + + // Now deal with snippet + /** @type {Astro.Blog.AstroEdit.Visualizer.Snippet.Model} */ + var _module = loadedModule[ type ]; + if ( _module ) + { + // Visualize snippet + new ( _module )( insertSnippet, snippetWrap, createSnippetMenu, temp ); + } + else + { + // no such module, or module is not loaded yet + debug.Info( "[Visualizer] Queueing: " + type ); + var token = snippetWrap( "token", type, false ); + token.setAttribute( "class", token.getAttribute( "class" ) + " flsf" ); + snippetQueue( type ).push([ token, temp ]); + + insertSnippet( token, true ); + } + }; + + var linebreakNodes = ["P", "DIV"]; + var linebreakNode = function( name ) + { + if( -1 < linebreakNodes.indexOf( name.toUpperCase() ) ) return "\n"; + return ""; + }; + + var ensureGoodness = function () + { + _savSelection(); + ensureLastLinebreak(); + }; + + var stepContent = function ( element, level ) + { + var j , snippetType + , elements = element.childNodes + , output = ""; + + for (var i = 0, l = elements.length; i < l; i ++) + { + j = elements[i]; + + // do nothing on lastline + if (j == lastLine) continue; + + if (j.nodeType == 1) + { + snippetType = IDOMElement( j ).getDAttribute( "type" ); + if( snippetType && loadedModule[ snippetType = snippetType.toLowerCase() ] ) + { + output += loadedModule[ snippetType ].compile( j.firstChild ); + } + else if ( j.firstChild ) + { + // Text + output += linebreakNode( j.nodeName ) + stepContent(j, ++level); + } + else + { + // Handle special

=> one line break + if(l == 1 && j.nodeName.toUpperCase() == "BR") continue; + + // Line breaks + output += "\n"; + } + } + // Text + else if (j.nodeType == 3) + { + output += j.nodeValue; + } + } + + return output; + }; + + ///// Initializations + var snippetReady = function ( e ) + { + // Initialize modules + var mod_name = e.substr( e.lastIndexOf(".") + 1, e.length ).toLowerCase() + /** @type {Astro.Blog.AstroEdit.Visualizer.Snippet.Model} */ + var _module = __import( e ); + var alias = _module.alias; + + // Implement module if valid and available + if ( _module && _module.compile ) + { + loadedModule[ mod_name ] = _module; + debug.Info( "[Visualizer] Module loaded: " + mod_name ); + // Set alias + if ( alias ) + { + alias = ( alias instanceof Array ) ? alias : [ alias ]; + + for ( var k in alias ) + { + loadedModule[ alias[k] ] = _module; + debug.Info( "[Visualizer] Alias: " + mod_name + " => " + alias ); + } + } + + // Append module"s control + temp = Dand.wrapne( + "span" + , mod_name + , new IKey( + "style" + , utils.objSearch( + snippetList + /** @param {System.utils.IKey} a */ + , function( a ) { return a.keyName.toLowerCase() == mod_name } + , "keyValue" + ) + ) + ); + + snippetControls.appendChild( temp ); + snippetControls.appendChild( Dand.textNode( "\t" ) ); + temp.onclick = new ( _module )( insertSnippet, snippetWrap, createSnippetMenu ); + + var queue = snippetQueue( mod_name, _module.alias ); + for( var i in queue ) + { + var token = queue[i]; + new ( _module )( replaceToken.bind({ token: token[0] }), snippetWrap, createSnippetMenu, token[1] ); + delete queue[i]; + } + } + else + { + if ( _module ) + { + delete loadedModule[ mod_name ]; + debug.Info( "[Visualizer] Module discarded: invalid module \"" + mod_name + "\"" ); + } + else + { + debug.Info( "[Visualizer] Module \"" + mod_name + "\" does not exists" ); + } + } + }; + + this.setContentDiv = function( element ) + { + contentDiv = element; + // listeners that return values cannot use addEventListener + contentDiv.onkeypress = function(e) + { + if (e.which == 13) + { + insertAtCaret( Dand.wrap( "br" ) ); + _savSelection(); + return false; + } + return true; + }; + + temp = IDOMElement( contentDiv ); + temp.addEventListener( "Input", ensureGoodness ); + temp.addEventListener( "KeyUp", ensureGoodness ); + temp.addEventListener( "Click", ensureGoodness ); + + contentDiv.focus(); + ensureGoodness(); + + try { + document.execCommand( "insertBrOnReturn", false, "true" ); + } catch(e) { + debug.Info( "Not firefox" ); + } + }; + + this.saveRaw = function () + { + return stepContent( contentDiv, 0 ); + }; + + this.visualizeData = function ( data ) + { + if ( !data ) return; + + lastOffset = 0; + // clear content + contentDiv.innerHTML = ""; + + ( raw = data ).replace( stackMatch, parseSnippet ); + if ( lastOffset != raw.length ) + { + // innerText does not work in firefox:( + temp = Dand.wrape( raw.substr( lastOffset, raw.length - lastOffset ) ); + // innerHTML will escape html entities, now replace linebreaks to br + temp.innerHTML = temp.innerHTML.replace( /[\r\n]/g, "
" ); + IDOMElement( contentDiv ).lootChildren( temp ); + } + temp = null; + raw = null; + }; + + this.saveSelection = _savSelection; + this.restoreSelection = _resSelection; + + article.invoke(this); + + var modules = []; + for( var i in snippetList ) + { + modules[ modules.length ] = snippetNs + snippetList[i].keyName; + } + + var ldr = new Loader( service_uri, "r" ); + ldr.load( modules, snippetReady ); + }; + + ns[ NS_EXPORT ]( EX_CLASS, "Visualizer", Visualizer ); +})(); diff --git a/botanjs/src/Astro/Blog/AstroEdit/_this.css b/botanjs/src/Astro/Blog/AstroEdit/_this.css new file mode 100644 index 0000000..e312862 --- /dev/null +++ b/botanjs/src/Astro/Blog/AstroEdit/_this.css @@ -0,0 +1,244 @@ +.ae_panel_section { + padding: 0 1em; + color: white; +} + +.ae_section_prop { + margin: 0.5em 0; + text-align: right; +} + +.ae_prop_value { + font-size: 1.2em; + text-align: right; +} + +/* Interactive value */ +.ae_iValue { + text-align: center; + padding: 0.5em; + cursor: default; +} + +.ae_background { + background-color: #fff; + background-image: + linear-gradient(90deg, transparent 1em, #666 1em, #666 1.2em, transparent 1.2em), + linear-gradient(#EEE .1em, transparent .1em); + background-size: 100% 1.5em; +} + + +/* Buttons */ +.ae_purple { background: purple; } +.ae_purple:hover { background: darkmagenta; } +.ae_coral { background: orangered; } +.ae_coral:hover { background: darkorange; } +.ae_dodgerblue { background: dodgerblue; } +.ae_caution { color: red; } +.ae_caution:hover { background: #333; } +.ae_dodgerblue:hover { background: cornflowerblue; } +/* End buttons */ + + +.ae_disabled { + color: grey; + background: none; +} + +.ae_blockswitch { + line-height: 2em; +} + +.ae_blockswitch > span { + white-space: nowrap; + /* text-transform:uppercase; */ + font-family: custom-sans; + padding: 0.2em 0.5em; + cursor: default; + opacity: 0.5; +} + +.ae_blockswitch > span:hover { + background-color: black; + opacity: 1; +} + +.ae_body { + max-height: 100%; + + overflow-y: scroll; + + position: fixed; +} + +.ae_content { + width: auto; + background: SkyBlue; +} + +.ae_panel { + width: 300px; + height: auto; + min-height: 100%; + background: #222; + color: white; + + position: absolute; + + top: 0; + right: 0; + + /* will handel mouse scroll later*/ + overflow: hidden; + + -moz-box-shadow: -2px 0 5px black; + -webkit-box-shadow: -2px 0 5px black; + box-shadow: -2px 0 5px black; +} + +.ae_topbar { + width: 100%; + color: #222; + padding: 0.35em 0; + overflow: hidden; + border-bottom: 7px solid #222; +} + + +.ae_title, .ae_stitle { + padding: 0.35em; +} + +.ae_title { + position: relative; + top: 0.25em; + font-size: 2em; +} + +.ae_stitle { + font-size: 1.5em; +} + +#ae_title { + font-size: 2.5em; + color: #444; +} + +#ae_content { + font-size: 100%; +} + +#ae_title, #ae_content { + background: none; + width: 100%; + + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +#ae_title:focus { + background: rgba(255, 255, 255, 0); +} + +#ae_content:focus { + background: rgba(255, 255, 255, 0); +} + +#ae_bgdimmer { + background: rgba(255, 255, 255, 0); +} + +#ae_content, #ae_bgdimmer { + color: #555; + padding: 1em 1em 2em 1em; +} + +.ae_preview { + display: block; + color: white; + text-decoration: none; + padding: 0.4em; + font-size: 100%; + width: 100%; +} + +.ae_user_info { + background: #111; + overflow: hidden; + position: relative; +} + +.ae_draft_section { + padding: 0.5em; +} + +.ae_draft_logo { + font-size: 3em; + position: absolute; + opacity: 0.2; + cursor: default; +} + +.ae_name { + text-align: right; + padding: 0.2em; +} + +.ae_user_content { + padding: 0.2em +} + +#ae_user_drafts { + overflow: hidden; +} + +.ae_dEntry { + cursor: default; + padding: 0.2em; + background: rgba(255, 255, 255, 0); +} + +.ae_dEntry:hover { + background: rgba(255, 255, 255, 0.2); +} + +.ae_dEntry_date { + text-align: right; +} + +.ae_expand_btn, .ae_callapse_btn { + background: url(http://file.astropenguin.net/blog/layout-images/collapse.png) center 2.5px no-repeat; + width: 100%; + height: 10px; +} + +.ae_expand_btn { + -webkit-transform: rotate(180deg); + -moz-transform: rotate(180deg); + transform: rotate(180deg); +} + +.ae_callapse_btn { + -webkit-transform: rotate(0deg); + -moz-transform: rotate(0deg); + transform: rotate(0deg); +} + +.ae_affected_count { + color: red; +} + +/*Active draft notation*/ +.ae_dActive_bubble { + float: right; + color: yellowgreen; + text-shadow: 0 0 5px yellowgreen; + font-size: 80%; +} + +body { + margin: 0 auto; + min-width: 1200px; +} diff --git a/botanjs/src/Astro/Blog/AstroEdit/_this.js b/botanjs/src/Astro/Blog/AstroEdit/_this.js new file mode 100644 index 0000000..9e173e9 --- /dev/null +++ b/botanjs/src/Astro/Blog/AstroEdit/_this.js @@ -0,0 +1,99 @@ +(function(){ + var ns = __namespace( "Astro.Blog.AstroEdit" ); + + /** @type {System.Cycle} */ + var Cycle = __import( "System.Cycle" ); + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + /** @type {Astro.Bootstrap} */ + var Bootstrap = __import( "Astro.Bootstrap" ); + /** @type {Astro.Blog.Config} */ + var Config = __import( "Astro.Blog.Config" ); + /** @type {Astro.Blog.AstroEdit.Article} */ + var Article = __import( "Astro.Blog.AstroEdit.Article" ); + /** @type {Astro.Blog.AstroEdit.Draft} */ + var Draft = __import( "Astro.Blog.AstroEdit.Draft" ); + /** @type {Astro.Blog.AstroEdit.Tag} */ + var Tag = __import( "Astro.Blog.AstroEdit.Tag" ); + /** @type {Astro.Blog.AstroEdit.Visualizer} */ + var Visualizer = __import( "Astro.Blog.AstroEdit.Visualizer" ); + /** @type {Astro.Blog.AstroEdit.Uploader} */ + var Uploader = __import( "Astro.Blog.AstroEdit.Uploader" ); + /** @type {Astro.Blog.AstroEdit.SiteLibrary} */ + var SiteLibrary = __import( "Astro.Blog.AstroEdit.SiteLibrary" ); + + var wh, ww, cw, html, article; + + var init = function () + { + //// Component initializations + /** @type {_AstConf_.AstroEdit} */ + var a_conf = Config.get( "AstroEdit" ); + var base_path = Config.get( "BasePath" ); + + Cycle.next( + function() + { + article.load( + a_conf.article_id + , function( obj, id ) + { + window.history.replaceState( obj, "", base_path + "astroedit/" + id + "/" ); + } + ); + } + ); + + article = new Article( a_conf.paths.set_article ); + + // Article modules + new Draft( article, a_conf.paths.get_drafts ); + new Tag( article, a_conf.paths.tag_count ); + new Visualizer( + article + , Dand.id( "ae_visual_snippets" ) + , Config.get( "ServiceUri" ) + ); + + // Independent modules + new Uploader( a_conf.paths.set_file ); + new SiteLibrary( + Config.get( "BasePath" ) + , a_conf.paths.get_files + , a_conf.paths.set_file + ); + + var title = Dand.id("ae_title"); + var content = Dand.id("ae_content"); + + // content height + content.style.minHeight = String(screen.availHeight) + "px"; + + html = document.body.parentNode; + + window.onresize = adjustLayout; + + // Setting event handlers + title.onblur = content.onblur = function () { Dand.id("ae_bgdimmer").style.background = ""; }; + content.onfocus = content.onfocus = function () + { + Dand.id("ae_bgdimmer").style.background = "rgba(255, 255, 255, 0.2)"; + }; + + Dand.id( "ae_publish_btn" ).onclick = function () { article.saveAndPublish(); }; + Dand.id( "ae_preview_btn" ).onclick = function () { article.preview(); }; + Dand.id( "ae_drop_btn" ).onclick = function () { article.drop(); };; + + adjustLayout(); + }; + + var adjustLayout = function () + { + ww = html.clientWidth; + wh = html.clientHeight; + cw = ww - 300; + Dand.id("ae_body").style.width = String(cw) + "px"; + }; + + Bootstrap.regInit( init ); +})(); diff --git a/botanjs/src/Astro/Blog/Components/Bubble.css b/botanjs/src/Astro/Blog/Components/Bubble.css new file mode 100644 index 0000000..331d0e7 --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/Bubble.css @@ -0,0 +1,35 @@ +.bubble { + position: fixed; + background: white; + border-radius: 300px; + + -moz-box-shadow: 7px 7px 10px; + -webkit-box-shadow: 7px 7px 10px; + box-shadow: 7px 7px 10px; + + z-index: 98; +} + +.innerBubble { + border-radius: 300px; + position: relative; + overflow: hidden; +} + +.innerBubble:before { + content: ''; + display: inline-block; + height: 100%; + vertical-align: middle; +} + +.bInner{ + display: inline-block; + width: 100%; + + vertical-align: middle; + text-align: center; + + font-size: 1.35em; + color: white; +} diff --git a/botanjs/src/Astro/Blog/Components/Bubble.js b/botanjs/src/Astro/Blog/Components/Bubble.js new file mode 100644 index 0000000..342b1da --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/Bubble.js @@ -0,0 +1,133 @@ +(function(){ + var ns = __namespace( "Astro.Blog.Components" ); + + /** @type {System.Cycle} */ + var Cycle = __import( "System.Cycle" ); + /** @type {System.utils.EventKey} */ + var EventKey = __import( "System.utils.EventKey" ); + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + /** @type {Dandelion.IDOMElement} */ + var IDOMElement = __import( "Dandelion.IDOMElement" ); + + var Bubble = function () { + this.stage = null; + this.bubble = null; + + //// default is somewhat purple + this.bgColor = "#662D91"; + + this.blowInner = function () + { + var b_style = this.bubble.style + , s_style = this.stage.style; + + b_style.margin = "10px 10px"; + b_style.width = "150px"; + b_style.height = "150px"; + + s_style.width = "170px"; + s_style.height = "170px"; + s_style.bottom = "20px"; + s_style.right = "20px"; + }; + + this.blowOuter = function () + { + var b_style = this.bubble.style + , s_style = this.stage.style; + + b_style.margin = "100px 100px"; + + s_style.width = "200px"; + s_style.height = "200px"; + s_style.bottom = "10px"; + s_style.right = "10px"; + + Cycle.delay( this.blowInner.bind(this), 250 ); + }; + + this.Void = function () + { + this.stage.style.display = "none"; + }; + + // Set Bindings + this.init = this.init.bind(this); + this.blurp = this.blurp.bind(this); + this.pop = this.pop.bind(this); + this.setColor = this.setColor.bind(this); + }; + + var wrapc = function( aClass, elem ) + { + return Dand.wrapc( "comp " + aClass, elem ); + }; + + Bubble.prototype.init = function () + { + this.stage = wrapc( "bubble" ); + this.bubble = wrapc( "innerBubble" ); + + var b_style = this.bubble.style + , s_style = this.stage.style; + + + b_style.margin = "85px 85px"; + b_style.width = "0px"; + b_style.height = "0px"; + b_style.background = this.bgColor; + b_style.overflow = "hidden"; + + this.bubble.appendChild( + this.message = wrapc( "bInner flsf" ) + ); + + this.stage.appendChild(this.bubble); + + s_style.display = "none"; + s_style.width = "10px"; + s_style.height = "10px"; + s_style.bottom = "85px"; + s_style.right = "85px"; + + + // onClick handle to prevent persistent bubble + IDOMElement( this.stage ).addEventListener( new EventKey( "Click", this.blurp ) ); + return this.stage; + }; + + Bubble.prototype.setColor = function (color) + { + this.bubble.style.background = color; + }; + + Bubble.prototype.blurp = function () + { + var b_style = this.bubble.style + , s_style = this.stage.style; + + b_style.margin = "0 0"; + b_style.width = "0px"; + b_style.height = "0px"; + b_style.overflow = "hidden"; + + + s_style.position = "fixed"; + s_style.width = "10px"; + s_style.height = "10px"; + s_style.bottom = "85px"; + s_style.right = "85px"; + + Cycle.delay( this.Void.bind(this), 250 ); + }; + + Bubble.prototype.pop = function (message) + { + this.message.innerHTML = message; + this.stage.style.display = "block"; + Cycle.delay( this.blowOuter.bind(this), 100 ); + }; + + ns[ NS_EXPORT ]( EX_CLASS, "Bubble", Bubble ); +})(); diff --git a/botanjs/src/Astro/Blog/Components/Calendar.css b/botanjs/src/Astro/Blog/Components/Calendar.css new file mode 100644 index 0000000..69e345d --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/Calendar.css @@ -0,0 +1,67 @@ +.calendar, #timeline { + cursor: default; +} + +.calendar{ + position: absolute; + display: none; + background: white; + margin: 20px auto; + font-size: 17px; + padding: 3px; + width: 241px; + box-shadow: 3px 3px 4px black; + border: 10px solid dodgerblue; + border-collapse: collapse; + font-family: Georgia; +} + +/*Inline_Blocks*/ +.calDate, #calDays > div > span { + display:-moz-inline-block; + display:-moz-inline-box; + display:inline-block; +} +/*End_Inline_Blocks*/ + +#calDays > div > span { + background: white; + border: 0px solid; + margin: 1.71428%; + padding: 3px 0px 3px 0px; + #:100/7 - (0.24% margin); + width: 10.857%; + text-align: center; + font-size: 0.8em; +} +#calDays>div { + height: 27px; + white-space: nowrap; +} +.calDate { + width: 155px; + text-align: center; +} +.navbtn { + opacity: .5; + width: 17px; + height: 20px; +} +.navbtn:hover { + opacity: 1; +} +.onhover { + border: 3px solid !important; + margin-left: -2px !important; + margin-top: -4px !important; + vertical-align: top; + padding: 0px 1px 2px 0px; + box-shadow: 3px 3px 3px black; +} +.toNorm { +} + +#norec{color: #FF7BAC;} +#notfin{color: #3FA9F5;} +#notyet{color: #BDCCD4;} +#today{color: #7AC943;} diff --git a/botanjs/src/Astro/Blog/Components/Calendar.js b/botanjs/src/Astro/Blog/Components/Calendar.js new file mode 100644 index 0000000..cec1de2 --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/Calendar.js @@ -0,0 +1,244 @@ +(function(){ + var ns = __namespace( "Astro.Blog.Components" ); + + /** @type {System.Cycle} */ + var Cycle = __import( "System.Cycle" ); + /** @type {System.Debug} */ + var debug = __import( "System.Debug" ); + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + /** @type {Dandelion.IDOMElement} */ + var IDOMElement = __import( "Dandelion.IDOMElement" ); + /** @type {Astro.utils.Date} */ + var XDate = __import( "Astro.utils.Date" ); + + var Calendar = function () + { + this.stage = null; + this.calDate = null; + this.show = false; + this.caption = null; + this.calDays = false; + this.currentHandler = function( v ) { + debug.Info( "[Astro.Blog.Components.Calendar] " + v ); + }; + }; + + var bodyClick = function ( e ) + { + var s = e.target.getAttribute("calObj") + if(s) + { + this.stage.style.display = "none"; + this.stage.style.position = ""; + this.show = false; + } + + if( this.show && !this.istg.contains( e.target ) ) + { + this.stage.style.display = "none"; + this.stage.style.position = ""; + this.show = false; + } + }; + + var addZero = function ( num ) + { + return num < 10 + ? "0" + String(num) + : String(num) + ; + }; + + Calendar.prototype.init = function() + { + this.stage = Dand.wrapc( "astx calendar" ); + this.istg = IDOMElement( this.stage ); + this.calDate = new Date; + + IDOMElement( document.body ).addEventListener( "Click", bodyClick.bind( this ) ); + + var tr = Dand.wrap(null, "navbar") + , td = Dand.wrap("span") + , btn = Dand.wrap("a", null, "navbtn") + ; + tr.setAttribute("style", "position: relative"); + + btn.onclick = function (e) { this.nextMon(); }.bind(this); + + td.style.textAlign = "right"; + td.style.width = "100%"; + td.style.position = "absolute"; + td.style.left = "0"; + + btn.appendChild(Dand.textNode("\u25ba")); + + td.appendChild(btn); + tr.appendChild(td); + + td = Dand.wrap("span"); + btn = Dand.wrap("a", null, "navbtn"); + + btn.appendChild(Dand.textNode("\u25c4")); + + btn.onclick = function (e) { this.prevMon(); }.bind(this); + + td.style["float"] = "left"; + td.style.position = "absolute"; + + td.appendChild(btn); + tr.appendChild(td); + + caption = Dand.wrap("span", null, "calDate"); + caption.style.width = "100%"; + caption.appendChild( + Dand.textNode( + XDate.MONTH[this.calDate.getMonth()] + ", " + this.calDate.getFullYear() + ) + ); + tr.appendChild(caption); + + this.stage.appendChild(tr); + + this.stage.onselectstart = function() { return false;}; + + return this.stage; + }; + + + Calendar.prototype.pop = function ( dateObj, handler ) + { + if( typeof( dateObj ) == "string" ) + { + var p = dateObj.split(","); + if ( p.length == 3 ) + dateObj = new Date( p[2], p[1] - 1, p[0] ); + } + + this.draw( dateObj, handler ); + + this.show = false; + + this.stage.style.display = "block"; + Cycle.next( function (){ this.show = true; }.bind(this) ); + }; + + Calendar.prototype.draw = function (dateObj, handler) + { + if(!dateObj) + dateObj = new Date; + + this.calDate = dateObj; + + var mon = dateObj.getMonth() + , yr = dateObj.getFullYear() + , j = dateObj.getDay() + , dt = dateObj.getDate() + , thisDate = new Date + , thisYear = thisDate.getFullYear() + , thisMonth = thisDate.getMonth() + , thisDate = thisDate.getDate() + , thisDate = Number(String(thisYear) + addZero(thisMonth) + addZero(thisDate)) + , currHead = String(yr) + addZero(mon) + , currDate; + + ( typeof handler == "function" ) && ( this.currentHandler = handler ); + + caption.innerHTML = XDate.MONTH[this.calDate.getMonth()] + ", " + this.calDate.getFullYear(); + + if(this.calDays) + this.calDays.parentElement.removeChild(this.calDays); + this.calDays = Dand.wrap(null, "calDays"); + + var days = (mon == 1) ? (yr % 4 == 0 ? 29: 28) : XDate.CAP_MONTHS[mon] ? 30 : 31; + for (var i = 0; i < days; i ++) + { + if(j < 0) + j = 6; + if(dt - i == 1) + break; + j --; + } + + var tr = Dand.wrap(), td; + for(i = 0; i < 7; i ++) + { + td = Dand.wrap("span"); + td.appendChild( Dand.textNode( XDate.DAY_ABBR[i] ) ); + tr.appendChild(td); + } + this.calDays.appendChild(tr); + + tr = Dand.wrap(); + for(i = 0; i < j; i ++) + { + td = Dand.wrap("span"); + td.style.background = "none"; + tr.appendChild(td); + } + + i = 0; + while( i ++ < days ) + { + currDate = Number(currHead + addZero(i)); + if(j > 6) + { + j = 0; + this.calDays.appendChild(tr); + tr = Dand.wrap(); + } + + td = Dand.wrap( "span" ); + td.setAttribute( "value", i + "," + (mon + 1) + "," + yr ); + td.setAttribute( "onmouseover", "className=\"onhover\";" ); + td.setAttribute( "onmouseout", "className=\"toNorm\";" ); + // Unique identifier for body click + // to test whether choice is chosen + td.setAttribute("calObj", "1"); + + td.onclick = function ( e ) + { + this.currentHandler( e.target.getAttribute("value") ); + }.bind(this); + + if(thisDate < currDate) + { + td.setAttribute("id", "notyet"); + } + else if(thisDate > currDate) + { + td.setAttribute("id", "norec"); + /* + if(!( book[yr] && book[yr][mon + 1] && book[yr][mon + 1][i] )) { + td.setAttribute("id", "norec"); + } else if(book[yr][mon + 1][i][1]) { + td.setAttribute("id", "notfin"); + } + */ + } + else if(currDate == thisDate) + { + td.setAttribute("id", "today"); + currlabel = td; + } + td.appendChild(Dand.textNode(i)); + tr.appendChild(td); + j ++; + } + + if(j) this.calDays.appendChild(tr); + + this.stage.appendChild(this.calDays); + }; + + Calendar.prototype.prevMon = function () { + this.draw( this.calDate = new Date( this.calDate.getFullYear(), this.calDate.getMonth() - 1 ) ); + }; + + Calendar.prototype.nextMon = function () { + this.draw( this.calDate = new Date( this.calDate.getFullYear(), this.calDate.getMonth() + 1 ) ); + }; + + + ns[ NS_EXPORT ]( EX_CLASS, "Calendar", Calendar ); +})(); diff --git a/botanjs/src/Astro/Blog/Components/Comment.css b/botanjs/src/Astro/Blog/Components/Comment.css new file mode 100644 index 0000000..a23955b --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/Comment.css @@ -0,0 +1,288 @@ +.comment-stage { + width: 80%; + float: right; + padding-bottom: 1em; + position: relative; +} + +.c_body { + position: relative; + padding-left: 10px; +} + +.c_title { + padding: 1em 0.5em; +} + +.c_bsign { + margin-left: -0.47em; + padding: 0.1em 0.5em 0.1em 1em; + font-size: 2em; + color: white; + background: cornflowerblue; +} + +.uc_ntoggle { + font-family: custom-sans; + vertical-align: top; + padding: 0.2em 0em; +} +.uc_ntoggle:before { content: '..'; } +.uc_ntoggle:after { content: '!'; } + +.cr_ntoggle { + font-family: custom-sans; + + padding: 0; + margin: 0; + + position: absolute; + + width: 1.5em; + height: 1.5em; + + bottom: 0; + right: -3em; + + border-radius: 2em 2em 2em 0em; + border: 0.5em solid white; + + line-height: 1.5em !important; + + background-color: white; + /* box-shadow: 2px 2px 10px -5px black; */ +} + +.cr_ntoggle:before, .cr_ntoggle:after { + padding: 0; + border-radius: 2em; +} + +.cr_ntoggle:before { + content: '..'; + background-color: slategrey; +} + +.cr_ntoggle:after { content: '!'; } + +.c_comm { + position: relative; + left: 1.6em; + padding-right: 1.6em; +} + +.c_comm > .c_cont:after { + content: ""; + width: 0; + height: 0; + border-top: 1em solid transparent; + border-bottom: 1em solid transparent; + border-right: 1em solid white; + + position: absolute; + top: 1em; + left: -0.9em; +} + +.c_comm > .c_cont:before { + content: ""; + top: 0; + left: -2.15em; + position: absolute; + background: cornflowerblue; + width: 8px; + height: 100%; +} + + +.c_cont { + position: relative; + background-color: white; + padding: 1em; + margin-top: 1em; + border: 1px solid #D7D4C9 +} + +.c_text { + padding-bottom: 0.5em; + + word-wrap: break-word; +} + +.c_info > div:first-child, .c_info > div > a { + text-align: right; + color: #D4145A; +} + +.c_info > div:last-child { + text-align: right; + color: #AAA; +} + +.cu_stack { + /* padding 0.5 - 0.2 border width */ + margin: 0 0 -0.3em 0.3em; + position: relative; + text-align: right; + + width: 100%; +} + +.cu_stack > div { + display: inline-block; +} + +.cu_avatar { + /* Equal to the border width */ + margin: 0 0 -0.2em 0.5em; +} + +.cu_avatar > img { + border: 0.2em white solid; + box-shadow: 0px 0px 5px 0 black; + width: 64px; + height: 64px; + float: right; +} + +.reply { + margin-left: 20%; + width: 80%; +} + +.reply > .c_cont:after, .r_indicator { + content: ""; + width: 0; + height: 0; + border-left: 1em solid transparent; + border-right: 1em solid transparent; + border-bottom: 1em solid white; + + position: absolute; + top: -1em; + right: 1em; +} + +.c_relative_wrap { + position: relative; + padding: 1em; + + background: radial-gradient(circle, rgba(0, 0, 0, 0) 10px, #EEE 10px) 0px 10px, #FFF; + background-size: 20px 20px; +} + +.commentblock { + margin-top: 1em; + width: 100%; + position: relative; + #background: white; +} + +#c_submit { + background: cornflowerblue; +} + +#c_submit:hover { + background: cadetblue; +} + +.c_reply { + background: Coral; +} + +.c_reply:hover { + background: LightCoral; +} + +.c_tag { + cursor: pointer; + position: absolute; + overflow: hidden; + height: 100%; + width: 0; + right: 0; + top: 0; +} + + +.c_tag > span { + -moz-transform: rotate(90deg); + -moz-transform-origin: 50% 50%; + -webkit-transform: rotate(90deg); + -webkit-transform-origin: 50% 50%; + transform: rotate(90deg); + transform-origin: 50% 50%; + font-size: 1.5em; + display: block; + color: white; +} + +.commentInput { + width: 100%; + height: 80px; + font-size: 1.2em; + font-family: custom-sans; +} + +.c_caption { + font-size: 1.2em; + font-family: custom-sans; +} + +.c_false_input { + font-size: 0.8em; + font-size: custom-serif; + font-style: italic; + color: red; + text-align: right; + height: 0; + overflow: hidden; +} + +.nocomment { + font-size: 1.2em; + padding: 1em; + background: white; + font-family: custom-serif !important; + margin: 1em; +} + +.info_field > div{ + margin: 0.2em 0; +} + +#capcha_wrapper { + overflow: hidden; + height: 0; + +} + +#recaptcha_field { + float: right; + background: white; +} + +iframe[src="about:blank"] { + /* recaptcha about:blank page */ + display: none; +} + +.commentblock, #capcha_wrapper, #c_input_panel, .c_comm { + -webkit-transition: all 500ms cubic-bezier(0.770, 0.000, 0.175, 1.000); + -moz-transition: all 500ms cubic-bezier(0.770, 0.000, 0.175, 1.000); + -ms-transition: all 500ms cubic-bezier(0.770, 0.000, 0.175, 1.000); + -o-transition: all 500ms cubic-bezier(0.770, 0.000, 0.175, 1.000); + transition: all 500ms cubic-bezier(0.770, 0.000, 0.175, 1.000); /* easeInOutQuart */ + + -webkit-transition-timing-function: cubic-bezier(0.770, 0.000, 0.175, 1.000); + -moz-transition-timing-function: cubic-bezier(0.770, 0.000, 0.175, 1.000); + -ms-transition-timing-function: cubic-bezier(0.770, 0.000, 0.175, 1.000); + -o-transition-timing-function: cubic-bezier(0.770, 0.000, 0.175, 1.000); + transition-timing-function: cubic-bezier(0.770, 0.000, 0.175, 1.000); /* easeInOutQuart */ +} + +.c_so_sorry { + padding: 0.2em; + font-size: 0.8em; + color: coral; +} diff --git a/botanjs/src/Astro/Blog/Components/Comment.js b/botanjs/src/Astro/Blog/Components/Comment.js new file mode 100644 index 0000000..a40e386 --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/Comment.js @@ -0,0 +1,709 @@ +(function(){ + var ns = __namespace( "Astro.Blog.Components.Comment" ); + + /** @type {System.Cycle} */ + var Cycle = __import( "System.Cycle" ); + /** @type {System.Debug} */ + var debug = __import( "System.Debug" ); + /** @type {System.Cycle.Trigger} */ + var Trigger = __import( "System.Cycle.Trigger" ); + /** @type {System.utils.IKey} */ + var IKey = __import( "System.utils.IKey" ); + /** @type {System.utils.EventKey} */ + var EventKey = __import( "System.utils.EventKey" ); + /** @type {System.utils.DataKey} */ + var DataKey = __import( "System.utils.DataKey" ); + /** @type {System.utils.Perf} */ + var Perf = __import( "System.utils.Perf" ); + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + /** @type {Dandelion.IDOMElement} */ + var IDOMElement = __import( "Dandelion.IDOMElement" ); + /** @type {Astro.Bootstrap} */ + var Bootstrap = __import( "Astro.Bootstrap" ); + /** @type {Astro.Blog.Config} */ + var Conf = __import( "Astro.Blog.Config" ); + /** @type {Astro.Blog.Components.Bubble} */ + var Bubble = __import( "Astro.Blog.Components.Bubble" ); + + var postData = __import( "System.Net.postData" ); + + /** @type {_3rdParty_.Recaptcha} */ + var Recaptcha; + + /** @type {_AstConf_.UserInfo} */ + var currentUser = Conf.get( "UserInfo" ); + /** @type {_AstConf_.Comment} */ + var Config = Conf.get( "Comment" ); + /** @type {_AstConf_.Article} */ + var article = Conf.get( "Article" ); + + /*{{{ Validation Methods */ + var v_match = function( str, regEx ) + { + // Optional string is empty + if( !str ) return true; + // Not empty, validate + if( str.match( regEx ) != null ) return str; + + return false; + }; + + var validateMail = function ( str ) + { + return v_match( str, /^[\_]*([a-z0-9]+(\.|\_*)?)+@([a-z][a-z0-9\-]+(\.|\-*\.))+[a-z]{2,6}$/ ); + }; + + var validateURL = function ( str ) + { + return v_match( str, /^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/ ); + }; + /* End Validation Methods}}}*/ + + var wrapc = Dand.wrapc; + + var init = function () + { + // TODO: should add controls to be able to remove comments + var contentHaveText = false + , nameHaveText = false + , fieldReady = false + , releaseReplyLock + , captcha_wrapper + , submit_button + , cBubble + , button + , cHeight = 0 + , elmH = "1.2em" + + , cp = Dand.id( "c_input_panel" ) + , contentField = Dand.id( "content_field" ) + , nameField = Dand.id( "name_field" ) + , c_body = Dand.id( "comment_body" ) + + // If nameField exists, we assume logged in + , loggedIn = !nameField + + + , contentHadHaveText = false + , commentInput = function () + { + // trim whitespaces + contentHaveText = contentField.value.trim(); + if( contentHaveText != contentHadHaveText ) { + fieldReadyTrigger(); + contentHadHaveText = contentHaveText; + } + } + + , nameHadHaveText = false + , nameInput = function () + { + // trim whitespaces + nameHaveText = nameField.value.trim(); + if( nameHadHaveText != nameHaveText ) { + fieldReadyTrigger(); + nameHadHaveText = nameHaveText; + } + } + + + , doReply = function () + { + var c_reply = this; + // This will ensure capcha_wrapper is set + fieldReadyTrigger(); + // Set comment id + submit_button.setAttribute( new DataKey( "cid", c_reply.getAttribute( "value" ) ) ); + + // Close reply indicator + Dand.id("ri_switch").style.top = "0"; + + // If this button is not that button + button && ( c_reply != button ) && releaseReplyButton(); + + + // Lock reply button + c_reply.setAttribute("locked", "1"); + c_reply.onclick = null; + + c_reply.style.cursor = "default"; + c_reply.style.background = "Crimson"; + c_reply.style.width = "1.2em"; + c_reply.style.right = "-1.2em"; + + // Configure release lock + button = c_reply; + + var rf = Dand.id( "recaptcha_field" ); + if( rf && rf.hasChildNodes() ) + { + // if capcha opened + closeCaptcha(); + hideSubmit(); + Cycle.delay( function() { + closeInputPanel( reviveInputpanel.bind( c_reply.parentNode.parentNode ) ) + }, 500); + } + else + { + Cycle.delay( function() { + closeInputPanel( reviveInputpanel.bind( c_reply.parentNode.parentNode ) ) + }, 250); + } + } + + , releaseReplyButton = function () + { + button.removeAttribute("locked"); + button.onclick = doReply.bind(button); + button.style.cursor + = button.style.background + = button.style.width + = button.style.right + = ""; + } + + , fieldReadyTrigger = loggedIn + ? /* Overload */ function () + { + // Get wrapper + captcha_wrapper || (captcha_wrapper = Dand.id( "capcha_wrapper", true )); + submit_button || ( submit_button = Dand.id( "c_submit", true ) ); + if(contentHaveText) + { + // show submit button + showSubmit(); + fieldReady = true; + } + else + { + // hide submit button + hideSubmit(); + fieldReady = false; + } + } + : /* Overload */ function () + { + captcha_wrapper || (captcha_wrapper = Dand.id( "capcha_wrapper", true )); + submit_button || ( submit_button = Dand.id( "c_submit", true ) ); + // Create capcha + if(!fieldReady && contentHaveText && nameHaveText) + { + createCaptcha(); + // show submit button + showSubmit(); + fieldReady = true; + } + else if(!(contentHaveText || nameHaveText)) + { + // hide submit button + hideSubmit(); + fieldReady = false; + } + + } + + , submitComment = loggedIn + ? /* Overload */ function () + { + // Postdata + var p = { + "article_id": article.id + , "name": currentUser.name + , "website": currentUser.website + , "avatar": currentUser.avatar + } + // pass-through obj + , comment_id = submit_button.getDAttribute( "cid" ); + + p.article_id = article.id; + // Set comment id if available + comment_id && ( p["comment_id"] = comment_id ); + hideSubmit(); + + if( getFieldsValidated(p) ) + { + popBubble(); + // Post the data, bind obj to Handler + postData( Config.processor, p, commentSuccess.bind(p), commentFailed ); + } + else + { + Cycle.delay( showSubmit, 1500 ); + } + } + : /* Overload */ function () + { + var p = { "article_id": article.id } + , comment_id = submit_button.getDAttribute( "cid" ); + + // Set comment id if available + comment_id && ( p["comment_id"] = comment_id ); + hideSubmit(); + + if( getFieldsValidated( p ) ) + { + popBubble(); + captcha_wrapper.readOnly = true; + + closeCaptcha(); + // Post the data, bind obj to Handler + postData( Config.processor, p, commentSuccess.bind(p), commentFailed ); + + } + else + { + Cycle.delay( showSubmit, 1500 ); + } + } + + , commentSuccess = function ( obj ) + { + // Pass Color = Green + cBubble.setColor("YellowGreen"); + + // Popup Success message + cBubble.pop("Success"); + + // blurp after 1 sec + Cycle.delay( function (){ cBubble.blurp(); }, 1500 ); + + generateCommentStack( this, obj ); + } + + // Input panel control + , closeInputPanel = function (handler) { + cHeight = cp.clientHeight; + + cp.style.transition = "all 0s"; + + cp.style.height = cHeight + "px"; + cp.style.overflow = "hidden"; + + // Delay for 10 millisec for establishing transition properties + Cycle.next(function() { + this.style.transition = ""; + }.bind(cp)); + + Trigger.transition(cp.style, "", function() + { + cp.style.padding = "0"; + cp.style.height = "0"; + }); + + // After transition finished, remove input panel + Trigger.height(cp, 0, function() + { + cp.parentNode.removeChild(cp); + // Pass panel to handler + if(handler) handler(); + }); + } + + , openInputPanel = function () + { + cp.style.padding = ""; + cp.style.height = cHeight + "px"; + + // Delay for 500 millisec waiting for transition finished + Cycle.delay(function() + { + cp.style.transition = "all 0s"; + cp.style.height = ""; + cp.style.overflow = ""; + + Dand.id("ri_switch").style.top = ""; + + fieldReady = false; + fieldReadyTrigger(); + }, 500); + } + + + , reviveInputpanel = function () + { + this.appendChild(cp); + Cycle.next(openInputPanel); + } + + + + // Comments submission and handling + + , commentFailed = function (obj) + { + // Handle error here to prevent accidental catch by caller + try + { + if(obj != null) + { + if(obj.reload) + { + // reload the recaptcha + createCaptcha(); + Cycle.delay(showSubmit, 1500); + + // Wrong answer. + var f = Dand.id("false_capcha"); + Cycle.delay( function() + { + this.innerHTML = "Wrong answer, please re-enter."; + this.style.height = "1.2em"; + }.bind(f), 500 ); + + Cycle.delay(function (){cBubble.blurp();}, 500); + } + else + { + // Reload not needed, serious error had occurred + Cycle.delay(function (){cBubble.blurp();}, 500); + Cycle.delay(function () + { + cBubble.setColor("red"); + cBubble.pop("Server error"); + }, 1000); + + } + } + else + { + // reload the recaptcha + createCaptcha(); + Cycle.delay(showSubmit, 1500); + + Cycle.delay(function (){cBubble.blurp();}, 500); + Cycle.delay(function () + { + cBubble.setColor("red"); + cBubble.pop("Cannot connect"); + }, 1000); + } + } + catch(e) + { + debug.Error(e); + } + } + + , submitKey = new EventKey("Click", submitComment) + // Enter key + , captchaKey = new EventKey("KeyDown", function(e) { if(e.keyCode == 13) submitComment(); }) + + + , _showSubmit = function () + { + // prevent multiple prop assign + if( !submit_button.hasListener( submitKey ) ) + { + submit_button.style.width = "1.2em"; + submit_button.style.right = "-1.2em"; + submit_button.style.cursor = "pointer"; + } + submit_button.addEventListener( submitKey ); + } + + , _hideSubmit = function () + { + // prevent multiple prop assign + if( submit_button.hasListener( submitKey ) ) + { + submit_button.style.cursor = "default"; + submit_button.style.width = ""; + submit_button.style.right = ""; + } + submit_button.removeEventListener( submitKey ); + } + + , showSubmit = loggedIn + ? /* Overload */ _showSubmit + : /* Overload */ function () + { + _showSubmit(); + captcha_wrapper.addEventListener(captchaKey); + } + , hideSubmit = loggedIn + ? /* Overload */ _hideSubmit + : /* Overload */ function () + { + _hideSubmit(); + captcha_wrapper.removeEventListener(captchaKey); + } + + + , generateCommentStack = function (rObj, obj) + { + + var + // Hold for transitions + c_ind, c_cont, cpole + // The info stack + , _c_info = wrapc("c_info", + [ + wrapc("fls", rObj.website ? Dand.wrapne( "a", rObj.name, IKey.quickDef( "target", "_blank", "href", rObj.website ) ) : rObj.name ) + , wrapc( "flsf", obj.time ) + ]) + // loggedIn Overload + , c_info = loggedIn + ? wrapc("cu_stack", [ _c_info + , Dand.textNode(" ") + , wrapc("cu_avatar" + , Dand.wrapna( "img", IKey.quickDef( "src", rObj.avatar, "alt", "avatar" ) ) + )] + ) + : _c_info + // Generate comment stack + , c_stack = rObj.comment_id + // Reply Structure + ? wrapc("reply", wrapc("c_cont", [ c_ind = wrapc("r_indicator") , wrapc("c_text", rObj.content) , c_info ])) + : wrapc("c_comm", + [ + c_ind = wrapc("c_indicator") + , c_cont = wrapc("c_cont", [ cpole = wrapc("cpole") , wrapc("c_text", rObj.content) , c_info ]) + ] + ) + ; + + // Remove transition properties + c_stack.style.transition = "all 0s"; + // Close Input panel + closeInputPanel( null ); + + // Remove false_fields + for(var i in fields) { + i = Dand.id("false_" + fields[i]); + i.parentNode.removeChild(i); + } + c_stack.style.opacity = 0; + cp.parentNode.insertBefore( c_stack, cp ); + + c_stack.style.marginTop = ( -c_stack.clientHeight ) + "px"; + + // if nocomment notice exist, remove it + if( i = Dand.id("nocomment") ) + { + i.style.transition = "all 0s"; + i.style.width = "658px"; + i.style.height = "22px"; + i.style.overflow = "hidden"; + // transition + Cycle.next(function() + { + this.style.transition = ""; + this.style.margin = "0"; + this.style.width = "0"; + this.style.padding = "0"; + this.style.height = "0"; + }.bind(i)); + // Pending remove + Trigger.height(i, 0, function(){ this.parentNode.removeChild(this); }.bind(i)); + } + + // Delay for 10 millisec for establishing transition properties + Cycle.next( function() { this.style.transition = ""; }.bind( c_stack ) ); + + Cycle.delay(function() + { + this.style.marginTop = ""; + this.style.opacity = 1; + }.bind(c_stack), 600); + } + + //// Captcha + , createCaptcha = loggedIn + ? function() {} + : function () + { + // Remove capcha + new IDOMElement().lootChildren( Dand.id( "recaptcha_field" ) ); + Recaptcha.render( "recaptcha_field", { + "theme": "light" + , "sitekey": Config.siteKey + } ); + + openCaptcha(); + } + + , openCaptcha = loggedIn + ? function() {} + :function () + { + var rf = Dand.id( "recaptcha_field" ); + + var k = function () { + return ( 0 < this.a.clientHeight ); + }.bind({ a: rf }); + + Trigger.register( + k , function() { + captcha_wrapper.style.height = rf.clientHeight + "px"; + } + , 50 ); + } + + , closeCaptcha = loggedIn + ? function() {} + :function () + { + captcha_wrapper.style.height = "0"; + } + + + + // Validation + , fields = loggedIn ? ["content"] : ["content", "name", "email", "website"] + , _getFieldsValidated = function (obj) + { + var name, field, falsefield, f; + + for(var i in fields) + { + name = fields[i]; + field = name + "_field"; + falsefield = "false_" + name; + + f = Dand.id( falsefield ); + f.style.height = 0; + switch(name) + { + case "name": + if(!( obj[name] = Dand.id(field).value.trim() )) + Cycle.delay( function() { this.style.height = elmH; }.bind(f), 500 ); + break; + case "content": + if(!( obj[name] = Dand.id(field).value.trim() )) + Cycle.delay( function() { this.style.height = elmH; }.bind(f), 500 ); + break; + case "website": + if(!( obj[name] = validateURL( Dand.id(field).value.trim() ))) + { + obj[name] = false; + Cycle.delay( function() { this.style.height = elmH; }.bind(f), 500 ); + } + else + { + if(obj[name] == true) + delete obj[name] + } + break; + case "email": + if(!( obj[name] = validateMail( Dand.id(field).value.trim() ) )) + { + obj[name] = false; + Cycle.delay( function() { this.style.height = elmH; }.bind(f), 500 ); + } + else + { + if(obj[name] == true) + delete obj[name] + } + break; + } + } + + for(var i in obj) if(!obj[i]) return false; + + return true; + } + + , getFieldsValidated = loggedIn + ? /* Overload */ _getFieldsValidated + : /* Overload */ function(obj) + { + var f = Dand.id("false_capcha"); + f.style.height = 0; + // get the response field + if(!( obj["recaptcha_response_field"] = Recaptcha.getResponse().trim() )) + { + Cycle.delay( + function() + { + this.innerHTML = "You need to prove that you are a human"; + this.style.height = elmH; + }.bind(f) + , 500 ); + } + // get the challenge field + // else obj["recaptcha_challenge_field"] = Recaptcha.get_challenge(); + + return _getFieldsValidated(obj); + } + + , showReplyButton = function () + { + this.style.width = "1.2em"; + this.style.right = "-1.2em"; + } + + , hideReplyButton = function () + { + if(!this.getAttribute("locked")) + this.style.width = this.style.right = ""; + } + + , popBubble = function () + { + if(cBubble == null) + { + // create a new bubble + cBubble = new Bubble(); + document.body.appendChild( cBubble.init() ); + // pop message + cBubble.setColor( "cornflowerblue" ); + Cycle.next( function () { cBubble.pop("Submitting"); } ); + } + } + ; + + if( !loggedIn ) + { + IDOMElement( nameField ).addEventListener( "Input", nameInput ); + } + + IDOMElement( contentField ).addEventListener( "Input", commentInput ); + + var l = c_body.childNodes, c_id; + + for( var i in l ) + { + if( l[i].nodeType == 1 + && ( c_id = IDOMElement( l[i] ).getDAttribute("value") ) + ) + { + var reply_button = Dand.id("c_reply_" + c_id); + reply_button.onclick = doReply.bind(reply_button); + + l[i].onmouseover = showReplyButton.bind(reply_button); + l[i].onmouseout = hideReplyButton.bind(reply_button); + } + } + + var stage = c_body.parentNode + BotanJS.addEventListener( "Responsive" + /** e @type {Astro.Blog.Events.Responsive} */ + , function( e ) { + e.data.ratio < 1 + ? stage.style.width = "100%" + : stage.style.width = "" + ; + } + ); + + if( !loggedIn ) + { + var reUUID = Perf.uuid; + Cycle.perma( + reUUID, function() + { + if( Recaptcha = window["grecaptcha"] ) + { + Cycle.permaRemove( reUUID ); + debug.Info( "Recaptcha instance is up" ); + } + } , 500 + ); + } + }; + + Bootstrap.regInit( init ); +})(); diff --git a/botanjs/src/Astro/Blog/Components/ControlPanel.css b/botanjs/src/Astro/Blog/Components/ControlPanel.css new file mode 100644 index 0000000..3a4313f --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/ControlPanel.css @@ -0,0 +1,50 @@ +.control_panel { + height: 100%; + margin-top: 0.2em; +} + +.control_panel > a { + display: inline-block; + position: relative; + overflow: hidden; + + width: 80px; + height: 80px; +} + +.control_panel > a:after { + content: attr(data-desc); + + font-family: custom-sans; + + background-color: rgba(0, 0, 0, 0.6); + color: white; + + position: absolute; + + width: 100%; + + padding: 0 0.2em; + + left: 0; + bottom: 0; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +.control_panel > a > span { + padding: 0.2em 0.5em; + background-color: orange; + color: white; +} + +.control_panel > div { + font-size: 0.8em; + font-family: custom-sans; +} + +.control_panel > div > a { + color: #222; +} diff --git a/botanjs/src/Astro/Blog/Components/ControlPanel.js b/botanjs/src/Astro/Blog/Components/ControlPanel.js new file mode 100644 index 0000000..b82128f --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/ControlPanel.js @@ -0,0 +1 @@ +// __namespace( "Astro.Blog.Components.ControlPanel" ); diff --git a/botanjs/src/Astro/Blog/Components/CrowdTag.css b/botanjs/src/Astro/Blog/Components/CrowdTag.css new file mode 100644 index 0000000..619509d --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/CrowdTag.css @@ -0,0 +1,6 @@ +.tags > a { + color: saddlebrown; + font-family: custom-sans; + padding: 0.2em; + float: left; +} diff --git a/botanjs/src/Astro/Blog/Components/CrowdTag.js b/botanjs/src/Astro/Blog/Components/CrowdTag.js new file mode 100644 index 0000000..355fd5e --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/CrowdTag.js @@ -0,0 +1 @@ +// __namespace( "Astro.Blog.Components.CrowdTag" ); diff --git a/botanjs/src/Astro/Blog/Components/Entry/Block.css b/botanjs/src/Astro/Blog/Components/Entry/Block.css new file mode 100644 index 0000000..588da7c --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/Entry/Block.css @@ -0,0 +1,149 @@ +.bk_block { + float: left; + + width: 225px; + height: 325px; + + margin: 1em; + + position: relative; + overflow: hidden; + + color: #666; + background-color: white; + border: 1px solid #D4D7C9; + + display: block; +} + +.bk_block:hover { + text-decoration: none; +} + +.bk_SlideWrapper { + position: absolute; + overflow: hidden; + top: 0.5em; + width: 100%; + height: 100%; +} + +.bk_date { + font-size: 0.8em; + text-align: right; +} + +.bk_title { + font-size: 1.2em; + max-height: 2.4em; + overflow: hidden; + text-overflow: ellipsis; + color: #444; +} + +.bk_content { + text-overflow: ellipsis; + overflow: hidden; +} + +.bk_author { + color: crimson; + text-align: right; +} + +.bk_cCount { + position: absolute; + bottom: 1em; + left: 0.5em; + + font-size: 0.8em; + font-family: sans-serif; + color: orangered; +} + + +.bk_blockSlide { + position: absolute; + width: 100%; + height: 150%; + + top: 0; +} + +.bk_blockSlide:after { + content: attr(data-content); + + position: absolute; + + top: 100%; + + width: 100%; + height: 50%; + + padding: 0 0.5em; + + font-size: 0.8em; + font-family: custom-serif; + + color: #EEE; + background: purple; + + overflow: hidden; + text-overflow: ellipsis; + + -webkit-box-shadow: inset 0px 15px 15px -15px black; + -moz-box-sizing: inset 0px 15px 15px -15px black; + box-shadow: inset 0px 15px 15px -15px black; + + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + + -webkit-transition: all 500ms cubic-bezier(0.215, 0.610, 0.355, 1.000); + -moz-transition: all 500ms cubic-bezier(0.215, 0.610, 0.355, 1.000); + -ms-transition: all 500ms cubic-bezier(0.215, 0.610, 0.355, 1.000); + -o-transition: all 500ms cubic-bezier(0.215, 0.610, 0.355, 1.000); + transition: all 500ms cubic-bezier(0.215, 0.610, 0.355, 1.000); /* easeOutCubic */ + + -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + -moz-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + -ms-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + -o-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); /* easeOutCubic */ +} + +.bk_blockSlide:hover:after { + top: 62.5%; + padding: 0.5em; +} + +.bk_blockSlide:hover { + top: -50%; +} + +.bk_blockFront { + position: absolute; + background: white; + + width: 100%; + height: 100%; +} + +.bk_blockWrapper { + position: relative; + padding: 0 0.5em; +} + +.bk_banner { + width: 50%; + padding: 50%; + + background-image: url(http://file.astropenguin.net/blog/layout-images/featured.png); + background-position: center; + background-repeat: no-repeat; + background-color: white; + + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} diff --git a/botanjs/src/Astro/Blog/Components/Entry/Block.js b/botanjs/src/Astro/Blog/Components/Entry/Block.js new file mode 100644 index 0000000..e406e74 --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/Entry/Block.js @@ -0,0 +1 @@ +// __namespace( "Astro.Blog.Components.Entry.Block" ); diff --git a/botanjs/src/Astro/Blog/Components/Entry/Blog.css b/botanjs/src/Astro/Blog/Components/Entry/Blog.css new file mode 100644 index 0000000..8fc6172 --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/Entry/Blog.css @@ -0,0 +1,104 @@ +.b_entry { + background-color: #FAFAFA; + /* box-shadow: 0 0 8px -2px black; */ + border: 1px solid #D7D4C9; + + word-wrap: break-word; + + position: relative; + + margin-top: 0; + padding: 1em; +} + +.b_title { + font-family: custom-serif; + font-size: 2.5em; + margin-bottom: 0.25em; + color: #444; +} + +.b_avartar { + width: 90px; + height: 90px; + + margin: 0 0 0.5em 0.5em; + + float: right; + + -moz-box-shadow: 0 0 5px 0 black; + -webkit-box-shadow: 0 0 5px 0 black; + box-shadow: 0 0 5px 0 black; + + background-color: white; + background-position: center; + background-repeat: no-repeat; +} + +.b_bodyWrapper { + font-family: custom-sans; + color: #555; + min-height: 155px; +} + +.b_button { + position: relative; + + font-family: custom-sans; + font-size: 1em; + + padding: 0.2em 0.5em; + margin: 0.5em 0.2em; + + background-color: grey; + color: white; + + cursor: default; + + float: right; +} + +.b_delete { + background-color: crimson; +} + +.b_publish { background-color: slategrey; } +.b_publish:before { content: 'Publish'; background-color: purple; } +.b_publish:after { content: 'Unpublish'; background-color: orangered; } + +.b_notify { background-color: slategrey; } +.b_notify:before { content: 'Follow'; } +.b_notify:after { content: 'Unfollow'; } + +.b_edit { + background-color: yellowgreen; +} + +.b_preview { + background-color: orangered; +} + +.b_author { + color: purple; + text-align: right; +} + +.b_date, .b_mdate { + text-align: right; +} + +.b_date { + font-family: custom-serif; +} + +.b_mdate { + font-style: italic; + font-family: custom-sans; + font-size: 0.8em; + opacity: 0.5; +} + +.b_tags > a { + font-size: 1em; + color: #76400C; +} diff --git a/botanjs/src/Astro/Blog/Components/Entry/Blog.js b/botanjs/src/Astro/Blog/Components/Entry/Blog.js new file mode 100644 index 0000000..8f10fbc --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/Entry/Blog.js @@ -0,0 +1 @@ +// __namespace( "Astro.Blog.Components.Entry.Blog" ); diff --git a/botanjs/src/Astro/Blog/Components/Entry/Home.css b/botanjs/src/Astro/Blog/Components/Entry/Home.css new file mode 100644 index 0000000..3bb22a9 --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/Entry/Home.css @@ -0,0 +1,129 @@ +.h_title { + font-size: 2.5em; + color: #444; +} + +.home_entry { + position: relative; + margin: 1em 0; +} + +.h_info { + position: absolute; + height: 100%; + width: 7em; + text-align: right; +} + + +.h_body { + margin-left: 7em; + margin-right: 0.5em; +} + +.h_bodyWrapper { + border: 1px solid #D4D7C9; + background-color: #FAFAFA; + color: #777; + + padding: 1em 1em 2em 1em; + + min-height: 155px; + /* Same as image size */ + max-width: 600px; +} + +.h_datetime { + right: 0; + bottom: 0.95em; +} + +.h_auth_com { + padding-top: 0.5em; + + font-family: Calibri; + color: #D4145A; +} + + +.h_avatarWrapper { + display: block; + + width: 80px; + height: 80px; +} + +.h_avatar, .a_avatarWrapper { + width: 80px; + height: 80px; + margin: 0 auto; +} + +.h_avatar { + + border-radius: 80px; + + background-color: #FAFAFA; + background-size: 50px 50px; + background-repeat: no-repeat; + background-position: center; + + -moz-box-shadow: 2px 2px 5px 0 black; + -webkit-box-shadow: 2px 2px 5px 0 black; + box-shadow: 2px 2px 5px 0 black; +} + +.h_avatar:hover { + width: 70px; + height: 70px; + border-radius: 70px; + + margin-top: 5px; + + background-size: 60px 60px; +} + +.h_infoWrapper { + padding: 0.5em; +} + +.h_cCount { + font-family: sans-serif; + color: cornflowerblue; + font-size: 80%; +} + +.h_title { + font-size: 2.5em; + color: #444; +} + +.h_title, .h_desc { + overflow: hidden; + text-overflow: ellipsis; +} + +.h_read_full { + position: absolute; + bottom: 0.5em; + right: 1.5em; + + font-size: 0.8em; + text-align: right; + padding: 0.5em 0 0.5em 0; + color: #F15A24; +} + +.h_read_full_a { + color: #F15A24; +} + +.h_img { + width: 100%; + max-height: 350px; + overflow: hidden; +} + +.h_img > img { + max-width: 100%; +} diff --git a/botanjs/src/Astro/Blog/Components/Entry/Home.js b/botanjs/src/Astro/Blog/Components/Entry/Home.js new file mode 100644 index 0000000..b171548 --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/Entry/Home.js @@ -0,0 +1 @@ +// __namespace( "Astro.Blog.Components.Entry.Home" ); diff --git a/botanjs/src/Astro/Blog/Components/Entry/List.css b/botanjs/src/Astro/Blog/Components/Entry/List.css new file mode 100644 index 0000000..24a4804 --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/Entry/List.css @@ -0,0 +1,67 @@ +.list_entry { + position: relative; + + margin: 1em 0; + padding: 0.5em; + + background-color: #FAFAFA; + border: 1px solid #D4D7C9; +} + +.caption { + font-size: 2.5em; + color: #444; +} + +.title { + font-size: 1.5em; + color: #555; +} + +.content { + color: #777; +} + +.tags { + padding: 0.5em 0; +} + +.flag { + font-family: custom-sans; + font-size: 0.8em; + + padding: 0 0.5em; + margin: 0 0 0 0.2em; + + float: right; + cursor: default; +} + +.flag.archived { color: white; background: #888; } +.flag.archived:hover { background: #666; } + +.flag.featured { color: white; background: coral; } +.flag.featured:hover { background: orangered; } + +.tag { + color: #76400C; + + padding: 0.2em 0.5em; + + font-family: custom-sans; +} + +.mdate, .author { + text-align: right; +} + +.author { + color: crimson; +} + +.mdate { + color: #AAA; + font-size: 0.8em; + font-family: custom-sans; +} + diff --git a/botanjs/src/Astro/Blog/Components/Entry/List.js b/botanjs/src/Astro/Blog/Components/Entry/List.js new file mode 100644 index 0000000..69d54bf --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/Entry/List.js @@ -0,0 +1 @@ +// __namespace( "Astro.Blog.Components.Entry.List" ); diff --git a/botanjs/src/Astro/Blog/Components/Entry/Mega.css b/botanjs/src/Astro/Blog/Components/Entry/Mega.css new file mode 100644 index 0000000..3140bce --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/Entry/Mega.css @@ -0,0 +1,139 @@ +.m_title { + font-size: 2.5em; + color: #444; +} + +.m_more { + color: #76400C; +} + +.mega_entry span { + display: block; +} + +.mega_entry { + border: 6px solid white; + background: white; + color: black; + + position: relative; + margin: 1em; + + display: block; + + word-wrap: break-word; + + box-shadow: 0 0 0 1px #D4D7C9; +} + +.mega_entry:hover { + text-decoration: none; +} + +.mega_entry:after { + content: attr(data-content); + + width: 100%; + height: 0; + + top: 100%; + + position: absolute; + overflow: hidden; + + color: white; + background: rgba(0, 0, 0, 0.65); + + font-family: custom-serif; + + padding: 0 0.5em; + + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + + -webkit-transition: all 300ms cubic-bezier(0.215, 0.610, 0.355, 1.000); + -moz-transition: all 300ms cubic-bezier(0.215, 0.610, 0.355, 1.000); + -ms-transition: all 300ms cubic-bezier(0.215, 0.610, 0.355, 1.000); + -o-transition: all 300ms cubic-bezier(0.215, 0.610, 0.355, 1.000); + transition: all 300ms cubic-bezier(0.215, 0.610, 0.355, 1.000); /* easeOutCubic */ + + -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + -moz-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + -ms-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + -o-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); /* easeOutCubic */ +} + +.mega_entry:focus:after, .mega_entry:hover:after { + top: 50%; + height: 50%; + padding: 0.5em; +} + +.mega_entry > #noteTag { + background: black; +} + +.noteTag { + color: white; + padding: 0.2em; + overflow: hidden; + + -moz-box-shadow: 0 2px 2px 0 black; + -webkit-box-shadow: 0 2px 2px 0 black; + box-shadow: 0 2px 2px 0 black; + + position: absolute; + background: slategrey; + right: -6px; + top: 10px; +} + +.mega_entry > .cCont { + position: relative; + + height: 130px; + background-position: center top; + background-repeat: no-repeat; + background-color: #EEE; + + background-image: url('http://file.astropenguin.net/blog/layout-images/archived.png'); +} + +.mega_entry > .cCont:before { + content: attr(data-content); + position: absolute; + + line-height: 100%; + font-size: 2.5em; + + padding: 0.1em; + + text-shadow: 2px 2px 8px black; + color: white; + + width: 100%; + height: 100%; + + box-sizing: border-box; + + background-color: rgba( 0, 0, 0, 0.2 ); +} + +.cDate { + padding: 0.2em; + font-size: 0.8em; +} +.cEOF { + height: 10px; +} + + +.Sun { background: #FF1D25; } +.Mon { background: #662D91; } +.Tue { background: #3FA9F5; } +.Wed { background: #7AC943; } +.Thu { background: #FF7BAC; } +.Fri { background: #603813; } +.Sat { background: #FF931E; } diff --git a/botanjs/src/Astro/Blog/Components/Entry/Mega.js b/botanjs/src/Astro/Blog/Components/Entry/Mega.js new file mode 100644 index 0000000..3c902f5 --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/Entry/Mega.js @@ -0,0 +1 @@ +// __namespace( "Astro.Blog.Components.Entry.Mega" ); diff --git a/botanjs/src/Astro/Blog/Components/Entry/Tag.css b/botanjs/src/Astro/Blog/Components/Entry/Tag.css new file mode 100644 index 0000000..ba8da11 --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/Entry/Tag.css @@ -0,0 +1,63 @@ +.t_title { + font-size: 2.5em; + color: #444; +} + +.ts_title { + font-size: 1.5em; + color: #555; +} + +ul.n-archive > li { + position: relative; + padding: 0.5em 0.5em 0.1em; + margin: 0.5em; + border-right: 1px solid transparent; +} + +ul.n-archive > li:hover { + border-right: 1px solid #555; +} + +ul.n-archive a { + width: 100%; + + display: inline-block; +} + +ul.n-archive a:before { + content: attr(data-value); + + margin-right: 0.5em; + padding: 0.5em; + + float: left; + width: 1.4em; + text-align: center; + + color: white; + font-family: custom-sans; +} + +ul.n-archive a:hover:before { + text-decoration: underline; +} + +ul.n-archive a:hover { + text-decoration: none; +} + +ul.n-archive a.Sun:before { color: rgba(255, 29, 37, 1); } +ul.n-archive a.Mon:before { color: rgba(102, 45, 145, 1); } +ul.n-archive a.Tue:before { color: rgba(63, 169, 245, 1); } +ul.n-archive a.Wed:before { color: rgba(122, 201, 67, 1); } +ul.n-archive a.Thu:before { color: rgba(255, 123, 172, 1); } +ul.n-archive a.Fri:before { color: rgba(96, 56, 19, 1); } +ul.n-archive a.Sat:before { color: rgba(255, 147, 30, 1); } +ul.n-archive a.Sun:hover:before { color: white; background: rgba(255, 29, 37, 1); } +ul.n-archive a.Mon:hover:before { color: white; background: rgba(102, 45, 145, 1); } +ul.n-archive a.Tue:hover:before { color: white; background: rgba(63, 169, 245, 1); } +ul.n-archive a.Wed:hover:before { color: white; background: rgba(122, 201, 67, 1); } +ul.n-archive a.Thu:hover:before { color: white; background: rgba(255, 123, 172, 1); } +ul.n-archive a.Fri:hover:before { color: white; background: rgba(96, 56, 19, 1); } +ul.n-archive a.Sat:hover:before { color: white; background: rgba(255, 147, 30, 1); } diff --git a/botanjs/src/Astro/Blog/Components/Entry/Tag.js b/botanjs/src/Astro/Blog/Components/Entry/Tag.js new file mode 100644 index 0000000..6a2b284 --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/Entry/Tag.js @@ -0,0 +1 @@ +// __namespace( "Astro.Blog.Components.Entry.Tag" ); diff --git a/botanjs/src/Astro/Blog/Components/Notification.css b/botanjs/src/Astro/Blog/Components/Notification.css new file mode 100644 index 0000000..1538844 --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/Notification.css @@ -0,0 +1,155 @@ +.notifications { + position: relative; + cursor: default; +} + +.nt_body { + position: absolute; + + top: 0; + left: -300px; + + max-width: 300px; + max-height: 600px; + + text-align: left; + + display: none; +} + +.nt_body > div { + float: right; +} + +.nt_button { + text-align: left; + display: block; + + margin: 0.2em 0; + + color: white; + background: #444; +} + +.nt_button:before { + content: attr(data-count); + display: inline-block; + + padding: 0 0.5em; + line-height: 1.5em; + + background-color: royalblue; +} + +.nt_button:before, .nt_switch:before { + -webkit-transition: all 500ms cubic-bezier(0.215, 0.610, 0.355, 1.000); + -moz-transition: all 500ms cubic-bezier(0.215, 0.610, 0.355, 1.000); + -ms-transition: all 500ms cubic-bezier(0.215, 0.610, 0.355, 1.000); + -o-transition: all 500ms cubic-bezier(0.215, 0.610, 0.355, 1.000); + transition: all 500ms cubic-bezier(0.215, 0.610, 0.355, 1.000); /* easeOutCubic */ + + -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + -moz-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + -ms-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + -o-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); /* easeOutCubic */ +} + +.nt_button:hover:before { + background: dodgerblue; + +} + +.nt_arrow { + border-top: 0.8em solid transparent; + border-left: 1em solid #444; + border-bottom: 0.8em solid transparent; +} + +.nt_container { + min-width: 300px; + + padding: 0.5em; + background: #444; + + margin-right: 0.5em; + margin-top: -1.6em; +} + +.nt_date { + text-align: right; +} + +.nt_container > ul { + white-space: nowrap; + + overflow: hidden; + text-overflow: ellipsis; + + color: white; +} + +.nt_container > ul > li { + padding: 0.25em 0.5em; + color: white; + text-decoration: none; +} + +.nt_container > ul > li:hover { + background-color: orangered; +} + +.nt_icon_settings { + background-image: url(http://file.astropenguin.net/blog/layout-images/settings.png); + padding-left: 25px !important; + background-repeat: no-repeat; +} + +ul.nt_smenu { + font-family: custom-sans; + cursor: default; +} + +ul.nt_smenu > li { + padding: 0.2em 0.5em; +} + +ul.nt_smenu > li:hover { + background-color: black; +} + +ul.nt_smenu > li[active] > span.nt_switch:before { + margin-top: -1.2em; +} + +ul.nt_smenu > li > span { + display: inline-block; +} + +.nt_switch { + width: 2.5em; + height: 1em; + text-align: center; + overflow: hidden; +} + +.nt_switch:before { + float: left; + color: red; + content: 'OFF'; +} + +.nt_switch:after { + float: left; + color: yellowgreen; + content: 'ON'; +} + +.nt_tname { + padding-left: 0.5em; + +} + +.nt_tcount { + float: right; +} diff --git a/botanjs/src/Astro/Blog/Components/Notification.js b/botanjs/src/Astro/Blog/Components/Notification.js new file mode 100644 index 0000000..cdd69dd --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/Notification.js @@ -0,0 +1,235 @@ +(function(){ + var ns = __namespace( "Astro.Blog.Components.Notification" ); + + /** @type {System.Debug} */ + var debug = __import( "System.Debug" ); + /** @type {System.Cycle} */ + var Cycle = __import( "System.Cycle" ); + /** @type {Dandelion.IDOMElement} */ + var IDOMElement = __import( "Dandelion.IDOMElement" ); + /** @type {System.utils.IKey} */ + var IKey = __import( "System.utils.IKey" ); + /** @type {System.utils.DataKey} */ + var DataKey = __import( "System.utils.DataKey" ); + /** @type {System.utils.EventKey} */ + var EventKey = __import( "System.utils.EventKey" ); + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + /** @type {Components.MessageBox} */ + var MessageBox = __import( "Components.MessageBox" ); + /** @type {Components.Mouse.ContextMenu} */ + var ContextMenu = __import( "Components.Mouse.ContextMenu" ); + /** @type {Astro.Bootstrap} */ + var Bootstrap = __import( "Astro.Bootstrap" ); + /** @type {Astro.Blog.Config} */ + var Config = __import( "Astro.Blog.Config" ); + /** @type {Astro.utils.Date} */ + var XDate = __import( "Astro.utils.Date" ); + + var postData = __import( "System.Net.postData" ); + var smstamp = __import( "Astro.utils.Date.smstamp" ); + + var init = function () + { + var stage = Dand.id( "notifications" ); + var bodyStyle = Dand.id( "nt_body" ).style; + + var conf = Config.get( "Notification" ); + var base_path = Config.get( "BasePath" ); + + var processor = base_path + conf.paths.get_mesg; + var contextMenu; + + var itemsMenu; + + var nError = function( e ) { + // TODO: Do something on error + debug.Info( e ); + }; + + var followLink = function(e) + { + window.location = base_path + this.link; + }; + + var toggleFollow = function(e) + { + var _action = "enable"; + if( this.item.getAttribute( "active" ) ) + { + _action = "disable"; + if( + 0 < IDOMElement( this.count ).getDAttribute( "count" ) + && !confirm( "All followed notifications of this type will be unfollowed. Continue?" ) + ) return; + } + + postData( + processor + , { + "action": _action + , "tid": IDOMElement( this.item ).getDAttribute( "tid" ) + , "cid": 0 + } + , toggleSuccess.bind(this) + , nError + ); + }; + + var toggleSuccess = function(e) + { + if( this.item.getAttribute( "active" ) ) + { + this.item.removeAttribute( "active" ); + this.count.innerHTML = "N/A"; + } + else + { + this.item.setAttribute( "active", 1 ); + this.count.innerHTML = "0"; + } + + }; + + var showSettings = function( e ) + { + // Create list + var ul = Dand.wrap("ul", "nt_imenu", "nt_smenu"); + + for( var i in e.data ) + { + var li + , li_s = [ + // On/off toggle + Dand.wrap( "span", null, "nt_switch" ) + , Dand.wrap( "span", null, "nt_tname", e.data[i].name ) + ] + , keys = [ new DataKey( "tid", i ) ] + ; + + if( e.data[i].hasOwnProperty("count") ) + { + // type count + li_s[2] = Dand.wrap( + "span" + , null + , "nt_tcount" + , e.data[i].count + "" + , new DataKey( "count", e.data[i].count ) + ); + // Active + keys[ keys.length ] = new IKey( "active", 1 ); + } + else + { + li_s[2] = Dand.wrap( "span", null, "nt_tcount", "N/A" ); + } + + // Create li element + li = Dand.wrapne( "li", li_s, keys ); + ul.appendChild( li ); + + IDOMElement( li ).addEventListener( + "Click" + , toggleFollow.bind({ item: li, count: li_s[2] }) + ); + + } + + var msgBox = new MessageBox( "Notification Settings", ul, "Close" ).show(); + }; + + var popupSettings = function() + { + postData( processor, { action: "getSettings" }, showSettings, nError ); + }; + + var readNotification = function(e) + { + postData( processor, { action: "read", id: this.id }, followLink.bind( this ), nError ); + }; + // functions + var createContextMenu = function(e) + { + var items = [], menuShow = false; + + for( var n in e.data ) + { + // Create items + items[items.length] = new IKey( + e.data[n].message + , new EventKey( + "m_" + e.data[n].id + , readNotification.bind( e.data[n] ) + ) + ); + } + + items[ items.length ] = new EventKey( "Settings", popupSettings ); + + contextMenu = new ContextMenu( + stage + , items + , "LMB" + , nt_body + // showMenu/hideMenu overrides style settings + , { + "class": "nt_container" + , "showMenu": function(stage, event) + { + if( stage.className == "nt_date" ) return; + if( menuShow ) return; + bodyStyle.marginLeft = "1em"; + bodyStyle.marginRight = "-1em"; + bodyStyle.opacity = 0; + bodyStyle.display = "block"; + Cycle.next(function() + { + bodyStyle.marginLeft + = bodyStyle.marginRight = 0; + + bodyStyle.opacity = 1; + menuShow = true; + }); + } + , "hideMenu": function(stage) + { + if( stage.className == "nt_date" ) return; + if( !menuShow ) return; + bodyStyle.marginLeft = "1em"; + bodyStyle.marginRight = "-1em"; + bodyStyle.opacity = 0; + + Cycle.delay(function() + { + bodyStyle.display = "none"; + // cubic 200, we set delay to 200 + menuShow = false; + }, 200); + } + // Prevent default subnode chaining + , "chainHide": function( stage ) { } + , "chainShow": function( stage ) { } + } + ); + + for( n in e.data ) + { + var li = contextMenu.getItemByKey( "m_" + e.data[n].id ).stage; + li.appendChild( + Dand.wrapc( + "nt_date" + , smstamp( new Date( Number( e.data[n].date ) * 1000 ) ) + ) + ); + } + + contextMenu.getItemByKey("Settings").stage.className = "nt_icon_settings"; + }; + + postData( processor, { action: "get" }, createContextMenu ); + }; + + Bootstrap.regInit( init ); + +})(); diff --git a/botanjs/src/Astro/Blog/Components/SiteFile.css b/botanjs/src/Astro/Blog/Components/SiteFile.css new file mode 100644 index 0000000..15ba366 --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/SiteFile.css @@ -0,0 +1,84 @@ +.site_file { + margin: 0.5em 0; +} + +.sf_regular { + padding: 1em; + background-color: #F0F0F0; + display: inline-block; +} + +.sf_failed { + color: orangered; + opacity: 0.5; +} +.sf_failed:hover { opacity: 1; } + +.loading_bubble { + width: 20px; + height: 20px; + + display: block; + float: left; + + position: relative; +} + +.loading_bubble > span { + width: 0.25em; + height: 0.25em; + + position: absolute; + + background-color: royalblue; + + animation: p1 1s infinite; + animation-timing-function: linear; + + /* Safari and Chrome */ + -webkit-animation: p1 1s infinite; + -webkit-animation-timing-function:linear; +} + +.loading_bubble > span:nth-child(1) { + top: 2.5px; + left: 2.5px; +} + +.loading_bubble > span:nth-child(2) { + top: 2.5px; + left: 12.5px; + + animation-delay: 250ms; + -webkit-animation-delay: 250ms; +} + +.loading_bubble > span:nth-child(4) { + top: 12.5px; + left: 12.5px; + + animation-delay: 500ms; + -webkit-animation-delay: 500ms; +} + +.loading_bubble > span:nth-child(3) { + top: 12.5px; + left: 2.5px; + + animation-delay: 750ms; + -webkit-animation-delay: 750ms; +} + +@keyframes p1 +{ + 0% { opacity: 0; } + 50% { opacity: 1; } + 100% { opacity: 0; } +} + +@-webkit-keyframes p1 /* Safari and Chrome */ +{ + 0% { opacity: 0; } + 50% { opacity: 1; } + 100% { opacity: 0; } +} diff --git a/botanjs/src/Astro/Blog/Components/SiteFile.js b/botanjs/src/Astro/Blog/Components/SiteFile.js new file mode 100644 index 0000000..ad2a7bd --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/SiteFile.js @@ -0,0 +1,147 @@ +(function(){ + var ns = __namespace( "Astro.Blog.Components" ); + + /** @type {System.utils.EventKey} */ + var IKey = __import( "System.utils.IKey" ); + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + /** @type {Dandelion.IDOMElement} */ + var IDOMElement = __import( "Dandelion.IDOMElement" ); + /** @type {Astro.Bootstrap} */ + var Bootstrap = __import( "Astro.Bootstrap" ); + /** @type {Astro.Blog.Config} */ + var Conf = __import( "Astro.Blog.Config" ); + + var getData = __import( "System.Net.getData" ); + var getSMStamp = __import( "Astro.utils.Date.smstamp" ); + + /** @type {_AstConf_.SiteFile} */ + var config = null; + + var SiteFile = function ( id, hash ) + { + if( !config ) throw new Error( "config is not defined" ); + // TODO: Make a trigger for downloading from server + var stage = Dand.id( id ) + + , applyStructure = function( obj ) + { + // remove loading bubbles + while( stage.hasChildNodes() ) stage.removeChild(stage.firstChild); + + /** @type {_AstJson_.SiteFile} */ + var finfo = JSON.parse( obj ).file; + + switch( finfo.type ) { + + case "image": + var node = Dand.wrap('img'); + var k = new IKey( "src", null ); + + switch( IDOMElement(stage).getDAttribute('size') ) + { + case "small": + k.keyValue = config.path.image.small + hash + '.jpg'; + break; + case "medium": + k.keyValue = config.path.image.medium + hash + '.jpg'; + break; + default: // large + k.keyValue = config.path.image.large + hash + '.jpg'; + } + IDOMElement( node ).setAttribute( k ); + + stage.appendChild(Dand.wrapne( + 'a', node + , [ + new IKey( 'href', config.f_host + finfo.src_location ) + , new IKey( 'title', finfo.name ) + , new IKey( 'target', '_blank' ) + ] + )); + + break; + + case "audio": + // TODO + break; + + default: + // create a form to post hash string to php + var hash_field = Dand.wrapna( + 'input', [ new IKey( 'type', 'hidden' ), new IKey( 'name', 'hash' ) ] + ) + , name_field = Dand.wrapna( + 'input', [ new IKey( 'type', 'hidden' ), new IKey( 'name', 'name' ) ] + ) + , link = Dand.wrapne( + 'a', 'download', new IKey( 'href', config.path.download + finfo.name ) + ) + + , form = Dand.wrap( + 'form', null, 'sf_regular' + , [ name_field, hash_field ] + , [ + new IKey('target', '_blank') + , new IKey('action', config.path.download + finfo.name) + , new IKey('method', 'POST') + ] + ) + ; + + hash_field.value = hash; + name_field.value = finfo.name; + + IDOMElement(link).addEventListener( + 'Click' + , function(e) { + form.submit(); + e.preventDefault(); + return false; + } + ); + + // file name + form.appendChild( Dand.wrapne( 'span', 'File: ' + finfo.name) ); + + // download, submit button + form.appendChild( Dand.wrapne( 'sup', [ Dand.textNode(" ["), link, Dand.textNode("]") ] ) ); + + // hash + form.appendChild( Dand.wrapne( 'sup', Dand.wrape( 'MD5: ' + hash ) ) ); + // date + form.appendChild( Dand.wrapne( 'sup', Dand.wrape( 'Date: ' + getSMStamp( new Date( finfo.date_created ) ) ) ) ); + + + stage.appendChild(form); + + } + + } + , loadFailed = function( obj ) + { + while( stage.hasChildNodes() ) stage.removeChild( stage.firstChild ); + stage.appendChild( Dand.wrapc( "sf_failed", Dand.textNode( "Error: Failed to get resources info" ) ) ); + } + ; + + getData( config.path.info + hash, applyStructure, loadFailed ); + }; + + var init = function() + { + config = Conf.get( "SiteFile" ); + if( config ) + { + for( var i in config.files ) + { + var f = config.files[i]; + new SiteFile( f[0], f[1] ); + } + } + }; + + Bootstrap.regInit( init ); + + ns[ NS_EXPORT ]( EX_CLASS, "SiteFile", SiteFile ); +})(); diff --git a/botanjs/src/Astro/Blog/Components/SocialButtons.css b/botanjs/src/Astro/Blog/Components/SocialButtons.css new file mode 100644 index 0000000..b53c89c --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/SocialButtons.css @@ -0,0 +1,8 @@ +.social_panel { + margin: 0.5em 0; + text-align: right; +} + +.social_panel > div { + vertical-align: top; +} diff --git a/botanjs/src/Astro/Blog/Components/SocialButtons.js b/botanjs/src/Astro/Blog/Components/SocialButtons.js new file mode 100644 index 0000000..6939b45 --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/SocialButtons.js @@ -0,0 +1,40 @@ +(function(){ + var ns = __namespace( "Astro.Blog.Components.SocialButtons" ); + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + /** @type {System.utils.IKey} */ + var IKey = __import( "System.utils.IKey" ); + /** @type {Astro.Bootstrap} */ + var Bootstrap = __import( "Astro.Bootstrap" ); + + var init = function( id ) + { + var s = Dand.tag( "script" )[0]; + + // Facebook + var fb = Dand.wrapna( + "script" + , IKey.quickDef( + "type" , 'text/javascript' + , "id" , 'facebook-jssdk' + , "src" , "//connect.facebook.net/en_US/all.js#xfbml=1" + ) + ); + + // Google+ + var gplus = Dand.wrapna( + "script" + , IKey.quickDef( + "type" , 'text/javascript' + , "async" , true + , "src" , "https://apis.google.com/js/plusone.js" + ) + ); + + s.parentNode.insertBefore( fb, s ); + s.parentNode.insertBefore( gplus, s ); + }; + + Bootstrap.regInit( init ); + +})(); diff --git a/botanjs/src/Astro/Blog/Components/Spoiler.css b/botanjs/src/Astro/Blog/Components/Spoiler.css new file mode 100644 index 0000000..463ff17 --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/Spoiler.css @@ -0,0 +1,25 @@ +.spoiler { + +} + +.spoiler .title { + background: cornflowerblue; + color: white; + padding: 0.2em 0.5em; + cursor: default; +} + +.spoiler .title:hover { + background: royalblue; +} + +.spoiler .title[clicked] { + opacity: 0.5; +} + +.spoiler .content { + padding: 0.5em; + font-size: 0.9em; + line-height: 1.2em; + display: none; +} diff --git a/botanjs/src/Astro/Blog/Components/Spoiler.js b/botanjs/src/Astro/Blog/Components/Spoiler.js new file mode 100644 index 0000000..042551c --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/Spoiler.js @@ -0,0 +1,49 @@ +(function(){ + var ns = __namespace( "Astro.Blog.Components.Spoiler" ); + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + /** @type {Dandelion.IDOMElement} */ + var IDOMElement = __import( "Dandelion.IDOMElement" ); + /** @type {Astro.Bootstrap} */ + var Bootstrap = __import( "Astro.Bootstrap" ); + /** @type {Astro.Blog.Config} */ + var Config = __import( "Astro.Blog.Config" ); + + var Spoiler = function( id ) + { + var sp_stage = Dand.id( "spoiler_" + id ); + var sp_display = ( sp_stage.nodeName == "span" ) ? "inline-block" : "block"; + + var ostage = IDOMElement( sp_stage ); + var sp_title = ostage.first( "DIV" ); + var sp_content = ostage.last( "DIV" ); + + sp_title.onclick = function () + { + var s_style = sp_content.style; + + if( s_style.display == sp_display ) + { + s_style.display = "none"; + sp_title.removeAttribute( "clicked" ); + } + else + { + s_style.display = sp_display; + sp_title.setAttribute( "clicked", "" ); + } + }; + + sp_stage.hasAttribute( "expanded" ) && sp_title.onclick(); + }; + + var sps = Config.get( "Spoiler" ); + + Bootstrap.regInit(function() { + for( var i in sps ) + { + new Spoiler( sps[i] ); + } + }); + +})(); diff --git a/botanjs/src/Astro/Blog/Components/TagControl.css b/botanjs/src/Astro/Blog/Components/TagControl.css new file mode 100644 index 0000000..4448c27 --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/TagControl.css @@ -0,0 +1,24 @@ +.tag-ctrl .title { + font-size: 1.5em; + color: #444; + clear: both; +} + +.tag-ctrl { + white-space-collapse: discard; +} + +.tag-ctrl > div > div { + padding: 0.2em 0; + float: left; +} + +.tag-ctrl > div > div > a { + padding: 0 0.2em; +} + +.tag-ctrl > div > div > a:first-child:hover { + color: white; + background: purple; + text-decoration: none; +} diff --git a/botanjs/src/Astro/Blog/Components/TagControl.js b/botanjs/src/Astro/Blog/Components/TagControl.js new file mode 100644 index 0000000..dd79978 --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/TagControl.js @@ -0,0 +1 @@ +// __namespace( "Astro.Blog.Components.TagControl" ); diff --git a/botanjs/src/Astro/Blog/Components/ToggleButton/CommentToggle.css b/botanjs/src/Astro/Blog/Components/ToggleButton/CommentToggle.css new file mode 100644 index 0000000..1cfd940 --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/ToggleButton/CommentToggle.css @@ -0,0 +1,42 @@ +.uc_ntoggle { + font-family: custom-sans; + vertical-align: top; + padding: 0.2em 0em; +} +.uc_ntoggle:before { content: '..'; } +.uc_ntoggle:after { content: '!'; } + +.cr_ntoggle { + font-family: custom-sans; + + padding: 0; + margin: 0; + + position: absolute; + + width: 1.5em; + height: 1.5em; + + bottom: 0; + right: -3em; + + border-radius: 2em 2em 2em 0em; + border: 0.5em solid white; + + line-height: 1.5em !important; + + background-color: white; + /* box-shadow: 2px 2px 10px -5px black; */ +} + +.cr_ntoggle:before, .cr_ntoggle:after { + padding: 0; + border-radius: 2em; +} + +.cr_ntoggle:before { + content: '..'; + background-color: slategrey; +} + +.cr_ntoggle:after { content: '!'; } diff --git a/botanjs/src/Astro/Blog/Components/ToggleButton/CommentToggle.js b/botanjs/src/Astro/Blog/Components/ToggleButton/CommentToggle.js new file mode 100644 index 0000000..4c549a3 --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/ToggleButton/CommentToggle.js @@ -0,0 +1,27 @@ +/* +(function(){ + var ns = __namespace( "Astro.Blog.Components.ToggleButton.CommentToggle" ); + + new ToggleButton('toggle_follow', nProcessor, { + enable: { action: 'enable', tid: 3, cid: 1 }, + disable: { action: 'disable', tid: 3, cid: 1 } + }); + + new ToggleButton('uc_ntoggle', nProcessor, { + enable: { action: 'enable', tid: 1, cid: 1645 }, + disable: { action: 'disable', tid: 1, cid: 1645 } + }); + + new ToggleButton('toggle_publish', '../../../user/ajax-set_article', { + enable: { draft: 0, article_id: 1645 }, + disable: { draft: 1, article_id: 1645 } + }); + + for(var i in commList) { + new ToggleButton('cr_ntoggle_' + commList[i], nProcessor, { + enable: { action: 'enable', tid: 2, cid: commList[i] }, + disable: { action: 'disable', tid: 2, cid: commList[i] } + }); + +})(); +//*/ diff --git a/botanjs/src/Astro/Blog/Components/ToggleButton/_this.css b/botanjs/src/Astro/Blog/Components/ToggleButton/_this.css new file mode 100644 index 0000000..aeb0d7f --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/ToggleButton/_this.css @@ -0,0 +1,84 @@ +.btn_toggle { + position: relative; + + font-family: serif; + font-size: 1em; + + padding: 0.2em 0.5em; + margin: 0.5em 0.2em; + + background-color: grey; + color: white; + + cursor: default; + + overflow: hidden; + display: inline-block; +} + +.btn_toggle > .btn_space { + visibility: hidden; + padding: 0 0.5em; +} + +.btn_toggle:hover { + text-decoration: none; +} + +.btn_toggle:hover:before, .btn_toggle:hover:after { + text-decoration: underline; +} + +.btn_toggle:before, .btn_toggle:after { + + padding-top: 0.2em; + + text-align: center; + + position: absolute; + font-size: 1.2em; + + width: 100%; + height: 100%; + + top: 0; + left: 0; + + -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + -moz-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + -ms-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + -o-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); /* easeOutCubic */ +} + +.btn_toggle:before { + content: ''; + top: 0%; + + -webkit-transition: all 500ms cubic-bezier(0.215, 0.610, 0.355, 1.000); + -moz-transition: all 500ms cubic-bezier(0.215, 0.610, 0.355, 1.000); + -ms-transition: all 500ms cubic-bezier(0.215, 0.610, 0.355, 1.000); + -o-transition: all 500ms cubic-bezier(0.215, 0.610, 0.355, 1.000); + transition: all 500ms cubic-bezier(0.215, 0.610, 0.355, 1.000); /* easeOutCubic */ +} + +.btn_toggle:after { + content: ''; + background-color: royalblue; + top: 200%; + + -webkit-transition: all 750ms cubic-bezier(0.215, 0.610, 0.355, 1.000); + -moz-transition: all 750ms cubic-bezier(0.215, 0.610, 0.355, 1.000); + -ms-transition: all 750ms cubic-bezier(0.215, 0.610, 0.355, 1.000); + -o-transition: all 750ms cubic-bezier(0.215, 0.610, 0.355, 1.000); + transition: all 500ms cubic-bezier(0.215, 0.610, 0.355, 1.000); /* easeOutCubic */ +} + +.btn_toggle[active]:after { + top: 0%; +} + + +.btn_toggle[active]:before { + top: -120%; +} diff --git a/botanjs/src/Astro/Blog/Components/ToggleButton/_this.js b/botanjs/src/Astro/Blog/Components/ToggleButton/_this.js new file mode 100644 index 0000000..8e0fe65 --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/ToggleButton/_this.js @@ -0,0 +1,61 @@ +(function(){ + var ns = __namespace( "Astro.Blog.Components" ); + + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + /** @type {Dandelion.IDOMElement} */ + var IDOMElement = __import( "Dandelion.IDOMElement" ); + /** @type {Astro.Bootstrap} */ + var Bootstrap = __import( "Astro.Bootstrap" ); + /** @type {Astro.Blog} */ + var config = __import( "Astro.Blog.Config" ); + + var postData = __import( "System.Net.postData" ); + + var ToggleButton = function ( elem, processor, obj ) + { + var stage = Dand.id( elem ); + if( !stage ) return; + + + var n_toggle = function (args) + { + if(stage.getAttribute('active')) + { + stage.removeAttribute('active'); + } + else + { + stage.setAttribute('active', 1); + } + }; + + var nError = function (args) + { + + } + ; + + IDOMElement(stage).addEventListener( + 'Click' + , function (e) { + var _action = stage.getAttribute('active') ? obj.disable : obj.enable; + postData( processor, _action, n_toggle, nError ); + } + ); + }; + + var init = function() + { + var toggles = config.get( "toggle_btns" ); + for( var i in toggles ) + { + new ToggleButton( toggles[ i ][0], toggles[ i ][1], toggles[ i ][2] ); + } + + }; + + Bootstrap.regInit( init ); + + ns[ NS_EXPORT ]( EX_CLASS, "ToggleButton", ToggleButton ); +})(); diff --git a/botanjs/src/Astro/Blog/Components/VerticalNote.css b/botanjs/src/Astro/Blog/Components/VerticalNote.css new file mode 100644 index 0000000..4cdd177 --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/VerticalNote.css @@ -0,0 +1,80 @@ +.vsign { + position: relative; + overflow-x: scroll; + overflow-y: hidden; +} +.vertical-text { + float: right; + + color: #777; + + padding: 1em 0.5em; + margin: 0.5em 1em; + + position: relative; +} + +.vertical-text.block { + background-color: #FAFAFA; +} + +.vertical-text > a.more { + display: block; + + top: 0; + left: 0; + + width: 100%; + height: 100%; + + padding: 0; + + position: absolute; + + border: 1px solid #D4D7C9; +} +.vertical-text > a.more:hover { + border-width: 2px; + border-color: purple; + + cursor: pointer; +} + +.vertical-text p +, .vertical-text a +, .vertical-text h1 , .vertical-text h2, .vertical-text h3 +, .vertical-text h4, .vertical-text h5, .vertical-text h6 { + padding: 0.1em; + margin: 0; + width: 1em; + letter-spacing: 1em; + + word-break: break-all; + word-wrap: break-word; +} + +.vertical-text > .block { + overflow: hidden; + width: 4.5em; +} + +.vertical-text > * { + display: inline-block; + float: right; + height: 390px; +} + +.vertical-text > p { + height: 400px; +} + +.vertical-text.source > * { + height: auto; +} + +.vertical-text.source { + height: 400px; + border: 0; + padding: 0; + visibility: hidden; +} diff --git a/botanjs/src/Astro/Blog/Components/VerticalNote.js b/botanjs/src/Astro/Blog/Components/VerticalNote.js new file mode 100644 index 0000000..c3ad426 --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/VerticalNote.js @@ -0,0 +1,79 @@ +(function(){ + var ns = __namespace( "Astro.Blog.Components.VerticalNote" ); + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + /** @type {Dandelion.IDOMElement} */ + var IDOMElement = __import( "Dandelion.IDOMElement" ); + /** @type {Astro.Bootstrap} */ + var Bootstrap = __import( "Astro.Bootstrap" ); + /** @type {Astro.Blog.Config} */ + var Config = __import( "Astro.Blog.Config" ); + /** @type {Astro.utils.Date} */ + var XDate = __import( "Astro.utils.Date" ); + + /** @param {Dandelion.IDOMElement} elem */ + var VerticalNote = function( elem ) + { + var relem = elem.element; + var maxHeight = relem.clientHeight; + + // Break for elements that are too long + var formatted = Dand.wrapc( relem.className.replace( / *source */, " " ) ); + + elem.foreach( 1, function( child ) + { + var ichild = IDOMElement( child ); + switch( ichild.getDAttribute( "flag" ) ) + { + case "date": + child.innerHTML = XDate.chinese( new Date( child.innerHTML ) ); + break; + case "anchor": + case "image": + formatted.appendChild( child ); + child.style.display = null; + return; + } + + var content = child.innerHTML; + var len = content.length; + var blockh = Math.ceil( child.clientHeight / len ); + + var opLen = Math.floor( maxHeight / blockh ); + + var i = 0; + + var doBreak = function( i ) + { + var nLine = Dand.wrapne( + child.nodeName + , content.substr( opLen * i, opLen ) + , ichild.aKeys() + ); + + formatted.appendChild( nLine ); + + formatted.addEventListener( + "click" + , function( e ) { + window.location = this.loc; + }.bind({ loc: elem.getDAttribute( "href" ) }) + ); + + len -= opLen; + }; + + for( var i = 0; opLen < len; i ++ ) doBreak( i ); + if( 0 < len ) doBreak( i ); + } ); + + relem.style.display = "none"; + relem.parentNode.insertBefore( formatted, relem.nextSibling ); + }; + + Bootstrap.regInit(function() { + Dand.glass( "vertical-text", true ) + .forEach( function( e ) { new VerticalNote( e ); } ); + }); + +})(); diff --git a/botanjs/src/Astro/Blog/Components/Video.css b/botanjs/src/Astro/Blog/Components/Video.css new file mode 100644 index 0000000..9bd9641 --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/Video.css @@ -0,0 +1,32 @@ +.v_wrapper { + width: 640px; + height: 390px; +} + +.v_wrapper > div{ + position: relative; + width: 100%; + height: 100%; + opacity: 0.6; + background: black; +} + +.v_wrapper > div:hover { + opacity: 0.2; +} + +.v_wrapper > div > div { + width: 0; + height: 0; + border-top: 3.5em solid transparent; + border-bottom: 3.5em solid transparent; + border-left: 5em solid white; + + position: absolute; + + left: 50%; + top: 50%; + margin-top: -3.5em; + margin-left: -1.8em; + + } \ No newline at end of file diff --git a/botanjs/src/Astro/Blog/Components/Video.js b/botanjs/src/Astro/Blog/Components/Video.js new file mode 100644 index 0000000..fd4530c --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/Video.js @@ -0,0 +1,103 @@ +(function(){ + var ns = __namespace( "Astro.Blog.Components.Video" ); + + /** @type {System.utils.IKey} */ + var IKey = __import( "System.utils.IKey" ); + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + /** @type {Dandelion.IDOMElement} */ + var IDOMElement = __import( "Dandelion.IDOMElement" ); + /** @type {Astro.Bootstrap} */ + var Bootstrap = __import( "Astro.Bootstrap" ); + /** @type {Astro.Blog.Config} */ + var Config = __import( "Astro.Blog.Config" ); + + var getData = __import( "System.Net.getData" ); + + var v_current = { player: false, mask: false, stage: false, listener: false }; + + var init = function() + { + var conf = Config.get( "Video" ); + if( conf ) + { + for( var i in conf ) + { + var type = conf[i]; + var vid = Dand.id( type ); + if( !vid ) continue; + + type = type.split( "_" )[0]; + + // showVimeoPlayer / showYoutubePlayer + var cfunc = function( e ) { createPlayer( this.vid, "http://www.youtube.com/embed/" ); }; + + if( type[0] == "v" ) + { + getVimeoThumbnail( vid ); + cfunc = function( e ) { createPlayer( this.vid, "http://player.vimeo.com/video/" ); }; + } + + vid.onclick = cfunc.bind({ vid: vid }); + } + } + }; + + var createPlayer = function ( vtag, url ) + { + // Remove previous playing video if exists + if( v_current.stage ) + { + v_current.stage.removeChild( v_current.player ); + v_current.stage.appendChild( v_current.mask ); + v_current.stage.onclick = v_current.listener; + } + + // Remove mask + ( v_current.stage = vtag ).removeChild( v_current.mask = vtag.firstChild ); + + v_current.player = Dand.wrapna( + "iframe" + , IKey.quickDef( + "src" , url + vtag.getAttribute( "value" ) + "?autoplay=1" + , "mozallowfullscreen" , "" + , "allowFullScreen" , "" + , "webkitAllowFullScreen" , "" + , "frameborder" , 0 + , "width" , vtag.clientWidth + , "height" , vtag.clientHeight + ) + ); + vtag.appendChild(v_current.player); + + // Save event listener + v_current.listener = vtag.onclick; + + // disable click event + vtag.onclick = null; + + // + // + }; + + var getVimeoThumbnail = function ( vtag ) + { + getData( + "http://vimeo.com/api/oembed.json?url=http%3A//vimeo.com/" + vtag.getAttribute( "value" ) + , parseObj.bind( vtag ) + , noThumb.bind( vtag ) + ); + }; + + var parseObj = function (str) + { + this.style.background = "black url(" + JSON.parse(str)["thumbnail_url"] + ") center center no-repeat"; + }; + + var noThumb = function () + { + + }; + + Bootstrap.regInit( init ); +})(); diff --git a/botanjs/src/Astro/Blog/Config.js b/botanjs/src/Astro/Blog/Config.js new file mode 100644 index 0000000..9807f22 --- /dev/null +++ b/botanjs/src/Astro/Blog/Config.js @@ -0,0 +1,12 @@ +(function(){ + var ns = __namespace( "Astro.Blog.Config" ); + + var conf = window["_AstConf_"] || {}; + + var _get = function( name ) + { + return conf[ name ] || null; + }; + + ns[ NS_EXPORT ]( EX_FUNC, "get", _get ); +})(); diff --git a/botanjs/src/Astro/Blog/Element/Footer.css b/botanjs/src/Astro/Blog/Element/Footer.css new file mode 100644 index 0000000..1ce3144 --- /dev/null +++ b/botanjs/src/Astro/Blog/Element/Footer.css @@ -0,0 +1,12 @@ +footer { + background-color: #222; + background-image: url(http://file.astropenguin.net/blog/layout-images/lines.png); + background-repeat: no-repeat; + background-position: right bottom; +} + +#fhorizon { + position: absolute; + top: -7px; +} + diff --git a/botanjs/src/Astro/Blog/Element/Footer.js b/botanjs/src/Astro/Blog/Element/Footer.js new file mode 100644 index 0000000..d8f0624 --- /dev/null +++ b/botanjs/src/Astro/Blog/Element/Footer.js @@ -0,0 +1,2 @@ +// __namespace( "Astro.Blog.Element.Footer" ); +// __import( "Astro.Common.Element.Footer" ); diff --git a/botanjs/src/Astro/Blog/Element/Header.css b/botanjs/src/Astro/Blog/Element/Header.css new file mode 100644 index 0000000..fed1b55 --- /dev/null +++ b/botanjs/src/Astro/Blog/Element/Header.css @@ -0,0 +1,89 @@ +.home { + position: relative; + width: 100%; + overflow: hidden; +} + +header { + position: relative; +} + +#menu { + font-size: 1.75em; + text-align: right; +} + +#menu > * { + font-family: custom-sans; + cursor: pointer; + line-height: 1em !important; + + position: relative; + + color: rgba( 0, 0, 0, 0.5 ); + -webkit-filter: blur( 2px ); + filter: blur( 2px ); +} + +#menu > *[active] { + -webkit-filter: blur( 0px ); + filter: blur( 0px ); + color: rgba( 128, 0, 128, 1 ); +} + +#menu > *:hover { + color: rgba( 0, 0, 0, 0.75 ); + -webkit-filter: blur( 0px ); + filter: blur( 0px ); + text-decoration: none; +} + +.horizon { + position: relative; + width: 100%; + height: 7px; + background: #76400C; + z-index: 4; +} + +.contact { + width: 100%; + height: 0; + + -moz-box-shadow: inset 0 0 10px 0 black; + -webkit-box-shadow: inset 0 0 10px 0 black; + box-shadow: inset 0 0 10px 0 black; + + color: white; + background: lightslategray; + position: absolute; + overflow: hidden; +} + +.collapse_panel { + position: absolute; + width: 100%; + height: 50px; + bottom: -33px; + font-size: 3em; + text-align: center; + color: white; + + -moz-box-shadow: 0 0 10px 0 black; + -webkit-box-shadow: 0 0 10px 0 black; + box-shadow: 0 0 10px 0 black; +} + +.collapse_panel:after { + content: ''; + position: absolute; + left: 0; + width: 100%; + height: 100%; + background:url(http://file.astropenguin.net/blog/layout-images/collapse.png) center 2.5px no-repeat; +} + +#collapse_panel:hover { + bottom: 0; + cursor: pointer; +} diff --git a/botanjs/src/Astro/Blog/Element/Header.js b/botanjs/src/Astro/Blog/Element/Header.js new file mode 100644 index 0000000..022a1f8 --- /dev/null +++ b/botanjs/src/Astro/Blog/Element/Header.js @@ -0,0 +1 @@ +// __namespace( "Astro.Blog.Element.Header" ); diff --git a/botanjs/src/Astro/Blog/Element/Layer.css b/botanjs/src/Astro/Blog/Element/Layer.css new file mode 100644 index 0000000..65669fa --- /dev/null +++ b/botanjs/src/Astro/Blog/Element/Layer.css @@ -0,0 +1,2 @@ +.mbody { z-index: 1; } +header, footer { z-index: 2; } diff --git a/botanjs/src/Astro/Blog/Element/Layer.js b/botanjs/src/Astro/Blog/Element/Layer.js new file mode 100644 index 0000000..49ab51f --- /dev/null +++ b/botanjs/src/Astro/Blog/Element/Layer.js @@ -0,0 +1 @@ +// __namespace( "Astro.Blog.Element.Layer" ); diff --git a/botanjs/src/Astro/Blog/Layout/Article/Control.js b/botanjs/src/Astro/Blog/Layout/Article/Control.js new file mode 100644 index 0000000..4a37e5d --- /dev/null +++ b/botanjs/src/Astro/Blog/Layout/Article/Control.js @@ -0,0 +1,53 @@ +(function(){ + var ns = __namespace( "Astro.Blog.Layout.Article.Control" ); + + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + /** @type {Dandelion.IDOMElement} */ + var IDOMElement = __import( "Dandelion.IDOMElement" ); + /** @type {Components.MessageBox} */ + var MessageBox = __import( "Components.MessageBox" ); + /** @type {Astro.Bootstrap} */ + var Bootstrap = __import( "Astro.Bootstrap" ); + /** @type {Astro.Blog.Config} */ + var config = __import( "Astro.Blog.Config" ); + + var postData = __import( "System.Net.postData" ); + + var aid = config.get( "ArticleID" ); + + /** @type {_AstConf_.Control} */ + var control = config.get( "Control" ); + + var init = function() + { + var delete_btn = Dand.id( "control_delete", true ); + if( delete_btn ) delete_btn.addEventListener( "Click", a_delete ); + }; + + var a_delete = function () + { + new MessageBox( + "Confirm" + , "Are you sure you want to delete this article?. Comments will also be deleted!" + , "Yes", "No" + , a_doDelete + ).show(); + }; + + var a_doDelete = function ( confirmed ) + { + var a_deleteSuccess = function ( args ) + { + window.location.reload( true ); + } + , a_deleteFailed = function ( args ) + { + + }; + + if ( confirmed ) postData( control.action.del, { "article_id": aid }, a_deleteSuccess, a_deleteFailed ); + }; + + Bootstrap.regInit( init ); +})(); diff --git a/botanjs/src/Astro/Blog/Layout/Article/Latest.js b/botanjs/src/Astro/Blog/Layout/Article/Latest.js new file mode 100644 index 0000000..0f9db83 --- /dev/null +++ b/botanjs/src/Astro/Blog/Layout/Article/Latest.js @@ -0,0 +1,6 @@ +(function(){ + var ns = __namespace( "Astro.Blog.Layout.Article.Latest" ); + + // __import( "Astro.Blog.Components.Entry.Home" ); + // __import( "Astro.Blog.Components.Entry.Mega" ); +})(); diff --git a/botanjs/src/Astro/Blog/Layout/Article/_this.js b/botanjs/src/Astro/Blog/Layout/Article/_this.js new file mode 100644 index 0000000..0a08eea --- /dev/null +++ b/botanjs/src/Astro/Blog/Layout/Article/_this.js @@ -0,0 +1,3 @@ +(function(){ + var ns = __namespace( "Astro.Blog.Layout.Article" ); +})(); diff --git a/botanjs/src/Astro/Blog/Layout/ErrorPages.css b/botanjs/src/Astro/Blog/Layout/ErrorPages.css new file mode 100644 index 0000000..376f5ad --- /dev/null +++ b/botanjs/src/Astro/Blog/Layout/ErrorPages.css @@ -0,0 +1,99 @@ +* { margin: 0; padding: 0; } + +/* Parallax & charCloud */ +.p_abs100 { + top: 0; + left: 0; + width: 100%; + height:100%; + position: absolute; + overflow: hidden; +} + +.p_charCloud +{ + font-family: sans-serif; +} + +/* End Parallax & charCloud */ +#g { width: 100%; height: 100%; position: absolute; top: 0; } + +#g, .slideTransitionOverride { + -webkit-transition: all 2ms cubic-bezier(0.115, 0.000, 0.355, 1.000); + -moz-transition: all 2s cubic-bezier(0.115, 0.000, 0.355, 1.000); + -ms-transition: all 2s cubic-bezier(0.115, 0.000, 0.355, 1.000); + -o-transition: all 2s cubic-bezier(0.115, 0.000, 0.355, 1.000); + transition: all 2s cubic-bezier(0.115, 0.000, 0.355, 1.000); /* custom */ + + -webkit-transition-timing-function: cubic-bezier(0.115, 0.000, 0.355, 1.000); + -moz-transition-timing-function: cubic-bezier(0.115, 0.000, 0.355, 1.000); + -ms-transition-timing-function: cubic-bezier(0.115, 0.000, 0.355, 1.000); + -o-transition-timing-function: cubic-bezier(0.115, 0.000, 0.355, 1.000); + transition-timing-function: cubic-bezier(0.115, 0.000, 0.355, 1.000); /* custom */ +} + +html, body { height: 100%; } + +.rooms { width: 100%; height:100%; position: absolute; overflow: hidden; z-index: -1; } + +#g > div{ + width: 100%; + height:100%; + position: relative; +} + +.c_center { + top: 50%; + left: 50%; + position: absolute; + + z-index: 2; +} + +.code{ + /* Values depends on the sprite sheet*/ + margin-left: -100px; + margin-top: -45px; + width: 200px; + height: 90px; +} + +.c401 { background: url(http://file.astropenguin.net/blog/layout-images/errorcodes.png) 0 0; } +.c403 { background: url(http://file.astropenguin.net/blog/layout-images/errorcodes.png) 200px 0; } +.c404 { background: url(http://file.astropenguin.net/blog/layout-images/errorcodes.png) 0 90px; } + +.b401 { background: cornflowerblue; } +.b403 { background: crimson; } +.b404 { background: slategrey; } + +.t401 { color: cornflowerblue; } +.t403 { color: crimson; } +.t404 { color: slategrey; } + + +.bc { + /* Actual ring diameter */ + width: 315px; + height: 315px; + border-radius: 315px; + + margin-left: -157.5px; + margin-top: -157.5px; +} + +.ringbg { + /* ring canvas size */ + width: 400px; + height: 400px; + + margin-left: -200px; + margin-top: -200px; + + background: url(http://file.astropenguin.net/blog/layout-images/ring.png) center center no-repeat; +} + + +h1 { + font-family: sans-serif; + font-size: 4em; +} \ No newline at end of file diff --git a/botanjs/src/Astro/Blog/Layout/ErrorPages.js b/botanjs/src/Astro/Blog/Layout/ErrorPages.js new file mode 100644 index 0000000..2f3bcc9 --- /dev/null +++ b/botanjs/src/Astro/Blog/Layout/ErrorPages.js @@ -0,0 +1,75 @@ +(function(){ + var ns = __namespace( "Astro.Blog.Layout.ErrorPages" ); + + /** @type {System.Cycle} */ + var Cycle = __import( "System.Cycle" ); + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + /** @type {Astro.Bootstrap} */ + var Bootstrap = __import( "Astro.Bootstrap" ); + /** @type {Astro.Blog} */ + var config = __import( "Astro.Blog.Config" ); + /** @type {Astro.Blog.Mechanism.CharacterCloud} */ + var CharacterCloud = __import( "Astro.Mechanism.CharacterCloud" ); + /** @type {Astro.Blog.Mechanism.Parallax} */ + var Parallax = __import( "Astro.Mechanism.Parallax" ); + + var init = function () + { + var errorcode = config.get( "ErrorCode" ); + var currentRoom = Dand.id( 'p' + errorcode ); + var parent = currentRoom.parentNode; + var rooms = parent.childNodes; + var l = rooms.length; + var rm; + // far from observer; + var cloudRange_1 = { lowerLimit: 0, upperLimit: 250, leftLimit: -10, rightLimit: 110 }; + var cloudRange_2 = { lowerLimit: 0, upperLimit: 150, leftLimit: -10, rightLimit: 110 }; + var cloudRange_3 = { lowerLimit: 0, upperLimit: 200, leftLimit: -10, rightLimit: 110 }; + // close; + var cloudRange_4 = { lowerLimit: 0, upperLimit: 100, leftLimit: -10, rightLimit: 110 }; + var cCloudSymbol; + + switch ( errorcode ) + { + case 401: + cCloudSymbol = "!"; + break; + case 403: + cCloudSymbol = "\u00D7 Forbidden"; + break; + default: + cCloudSymbol = "Page not found"; + } + + Parallax.cssSlide( Dand.wrap(), 0, cloudRange_1 ); + Parallax.cssSlide( Dand.wrap(), 0, cloudRange_2 ); + Parallax.cssSlide( Dand.wrap(), 0, cloudRange_3 ); + Parallax.cssSlide( Dand.wrap(), 0, cloudRange_4 ); + + var parallax_container = Dand.id( 'p' + errorcode ); + + parallax_container.appendChild( Parallax.cssSlide( CharacterCloud.create( cCloudSymbol, "p_charCloud t" + errorcode, 20, cloudRange_1 ), 1, cloudRange_1 ) ); + parallax_container.appendChild( Parallax.cssSlide( CharacterCloud.create( cCloudSymbol, "p_charCloud t" + errorcode, 20, cloudRange_2 ), 1, cloudRange_2 ) ); + parallax_container.appendChild( Parallax.cssSlide( CharacterCloud.create( cCloudSymbol, "p_charCloud t" + errorcode, 20, cloudRange_3 ), 1, cloudRange_3 ) ); + parallax_container.appendChild( Parallax.cssSlide( CharacterCloud.create( cCloudSymbol, "p_charCloud t" + errorcode, 20, cloudRange_4 ), 1, cloudRange_4 ) ); + + for( var r = 0, i = 0; r < l; r ++ ) + { + rm = rooms[r]; + if( rm.nodeType == 1 ) + { + if( rm == currentRoom ) + { + parent.style.top = ( -i * 100 ) + "%"; + // Parallax Scrolling! + Cycle.next( function() { Parallax.verticalSlideTo(i) } ); + break; + } + i ++; + } + } + }; + + Bootstrap.regInit( init ); +})(); diff --git a/botanjs/src/Astro/Blog/Layout/Login.css b/botanjs/src/Astro/Blog/Layout/Login.css new file mode 100644 index 0000000..aaec0e5 --- /dev/null +++ b/botanjs/src/Astro/Blog/Layout/Login.css @@ -0,0 +1,63 @@ +body { + background-color: #222; + background-image: radial-gradient( + circle 150px at -75% -75% + , transparent 0% + , transparent 94% + , rgba(255, 255, 255, 0.6) 94% + , rgba(255, 255, 255, 0.6) 99% + , transparent + ) + , radial-gradient( + circle 150px at 173% 174% + , transparent 0% + , transparent 94% + , rgba(255, 255, 255, 0.6) 94% + , rgba(255, 255, 255, 0.6) 99% + , transparent + ) + ; + + background-size: 100px 100px; + + width: 100%; + height: 100%; + + position: absolute; +} + +form { + overflow: hidden; +} + +input { + width: 100%; + margin-bottom: 0.5em; +} + +.mbox_titlebar, .mbox_body { + background: rgba(0, 0, 0, 0.1) !important; +} + +.cstatus { + position: relative; +} + +.status { + position: absolute; + + right: 0.25em; + top: 0.25em; + + width: 0.5em; + height: 0.5em; + + background: grey; + box-shadow: 0 0 5px 0; +} + +div.msg { text-align: right; } +sub.good { color: greenyellow; } +sub.failed { color: #DDD; } +sub.suspicious { color: orangered; } +sub.banned { color: red; } diff --git a/botanjs/src/Astro/Blog/Layout/Login.js b/botanjs/src/Astro/Blog/Layout/Login.js new file mode 100644 index 0000000..1cf1d8b --- /dev/null +++ b/botanjs/src/Astro/Blog/Layout/Login.js @@ -0,0 +1,75 @@ +(function(){ + var ns = __namespace( "Astro.Blog.Layout.Login" ); + + /** @type {System.utils.IKey} */ + var IKey = __import( "System.utils.IKey" ); + /** @type {Components.MessageBox} */ + var MessageBox = __import( "Components.MessageBox" ); + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + /** @type {Astro.Bootstrap} */ + var Bootstrap = __import( "Astro.Bootstrap" ); + /** @type {Astro.Blog.Config} */ + var config = __import( "Astro.Blog.Config" ); + + // __import( "Dandelion.CSSReset" ); CSS_RESERVATION + // __import( "Dandelion.CSSAnimations" ); CSS_RESERVATION + + /** @type {_AstConf_.Login} */ + var conf = config.get( "Login" ); + + var sHeat = conf.sHeat || ""; + var formAction = conf.formAct || "./"; + + var field_username = new IKey( "name", "username" ); + var field_password = new IKey( "name", "password" ); + + var init = function () + { + var form = Dand.wrapne('form' + , [ + // Basic login and password fields + , Dand.wrapc("flsf", "Name:") + , Dand.wrapna('input', [ field_username, new IKey("type", "text") ] ) + + , Dand.wrapc("flsf", "Password:") + , Dand.wrapna('input', [ field_password, new IKey("type", "password") ] ) + + , Dand.wrapc('msg', Dand.wrap('sub', null, sHeat.toLowerCase(), sHeat)) + ] + , [ + // Form attributes + new IKey('action', formAction) + , new IKey('method', 'POST') + ] + ) + ; + + + var mbox = new MessageBox( "Blog.Astro", form, "Login", false, submitForm.bind( form ) ).show(); + + // Handle enter button + mbox.onkeyup = function( _e ) + { + if ( submitForm.bind( form )( _e.which == 13 ) ) + { + document.body.removeChild( this ); + } + }; + }; + + var submitForm = function (bool) { + if ( bool ) + { + if ( this[ field_username.keyValue ].value != "" + && this[ field_password.keyValue ] != "" ) + { + this.submit(); + return true; + } + } + return false; + }; + + Bootstrap.regInit( init ); +})(); diff --git a/botanjs/src/Astro/Blog/Layout/MainFrame.css b/botanjs/src/Astro/Blog/Layout/MainFrame.css new file mode 100644 index 0000000..755839e --- /dev/null +++ b/botanjs/src/Astro/Blog/Layout/MainFrame.css @@ -0,0 +1,108 @@ +html, body { height: 100%; } + +html { background-color: #222; } + +body { + background-color: #F0F0F0; + font-family: custom-sans; +} + +pre { font-family: monospace; } + +::selection { + color: white; + background: purple; +} +::-moz-selection { + color: white; + background: purple; +} + +p { padding: 0.5em; } + +a { + color: #333; + text-decoration: none; +} + +a:hover { text-decoration: underline; } + +h1, h2, h3, h4, .h1, .h2, .h3, .h4 { font-family: custom-serif; } +h1, .h1 { font-size: 2.5em; } +h2, .h2 { font-size: 2em; } +h3, .h3 { font-size: 1.5em; } +h4, .h4 { font-size: 1em; } +h5, .h5 { font-size: 0.8em; } +h6, .h6 { font-size: 0.5em; } + +.clearfix { + clear: both; + padding: 0 !important; + margin: 0 !important; + +} + +.begin-wrapper { + position: relative; + + min-height: 100%; + background-color: #EBEAEF; + + overflow: hidden; +} + +.mbody { + position: relative; + width: 100%; +} + +.main-column { + width: 85%; + margin: 0 auto; +} + +.right { text-align: right; } +.panel { padding: 1.2em; } + +/* transition properties */ +div#header, div#mbody, div#contact, div#horizon { + + -webkit-transition: all 500ms cubic-bezier(0.770, 0.000, 0.175, 1.000); + -moz-transition: all 500ms cubic-bezier(0.770, 0.000, 0.175, 1.000); + -ms-transition: all 500ms cubic-bezier(0.770, 0.000, 0.175, 1.000); + -o-transition: all 500ms cubic-bezier(0.770, 0.000, 0.175, 1.000); + transition: all 500ms cubic-bezier(0.770, 0.000, 0.175, 1.000); /* easeInOutQuart */ + + -webkit-transition-timing-function: cubic-bezier(0.770, 0.000, 0.175, 1.000); + -moz-transition-timing-function: cubic-bezier(0.770, 0.000, 0.175, 1.000); + -ms-transition-timing-function: cubic-bezier(0.770, 0.000, 0.175, 1.000); + -o-transition-timing-function: cubic-bezier(0.770, 0.000, 0.175, 1.000); + transition-timing-function: cubic-bezier(0.770, 0.000, 0.175, 1.000); /* easeInOutQuart */ +} + +@keyframes spin { + 0% { transform: rotate( 0deg ); } + 25% { transform: rotate( 90deg ); } + 50% { transform: rotate( 180deg ); } + 75% { transform: rotate( 270deg ); } + 100% { transform: rotate( 360deg ); } +} + +@keyframes aspin { + 0% { transform: rotate( 0deg ); } + 25% { transform: rotate( -90deg ); } + 50% { transform: rotate( -180deg ); } + 75% { transform: rotate( -270deg ); } + 100% { transform: rotate( -360deg ); } +} + +.spin { + animation-duration: 60s; + animation-timing-function: linear; + animation-iteration-count: infinite; + animation-name: aspin; +} + +.cw { animation-name: spin; } + +/* end transition properties */ diff --git a/botanjs/src/Astro/Blog/Layout/MainFrame.js b/botanjs/src/Astro/Blog/Layout/MainFrame.js new file mode 100644 index 0000000..d8604ba --- /dev/null +++ b/botanjs/src/Astro/Blog/Layout/MainFrame.js @@ -0,0 +1,256 @@ +(function(){ + var ns = __namespace( "Astro.Blog.Layout.MainFrame" ); + + /** @type {System.Cycle} */ + var Cycle = __import( "System.Cycle" ); + /** @type {System.utils.IKey} */ + var IKey = __import( "System.utils.IKey" ); + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + /** @type {Dandelion.IDOMObject} */ + var IDOMObject = __import( "Dandelion.IDOMObject" ); + /** @type {Dandelion.IDOMElement} */ + var IDOMElement = __import( "Dandelion.IDOMElement" ); + /** @type {Dandelion.Window} */ + var wsupp = __import( "Dandelion.Window" ); + /** @type {System.Debug} */ + var debug = __import( "System.Debug" ); + /** @type {Astro.Bootstrap} */ + var Bootstrap = __import( "Astro.Bootstrap" ); + /** @type {Astro.Mechanism.CharacterCloud} */ + var CharacterCloud = __import( "Astro.Mechanism.CharacterCloud" ); + /** @type {Astro.Mechanism.Parallax} */ + var Parallax = __import( "Astro.Mechanism.Parallax" ); + + // __import( "Dandelion.CSSReset" ); CSS_RESERVATION + // __import( "Dandelion.CSSAnimations" ); CSS_RESERVATION + // __import( "Astro.Blog.Element.Layer" ); CSS_RESERVATION + + var main; + var header; + var main_h; + + // menu and horizon + var horizon; + var contact; + var contaht_page; + var collapse_panel; + var c_expand = false; + var savedPath; + + var init = function () + { + // Footer at bottom + var padder = Dand.wrap(); + var begin_wrapper = Dand.id( "begin-wrapper" ); + var content_wrapper = Dand.id( "mbody" ); + var footer = Dand.tag( "footer" ); + var fhorizon = Dand.id( "fhorizon" ); + + if( footer.length ) + { + footer = footer[0]; + var fheight = footer.scrollHeight || footer.offsetHeight; + var hheight = fhorizon.scrollHeight || fhorizon.offsetHeight; + + padder.style.height = ( fheight + hheight ) + "px"; + begin_wrapper.style.marginBottom = "-" + fheight + "px"; + } + + content_wrapper.appendChild( padder ); + + + IDOMObject( window ).addEventListener( "Resize", responsify ); + + initTopButton(); + navControl(); + responsify( null, true ); + initBackgroundParallax(); + }; + + var topButtons = []; + var initTopButton = function() + { + // init params + header = Dand.id( "header" ); + horizon = Dand.id( "horizon" ); + main = Dand.id( "mbody" ); + + contact_page = Dand.id( "contact" ); + collapse_panel = Dand.id( "collapse_panel" ); + + horizon.style.backgroundColor + = fhorizon.style.backgroundColor + = "purple"; + + contact = Dand.id( "menu_cont", true ); + contact.addEventListener( "Click", expandContact ); + + Dand.id( "menu", true ).foreach( + 1, function( e ) + { + topButtons.push( e ); + if( e.getAttribute( "active" ) !== null ) + { + e.setAttribute( "master", true ); + } + } + ); + }; + + var navControl = function () + { + // Page control + /** @type {Dandelion.IDOMElement} */ + var page_control = Dand.id( "top_control", true ); + var bottom_control = Dand.id( "bottom_control" ); + + if ( page_control && bottom_control ) + { + var appendp = function( elem, self ) + { + var clone = elem.cloneNode( true ); + if( clone.className == "p_navigation" ) + { + IDOMElement( clone ).reverseChild(); + } + bottom_control.appendChild( clone ); + return true; + }; + + page_control.last( document.ELEMENT_NODE, appendp ); + page_control.first( document.ELEMENT_NODE, appendp ); + } + }; + + /** @type {Dandelion.IDOMElement} */ + var rspd_ratio = 0; + var responsify = function( e, override ) + { + // Ratio changes would trigger content + var ratio = wsupp.clientWidth / wsupp.clientHeight; + + // Swap only on ration changes from 1 < x OR x < 1 + if( ( ratio < 1 && 1 < rspd_ratio ) || ( 1 < ratio && rspd_ratio < 1 ) || override ) + { + rspd_ratio = ratio; + debug.Info( "Responsive Event: R = " + ratio ); + + BotanJS.dispatchEvent( new BotanEvent( "Responsive", { "ratio": ratio } ) ); + } + }; + + + /////// Menu + // Contact + var expandContact = function () + { + // disable click event on the button + contact.removeEventListener( "Click", expandContact ); + // enable click event for collapse + collapse_panel.onclick = doCollapse; + + // Expand contact panel + contact.style.cursor = "default"; + contact_page.style.height = "400px"; + header.style.marginTop = "400px"; + + // Save horizon color to collapse panel + collapse_panel.style.backgroundColor = horizon.style.backgroundColor; + + horizon.style.backgroundColor = "dimgray"; + + for( var i in topButtons ) topButtons[i].removeAttribute( "active" ); + contact.setAttribute( "active", "" ); + + c_expand = true; + }; + + var doCollapse = function () + { + // disable click event for collapse + collapse_panel.onclick = null; + // enable click event on the button + contact.addEventListener( "Click", expandContact ); + + // Reverting states + contact_page.style.height + = contact.style.color + = contact.style.cursor + = header.style.marginTop + = ""; + + // Apply saved color to horizon + horizon.style.backgroundColor = collapse_panel.style.backgroundColor; + + for( var i in topButtons ) + { + if( topButtons[i].getAttribute( "master" ) ) + { + topButtons[i].setAttribute( "active", "" ); + } + else + { + topButtons[i].removeAttribute( "active" ); + } + } + + c_expand = false; + }; + + var initBackgroundParallax = function () + { + var bg = Dand.id("main_background"); + if( !bg ) + { + debug.Info( "Parallax Container is not available" ); + return; + } + // far from observer + var slide_1 = { lowerLimit: 70, upperLimit: 100 } + // bottom cloud, concentrated + , slide_2a = { lowerLimit: 0, upperLimit: 200 } + , slide_2b = { lowerLimit: 0, upperLimit: 200 } + , slide_2c = { lowerLimit: 0, upperLimit: 200 } + + , slide_3 = { lowerLimit: 20, upperLimit: 100 } + , slide_4 = { lowerLimit: 70, upperLimit: 100 } + + , cloudRange_1 = { lowerLimit: 0, upperLimit: 100, leftLimit: -10, rightLimit: 110 } + , cloudRange_2a = { lowerLimit: 180, upperLimit: 200, leftLimit: -10, rightLimit: 110 } + , cloudRange_2b = { lowerLimit: 290, upperLimit: 300, leftLimit: -10, rightLimit: 110 } + , cloudRange_2c = { lowerLimit: 390, upperLimit: 400, leftLimit: -10, rightLimit: 110 } + , cloudRange_3 = { lowerLimit: 0, upperLimit: 300, leftLimit: -10, rightLimit: 110 } + , cloudRange_4 = { lowerLimit: 80, upperLimit: 100, leftLimit: -10, rightLimit: 110 } + + , cCloudSymbol = ["\u25CF", "\u25CF", "\u25CF", "\u25CB", "\u25CB"] + , cCloudSymbol2 = ["\u25CC" ] + + , colors = ["FF1D25", "662D91", "3FA9F5", "7AC943", "FF7BAC", "603813", "FF931E"] + , i = new Date().getDay() + + , cCloud_1 = CharacterCloud.create( cCloudSymbol2, null, 10, cloudRange_1 ) + , cCloud_2a = CharacterCloud.create( cCloudSymbol, null, 10, cloudRange_2a ) + , cCloud_2b = CharacterCloud.create( cCloudSymbol, null, 20, cloudRange_2b, 10 ) + , cCloud_2c = CharacterCloud.create( cCloudSymbol, null, 40, cloudRange_2c, 5 ) + , cCloud_3 = CharacterCloud.create( cCloudSymbol2, "spin", 0, cloudRange_3 ) + , cCloud_4 = CharacterCloud.create( cCloudSymbol2, "spin cw", 0, cloudRange_4 ); + + bg.appendChild( Parallax.cssSlide( cCloud_1, 0, slide_1 ) ); + bg.appendChild( Parallax.cssSlide( cCloud_2a, 1, slide_2a ) ); + bg.appendChild( Parallax.cssSlide( cCloud_2b, 1, slide_2b ) ); + bg.appendChild( Parallax.cssSlide( cCloud_2c, 1, slide_2c ) ); + bg.appendChild( Parallax.cssSlide( cCloud_3, 2, slide_3 ) ); + bg.appendChild( Parallax.cssSlide( cCloud_4, 3, slide_4 ) ); + + IDOMElement( bg ).foreach( 1, function(e) + { + e.style.color = "#" + colors[i ++]; + if (colors.length < i) i = 0; + }); + + Parallax.attach( window, wsupp, 0.2 ); + }; + + Bootstrap.regInit( init ); +})(); diff --git a/botanjs/src/Astro/Blog/Layout/TwoColumn.css b/botanjs/src/Astro/Blog/Layout/TwoColumn.css new file mode 100644 index 0000000..d8807c9 --- /dev/null +++ b/botanjs/src/Astro/Blog/Layout/TwoColumn.css @@ -0,0 +1,102 @@ +.contentWrap { + position: relative; + width: 100%; +} + +#dockleft { + position: absolute; + z-index: 0; +} + +.main { + /* background-color: #FAFAFA; */ + vertical-align: top; + min-width: 80%; + + position: relative; +} + +/** + * Simply defined as: + * Text / Text / Text . Text / Text / Tex + **/ +ul.breadcrumb > li { display: inline-block; } +ul.breadcrumb > li:before { content: "/"; } +ul.breadcrumb > li:first-child:before, +ul.breadcrumb > li.sep + li:before, +ul.breadcrumb > li.sep:before { content: " "; } +ul.breadcrumb > li.sep:after { content: "\2022"; } + +.nav_panel { + padding-left 0.5em; + min-width: 20%; +} + +#dockright { + position: relative; + /*border-right: #76400C solid 0.2em;*/ +} + +#dockright > div { + float: right; + + margin: 0 -.3em; + padding: 0 0.2em 2em 0.2em; + display: inline-block; + width: 0; +} + +#extend_sec { + min-height: 7px; +} + +#extend_sec, #dockright { + /* Same as dockright */ + width: 100%; +} + +.vpole { + /* Should be the same as parent */ + padding: 0 0.5em; + position: relative; +} + +#bottom_control { + text-align: right; +} + +.p_navigation { + clear: both; +} + +.p_navigation > a, .p_controls > a { + color: #333; + padding: 0.2em 0.5em; +} + +.p_navigation > a { + font-size: 0.8em; + font-family: custom-sans; +} + +.p_controls > a { + color: #333; + font-size: 1.2em; +} + +.ptop { + margin-left: -1em !important; +} +/*Backgrounds*/ + +/* This style is necessary + * to prevent anchor shifting issue + */ +#main_background { + position: absolute; + overflow: hidden; + width: 100%; + height: 100%; +} + +/*End_background*/ diff --git a/botanjs/src/Astro/Blog/Layout/TwoColumn.js b/botanjs/src/Astro/Blog/Layout/TwoColumn.js new file mode 100644 index 0000000..74f64f8 --- /dev/null +++ b/botanjs/src/Astro/Blog/Layout/TwoColumn.js @@ -0,0 +1,28 @@ +(function(){ + var ns = __namespace( "Astro.Blog.Layout.TwoColumn" ); + + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + /** @type {Astro.Bootstrap} */ + var Bootstrap = __import( "Astro.Bootstrap" ); + + var init = function () + { + var rspd = Dand.id( "dockright", true ); + if( rspd ) + { + BotanJS.addEventListener( "Responsive" + /** e @type {Astro.Blog.Events.Responsive} */ + , function( e ) { + rspd.foreach( + document.ELEMENT_NODE + , e.data.ratio < 1 + ? function( elem ) { elem.style.width = "100%"; } + : function( elem ) { elem.style.width = ""; } + ); + }); + } + }; + + Bootstrap.regInit( init ); +})(); diff --git a/botanjs/src/Astro/Blog/Layout/_this.js b/botanjs/src/Astro/Blog/Layout/_this.js new file mode 100644 index 0000000..bd6fa58 --- /dev/null +++ b/botanjs/src/Astro/Blog/Layout/_this.js @@ -0,0 +1,3 @@ +(function(){ + var ns = __namespace( "Astro.Blog.Layout" ); +})(); diff --git a/botanjs/src/Astro/Bootstrap.css b/botanjs/src/Astro/Bootstrap.css new file mode 100644 index 0000000..1a3e771 --- /dev/null +++ b/botanjs/src/Astro/Bootstrap.css @@ -0,0 +1,85 @@ +/*{{{ Global Font Settings */ +@font-face{ + font-family: custom-sans; + src: local("Quicksand Regular"), + local("Quicksand-Regular"), + url("http://file.astropenguin.net/blog/fonts/Quicksand-Regular/Quicksand-Regular.woff") format("woff"), + url("http://file.astropenguin.net/blog/fonts/Quicksand-Regular/Quicksand-Regular.svg") format("svg"), + local("Helvetica-Light"), + local("Avenir"), + local("Verdana"), + local("Tahoma"), + local("Geneva"), + local("sans-serif") + ; + unicode-range: U+00-FF; +} + +@font-face{ + font-family: custom-serif; + src: url("http://file.astropenguin.net/blog/fonts/DAYROM__/DAYROM__.woff") format("woff"), + url("http://file.astropenguin.net/blog/fonts/DAYROM__/DAYROM__.svg") format("svg"), + local("Palatino Linotype"), + local("Palatino"), + local("Georgia"), + local("serif"); + unicode-range: U+00-FF; +} + +.flsf { + font-family: custom-sans; +} + +.fls { + font-family: custom-serif; +} + +.fsf { + font-family: Calibri; +} +/* End Global Font Settings }}}*/ + +/*{{{ Global Element Styles */ +pre { + font-family: monospace; +} + +textarea, input, div[contentEditable="true"], select { + outline: none; +} + +textarea, input, div[contentEditable="true"] { + cursor: auto; + border-width: 1px; + padding: 0.2em; + resize: none; + border-style: none; + background-color: #EEE; +} + +textarea:focus, input:focus, div.editable:focus { + background-color: #FFF; +} + +textarea:hover, input:hover, div.editable:hover { + background-color: #FFF; +} + +::-webkit-input-placeholder { /* WebKit browsers */ + color: #AAA; +} + +:-moz-placeholder { /* Mozilla Firefox 4 to 18 */ + color: #AAA; + opacity: 1; +} + +::-moz-placeholder { /* Mozilla Firefox 19+ */ + color: #AAA; + opacity: 1; +} + +:-ms-input-placeholder { /* Internet Explorer 10+ */ + color: #AAA !important; +} +/* End Global Element Styles }}}*/ diff --git a/botanjs/src/Astro/Bootstrap.js b/botanjs/src/Astro/Bootstrap.js new file mode 100644 index 0000000..16f5268 --- /dev/null +++ b/botanjs/src/Astro/Bootstrap.js @@ -0,0 +1,71 @@ +(function(){ + var ns = __namespace( "Astro.Bootstrap" ); + var debug = __import( "System.Debug" ); + + // __import( "Dandelion.CSSReset" ); CSS_RESERVATION + // __import( "Dandelion.CSSAnimations" ); CSS_RESERVATION + + var infs = []; + + // Init Helper, body onload + var regInitFunc = function( f ) { infs[ infs.length ] = f; }; + + var inited = false; + var consoleExists = false; + var SyntaxHighlighterExists = false; + var CConsole = "Components.Console"; + + var SyntaxHighlighter = "Libraries.SyntaxHighlighter"; + + var init = function() + { + if( inited ) return; + inited = true; + + if( consoleExists ) + { + // The + is to prevent resolver resolving this class + // since this is optional + new ( __import( CConsole ) ); + } + + var l = infs.length; + debug.Info( "[Astro.Blog] init(" + l + ")" ); + for( var i = 0; i < l; i ++ ) + { + infs[i](); + } + + if( SyntaxHighlighterExists ) + { + debug.Info( "[SyntaxHighlighter] Initializing" ); + + /** @type {Libraries.SyntaxHighlighter} */ + var synt = __import( SyntaxHighlighter ); + synt.highlight(); + } + }; + + /*{{{ Class Catching */ + BotanJS.addEventListener( "NS_EXPORT", function( e ) + { + switch( e.data.name ) + { + case CConsole: + consoleExists = true; + break; + case SyntaxHighlighter: + SyntaxHighlighterExists = true; + break; + } + }); + + try { + __import( CConsole ); + consoleExists = true; + } catch( e ) { }; + /* End Console Catching }}}*/ + + ns[ NS_EXPORT ]( EX_FUNC, "init", init ); + ns[ NS_EXPORT ]( EX_FUNC, "regInit", regInitFunc ) +})(); diff --git a/botanjs/src/Astro/Build/Components/BuildList.css b/botanjs/src/Astro/Build/Components/BuildList.css new file mode 100644 index 0000000..8aecb18 --- /dev/null +++ b/botanjs/src/Astro/Build/Components/BuildList.css @@ -0,0 +1,24 @@ +.build-list > a { + font-family: monospace; + + padding: 0.25em 0.25em; + margin: 0.25em 0; + display: block; +} + +.build-list > a[data-status^="-"] > .newsha { + color: red; +} + +.build-list > a > .newsha { + color: green; +} + +.newsha { + color: white; +} + +.build-list > a * { + padding: 0.25em 0.5em; + margin: 0.25em 0; +} diff --git a/botanjs/src/Astro/Build/Components/BuildList.js b/botanjs/src/Astro/Build/Components/BuildList.js new file mode 100644 index 0000000..d085aae --- /dev/null +++ b/botanjs/src/Astro/Build/Components/BuildList.js @@ -0,0 +1 @@ +// __namespace( "Astro.Build.Components.BuildList" ); diff --git a/botanjs/src/Astro/Build/Components/BuildReport.css b/botanjs/src/Astro/Build/Components/BuildReport.css new file mode 100644 index 0000000..18db73b --- /dev/null +++ b/botanjs/src/Astro/Build/Components/BuildReport.css @@ -0,0 +1,67 @@ +.build-report > pre { + padding: 2em; + + border-width: 1px; + + color: #C2C5C9; + background-color: #0C121B; + + word-wrap: break-word; +} + + +.build-report > pre.ok { + +} + +.build-status { + color: #888; + padding-left: 2em; + margin-bottom: 0.5em; +} +.build-status > * .ok { color: green; } +.build-status > * .failed { color: darkred; } + +.build-commit-message { + font-family: monospace; + padding: 0.2em 0; +} + +#commit-sha { color: #666; } +#commit-sha.ok { color: royalblue; } +#commit-sha.failed { color: orangered; } + +.section { + position: relative; + + margin: 1em -2em; + padding: 2em; + + background-color: black; + color: #909396; +} + +.section:hover { + color: inherit; +} + +.section:before { + content: attr(data-name); + right: 0.2em; + bottom: 0; + + font-family: custom-sans; + font-size: 2em; + + color: #C2C5C9; + + position: absolute; +} + +.section:hover:before { + color: #909396; +} + + +.status.failed { color: orangered; } +.status.ok { color: yellowgreen; } diff --git a/botanjs/src/Astro/Build/Components/BuildReport.js b/botanjs/src/Astro/Build/Components/BuildReport.js new file mode 100644 index 0000000..d84a1d9 --- /dev/null +++ b/botanjs/src/Astro/Build/Components/BuildReport.js @@ -0,0 +1,55 @@ +(function(){ + var ns = __namespace( "Astro.Build.Components.BuildReport" ); + + /** @type {System.utils.IKey} */ + var IKey = __import( "System.utils.IKey" ); + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + /** @type {Astro.Bootstrap} */ + var Bootstrap = __import( "Astro.Bootstrap" ); + /** @type {System.Debug} */ + var debug = __import( "System.Debug" ); + + var getData = __import( "System.Net.getData" ); + + var init = function() + { + var commit = Dand.id( "commit-sha", true ); + var putCommitMessage = function( e ) + { + Dand.id( "commit-message" ).innerHTML = e || "Failed to load message"; + commit.setAttribute( new IKey( "class", e ? "ok" : "failed" ) ) + }; + + sanitizeReport(); + + getData( "/" + commit.getDAttribute( "project" ) + "/commit-message/" + commit.getDAttribute( "sha" ), putCommitMessage, putCommitMessage ); + }; + + var sanitizeReport = function() + { + var buildMessage = Dand.id( "build-message" ); + var message = buildMessage.innerHTML.replace( ); + + var sRegEx = /[\r\n]*{CI_SECTION_START}[\r\n\s]*(.*)[\r\n]*/g; + var eRegEx = /[\r\n]*{CI_SECTION_END}[\r\n]*/g; + + var sCount = ( message.match( sRegEx ) || [] ).length; + if( !sCount ) return; + + if( sCount != ( message.match( eRegEx ) || [] ).length ) + { + debug.Error( new Error( "Section Flag count mismatch" ) ); + return; + } + + buildMessage.innerHTML = message + .replace( sRegEx, "
" )
+			.replace( eRegEx, "
" ) + .replace( /: (failed|ok)\n/g, ": $1\n" ) + ; + + }; + + Bootstrap.regInit( init ); +})(); diff --git a/botanjs/src/Astro/Build/Components/ItemList.css b/botanjs/src/Astro/Build/Components/ItemList.css new file mode 100644 index 0000000..18a9467 --- /dev/null +++ b/botanjs/src/Astro/Build/Components/ItemList.css @@ -0,0 +1,59 @@ +div.project-list > a * { + -webkit-transition: all .25s; + -moz-transition: all .25s; + -o-transition: all .25s; + transition: all .25s; +} + +div.project-list > a { + width: 100%; + height: 50px; + + color: #909396; + background-color: #48494A; + + font-size: 4em; + + text-align: right; + + display: block; + overflow: hidden; + + position: relative; + + margin: 0.2em 0; + + -webkit-transition: all .5s; + -moz-transition: all .5s; + -o-transition: all .5s; + transition: all .5s; + + box-sizing: border-box; +} + +div.project-list > a:after { + content: attr(data-desc); + + color: #C2C5C9; + font-size: 0.25em; + padding: 0.25em 0.5em; + + top: 0; + + display: block; + + position: absolute; + + -webkit-transition: all .5s; + -moz-transition: all .5s; + -o-transition: all .5s; + transition: all .5s; +} + +div.project-list > a:hover { + padding-right: 0.25em; +} + +div.project-list > a:hover:after { + padding-left: 1em; +} diff --git a/botanjs/src/Astro/Build/Components/ItemList.js b/botanjs/src/Astro/Build/Components/ItemList.js new file mode 100644 index 0000000..0e25899 --- /dev/null +++ b/botanjs/src/Astro/Build/Components/ItemList.js @@ -0,0 +1 @@ +// __namespace( "Astro.Build.Components.ItemList" ); diff --git a/botanjs/src/Astro/Build/Element/Footer.css b/botanjs/src/Astro/Build/Element/Footer.css new file mode 100644 index 0000000..1bd0f35 --- /dev/null +++ b/botanjs/src/Astro/Build/Element/Footer.css @@ -0,0 +1,12 @@ +footer:before { + content: ''; + + width: 100%; + height: 0.5em; + + background-color: #3A68B2; + + display: block; +} + +.footer_bg { width: 75%; } diff --git a/botanjs/src/Astro/Build/Element/Footer.js b/botanjs/src/Astro/Build/Element/Footer.js new file mode 100644 index 0000000..35a52bc --- /dev/null +++ b/botanjs/src/Astro/Build/Element/Footer.js @@ -0,0 +1,2 @@ +// __namespace( "Astro.Build.Element.Footer" ); +// __import( "Astro.Common.Element.Footer" ); diff --git a/botanjs/src/Astro/Build/Element/Header.css b/botanjs/src/Astro/Build/Element/Header.css new file mode 100644 index 0000000..37e9b3a --- /dev/null +++ b/botanjs/src/Astro/Build/Element/Header.css @@ -0,0 +1,87 @@ +header { + position: relative; + border-bottom: 0.5em solid #3A68B2; +} + +header:before { + content: ''; + + width: 100%; + + bottom: 0; + + display: block; + position: absolute; +} + +.left, .right { + width: 50%; + display: block; +} + +.right { + position: absolute; + top: 0; + right: 0; +} + +nav { + width: 75%; + margin: 0 auto; +} + +nav div ul { + list-style: none; + font-size: 1.5em; +} + +nav div ul:after { + content: ""; + clear: both; + display: block; +} + +nav div ul ul { + top: 100%; + left: 0; + + min-width: 5em; + + display: none; + position: absolute; +} +nav div ul li { + padding: 0.25em 0.5em 0 0.25em; + + float: right; + + position: relative; +} + +nav div ul li:hover { +} + +nav div ul li a { + color: #C2C5C9; +} + +nav div.right ul { float: right; } + + nav div ul li:hover > ul { + display: block; + } + +svg.banner-deco { + float: right; + width: 68em; + height: 10em; +} + +nav sup { + font-size: 50%; + vertical-align: top; +} + +.header-padder { + clear: both; +} diff --git a/botanjs/src/Astro/Build/Element/Header.js b/botanjs/src/Astro/Build/Element/Header.js new file mode 100644 index 0000000..ff2238d --- /dev/null +++ b/botanjs/src/Astro/Build/Element/Header.js @@ -0,0 +1 @@ +// __namespace( "Astro.Build.Element.Header" ); diff --git a/botanjs/src/Astro/Build/Layout/MainFrame.css b/botanjs/src/Astro/Build/Layout/MainFrame.css new file mode 100644 index 0000000..89843cc --- /dev/null +++ b/botanjs/src/Astro/Build/Layout/MainFrame.css @@ -0,0 +1,86 @@ +html, body { height: 100%; } + +html { background-color: #222; } +body { + font-family: custom-sans; +} + +header, footer { background-color: #0C121B; } + +.content-wrapper { + position: relative; + + margin: 0 auto; + padding: 2em; + + width: 75%; + + background-color: rgba( 255, 255, 255, 0.6 ); +} + +.begin-wrapper { + position: relative; + + min-height: 100%; + color: #0C121B; + background-color: white; /*#C2C5C9*/ + + overflow: hidden; +} + +.block_deco { + position: absolute; + + width: 100%; + height: 400px; + + bottom: 1000%;; + right: -27px; + + background: url("http://file.astropenguin.net/blog/layout-images/build - blockdeco.png") no-repeat right bottom; +} + +* html .begin-wrapper { height: 100%; } + +.working-in-progress { + width: 100%; + height: 2em; + + color: white; + background-color: black; + background-image: repeating-linear-gradient(-35deg, transparent, transparent 35px, yellow 35px, yellow 70px); + + position: relative; + display: block; +} + +a { + color: #3A68B2;/*#48494A;*/ + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +h1, h2, h3, h4 { font-family: custom-serif; } + +h1 { font-size: 2em; } +h2 { font-size: 1.5em; } +h3 { font-size: 1.2em; } + +ul.breadcrumb > li { + display: inline-block; +} + +ul.breadcrumb > li:first-child:before { + content: ""; + position: absolute; +} + +ul.breadcrumb > li:before { + content: ">"; + color: rgba( 0, 0, 0, 0.2 ); +} + +.greyed { color: #C2C5C9; } diff --git a/botanjs/src/Astro/Build/Layout/MainFrame.js b/botanjs/src/Astro/Build/Layout/MainFrame.js new file mode 100644 index 0000000..7723092 --- /dev/null +++ b/botanjs/src/Astro/Build/Layout/MainFrame.js @@ -0,0 +1,88 @@ +(function(){ + var ns = __namespace( "Astro.Build.Layout.MainFrame" ); + + var Dand = __import( "Dandelion" ); + /** @type {Astro.Bootstrap} */ + var Bootstrap = __import( "Astro.Bootstrap" ); + /** @type {Dandelion.IDOMElement} */ + var IDOMElement = __import( "Dandelion.IDOMElement" ); + /** @type {Astro.Mechanism.CharacterCloud} */ + var CharacterCloud = __import( "Astro.Mechanism.CharacterCloud" ); + /** @type {Astro.Mechanism.Parallax} */ + var Parallax = __import( "Astro.Mechanism.Parallax" ); + /** @type {Dandelion.Window} */ + var wsupp = __import( "Dandelion.Window" ); + + // __import( "Dandelion.CSSReset" ); CSS_RESERVATION + // __import( "Dandelion.CSSAnimations" ); CSS_RESERVATION + + var init = function () + { + var padder = Dand.id( "padder" ); + var wrapper = Dand.id( "wrapper" ); + var footer = Dand.tag( "footer" ); + + var fheight = 0; + if( footer.length ) + { + footer = footer[0]; + fheight = ( footer.scrollHeight || footer.offsetHeight ); + padder.style.height = fheight + "px"; + wrapper.style.marginBottom = "-" + padder.style.height; + } + + block_deco.style.bottom = ( fheight - 72 ) + "px"; + initBackgroundParallax(); + }; + + var initBackgroundParallax = function () + { + var bg = Dand.id("main_background") + // far from observer + , slide_1 = { lowerLimit: 70, upperLimit: 100 } + // bottom cloud, concentrated + , slide_2a = { lowerLimit: 0, upperLimit: 200 } + , slide_2b = { lowerLimit: 0, upperLimit: 200 } + , slide_2c = { lowerLimit: 0, upperLimit: 200 } + + , slide_3 = { lowerLimit: 20, upperLimit: 100 } + , slide_4 = { lowerLimit: 70, upperLimit: 100 } + + , cloudRange_1 = { lowerLimit: 0, upperLimit: 100, leftLimit: -10, rightLimit: 110 } + , cloudRange_2a = { lowerLimit: 0, upperLimit: 200, leftLimit: -10, rightLimit: 110 } + , cloudRange_2b = { lowerLimit: 0, upperLimit: 300, leftLimit: -10, rightLimit: 110 } + , cloudRange_2c = { lowerLimit: 0, upperLimit: 400, leftLimit: -10, rightLimit: 110 } + , cloudRange_3 = { lowerLimit: 0, upperLimit: 300, leftLimit: -10, rightLimit: 110 } + , cloudRange_4 = { lowerLimit: 80, upperLimit: 100, leftLimit: -10, rightLimit: 110 } + + , cCloudSymbol = ["\u25C6", "\u25C7", "\u25C8"] + , cCloudSymbol2 = ["\u25C6", "\u25C7"] + + , colors = ["909396", "0C121B", "3A68B2", "48494A"] + , i = new Date().getDay() + + , cCloud_1 = CharacterCloud.create( cCloudSymbol2, null, 20, cloudRange_1 ) + , cCloud_2a = CharacterCloud.create( cCloudSymbol, null, 20, cloudRange_2a ) + , cCloud_2b = CharacterCloud.create( cCloudSymbol, null, 30, cloudRange_2b, 10 ) + , cCloud_2c = CharacterCloud.create( cCloudSymbol, null, 80, cloudRange_2c, 5 ) + , cCloud_3 = CharacterCloud.create( cCloudSymbol2, null, 20, cloudRange_3 ) + , cCloud_4 = CharacterCloud.create( cCloudSymbol2, null, 20, cloudRange_4 ); + + bg.appendChild( Parallax.cssSlide( cCloud_1, 0, slide_1 ) ); + bg.appendChild( Parallax.cssSlide( cCloud_2a, 1, slide_2a ) ); + bg.appendChild( Parallax.cssSlide( cCloud_2b, 1, slide_2b ) ); + bg.appendChild( Parallax.cssSlide( cCloud_2c, 1, slide_2c ) ); + bg.appendChild( Parallax.cssSlide( cCloud_3, 2, slide_3 ) ); + bg.appendChild( Parallax.cssSlide( cCloud_4, 3, slide_4 ) ); + + IDOMElement( bg ).foreach( 1, function(e) + { + e.style.color = "#" + colors[i ++]; + if (colors.length < i) i = 0; + }); + + Parallax.attach( window, wsupp, 0.3 ); + }; + + Bootstrap.regInit( init ); +})(); diff --git a/botanjs/src/Astro/Build/Page/About.css b/botanjs/src/Astro/Build/Page/About.css new file mode 100644 index 0000000..06e68f7 --- /dev/null +++ b/botanjs/src/Astro/Build/Page/About.css @@ -0,0 +1,11 @@ +ol.numlist { + counter-reset: item; +} + +ol.numlist > li:before { + display: inline-block; + content: counter(item); + counter-increment: item; + width: 1.2em; + text-align: center; +} diff --git a/botanjs/src/Astro/Build/Page/About.js b/botanjs/src/Astro/Build/Page/About.js new file mode 100644 index 0000000..9860667 --- /dev/null +++ b/botanjs/src/Astro/Build/Page/About.js @@ -0,0 +1 @@ +// var ns = __namespace( "Astro.Build.Page.About" ); diff --git a/botanjs/src/Astro/Build/Page/Index.css b/botanjs/src/Astro/Build/Page/Index.css new file mode 100644 index 0000000..a448192 --- /dev/null +++ b/botanjs/src/Astro/Build/Page/Index.css @@ -0,0 +1,24 @@ +.site-news { font-family: monospace; } +.site-news > span { display: block; } + +.rbuilds > a { display: block; } +.rbuilds > a > span { + padding: 0 0.5em; +} + +.bstatus { + color: red; + margin: 0 0.2em; +} + +.bstatus[data-ok=true] { + color: green; +} + +.bstatus:before { + content: "Failed"; +} + +.bstatus[data-ok=true]:before { + content: "OK"; +} diff --git a/botanjs/src/Astro/Build/Page/Index.js b/botanjs/src/Astro/Build/Page/Index.js new file mode 100644 index 0000000..54f67fd --- /dev/null +++ b/botanjs/src/Astro/Build/Page/Index.js @@ -0,0 +1 @@ +// var ns = __namespace( "Astro.Build.Page.Index" ); diff --git a/botanjs/src/Astro/Build/Page/_this.css b/botanjs/src/Astro/Build/Page/_this.css new file mode 100644 index 0000000..412192b --- /dev/null +++ b/botanjs/src/Astro/Build/Page/_this.css @@ -0,0 +1,5 @@ +.panel { + padding: 0.5em; + display: block; +} + diff --git a/botanjs/src/Astro/Common/Element/Footer.css b/botanjs/src/Astro/Common/Element/Footer.css new file mode 100644 index 0000000..cd0b895 --- /dev/null +++ b/botanjs/src/Astro/Common/Element/Footer.css @@ -0,0 +1,36 @@ +footer { + width: 100%; + position: relative; +} + +.footer_bg { + margin: 0 auto; + height: 100%; +} + +.flink_section { + font-family: custom-sans; + float: left; + padding: 0.5em; +} + +.flink_section > span { + font-size: 1.5em; + color: white; +} + +.flink_section > a { + font-size: 1em; + color: #999; + display: block; +} + +.copysign { + clear: both; + color: white; + text-align: right; +} + +.copysign > a { + color: #BBB; +} diff --git a/botanjs/src/Astro/Common/Element/Footer.js b/botanjs/src/Astro/Common/Element/Footer.js new file mode 100644 index 0000000..2cf2aaa --- /dev/null +++ b/botanjs/src/Astro/Common/Element/Footer.js @@ -0,0 +1 @@ +// __namespace( "Astro.Common.Element.Footer" ); diff --git a/botanjs/src/Astro/Mechanism/CharacterCloud.css b/botanjs/src/Astro/Mechanism/CharacterCloud.css new file mode 100644 index 0000000..4e11707 --- /dev/null +++ b/botanjs/src/Astro/Mechanism/CharacterCloud.css @@ -0,0 +1,7 @@ +.characterCloud { + top: 0; + left: 0; + width: 100%; + height: 100%; + position: absolute; +} \ No newline at end of file diff --git a/botanjs/src/Astro/Mechanism/CharacterCloud.js b/botanjs/src/Astro/Mechanism/CharacterCloud.js new file mode 100644 index 0000000..df2dccf --- /dev/null +++ b/botanjs/src/Astro/Mechanism/CharacterCloud.js @@ -0,0 +1,77 @@ +(function(){ + var ns = __namespace( "Astro.Mechanism.CharacterCloud" ); + + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + + var CharacterCloud = {}; + + // Character cloud creates a cloud of character with randomized properties + var create = function( ch, char_class, size, cloudRange, charSize ) + { + var cloudMap = Dand.wrapc( "characterCloud" ) + , charElmt + , rx, ry, rs + , cs = charSize || 15 + , l_l = cloudRange.lowerLimit + // vertical range + , vr = cloudRange.upperLimit - l_l + , lf_l = cloudRange.leftLimit + // horizontal range + , hr = cloudRange.rightLimit + + , charStack = ( ch instanceof Array ); + ; + + + // The loop is CPU intensive + // we need to focus on reducing the CPU usage + if( charStack ) + { + var l = ch.length; + for(var i = 0; i < size; i ++) + { + rx = String( lf_l + Math.random()*hr ) + "%"; + ry = String( l_l + Math.random()*vr ) + "%"; + rs = Math.random()*cs; + charElmt = Dand.wrap('span', null, char_class, ch[Math.floor(Math.random()*l)]); + + var cE_style = charElmt.style; + + cE_style.position = "absolute"; + cE_style.left = rx; + cE_style.top = ry; + // cE_style.opacity = Math.random() + ""; + cE_style.fontSize = rs + "em"; + cE_style.marginTop = marginLeft = String( -0.5*rs ) + "em"; + + cloudMap.appendChild(charElmt); + } + } + else + { + for(var i = 0; i < size; i ++) + { + rx = String(lf_l + Math.random()*hr) + "%"; + ry = String(l_l + Math.random()*vr) + "%"; + rs = Math.random()*15; + charElmt = Dand.wrap('span', null, char_class, ch); + + var cE_style = charElmt.style; + + cE_style.position = "absolute"; + cE_style.left = rx; + cE_style.top = ry; + // cE_style.opacity = String(Math.random()); + cE_style.fontSize = String(rs) + "em"; + cE_style.marginTop = marginLeft = String( -0.5*rs ) + "em"; + + cloudMap.appendChild( charElmt ); + } + } + + return cloudMap; + }; + + ns[ NS_EXPORT ]( EX_FUNC, "create", create ); +})(); diff --git a/botanjs/src/Astro/Mechanism/Parallax.css b/botanjs/src/Astro/Mechanism/Parallax.css new file mode 100644 index 0000000..103e784 --- /dev/null +++ b/botanjs/src/Astro/Mechanism/Parallax.css @@ -0,0 +1,6 @@ +.parallaxCSSSlideLayer { + position: absolute; + width: 100%; + height: 100%; + top: 0; +} \ No newline at end of file diff --git a/botanjs/src/Astro/Mechanism/Parallax.js b/botanjs/src/Astro/Mechanism/Parallax.js new file mode 100644 index 0000000..a3c414b --- /dev/null +++ b/botanjs/src/Astro/Mechanism/Parallax.js @@ -0,0 +1,89 @@ +(function(){ + var ns = __namespace( "Astro.Mechanism.Parallax" ); + + /** @type {System.Cycle} */ + var Cycle = __import( "System.Cycle" ); + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + + var Parallax = { + totalCSSSlide: 0 + }; + + var cssSlide = function( element, slide_index, distance ) + { + // The concept is drawn in physical book, will make a blog post for this:) + var name, s; + if( !( s = Parallax[ name = "s" + slide_index ] ) ) + { + s = Parallax[name] = []; + Parallax.totalCSSSlide ++; + } + return ( + s[ s.length ] = { + element: Dand.wrapc( "parallaxCSSSlideLayer slideTransitionOverride", element ) + // vertical range + , verticalRange: distance.upperLimit - distance.lowerLimit - 100 + // horizontal range + , horizontalRange: distance.rightLimit - distance.leftLimit - 100 + } + ).element + ; + }; + + var verticalSlideTo = function( slide_index ) + { + var s, l = Parallax.totalCSSSlide; + for( var i = 0; i < l; i ++ ) + { + if(i <= slide_index) + { + s = Parallax["s" + i]; + for( var j = 0, k; j < s.length; j ++ ) + { + k = s[j]; + k.element.style.top = String(-k.verticalRange*((slide_index + 1))) + "%"; + } + } + else break; + } + }; + + var attach = function ( eDispatcher, sSupplier, opacityModifier ) + { + var opacityModifier = ( opacityModifier == undefined ) ? 1 : opacityModifier + 0; + var s, l = Parallax.totalCSSSlide; + + for( var i = 0; i < l; i ++ ) + { + s = Parallax["s" + i]; + for( var j = 0, k; j < s.length; j ++ ) + { + k = s[j]; + k.element.style.opacity = ( ( 0.35 + 0.55 * i / l ) * opacityModifier ) + ""; + } + } + + Cycle.perma( + "PARALLAXSCR" + , function() + { + var p = sSupplier.scrollTop/(sSupplier.scrollHeight - sSupplier.clientHeight); + for(var i = 0; i < l; i ++) + { + s = Parallax["s" + i]; + for(var j = 0, k; j < s.length; j ++) + { + k = s[j]; + k.element.style.top = String(-k.verticalRange*((j + 1)*p)) + "%"; + } + } + } + , 15 + ); + }; + + ns[ NS_EXPORT ]( EX_FUNC, "cssSlide", cssSlide ); + ns[ NS_EXPORT ]( EX_FUNC, "verticalSlideTo", verticalSlideTo ); + ns[ NS_EXPORT ]( EX_FUNC, "attach", attach ); +})(); diff --git a/botanjs/src/Astro/utils/Date.js b/botanjs/src/Astro/utils/Date.js new file mode 100644 index 0000000..1a82218 --- /dev/null +++ b/botanjs/src/Astro/utils/Date.js @@ -0,0 +1,140 @@ +(function(){ + var ns = __namespace( "Astro.utils.Date" ); + + //// Static utilities + // Chinese char for 0-9 + var cChar = [ "12295", "19968", "20108", "19977", "22235", "20116", "20845", "19971", "20843", "20061", "21313" ]; + // Capital month + var CAP_MONTHS = [ false, false, false, true, false, true, false, false, true, false, true, false ]; + var MONTH_ABBR = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; + var MONTH = [ + "January" + , "February" + , "March" + , "April" + , "May" + , "June" + , "July" + , "August" + , "September" + , "October" + , "November" + , "December" + ]; + var DAY_ABBR = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; + var DAY = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; + + // get responding chinese char from number + var cCountDay = function (num) + { + str = num.toString(); + if( num != 0 && num % 10 == 0 ) + { + return ( num == 10 ? "" : String.fromCharCode( cChar[ str[0] ] ) ) + + String.fromCharCode( cChar[10] ); + } + else if( num < 10 ) + { + return String.fromCharCode( cChar[ str[0] ] ); + } + else if( num < 20 ) + { + return String.fromCharCode( cChar[10] ) + + String.fromCharCode( cChar[ str[1] ] ); + } + + return String.fromCharCode( cChar[ str[0] ] ) + + String.fromCharCode( cChar[10] ) + + String.fromCharCode( cChar[ str[1] ] ); + }; + + + // Input yyyy-mm-dd small small + // output dd mmmm yyyy DDDDD + var prettyDay = function ( b, sMon, sDay ) + { + var c = b.split("-"); + var d = new Date( c[0], c[1] - 1, c[2] ); + + return d.getDate() + " " + + ( sMon ? MONTH_ABBR[ d.getMonth() ] : MONTH[ d.getMonth() ] ) + " " + + d.getFullYear() + " " + + ( sDay ? DAY_ABBR[ d.getDay() ] : DAY[ d.getDay() ] ) + ; + }; + + // Small month stamp: output dd-mmm-yyyy + var smstamp = function ( dateObj ) + { + return dateObj.getDate() + "-" + MONTH_ABBR[ dateObj.getMonth() ] + "-" + dateObj.getFullYear(); + }; + + // Pretty format XXth MMMM, YYYY + var pretty = function( dateObj, plain ) + { + return String( dateObj.getDate() ) + + ( plain ? "" : "" ) + + getOrdinalSuffix( dateObj.getDate() ) + + ( plain ? " " : " " ) + + MONTH[ dateObj.getMonth() ] + + ", " + + String( dateObj.getFullYear() ) + ; + }; + + // returns a timespan + // Input Array [ yyyy, mm, dd ], [ yyyy, mm, dd ] + var diff = function( from, to ) + { + return new Date( + new Date( to[0], to[1], to[2] ).getTime() + - new Date( from[0], from[1], from[2] ).getTime() + ); + }; + + // Get a chinese date format + var chinese = function ( date ) + { + var str = date.getFullYear().toString(); + var datestmp = ""; + + for(i in str) + { + datestmp += String.fromCharCode( cChar[ str[i] ] ); + } + + datestmp += String.fromCharCode("24180"); + + datestmp += cCountDay(date.getMonth() + 1) + + String.fromCharCode("26376") + + cCountDay(date.getDate()) + + String.fromCharCode("26085"); + + return datestmp; + }; + + // returns a suffix string + // st, nd, rd, th + var getOrdinalSuffix = function(day) + { + if (day < 4 || ( 20 < day && day < 24 )) { + if (day == 1 || day == 21) return "st"; + else if (day == 2 || day == 22) return "nd"; + else if (day == 3 || day == 23) return "rd"; + } + else if (day == 31) return "st"; + return "th"; + }; + + ns[ NS_EXPORT ]( EX_FUNC, "pretty", pretty ); + ns[ NS_EXPORT ]( EX_FUNC, "prettyDay", prettyDay ); + ns[ NS_EXPORT ]( EX_FUNC, "diff", diff ); + ns[ NS_EXPORT ]( EX_FUNC, "smstamp", smstamp ); + ns[ NS_EXPORT ]( EX_FUNC, "chinese", chinese ); + + ns[ NS_EXPORT ]( EX_CONST, "CAP_MONTHS", CAP_MONTHS ); + ns[ NS_EXPORT ]( EX_CONST, "MONTH", MONTH ); + ns[ NS_EXPORT ]( EX_CONST, "MONTH_ABBR", MONTH_ABBR ); + ns[ NS_EXPORT ]( EX_CONST, "DAY", DAY ); + ns[ NS_EXPORT ]( EX_CONST, "DAY_ABBR", DAY_ABBR ); +})(); diff --git a/botanjs/src/Astro/utils/_this.js b/botanjs/src/Astro/utils/_this.js new file mode 100644 index 0000000..c17dfdb --- /dev/null +++ b/botanjs/src/Astro/utils/_this.js @@ -0,0 +1,3 @@ +(function(){ + var ns = __namespace( "Astro.utils" ); +})(); diff --git a/botanjs/src/externs/Astro.Blog.AstroEdit.Article.js b/botanjs/src/externs/Astro.Blog.AstroEdit.Article.js new file mode 100644 index 0000000..f4c3720 --- /dev/null +++ b/botanjs/src/externs/Astro.Blog.AstroEdit.Article.js @@ -0,0 +1,18 @@ +/** @constructor */ +Astro.Blog.AstroEdit.Article = function(){}; +/** @type {Function} */ +Astro.Blog.AstroEdit.Article.saveOrBackup; +/** @type {Function} */ +Astro.Blog.AstroEdit.Article.load; +/** @type {Function} */ +Astro.Blog.AstroEdit.Article.getArticleId; +/** @type {Function} */ +Astro.Blog.AstroEdit.Article.preview; +/** @type {Function} */ +Astro.Blog.AstroEdit.Article.invoke; +/** @type {Function} */ +Astro.Blog.AstroEdit.Article.saveAndPublish; +/** @type {Function} */ +Astro.Blog.AstroEdit.Article.drop; +/** @type {Function} */ +Astro.Blog.AstroEdit.Article.updateContent; diff --git a/botanjs/src/externs/Astro.Blog.AstroEdit.Tag.js b/botanjs/src/externs/Astro.Blog.AstroEdit.Tag.js new file mode 100644 index 0000000..a3c6b92 --- /dev/null +++ b/botanjs/src/externs/Astro.Blog.AstroEdit.Tag.js @@ -0,0 +1,6 @@ +/** @constructor */ +Astro.Blog.AstroEdit.Tag = function(){}; +/** @type {Function} */ +Astro.Blog.AstroEdit.Tag.getTags; +/** @type {Function} */ +Astro.Blog.AstroEdit.Tag.setTags; diff --git a/botanjs/src/externs/Astro.Blog.AstroEdit.Visualizer.Snippet.Model.js b/botanjs/src/externs/Astro.Blog.AstroEdit.Visualizer.Snippet.Model.js new file mode 100644 index 0000000..63e6b2d --- /dev/null +++ b/botanjs/src/externs/Astro.Blog.AstroEdit.Visualizer.Snippet.Model.js @@ -0,0 +1,6 @@ +/** @constructor */ +Astro.Blog.AstroEdit.Visualizer.Snippet.Model = function(){}; +/** @type {Function} */ +Astro.Blog.AstroEdit.Visualizer.Snippet.Model.compile; +/** @type {Object} */ +Astro.Blog.AstroEdit.Visualizer.Snippet.Model.alias; diff --git a/botanjs/src/externs/Astro.Blog.AstroEdit.Visualizer.Snippet.js b/botanjs/src/externs/Astro.Blog.AstroEdit.Visualizer.Snippet.js new file mode 100644 index 0000000..f8b9308 --- /dev/null +++ b/botanjs/src/externs/Astro.Blog.AstroEdit.Visualizer.Snippet.js @@ -0,0 +1,6 @@ +/** @constructor */ +Astro.Blog.AstroEdit.Visualizer.Snippet = function(){}; +/** @type {Function} */ +Astro.Blog.AstroEdit.Visualizer.Snippet.escapeStr; +/** @type {Function} */ +Astro.Blog.AstroEdit.Visualizer.Snippet.compileProp; diff --git a/botanjs/src/externs/Astro.Blog.AstroEdit.Visualizer.js b/botanjs/src/externs/Astro.Blog.AstroEdit.Visualizer.js new file mode 100644 index 0000000..4cf2549 --- /dev/null +++ b/botanjs/src/externs/Astro.Blog.AstroEdit.Visualizer.js @@ -0,0 +1,12 @@ +/** @constructor */ +Astro.Blog.AstroEdit.Visualizer = function(){}; +/** @type {Function} */ +Astro.Blog.AstroEdit.Visualizer.setContentDiv; +/** @type {Function} */ +Astro.Blog.AstroEdit.Visualizer.saveRaw; +/** @type {Function} */ +Astro.Blog.AstroEdit.Visualizer.visualizeData; +/** @type {Function} */ +Astro.Blog.AstroEdit.Visualizer.saveSelection; +/** @type {Function} */ +Astro.Blog.AstroEdit.Visualizer.restoreSelection; diff --git a/botanjs/src/externs/Astro.Blog.AstroEdit.js b/botanjs/src/externs/Astro.Blog.AstroEdit.js new file mode 100644 index 0000000..9ce5259 --- /dev/null +++ b/botanjs/src/externs/Astro.Blog.AstroEdit.js @@ -0,0 +1,2 @@ +/** @type {Object} */ +Astro.Blog.AstroEdit = {}; diff --git a/botanjs/src/externs/Astro.Blog.Components.Bubble.js b/botanjs/src/externs/Astro.Blog.Components.Bubble.js new file mode 100644 index 0000000..9e401d3 --- /dev/null +++ b/botanjs/src/externs/Astro.Blog.Components.Bubble.js @@ -0,0 +1,18 @@ +/** @constructor */ +Astro.Blog.Components.Bubble = function() {}; + +/** @type {Function} */ +Astro.Blog.Components.Bubble.prototype.init; + +/** @type {Function} */ +Astro.Blog.Components.Bubble.prototype.blurp; + +/** @type {Function} + * @param {String} mesg + */ +Astro.Blog.Components.Bubble.prototype.pop = function( mesg ) { }; + +/** @type {Function} + * @param {String} color + */ +Astro.Blog.Components.Bubble.prototype.setColor = function( color ) { }; diff --git a/botanjs/src/externs/Astro.Blog.Components.Calendar.js b/botanjs/src/externs/Astro.Blog.Components.Calendar.js new file mode 100644 index 0000000..40132fa --- /dev/null +++ b/botanjs/src/externs/Astro.Blog.Components.Calendar.js @@ -0,0 +1,13 @@ +/** @constructor */ +Astro.Blog.Components.Calendar = function() {}; + +/** @type {Function}*/ +Astro.Blog.Components.Calendar.init; +/** @type {Function}*/ +Astro.Blog.Components.Calendar.prevMon; +/** @type {Function}*/ +Astro.Blog.Components.Calendar.nextMon; +/** @type {Function}*/ +Astro.Blog.Components.Calendar.pop; +/** @type {Function}*/ +Astro.Blog.Components.Calendar.draw; diff --git a/botanjs/src/externs/Astro.Blog.Components.js b/botanjs/src/externs/Astro.Blog.Components.js new file mode 100644 index 0000000..9103a42 --- /dev/null +++ b/botanjs/src/externs/Astro.Blog.Components.js @@ -0,0 +1,2 @@ +/** @constructor */ +Astro.Blog.Components = function() {}; diff --git a/botanjs/src/externs/Astro.Blog.Config.js b/botanjs/src/externs/Astro.Blog.Config.js new file mode 100644 index 0000000..d177e9c --- /dev/null +++ b/botanjs/src/externs/Astro.Blog.Config.js @@ -0,0 +1,5 @@ +/** @constructor */ +Astro.Blog.Config = function() {}; + +/** @type {Function} */ +Astro.Blog.Config.get; diff --git a/botanjs/src/externs/Astro.Blog.Events.Responsive.js b/botanjs/src/externs/Astro.Blog.Events.Responsive.js new file mode 100644 index 0000000..57eb4e9 --- /dev/null +++ b/botanjs/src/externs/Astro.Blog.Events.Responsive.js @@ -0,0 +1,8 @@ +/** @type {Object} */ +Astro.Blog.Events.Responsive = {}; +/** @type {Object} */ +Astro.Blog.Events.Responsive.data = {}; +/** @type {Number} */ +Astro.Blog.Events.Responsive.data.ratio = {}; + + diff --git a/botanjs/src/externs/Astro.Blog.Events.js b/botanjs/src/externs/Astro.Blog.Events.js new file mode 100644 index 0000000..8f6bdd7 --- /dev/null +++ b/botanjs/src/externs/Astro.Blog.Events.js @@ -0,0 +1,2 @@ +/** @type {Object} */ +Astro.Blog.Events = {}; diff --git a/botanjs/src/externs/Astro.Blog.js b/botanjs/src/externs/Astro.Blog.js new file mode 100644 index 0000000..c54f099 --- /dev/null +++ b/botanjs/src/externs/Astro.Blog.js @@ -0,0 +1,2 @@ +/** @constructor */ +Astro.Blog = function() {}; diff --git a/botanjs/src/externs/Astro.Bootstrap.js b/botanjs/src/externs/Astro.Bootstrap.js new file mode 100644 index 0000000..2be6d8e --- /dev/null +++ b/botanjs/src/externs/Astro.Bootstrap.js @@ -0,0 +1,8 @@ +/** @constructor */ +Astro.Bootstrap = function() {}; + +/** @type {Function} */ +Astro.Bootstrap.init; + +/** @type {Function} */ +Astro.Bootstrap.regInit; diff --git a/botanjs/src/externs/Astro.Mechanism.CharacterCloud.js b/botanjs/src/externs/Astro.Mechanism.CharacterCloud.js new file mode 100644 index 0000000..bc81c32 --- /dev/null +++ b/botanjs/src/externs/Astro.Mechanism.CharacterCloud.js @@ -0,0 +1,5 @@ +/** @constructor */ +Astro.Mechanism.CharacterCloud = function() {}; + +/** @type {Function} */ +Astro.Mechanism.CharacterCloud.create; diff --git a/botanjs/src/externs/Astro.Mechanism.Parallax.js b/botanjs/src/externs/Astro.Mechanism.Parallax.js new file mode 100644 index 0000000..719bd2e --- /dev/null +++ b/botanjs/src/externs/Astro.Mechanism.Parallax.js @@ -0,0 +1,9 @@ +/** @constructor */ +Astro.Mechanism.Parallax = function() {}; + +/** @type {Function} */ +Astro.Mechanism.Parallax.cssSlide; +/** @type {Function} */ +Astro.Mechanism.Parallax.verticalSlideTo; +/** @type {Function} */ +Astro.Mechanism.Parallax.attach; diff --git a/botanjs/src/externs/Astro.Mechanism.js b/botanjs/src/externs/Astro.Mechanism.js new file mode 100644 index 0000000..da46090 --- /dev/null +++ b/botanjs/src/externs/Astro.Mechanism.js @@ -0,0 +1,2 @@ +/** @constructor */ +Astro.Mechanism = function() {}; diff --git a/botanjs/src/externs/Astro.js b/botanjs/src/externs/Astro.js new file mode 100644 index 0000000..609cac1 --- /dev/null +++ b/botanjs/src/externs/Astro.js @@ -0,0 +1,2 @@ +/** @constructor */ +var Astro = function() {}; diff --git a/botanjs/src/externs/Astro.utils.Date.js b/botanjs/src/externs/Astro.utils.Date.js new file mode 100644 index 0000000..d753b1e --- /dev/null +++ b/botanjs/src/externs/Astro.utils.Date.js @@ -0,0 +1,24 @@ +/** @constructor */ +Astro.utils.Date = function() {}; + +/** @type {Function}*/ +Astro.utils.Date.pretty; +/** @type {Function}*/ +Astro.utils.Date.prettyDay; +/** @type {Function}*/ +Astro.utils.Date.diff; +/** @type {Function}*/ +Astro.utils.Date.smstamp; +/** @type {Function}*/ +Astro.utils.Date.chinese; + +/** @type {constant}*/ +Astro.utils.Date.MONTH; +/** @type {constant}*/ +Astro.utils.Date.MONTH_ABBR; +/** @type {constant}*/ +Astro.utils.Date.DAY; +/** @type {constant}*/ +Astro.utils.Date.DAY_ABBR; +/** @type {constant}*/ +Astro.utils.Date.CAP_MONTHS; diff --git a/botanjs/src/externs/Astro.utils.js b/botanjs/src/externs/Astro.utils.js new file mode 100644 index 0000000..6bf8f73 --- /dev/null +++ b/botanjs/src/externs/Astro.utils.js @@ -0,0 +1,2 @@ +/** @constructor */ +Astro.utils = function() {}; diff --git a/botanjs/src/externs/_3rdParty_.Recaptcha.js b/botanjs/src/externs/_3rdParty_.Recaptcha.js new file mode 100644 index 0000000..e4c340c --- /dev/null +++ b/botanjs/src/externs/_3rdParty_.Recaptcha.js @@ -0,0 +1,12 @@ +/** @constructor */ +_3rdParty_.Recaptcha = function() {}; + +/** @type {Number} */ +_3rdParty_.Recaptcha.timer_id; + +/** @type {Function} */ +_3rdParty_.render; +/** @type {Function} */ +_3rdParty_.reset; +/** @type {Function} */ +_3rdParty_.getResponse; diff --git a/botanjs/src/externs/_3rdParty_.js b/botanjs/src/externs/_3rdParty_.js new file mode 100644 index 0000000..ea23482 --- /dev/null +++ b/botanjs/src/externs/_3rdParty_.js @@ -0,0 +1,2 @@ +/** @type {Object} */ +var _3rdParty_ = {}; diff --git a/botanjs/src/externs/_AstConf_.Article.js b/botanjs/src/externs/_AstConf_.Article.js new file mode 100644 index 0000000..1c442ae --- /dev/null +++ b/botanjs/src/externs/_AstConf_.Article.js @@ -0,0 +1,4 @@ +/** @type {Object} */ +_AstConf_.Article = {}; +/** @type {String} */ +_AstConf_.Article.id; diff --git a/botanjs/src/externs/_AstConf_.AstroEdit.js b/botanjs/src/externs/_AstConf_.AstroEdit.js new file mode 100644 index 0000000..0ef0cc9 --- /dev/null +++ b/botanjs/src/externs/_AstConf_.AstroEdit.js @@ -0,0 +1,20 @@ +/** @type {Object} */ +_AstConf_.AstroEdit = {}; +/** @type {String} */ +_AstConf_.AstroEdit.article_id; +/** @type {object} */ +_AstConf_.AstroEdit.paths = {}; + /** @type {string} */ + _AstConf_.AstroEdit.paths.set_article; + /** @type {string} */ + _AstConf_.AstroEdit.paths.get_article; + /** @type {string} */ + _AstConf_.AstroEdit.paths.get_drafts; + /** @type {string} */ + _AstConf_.AstroEdit.paths.get_files; + /** @type {string} */ + _AstConf_.AstroEdit.paths.set_file; + /** @type {string} */ + _AstConf_.AstroEdit.paths.tag_count; + /** @type {string} */ + _AstConf_.AstroEdit.paths.set_tag; diff --git a/botanjs/src/externs/_AstConf_.Comment.js b/botanjs/src/externs/_AstConf_.Comment.js new file mode 100644 index 0000000..5204e8a --- /dev/null +++ b/botanjs/src/externs/_AstConf_.Comment.js @@ -0,0 +1,6 @@ +/** @type {Object} */ +_AstConf_.Comment = {}; +/** @type {String} */ +_AstConf_.Comment.processor; +/** @type {String} */ +_AstConf_.Comment.siteKey; diff --git a/botanjs/src/externs/_AstConf_.Control.js b/botanjs/src/externs/_AstConf_.Control.js new file mode 100644 index 0000000..bb49c47 --- /dev/null +++ b/botanjs/src/externs/_AstConf_.Control.js @@ -0,0 +1,6 @@ +/** @type {Object} */ +_AstConf_.Control = {}; +/** @type {Object} */ +_AstConf_.Control.action; + /** @type {String} */ + _AstConf_.Control.action.del; diff --git a/botanjs/src/externs/_AstConf_.Login.js b/botanjs/src/externs/_AstConf_.Login.js new file mode 100644 index 0000000..2379ac3 --- /dev/null +++ b/botanjs/src/externs/_AstConf_.Login.js @@ -0,0 +1,6 @@ +/** @type {Object} */ +_AstConf_.Login = {}; +/** @type {String} */ +_AstConf_.Login.formAct; +/** @type {String} */ +_AstConf_.Login.sHeat; diff --git a/botanjs/src/externs/_AstConf_.SiteFile.js b/botanjs/src/externs/_AstConf_.SiteFile.js new file mode 100644 index 0000000..1b6513c --- /dev/null +++ b/botanjs/src/externs/_AstConf_.SiteFile.js @@ -0,0 +1,21 @@ +/** @type {Object} */ +_AstConf_.SiteFile = {}; + /** @type {String} */ + _AstConf_.SiteFile.f_host; + + /** @type {Object} */ + _AstConf_.SiteFile.path; + /** @type {String} */ + _AstConf_.SiteFile.path.download; + /** @type {String} */ + _AstConf_.SiteFile.path.info; + /** @type {Object} */ + _AstConf_.SiteFile.path.image; + /** @type {String} */ + _AstConf_.SiteFile.path.image.small; + /** @type {String} */ + _AstConf_.SiteFile.path.image.medium; + /** @type {String} */ + _AstConf_.SiteFile.path.image.large; + /** @type {Array} */ + _AstConf_.SiteFile.files; diff --git a/botanjs/src/externs/_AstConf_.UserInfo.js b/botanjs/src/externs/_AstConf_.UserInfo.js new file mode 100644 index 0000000..deda862 --- /dev/null +++ b/botanjs/src/externs/_AstConf_.UserInfo.js @@ -0,0 +1,9 @@ +/** @type {Object} */ +_AstConf_.UserInfo = {}; + +/** @type {String} */ +_AstConf_.UserInfo.name; +/** @type {String} */ +_AstConf_.UserInfo.website; +/** @type {String} */ +_AstConf_.UserInfo.avatar; diff --git a/botanjs/src/externs/_AstConf_.js b/botanjs/src/externs/_AstConf_.js new file mode 100644 index 0000000..721280d --- /dev/null +++ b/botanjs/src/externs/_AstConf_.js @@ -0,0 +1,2 @@ +/** @type {Object} */ +var _AstConf_ = {}; diff --git a/botanjs/src/externs/_AstJson_.AJaxGetArticle.js b/botanjs/src/externs/_AstJson_.AJaxGetArticle.js new file mode 100644 index 0000000..697ca25 --- /dev/null +++ b/botanjs/src/externs/_AstJson_.AJaxGetArticle.js @@ -0,0 +1,29 @@ +/** @type {Object} */ +_AstJson_.AJaxGetArticle = {}; + +/** @type {Boolean} */ +_AstJson_.AJaxGetArticle.status; +/** @type {String} */ +_AstJson_.AJaxGetArticle.backup; +/** @type {Object} */ +_AstJson_.AJaxGetArticle.entry; + /** @type {String} */ + _AstJson_.AJaxGetArticle.entry.slug; + /** @type {Boolean} */ + _AstJson_.AJaxGetArticle.entry.archived; + /** @type {String} */ + _AstJson_.AJaxGetArticle.entry.date_created; + /** @type {Boolean} */ + _AstJson_.AJaxGetArticle.entry.draft; + /** @type {Boolean} */ + _AstJson_.AJaxGetArticle.entry.featured; + /** @type {String} */ + _AstJson_.AJaxGetArticle.entry.date_modified; + /** @type {String} */ + _AstJson_.AJaxGetArticle.entry.date_published; + /** @type {Array} */ + _AstJson_.AJaxGetArticle.entry.tags; + /** @type {String} */ + _AstJson_.AJaxGetArticle.entry.text; + /** @type {String} */ + _AstJson_.AJaxGetArticle.entry.title; diff --git a/botanjs/src/externs/_AstJson_.AJaxGetDrafts.js b/botanjs/src/externs/_AstJson_.AJaxGetDrafts.js new file mode 100644 index 0000000..9a19293 --- /dev/null +++ b/botanjs/src/externs/_AstJson_.AJaxGetDrafts.js @@ -0,0 +1,18 @@ +/** @type {Object} */ +_AstJson_.AJaxGetDrafts = {}; + +/** @type {Boolean} */ +_AstJson_.AJaxGetDrafts.status; +/** @type {Array} */ +_AstJson_.AJaxGetDrafts.entries; + +/** @type {Object} */ +_AstJson_.AJaxGetDrafts.entry = {}; + /** @type {String} */ + _AstJson_.AJaxGetDrafts.entry.content; + /** @type {String} */ + _AstJson_.AJaxGetDrafts.entry.date; + /** @type {String} */ + _AstJson_.AJaxGetDrafts.entry._id; + /** @type {String} */ + _AstJson_.AJaxGetDrafts.entry.title; diff --git a/botanjs/src/externs/_AstJson_.AJaxGetFiles.Request.js b/botanjs/src/externs/_AstJson_.AJaxGetFiles.Request.js new file mode 100644 index 0000000..4e3f0e5 --- /dev/null +++ b/botanjs/src/externs/_AstJson_.AJaxGetFiles.Request.js @@ -0,0 +1,13 @@ +/** @type {Object} */ +_AstJson_.AJaxGetFiles.Request = {}; + +/** @type {String} */ +_AstJson_.AJaxGetFiles.Request.from; +/** @type {String} */ +_AstJson_.AJaxGetFiles.Request.to; +/** @type {String} */ +_AstJson_.AJaxGetFiles.Request.group; +/** @type {String} */ +_AstJson_.AJaxGetFiles.Request.listFiles; +/** @type {String} */ +_AstJson_.AJaxGetFiles.Request.aid; diff --git a/botanjs/src/externs/_AstJson_.AJaxGetFiles.js b/botanjs/src/externs/_AstJson_.AJaxGetFiles.js new file mode 100644 index 0000000..314ab03 --- /dev/null +++ b/botanjs/src/externs/_AstJson_.AJaxGetFiles.js @@ -0,0 +1,24 @@ +/** @type {Object} */ +_AstJson_.AJaxGetFiles = {}; + +/** @type {Boolean} */ +_AstJson_.AJaxGetFiles.status; +/** @type {Array} */ +_AstJson_.AJaxGetFiles.files; + +/** @type {Object} */ +_AstJson_.AJaxGetFiles.file = {}; + /** @type {String} */ + _AstJson_.AJaxGetFiles.file.author; + /** @type {String} */ + _AstJson_.AJaxGetFiles.file.cCount; + /** @type {String} */ + _AstJson_.AJaxGetFiles.file.date; + /** @type {String} */ + _AstJson_.AJaxGetFiles.file.hash; + /** @type {String} */ + _AstJson_.AJaxGetFiles.file.id; + /** @type {String} */ + _AstJson_.AJaxGetFiles.file.name; + /** @type {String} */ + _AstJson_.AJaxGetFiles.file.src_location; diff --git a/botanjs/src/externs/_AstJson_.SiteFile.js b/botanjs/src/externs/_AstJson_.SiteFile.js new file mode 100644 index 0000000..0cfbb04 --- /dev/null +++ b/botanjs/src/externs/_AstJson_.SiteFile.js @@ -0,0 +1,21 @@ +/** @type {Object} */ +_AstJson_.SiteFile = {}; + +/** @type {Boolean} */ +_AstJson_.SiteFile.status; +/** @type {String} */ +_AstJson_.SiteFile.message; +/** @type {Object} */ +_AstJson_.SiteFile.file; + /** @type {String} */ + _AstJson_.SiteFile.file.date_created; + /** @type {String} */ + _AstJson_.SiteFile.file.name; + /** @type {String} */ + _AstJson_.SiteFile.file.id; + /** @type {String} */ + _AstJson_.SiteFile.file.nickname; + /** @type {String} */ + _AstJson_.SiteFile.file.type; + /** @type {String} */ + _AstJson_.SiteFile.file.src_location; diff --git a/botanjs/src/externs/_AstJson_.js b/botanjs/src/externs/_AstJson_.js new file mode 100644 index 0000000..ca6cfe7 --- /dev/null +++ b/botanjs/src/externs/_AstJson_.js @@ -0,0 +1,2 @@ +/** @type {Object} */ +var _AstJson_ = {}; diff --git a/settings.ini b/settings.ini index 65c8da3..42409f5 100644 --- a/settings.ini +++ b/settings.ini @@ -7,9 +7,9 @@ Cache = ${SiteRoot}/cache [BotanJS] SrcDir = ${Paths:Runtime}/botanjs/src -REDIS_PASS = PASSWORD_FOR_REDIS_DB +REDIS_PASS = RJszCzFoeZaULKyY3w5W0kMVF4Ei5ZsqMVexk8wxFzQEYnRuLsdGOkHIAXYe4XNuByZHfbee7GxLsuo9xvEIKdYVpvVRYMUbcf25cuOIWV1sLgxhRv0q9KtH7cLpBroa1BIiqHtbzkd3erenel6siIqyHQxV0jPVFfm0ayCvYmdHiVL1VphBpTSnAX8JNvR2Iim5Q7aGiDpLxQD0nnnc1uQuJjwBNA3jkjddMMvHgN8iYleq4SA2xycqNNFzejlT -CeleryBroker = redis://:${REDIS_PASS}@123.123.123.123:1234/9 +CeleryBroker = redis://:${REDIS_PASS}@192.168.100.98:6379/9 [Service]