From a095c9f4b5f389b5a9bcb4664032962982f1166b Mon Sep 17 00:00:00 2001 From: Auke van Slooten Date: Fri, 7 Jun 2024 15:38:14 +0200 Subject: [PATCH 01/28] added logo, moved current styling to first entry in the list of css components --- .../componentCss/{style.css => 1-style.css} | 0 www/api/data/components/1-styling/meta.json | 2 +- .../header/componentTemplates/logo.html | 90 +++++++++++++++++++ 3 files changed, 91 insertions(+), 1 deletion(-) rename www/api/data/components/1-styling/componentCss/{style.css => 1-style.css} (100%) create mode 100644 www/api/data/components/header/componentTemplates/logo.html diff --git a/www/api/data/components/1-styling/componentCss/style.css b/www/api/data/components/1-styling/componentCss/1-style.css similarity index 100% rename from www/api/data/components/1-styling/componentCss/style.css rename to www/api/data/components/1-styling/componentCss/1-style.css diff --git a/www/api/data/components/1-styling/meta.json b/www/api/data/components/1-styling/meta.json index 64f5a99..1d9da25 100644 --- a/www/api/data/components/1-styling/meta.json +++ b/www/api/data/components/1-styling/meta.json @@ -1 +1 @@ -{"id":"styling","description":""} \ No newline at end of file +{"id":"1-styling","description":""} \ No newline at end of file diff --git a/www/api/data/components/header/componentTemplates/logo.html b/www/api/data/components/header/componentTemplates/logo.html new file mode 100644 index 0000000..0dba705 --- /dev/null +++ b/www/api/data/components/header/componentTemplates/logo.html @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From a00885c7fb157eeb195fa383584c4559b4fcbd42 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Thu, 30 May 2024 08:26:56 +0200 Subject: [PATCH 02/28] div is=simply-component to simply-render --- .../componentTemplates/componentActions.html | 4 +- .../componentTemplates/componentBodyHtml.html | 2 +- .../componentTemplates/componentCommands.html | 4 +- .../componentComponentTemplate.html | 4 +- .../componentDataSources.html | 4 +- .../componentTemplates/componentFootHtml.html | 2 +- .../componentTemplates/componentHeadHtml.html | 2 +- .../componentPageTemplate.html | 4 +- .../componentTransformers.html | 2 +- .../navigation/componentTemplates/menu.html | 2 +- www/api/data/generated.html | 106 +++++++++--------- www/api/data/page-frame/fullApp.html | 2 +- www/api/data/page-frame/pagePreview.html | 2 +- .../pageTemplates/Edit base component.html | 16 +-- .../pageTemplates/Edit component.html | 20 ++-- .../pages/page-frame/dataApi/getPageFrame.js | 4 +- .../pageTemplates/Edit page frame.html | 4 +- .../pages/page/pageTemplates/Edit page.html | 20 ++-- .../preview/pageTemplates/preview-app.html | 2 +- .../pageTemplates/preview-component.html | 6 +- .../publish/pageTemplates/Publish App.html | 2 +- 21 files changed, 107 insertions(+), 107 deletions(-) diff --git a/www/api/data/components/component-actions/componentTemplates/componentActions.html b/www/api/data/components/component-actions/componentTemplates/componentActions.html index aeb0259..ba36bd4 100644 --- a/www/api/data/components/component-actions/componentTemplates/componentActions.html +++ b/www/api/data/components/component-actions/componentTemplates/componentActions.html @@ -31,12 +31,12 @@ diff --git a/www/api/data/components/component-body-html/componentTemplates/componentBodyHtml.html b/www/api/data/components/component-body-html/componentTemplates/componentBodyHtml.html index 7ddc223..38fb51a 100644 --- a/www/api/data/components/component-body-html/componentTemplates/componentBodyHtml.html +++ b/www/api/data/components/component-body-html/componentTemplates/componentBodyHtml.html @@ -22,7 +22,7 @@
-
+
diff --git a/www/api/data/components/component-commands/componentTemplates/componentCommands.html b/www/api/data/components/component-commands/componentTemplates/componentCommands.html index 259abee..f94be5b 100644 --- a/www/api/data/components/component-commands/componentTemplates/componentCommands.html +++ b/www/api/data/components/component-commands/componentTemplates/componentCommands.html @@ -31,12 +31,12 @@ diff --git a/www/api/data/components/component-component-html/componentTemplates/componentComponentTemplate.html b/www/api/data/components/component-component-html/componentTemplates/componentComponentTemplate.html index 6e1d49a..ce34dba 100644 --- a/www/api/data/components/component-component-html/componentTemplates/componentComponentTemplate.html +++ b/www/api/data/components/component-component-html/componentTemplates/componentComponentTemplate.html @@ -37,10 +37,10 @@
-
+
-
+ diff --git a/www/api/data/components/component-data-sources/componentTemplates/componentDataSources.html b/www/api/data/components/component-data-sources/componentTemplates/componentDataSources.html index cd04c2d..efd2a96 100644 --- a/www/api/data/components/component-data-sources/componentTemplates/componentDataSources.html +++ b/www/api/data/components/component-data-sources/componentTemplates/componentDataSources.html @@ -46,7 +46,7 @@
@@ -64,7 +64,7 @@
diff --git a/www/api/data/components/component-foot-html/componentTemplates/componentFootHtml.html b/www/api/data/components/component-foot-html/componentTemplates/componentFootHtml.html index 6dacb8f..7ba2ce3 100644 --- a/www/api/data/components/component-foot-html/componentTemplates/componentFootHtml.html +++ b/www/api/data/components/component-foot-html/componentTemplates/componentFootHtml.html @@ -22,7 +22,7 @@
-
+
diff --git a/www/api/data/components/component-head-html/componentTemplates/componentHeadHtml.html b/www/api/data/components/component-head-html/componentTemplates/componentHeadHtml.html index e13c938..ec9af10 100644 --- a/www/api/data/components/component-head-html/componentTemplates/componentHeadHtml.html +++ b/www/api/data/components/component-head-html/componentTemplates/componentHeadHtml.html @@ -22,7 +22,7 @@
-
+
diff --git a/www/api/data/components/component-page-template/componentTemplates/componentPageTemplate.html b/www/api/data/components/component-page-template/componentTemplates/componentPageTemplate.html index 3a992ff..d338dd2 100644 --- a/www/api/data/components/component-page-template/componentTemplates/componentPageTemplate.html +++ b/www/api/data/components/component-page-template/componentTemplates/componentPageTemplate.html @@ -37,10 +37,10 @@
-
+
-
+ diff --git a/www/api/data/components/component-transformers/componentTemplates/componentTransformers.html b/www/api/data/components/component-transformers/componentTemplates/componentTransformers.html index 5a4cad1..15a3ff2 100644 --- a/www/api/data/components/component-transformers/componentTemplates/componentTransformers.html +++ b/www/api/data/components/component-transformers/componentTemplates/componentTransformers.html @@ -36,7 +36,7 @@ diff --git a/www/api/data/components/navigation/componentTemplates/menu.html b/www/api/data/components/navigation/componentTemplates/menu.html index 0bc784a..8f3f17e 100644 --- a/www/api/data/components/navigation/componentTemplates/menu.html +++ b/www/api/data/components/navigation/componentTemplates/menu.html @@ -2,7 +2,7 @@ \ No newline at end of file diff --git a/www/api/data/generated.html b/www/api/data/generated.html index a6d0666..08d6ce6 100644 --- a/www/api/data/generated.html +++ b/www/api/data/generated.html @@ -1562,8 +1562,8 @@ .catch(function() { let defaults = { "componentPreview.html" : "<!DOCTYPE HTML>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <!-- Component CSS -->\n <style>\n {{componentCss}}\n </style>\n <!-- /Component CSS -->\n <!-- Page CSS -->\n <style>\n {{pageCss}}\n </style>\n <!-- /Page CSS -->\n <!-- Head HTML -->\n {{headHtml}}\n <!-- /Head HTML -->\n <script>\n function clone(ob) {\n return JSON.parse(JSON.stringify(ob));\n }\n function updateDataSource(name) {\n document.querySelectorAll('[data-simply-data=\"'+name+'\"]').forEach(function(list) {\n editor.list.applyDataSource(list, name);\n list.dataBindingPaused = 0;\n });\n }\n </script>\n </head>\n <body>\n <!-- Component HTML templates -->\n {{componentTemplates}}\n <!-- /Component HTML templates -->\n <div class=\"main\">\n {{componentPreview}}\n </div>\n <script src=\"js/simply.everything.js\"></script>\n <script src=\"js/simply-edit.js\" data-api-key=\"muze\"></script>\n <script>\n /* Transformers */\n editor.transformers = {\n {{transformers}}\n };\n /* /Transformers */\n </script>\n <script>\n /* Sorters */\n editor.sorters = {\n {{sorters}}\n };\n /* /Sorters */\n </script>\n <script>\n window.addEventListener(\"simply-content-loaded\", function() {\n /* Data sources */\n {{dataSources}}\n /* /Data sources */\n });\n </script>\n <!-- Foot HTML -->\n {{footHtml}}\n <!-- /Foot HTML -->\n </body>\n</html>", - "fullApp.html" : "<!DOCTYPE HTML>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <!-- Component CSS -->\n <style>\n {{componentCss}}\n </style>\n <!-- /Component CSS -->\n <!-- Page CSS -->\n <style>\n {{pageCss}}\n </style>\n <!-- /Page CSS -->\n <!-- Head HTML -->\n {{headHtml}}\n <!-- /Head HTML -->\n <script>\n var simplyDataApi = {};\n var simplyApp = {};\n window.addEventListener(\"simply-content-loaded\", function() {\n simply.bind = false;\n /* Raw API */\n var simplyRawApi = {\n {{rawApi}}\n };\n /* End of Raw API */\n /* Data API */\n simplyDataApi = {\n {{dataApi}}\n };\n /* End of Data API */\n simplyApp = simply.app({\n /* Actions */\n actions: {\n {{actions}}\n },\n /* /Actions */\n /* Commands */\n commands: {\n {{commands}}\n },\n /* /Commands */\n /* Routes */\n routes: {\n {{routes}}\n }\n /* /Routes */\n });\n });\n function clone(ob) {\n return JSON.parse(JSON.stringify(ob));\n }\n function updateDataSource(name) {\n document.querySelectorAll('[data-simply-data=\"'+name+'\"]').forEach(function(list) {\n editor.list.applyDataSource(list, name);\n list.dataBindingPaused = 0;\n });\n }\n </script>\n </head>\n <body>\n <!-- Body HTML -->\n {{bodyHtml}}\n <!-- /Body HTML -->\n <!-- Component HTML templates -->\n {{componentTemplates}}\n <!-- /Component HTML templates -->\n <header data-simply-path=\"/\" data-simply-field=\"header\" data-simply-content=\"template\" data-simply-default-value=\"Header\">\n <template data-simply-template='Header' rel=\"header\"></template>\n </header>\n <nav>\n <div is=\"simply-component\" rel=\"menu\"></div>\n </nav>\n <div class=\"main\" data-simply-field=\"page\" data-simply-content=\"template\">\n <!-- Page HTML templates -->\n {{pageTemplates}}\n <!-- /Page HTML templates -->\n </div>\n <script src=\"js/simply.everything.js\"></script>\n <script src=\"js/simply-edit.js\" data-api-key=\"muze\"></script>\n <script>\n /* Transformers */\n editor.transformers = {\n {{transformers}}\n };\n /* /Transformers */\n </script>\n <script>\n /* Sorters */\n editor.sorters = {\n {{sorters}}\n };\n /* /Sorters */\n </script>\n <script>\n window.addEventListener(\"simply-content-loaded\", function() {\n /* Data sources */\n {{dataSources}}\n /* /Data sources */\n });\n </script>\n <!-- Foot HTML -->\n {{footHtml}}\n <!-- /Foot HTML -->\n </body>\n</html>", - "pagePreview.html" : "<!DOCTYPE HTML>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <!-- Component CSS -->\n <style>\n {{componentCss}}\n </style>\n <!-- /Component CSS -->\n <!-- Page CSS -->\n <style>\n {{pageCss}}\n </style>\n <!-- /Page CSS -->\n <!-- Head HTML -->\n {{headHtml}}\n <!-- /Head HTML -->\n <script>\n function clone(ob) {\n return JSON.parse(JSON.stringify(ob));\n }\n function updateDataSource(name) {\n document.querySelectorAll('[data-simply-data=\"'+name+'\"]').forEach(function(list) {\n editor.list.applyDataSource(list, name);\n list.dataBindingPaused = 0;\n });\n }\n </script>\n </head>\n <body>\n <!-- Component HTML templates -->\n {{componentTemplates}}\n <!-- /Component HTML templates -->\n <header data-simply-path=\"/\" data-simply-field=\"header\" data-simply-content=\"template\" data-simply-default-value=\"Header\">\n <template data-simply-template='Header' rel=\"header\"></template>\n </header>\n <nav>\n <div is=\"simply-component\" rel=\"menu\"></div>\n </nav>\n <div class=\"main\" data-simply-field=\"page\" data-simply-content=\"template\">\n {{pagePreview}}\n </div>\n <script src=\"js/simply.everything.js\"></script>\n <script src=\"js/simply-edit.js\" data-api-key=\"muze\"></script>\n <script>\n /* Transformers */\n editor.transformers = {\n {{transformers}}\n };\n /* /Transformers */\n </script>\n <script>\n /* Sorters */\n editor.sorters = {\n {{sorters}}\n };\n /* /Sorters */\n </script>\n <script>\n window.addEventListener(\"simply-content-loaded\", function() {\n /* Data sources */\n {{dataSources}}\n /* /Data sources */\n });\n </script>\n <!-- Foot HTML -->\n {{footHtml}}\n <!-- /Foot HTML -->\n </body>\n</html>" + "fullApp.html" : "<!DOCTYPE HTML>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <!-- Component CSS -->\n <style>\n {{componentCss}}\n </style>\n <!-- /Component CSS -->\n <!-- Page CSS -->\n <style>\n {{pageCss}}\n </style>\n <!-- /Page CSS -->\n <!-- Head HTML -->\n {{headHtml}}\n <!-- /Head HTML -->\n <script>\n var simplyDataApi = {};\n var simplyApp = {};\n window.addEventListener(\"simply-content-loaded\", function() {\n simply.bind = false;\n /* Raw API */\n var simplyRawApi = {\n {{rawApi}}\n };\n /* End of Raw API */\n /* Data API */\n simplyDataApi = {\n {{dataApi}}\n };\n /* End of Data API */\n simplyApp = simply.app({\n /* Actions */\n actions: {\n {{actions}}\n },\n /* /Actions */\n /* Commands */\n commands: {\n {{commands}}\n },\n /* /Commands */\n /* Routes */\n routes: {\n {{routes}}\n }\n /* /Routes */\n });\n });\n function clone(ob) {\n return JSON.parse(JSON.stringify(ob));\n }\n function updateDataSource(name) {\n document.querySelectorAll('[data-simply-data=\"'+name+'\"]').forEach(function(list) {\n editor.list.applyDataSource(list, name);\n list.dataBindingPaused = 0;\n });\n }\n </script>\n </head>\n <body>\n <!-- Body HTML -->\n {{bodyHtml}}\n <!-- /Body HTML -->\n <!-- Component HTML templates -->\n {{componentTemplates}}\n <!-- /Component HTML templates -->\n <header data-simply-path=\"/\" data-simply-field=\"header\" data-simply-content=\"template\" data-simply-default-value=\"Header\">\n <template data-simply-template='Header' rel=\"header\"></template>\n </header>\n <nav>\n <simply-render rel=\"menu\"></simply-render>\n </nav>\n <div class=\"main\" data-simply-field=\"page\" data-simply-content=\"template\">\n <!-- Page HTML templates -->\n {{pageTemplates}}\n <!-- /Page HTML templates -->\n </div>\n <script src=\"js/simply.everything.js\"></script>\n <script src=\"js/simply-edit.js\" data-api-key=\"muze\"></script>\n <script>\n /* Transformers */\n editor.transformers = {\n {{transformers}}\n };\n /* /Transformers */\n </script>\n <script>\n /* Sorters */\n editor.sorters = {\n {{sorters}}\n };\n /* /Sorters */\n </script>\n <script>\n window.addEventListener(\"simply-content-loaded\", function() {\n /* Data sources */\n {{dataSources}}\n /* /Data sources */\n });\n </script>\n <!-- Foot HTML -->\n {{footHtml}}\n <!-- /Foot HTML -->\n </body>\n</html>", + "pagePreview.html" : "<!DOCTYPE HTML>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <!-- Component CSS -->\n <style>\n {{componentCss}}\n </style>\n <!-- /Component CSS -->\n <!-- Page CSS -->\n <style>\n {{pageCss}}\n </style>\n <!-- /Page CSS -->\n <!-- Head HTML -->\n {{headHtml}}\n <!-- /Head HTML -->\n <script>\n function clone(ob) {\n return JSON.parse(JSON.stringify(ob));\n }\n function updateDataSource(name) {\n document.querySelectorAll('[data-simply-data=\"'+name+'\"]').forEach(function(list) {\n editor.list.applyDataSource(list, name);\n list.dataBindingPaused = 0;\n });\n }\n </script>\n </head>\n <body>\n <!-- Component HTML templates -->\n {{componentTemplates}}\n <!-- /Component HTML templates -->\n <header data-simply-path=\"/\" data-simply-field=\"header\" data-simply-content=\"template\" data-simply-default-value=\"Header\">\n <template data-simply-template='Header' rel=\"header\"></template>\n </header>\n <nav>\n <simply-render rel=\"menu\"></simply-render>\n </nav>\n <div class=\"main\" data-simply-field=\"page\" data-simply-content=\"template\">\n {{pagePreview}}\n </div>\n <script src=\"js/simply.everything.js\"></script>\n <script src=\"js/simply-edit.js\" data-api-key=\"muze\"></script>\n <script>\n /* Transformers */\n editor.transformers = {\n {{transformers}}\n };\n /* /Transformers */\n </script>\n <script>\n /* Sorters */\n editor.sorters = {\n {{sorters}}\n };\n /* /Sorters */\n </script>\n <script>\n window.addEventListener(\"simply-content-loaded\", function() {\n /* Data sources */\n {{dataSources}}\n /* /Data sources */\n });\n </script>\n <!-- Foot HTML -->\n {{footHtml}}\n <!-- /Foot HTML -->\n </body>\n</html>" }; let elements = {}; @@ -2678,12 +2678,12 @@ @@ -2717,7 +2717,7 @@
-
+
@@ -2759,12 +2759,12 @@ @@ -2846,10 +2846,10 @@
-
+
-
+ @@ -2936,7 +2936,7 @@
@@ -2954,7 +2954,7 @@
@@ -2997,7 +2997,7 @@
-
+
@@ -3030,7 +3030,7 @@
-
+
@@ -3164,10 +3164,10 @@
-
+
-
+ @@ -3471,7 +3471,7 @@ @@ -3502,7 +3502,7 @@

Simply Code - Build something awesome!

@@ -3548,7 +3548,7 @@

Simply Code - Build something awesome!

@@ -3561,14 +3561,14 @@

Edit base component:

-
-
-
-
-
-
-
-
+ + + + + + + + diff --git a/www/api/data/page-frame/fullApp.html b/www/api/data/page-frame/fullApp.html index a0f8ffe..b5c386c 100644 --- a/www/api/data/page-frame/fullApp.html +++ b/www/api/data/page-frame/fullApp.html @@ -70,7 +70,7 @@
diff --git a/www/api/data/page-frame/pagePreview.html b/www/api/data/page-frame/pagePreview.html index 249fa3b..0d5b239 100644 --- a/www/api/data/page-frame/pagePreview.html +++ b/www/api/data/page-frame/pagePreview.html @@ -35,7 +35,7 @@
{{pagePreview}} diff --git a/www/api/data/pages/base-component/pageTemplates/Edit base component.html b/www/api/data/pages/base-component/pageTemplates/Edit base component.html index e201d7b..d8f052d 100644 --- a/www/api/data/pages/base-component/pageTemplates/Edit base component.html +++ b/www/api/data/pages/base-component/pageTemplates/Edit base component.html @@ -6,12 +6,12 @@

Edit base component:

-
-
-
-
-
-
-
-
+ + + + + + + + \ No newline at end of file diff --git a/www/api/data/pages/component/pageTemplates/Edit component.html b/www/api/data/pages/component/pageTemplates/Edit component.html index 9676ba0..fdd3f84 100644 --- a/www/api/data/pages/component/pageTemplates/Edit component.html +++ b/www/api/data/pages/component/pageTemplates/Edit component.html @@ -6,14 +6,14 @@

Edit component:

-
-
-
-
-
-
-
-
-
-
+ + + + + + + + + + \ No newline at end of file diff --git a/www/api/data/pages/page-frame/dataApi/getPageFrame.js b/www/api/data/pages/page-frame/dataApi/getPageFrame.js index f44fa1b..b999bcf 100644 --- a/www/api/data/pages/page-frame/dataApi/getPageFrame.js +++ b/www/api/data/pages/page-frame/dataApi/getPageFrame.js @@ -12,8 +12,8 @@ function() { .catch(function() { let defaults = { "componentPreview.html" : "<!DOCTYPE HTML>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <!-- Component CSS -->\n <style>\n {{componentCss}}\n </style>\n <!-- /Component CSS -->\n <!-- Page CSS -->\n <style>\n {{pageCss}}\n </style>\n <!-- /Page CSS -->\n <!-- Head HTML -->\n {{headHtml}}\n <!-- /Head HTML -->\n <script>\n function clone(ob) {\n return JSON.parse(JSON.stringify(ob));\n }\n function updateDataSource(name) {\n document.querySelectorAll('[data-simply-data=\"'+name+'\"]').forEach(function(list) {\n editor.list.applyDataSource(list, name);\n list.dataBindingPaused = 0;\n });\n }\n </script>\n </head>\n <body>\n <!-- Component HTML templates -->\n {{componentTemplates}}\n <!-- /Component HTML templates -->\n <div class=\"main\">\n {{componentPreview}}\n </div>\n <script src=\"js/simply.everything.js\"></script>\n <script src=\"js/simply-edit.js\" data-api-key=\"muze\"></script>\n <script>\n /* Transformers */\n editor.transformers = {\n {{transformers}}\n };\n /* /Transformers */\n </script>\n <script>\n /* Sorters */\n editor.sorters = {\n {{sorters}}\n };\n /* /Sorters */\n </script>\n <script>\n window.addEventListener(\"simply-content-loaded\", function() {\n /* Data sources */\n {{dataSources}}\n /* /Data sources */\n });\n </script>\n <!-- Foot HTML -->\n {{footHtml}}\n <!-- /Foot HTML -->\n </body>\n</html>", - "fullApp.html" : "<!DOCTYPE HTML>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <!-- Component CSS -->\n <style>\n {{componentCss}}\n </style>\n <!-- /Component CSS -->\n <!-- Page CSS -->\n <style>\n {{pageCss}}\n </style>\n <!-- /Page CSS -->\n <!-- Head HTML -->\n {{headHtml}}\n <!-- /Head HTML -->\n <script>\n var simplyDataApi = {};\n var simplyApp = {};\n window.addEventListener(\"simply-content-loaded\", function() {\n simply.bind = false;\n /* Raw API */\n var simplyRawApi = {\n {{rawApi}}\n };\n /* End of Raw API */\n /* Data API */\n simplyDataApi = {\n {{dataApi}}\n };\n /* End of Data API */\n simplyApp = simply.app({\n /* Actions */\n actions: {\n {{actions}}\n },\n /* /Actions */\n /* Commands */\n commands: {\n {{commands}}\n },\n /* /Commands */\n /* Routes */\n routes: {\n {{routes}}\n }\n /* /Routes */\n });\n });\n function clone(ob) {\n return JSON.parse(JSON.stringify(ob));\n }\n function updateDataSource(name) {\n document.querySelectorAll('[data-simply-data=\"'+name+'\"]').forEach(function(list) {\n editor.list.applyDataSource(list, name);\n list.dataBindingPaused = 0;\n });\n }\n </script>\n </head>\n <body>\n <!-- Body HTML -->\n {{bodyHtml}}\n <!-- /Body HTML -->\n <!-- Component HTML templates -->\n {{componentTemplates}}\n <!-- /Component HTML templates -->\n <header data-simply-path=\"/\" data-simply-field=\"header\" data-simply-content=\"template\" data-simply-default-value=\"Header\">\n <template data-simply-template='Header' rel=\"header\"></template>\n </header>\n <nav>\n <div is=\"simply-component\" rel=\"menu\"></div>\n </nav>\n <div class=\"main\" data-simply-field=\"page\" data-simply-content=\"template\">\n <!-- Page HTML templates -->\n {{pageTemplates}}\n <!-- /Page HTML templates -->\n </div>\n <script src=\"js/simply.everything.js\"></script>\n <script src=\"js/simply-edit.js\" data-api-key=\"muze\"></script>\n <script>\n /* Transformers */\n editor.transformers = {\n {{transformers}}\n };\n /* /Transformers */\n </script>\n <script>\n /* Sorters */\n editor.sorters = {\n {{sorters}}\n };\n /* /Sorters */\n </script>\n <script>\n window.addEventListener(\"simply-content-loaded\", function() {\n /* Data sources */\n {{dataSources}}\n /* /Data sources */\n });\n </script>\n <!-- Foot HTML -->\n {{footHtml}}\n <!-- /Foot HTML -->\n </body>\n</html>", - "pagePreview.html" : "<!DOCTYPE HTML>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <!-- Component CSS -->\n <style>\n {{componentCss}}\n </style>\n <!-- /Component CSS -->\n <!-- Page CSS -->\n <style>\n {{pageCss}}\n </style>\n <!-- /Page CSS -->\n <!-- Head HTML -->\n {{headHtml}}\n <!-- /Head HTML -->\n <script>\n function clone(ob) {\n return JSON.parse(JSON.stringify(ob));\n }\n function updateDataSource(name) {\n document.querySelectorAll('[data-simply-data=\"'+name+'\"]').forEach(function(list) {\n editor.list.applyDataSource(list, name);\n list.dataBindingPaused = 0;\n });\n }\n </script>\n </head>\n <body>\n <!-- Component HTML templates -->\n {{componentTemplates}}\n <!-- /Component HTML templates -->\n <header data-simply-path=\"/\" data-simply-field=\"header\" data-simply-content=\"template\" data-simply-default-value=\"Header\">\n <template data-simply-template='Header' rel=\"header\"></template>\n </header>\n <nav>\n <div is=\"simply-component\" rel=\"menu\"></div>\n </nav>\n <div class=\"main\" data-simply-field=\"page\" data-simply-content=\"template\">\n {{pagePreview}}\n </div>\n <script src=\"js/simply.everything.js\"></script>\n <script src=\"js/simply-edit.js\" data-api-key=\"muze\"></script>\n <script>\n /* Transformers */\n editor.transformers = {\n {{transformers}}\n };\n /* /Transformers */\n </script>\n <script>\n /* Sorters */\n editor.sorters = {\n {{sorters}}\n };\n /* /Sorters */\n </script>\n <script>\n window.addEventListener(\"simply-content-loaded\", function() {\n /* Data sources */\n {{dataSources}}\n /* /Data sources */\n });\n </script>\n <!-- Foot HTML -->\n {{footHtml}}\n <!-- /Foot HTML -->\n </body>\n</html>" + "fullApp.html" : "<!DOCTYPE HTML>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <!-- Component CSS -->\n <style>\n {{componentCss}}\n </style>\n <!-- /Component CSS -->\n <!-- Page CSS -->\n <style>\n {{pageCss}}\n </style>\n <!-- /Page CSS -->\n <!-- Head HTML -->\n {{headHtml}}\n <!-- /Head HTML -->\n <script>\n var simplyDataApi = {};\n var simplyApp = {};\n window.addEventListener(\"simply-content-loaded\", function() {\n simply.bind = false;\n /* Raw API */\n var simplyRawApi = {\n {{rawApi}}\n };\n /* End of Raw API */\n /* Data API */\n simplyDataApi = {\n {{dataApi}}\n };\n /* End of Data API */\n simplyApp = simply.app({\n /* Actions */\n actions: {\n {{actions}}\n },\n /* /Actions */\n /* Commands */\n commands: {\n {{commands}}\n },\n /* /Commands */\n /* Routes */\n routes: {\n {{routes}}\n }\n /* /Routes */\n });\n });\n function clone(ob) {\n return JSON.parse(JSON.stringify(ob));\n }\n function updateDataSource(name) {\n document.querySelectorAll('[data-simply-data=\"'+name+'\"]').forEach(function(list) {\n editor.list.applyDataSource(list, name);\n list.dataBindingPaused = 0;\n });\n }\n </script>\n </head>\n <body>\n <!-- Body HTML -->\n {{bodyHtml}}\n <!-- /Body HTML -->\n <!-- Component HTML templates -->\n {{componentTemplates}}\n <!-- /Component HTML templates -->\n <header data-simply-path=\"/\" data-simply-field=\"header\" data-simply-content=\"template\" data-simply-default-value=\"Header\">\n <template data-simply-template='Header' rel=\"header\"></template>\n </header>\n <nav>\n <simply-render rel=\"menu\"></simply-render>\n </nav>\n <div class=\"main\" data-simply-field=\"page\" data-simply-content=\"template\">\n <!-- Page HTML templates -->\n {{pageTemplates}}\n <!-- /Page HTML templates -->\n </div>\n <script src=\"js/simply.everything.js\"></script>\n <script src=\"js/simply-edit.js\" data-api-key=\"muze\"></script>\n <script>\n /* Transformers */\n editor.transformers = {\n {{transformers}}\n };\n /* /Transformers */\n </script>\n <script>\n /* Sorters */\n editor.sorters = {\n {{sorters}}\n };\n /* /Sorters */\n </script>\n <script>\n window.addEventListener(\"simply-content-loaded\", function() {\n /* Data sources */\n {{dataSources}}\n /* /Data sources */\n });\n </script>\n <!-- Foot HTML -->\n {{footHtml}}\n <!-- /Foot HTML -->\n </body>\n</html>", + "pagePreview.html" : "<!DOCTYPE HTML>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <!-- Component CSS -->\n <style>\n {{componentCss}}\n </style>\n <!-- /Component CSS -->\n <!-- Page CSS -->\n <style>\n {{pageCss}}\n </style>\n <!-- /Page CSS -->\n <!-- Head HTML -->\n {{headHtml}}\n <!-- /Head HTML -->\n <script>\n function clone(ob) {\n return JSON.parse(JSON.stringify(ob));\n }\n function updateDataSource(name) {\n document.querySelectorAll('[data-simply-data=\"'+name+'\"]').forEach(function(list) {\n editor.list.applyDataSource(list, name);\n list.dataBindingPaused = 0;\n });\n }\n </script>\n </head>\n <body>\n <!-- Component HTML templates -->\n {{componentTemplates}}\n <!-- /Component HTML templates -->\n <header data-simply-path=\"/\" data-simply-field=\"header\" data-simply-content=\"template\" data-simply-default-value=\"Header\">\n <template data-simply-template='Header' rel=\"header\"></template>\n </header>\n <nav>\n <simply-render rel=\"menu\"></simply-render>\n </nav>\n <div class=\"main\" data-simply-field=\"page\" data-simply-content=\"template\">\n {{pagePreview}}\n </div>\n <script src=\"js/simply.everything.js\"></script>\n <script src=\"js/simply-edit.js\" data-api-key=\"muze\"></script>\n <script>\n /* Transformers */\n editor.transformers = {\n {{transformers}}\n };\n /* /Transformers */\n </script>\n <script>\n /* Sorters */\n editor.sorters = {\n {{sorters}}\n };\n /* /Sorters */\n </script>\n <script>\n window.addEventListener(\"simply-content-loaded\", function() {\n /* Data sources */\n {{dataSources}}\n /* /Data sources */\n });\n </script>\n <!-- Foot HTML -->\n {{footHtml}}\n <!-- /Foot HTML -->\n </body>\n</html>" }; let elements = {}; diff --git a/www/api/data/pages/page-frame/pageTemplates/Edit page frame.html b/www/api/data/pages/page-frame/pageTemplates/Edit page frame.html index 9967414..b01f4f9 100644 --- a/www/api/data/pages/page-frame/pageTemplates/Edit page frame.html +++ b/www/api/data/pages/page-frame/pageTemplates/Edit page frame.html @@ -5,6 +5,6 @@

Edit page frame

-
-
+ + \ No newline at end of file diff --git a/www/api/data/pages/page/pageTemplates/Edit page.html b/www/api/data/pages/page/pageTemplates/Edit page.html index 445ff0c..46052b5 100644 --- a/www/api/data/pages/page/pageTemplates/Edit page.html +++ b/www/api/data/pages/page/pageTemplates/Edit page.html @@ -6,14 +6,14 @@

Edit page:

-
-
-
-
-
-
-
-
-
-
+ + + + + + + + + + \ No newline at end of file diff --git a/www/api/data/pages/preview/pageTemplates/preview-app.html b/www/api/data/pages/preview/pageTemplates/preview-app.html index eb925df..35740a9 100644 --- a/www/api/data/pages/preview/pageTemplates/preview-app.html +++ b/www/api/data/pages/preview/pageTemplates/preview-app.html @@ -1,3 +1,3 @@
-
+
\ No newline at end of file diff --git a/www/api/data/pages/preview/pageTemplates/preview-component.html b/www/api/data/pages/preview/pageTemplates/preview-component.html index 41e5aab..199e776 100644 --- a/www/api/data/pages/preview/pageTemplates/preview-component.html +++ b/www/api/data/pages/preview/pageTemplates/preview-component.html @@ -1,5 +1,5 @@
-
-
-
+ + +
\ No newline at end of file diff --git a/www/api/data/pages/publish/pageTemplates/Publish App.html b/www/api/data/pages/publish/pageTemplates/Publish App.html index 1e12ff1..bddc24c 100644 --- a/www/api/data/pages/publish/pageTemplates/Publish App.html +++ b/www/api/data/pages/publish/pageTemplates/Publish App.html @@ -3,5 +3,5 @@

App preview

-
+ \ No newline at end of file From 2f851c425ca102e992f90b0e6ea361a429aca901 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Thu, 30 May 2024 08:27:09 +0200 Subject: [PATCH 03/28] div is=simply-component to simply-render --- www/index.html | 106 ++++++++++++++++++++++++------------------------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/www/index.html b/www/index.html index 793fe33..331da58 100644 --- a/www/index.html +++ b/www/index.html @@ -1154,8 +1154,8 @@ .catch(function() { let defaults = { "componentPreview.html" : "<!DOCTYPE HTML>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <!-- Component CSS -->\n <style>\n {{componentCss}}\n </style>\n <!-- /Component CSS -->\n <!-- Page CSS -->\n <style>\n {{pageCss}}\n </style>\n <!-- /Page CSS -->\n <!-- Head HTML -->\n {{headHtml}}\n <!-- /Head HTML -->\n <script>\n function clone(ob) {\n return JSON.parse(JSON.stringify(ob));\n }\n function updateDataSource(name) {\n document.querySelectorAll('[data-simply-data=\"'+name+'\"]').forEach(function(list) {\n editor.list.applyDataSource(list, name);\n list.dataBindingPaused = 0;\n });\n }\n </script>\n </head>\n <body>\n <!-- Component HTML templates -->\n {{componentTemplates}}\n <!-- /Component HTML templates -->\n <div class=\"main\">\n {{componentPreview}}\n </div>\n <script src=\"js/simply.everything.js\"></script>\n <script src=\"js/simply-edit.js\" data-api-key=\"muze\"></script>\n <script>\n /* Transformers */\n editor.transformers = {\n {{transformers}}\n };\n /* /Transformers */\n </script>\n <script>\n /* Sorters */\n editor.sorters = {\n {{sorters}}\n };\n /* /Sorters */\n </script>\n <script>\n window.addEventListener(\"simply-content-loaded\", function() {\n /* Data sources */\n {{dataSources}}\n /* /Data sources */\n });\n </script>\n <!-- Foot HTML -->\n {{footHtml}}\n <!-- /Foot HTML -->\n </body>\n</html>", - "fullApp.html" : "<!DOCTYPE HTML>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <!-- Component CSS -->\n <style>\n {{componentCss}}\n </style>\n <!-- /Component CSS -->\n <!-- Page CSS -->\n <style>\n {{pageCss}}\n </style>\n <!-- /Page CSS -->\n <!-- Head HTML -->\n {{headHtml}}\n <!-- /Head HTML -->\n <script>\n var simplyDataApi = {};\n var simplyApp = {};\n window.addEventListener(\"simply-content-loaded\", function() {\n simply.bind = false;\n /* Raw API */\n var simplyRawApi = {\n {{rawApi}}\n };\n /* End of Raw API */\n /* Data API */\n simplyDataApi = {\n {{dataApi}}\n };\n /* End of Data API */\n simplyApp = simply.app({\n /* Actions */\n actions: {\n {{actions}}\n },\n /* /Actions */\n /* Commands */\n commands: {\n {{commands}}\n },\n /* /Commands */\n /* Routes */\n routes: {\n {{routes}}\n }\n /* /Routes */\n });\n });\n function clone(ob) {\n return JSON.parse(JSON.stringify(ob));\n }\n function updateDataSource(name) {\n document.querySelectorAll('[data-simply-data=\"'+name+'\"]').forEach(function(list) {\n editor.list.applyDataSource(list, name);\n list.dataBindingPaused = 0;\n });\n }\n </script>\n </head>\n <body>\n <!-- Body HTML -->\n {{bodyHtml}}\n <!-- /Body HTML -->\n <!-- Component HTML templates -->\n {{componentTemplates}}\n <!-- /Component HTML templates -->\n <header data-simply-path=\"/\" data-simply-field=\"header\" data-simply-content=\"template\" data-simply-default-value=\"Header\">\n <template data-simply-template='Header' rel=\"header\"></template>\n </header>\n <nav>\n <div is=\"simply-component\" rel=\"menu\"></div>\n </nav>\n <div class=\"main\" data-simply-field=\"page\" data-simply-content=\"template\">\n <!-- Page HTML templates -->\n {{pageTemplates}}\n <!-- /Page HTML templates -->\n </div>\n <script src=\"js/simply.everything.js\"></script>\n <script src=\"js/simply-edit.js\" data-api-key=\"muze\"></script>\n <script>\n /* Transformers */\n editor.transformers = {\n {{transformers}}\n };\n /* /Transformers */\n </script>\n <script>\n /* Sorters */\n editor.sorters = {\n {{sorters}}\n };\n /* /Sorters */\n </script>\n <script>\n window.addEventListener(\"simply-content-loaded\", function() {\n /* Data sources */\n {{dataSources}}\n /* /Data sources */\n });\n </script>\n <!-- Foot HTML -->\n {{footHtml}}\n <!-- /Foot HTML -->\n </body>\n</html>", - "pagePreview.html" : "<!DOCTYPE HTML>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <!-- Component CSS -->\n <style>\n {{componentCss}}\n </style>\n <!-- /Component CSS -->\n <!-- Page CSS -->\n <style>\n {{pageCss}}\n </style>\n <!-- /Page CSS -->\n <!-- Head HTML -->\n {{headHtml}}\n <!-- /Head HTML -->\n <script>\n function clone(ob) {\n return JSON.parse(JSON.stringify(ob));\n }\n function updateDataSource(name) {\n document.querySelectorAll('[data-simply-data=\"'+name+'\"]').forEach(function(list) {\n editor.list.applyDataSource(list, name);\n list.dataBindingPaused = 0;\n });\n }\n </script>\n </head>\n <body>\n <!-- Component HTML templates -->\n {{componentTemplates}}\n <!-- /Component HTML templates -->\n <header data-simply-path=\"/\" data-simply-field=\"header\" data-simply-content=\"template\" data-simply-default-value=\"Header\">\n <template data-simply-template='Header' rel=\"header\"></template>\n </header>\n <nav>\n <div is=\"simply-component\" rel=\"menu\"></div>\n </nav>\n <div class=\"main\" data-simply-field=\"page\" data-simply-content=\"template\">\n {{pagePreview}}\n </div>\n <script src=\"js/simply.everything.js\"></script>\n <script src=\"js/simply-edit.js\" data-api-key=\"muze\"></script>\n <script>\n /* Transformers */\n editor.transformers = {\n {{transformers}}\n };\n /* /Transformers */\n </script>\n <script>\n /* Sorters */\n editor.sorters = {\n {{sorters}}\n };\n /* /Sorters */\n </script>\n <script>\n window.addEventListener(\"simply-content-loaded\", function() {\n /* Data sources */\n {{dataSources}}\n /* /Data sources */\n });\n </script>\n <!-- Foot HTML -->\n {{footHtml}}\n <!-- /Foot HTML -->\n </body>\n</html>" + "fullApp.html" : "<!DOCTYPE HTML>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <!-- Component CSS -->\n <style>\n {{componentCss}}\n </style>\n <!-- /Component CSS -->\n <!-- Page CSS -->\n <style>\n {{pageCss}}\n </style>\n <!-- /Page CSS -->\n <!-- Head HTML -->\n {{headHtml}}\n <!-- /Head HTML -->\n <script>\n var simplyDataApi = {};\n var simplyApp = {};\n window.addEventListener(\"simply-content-loaded\", function() {\n simply.bind = false;\n /* Raw API */\n var simplyRawApi = {\n {{rawApi}}\n };\n /* End of Raw API */\n /* Data API */\n simplyDataApi = {\n {{dataApi}}\n };\n /* End of Data API */\n simplyApp = simply.app({\n /* Actions */\n actions: {\n {{actions}}\n },\n /* /Actions */\n /* Commands */\n commands: {\n {{commands}}\n },\n /* /Commands */\n /* Routes */\n routes: {\n {{routes}}\n }\n /* /Routes */\n });\n });\n function clone(ob) {\n return JSON.parse(JSON.stringify(ob));\n }\n function updateDataSource(name) {\n document.querySelectorAll('[data-simply-data=\"'+name+'\"]').forEach(function(list) {\n editor.list.applyDataSource(list, name);\n list.dataBindingPaused = 0;\n });\n }\n </script>\n </head>\n <body>\n <!-- Body HTML -->\n {{bodyHtml}}\n <!-- /Body HTML -->\n <!-- Component HTML templates -->\n {{componentTemplates}}\n <!-- /Component HTML templates -->\n <header data-simply-path=\"/\" data-simply-field=\"header\" data-simply-content=\"template\" data-simply-default-value=\"Header\">\n <template data-simply-template='Header' rel=\"header\"></template>\n </header>\n <nav>\n <simply-render rel=\"menu\"></simply-render>\n </nav>\n <div class=\"main\" data-simply-field=\"page\" data-simply-content=\"template\">\n <!-- Page HTML templates -->\n {{pageTemplates}}\n <!-- /Page HTML templates -->\n </div>\n <script src=\"js/simply.everything.js\"></script>\n <script src=\"js/simply-edit.js\" data-api-key=\"muze\"></script>\n <script>\n /* Transformers */\n editor.transformers = {\n {{transformers}}\n };\n /* /Transformers */\n </script>\n <script>\n /* Sorters */\n editor.sorters = {\n {{sorters}}\n };\n /* /Sorters */\n </script>\n <script>\n window.addEventListener(\"simply-content-loaded\", function() {\n /* Data sources */\n {{dataSources}}\n /* /Data sources */\n });\n </script>\n <!-- Foot HTML -->\n {{footHtml}}\n <!-- /Foot HTML -->\n </body>\n</html>", + "pagePreview.html" : "<!DOCTYPE HTML>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <!-- Component CSS -->\n <style>\n {{componentCss}}\n </style>\n <!-- /Component CSS -->\n <!-- Page CSS -->\n <style>\n {{pageCss}}\n </style>\n <!-- /Page CSS -->\n <!-- Head HTML -->\n {{headHtml}}\n <!-- /Head HTML -->\n <script>\n function clone(ob) {\n return JSON.parse(JSON.stringify(ob));\n }\n function updateDataSource(name) {\n document.querySelectorAll('[data-simply-data=\"'+name+'\"]').forEach(function(list) {\n editor.list.applyDataSource(list, name);\n list.dataBindingPaused = 0;\n });\n }\n </script>\n </head>\n <body>\n <!-- Component HTML templates -->\n {{componentTemplates}}\n <!-- /Component HTML templates -->\n <header data-simply-path=\"/\" data-simply-field=\"header\" data-simply-content=\"template\" data-simply-default-value=\"Header\">\n <template data-simply-template='Header' rel=\"header\"></template>\n </header>\n <nav>\n <simply-render rel=\"menu\"></simply-render>\n </nav>\n <div class=\"main\" data-simply-field=\"page\" data-simply-content=\"template\">\n {{pagePreview}}\n </div>\n <script src=\"js/simply.everything.js\"></script>\n <script src=\"js/simply-edit.js\" data-api-key=\"muze\"></script>\n <script>\n /* Transformers */\n editor.transformers = {\n {{transformers}}\n };\n /* /Transformers */\n </script>\n <script>\n /* Sorters */\n editor.sorters = {\n {{sorters}}\n };\n /* /Sorters */\n </script>\n <script>\n window.addEventListener(\"simply-content-loaded\", function() {\n /* Data sources */\n {{dataSources}}\n /* /Data sources */\n });\n </script>\n <!-- Foot HTML -->\n {{footHtml}}\n <!-- /Foot HTML -->\n </body>\n</html>" }; let elements = {}; @@ -2270,12 +2270,12 @@ @@ -2309,7 +2309,7 @@
-
+
@@ -2351,12 +2351,12 @@ @@ -2438,10 +2438,10 @@
-
+
-
+ @@ -2528,7 +2528,7 @@
@@ -2546,7 +2546,7 @@
@@ -2589,7 +2589,7 @@
-
+
@@ -2622,7 +2622,7 @@
-
+
@@ -2756,10 +2756,10 @@
-
+
-
+ @@ -3063,7 +3063,7 @@ @@ -3094,7 +3094,7 @@

Simply Code - Build something awesome!

@@ -3140,7 +3140,7 @@

Simply Code - Build something awesome!

@@ -3153,14 +3153,14 @@

Edit base component:

-
-
-
-
-
-
-
-
+ + + + + + + + From 9c7f7042e53386eb939551a08c54357da465ec49 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Thu, 30 May 2024 08:34:11 +0200 Subject: [PATCH 04/28] set simply-storage to none --- www/api/data/generated.html | 8 ++++---- www/api/data/page-frame/componentPreview.html | 2 +- www/api/data/page-frame/fullApp.html | 2 +- www/api/data/page-frame/pagePreview.html | 2 +- www/api/data/pages/page-frame/dataApi/getPageFrame.js | 6 +++--- www/index.html | 8 ++++---- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/www/api/data/generated.html b/www/api/data/generated.html index 08d6ce6..e824993 100644 --- a/www/api/data/generated.html +++ b/www/api/data/generated.html @@ -1561,9 +1561,9 @@ }) .catch(function() { let defaults = { - "componentPreview.html" : "<!DOCTYPE HTML>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <!-- Component CSS -->\n <style>\n {{componentCss}}\n </style>\n <!-- /Component CSS -->\n <!-- Page CSS -->\n <style>\n {{pageCss}}\n </style>\n <!-- /Page CSS -->\n <!-- Head HTML -->\n {{headHtml}}\n <!-- /Head HTML -->\n <script>\n function clone(ob) {\n return JSON.parse(JSON.stringify(ob));\n }\n function updateDataSource(name) {\n document.querySelectorAll('[data-simply-data=\"'+name+'\"]').forEach(function(list) {\n editor.list.applyDataSource(list, name);\n list.dataBindingPaused = 0;\n });\n }\n </script>\n </head>\n <body>\n <!-- Component HTML templates -->\n {{componentTemplates}}\n <!-- /Component HTML templates -->\n <div class=\"main\">\n {{componentPreview}}\n </div>\n <script src=\"js/simply.everything.js\"></script>\n <script src=\"js/simply-edit.js\" data-api-key=\"muze\"></script>\n <script>\n /* Transformers */\n editor.transformers = {\n {{transformers}}\n };\n /* /Transformers */\n </script>\n <script>\n /* Sorters */\n editor.sorters = {\n {{sorters}}\n };\n /* /Sorters */\n </script>\n <script>\n window.addEventListener(\"simply-content-loaded\", function() {\n /* Data sources */\n {{dataSources}}\n /* /Data sources */\n });\n </script>\n <!-- Foot HTML -->\n {{footHtml}}\n <!-- /Foot HTML -->\n </body>\n</html>", - "fullApp.html" : "<!DOCTYPE HTML>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <!-- Component CSS -->\n <style>\n {{componentCss}}\n </style>\n <!-- /Component CSS -->\n <!-- Page CSS -->\n <style>\n {{pageCss}}\n </style>\n <!-- /Page CSS -->\n <!-- Head HTML -->\n {{headHtml}}\n <!-- /Head HTML -->\n <script>\n var simplyDataApi = {};\n var simplyApp = {};\n window.addEventListener(\"simply-content-loaded\", function() {\n simply.bind = false;\n /* Raw API */\n var simplyRawApi = {\n {{rawApi}}\n };\n /* End of Raw API */\n /* Data API */\n simplyDataApi = {\n {{dataApi}}\n };\n /* End of Data API */\n simplyApp = simply.app({\n /* Actions */\n actions: {\n {{actions}}\n },\n /* /Actions */\n /* Commands */\n commands: {\n {{commands}}\n },\n /* /Commands */\n /* Routes */\n routes: {\n {{routes}}\n }\n /* /Routes */\n });\n });\n function clone(ob) {\n return JSON.parse(JSON.stringify(ob));\n }\n function updateDataSource(name) {\n document.querySelectorAll('[data-simply-data=\"'+name+'\"]').forEach(function(list) {\n editor.list.applyDataSource(list, name);\n list.dataBindingPaused = 0;\n });\n }\n </script>\n </head>\n <body>\n <!-- Body HTML -->\n {{bodyHtml}}\n <!-- /Body HTML -->\n <!-- Component HTML templates -->\n {{componentTemplates}}\n <!-- /Component HTML templates -->\n <header data-simply-path=\"/\" data-simply-field=\"header\" data-simply-content=\"template\" data-simply-default-value=\"Header\">\n <template data-simply-template='Header' rel=\"header\"></template>\n </header>\n <nav>\n <simply-render rel=\"menu\"></simply-render>\n </nav>\n <div class=\"main\" data-simply-field=\"page\" data-simply-content=\"template\">\n <!-- Page HTML templates -->\n {{pageTemplates}}\n <!-- /Page HTML templates -->\n </div>\n <script src=\"js/simply.everything.js\"></script>\n <script src=\"js/simply-edit.js\" data-api-key=\"muze\"></script>\n <script>\n /* Transformers */\n editor.transformers = {\n {{transformers}}\n };\n /* /Transformers */\n </script>\n <script>\n /* Sorters */\n editor.sorters = {\n {{sorters}}\n };\n /* /Sorters */\n </script>\n <script>\n window.addEventListener(\"simply-content-loaded\", function() {\n /* Data sources */\n {{dataSources}}\n /* /Data sources */\n });\n </script>\n <!-- Foot HTML -->\n {{footHtml}}\n <!-- /Foot HTML -->\n </body>\n</html>", - "pagePreview.html" : "<!DOCTYPE HTML>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <!-- Component CSS -->\n <style>\n {{componentCss}}\n </style>\n <!-- /Component CSS -->\n <!-- Page CSS -->\n <style>\n {{pageCss}}\n </style>\n <!-- /Page CSS -->\n <!-- Head HTML -->\n {{headHtml}}\n <!-- /Head HTML -->\n <script>\n function clone(ob) {\n return JSON.parse(JSON.stringify(ob));\n }\n function updateDataSource(name) {\n document.querySelectorAll('[data-simply-data=\"'+name+'\"]').forEach(function(list) {\n editor.list.applyDataSource(list, name);\n list.dataBindingPaused = 0;\n });\n }\n </script>\n </head>\n <body>\n <!-- Component HTML templates -->\n {{componentTemplates}}\n <!-- /Component HTML templates -->\n <header data-simply-path=\"/\" data-simply-field=\"header\" data-simply-content=\"template\" data-simply-default-value=\"Header\">\n <template data-simply-template='Header' rel=\"header\"></template>\n </header>\n <nav>\n <simply-render rel=\"menu\"></simply-render>\n </nav>\n <div class=\"main\" data-simply-field=\"page\" data-simply-content=\"template\">\n {{pagePreview}}\n </div>\n <script src=\"js/simply.everything.js\"></script>\n <script src=\"js/simply-edit.js\" data-api-key=\"muze\"></script>\n <script>\n /* Transformers */\n editor.transformers = {\n {{transformers}}\n };\n /* /Transformers */\n </script>\n <script>\n /* Sorters */\n editor.sorters = {\n {{sorters}}\n };\n /* /Sorters */\n </script>\n <script>\n window.addEventListener(\"simply-content-loaded\", function() {\n /* Data sources */\n {{dataSources}}\n /* /Data sources */\n });\n </script>\n <!-- Foot HTML -->\n {{footHtml}}\n <!-- /Foot HTML -->\n </body>\n</html>" + "componentPreview.html" : "<!DOCTYPE HTML>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <!-- Component CSS -->\n <style>\n {{componentCss}}\n </style>\n <!-- /Component CSS -->\n <!-- Page CSS -->\n <style>\n {{pageCss}}\n </style>\n <!-- /Page CSS -->\n <!-- Head HTML -->\n {{headHtml}}\n <!-- /Head HTML -->\n <script>\n function clone(ob) {\n return JSON.parse(JSON.stringify(ob));\n }\n function updateDataSource(name) {\n document.querySelectorAll('[data-simply-data=\"'+name+'\"]').forEach(function(list) {\n editor.list.applyDataSource(list, name);\n list.dataBindingPaused = 0;\n });\n }\n </script>\n </head>\n <body>\n <!-- Component HTML templates -->\n {{componentTemplates}}\n <!-- /Component HTML templates -->\n <div class=\"main\">\n {{componentPreview}}\n </div>\n <script src=\"js/simply.everything.js\"></script>\n <script src=\"js/simply-edit.js\" data-simply-storage=\"none\" data-api-key=\"muze\"></script>\n <script>\n /* Transformers */\n editor.transformers = {\n {{transformers}}\n };\n /* /Transformers */\n </script>\n <script>\n /* Sorters */\n editor.sorters = {\n {{sorters}}\n };\n /* /Sorters */\n </script>\n <script>\n window.addEventListener(\"simply-content-loaded\", function() {\n /* Data sources */\n {{dataSources}}\n /* /Data sources */\n });\n </script>\n <!-- Foot HTML -->\n {{footHtml}}\n <!-- /Foot HTML -->\n </body>\n</html>", + "fullApp.html" : "<!DOCTYPE HTML>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <!-- Component CSS -->\n <style>\n {{componentCss}}\n </style>\n <!-- /Component CSS -->\n <!-- Page CSS -->\n <style>\n {{pageCss}}\n </style>\n <!-- /Page CSS -->\n <!-- Head HTML -->\n {{headHtml}}\n <!-- /Head HTML -->\n <script>\n var simplyDataApi = {};\n var simplyApp = {};\n window.addEventListener(\"simply-content-loaded\", function() {\n simply.bind = false;\n /* Raw API */\n var simplyRawApi = {\n {{rawApi}}\n };\n /* End of Raw API */\n /* Data API */\n simplyDataApi = {\n {{dataApi}}\n };\n /* End of Data API */\n simplyApp = simply.app({\n /* Actions */\n actions: {\n {{actions}}\n },\n /* /Actions */\n /* Commands */\n commands: {\n {{commands}}\n },\n /* /Commands */\n /* Routes */\n routes: {\n {{routes}}\n }\n /* /Routes */\n });\n });\n function clone(ob) {\n return JSON.parse(JSON.stringify(ob));\n }\n function updateDataSource(name) {\n document.querySelectorAll('[data-simply-data=\"'+name+'\"]').forEach(function(list) {\n editor.list.applyDataSource(list, name);\n list.dataBindingPaused = 0;\n });\n }\n </script>\n </head>\n <body>\n <!-- Body HTML -->\n {{bodyHtml}}\n <!-- /Body HTML -->\n <!-- Component HTML templates -->\n {{componentTemplates}}\n <!-- /Component HTML templates -->\n <header data-simply-path=\"/\" data-simply-field=\"header\" data-simply-content=\"template\" data-simply-default-value=\"Header\">\n <template data-simply-template='Header' rel=\"header\"></template>\n </header>\n <nav>\n <simply-render rel=\"menu\"></simply-render>\n </nav>\n <div class=\"main\" data-simply-field=\"page\" data-simply-content=\"template\">\n <!-- Page HTML templates -->\n {{pageTemplates}}\n <!-- /Page HTML templates -->\n </div>\n <script src=\"js/simply.everything.js\"></script>\n <script src=\"js/simply-edit.js\" data-simply-storage=\"none\" data-api-key=\"muze\"></script>\n <script>\n /* Transformers */\n editor.transformers = {\n {{transformers}}\n };\n /* /Transformers */\n </script>\n <script>\n /* Sorters */\n editor.sorters = {\n {{sorters}}\n };\n /* /Sorters */\n </script>\n <script>\n window.addEventListener(\"simply-content-loaded\", function() {\n /* Data sources */\n {{dataSources}}\n /* /Data sources */\n });\n </script>\n <!-- Foot HTML -->\n {{footHtml}}\n <!-- /Foot HTML -->\n </body>\n</html>", + "pagePreview.html" : "<!DOCTYPE HTML>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <!-- Component CSS -->\n <style>\n {{componentCss}}\n </style>\n <!-- /Component CSS -->\n <!-- Page CSS -->\n <style>\n {{pageCss}}\n </style>\n <!-- /Page CSS -->\n <!-- Head HTML -->\n {{headHtml}}\n <!-- /Head HTML -->\n <script>\n function clone(ob) {\n return JSON.parse(JSON.stringify(ob));\n }\n function updateDataSource(name) {\n document.querySelectorAll('[data-simply-data=\"'+name+'\"]').forEach(function(list) {\n editor.list.applyDataSource(list, name);\n list.dataBindingPaused = 0;\n });\n }\n </script>\n </head>\n <body>\n <!-- Component HTML templates -->\n {{componentTemplates}}\n <!-- /Component HTML templates -->\n <header data-simply-path=\"/\" data-simply-field=\"header\" data-simply-content=\"template\" data-simply-default-value=\"Header\">\n <template data-simply-template='Header' rel=\"header\"></template>\n </header>\n <nav>\n <simply-render rel=\"menu\"></simply-render>\n </nav>\n <div class=\"main\" data-simply-field=\"page\" data-simply-content=\"template\">\n {{pagePreview}}\n </div>\n <script src=\"js/simply.everything.js\"></script>\n <script src=\"js/simply-edit.js\" data-simply-storage=\"none\" data-api-key=\"muze\"></script>\n <script>\n /* Transformers */\n editor.transformers = {\n {{transformers}}\n };\n /* /Transformers */\n </script>\n <script>\n /* Sorters */\n editor.sorters = {\n {{sorters}}\n };\n /* /Sorters */\n </script>\n <script>\n window.addEventListener(\"simply-content-loaded\", function() {\n /* Data sources */\n {{dataSources}}\n /* /Data sources */\n });\n </script>\n <!-- Foot HTML -->\n {{footHtml}}\n <!-- /Foot HTML -->\n </body>\n</html>" }; let elements = {}; @@ -3738,7 +3738,7 @@

App preview

- + - + - + - + - + - \ No newline at end of file + \ No newline at end of file diff --git a/www/api/data/base-components/codemirror/footHtml/Codemirror modes.html b/www/api/data/base-components/codemirror/footHtml/Codemirror modes.html index def9544..b99261f 100644 --- a/www/api/data/base-components/codemirror/footHtml/Codemirror modes.html +++ b/www/api/data/base-components/codemirror/footHtml/Codemirror modes.html @@ -1,4 +1,4 @@ - - - - \ No newline at end of file + + + + \ No newline at end of file diff --git a/www/api/data/base-components/codemirror/footHtml/Codemirror styles.html b/www/api/data/base-components/codemirror/footHtml/Codemirror styles.html index bf3d94e..f5ab220 100644 --- a/www/api/data/base-components/codemirror/footHtml/Codemirror styles.html +++ b/www/api/data/base-components/codemirror/footHtml/Codemirror styles.html @@ -1,2 +1,2 @@ - - \ No newline at end of file + + \ No newline at end of file From 934afeb70889602df2d567742c1e5d7e767f238b Mon Sep 17 00:00:00 2001 From: Ben Peachey Date: Sun, 7 Jul 2024 17:13:36 +0200 Subject: [PATCH 12/28] Update generated code. --- www/api/data/generated.html | 186 ++++++++++++++++++------------------ www/index.html | 14 +-- 2 files changed, 100 insertions(+), 100 deletions(-) diff --git a/www/api/data/generated.html b/www/api/data/generated.html index 0bf4667..9c9739b 100644 --- a/www/api/data/generated.html +++ b/www/api/data/generated.html @@ -33,18 +33,18 @@ } /* style */ @import url('https://fonts.googleapis.com/css?family=Alegreya+Sans:400,400i,700,700i'); - + :root { --highlight-dark: #f16623; --highlight-light: #ff8003; --highlight-color: #fff; --highlight-background: linear-gradient( to left, var(--highlight-light), var(--highlight-dark) ); - + --support-dark: #444; --support-light: #484848; --support-color: #eee; --support-background: linear-gradient( to left, var(--support-light), var(--support-dark) ); - + --grey-dark: #38393c; --grey-medium: #7f8185; --grey-light: #e9ebec; @@ -52,23 +52,23 @@ --black: #000; --white: #fff; --grey-background: var(--grey-dark); - + --font-family: 'Alegreya Sans', sans-serif; --font-size: 14px; --line-height: 1.5em; --color: #7f8185; --background: #333; } - + /* general styling on default elements */ - + html, body { margin: 0; padding: 0; font-family: var(--font-family); font-size: var(--font-size); line-height: var(--line-height); - color: var(--color); + color: var(--color); background-color: var(--background); } body { @@ -84,7 +84,7 @@ margin: 0; margin-bottom: 0.5em; } - + h2 { font-size: 1.6em; font-weight: 400; @@ -92,25 +92,25 @@ margin: 0; margin-bottom: 0.5em; } - + * { box-sizing: border-box; } - + img { display: block; max-width: 100%; } - + a { color: var(--highlight-dark); } a:visited { color: var(--highlight-dark); } - + /* custom styling for custom elements */ - + .sb-button, a.sb-button { background: var(--support-background); @@ -120,7 +120,7 @@ border: 1px solid #ccc; text-decoration: none; } - + .sb-button:first-child { margin-left: 0; } @@ -131,7 +131,7 @@ background: var(--highlight-background); color: var(--highlight-color); } - + .text-content { padding: 2.2375em; max-width: 50em; @@ -139,13 +139,13 @@ .text-content *:first-child { margin-top: 0; } - + body { - display: grid; - grid-template-columns: 210px 2fr 2fr; - grid-template-rows: 60px 2fr 2fr; - gap: 0px 0px; - grid-template-areas: + display: grid; + grid-template-columns: 210px 2fr 2fr; + grid-template-rows: 60px 2fr 2fr; + gap: 0px 0px; + grid-template-areas: "header header header" "nav pane pane" "nav pane pane" @@ -171,7 +171,7 @@ nav ul ul { padding: 0 1.7em; } - + nav > ul > li[data-simply-command=expandMenu][open]::before { content: "[-] "; font-family: monospace; @@ -183,7 +183,7 @@ .sb-part { margin-top: 1em; } - + .sb-part-header { display: grid; grid-template-columns: 1fr 1fr; @@ -273,7 +273,7 @@ .sb-editor-code textarea { margin-top: -1px; } - + ul.sb-components-list { list-style: none; padding: 0; @@ -289,9 +289,9 @@ padding: 10px; border-radius: 2px; } - + /* Components: Toast */ - + :root { --simply-toast-height: 60px; --simply-toast-hide-delay: 3s; @@ -313,7 +313,7 @@ --simply-heading-weight: 900; --simply-heading-multiplier: 1.1; } - + ul.simply-toasts, ol.simply-toasts, .simply-toasts { @@ -354,7 +354,7 @@ li.simply-toast-warning { border-color: var(--simply-warning-color); } - + @keyframes simply-toast-show { 0% { transform: scaleX(0); @@ -413,7 +413,7 @@ animation: simply-toast-move var(--simply-toast-show-duration), simply-toast-hide var(--simply-toast-hide-duration) forwards; animation-delay: 0s, var(--simply-toast-hide-delay); } - + /* QUnit iframe */ .qunit-code { display: none; @@ -538,14 +538,14 @@ border: 0; z-index: 10; } - body:has(main.sb-fullscreen-preview) header, + body:has(main.sb-fullscreen-preview) header, body:has(main.sb-fullscreen-preview) nav { display: none; } - + @@ -4223,18 +4223,18 @@

App preview

// Handle changes of the part name var component = event.data.dataBinding.parentKey.split("/")[3]; var componentNameField = simplyApp.actions.getComponentNameField(component); - + if (event.data.arguments[0] == componentNameField) { var newname = event.data.arguments[1]; var oldname = event.data.arguments[2]; - + editor.pageData.app[component].forEach(function(appPart) { if (appPart[componentNameField] == oldname) { appPart[componentNameField] = newname; } }); } - + if (typeof autoRunPreviewTimeout !== "undefined") { window.clearTimeout(autoRunPreviewTimeout); } @@ -4260,11 +4260,11 @@

App preview

} }); } - + document.querySelectorAll("[data-simply-transformer=simplyPreviewComponent]").forEach(function(element) { element.innerHTML = editor.transformers.simplyPreviewComponent.render.call(element, element.dataBinding.get()); }); - + simplyApp.commands.autoRunPreviews() }, 500); } @@ -4288,15 +4288,15 @@

App preview

}); - + - - - - + + + + - - + + - \ No newline at end of file + diff --git a/www/index.html b/www/index.html index e824993..47d122a 100644 --- a/www/index.html +++ b/www/index.html @@ -4286,15 +4286,15 @@

App preview

}); - + - - - - + + + + - - + + @@ -4223,18 +4235,18 @@

App preview

// Handle changes of the part name var component = event.data.dataBinding.parentKey.split("/")[3]; var componentNameField = simplyApp.actions.getComponentNameField(component); - + if (event.data.arguments[0] == componentNameField) { var newname = event.data.arguments[1]; var oldname = event.data.arguments[2]; - + editor.pageData.app[component].forEach(function(appPart) { if (appPart[componentNameField] == oldname) { appPart[componentNameField] = newname; } }); } - + if (typeof autoRunPreviewTimeout !== "undefined") { window.clearTimeout(autoRunPreviewTimeout); } @@ -4260,11 +4272,11 @@

App preview

} }); } - + document.querySelectorAll("[data-simply-transformer=simplyPreviewComponent]").forEach(function(element) { element.innerHTML = editor.transformers.simplyPreviewComponent.render.call(element, element.dataBinding.get()); }); - + simplyApp.commands.autoRunPreviews() }, 500); } @@ -4356,12 +4368,12 @@

App preview

localStorage.dragdrop = "dragStart"; document.currentDragItem = target; // event.dataTransfer.effectAllowed = 'move'; - + event.dataTransfer.setData("application/json", JSON.stringify(simply.dragdrop.getData(target), true)); var simplyType = "simply/" + target.parentNode.dataBinding.config.key.toLowerCase(); event.dataTransfer.setData(simplyType, "1"); event.dataTransfer.setDragImage(event.target, 0, 0); - + return true; }, dragEnter : function(event) { @@ -4394,17 +4406,17 @@

App preview

drop : function(event) { var listParent = simply.dragdrop.getListParent(event.target); var data = JSON.parse(event.dataTransfer.getData("application/json")); - + listParent.classList.remove("simply-dragdrop-receiving"); - + const expectedType = "simply/" + listParent.dataBinding.config.key.toLowerCase(); const isTypeAccepted = event.dataTransfer.types.includes(expectedType); - + if (listParent && isTypeAccepted) { var data = JSON.parse(event.dataTransfer.getData("application/json")); event.preventDefault(); let dropEffect = event.dataTransfer.dropEffect; - + switch (dropEffect) { case "move": localStorage.dragdrop = "move"; @@ -4477,4 +4489,4 @@

App preview

- + \ No newline at end of file diff --git a/www/api/data/pages/page-frame/dataApi/getPageFrame.js b/www/api/data/pages/page-frame/dataApi/getPageFrame.js index 99b284a..abe4d96 100644 --- a/www/api/data/pages/page-frame/dataApi/getPageFrame.js +++ b/www/api/data/pages/page-frame/dataApi/getPageFrame.js @@ -12,8 +12,8 @@ function() { .catch(function() { let defaults = { "componentPreview.html" : "<!DOCTYPE HTML>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <!-- Component CSS -->\n <style>\n {{componentCss}}\n </style>\n <!-- /Component CSS -->\n <!-- Page CSS -->\n <style>\n {{pageCss}}\n </style>\n <!-- /Page CSS -->\n <!-- Head HTML -->\n {{headHtml}}\n <!-- /Head HTML -->\n <script>\n function clone(ob) {\n return JSON.parse(JSON.stringify(ob));\n }\n function updateDataSource(name) {\n document.querySelectorAll('[data-simply-data=\"'+name+'\"]').forEach(function(list) {\n editor.list.applyDataSource(list, name);\n list.dataBindingPaused = 0;\n });\n }\n </script>\n </head>\n <body>\n <!-- Component HTML templates -->\n {{componentTemplates}}\n <!-- /Component HTML templates -->\n <div class=\"main\">\n {{componentPreview}}\n </div>\n <script src=\"js/simply.everything.js\"></script>\n <script src=\"js/simply-edit.js\" data-simply-storage=\"none\" data-api-key=\"muze\"></script>\n <script>\n /* Transformers */\n editor.transformers = {\n {{transformers}}\n };\n /* /Transformers */\n </script>\n <script>\n /* Sorters */\n editor.sorters = {\n {{sorters}}\n };\n /* /Sorters */\n </script>\n <script>\n window.addEventListener(\"simply-content-loaded\", function() {\n /* Data sources */\n {{dataSources}}\n /* /Data sources */\n });\n </script>\n <!-- Foot HTML -->\n {{footHtml}}\n <!-- /Foot HTML -->\n </body>\n</html>", - "fullApp.html" : "<!DOCTYPE HTML>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <!-- Component CSS -->\n <style>\n {{componentCss}}\n </style>\n <!-- /Component CSS -->\n <!-- Page CSS -->\n <style>\n {{pageCss}}\n </style>\n <!-- /Page CSS -->\n <!-- Head HTML -->\n {{headHtml}}\n <!-- /Head HTML -->\n <script>\n var simplyDataApi = {};\n var simplyApp = {};\n window.addEventListener(\"simply-content-loaded\", function() {\n simply.bind = false;\n /* Raw API */\n var simplyRawApi = {\n {{rawApi}}\n };\n /* End of Raw API */\n /* Data API */\n simplyDataApi = {\n {{dataApi}}\n };\n /* End of Data API */\n simplyApp = simply.app({\n /* Actions */\n actions: {\n {{actions}}\n },\n /* /Actions */\n /* Commands */\n commands: {\n {{commands}}\n },\n /* /Commands */\n /* Routes */\n routes: {\n {{routes}}\n }\n /* /Routes */\n });\n });\n function clone(ob) {\n return JSON.parse(JSON.stringify(ob));\n }\n function updateDataSource(name) {\n document.querySelectorAll('[data-simply-data=\"'+name+'\"]').forEach(function(list) {\n editor.list.applyDataSource(list, name);\n list.dataBindingPaused = 0;\n });\n }\n </script>\n </head>\n <body>\n <!-- Body HTML -->\n {{bodyHtml}}\n <!-- /Body HTML -->\n <!-- Component HTML templates -->\n {{componentTemplates}}\n <!-- /Component HTML templates -->\n <header data-simply-path=\"/\" data-simply-field=\"header\" data-simply-content=\"template\" data-simply-default-value=\"Header\">\n <template data-simply-template='Header' rel=\"header\"></template>\n </header>\n <nav>\n <simply-render rel=\"menu\"></simply-render>\n </nav>\n <div class=\"main\" data-simply-field=\"page\" data-simply-content=\"template\">\n <!-- Page HTML templates -->\n {{pageTemplates}}\n <!-- /Page HTML templates -->\n </div>\n <script src=\"js/simply.everything.js\"></script>\n <script src=\"js/simply-edit.js\" data-simply-storage=\"none\" data-api-key=\"muze\"></script>\n <script>\n /* Transformers */\n editor.transformers = {\n {{transformers}}\n };\n /* /Transformers */\n </script>\n <script>\n /* Sorters */\n editor.sorters = {\n {{sorters}}\n };\n /* /Sorters */\n </script>\n <script>\n window.addEventListener(\"simply-content-loaded\", function() {\n /* Data sources */\n {{dataSources}}\n /* /Data sources */\n });\n </script>\n <!-- Foot HTML -->\n {{footHtml}}\n <!-- /Foot HTML -->\n </body>\n</html>", - "pagePreview.html" : "<!DOCTYPE HTML>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <!-- Component CSS -->\n <style>\n {{componentCss}}\n </style>\n <!-- /Component CSS -->\n <!-- Page CSS -->\n <style>\n {{pageCss}}\n </style>\n <!-- /Page CSS -->\n <!-- Head HTML -->\n {{headHtml}}\n <!-- /Head HTML -->\n <script>\n function clone(ob) {\n return JSON.parse(JSON.stringify(ob));\n }\n function updateDataSource(name) {\n document.querySelectorAll('[data-simply-data=\"'+name+'\"]').forEach(function(list) {\n editor.list.applyDataSource(list, name);\n list.dataBindingPaused = 0;\n });\n }\n </script>\n </head>\n <body>\n <!-- Component HTML templates -->\n {{componentTemplates}}\n <!-- /Component HTML templates -->\n <header data-simply-path=\"/\" data-simply-field=\"header\" data-simply-content=\"template\" data-simply-default-value=\"Header\">\n <template data-simply-template='Header' rel=\"header\"></template>\n </header>\n <nav>\n <simply-render rel=\"menu\"></simply-render>\n </nav>\n <div class=\"main\" data-simply-field=\"page\" data-simply-content=\"template\">\n {{pagePreview}}\n </div>\n <script src=\"js/simply.everything.js\"></script>\n <script src=\"js/simply-edit.js\" data-simply-storage=\"none\" data-api-key=\"muze\"></script>\n <script>\n /* Transformers */\n editor.transformers = {\n {{transformers}}\n };\n /* /Transformers */\n </script>\n <script>\n /* Sorters */\n editor.sorters = {\n {{sorters}}\n };\n /* /Sorters */\n </script>\n <script>\n window.addEventListener(\"simply-content-loaded\", function() {\n /* Data sources */\n {{dataSources}}\n /* /Data sources */\n });\n </script>\n <!-- Foot HTML -->\n {{footHtml}}\n <!-- /Foot HTML -->\n </body>\n</html>" + "fullApp.html" : "<!DOCTYPE HTML>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <!-- Component CSS -->\n <style>\n {{componentCss}}\n </style>\n <!-- /Component CSS -->\n <!-- Page CSS -->\n <style>\n {{pageCss}}\n </style>\n <!-- /Page CSS -->\n <!-- Head HTML -->\n {{headHtml}}\n <!-- /Head HTML -->\n <script>\n var simplyDataApi = {};\n var simplyApp = {};\n window.addEventListener(\"simply-content-loaded\", function() {\n simply.bind = false;\n /* Raw API */\n var simplyRawApi = {\n {{rawApi}}\n };\n /* End of Raw API */\n /* Data API */\n simplyDataApi = {\n {{dataApi}}\n };\n /* End of Data API */\n simplyApp = simply.app({\n /* Actions */\n actions: {\n {{actions}}\n },\n /* /Actions */\n /* Commands */\n commands: {\n {{commands}}\n },\n /* /Commands */\n /* Routes */\n routes: {\n {{routes}}\n }\n /* /Routes */\n });\n });\n function clone(ob) {\n return JSON.parse(JSON.stringify(ob));\n }\n function updateDataSource(name) {\n document.querySelectorAll('[data-simply-data=\"'+name+'\"]').forEach(function(list) {\n editor.list.applyDataSource(list, name);\n list.dataBindingPaused = 0;\n });\n }\n </script>\n </head>\n <body>\n <!-- Body HTML -->\n {{bodyHtml}}\n <!-- /Body HTML -->\n <!-- Component HTML templates -->\n {{componentTemplates}}\n <!-- /Component HTML templates -->\n <div class=\"main\" data-simply-field=\"page\" data-simply-content=\"template\">\n <!-- Page HTML templates -->\n {{pageTemplates}}\n <!-- /Page HTML templates -->\n </div>\n <script src=\"js/simply.everything.js\"></script>\n <script src=\"js/simply-edit.js\" data-simply-storage=\"none\" data-api-key=\"muze\"></script>\n <script>\n /* Transformers */\n editor.transformers = {\n {{transformers}}\n };\n /* /Transformers */\n </script>\n <script>\n /* Sorters */\n editor.sorters = {\n {{sorters}}\n };\n /* /Sorters */\n </script>\n <script>\n window.addEventListener(\"simply-content-loaded\", function() {\n /* Data sources */\n {{dataSources}}\n /* /Data sources */\n });\n </script>\n <!-- Foot HTML -->\n {{footHtml}}\n <!-- /Foot HTML -->\n </body>\n</html>", + "pagePreview.html" : "<!DOCTYPE HTML>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <!-- Component CSS -->\n <style>\n {{componentCss}}\n </style>\n <!-- /Component CSS -->\n <!-- Page CSS -->\n <style>\n {{pageCss}}\n </style>\n <!-- /Page CSS -->\n <!-- Head HTML -->\n {{headHtml}}\n <!-- /Head HTML -->\n <script>\n function clone(ob) {\n return JSON.parse(JSON.stringify(ob));\n }\n function updateDataSource(name) {\n document.querySelectorAll('[data-simply-data=\"'+name+'\"]').forEach(function(list) {\n editor.list.applyDataSource(list, name);\n list.dataBindingPaused = 0;\n });\n }\n </script>\n </head>\n <body>\n <!-- Component HTML templates -->\n {{componentTemplates}}\n <!-- /Component HTML templates -->\n <div class=\"main\" data-simply-field=\"page\" data-simply-content=\"template\">\n {{pagePreview}}\n </div>\n <script src=\"js/simply.everything.js\"></script>\n <script src=\"js/simply-edit.js\" data-simply-storage=\"none\" data-api-key=\"muze\"></script>\n <script>\n /* Transformers */\n editor.transformers = {\n {{transformers}}\n };\n /* /Transformers */\n </script>\n <script>\n /* Sorters */\n editor.sorters = {\n {{sorters}}\n };\n /* /Sorters */\n </script>\n <script>\n window.addEventListener(\"simply-content-loaded\", function() {\n /* Data sources */\n {{dataSources}}\n /* /Data sources */\n });\n </script>\n <!-- Foot HTML -->\n {{footHtml}}\n <!-- /Foot HTML -->\n </body>\n</html>" }; let elements = {}; diff --git a/www/index.html b/www/index.html index 8617839..e37e2ff 100644 --- a/www/index.html +++ b/www/index.html @@ -1562,8 +1562,8 @@ .catch(function() { let defaults = { "componentPreview.html" : "<!DOCTYPE HTML>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <!-- Component CSS -->\n <style>\n {{componentCss}}\n </style>\n <!-- /Component CSS -->\n <!-- Page CSS -->\n <style>\n {{pageCss}}\n </style>\n <!-- /Page CSS -->\n <!-- Head HTML -->\n {{headHtml}}\n <!-- /Head HTML -->\n <script>\n function clone(ob) {\n return JSON.parse(JSON.stringify(ob));\n }\n function updateDataSource(name) {\n document.querySelectorAll('[data-simply-data=\"'+name+'\"]').forEach(function(list) {\n editor.list.applyDataSource(list, name);\n list.dataBindingPaused = 0;\n });\n }\n </script>\n </head>\n <body>\n <!-- Component HTML templates -->\n {{componentTemplates}}\n <!-- /Component HTML templates -->\n <div class=\"main\">\n {{componentPreview}}\n </div>\n <script src=\"js/simply.everything.js\"></script>\n <script src=\"js/simply-edit.js\" data-simply-storage=\"none\" data-api-key=\"muze\"></script>\n <script>\n /* Transformers */\n editor.transformers = {\n {{transformers}}\n };\n /* /Transformers */\n </script>\n <script>\n /* Sorters */\n editor.sorters = {\n {{sorters}}\n };\n /* /Sorters */\n </script>\n <script>\n window.addEventListener(\"simply-content-loaded\", function() {\n /* Data sources */\n {{dataSources}}\n /* /Data sources */\n });\n </script>\n <!-- Foot HTML -->\n {{footHtml}}\n <!-- /Foot HTML -->\n </body>\n</html>", - "fullApp.html" : "<!DOCTYPE HTML>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <!-- Component CSS -->\n <style>\n {{componentCss}}\n </style>\n <!-- /Component CSS -->\n <!-- Page CSS -->\n <style>\n {{pageCss}}\n </style>\n <!-- /Page CSS -->\n <!-- Head HTML -->\n {{headHtml}}\n <!-- /Head HTML -->\n <script>\n var simplyDataApi = {};\n var simplyApp = {};\n window.addEventListener(\"simply-content-loaded\", function() {\n simply.bind = false;\n /* Raw API */\n var simplyRawApi = {\n {{rawApi}}\n };\n /* End of Raw API */\n /* Data API */\n simplyDataApi = {\n {{dataApi}}\n };\n /* End of Data API */\n simplyApp = simply.app({\n /* Actions */\n actions: {\n {{actions}}\n },\n /* /Actions */\n /* Commands */\n commands: {\n {{commands}}\n },\n /* /Commands */\n /* Routes */\n routes: {\n {{routes}}\n }\n /* /Routes */\n });\n });\n function clone(ob) {\n return JSON.parse(JSON.stringify(ob));\n }\n function updateDataSource(name) {\n document.querySelectorAll('[data-simply-data=\"'+name+'\"]').forEach(function(list) {\n editor.list.applyDataSource(list, name);\n list.dataBindingPaused = 0;\n });\n }\n </script>\n </head>\n <body>\n <!-- Body HTML -->\n {{bodyHtml}}\n <!-- /Body HTML -->\n <!-- Component HTML templates -->\n {{componentTemplates}}\n <!-- /Component HTML templates -->\n <header data-simply-path=\"/\" data-simply-field=\"header\" data-simply-content=\"template\" data-simply-default-value=\"Header\">\n <template data-simply-template='Header' rel=\"header\"></template>\n </header>\n <nav>\n <simply-render rel=\"menu\"></simply-render>\n </nav>\n <div class=\"main\" data-simply-field=\"page\" data-simply-content=\"template\">\n <!-- Page HTML templates -->\n {{pageTemplates}}\n <!-- /Page HTML templates -->\n </div>\n <script src=\"js/simply.everything.js\"></script>\n <script src=\"js/simply-edit.js\" data-simply-storage=\"none\" data-api-key=\"muze\"></script>\n <script>\n /* Transformers */\n editor.transformers = {\n {{transformers}}\n };\n /* /Transformers */\n </script>\n <script>\n /* Sorters */\n editor.sorters = {\n {{sorters}}\n };\n /* /Sorters */\n </script>\n <script>\n window.addEventListener(\"simply-content-loaded\", function() {\n /* Data sources */\n {{dataSources}}\n /* /Data sources */\n });\n </script>\n <!-- Foot HTML -->\n {{footHtml}}\n <!-- /Foot HTML -->\n </body>\n</html>", - "pagePreview.html" : "<!DOCTYPE HTML>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <!-- Component CSS -->\n <style>\n {{componentCss}}\n </style>\n <!-- /Component CSS -->\n <!-- Page CSS -->\n <style>\n {{pageCss}}\n </style>\n <!-- /Page CSS -->\n <!-- Head HTML -->\n {{headHtml}}\n <!-- /Head HTML -->\n <script>\n function clone(ob) {\n return JSON.parse(JSON.stringify(ob));\n }\n function updateDataSource(name) {\n document.querySelectorAll('[data-simply-data=\"'+name+'\"]').forEach(function(list) {\n editor.list.applyDataSource(list, name);\n list.dataBindingPaused = 0;\n });\n }\n </script>\n </head>\n <body>\n <!-- Component HTML templates -->\n {{componentTemplates}}\n <!-- /Component HTML templates -->\n <header data-simply-path=\"/\" data-simply-field=\"header\" data-simply-content=\"template\" data-simply-default-value=\"Header\">\n <template data-simply-template='Header' rel=\"header\"></template>\n </header>\n <nav>\n <simply-render rel=\"menu\"></simply-render>\n </nav>\n <div class=\"main\" data-simply-field=\"page\" data-simply-content=\"template\">\n {{pagePreview}}\n </div>\n <script src=\"js/simply.everything.js\"></script>\n <script src=\"js/simply-edit.js\" data-simply-storage=\"none\" data-api-key=\"muze\"></script>\n <script>\n /* Transformers */\n editor.transformers = {\n {{transformers}}\n };\n /* /Transformers */\n </script>\n <script>\n /* Sorters */\n editor.sorters = {\n {{sorters}}\n };\n /* /Sorters */\n </script>\n <script>\n window.addEventListener(\"simply-content-loaded\", function() {\n /* Data sources */\n {{dataSources}}\n /* /Data sources */\n });\n </script>\n <!-- Foot HTML -->\n {{footHtml}}\n <!-- /Foot HTML -->\n </body>\n</html>" + "fullApp.html" : "<!DOCTYPE HTML>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <!-- Component CSS -->\n <style>\n {{componentCss}}\n </style>\n <!-- /Component CSS -->\n <!-- Page CSS -->\n <style>\n {{pageCss}}\n </style>\n <!-- /Page CSS -->\n <!-- Head HTML -->\n {{headHtml}}\n <!-- /Head HTML -->\n <script>\n var simplyDataApi = {};\n var simplyApp = {};\n window.addEventListener(\"simply-content-loaded\", function() {\n simply.bind = false;\n /* Raw API */\n var simplyRawApi = {\n {{rawApi}}\n };\n /* End of Raw API */\n /* Data API */\n simplyDataApi = {\n {{dataApi}}\n };\n /* End of Data API */\n simplyApp = simply.app({\n /* Actions */\n actions: {\n {{actions}}\n },\n /* /Actions */\n /* Commands */\n commands: {\n {{commands}}\n },\n /* /Commands */\n /* Routes */\n routes: {\n {{routes}}\n }\n /* /Routes */\n });\n });\n function clone(ob) {\n return JSON.parse(JSON.stringify(ob));\n }\n function updateDataSource(name) {\n document.querySelectorAll('[data-simply-data=\"'+name+'\"]').forEach(function(list) {\n editor.list.applyDataSource(list, name);\n list.dataBindingPaused = 0;\n });\n }\n </script>\n </head>\n <body>\n <!-- Body HTML -->\n {{bodyHtml}}\n <!-- /Body HTML -->\n <!-- Component HTML templates -->\n {{componentTemplates}}\n <!-- /Component HTML templates -->\n <div class=\"main\" data-simply-field=\"page\" data-simply-content=\"template\">\n <!-- Page HTML templates -->\n {{pageTemplates}}\n <!-- /Page HTML templates -->\n </div>\n <script src=\"js/simply.everything.js\"></script>\n <script src=\"js/simply-edit.js\" data-simply-storage=\"none\" data-api-key=\"muze\"></script>\n <script>\n /* Transformers */\n editor.transformers = {\n {{transformers}}\n };\n /* /Transformers */\n </script>\n <script>\n /* Sorters */\n editor.sorters = {\n {{sorters}}\n };\n /* /Sorters */\n </script>\n <script>\n window.addEventListener(\"simply-content-loaded\", function() {\n /* Data sources */\n {{dataSources}}\n /* /Data sources */\n });\n </script>\n <!-- Foot HTML -->\n {{footHtml}}\n <!-- /Foot HTML -->\n </body>\n</html>", + "pagePreview.html" : "<!DOCTYPE HTML>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <!-- Component CSS -->\n <style>\n {{componentCss}}\n </style>\n <!-- /Component CSS -->\n <!-- Page CSS -->\n <style>\n {{pageCss}}\n </style>\n <!-- /Page CSS -->\n <!-- Head HTML -->\n {{headHtml}}\n <!-- /Head HTML -->\n <script>\n function clone(ob) {\n return JSON.parse(JSON.stringify(ob));\n }\n function updateDataSource(name) {\n document.querySelectorAll('[data-simply-data=\"'+name+'\"]').forEach(function(list) {\n editor.list.applyDataSource(list, name);\n list.dataBindingPaused = 0;\n });\n }\n </script>\n </head>\n <body>\n <!-- Component HTML templates -->\n {{componentTemplates}}\n <!-- /Component HTML templates -->\n <div class=\"main\" data-simply-field=\"page\" data-simply-content=\"template\">\n {{pagePreview}}\n </div>\n <script src=\"js/simply.everything.js\"></script>\n <script src=\"js/simply-edit.js\" data-simply-storage=\"none\" data-api-key=\"muze\"></script>\n <script>\n /* Transformers */\n editor.transformers = {\n {{transformers}}\n };\n /* /Transformers */\n </script>\n <script>\n /* Sorters */\n editor.sorters = {\n {{sorters}}\n };\n /* /Sorters */\n </script>\n <script>\n window.addEventListener(\"simply-content-loaded\", function() {\n /* Data sources */\n {{dataSources}}\n /* /Data sources */\n });\n </script>\n <!-- Foot HTML -->\n {{footHtml}}\n <!-- /Foot HTML -->\n </body>\n</html>" }; let elements = {}; From 2da9f741b392ed884b4e4b3123208c3f15d34c03 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Wed, 16 Oct 2024 19:31:59 +0200 Subject: [PATCH 15/28] update simply-edit --- www/js/simply-edit.js | 997 +--- www/simply/css/editor.v9.css | 2265 ++++++++ www/simply/databind.js | 1037 ++++ www/simply/diff_match_patch.js | 76 + www/simply/pack | 1 + www/simply/plugin.simply-about.html | 191 + www/simply/plugin.simply-baseurl.html | 52 + www/simply/plugin.simply-browse.html | 934 ++++ www/simply/plugin.simply-diff.html | 284 + www/simply/plugin.simply-dropbox.html | 48 + www/simply/plugin.simply-htmlsource.html | 190 + www/simply/plugin.simply-keyboard.html | 170 + www/simply/plugin.simply-login.html | 67 + www/simply/plugin.simply-meta.html | 143 + www/simply/plugin.simply-paste.html | 362 ++ www/simply/plugin.simply-paste.html.krak | 351 ++ www/simply/plugin.simply-plain.html | 62 + www/simply/plugin.simply-save.html | 86 + www/simply/plugin.simply-scaler.html | 221 + www/simply/plugin.simply-symbol.html | 133 + www/simply/plugin.simply-template.html | 134 + www/simply/plugin.simply-undo-redo.html | 233 + www/simply/plugin.toolbar-scroll.html | 103 + www/simply/scripts.js | 2325 ++++++++ www/simply/simply.elementBinding.js | 697 +++ www/simply/simply.tripleBinding.js | 575 ++ www/simply/slip.js | 1095 ++++ www/simply/toolbar.simply-basepack.html | 5371 +++++++++++++++++++ www/simply/toolbar.simply-basepack.html.foo | 5354 ++++++++++++++++++ www/simply/toolbar.simply-icon.html | 16 + www/simply/toolbar.simply-iframe.html | 82 + www/simply/toolbar.simply-image.html | 673 +++ www/simply/toolbar.simply-list.html | 448 ++ www/simply/toolbar.simply-main-toolbar.html | 38 + www/simply/toolbar.simply-selectable.html | 167 + www/simply/toolbar.simply-text.html | 998 ++++ www/simply/toolbars.js | 1303 +++++ 37 files changed, 26354 insertions(+), 928 deletions(-) mode change 100644 => 100755 www/js/simply-edit.js create mode 100644 www/simply/css/editor.v9.css create mode 100644 www/simply/databind.js create mode 100644 www/simply/diff_match_patch.js create mode 100755 www/simply/pack create mode 100755 www/simply/plugin.simply-about.html create mode 100644 www/simply/plugin.simply-baseurl.html create mode 100644 www/simply/plugin.simply-browse.html create mode 100644 www/simply/plugin.simply-diff.html create mode 100644 www/simply/plugin.simply-dropbox.html create mode 100644 www/simply/plugin.simply-htmlsource.html create mode 100644 www/simply/plugin.simply-keyboard.html create mode 100644 www/simply/plugin.simply-login.html create mode 100644 www/simply/plugin.simply-meta.html create mode 100644 www/simply/plugin.simply-paste.html create mode 100644 www/simply/plugin.simply-paste.html.krak create mode 100644 www/simply/plugin.simply-plain.html create mode 100644 www/simply/plugin.simply-save.html create mode 100644 www/simply/plugin.simply-scaler.html create mode 100644 www/simply/plugin.simply-symbol.html create mode 100644 www/simply/plugin.simply-template.html create mode 100644 www/simply/plugin.simply-undo-redo.html create mode 100644 www/simply/plugin.toolbar-scroll.html create mode 100644 www/simply/scripts.js create mode 100644 www/simply/simply.elementBinding.js create mode 100644 www/simply/simply.tripleBinding.js create mode 100644 www/simply/slip.js create mode 100644 www/simply/toolbar.simply-basepack.html create mode 100644 www/simply/toolbar.simply-basepack.html.foo create mode 100644 www/simply/toolbar.simply-icon.html create mode 100644 www/simply/toolbar.simply-iframe.html create mode 100644 www/simply/toolbar.simply-image.html create mode 100755 www/simply/toolbar.simply-list.html create mode 100755 www/simply/toolbar.simply-main-toolbar.html create mode 100644 www/simply/toolbar.simply-selectable.html create mode 100644 www/simply/toolbar.simply-text.html create mode 100755 www/simply/toolbars.js diff --git a/www/js/simply-edit.js b/www/js/simply-edit.js old mode 100644 new mode 100755 index 6dee8a0..5be4d05 --- a/www/js/simply-edit.js +++ b/www/js/simply-edit.js @@ -100,7 +100,10 @@ var dataFields; if (target.nodeType == document.ELEMENT_NODE && target.getAttribute("data-simply-field")) { dataFields = [target]; - if (target.getAttribute("data-simply-content") === 'fixed') { // special case - if the target field has content fixed, we need to handle its children as well. + if ( + (target.getAttribute("data-simply-content") === 'fixed') || + (target.getAttribute("data-simply-content") === 'attributes') + ) { // special case - if the target field has content fixed or attributes, we need to handle its children as well. var extraFields = target.querySelectorAll("[data-simply-field]"); for (var x=0; x " + newparent); - value._bindings_[subbinding].parentKey = newparent; - if (value[subbinding] && value[subbinding].length) { - for (var i=0; i 5) { - console.log("Warning: databinding resolve loop detected!"); - window.setTimeout(function() { - binding.resolveCounter = 0; - }, 300); // 300 is a guess; could be any other number. It needs to be long enough so that everyone can settle down before we start resolving again. - return true; - } - return false; - }; - - var setElements = function() { - if (binding.elementTimer) { - window.clearTimeout(binding.elementTimer); - } - for (var i=0; i -1) { - binding.removeListeners(element); - binding.elements.splice(binding.elements.indexOf(element), 1); - } - }; - - this.cleanupBindings = function() { - if (binding.elements.length < 2) { - return; - } - - var inDocument = function(element) { - if (document.contains && document.contains(element)) { - return true; - } - var parent = element.parentNode; - while (parent) { - if (parent === document) { - return true; - } - if (parent.nodeType === document.DOCUMENT_FRAGMENT_NODE) { - if (parent.host && inDocument(parent.host)) { - return true; - } - } - parent = parent.parentNode; - } - return false; - }; - - binding.elements.forEach(function(element) { - if (!inDocument(element)) { - element.markedForRemoval = true; - } else { - element.markedForRemoval = false; - } - }); - - if (binding.cleanupTimer) { - clearTimeout(binding.cleanupTimer); - } - - binding.cleanupTimer = window.setTimeout(function() { - binding.elements.filter(function(element) { - if (element.markedForRemoval && !inDocument(element)) { - element.dataBinding.unbind(element); - return false; - } - element.markedForRemoval = false; - return true; - }); - }, 1000); // If after 1 second the element is still not in the dom, remove the binding; - }; - - initBindings(data, key); - // Call the custom init function, if it is there; - if (typeof binding.config.init === "function") { - binding.config.init.call(binding); - } - - if (binding.mode == "list") { - document.addEventListener("databind:resolved", function() { - if (!binding.skipOldValueUpdate) { - oldValue = dereference(binding.get()); - } - }); - } - }; - - var fieldNodeRemovedHandler = function(evt) { - if (!this.parentNode && this.dataBinding) { - this.dataBinding.unbind(this); - } - }; - - dataBinding.prototype.addListeners = function(element) { - if (element.dataBinding) { - element.dataBinding.removeListeners(element); - } - if (typeof element.mutationObserver === "undefined") { - if (typeof MutationObserver === "function") { - element.mutationObserver = new MutationObserver(this.handleMutation); - } - } - if (this.mode == "field") { - if (element.mutationObserver) { - element.mutationObserver.observe(element, {attributes: true}); - } - element.addEventListener("DOMSubtreeModified", this.handleEvent); - element.addEventListener("DOMNodeRemoved", fieldNodeRemovedHandler); - element.addEventListener("change", this.handleEvent); - } - if (this.mode == "list") { - if (element.mutationObserver) { - element.mutationObserver.observe(element, {attributes: true}); - } - element.addEventListener("DOMNodeRemoved", this.handleEvent); - element.addEventListener("DOMNodeInserted", this.handleEvent); - } - element.addEventListener("databinding:valuechanged", this.handleEvent); - - element.addEventListener("databinding:pause", function() { - this.dataBinding.pauseListeners(this); - }); - element.addEventListener("databinding:resume", function() { - this.dataBinding.resumeListeners(this); - }); - }; - dataBinding.prototype.resumeListeners = function(element) { - element.dataBindingPaused--; - if (element.dataBindingPaused < 0) { - console.log("Warning: resume called of non-paused databinding"); - element.dataBindingPaused = 0; - } - }; - dataBinding.prototype.pauseListeners = function(element) { - element.dataBindingPaused++; - }; - dataBinding.prototype.removeListeners = function(element) { - if (this.mode == "field") { - if (element.mutationObserver) { - element.mutationObserver.disconnect(); - } - element.removeEventListener("DOMSubtreeModified", this.handleEvent); - element.removeEventListener("DOMNodeRemoved", fieldNodeRemovedHandler); - element.removeEventListener("change", this.handleEvent); - } - if (this.mode == "list") { - if (element.mutationObserver) { - element.mutationObserver.disconnect(); - } - element.removeEventListener("DOMNodeRemoved", this.handleEvent); - element.removeEventListener("DOMNodeInserted", this.handleEvent); - } - element.removeEventListener("databinding:valuechanged", this.handleEvent); - }; - - dataBinding.prototype.handleMutation = function(event) { - // FIXME: assuming that one set of mutation events always have the same target; this might not be the case; - var target = event[0].target; - if (!target.dataBinding) { - return; - } - if (target.dataBindingPaused) { - return; - } - - if (target.dataBinding.paused) { - return; - } - var handleMe = false; - for (var i=0; i [data-simply-list-item]"); - for (i=0; i [data-simply-list-item]"); - for (i=0; i ul::after, .simply-toolbar-section > ul::after { + content: ""; + clear: both; + display: block; + } + .simply-toolbar .marker { + content: ""; + display: block; + position: absolute; + margin-top: -12px; + left: 50%; + margin-left: -12px; + width: 0; + border-bottom: 12px solid #ea5922; + border-top: 0px; + border-left: 12px solid transparent; + border-right: 12px solid transparent; + } + .simply-toolbar > ul { + background: linear-gradient(to bottom, white 0%, #FFF 95%, #DDD 100%); + min-width: 100%; + line-height: 0px; + } + .simply-toolbar > ul, + .simply-toolbar > ul > li, + .simply-toolbar-section > ul, + .simply-toolbar-section > ul > li { + margin: 0px; + padding: 0px; + border: 0px; + list-style: none; + white-space: nowrap; + } + .simply-toolbar-section > ul > li.simply-text-format { + margin-right: 4px; + } + .simply-toolbar li { + position: relative; + float: left; + } + #simply-main-toolbar .simply-toolbar { + min-height: 60px; + transform: translate3d(0,0,0); + } + #simply-main-toolbar .simply-buttons { + white-space: nowrap !important; + position: absolute; + } + #simply-main-toolbar .simply-toolbar li { + float: none; + display: inline-block; + } + + #vdTablePopup { + left: 40px; + top: 0px; + padding-bottom: 20px; + width: auto; + height: auto; + } + #vdTableText { + position: absolute; + bottom: 10px; + width: 100%; + } + #vdTablePreview table { + border-spacing: 2px; + border-collapse: separate; + width: 110px; + height: 110px; + } + + .simply-toolbar button { + border: 0px; + margin: 0px; + padding: 0px 2px; + background: transparent; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + position: relative; + min-width: 50px; + text-align: center; + height: 60px; + font-size: 11px; + color: #666 !important; + box-sizing: border-box; + font-weight: inherit; + letter-spacing: 0; + line-height: inherit; + text-transform: inherit; + font-family: inherit; + box-shadow: inherit; + border-radius: 0; + transition: inherit; + font-variant-caps: normal; + } + + @media (max-width: 480px) { + .simply-toolbar button { + min-width: 48px; + } + } + @media (max-width: 320px) { + .simply-toolbar button { + min-width: 40px; + } + } + #simply-main-toolbar button { + vertical-align: top; + } + .simply-toolbar button[disabled] { + opacity: 0.3; + } + .simply-toolbar button > i, + .simply-toolbar button > span.fa-stack { + line-height: 50px; + font-size: 19px; + display: inline-block; + padding: 0px 4px; + line-height: 38px; + display: block; + margin: -13px auto 0px; + position: relative; + } + .simply-toolbar button.simply-selected { + background-color: #EEE; + position: relative; + border-left: 1px solid #DDD; + border-right: 1px solid white; + } + .simply-toolbar button.simply-disabled { + opacity: 0.3; + } + + .simply-toolbar button:focus { + border-bottom: 2px solid orange !important; + } + .simply-toolbar label button:focus { + border-bottom: 0px !important; + } + button.simply-selected::first-child { + border-left: 0px; + } + button.simply-selected::last-child { + border-right: 0px; + } + + .simply-toolbar-section { + background-color: #EEE; + display: none; + clear: both; + } + section.simply-section.active { + opacity: 1; + z-index: 99999; + } + section.simply-section { + position: absolute; + opacity: 0; + -webkit-transition: opacity 0.2s ease-in-out; + -moz-transition: opacity 0.2s ease-in-out; + -ms-transition: opacity 0.2s ease-in-out; + -o-transition: opacity 0.2s ease-in-out; + transition: opacity 0.2s ease-in-out; + left: -10000px; /* position off screen initially */ + height: inherit; + } + .tagStack li { + padding-right: 5px; + } + .simply-toolbar-section ul { + background: linear-gradient(to bottom, #EEE 0%, #DDD 100%); + padding: 4px 2px; + } + .simply-toolbar-section.simply-selected { + display: block; + white-space: nowrap; + } + .simply-toolbar-section button { + height: 40px; + min-width: 23px; + border: 1px solid transparent; + line-height: 6px; + } + .simply-toolbar-section button > i, + .simply-toolbar-section button > span.fa-stack { + font-size: 14px; + line-height: 16px; + width: 23px; + margin: 0px auto 4px; + } + .simply-toolbar-section button.simply-selected { + background-color: #D7D7D7; + border: 1px solid #EEE; + border-left: 1px solid #888; + border-top: 1px solid #888; + border-radius: 2px; + } + section.simply-section { + margin-bottom: 150px; + } + section.simply-section h1 { + font-size: 16px; + font-weight: bold; + display: none; + } + button.simply-expands::after { + content: ""; + display: block; + position: absolute; + bottom: 6px; + left: 50%; + margin-left: -3px; + width: 0; + border-top: 3px solid #888; + border-bottom: 0px; + border-left: 3px solid transparent; + border-right: 3px solid transparent; + opacity: 1; + transform: inherit; + -webkit-transform: inherit; + top: inherit; + height: 0; + } + button.simply-selected.simply-expands::after { + display: none; + } + .simply-toolbar-section > div { + padding-left: 80px; + } + + .simply-toolbar-section label { + width: 60px; + font-size: 12px; + display: inline-block; + font-weight: normal; + padding-left: 10px; + margin: inherit; + margin-left: -80px; + color: inherit; + } + .simply-toolbar-section input, + .simply-toolbar-section select { + background-color: white; + color: black; + margin-top: 3px; + margin-bottom: 3px; + border: 1px solid #888; + border-bottom-color: #EEE; + border-right-color: #EEE; + border-radius: 2px; + line-height: 22px; + min-height: 22px; + width: 100%; + font-family: inherit; + font-size: inherit; + display: inline-block; + box-sizing: border-box !important; + padding: 2px 0 !important; + margin: 3px 0 !important; + } + .simply-toolbar-section select { + padding: 4px 0px !important; + } + .simply-toolbar button:focus { + outline: none; + } + .simply-context-html { + padding-left: 8px; + background-color: #EEE; + background: linear-gradient(to bottom, #EEE 0%, #DDD 100%); + overflow: hidden; + } + .simply-context-html ul, + .simply-context-html li { + display: block; + float: left; + } + a.simply-context-tag { + color: black; + font-size: 11px; + line-height: 12px; + padding: 0px 2px; + margin: 2px 0px; + display: inline-block; + cursor: pointer; + } + a.simply-context-tag.simply-selected { + background-color: #CCC; + border: 1px solid #EEE; + border-left: 1px solid #888; + border-top: 1px solid #888; + border-radius: 2px; + } + .simply-context-html li:last-child a.simply-context-tag::after { + content: ""; + } + + /* larger style html context */ + a.simply-context-tag { + font-size: 12px; + line-height: 14px; + display: block; + float: left; + padding: 2px; + margin: 2px; + border: 1px solid #666; + border-radius: 2px; + color: black; + background-color: #CCC; + } + a.simply-context-tag.simply-selected { + background-color: #FFFFCC; + } + .simply-float-right { + float: right; + } + .simply-toolbar button.simply-small > i, + .simply-toolbar button.simply-small > span.fa-stack { + line-height: 24px; + font-size: 14px; + margin: 0px; + } + .simply-toolbar button.simply-small { + height: auto; + width: auto; + min-width: 20px; + } + /* end */ + + li.simply-text-format { + line-height: 32px; + vertical-align: top; + width: 100%; + } + + li.simply-seperator label:before { + display: block; + position: absolute; + border-left: 1px solid #DDD; + border-right: 1px solid white; + height: 40px; + content: ""; + margin-top: -14px; + margin-left: -4px; + } + + label.simply-subsection { + text-align: center; + vertical-align: top; + line-height: 14px; + } + .simply-disabled { + color: #BBB; + } + #vdTextStyle { + height: auto; + width: auto; + overflow-x: inherit; + margin-left: auto; + padding: auto; + } + .simply-cell-width select, + .simply-cell-height select, + .simply-table-width select, + .simply-table-height select { + width: 40px; + } + button[data-simply-section=simply-clipboard], + .simply-clipboard { + display: none; + } + #editorPane, #vdMetaDataSlide { + -webkit-overflow-scrolling: touch !important; + } + /* simply dropdown list */ + .simply-list { + display: inline-block; + position: relative; + -webkit-user-select: none; + } + ul.simply-list-items { + position: absolute; + width: 100%; + min-width: 120px; + background-color: white; + box-sizing: border-box; + padding: 2px; + display: none; + margin: 0; + border: 1px solid #ccc; + } + .simply-list-items li { + list-style: none; + float: none; + padding: 2px 4px; + } + .simply-list-items input { + margin-right: 5px; + } + .simply-list-items label { + font-size: 13px; + line-height: 18px; + font-weight: normal; + display: block; + } + .simply-list.visible .simply-list-items { + display: block; + } + /* context menu */ + .simply-context-section { + position: absolute; + right: 20px; + top: 130px; + width: 210px; + height: 240px; + border: 1px solid #ccc; + box-shadow: 0px 0px 5px #888; + padding: 5px; + background: #F4F4F4; + display: none; + } + .simply-context-section.simply-selected { + display: block; + } + .simply-context-section .simply-close { + position: absolute; + top: -18px; + right: -18px; + width: 36px; + height: 36px; + background-image: url(' make_url(currentsite()); graphics/close.png'); + margin: 0px; + padding: 0px; + border: 0px; + min-width: 36px; + } + .simply-context-section iframe { + border: 0px; + margin: 0px; + padding: 0px; + width: 100%; + height: 100%; + } + .simply-context-section.simply-help { + top: 200px; + left: 50%; + width: 400px; + height: 250px; + margin-left: -200px; + } + +#simply-main-toolbar { + left: 0px !important; + opacity: 1 !important; + position: fixed; + margin-bottom: auto; + top: 0px; + right: 0px; + z-index: 100000; +} +#simply-main-toolbar .simply-toolbar { + position: static; +} +#simply-main-toolbar .simply-toolbar:before { + display: none; +} + +#simply-main-toolbar .simply-selected { + border: 0px; +} +#vdToolbars { + height: auto; + border: 0px; + margin-right: 0px; +} +#vdEditPane { + border: 0px; +} +#simply-main-toolbar .simply-buttons { + white-space: normal; +} +#simply-main-toolbar > .simply-toolbar > ul.simply-buttons > li.simply-seperator { + border-right: 1px solid #ddd; + height: 58px; + vertical-align: top; +} +#simply-main-toolbar i.simply-logo { + margin-bottom: 10px; + position: relative; + top: 4px; + width: 24px; + box-sizing: border-box; +} +.simply-hidden { + display: none !important; +} + +#simply-main-toolbar.simply-collapse .simply-toolbar .marker { + margin-top: -5px; + margin-left: 0px; + left: 0; + width: 0; + border-bottom: 0; + border-top: 25px solid #ea5922; + border-left: 0; + border-right: 25px solid transparent; +} +#simply-main-toolbar.simply-collapse .simply-toolbar { + border-top-color: transparent; +} + +#simply-main-toolbar.simply-collapse { + right: auto; +} +#simply-main-toolbar.simply-collapse li:nth-child(n+2) { + display: none; +} + + +/* Dialogs */ +.simply-dialog { + display: none; +} +.simply-dialog.active { + display: block; + border: 1px solid #aaa; + border-top: 5px solid #ea5922; + background-color: white; + font-family: arial, helvetica, sans-serif; + color: black; + padding: 0px; + position: fixed; + z-index: 100002; + box-shadow: 0px 0px 8px #444; +} + +.simply-dialog.simply-modal { + top: 50%; + height: 400px; + max-height: 80%; + margin-top: -200px; + + left: 50%; + width: 480px; + margin-left: -240px; + background-color: #EEE; +} +.simply-dialog.simply-modal.fullscreen { + top: 0px; + bottom: 0px; + left: 0px; + right: 0px; + max-width: 100%; + max-height: 100%; + height: auto; + width: auto; + margin-left: 0px; + margin-top: 0px; +} + + +@media (max-width: 641px) { + .simply-dialog, + .simply-dialog.simply-modal { + top: 0px; + bottom: 0px; + left: 0px; + right: 0px; + max-width: 100%; + max-height: 100%; + height: auto; + width: auto; + margin-left: 0px; + margin-top: 0px; + } + [data-simply-action="simply-dialog-fullscreen"] { + display: none; + } + .simply-dialog-body { + max-width: 100%; + } +} + +.simply-toolbar .simply-right { + float: right; +} +.simply-dialog .marker { + display: none; +} +.simply-dialog .simply-toolbar { + border: 0; + border-top: 1px solid #eee; + box-shadow: none; + width: 100%; +} + +.simply-dialog.simply-modal .simply-dialog-body { + overflow-y: scroll; + position: absolute; + top: 60px; + bottom: 0px; + padding: 11px 5px; + width: 100%; + box-sizing: border-box; +} +.simply-dialog-body:first-child { + top: 0px; +} +.simply-dialog-body:nth-child(2):last-child { + bottom: 0px; +} +.simply-dialog-body:nth-child(2):nth-last-child(2) { + bottom: 60px; +} + +.simply-dialog .simply-toolbar:first-child { + position: absolute; + top: 0px; +} +.simply-dialog .simply-toolbar:last-child { + position: absolute; + bottom: 0px; +} +.simply-dialog.simply-modal .simply-toolbar-section { + padding: 10px 5px; +} +.simply-empty[data-simply-list] { + min-height: 24px; + background-color: rgba(128,128,128,0.1); + outline: 2px dashed rgba(128,128,128,0.3); + text-align: center; +} +[data-simply-field]:not(input):not(textarea):not(img):empty { + min-height: 24px; + text-align: left; +} +.simply-empty[data-simply-list]:before, +[data-simply-field]:not(input):not(textarea):not(img):not([data-simply-list-item]):empty:before { + text-align: center; + font-family: FontAwesome; + font-size: 20px; + color: #888; + width: 100%; + line-height: 24px; + vertical-align: middle; + padding-top: 5px; + transition: 0.6s opacity ease; + opacity: 1; +} +.simply-empty[data-simply-list]:not([data-simply-list-icon]):before { + content: "\f1b3"; /* cubes */ +} +.simply-empty[data-simply-list][data-simply-list-icon]:not([data-simply-list-icon|="fa"]):before { + content: attr(data-simply-list-icon); +} +.simply-empty[data-simply-list]:after { + content: "(Empty list)"; + text-align: center; + font-family: arial; + font-size: 12px; + color: #888; + width: 100%; + line-height: 24px; + vertical-align: middle; + padding-bottom: 5px; + margin-left: 4px; +} +[data-simply-field]:not([data-simply-list-item]):empty:hover:before, +[data-simply-field]:not([data-simply-list-item]):empty:hover:after { + opacity: 0.3; +} + +[data-simply-field]:not(input):not(textarea):empty:not([data-simply-field-icon]):not([data-simply-list-item]):before { + content: "\f044"; /* pencil-square-o */ +} +[data-simply-field][data-simply-field-icon]:not(input):not(textarea):empty:not([data-simply-field-icon|="fa"]):not([data-simply-list-item]):before { + content: attr(data-simply-field-icon); +} +[data-simply-field]:not(input):not(textarea):empty:after { + content: "(Empty)"; + text-align: center; + font-family: arial; + font-size: 12px; + color: #888; + width: 100%; + line-height: 24px; + vertical-align: middle; + padding-bottom: 5px; + margin-left: 4px; + opacity: 1; + transition: 0.6s opacity ease; +} +body[data-simply-edit] [data-simply-collapsed] { + display: inline-block; +} +body[data-simply-edit] [data-simply-hope] { + min-height: 1.2em; + min-width: 1.2em; +} + +/* plain view */ +body.simply-plain [data-simply-field], +body.simply-plain [data-simply-list], +body.simply-plain [data-simply-list-item] { + display: block !important; + position: static !important; + vertical-align: top; + margin-left: 20px; +} +body.simply-plain [data-simply-field]:before { + content: "(Field) " attr(data-simply-field); +} +body.simply-plain [data-simply-list]:before { + content: "(List) " attr(data-simply-list); + position: static; + opacity: 1; +} +body.simply-plain [data-simply-list-item]:before, +body.simply-plain tr[data-simply-list-item] td:first-child:before { + content: "(List item) " attr(data-simply-template); + position: static; + opacity: 1; +} + +body.simply-plain [data-simply-list]:before, +body.simply-plain [data-simply-list-item]:before, +body.simply-plain tr[data-simply-list-item] td:first-child:before, +body.simply-plain [data-simply-field]:before { + border: 1px solid #999; + border-radius: 24px; + background-color: #eee; + color: #333; + display: inline-block; + width: auto; + margin: 5px; + padding: 5px; + font-size: 12px; + font-family: arial; + font-weight: normal; + font-style: normal; +} + +.simply-gadget { + position: relative; +} +.simply-gadget *[data-simply-list]:before { + display: none; +} +.simply-gadget > *:before, +.simply-gadget *[data-simply-list]:before { + display: block; + content: ""; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + z-index: 1000; + opacity: 0 !important; + border:0; + margin: 0; +} + +.simply-gadget *[data-simply-field] { + outline: 0; +} +.simply-gadget *[data-simply-list-item]:before { + display: none; +} +.simply-gadget *[data-simply-field]:hover { + outline: 0; +} +.simply-gadget[data-simply-selectable] { + outline: 2px dashed rgba(128,128,128,0.3); +} + + +/* Font awesome icons mapping */ +[data-simply-list-icon="fa-glass"]:before{content:"\f000"} +[data-simply-list-icon="fa-music"]:before{content:"\f001"} +[data-simply-list-icon="fa-search"]:before{content:"\f002"} +[data-simply-list-icon="fa-envelope-o"]:before{content:"\f003"} +[data-simply-list-icon="fa-heart"]:before{content:"\f004"} +[data-simply-list-icon="fa-star"]:before{content:"\f005"} +[data-simply-list-icon="fa-star-o"]:before{content:"\f006"} +[data-simply-list-icon="fa-user"]:before{content:"\f007"} +[data-simply-list-icon="fa-film"]:before{content:"\f008"} +[data-simply-list-icon="fa-th-large"]:before{content:"\f009"} +[data-simply-list-icon="fa-th"]:before{content:"\f00a"} +[data-simply-list-icon="fa-th-list"]:before{content:"\f00b"} +[data-simply-list-icon="fa-check"]:before{content:"\f00c"} +[data-simply-list-icon="fa-remove"]:before, +[data-simply-list-icon="fa-close"]:before, +[data-simply-list-icon="fa-times"]:before{content:"\f00d"} +[data-simply-list-icon="fa-search-plus"]:before{content:"\f00e"} +[data-simply-list-icon="fa-search-minus"]:before{content:"\f010"} +[data-simply-list-icon="fa-power-off"]:before{content:"\f011"} +[data-simply-list-icon="fa-signal"]:before{content:"\f012"} +[data-simply-list-icon="fa-gear"]:before, +[data-simply-list-icon="fa-cog"]:before{content:"\f013"} +[data-simply-list-icon="fa-trash-o"]:before{content:"\f014"} +[data-simply-list-icon="fa-home"]:before{content:"\f015"} +[data-simply-list-icon="fa-file-o"]:before{content:"\f016"} +[data-simply-list-icon="fa-clock-o"]:before{content:"\f017"} +[data-simply-list-icon="fa-road"]:before{content:"\f018"} +[data-simply-list-icon="fa-download"]:before{content:"\f019"} +[data-simply-list-icon="fa-arrow-circle-o-down"]:before{content:"\f01a"} +[data-simply-list-icon="fa-arrow-circle-o-up"]:before{content:"\f01b"} +[data-simply-list-icon="fa-inbox"]:before{content:"\f01c"} +[data-simply-list-icon="fa-play-circle-o"]:before{content:"\f01d"} +[data-simply-list-icon="fa-rotate-right"]:before, +[data-simply-list-icon="fa-repeat"]:before{content:"\f01e"} +[data-simply-list-icon="fa-refresh"]:before{content:"\f021"} +[data-simply-list-icon="fa-list-alt"]:before{content:"\f022"} +[data-simply-list-icon="fa-lock"]:before{content:"\f023"} +[data-simply-list-icon="fa-flag"]:before{content:"\f024"} +[data-simply-list-icon="fa-headphones"]:before{content:"\f025"} +[data-simply-list-icon="fa-volume-off"]:before{content:"\f026"} +[data-simply-list-icon="fa-volume-down"]:before{content:"\f027"} +[data-simply-list-icon="fa-volume-up"]:before{content:"\f028"} +[data-simply-list-icon="fa-qrcode"]:before{content:"\f029"} +[data-simply-list-icon="fa-barcode"]:before{content:"\f02a"} +[data-simply-list-icon="fa-tag"]:before{content:"\f02b"} +[data-simply-list-icon="fa-tags"]:before{content:"\f02c"} +[data-simply-list-icon="fa-book"]:before{content:"\f02d"} +[data-simply-list-icon="fa-bookmark"]:before{content:"\f02e"} +[data-simply-list-icon="fa-print"]:before{content:"\f02f"} +[data-simply-list-icon="fa-camera"]:before{content:"\f030"} +[data-simply-list-icon="fa-font"]:before{content:"\f031"} +[data-simply-list-icon="fa-bold"]:before{content:"\f032"} +[data-simply-list-icon="fa-italic"]:before{content:"\f033"} +[data-simply-list-icon="fa-text-height"]:before{content:"\f034"} +[data-simply-list-icon="fa-text-width"]:before{content:"\f035"} +[data-simply-list-icon="fa-align-left"]:before{content:"\f036"} +[data-simply-list-icon="fa-align-center"]:before{content:"\f037"} +[data-simply-list-icon="fa-align-right"]:before{content:"\f038"} +[data-simply-list-icon="fa-align-justify"]:before{content:"\f039"} +[data-simply-list-icon="fa-list"]:before{content:"\f03a"} +[data-simply-list-icon="fa-dedent"]:before, +[data-simply-list-icon="fa-outdent"]:before{content:"\f03b"} +[data-simply-list-icon="fa-indent"]:before{content:"\f03c"} +[data-simply-list-icon="fa-video-camera"]:before{content:"\f03d"} +[data-simply-list-icon="fa-photo"]:before, +[data-simply-list-icon="fa-image"]:before, +[data-simply-list-icon="fa-picture-o"]:before{content:"\f03e"} +[data-simply-list-icon="fa-pencil"]:before{content:"\f040"} +[data-simply-list-icon="fa-map-marker"]:before{content:"\f041"} +[data-simply-list-icon="fa-adjust"]:before{content:"\f042"} +[data-simply-list-icon="fa-tint"]:before{content:"\f043"} +[data-simply-list-icon="fa-edit"]:before, +[data-simply-list-icon="fa-pencil-square-o"]:before{content:"\f044"} +[data-simply-list-icon="fa-share-square-o"]:before{content:"\f045"} +[data-simply-list-icon="fa-check-square-o"]:before{content:"\f046"} +[data-simply-list-icon="fa-arrows"]:before{content:"\f047"} +[data-simply-list-icon="fa-step-backward"]:before{content:"\f048"} +[data-simply-list-icon="fa-fast-backward"]:before{content:"\f049"} +[data-simply-list-icon="fa-backward"]:before{content:"\f04a"} +[data-simply-list-icon="fa-play"]:before{content:"\f04b"} +[data-simply-list-icon="fa-pause"]:before{content:"\f04c"} +[data-simply-list-icon="fa-stop"]:before{content:"\f04d"} +[data-simply-list-icon="fa-forward"]:before{content:"\f04e"} +[data-simply-list-icon="fa-fast-forward"]:before{content:"\f050"} +[data-simply-list-icon="fa-step-forward"]:before{content:"\f051"} +[data-simply-list-icon="fa-eject"]:before{content:"\f052"} +[data-simply-list-icon="fa-chevron-left"]:before{content:"\f053"} +[data-simply-list-icon="fa-chevron-right"]:before{content:"\f054"} +[data-simply-list-icon="fa-plus-circle"]:before{content:"\f055"} +[data-simply-list-icon="fa-minus-circle"]:before{content:"\f056"} +[data-simply-list-icon="fa-times-circle"]:before{content:"\f057"} +[data-simply-list-icon="fa-check-circle"]:before{content:"\f058"} +[data-simply-list-icon="fa-question-circle"]:before{content:"\f059"} +[data-simply-list-icon="fa-info-circle"]:before{content:"\f05a"} +[data-simply-list-icon="fa-crosshairs"]:before{content:"\f05b"} +[data-simply-list-icon="fa-times-circle-o"]:before{content:"\f05c"} +[data-simply-list-icon="fa-check-circle-o"]:before{content:"\f05d"} +[data-simply-list-icon="fa-ban"]:before{content:"\f05e"} +[data-simply-list-icon="fa-arrow-left"]:before{content:"\f060"} +[data-simply-list-icon="fa-arrow-right"]:before{content:"\f061"} +[data-simply-list-icon="fa-arrow-up"]:before{content:"\f062"} +[data-simply-list-icon="fa-arrow-down"]:before{content:"\f063"} +[data-simply-list-icon="fa-mail-forward"]:before, +[data-simply-list-icon="fa-share"]:before{content:"\f064"} +[data-simply-list-icon="fa-expand"]:before{content:"\f065"} +[data-simply-list-icon="fa-compress"]:before{content:"\f066"} +[data-simply-list-icon="fa-plus"]:before{content:"\f067"} +[data-simply-list-icon="fa-minus"]:before{content:"\f068"} +[data-simply-list-icon="fa-asterisk"]:before{content:"\f069"} +[data-simply-list-icon="fa-exclamation-circle"]:before{content:"\f06a"} +[data-simply-list-icon="fa-gift"]:before{content:"\f06b"} +[data-simply-list-icon="fa-leaf"]:before{content:"\f06c"} +[data-simply-list-icon="fa-fire"]:before{content:"\f06d"} +[data-simply-list-icon="fa-eye"]:before{content:"\f06e"} +[data-simply-list-icon="fa-eye-slash"]:before{content:"\f070"} +[data-simply-list-icon="fa-warning"]:before, +[data-simply-list-icon="fa-exclamation-triangle"]:before{content:"\f071"} +[data-simply-list-icon="fa-plane"]:before{content:"\f072"} +[data-simply-list-icon="fa-calendar"]:before{content:"\f073"} +[data-simply-list-icon="fa-random"]:before{content:"\f074"} +[data-simply-list-icon="fa-comment"]:before{content:"\f075"} +[data-simply-list-icon="fa-magnet"]:before{content:"\f076"} +[data-simply-list-icon="fa-chevron-up"]:before{content:"\f077"} +[data-simply-list-icon="fa-chevron-down"]:before{content:"\f078"} +[data-simply-list-icon="fa-retweet"]:before{content:"\f079"} +[data-simply-list-icon="fa-shopping-cart"]:before{content:"\f07a"} +[data-simply-list-icon="fa-folder"]:before{content:"\f07b"} +[data-simply-list-icon="fa-folder-open"]:before{content:"\f07c"} +[data-simply-list-icon="fa-arrows-v"]:before{content:"\f07d"} +[data-simply-list-icon="fa-arrows-h"]:before{content:"\f07e"} +[data-simply-list-icon="fa-bar-chart-o"]:before, +[data-simply-list-icon="fa-bar-chart"]:before{content:"\f080"} +[data-simply-list-icon="fa-twitter-square"]:before{content:"\f081"} +[data-simply-list-icon="fa-facebook-square"]:before{content:"\f082"} +[data-simply-list-icon="fa-camera-retro"]:before{content:"\f083"} +[data-simply-list-icon="fa-key"]:before{content:"\f084"} +[data-simply-list-icon="fa-gears"]:before, +[data-simply-list-icon="fa-cogs"]:before{content:"\f085"} +[data-simply-list-icon="fa-comments"]:before{content:"\f086"} +[data-simply-list-icon="fa-thumbs-o-up"]:before{content:"\f087"} +[data-simply-list-icon="fa-thumbs-o-down"]:before{content:"\f088"} +[data-simply-list-icon="fa-star-half"]:before{content:"\f089"} +[data-simply-list-icon="fa-heart-o"]:before{content:"\f08a"} +[data-simply-list-icon="fa-sign-out"]:before{content:"\f08b"} +[data-simply-list-icon="fa-linkedin-square"]:before{content:"\f08c"} +[data-simply-list-icon="fa-thumb-tack"]:before{content:"\f08d"} +[data-simply-list-icon="fa-external-link"]:before{content:"\f08e"} +[data-simply-list-icon="fa-sign-in"]:before{content:"\f090"} +[data-simply-list-icon="fa-trophy"]:before{content:"\f091"} +[data-simply-list-icon="fa-github-square"]:before{content:"\f092"} +[data-simply-list-icon="fa-upload"]:before{content:"\f093"} +[data-simply-list-icon="fa-lemon-o"]:before{content:"\f094"} +[data-simply-list-icon="fa-phone"]:before{content:"\f095"} +[data-simply-list-icon="fa-square-o"]:before{content:"\f096"} +[data-simply-list-icon="fa-bookmark-o"]:before{content:"\f097"} +[data-simply-list-icon="fa-phone-square"]:before{content:"\f098"} +[data-simply-list-icon="fa-twitter"]:before{content:"\f099"} +[data-simply-list-icon="fa-facebook-f"]:before, +[data-simply-list-icon="fa-facebook"]:before{content:"\f09a"} +[data-simply-list-icon="fa-github"]:before{content:"\f09b"} +[data-simply-list-icon="fa-unlock"]:before{content:"\f09c"} +[data-simply-list-icon="fa-credit-card"]:before{content:"\f09d"} +[data-simply-list-icon="fa-feed"]:before, +[data-simply-list-icon="fa-rss"]:before{content:"\f09e"} +[data-simply-list-icon="fa-hdd-o"]:before{content:"\f0a0"} +[data-simply-list-icon="fa-bullhorn"]:before{content:"\f0a1"} +[data-simply-list-icon="fa-bell"]:before{content:"\f0f3"} +[data-simply-list-icon="fa-certificate"]:before{content:"\f0a3"} +[data-simply-list-icon="fa-hand-o-right"]:before{content:"\f0a4"} +[data-simply-list-icon="fa-hand-o-left"]:before{content:"\f0a5"} +[data-simply-list-icon="fa-hand-o-up"]:before{content:"\f0a6"} +[data-simply-list-icon="fa-hand-o-down"]:before{content:"\f0a7"} +[data-simply-list-icon="fa-arrow-circle-left"]:before{content:"\f0a8"} +[data-simply-list-icon="fa-arrow-circle-right"]:before{content:"\f0a9"} +[data-simply-list-icon="fa-arrow-circle-up"]:before{content:"\f0aa"} +[data-simply-list-icon="fa-arrow-circle-down"]:before{content:"\f0ab"} +[data-simply-list-icon="fa-globe"]:before{content:"\f0ac"} +[data-simply-list-icon="fa-wrench"]:before{content:"\f0ad"} +[data-simply-list-icon="fa-tasks"]:before{content:"\f0ae"} +[data-simply-list-icon="fa-filter"]:before{content:"\f0b0"} +[data-simply-list-icon="fa-briefcase"]:before{content:"\f0b1"} +[data-simply-list-icon="fa-arrows-alt"]:before{content:"\f0b2"} +[data-simply-list-icon="fa-group"]:before, +[data-simply-list-icon="fa-users"]:before{content:"\f0c0"} +[data-simply-list-icon="fa-chain"]:before, +[data-simply-list-icon="fa-link"]:before{content:"\f0c1"} +[data-simply-list-icon="fa-cloud"]:before{content:"\f0c2"} +[data-simply-list-icon="fa-flask"]:before{content:"\f0c3"} +[data-simply-list-icon="fa-cut"]:before, +[data-simply-list-icon="fa-scissors"]:before{content:"\f0c4"} +[data-simply-list-icon="fa-copy"]:before, +[data-simply-list-icon="fa-files-o"]:before{content:"\f0c5"} +[data-simply-list-icon="fa-paperclip"]:before{content:"\f0c6"} +[data-simply-list-icon="fa-save"]:before, +[data-simply-list-icon="fa-floppy-o"]:before{content:"\f0c7"} +[data-simply-list-icon="fa-square"]:before{content:"\f0c8"} +[data-simply-list-icon="fa-navicon"]:before, +[data-simply-list-icon="fa-reorder"]:before, +[data-simply-list-icon="fa-bars"]:before{content:"\f0c9"} +[data-simply-list-icon="fa-list-ul"]:before{content:"\f0ca"} +[data-simply-list-icon="fa-list-ol"]:before{content:"\f0cb"} +[data-simply-list-icon="fa-strikethrough"]:before{content:"\f0cc"} +[data-simply-list-icon="fa-underline"]:before{content:"\f0cd"} +[data-simply-list-icon="fa-table"]:before{content:"\f0ce"} +[data-simply-list-icon="fa-magic"]:before{content:"\f0d0"} +[data-simply-list-icon="fa-truck"]:before{content:"\f0d1"} +[data-simply-list-icon="fa-pinterest"]:before{content:"\f0d2"} +[data-simply-list-icon="fa-pinterest-square"]:before{content:"\f0d3"} +[data-simply-list-icon="fa-google-plus-square"]:before{content:"\f0d4"} +[data-simply-list-icon="fa-google-plus"]:before{content:"\f0d5"} +[data-simply-list-icon="fa-money"]:before{content:"\f0d6"} +[data-simply-list-icon="fa-caret-down"]:before{content:"\f0d7"} +[data-simply-list-icon="fa-caret-up"]:before{content:"\f0d8"} +[data-simply-list-icon="fa-caret-left"]:before{content:"\f0d9"} +[data-simply-list-icon="fa-caret-right"]:before{content:"\f0da"} +[data-simply-list-icon="fa-columns"]:before{content:"\f0db"} +[data-simply-list-icon="fa-unsorted"]:before, +[data-simply-list-icon="fa-sort"]:before{content:"\f0dc"} +[data-simply-list-icon="fa-sort-down"]:before, +[data-simply-list-icon="fa-sort-desc"]:before{content:"\f0dd"} +[data-simply-list-icon="fa-sort-up"]:before, +[data-simply-list-icon="fa-sort-asc"]:before{content:"\f0de"} +[data-simply-list-icon="fa-envelope"]:before{content:"\f0e0"} +[data-simply-list-icon="fa-linkedin"]:before{content:"\f0e1"} +[data-simply-list-icon="fa-rotate-left"]:before, +[data-simply-list-icon="fa-undo"]:before{content:"\f0e2"} +[data-simply-list-icon="fa-legal"]:before, +[data-simply-list-icon="fa-gavel"]:before{content:"\f0e3"} +[data-simply-list-icon="fa-dashboard"]:before, +[data-simply-list-icon="fa-tachometer"]:before{content:"\f0e4"} +[data-simply-list-icon="fa-comment-o"]:before{content:"\f0e5"} +[data-simply-list-icon="fa-comments-o"]:before{content:"\f0e6"} +[data-simply-list-icon="fa-flash"]:before, +[data-simply-list-icon="fa-bolt"]:before{content:"\f0e7"} +[data-simply-list-icon="fa-sitemap"]:before{content:"\f0e8"} +[data-simply-list-icon="fa-umbrella"]:before{content:"\f0e9"} +[data-simply-list-icon="fa-paste"]:before, +[data-simply-list-icon="fa-clipboard"]:before{content:"\f0ea"} +[data-simply-list-icon="fa-lightbulb-o"]:before{content:"\f0eb"} +[data-simply-list-icon="fa-exchange"]:before{content:"\f0ec"} +[data-simply-list-icon="fa-cloud-download"]:before{content:"\f0ed"} +[data-simply-list-icon="fa-cloud-upload"]:before{content:"\f0ee"} +[data-simply-list-icon="fa-user-md"]:before{content:"\f0f0"} +[data-simply-list-icon="fa-stethoscope"]:before{content:"\f0f1"} +[data-simply-list-icon="fa-suitcase"]:before{content:"\f0f2"} +[data-simply-list-icon="fa-bell-o"]:before{content:"\f0a2"} +[data-simply-list-icon="fa-coffee"]:before{content:"\f0f4"} +[data-simply-list-icon="fa-cutlery"]:before{content:"\f0f5"} +[data-simply-list-icon="fa-file-text-o"]:before{content:"\f0f6"} +[data-simply-list-icon="fa-building-o"]:before{content:"\f0f7"} +[data-simply-list-icon="fa-hospital-o"]:before{content:"\f0f8"} +[data-simply-list-icon="fa-ambulance"]:before{content:"\f0f9"} +[data-simply-list-icon="fa-medkit"]:before{content:"\f0fa"} +[data-simply-list-icon="fa-fighter-jet"]:before{content:"\f0fb"} +[data-simply-list-icon="fa-beer"]:before{content:"\f0fc"} +[data-simply-list-icon="fa-h-square"]:before{content:"\f0fd"} +[data-simply-list-icon="fa-plus-square"]:before{content:"\f0fe"} +[data-simply-list-icon="fa-angle-double-left"]:before{content:"\f100"} +[data-simply-list-icon="fa-angle-double-right"]:before{content:"\f101"} +[data-simply-list-icon="fa-angle-double-up"]:before{content:"\f102"} +[data-simply-list-icon="fa-angle-double-down"]:before{content:"\f103"} +[data-simply-list-icon="fa-angle-left"]:before{content:"\f104"} +[data-simply-list-icon="fa-angle-right"]:before{content:"\f105"} +[data-simply-list-icon="fa-angle-up"]:before{content:"\f106"} +[data-simply-list-icon="fa-angle-down"]:before{content:"\f107"} +[data-simply-list-icon="fa-desktop"]:before{content:"\f108"} +[data-simply-list-icon="fa-laptop"]:before{content:"\f109"} +[data-simply-list-icon="fa-tablet"]:before{content:"\f10a"} +[data-simply-list-icon="fa-mobile-phone"]:before, +[data-simply-list-icon="fa-mobile"]:before{content:"\f10b"} +[data-simply-list-icon="fa-circle-o"]:before{content:"\f10c"} +[data-simply-list-icon="fa-quote-left"]:before{content:"\f10d"} +[data-simply-list-icon="fa-quote-right"]:before{content:"\f10e"} +[data-simply-list-icon="fa-spinner"]:before{content:"\f110"} +[data-simply-list-icon="fa-circle"]:before{content:"\f111"} +[data-simply-list-icon="fa-mail-reply"]:before, +[data-simply-list-icon="fa-reply"]:before{content:"\f112"} +[data-simply-list-icon="fa-github-alt"]:before{content:"\f113"} +[data-simply-list-icon="fa-folder-o"]:before{content:"\f114"} +[data-simply-list-icon="fa-folder-open-o"]:before{content:"\f115"} +[data-simply-list-icon="fa-smile-o"]:before{content:"\f118"} +[data-simply-list-icon="fa-frown-o"]:before{content:"\f119"} +[data-simply-list-icon="fa-meh-o"]:before{content:"\f11a"} +[data-simply-list-icon="fa-gamepad"]:before{content:"\f11b"} +[data-simply-list-icon="fa-keyboard-o"]:before{content:"\f11c"} +[data-simply-list-icon="fa-flag-o"]:before{content:"\f11d"} +[data-simply-list-icon="fa-flag-checkered"]:before{content:"\f11e"} +[data-simply-list-icon="fa-terminal"]:before{content:"\f120"} +[data-simply-list-icon="fa-code"]:before{content:"\f121"} +[data-simply-list-icon="fa-mail-reply-all"]:before, +[data-simply-list-icon="fa-reply-all"]:before{content:"\f122"} +[data-simply-list-icon="fa-star-half-empty"]:before, +[data-simply-list-icon="fa-star-half-full"]:before, +[data-simply-list-icon="fa-star-half-o"]:before{content:"\f123"} +[data-simply-list-icon="fa-location-arrow"]:before{content:"\f124"} +[data-simply-list-icon="fa-crop"]:before{content:"\f125"} +[data-simply-list-icon="fa-code-fork"]:before{content:"\f126"} +[data-simply-list-icon="fa-unlink"]:before, +[data-simply-list-icon="fa-chain-broken"]:before{content:"\f127"} +[data-simply-list-icon="fa-question"]:before{content:"\f128"} +[data-simply-list-icon="fa-info"]:before{content:"\f129"} +[data-simply-list-icon="fa-exclamation"]:before{content:"\f12a"} +[data-simply-list-icon="fa-superscript"]:before{content:"\f12b"} +[data-simply-list-icon="fa-subscript"]:before{content:"\f12c"} +[data-simply-list-icon="fa-eraser"]:before{content:"\f12d"} +[data-simply-list-icon="fa-puzzle-piece"]:before{content:"\f12e"} +[data-simply-list-icon="fa-microphone"]:before{content:"\f130"} +[data-simply-list-icon="fa-microphone-slash"]:before{content:"\f131"} +[data-simply-list-icon="fa-shield"]:before{content:"\f132"} +[data-simply-list-icon="fa-calendar-o"]:before{content:"\f133"} +[data-simply-list-icon="fa-fire-extinguisher"]:before{content:"\f134"} +[data-simply-list-icon="fa-rocket"]:before{content:"\f135"} +[data-simply-list-icon="fa-maxcdn"]:before{content:"\f136"} +[data-simply-list-icon="fa-chevron-circle-left"]:before{content:"\f137"} +[data-simply-list-icon="fa-chevron-circle-right"]:before{content:"\f138"} +[data-simply-list-icon="fa-chevron-circle-up"]:before{content:"\f139"} +[data-simply-list-icon="fa-chevron-circle-down"]:before{content:"\f13a"} +[data-simply-list-icon="fa-html5"]:before{content:"\f13b"} +[data-simply-list-icon="fa-css3"]:before{content:"\f13c"} +[data-simply-list-icon="fa-anchor"]:before{content:"\f13d"} +[data-simply-list-icon="fa-unlock-alt"]:before{content:"\f13e"} +[data-simply-list-icon="fa-bullseye"]:before{content:"\f140"} +[data-simply-list-icon="fa-ellipsis-h"]:before{content:"\f141"} +[data-simply-list-icon="fa-ellipsis-v"]:before{content:"\f142"} +[data-simply-list-icon="fa-rss-square"]:before{content:"\f143"} +[data-simply-list-icon="fa-play-circle"]:before{content:"\f144"} +[data-simply-list-icon="fa-ticket"]:before{content:"\f145"} +[data-simply-list-icon="fa-minus-square"]:before{content:"\f146"} +[data-simply-list-icon="fa-minus-square-o"]:before{content:"\f147"} +[data-simply-list-icon="fa-level-up"]:before{content:"\f148"} +[data-simply-list-icon="fa-level-down"]:before{content:"\f149"} +[data-simply-list-icon="fa-check-square"]:before{content:"\f14a"} +[data-simply-list-icon="fa-pencil-square"]:before{content:"\f14b"} +[data-simply-list-icon="fa-external-link-square"]:before{content:"\f14c"} +[data-simply-list-icon="fa-share-square"]:before{content:"\f14d"} +[data-simply-list-icon="fa-compass"]:before{content:"\f14e"} +[data-simply-list-icon="fa-toggle-down"]:before, +[data-simply-list-icon="fa-caret-square-o-down"]:before{content:"\f150"} +[data-simply-list-icon="fa-toggle-up"]:before, +[data-simply-list-icon="fa-caret-square-o-up"]:before{content:"\f151"} +[data-simply-list-icon="fa-toggle-right"]:before, +[data-simply-list-icon="fa-caret-square-o-right"]:before{content:"\f152"} +[data-simply-list-icon="fa-euro"]:before, +[data-simply-list-icon="fa-eur"]:before{content:"\f153"} +[data-simply-list-icon="fa-gbp"]:before{content:"\f154"} +[data-simply-list-icon="fa-dollar"]:before, +[data-simply-list-icon="fa-usd"]:before{content:"\f155"} +[data-simply-list-icon="fa-rupee"]:before, +[data-simply-list-icon="fa-inr"]:before{content:"\f156"} +[data-simply-list-icon="fa-cny"]:before, +[data-simply-list-icon="fa-rmb"]:before, +[data-simply-list-icon="fa-yen"]:before, +[data-simply-list-icon="fa-jpy"]:before{content:"\f157"} +[data-simply-list-icon="fa-ruble"]:before, +[data-simply-list-icon="fa-rouble"]:before, +[data-simply-list-icon="fa-rub"]:before{content:"\f158"} +[data-simply-list-icon="fa-won"]:before, +[data-simply-list-icon="fa-krw"]:before{content:"\f159"} +[data-simply-list-icon="fa-bitcoin"]:before, +[data-simply-list-icon="fa-btc"]:before{content:"\f15a"} +[data-simply-list-icon="fa-file"]:before{content:"\f15b"} +[data-simply-list-icon="fa-file-text"]:before{content:"\f15c"} +[data-simply-list-icon="fa-sort-alpha-asc"]:before{content:"\f15d"} +[data-simply-list-icon="fa-sort-alpha-desc"]:before{content:"\f15e"} +[data-simply-list-icon="fa-sort-amount-asc"]:before{content:"\f160"} +[data-simply-list-icon="fa-sort-amount-desc"]:before{content:"\f161"} +[data-simply-list-icon="fa-sort-numeric-asc"]:before{content:"\f162"} +[data-simply-list-icon="fa-sort-numeric-desc"]:before{content:"\f163"} +[data-simply-list-icon="fa-thumbs-up"]:before{content:"\f164"} +[data-simply-list-icon="fa-thumbs-down"]:before{content:"\f165"} +[data-simply-list-icon="fa-youtube-square"]:before{content:"\f166"} +[data-simply-list-icon="fa-youtube"]:before{content:"\f167"} +[data-simply-list-icon="fa-xing"]:before{content:"\f168"} +[data-simply-list-icon="fa-xing-square"]:before{content:"\f169"} +[data-simply-list-icon="fa-youtube-play"]:before{content:"\f16a"} +[data-simply-list-icon="fa-dropbox"]:before{content:"\f16b"} +[data-simply-list-icon="fa-stack-overflow"]:before{content:"\f16c"} +[data-simply-list-icon="fa-instagram"]:before{content:"\f16d"} +[data-simply-list-icon="fa-flickr"]:before{content:"\f16e"} +[data-simply-list-icon="fa-adn"]:before{content:"\f170"} +[data-simply-list-icon="fa-bitbucket"]:before{content:"\f171"} +[data-simply-list-icon="fa-bitbucket-square"]:before{content:"\f172"} +[data-simply-list-icon="fa-tumblr"]:before{content:"\f173"} +[data-simply-list-icon="fa-tumblr-square"]:before{content:"\f174"} +[data-simply-list-icon="fa-long-arrow-down"]:before{content:"\f175"} +[data-simply-list-icon="fa-long-arrow-up"]:before{content:"\f176"} +[data-simply-list-icon="fa-long-arrow-left"]:before{content:"\f177"} +[data-simply-list-icon="fa-long-arrow-right"]:before{content:"\f178"} +[data-simply-list-icon="fa-apple"]:before{content:"\f179"} +[data-simply-list-icon="fa-windows"]:before{content:"\f17a"} +[data-simply-list-icon="fa-android"]:before{content:"\f17b"} +[data-simply-list-icon="fa-linux"]:before{content:"\f17c"} +[data-simply-list-icon="fa-dribbble"]:before{content:"\f17d"} +[data-simply-list-icon="fa-skype"]:before{content:"\f17e"} +[data-simply-list-icon="fa-foursquare"]:before{content:"\f180"} +[data-simply-list-icon="fa-trello"]:before{content:"\f181"} +[data-simply-list-icon="fa-female"]:before{content:"\f182"} +[data-simply-list-icon="fa-male"]:before{content:"\f183"} +[data-simply-list-icon="fa-gittip"]:before, +[data-simply-list-icon="fa-gratipay"]:before{content:"\f184"} +[data-simply-list-icon="fa-sun-o"]:before{content:"\f185"} +[data-simply-list-icon="fa-moon-o"]:before{content:"\f186"} +[data-simply-list-icon="fa-archive"]:before{content:"\f187"} +[data-simply-list-icon="fa-bug"]:before{content:"\f188"} +[data-simply-list-icon="fa-vk"]:before{content:"\f189"} +[data-simply-list-icon="fa-weibo"]:before{content:"\f18a"} +[data-simply-list-icon="fa-renren"]:before{content:"\f18b"} +[data-simply-list-icon="fa-pagelines"]:before{content:"\f18c"} +[data-simply-list-icon="fa-stack-exchange"]:before{content:"\f18d"} +[data-simply-list-icon="fa-arrow-circle-o-right"]:before{content:"\f18e"} +[data-simply-list-icon="fa-arrow-circle-o-left"]:before{content:"\f190"} +[data-simply-list-icon="fa-toggle-left"]:before, +[data-simply-list-icon="fa-caret-square-o-left"]:before{content:"\f191"} +[data-simply-list-icon="fa-dot-circle-o"]:before{content:"\f192"} +[data-simply-list-icon="fa-wheelchair"]:before{content:"\f193"} +[data-simply-list-icon="fa-vimeo-square"]:before{content:"\f194"} +[data-simply-list-icon="fa-turkish-lira"]:before, +[data-simply-list-icon="fa-try"]:before{content:"\f195"} +[data-simply-list-icon="fa-plus-square-o"]:before{content:"\f196"} +[data-simply-list-icon="fa-space-shuttle"]:before{content:"\f197"} +[data-simply-list-icon="fa-slack"]:before{content:"\f198"} +[data-simply-list-icon="fa-envelope-square"]:before{content:"\f199"} +[data-simply-list-icon="fa-wordpress"]:before{content:"\f19a"} +[data-simply-list-icon="fa-openid"]:before{content:"\f19b"} +[data-simply-list-icon="fa-institution"]:before, +[data-simply-list-icon="fa-bank"]:before, +[data-simply-list-icon="fa-university"]:before{content:"\f19c"} +[data-simply-list-icon="fa-mortar-board"]:before, +[data-simply-list-icon="fa-graduation-cap"]:before{content:"\f19d"} +[data-simply-list-icon="fa-yahoo"]:before{content:"\f19e"} +[data-simply-list-icon="fa-google"]:before{content:"\f1a0"} +[data-simply-list-icon="fa-reddit"]:before{content:"\f1a1"} +[data-simply-list-icon="fa-reddit-square"]:before{content:"\f1a2"} +[data-simply-list-icon="fa-stumbleupon-circle"]:before{content:"\f1a3"} +[data-simply-list-icon="fa-stumbleupon"]:before{content:"\f1a4"} +[data-simply-list-icon="fa-delicious"]:before{content:"\f1a5"} +[data-simply-list-icon="fa-digg"]:before{content:"\f1a6"} +[data-simply-list-icon="fa-pied-piper"]:before{content:"\f1a7"} +[data-simply-list-icon="fa-pied-piper-alt"]:before{content:"\f1a8"} +[data-simply-list-icon="fa-drupal"]:before{content:"\f1a9"} +[data-simply-list-icon="fa-joomla"]:before{content:"\f1aa"} +[data-simply-list-icon="fa-language"]:before{content:"\f1ab"} +[data-simply-list-icon="fa-fax"]:before{content:"\f1ac"} +[data-simply-list-icon="fa-building"]:before{content:"\f1ad"} +[data-simply-list-icon="fa-child"]:before{content:"\f1ae"} +[data-simply-list-icon="fa-paw"]:before{content:"\f1b0"} +[data-simply-list-icon="fa-spoon"]:before{content:"\f1b1"} +[data-simply-list-icon="fa-cube"]:before{content:"\f1b2"} +[data-simply-list-icon="fa-cubes"]:before{content:"\f1b3"} +[data-simply-list-icon="fa-behance"]:before{content:"\f1b4"} +[data-simply-list-icon="fa-behance-square"]:before{content:"\f1b5"} +[data-simply-list-icon="fa-steam"]:before{content:"\f1b6"} +[data-simply-list-icon="fa-steam-square"]:before{content:"\f1b7"} +[data-simply-list-icon="fa-recycle"]:before{content:"\f1b8"} +[data-simply-list-icon="fa-automobile"]:before, +[data-simply-list-icon="fa-car"]:before{content:"\f1b9"} +[data-simply-list-icon="fa-cab"]:before, +[data-simply-list-icon="fa-taxi"]:before{content:"\f1ba"} +[data-simply-list-icon="fa-tree"]:before{content:"\f1bb"} +[data-simply-list-icon="fa-spotify"]:before{content:"\f1bc"} +[data-simply-list-icon="fa-deviantart"]:before{content:"\f1bd"} +[data-simply-list-icon="fa-soundcloud"]:before{content:"\f1be"} +[data-simply-list-icon="fa-database"]:before{content:"\f1c0"} +[data-simply-list-icon="fa-file-pdf-o"]:before{content:"\f1c1"} +[data-simply-list-icon="fa-file-word-o"]:before{content:"\f1c2"} +[data-simply-list-icon="fa-file-excel-o"]:before{content:"\f1c3"} +[data-simply-list-icon="fa-file-powerpoint-o"]:before{content:"\f1c4"} +[data-simply-list-icon="fa-file-photo-o"]:before, +[data-simply-list-icon="fa-file-picture-o"]:before, +[data-simply-list-icon="fa-file-image-o"]:before{content:"\f1c5"} +[data-simply-list-icon="fa-file-zip-o"]:before, +[data-simply-list-icon="fa-file-archive-o"]:before{content:"\f1c6"} +[data-simply-list-icon="fa-file-sound-o"]:before, +[data-simply-list-icon="fa-file-audio-o"]:before{content:"\f1c7"} +[data-simply-list-icon="fa-file-movie-o"]:before, +[data-simply-list-icon="fa-file-video-o"]:before{content:"\f1c8"} +[data-simply-list-icon="fa-file-code-o"]:before{content:"\f1c9"} +[data-simply-list-icon="fa-vine"]:before{content:"\f1ca"} +[data-simply-list-icon="fa-codepen"]:before{content:"\f1cb"} +[data-simply-list-icon="fa-jsfiddle"]:before{content:"\f1cc"} +[data-simply-list-icon="fa-life-bouy"]:before, +[data-simply-list-icon="fa-life-buoy"]:before, +[data-simply-list-icon="fa-life-saver"]:before, +[data-simply-list-icon="fa-support"]:before, +[data-simply-list-icon="fa-life-ring"]:before{content:"\f1cd"} +[data-simply-list-icon="fa-circle-o-notch"]:before{content:"\f1ce"} +[data-simply-list-icon="fa-ra"]:before, +[data-simply-list-icon="fa-rebel"]:before{content:"\f1d0"} +[data-simply-list-icon="fa-ge"]:before, +[data-simply-list-icon="fa-empire"]:before{content:"\f1d1"} +[data-simply-list-icon="fa-git-square"]:before{content:"\f1d2"} +[data-simply-list-icon="fa-git"]:before{content:"\f1d3"} +[data-simply-list-icon="fa-y-combinator-square"]:before, +[data-simply-list-icon="fa-yc-square"]:before, +[data-simply-list-icon="fa-hacker-news"]:before{content:"\f1d4"} +[data-simply-list-icon="fa-tencent-weibo"]:before{content:"\f1d5"} +[data-simply-list-icon="fa-qq"]:before{content:"\f1d6"} +[data-simply-list-icon="fa-wechat"]:before, +[data-simply-list-icon="fa-weixin"]:before{content:"\f1d7"} +[data-simply-list-icon="fa-send"]:before, +[data-simply-list-icon="fa-paper-plane"]:before{content:"\f1d8"} +[data-simply-list-icon="fa-send-o"]:before, +[data-simply-list-icon="fa-paper-plane-o"]:before{content:"\f1d9"} +[data-simply-list-icon="fa-history"]:before{content:"\f1da"} +[data-simply-list-icon="fa-circle-thin"]:before{content:"\f1db"} +[data-simply-list-icon="fa-header"]:before{content:"\f1dc"} +[data-simply-list-icon="fa-paragraph"]:before{content:"\f1dd"} +[data-simply-list-icon="fa-sliders"]:before{content:"\f1de"} +[data-simply-list-icon="fa-share-alt"]:before{content:"\f1e0"} +[data-simply-list-icon="fa-share-alt-square"]:before{content:"\f1e1"} +[data-simply-list-icon="fa-bomb"]:before{content:"\f1e2"} +[data-simply-list-icon="fa-soccer-ball-o"]:before, +[data-simply-list-icon="fa-futbol-o"]:before{content:"\f1e3"} +[data-simply-list-icon="fa-tty"]:before{content:"\f1e4"} +[data-simply-list-icon="fa-binoculars"]:before{content:"\f1e5"} +[data-simply-list-icon="fa-plug"]:before{content:"\f1e6"} +[data-simply-list-icon="fa-slideshare"]:before{content:"\f1e7"} +[data-simply-list-icon="fa-twitch"]:before{content:"\f1e8"} +[data-simply-list-icon="fa-yelp"]:before{content:"\f1e9"} +[data-simply-list-icon="fa-newspaper-o"]:before{content:"\f1ea"} +[data-simply-list-icon="fa-wifi"]:before{content:"\f1eb"} +[data-simply-list-icon="fa-calculator"]:before{content:"\f1ec"} +[data-simply-list-icon="fa-paypal"]:before{content:"\f1ed"} +[data-simply-list-icon="fa-google-wallet"]:before{content:"\f1ee"} +[data-simply-list-icon="fa-cc-visa"]:before{content:"\f1f0"} +[data-simply-list-icon="fa-cc-mastercard"]:before{content:"\f1f1"} +[data-simply-list-icon="fa-cc-discover"]:before{content:"\f1f2"} +[data-simply-list-icon="fa-cc-amex"]:before{content:"\f1f3"} +[data-simply-list-icon="fa-cc-paypal"]:before{content:"\f1f4"} +[data-simply-list-icon="fa-cc-stripe"]:before{content:"\f1f5"} +[data-simply-list-icon="fa-bell-slash"]:before{content:"\f1f6"} +[data-simply-list-icon="fa-bell-slash-o"]:before{content:"\f1f7"} +[data-simply-list-icon="fa-trash"]:before{content:"\f1f8"} +[data-simply-list-icon="fa-copyright"]:before{content:"\f1f9"} +[data-simply-list-icon="fa-at"]:before{content:"\f1fa"} +[data-simply-list-icon="fa-eyedropper"]:before{content:"\f1fb"} +[data-simply-list-icon="fa-paint-brush"]:before{content:"\f1fc"} +[data-simply-list-icon="fa-birthday-cake"]:before{content:"\f1fd"} +[data-simply-list-icon="fa-area-chart"]:before{content:"\f1fe"} +[data-simply-list-icon="fa-pie-chart"]:before{content:"\f200"} +[data-simply-list-icon="fa-line-chart"]:before{content:"\f201"} +[data-simply-list-icon="fa-lastfm"]:before{content:"\f202"} +[data-simply-list-icon="fa-lastfm-square"]:before{content:"\f203"} +[data-simply-list-icon="fa-toggle-off"]:before{content:"\f204"} +[data-simply-list-icon="fa-toggle-on"]:before{content:"\f205"} +[data-simply-list-icon="fa-bicycle"]:before{content:"\f206"} +[data-simply-list-icon="fa-bus"]:before{content:"\f207"} +[data-simply-list-icon="fa-ioxhost"]:before{content:"\f208"} +[data-simply-list-icon="fa-angellist"]:before{content:"\f209"} +[data-simply-list-icon="fa-cc"]:before{content:"\f20a"} +[data-simply-list-icon="fa-shekel"]:before, +[data-simply-list-icon="fa-sheqel"]:before, +[data-simply-list-icon="fa-ils"]:before{content:"\f20b"} +[data-simply-list-icon="fa-meanpath"]:before{content:"\f20c"} +[data-simply-list-icon="fa-buysellads"]:before{content:"\f20d"} +[data-simply-list-icon="fa-connectdevelop"]:before{content:"\f20e"} +[data-simply-list-icon="fa-dashcube"]:before{content:"\f210"} +[data-simply-list-icon="fa-forumbee"]:before{content:"\f211"} +[data-simply-list-icon="fa-leanpub"]:before{content:"\f212"} +[data-simply-list-icon="fa-sellsy"]:before{content:"\f213"} +[data-simply-list-icon="fa-shirtsinbulk"]:before{content:"\f214"} +[data-simply-list-icon="fa-simplybuilt"]:before{content:"\f215"} +[data-simply-list-icon="fa-skyatlas"]:before{content:"\f216"} +[data-simply-list-icon="fa-cart-plus"]:before{content:"\f217"} +[data-simply-list-icon="fa-cart-arrow-down"]:before{content:"\f218"} +[data-simply-list-icon="fa-diamond"]:before{content:"\f219"} +[data-simply-list-icon="fa-ship"]:before{content:"\f21a"} +[data-simply-list-icon="fa-user-secret"]:before{content:"\f21b"} +[data-simply-list-icon="fa-motorcycle"]:before{content:"\f21c"} +[data-simply-list-icon="fa-street-view"]:before{content:"\f21d"} +[data-simply-list-icon="fa-heartbeat"]:before{content:"\f21e"} +[data-simply-list-icon="fa-venus"]:before{content:"\f221"} +[data-simply-list-icon="fa-mars"]:before{content:"\f222"} +[data-simply-list-icon="fa-mercury"]:before{content:"\f223"} +[data-simply-list-icon="fa-intersex"]:before, +[data-simply-list-icon="fa-transgender"]:before{content:"\f224"} +[data-simply-list-icon="fa-transgender-alt"]:before{content:"\f225"} +[data-simply-list-icon="fa-venus-double"]:before{content:"\f226"} +[data-simply-list-icon="fa-mars-double"]:before{content:"\f227"} +[data-simply-list-icon="fa-venus-mars"]:before{content:"\f228"} +[data-simply-list-icon="fa-mars-stroke"]:before{content:"\f229"} +[data-simply-list-icon="fa-mars-stroke-v"]:before{content:"\f22a"} +[data-simply-list-icon="fa-mars-stroke-h"]:before{content:"\f22b"} +[data-simply-list-icon="fa-neuter"]:before{content:"\f22c"} +[data-simply-list-icon="fa-genderless"]:before{content:"\f22d"} +[data-simply-list-icon="fa-facebook-official"]:before{content:"\f230"} +[data-simply-list-icon="fa-pinterest-p"]:before{content:"\f231"} +[data-simply-list-icon="fa-whatsapp"]:before{content:"\f232"} +[data-simply-list-icon="fa-server"]:before{content:"\f233"} +[data-simply-list-icon="fa-user-plus"]:before{content:"\f234"} +[data-simply-list-icon="fa-user-times"]:before{content:"\f235"} +[data-simply-list-icon="fa-hotel"]:before, +[data-simply-list-icon="fa-bed"]:before{content:"\f236"} +[data-simply-list-icon="fa-viacoin"]:before{content:"\f237"} +[data-simply-list-icon="fa-train"]:before{content:"\f238"} +[data-simply-list-icon="fa-subway"]:before{content:"\f239"} +[data-simply-list-icon="fa-medium"]:before{content:"\f23a"} +[data-simply-list-icon="fa-yc"]:before, +[data-simply-list-icon="fa-y-combinator"]:before{content:"\f23b"} +[data-simply-list-icon="fa-optin-monster"]:before{content:"\f23c"} +[data-simply-list-icon="fa-opencart"]:before{content:"\f23d"} +[data-simply-list-icon="fa-expeditedssl"]:before{content:"\f23e"} +[data-simply-list-icon="fa-battery-4"]:before, +[data-simply-list-icon="fa-battery-full"]:before{content:"\f240"} +[data-simply-list-icon="fa-battery-3"]:before, +[data-simply-list-icon="fa-battery-three-quarters"]:before{content:"\f241"} +[data-simply-list-icon="fa-battery-2"]:before, +[data-simply-list-icon="fa-battery-half"]:before{content:"\f242"} +[data-simply-list-icon="fa-battery-1"]:before, +[data-simply-list-icon="fa-battery-quarter"]:before{content:"\f243"} +[data-simply-list-icon="fa-battery-0"]:before, +[data-simply-list-icon="fa-battery-empty"]:before{content:"\f244"} +[data-simply-list-icon="fa-mouse-pointer"]:before{content:"\f245"} +[data-simply-list-icon="fa-i-cursor"]:before{content:"\f246"} +[data-simply-list-icon="fa-object-group"]:before{content:"\f247"} +[data-simply-list-icon="fa-object-ungroup"]:before{content:"\f248"} +[data-simply-list-icon="fa-sticky-note"]:before{content:"\f249"} +[data-simply-list-icon="fa-sticky-note-o"]:before{content:"\f24a"} +[data-simply-list-icon="fa-cc-jcb"]:before{content:"\f24b"} +[data-simply-list-icon="fa-cc-diners-club"]:before{content:"\f24c"} +[data-simply-list-icon="fa-clone"]:before{content:"\f24d"} +[data-simply-list-icon="fa-balance-scale"]:before{content:"\f24e"} +[data-simply-list-icon="fa-hourglass-o"]:before{content:"\f250"} +[data-simply-list-icon="fa-hourglass-1"]:before, +[data-simply-list-icon="fa-hourglass-start"]:before{content:"\f251"} +[data-simply-list-icon="fa-hourglass-2"]:before, +[data-simply-list-icon="fa-hourglass-half"]:before{content:"\f252"} +[data-simply-list-icon="fa-hourglass-3"]:before, +[data-simply-list-icon="fa-hourglass-end"]:before{content:"\f253"} +[data-simply-list-icon="fa-hourglass"]:before{content:"\f254"} +[data-simply-list-icon="fa-hand-grab-o"]:before, +[data-simply-list-icon="fa-hand-rock-o"]:before{content:"\f255"} +[data-simply-list-icon="fa-hand-stop-o"]:before, +[data-simply-list-icon="fa-hand-paper-o"]:before{content:"\f256"} +[data-simply-list-icon="fa-hand-scissors-o"]:before{content:"\f257"} +[data-simply-list-icon="fa-hand-lizard-o"]:before{content:"\f258"} +[data-simply-list-icon="fa-hand-spock-o"]:before{content:"\f259"} +[data-simply-list-icon="fa-hand-pointer-o"]:before{content:"\f25a"} +[data-simply-list-icon="fa-hand-peace-o"]:before{content:"\f25b"} +[data-simply-list-icon="fa-trademark"]:before{content:"\f25c"} +[data-simply-list-icon="fa-registered"]:before{content:"\f25d"} +[data-simply-list-icon="fa-creative-commons"]:before{content:"\f25e"} +[data-simply-list-icon="fa-gg"]:before{content:"\f260"} +[data-simply-list-icon="fa-gg-circle"]:before{content:"\f261"} +[data-simply-list-icon="fa-tripadvisor"]:before{content:"\f262"} +[data-simply-list-icon="fa-odnoklassniki"]:before{content:"\f263"} +[data-simply-list-icon="fa-odnoklassniki-square"]:before{content:"\f264"} +[data-simply-list-icon="fa-get-pocket"]:before{content:"\f265"} +[data-simply-list-icon="fa-wikipedia-w"]:before{content:"\f266"} +[data-simply-list-icon="fa-safari"]:before{content:"\f267"} +[data-simply-list-icon="fa-chrome"]:before{content:"\f268"} +[data-simply-list-icon="fa-firefox"]:before{content:"\f269"} +[data-simply-list-icon="fa-opera"]:before{content:"\f26a"} +[data-simply-list-icon="fa-internet-explorer"]:before{content:"\f26b"} +[data-simply-list-icon="fa-tv"]:before, +[data-simply-list-icon="fa-television"]:before{content:"\f26c"} +[data-simply-list-icon="fa-contao"]:before{content:"\f26d"} +[data-simply-list-icon="fa-500px"]:before{content:"\f26e"} +[data-simply-list-icon="fa-amazon"]:before{content:"\f270"} +[data-simply-list-icon="fa-calendar-plus-o"]:before{content:"\f271"} +[data-simply-list-icon="fa-calendar-minus-o"]:before{content:"\f272"} +[data-simply-list-icon="fa-calendar-times-o"]:before{content:"\f273"} +[data-simply-list-icon="fa-calendar-check-o"]:before{content:"\f274"} +[data-simply-list-icon="fa-industry"]:before{content:"\f275"} +[data-simply-list-icon="fa-map-pin"]:before{content:"\f276"} +[data-simply-list-icon="fa-map-signs"]:before{content:"\f277"} +[data-simply-list-icon="fa-map-o"]:before{content:"\f278"} +[data-simply-list-icon="fa-map"]:before{content:"\f279"} +[data-simply-list-icon="fa-commenting"]:before{content:"\f27a"} +[data-simply-list-icon="fa-commenting-o"]:before{content:"\f27b"} +[data-simply-list-icon="fa-houzz"]:before{content:"\f27c"} +[data-simply-list-icon="fa-vimeo"]:before{content:"\f27d"} +[data-simply-list-icon="fa-black-tie"]:before{content:"\f27e"} +[data-simply-list-icon="fa-fonticons"]:before{content:"\f280"} + +tr[data-simply-list-icon]:before{content:''} +tr[data-simply-list-icon="fa-glass"] td:first-child:before{content:"\f000"} +tr[data-simply-list-icon="fa-music"] td:first-child:before{content:"\f001"} +tr[data-simply-list-icon="fa-search"] td:first-child:before{content:"\f002"} +tr[data-simply-list-icon="fa-envelope-o"] td:first-child:before{content:"\f003"} +tr[data-simply-list-icon="fa-heart"] td:first-child:before{content:"\f004"} +tr[data-simply-list-icon="fa-star"] td:first-child:before{content:"\f005"} +tr[data-simply-list-icon="fa-star-o"] td:first-child:before{content:"\f006"} +tr[data-simply-list-icon="fa-user"] td:first-child:before{content:"\f007"} +tr[data-simply-list-icon="fa-film"] td:first-child:before{content:"\f008"} +tr[data-simply-list-icon="fa-th-large"] td:first-child:before{content:"\f009"} +tr[data-simply-list-icon="fa-th"] td:first-child:before{content:"\f00a"} +tr[data-simply-list-icon="fa-th-list"] td:first-child:before{content:"\f00b"} +tr[data-simply-list-icon="fa-check"] td:first-child:before{content:"\f00c"} +tr[data-simply-list-icon="fa-remove"] td:first-child:before, +tr[data-simply-list-icon="fa-close"] td:first-child:before, +tr[data-simply-list-icon="fa-times"] td:first-child:before{content:"\f00d"} +tr[data-simply-list-icon="fa-search-plus"] td:first-child:before{content:"\f00e"} +tr[data-simply-list-icon="fa-search-minus"] td:first-child:before{content:"\f010"} +tr[data-simply-list-icon="fa-power-off"] td:first-child:before{content:"\f011"} +tr[data-simply-list-icon="fa-signal"] td:first-child:before{content:"\f012"} +tr[data-simply-list-icon="fa-gear"] td:first-child:before, +tr[data-simply-list-icon="fa-cog"] td:first-child:before{content:"\f013"} +tr[data-simply-list-icon="fa-trash-o"] td:first-child:before{content:"\f014"} +tr[data-simply-list-icon="fa-home"] td:first-child:before{content:"\f015"} +tr[data-simply-list-icon="fa-file-o"] td:first-child:before{content:"\f016"} +tr[data-simply-list-icon="fa-clock-o"] td:first-child:before{content:"\f017"} +tr[data-simply-list-icon="fa-road"] td:first-child:before{content:"\f018"} +tr[data-simply-list-icon="fa-download"] td:first-child:before{content:"\f019"} +tr[data-simply-list-icon="fa-arrow-circle-o-down"] td:first-child:before{content:"\f01a"} +tr[data-simply-list-icon="fa-arrow-circle-o-up"] td:first-child:before{content:"\f01b"} +tr[data-simply-list-icon="fa-inbox"] td:first-child:before{content:"\f01c"} +tr[data-simply-list-icon="fa-play-circle-o"] td:first-child:before{content:"\f01d"} +tr[data-simply-list-icon="fa-rotate-right"] td:first-child:before, +tr[data-simply-list-icon="fa-repeat"] td:first-child:before{content:"\f01e"} +tr[data-simply-list-icon="fa-refresh"] td:first-child:before{content:"\f021"} +tr[data-simply-list-icon="fa-list-alt"] td:first-child:before{content:"\f022"} +tr[data-simply-list-icon="fa-lock"] td:first-child:before{content:"\f023"} +tr[data-simply-list-icon="fa-flag"] td:first-child:before{content:"\f024"} +tr[data-simply-list-icon="fa-headphones"] td:first-child:before{content:"\f025"} +tr[data-simply-list-icon="fa-volume-off"] td:first-child:before{content:"\f026"} +tr[data-simply-list-icon="fa-volume-down"] td:first-child:before{content:"\f027"} +tr[data-simply-list-icon="fa-volume-up"] td:first-child:before{content:"\f028"} +tr[data-simply-list-icon="fa-qrcode"] td:first-child:before{content:"\f029"} +tr[data-simply-list-icon="fa-barcode"] td:first-child:before{content:"\f02a"} +tr[data-simply-list-icon="fa-tag"] td:first-child:before{content:"\f02b"} +tr[data-simply-list-icon="fa-tags"] td:first-child:before{content:"\f02c"} +tr[data-simply-list-icon="fa-book"] td:first-child:before{content:"\f02d"} +tr[data-simply-list-icon="fa-bookmark"] td:first-child:before{content:"\f02e"} +tr[data-simply-list-icon="fa-print"] td:first-child:before{content:"\f02f"} +tr[data-simply-list-icon="fa-camera"] td:first-child:before{content:"\f030"} +tr[data-simply-list-icon="fa-font"] td:first-child:before{content:"\f031"} +tr[data-simply-list-icon="fa-bold"] td:first-child:before{content:"\f032"} +tr[data-simply-list-icon="fa-italic"] td:first-child:before{content:"\f033"} +tr[data-simply-list-icon="fa-text-height"] td:first-child:before{content:"\f034"} +tr[data-simply-list-icon="fa-text-width"] td:first-child:before{content:"\f035"} +tr[data-simply-list-icon="fa-align-left"] td:first-child:before{content:"\f036"} +tr[data-simply-list-icon="fa-align-center"] td:first-child:before{content:"\f037"} +tr[data-simply-list-icon="fa-align-right"] td:first-child:before{content:"\f038"} +tr[data-simply-list-icon="fa-align-justify"] td:first-child:before{content:"\f039"} +tr[data-simply-list-icon="fa-list"] td:first-child:before{content:"\f03a"} +tr[data-simply-list-icon="fa-dedent"] td:first-child:before, +tr[data-simply-list-icon="fa-outdent"] td:first-child:before{content:"\f03b"} +tr[data-simply-list-icon="fa-indent"] td:first-child:before{content:"\f03c"} +tr[data-simply-list-icon="fa-video-camera"] td:first-child:before{content:"\f03d"} +tr[data-simply-list-icon="fa-photo"] td:first-child:before, +tr[data-simply-list-icon="fa-image"] td:first-child:before, +tr[data-simply-list-icon="fa-picture-o"] td:first-child:before{content:"\f03e"} +tr[data-simply-list-icon="fa-pencil"] td:first-child:before{content:"\f040"} +tr[data-simply-list-icon="fa-map-marker"] td:first-child:before{content:"\f041"} +tr[data-simply-list-icon="fa-adjust"] td:first-child:before{content:"\f042"} +tr[data-simply-list-icon="fa-tint"] td:first-child:before{content:"\f043"} +tr[data-simply-list-icon="fa-edit"] td:first-child:before, +tr[data-simply-list-icon="fa-pencil-square-o"] td:first-child:before{content:"\f044"} +tr[data-simply-list-icon="fa-share-square-o"] td:first-child:before{content:"\f045"} +tr[data-simply-list-icon="fa-check-square-o"] td:first-child:before{content:"\f046"} +tr[data-simply-list-icon="fa-arrows"] td:first-child:before{content:"\f047"} +tr[data-simply-list-icon="fa-step-backward"] td:first-child:before{content:"\f048"} +tr[data-simply-list-icon="fa-fast-backward"] td:first-child:before{content:"\f049"} +tr[data-simply-list-icon="fa-backward"] td:first-child:before{content:"\f04a"} +tr[data-simply-list-icon="fa-play"] td:first-child:before{content:"\f04b"} +tr[data-simply-list-icon="fa-pause"] td:first-child:before{content:"\f04c"} +tr[data-simply-list-icon="fa-stop"] td:first-child:before{content:"\f04d"} +tr[data-simply-list-icon="fa-forward"] td:first-child:before{content:"\f04e"} +tr[data-simply-list-icon="fa-fast-forward"] td:first-child:before{content:"\f050"} +tr[data-simply-list-icon="fa-step-forward"] td:first-child:before{content:"\f051"} +tr[data-simply-list-icon="fa-eject"] td:first-child:before{content:"\f052"} +tr[data-simply-list-icon="fa-chevron-left"] td:first-child:before{content:"\f053"} +tr[data-simply-list-icon="fa-chevron-right"] td:first-child:before{content:"\f054"} +tr[data-simply-list-icon="fa-plus-circle"] td:first-child:before{content:"\f055"} +tr[data-simply-list-icon="fa-minus-circle"] td:first-child:before{content:"\f056"} +tr[data-simply-list-icon="fa-times-circle"] td:first-child:before{content:"\f057"} +tr[data-simply-list-icon="fa-check-circle"] td:first-child:before{content:"\f058"} +tr[data-simply-list-icon="fa-question-circle"] td:first-child:before{content:"\f059"} +tr[data-simply-list-icon="fa-info-circle"] td:first-child:before{content:"\f05a"} +tr[data-simply-list-icon="fa-crosshairs"] td:first-child:before{content:"\f05b"} +tr[data-simply-list-icon="fa-times-circle-o"] td:first-child:before{content:"\f05c"} +tr[data-simply-list-icon="fa-check-circle-o"] td:first-child:before{content:"\f05d"} +tr[data-simply-list-icon="fa-ban"] td:first-child:before{content:"\f05e"} +tr[data-simply-list-icon="fa-arrow-left"] td:first-child:before{content:"\f060"} +tr[data-simply-list-icon="fa-arrow-right"] td:first-child:before{content:"\f061"} +tr[data-simply-list-icon="fa-arrow-up"] td:first-child:before{content:"\f062"} +tr[data-simply-list-icon="fa-arrow-down"] td:first-child:before{content:"\f063"} +tr[data-simply-list-icon="fa-mail-forward"] td:first-child:before, +tr[data-simply-list-icon="fa-share"] td:first-child:before{content:"\f064"} +tr[data-simply-list-icon="fa-expand"] td:first-child:before{content:"\f065"} +tr[data-simply-list-icon="fa-compress"] td:first-child:before{content:"\f066"} +tr[data-simply-list-icon="fa-plus"] td:first-child:before{content:"\f067"} +tr[data-simply-list-icon="fa-minus"] td:first-child:before{content:"\f068"} +tr[data-simply-list-icon="fa-asterisk"] td:first-child:before{content:"\f069"} +tr[data-simply-list-icon="fa-exclamation-circle"] td:first-child:before{content:"\f06a"} +tr[data-simply-list-icon="fa-gift"] td:first-child:before{content:"\f06b"} +tr[data-simply-list-icon="fa-leaf"] td:first-child:before{content:"\f06c"} +tr[data-simply-list-icon="fa-fire"] td:first-child:before{content:"\f06d"} +tr[data-simply-list-icon="fa-eye"] td:first-child:before{content:"\f06e"} +tr[data-simply-list-icon="fa-eye-slash"] td:first-child:before{content:"\f070"} +tr[data-simply-list-icon="fa-warning"] td:first-child:before, +tr[data-simply-list-icon="fa-exclamation-triangle"] td:first-child:before{content:"\f071"} +tr[data-simply-list-icon="fa-plane"] td:first-child:before{content:"\f072"} +tr[data-simply-list-icon="fa-calendar"] td:first-child:before{content:"\f073"} +tr[data-simply-list-icon="fa-random"] td:first-child:before{content:"\f074"} +tr[data-simply-list-icon="fa-comment"] td:first-child:before{content:"\f075"} +tr[data-simply-list-icon="fa-magnet"] td:first-child:before{content:"\f076"} +tr[data-simply-list-icon="fa-chevron-up"] td:first-child:before{content:"\f077"} +tr[data-simply-list-icon="fa-chevron-down"] td:first-child:before{content:"\f078"} +tr[data-simply-list-icon="fa-retweet"] td:first-child:before{content:"\f079"} +tr[data-simply-list-icon="fa-shopping-cart"] td:first-child:before{content:"\f07a"} +tr[data-simply-list-icon="fa-folder"] td:first-child:before{content:"\f07b"} +tr[data-simply-list-icon="fa-folder-open"] td:first-child:before{content:"\f07c"} +tr[data-simply-list-icon="fa-arrows-v"] td:first-child:before{content:"\f07d"} +tr[data-simply-list-icon="fa-arrows-h"] td:first-child:before{content:"\f07e"} +tr[data-simply-list-icon="fa-bar-chart-o"] td:first-child:before, +tr[data-simply-list-icon="fa-bar-chart"] td:first-child:before{content:"\f080"} +tr[data-simply-list-icon="fa-twitter-square"] td:first-child:before{content:"\f081"} +tr[data-simply-list-icon="fa-facebook-square"] td:first-child:before{content:"\f082"} +tr[data-simply-list-icon="fa-camera-retro"] td:first-child:before{content:"\f083"} +tr[data-simply-list-icon="fa-key"] td:first-child:before{content:"\f084"} +tr[data-simply-list-icon="fa-gears"] td:first-child:before, +tr[data-simply-list-icon="fa-cogs"] td:first-child:before{content:"\f085"} +tr[data-simply-list-icon="fa-comments"] td:first-child:before{content:"\f086"} +tr[data-simply-list-icon="fa-thumbs-o-up"] td:first-child:before{content:"\f087"} +tr[data-simply-list-icon="fa-thumbs-o-down"] td:first-child:before{content:"\f088"} +tr[data-simply-list-icon="fa-star-half"] td:first-child:before{content:"\f089"} +tr[data-simply-list-icon="fa-heart-o"] td:first-child:before{content:"\f08a"} +tr[data-simply-list-icon="fa-sign-out"] td:first-child:before{content:"\f08b"} +tr[data-simply-list-icon="fa-linkedin-square"] td:first-child:before{content:"\f08c"} +tr[data-simply-list-icon="fa-thumb-tack"] td:first-child:before{content:"\f08d"} +tr[data-simply-list-icon="fa-external-link"] td:first-child:before{content:"\f08e"} +tr[data-simply-list-icon="fa-sign-in"] td:first-child:before{content:"\f090"} +tr[data-simply-list-icon="fa-trophy"] td:first-child:before{content:"\f091"} +tr[data-simply-list-icon="fa-github-square"] td:first-child:before{content:"\f092"} +tr[data-simply-list-icon="fa-upload"] td:first-child:before{content:"\f093"} +tr[data-simply-list-icon="fa-lemon-o"] td:first-child:before{content:"\f094"} +tr[data-simply-list-icon="fa-phone"] td:first-child:before{content:"\f095"} +tr[data-simply-list-icon="fa-square-o"] td:first-child:before{content:"\f096"} +tr[data-simply-list-icon="fa-bookmark-o"] td:first-child:before{content:"\f097"} +tr[data-simply-list-icon="fa-phone-square"] td:first-child:before{content:"\f098"} +tr[data-simply-list-icon="fa-twitter"] td:first-child:before{content:"\f099"} +tr[data-simply-list-icon="fa-facebook-f"] td:first-child:before, +tr[data-simply-list-icon="fa-facebook"] td:first-child:before{content:"\f09a"} +tr[data-simply-list-icon="fa-github"] td:first-child:before{content:"\f09b"} +tr[data-simply-list-icon="fa-unlock"] td:first-child:before{content:"\f09c"} +tr[data-simply-list-icon="fa-credit-card"] td:first-child:before{content:"\f09d"} +tr[data-simply-list-icon="fa-feed"] td:first-child:before, +tr[data-simply-list-icon="fa-rss"] td:first-child:before{content:"\f09e"} +tr[data-simply-list-icon="fa-hdd-o"] td:first-child:before{content:"\f0a0"} +tr[data-simply-list-icon="fa-bullhorn"] td:first-child:before{content:"\f0a1"} +tr[data-simply-list-icon="fa-bell"] td:first-child:before{content:"\f0f3"} +tr[data-simply-list-icon="fa-certificate"] td:first-child:before{content:"\f0a3"} +tr[data-simply-list-icon="fa-hand-o-right"] td:first-child:before{content:"\f0a4"} +tr[data-simply-list-icon="fa-hand-o-left"] td:first-child:before{content:"\f0a5"} +tr[data-simply-list-icon="fa-hand-o-up"] td:first-child:before{content:"\f0a6"} +tr[data-simply-list-icon="fa-hand-o-down"] td:first-child:before{content:"\f0a7"} +tr[data-simply-list-icon="fa-arrow-circle-left"] td:first-child:before{content:"\f0a8"} +tr[data-simply-list-icon="fa-arrow-circle-right"] td:first-child:before{content:"\f0a9"} +tr[data-simply-list-icon="fa-arrow-circle-up"] td:first-child:before{content:"\f0aa"} +tr[data-simply-list-icon="fa-arrow-circle-down"] td:first-child:before{content:"\f0ab"} +tr[data-simply-list-icon="fa-globe"] td:first-child:before{content:"\f0ac"} +tr[data-simply-list-icon="fa-wrench"] td:first-child:before{content:"\f0ad"} +tr[data-simply-list-icon="fa-tasks"] td:first-child:before{content:"\f0ae"} +tr[data-simply-list-icon="fa-filter"] td:first-child:before{content:"\f0b0"} +tr[data-simply-list-icon="fa-briefcase"] td:first-child:before{content:"\f0b1"} +tr[data-simply-list-icon="fa-arrows-alt"] td:first-child:before{content:"\f0b2"} +tr[data-simply-list-icon="fa-group"] td:first-child:before, +tr[data-simply-list-icon="fa-users"] td:first-child:before{content:"\f0c0"} +tr[data-simply-list-icon="fa-chain"] td:first-child:before, +tr[data-simply-list-icon="fa-link"] td:first-child:before{content:"\f0c1"} +tr[data-simply-list-icon="fa-cloud"] td:first-child:before{content:"\f0c2"} +tr[data-simply-list-icon="fa-flask"] td:first-child:before{content:"\f0c3"} +tr[data-simply-list-icon="fa-cut"] td:first-child:before, +tr[data-simply-list-icon="fa-scissors"] td:first-child:before{content:"\f0c4"} +tr[data-simply-list-icon="fa-copy"] td:first-child:before, +tr[data-simply-list-icon="fa-files-o"] td:first-child:before{content:"\f0c5"} +tr[data-simply-list-icon="fa-paperclip"] td:first-child:before{content:"\f0c6"} +tr[data-simply-list-icon="fa-save"] td:first-child:before, +tr[data-simply-list-icon="fa-floppy-o"] td:first-child:before{content:"\f0c7"} +tr[data-simply-list-icon="fa-square"] td:first-child:before{content:"\f0c8"} +tr[data-simply-list-icon="fa-navicon"] td:first-child:before, +tr[data-simply-list-icon="fa-reorder"] td:first-child:before, +tr[data-simply-list-icon="fa-bars"] td:first-child:before{content:"\f0c9"} +tr[data-simply-list-icon="fa-list-ul"] td:first-child:before{content:"\f0ca"} +tr[data-simply-list-icon="fa-list-ol"] td:first-child:before{content:"\f0cb"} +tr[data-simply-list-icon="fa-strikethrough"] td:first-child:before{content:"\f0cc"} +tr[data-simply-list-icon="fa-underline"] td:first-child:before{content:"\f0cd"} +tr[data-simply-list-icon="fa-table"] td:first-child:before{content:"\f0ce"} +tr[data-simply-list-icon="fa-magic"] td:first-child:before{content:"\f0d0"} +tr[data-simply-list-icon="fa-truck"] td:first-child:before{content:"\f0d1"} +tr[data-simply-list-icon="fa-pinterest"] td:first-child:before{content:"\f0d2"} +tr[data-simply-list-icon="fa-pinterest-square"] td:first-child:before{content:"\f0d3"} +tr[data-simply-list-icon="fa-google-plus-square"] td:first-child:before{content:"\f0d4"} +tr[data-simply-list-icon="fa-google-plus"] td:first-child:before{content:"\f0d5"} +tr[data-simply-list-icon="fa-money"] td:first-child:before{content:"\f0d6"} +tr[data-simply-list-icon="fa-caret-down"] td:first-child:before{content:"\f0d7"} +tr[data-simply-list-icon="fa-caret-up"] td:first-child:before{content:"\f0d8"} +tr[data-simply-list-icon="fa-caret-left"] td:first-child:before{content:"\f0d9"} +tr[data-simply-list-icon="fa-caret-right"] td:first-child:before{content:"\f0da"} +tr[data-simply-list-icon="fa-columns"] td:first-child:before{content:"\f0db"} +tr[data-simply-list-icon="fa-unsorted"] td:first-child:before, +tr[data-simply-list-icon="fa-sort"] td:first-child:before{content:"\f0dc"} +tr[data-simply-list-icon="fa-sort-down"] td:first-child:before, +tr[data-simply-list-icon="fa-sort-desc"] td:first-child:before{content:"\f0dd"} +tr[data-simply-list-icon="fa-sort-up"] td:first-child:before, +tr[data-simply-list-icon="fa-sort-asc"] td:first-child:before{content:"\f0de"} +tr[data-simply-list-icon="fa-envelope"] td:first-child:before{content:"\f0e0"} +tr[data-simply-list-icon="fa-linkedin"] td:first-child:before{content:"\f0e1"} +tr[data-simply-list-icon="fa-rotate-left"] td:first-child:before, +tr[data-simply-list-icon="fa-undo"] td:first-child:before{content:"\f0e2"} +tr[data-simply-list-icon="fa-legal"] td:first-child:before, +tr[data-simply-list-icon="fa-gavel"] td:first-child:before{content:"\f0e3"} +tr[data-simply-list-icon="fa-dashboard"] td:first-child:before, +tr[data-simply-list-icon="fa-tachometer"] td:first-child:before{content:"\f0e4"} +tr[data-simply-list-icon="fa-comment-o"] td:first-child:before{content:"\f0e5"} +tr[data-simply-list-icon="fa-comments-o"] td:first-child:before{content:"\f0e6"} +tr[data-simply-list-icon="fa-flash"] td:first-child:before, +tr[data-simply-list-icon="fa-bolt"] td:first-child:before{content:"\f0e7"} +tr[data-simply-list-icon="fa-sitemap"] td:first-child:before{content:"\f0e8"} +tr[data-simply-list-icon="fa-umbrella"] td:first-child:before{content:"\f0e9"} +tr[data-simply-list-icon="fa-paste"] td:first-child:before, +tr[data-simply-list-icon="fa-clipboard"] td:first-child:before{content:"\f0ea"} +tr[data-simply-list-icon="fa-lightbulb-o"] td:first-child:before{content:"\f0eb"} +tr[data-simply-list-icon="fa-exchange"] td:first-child:before{content:"\f0ec"} +tr[data-simply-list-icon="fa-cloud-download"] td:first-child:before{content:"\f0ed"} +tr[data-simply-list-icon="fa-cloud-upload"] td:first-child:before{content:"\f0ee"} +tr[data-simply-list-icon="fa-user-md"] td:first-child:before{content:"\f0f0"} +tr[data-simply-list-icon="fa-stethoscope"] td:first-child:before{content:"\f0f1"} +tr[data-simply-list-icon="fa-suitcase"] td:first-child:before{content:"\f0f2"} +tr[data-simply-list-icon="fa-bell-o"] td:first-child:before{content:"\f0a2"} +tr[data-simply-list-icon="fa-coffee"] td:first-child:before{content:"\f0f4"} +tr[data-simply-list-icon="fa-cutlery"] td:first-child:before{content:"\f0f5"} +tr[data-simply-list-icon="fa-file-text-o"] td:first-child:before{content:"\f0f6"} +tr[data-simply-list-icon="fa-building-o"] td:first-child:before{content:"\f0f7"} +tr[data-simply-list-icon="fa-hospital-o"] td:first-child:before{content:"\f0f8"} +tr[data-simply-list-icon="fa-ambulance"] td:first-child:before{content:"\f0f9"} +tr[data-simply-list-icon="fa-medkit"] td:first-child:before{content:"\f0fa"} +tr[data-simply-list-icon="fa-fighter-jet"] td:first-child:before{content:"\f0fb"} +tr[data-simply-list-icon="fa-beer"] td:first-child:before{content:"\f0fc"} +tr[data-simply-list-icon="fa-h-square"] td:first-child:before{content:"\f0fd"} +tr[data-simply-list-icon="fa-plus-square"] td:first-child:before{content:"\f0fe"} +tr[data-simply-list-icon="fa-angle-double-left"] td:first-child:before{content:"\f100"} +tr[data-simply-list-icon="fa-angle-double-right"] td:first-child:before{content:"\f101"} +tr[data-simply-list-icon="fa-angle-double-up"] td:first-child:before{content:"\f102"} +tr[data-simply-list-icon="fa-angle-double-down"] td:first-child:before{content:"\f103"} +tr[data-simply-list-icon="fa-angle-left"] td:first-child:before{content:"\f104"} +tr[data-simply-list-icon="fa-angle-right"] td:first-child:before{content:"\f105"} +tr[data-simply-list-icon="fa-angle-up"] td:first-child:before{content:"\f106"} +tr[data-simply-list-icon="fa-angle-down"] td:first-child:before{content:"\f107"} +tr[data-simply-list-icon="fa-desktop"] td:first-child:before{content:"\f108"} +tr[data-simply-list-icon="fa-laptop"] td:first-child:before{content:"\f109"} +tr[data-simply-list-icon="fa-tablet"] td:first-child:before{content:"\f10a"} +tr[data-simply-list-icon="fa-mobile-phone"] td:first-child:before, +tr[data-simply-list-icon="fa-mobile"] td:first-child:before{content:"\f10b"} +tr[data-simply-list-icon="fa-circle-o"] td:first-child:before{content:"\f10c"} +tr[data-simply-list-icon="fa-quote-left"] td:first-child:before{content:"\f10d"} +tr[data-simply-list-icon="fa-quote-right"] td:first-child:before{content:"\f10e"} +tr[data-simply-list-icon="fa-spinner"] td:first-child:before{content:"\f110"} +tr[data-simply-list-icon="fa-circle"] td:first-child:before{content:"\f111"} +tr[data-simply-list-icon="fa-mail-reply"] td:first-child:before, +tr[data-simply-list-icon="fa-reply"] td:first-child:before{content:"\f112"} +tr[data-simply-list-icon="fa-github-alt"] td:first-child:before{content:"\f113"} +tr[data-simply-list-icon="fa-folder-o"] td:first-child:before{content:"\f114"} +tr[data-simply-list-icon="fa-folder-open-o"] td:first-child:before{content:"\f115"} +tr[data-simply-list-icon="fa-smile-o"] td:first-child:before{content:"\f118"} +tr[data-simply-list-icon="fa-frown-o"] td:first-child:before{content:"\f119"} +tr[data-simply-list-icon="fa-meh-o"] td:first-child:before{content:"\f11a"} +tr[data-simply-list-icon="fa-gamepad"] td:first-child:before{content:"\f11b"} +tr[data-simply-list-icon="fa-keyboard-o"] td:first-child:before{content:"\f11c"} +tr[data-simply-list-icon="fa-flag-o"] td:first-child:before{content:"\f11d"} +tr[data-simply-list-icon="fa-flag-checkered"] td:first-child:before{content:"\f11e"} +tr[data-simply-list-icon="fa-terminal"] td:first-child:before{content:"\f120"} +tr[data-simply-list-icon="fa-code"] td:first-child:before{content:"\f121"} +tr[data-simply-list-icon="fa-mail-reply-all"] td:first-child:before, +tr[data-simply-list-icon="fa-reply-all"] td:first-child:before{content:"\f122"} +tr[data-simply-list-icon="fa-star-half-empty"] td:first-child:before, +tr[data-simply-list-icon="fa-star-half-full"] td:first-child:before, +tr[data-simply-list-icon="fa-star-half-o"] td:first-child:before{content:"\f123"} +tr[data-simply-list-icon="fa-location-arrow"] td:first-child:before{content:"\f124"} +tr[data-simply-list-icon="fa-crop"] td:first-child:before{content:"\f125"} +tr[data-simply-list-icon="fa-code-fork"] td:first-child:before{content:"\f126"} +tr[data-simply-list-icon="fa-unlink"] td:first-child:before, +tr[data-simply-list-icon="fa-chain-broken"] td:first-child:before{content:"\f127"} +tr[data-simply-list-icon="fa-question"] td:first-child:before{content:"\f128"} +tr[data-simply-list-icon="fa-info"] td:first-child:before{content:"\f129"} +tr[data-simply-list-icon="fa-exclamation"] td:first-child:before{content:"\f12a"} +tr[data-simply-list-icon="fa-superscript"] td:first-child:before{content:"\f12b"} +tr[data-simply-list-icon="fa-subscript"] td:first-child:before{content:"\f12c"} +tr[data-simply-list-icon="fa-eraser"] td:first-child:before{content:"\f12d"} +tr[data-simply-list-icon="fa-puzzle-piece"] td:first-child:before{content:"\f12e"} +tr[data-simply-list-icon="fa-microphone"] td:first-child:before{content:"\f130"} +tr[data-simply-list-icon="fa-microphone-slash"] td:first-child:before{content:"\f131"} +tr[data-simply-list-icon="fa-shield"] td:first-child:before{content:"\f132"} +tr[data-simply-list-icon="fa-calendar-o"] td:first-child:before{content:"\f133"} +tr[data-simply-list-icon="fa-fire-extinguisher"] td:first-child:before{content:"\f134"} +tr[data-simply-list-icon="fa-rocket"] td:first-child:before{content:"\f135"} +tr[data-simply-list-icon="fa-maxcdn"] td:first-child:before{content:"\f136"} +tr[data-simply-list-icon="fa-chevron-circle-left"] td:first-child:before{content:"\f137"} +tr[data-simply-list-icon="fa-chevron-circle-right"] td:first-child:before{content:"\f138"} +tr[data-simply-list-icon="fa-chevron-circle-up"] td:first-child:before{content:"\f139"} +tr[data-simply-list-icon="fa-chevron-circle-down"] td:first-child:before{content:"\f13a"} +tr[data-simply-list-icon="fa-html5"] td:first-child:before{content:"\f13b"} +tr[data-simply-list-icon="fa-css3"] td:first-child:before{content:"\f13c"} +tr[data-simply-list-icon="fa-anchor"] td:first-child:before{content:"\f13d"} +tr[data-simply-list-icon="fa-unlock-alt"] td:first-child:before{content:"\f13e"} +tr[data-simply-list-icon="fa-bullseye"] td:first-child:before{content:"\f140"} +tr[data-simply-list-icon="fa-ellipsis-h"] td:first-child:before{content:"\f141"} +tr[data-simply-list-icon="fa-ellipsis-v"] td:first-child:before{content:"\f142"} +tr[data-simply-list-icon="fa-rss-square"] td:first-child:before{content:"\f143"} +tr[data-simply-list-icon="fa-play-circle"] td:first-child:before{content:"\f144"} +tr[data-simply-list-icon="fa-ticket"] td:first-child:before{content:"\f145"} +tr[data-simply-list-icon="fa-minus-square"] td:first-child:before{content:"\f146"} +tr[data-simply-list-icon="fa-minus-square-o"] td:first-child:before{content:"\f147"} +tr[data-simply-list-icon="fa-level-up"] td:first-child:before{content:"\f148"} +tr[data-simply-list-icon="fa-level-down"] td:first-child:before{content:"\f149"} +tr[data-simply-list-icon="fa-check-square"] td:first-child:before{content:"\f14a"} +tr[data-simply-list-icon="fa-pencil-square"] td:first-child:before{content:"\f14b"} +tr[data-simply-list-icon="fa-external-link-square"] td:first-child:before{content:"\f14c"} +tr[data-simply-list-icon="fa-share-square"] td:first-child:before{content:"\f14d"} +tr[data-simply-list-icon="fa-compass"] td:first-child:before{content:"\f14e"} +tr[data-simply-list-icon="fa-toggle-down"] td:first-child:before, +tr[data-simply-list-icon="fa-caret-square-o-down"] td:first-child:before{content:"\f150"} +tr[data-simply-list-icon="fa-toggle-up"] td:first-child:before, +tr[data-simply-list-icon="fa-caret-square-o-up"] td:first-child:before{content:"\f151"} +tr[data-simply-list-icon="fa-toggle-right"] td:first-child:before, +tr[data-simply-list-icon="fa-caret-square-o-right"] td:first-child:before{content:"\f152"} +tr[data-simply-list-icon="fa-euro"] td:first-child:before, +tr[data-simply-list-icon="fa-eur"] td:first-child:before{content:"\f153"} +tr[data-simply-list-icon="fa-gbp"] td:first-child:before{content:"\f154"} +tr[data-simply-list-icon="fa-dollar"] td:first-child:before, +tr[data-simply-list-icon="fa-usd"] td:first-child:before{content:"\f155"} +tr[data-simply-list-icon="fa-rupee"] td:first-child:before, +tr[data-simply-list-icon="fa-inr"] td:first-child:before{content:"\f156"} +tr[data-simply-list-icon="fa-cny"] td:first-child:before, +tr[data-simply-list-icon="fa-rmb"] td:first-child:before, +tr[data-simply-list-icon="fa-yen"] td:first-child:before, +tr[data-simply-list-icon="fa-jpy"] td:first-child:before{content:"\f157"} +tr[data-simply-list-icon="fa-ruble"] td:first-child:before, +tr[data-simply-list-icon="fa-rouble"] td:first-child:before, +tr[data-simply-list-icon="fa-rub"] td:first-child:before{content:"\f158"} +tr[data-simply-list-icon="fa-won"] td:first-child:before, +tr[data-simply-list-icon="fa-krw"] td:first-child:before{content:"\f159"} +tr[data-simply-list-icon="fa-bitcoin"] td:first-child:before, +tr[data-simply-list-icon="fa-btc"] td:first-child:before{content:"\f15a"} +tr[data-simply-list-icon="fa-file"] td:first-child:before{content:"\f15b"} +tr[data-simply-list-icon="fa-file-text"] td:first-child:before{content:"\f15c"} +tr[data-simply-list-icon="fa-sort-alpha-asc"] td:first-child:before{content:"\f15d"} +tr[data-simply-list-icon="fa-sort-alpha-desc"] td:first-child:before{content:"\f15e"} +tr[data-simply-list-icon="fa-sort-amount-asc"] td:first-child:before{content:"\f160"} +tr[data-simply-list-icon="fa-sort-amount-desc"] td:first-child:before{content:"\f161"} +tr[data-simply-list-icon="fa-sort-numeric-asc"] td:first-child:before{content:"\f162"} +tr[data-simply-list-icon="fa-sort-numeric-desc"] td:first-child:before{content:"\f163"} +tr[data-simply-list-icon="fa-thumbs-up"] td:first-child:before{content:"\f164"} +tr[data-simply-list-icon="fa-thumbs-down"] td:first-child:before{content:"\f165"} +tr[data-simply-list-icon="fa-youtube-square"] td:first-child:before{content:"\f166"} +tr[data-simply-list-icon="fa-youtube"] td:first-child:before{content:"\f167"} +tr[data-simply-list-icon="fa-xing"] td:first-child:before{content:"\f168"} +tr[data-simply-list-icon="fa-xing-square"] td:first-child:before{content:"\f169"} +tr[data-simply-list-icon="fa-youtube-play"] td:first-child:before{content:"\f16a"} +tr[data-simply-list-icon="fa-dropbox"] td:first-child:before{content:"\f16b"} +tr[data-simply-list-icon="fa-stack-overflow"] td:first-child:before{content:"\f16c"} +tr[data-simply-list-icon="fa-instagram"] td:first-child:before{content:"\f16d"} +tr[data-simply-list-icon="fa-flickr"] td:first-child:before{content:"\f16e"} +tr[data-simply-list-icon="fa-adn"] td:first-child:before{content:"\f170"} +tr[data-simply-list-icon="fa-bitbucket"] td:first-child:before{content:"\f171"} +tr[data-simply-list-icon="fa-bitbucket-square"] td:first-child:before{content:"\f172"} +tr[data-simply-list-icon="fa-tumblr"] td:first-child:before{content:"\f173"} +tr[data-simply-list-icon="fa-tumblr-square"] td:first-child:before{content:"\f174"} +tr[data-simply-list-icon="fa-long-arrow-down"] td:first-child:before{content:"\f175"} +tr[data-simply-list-icon="fa-long-arrow-up"] td:first-child:before{content:"\f176"} +tr[data-simply-list-icon="fa-long-arrow-left"] td:first-child:before{content:"\f177"} +tr[data-simply-list-icon="fa-long-arrow-right"] td:first-child:before{content:"\f178"} +tr[data-simply-list-icon="fa-apple"] td:first-child:before{content:"\f179"} +tr[data-simply-list-icon="fa-windows"] td:first-child:before{content:"\f17a"} +tr[data-simply-list-icon="fa-android"] td:first-child:before{content:"\f17b"} +tr[data-simply-list-icon="fa-linux"] td:first-child:before{content:"\f17c"} +tr[data-simply-list-icon="fa-dribbble"] td:first-child:before{content:"\f17d"} +tr[data-simply-list-icon="fa-skype"] td:first-child:before{content:"\f17e"} +tr[data-simply-list-icon="fa-foursquare"] td:first-child:before{content:"\f180"} +tr[data-simply-list-icon="fa-trello"] td:first-child:before{content:"\f181"} +tr[data-simply-list-icon="fa-female"] td:first-child:before{content:"\f182"} +tr[data-simply-list-icon="fa-male"] td:first-child:before{content:"\f183"} +tr[data-simply-list-icon="fa-gittip"] td:first-child:before, +tr[data-simply-list-icon="fa-gratipay"] td:first-child:before{content:"\f184"} +tr[data-simply-list-icon="fa-sun-o"] td:first-child:before{content:"\f185"} +tr[data-simply-list-icon="fa-moon-o"] td:first-child:before{content:"\f186"} +tr[data-simply-list-icon="fa-archive"] td:first-child:before{content:"\f187"} +tr[data-simply-list-icon="fa-bug"] td:first-child:before{content:"\f188"} +tr[data-simply-list-icon="fa-vk"] td:first-child:before{content:"\f189"} +tr[data-simply-list-icon="fa-weibo"] td:first-child:before{content:"\f18a"} +tr[data-simply-list-icon="fa-renren"] td:first-child:before{content:"\f18b"} +tr[data-simply-list-icon="fa-pagelines"] td:first-child:before{content:"\f18c"} +tr[data-simply-list-icon="fa-stack-exchange"] td:first-child:before{content:"\f18d"} +tr[data-simply-list-icon="fa-arrow-circle-o-right"] td:first-child:before{content:"\f18e"} +tr[data-simply-list-icon="fa-arrow-circle-o-left"] td:first-child:before{content:"\f190"} +tr[data-simply-list-icon="fa-toggle-left"] td:first-child:before, +tr[data-simply-list-icon="fa-caret-square-o-left"] td:first-child:before{content:"\f191"} +tr[data-simply-list-icon="fa-dot-circle-o"] td:first-child:before{content:"\f192"} +tr[data-simply-list-icon="fa-wheelchair"] td:first-child:before{content:"\f193"} +tr[data-simply-list-icon="fa-vimeo-square"] td:first-child:before{content:"\f194"} +tr[data-simply-list-icon="fa-turkish-lira"] td:first-child:before, +tr[data-simply-list-icon="fa-try"] td:first-child:before{content:"\f195"} +tr[data-simply-list-icon="fa-plus-square-o"] td:first-child:before{content:"\f196"} +tr[data-simply-list-icon="fa-space-shuttle"] td:first-child:before{content:"\f197"} +tr[data-simply-list-icon="fa-slack"] td:first-child:before{content:"\f198"} +tr[data-simply-list-icon="fa-envelope-square"] td:first-child:before{content:"\f199"} +tr[data-simply-list-icon="fa-wordpress"] td:first-child:before{content:"\f19a"} +tr[data-simply-list-icon="fa-openid"] td:first-child:before{content:"\f19b"} +tr[data-simply-list-icon="fa-institution"] td:first-child:before, +tr[data-simply-list-icon="fa-bank"] td:first-child:before, +tr[data-simply-list-icon="fa-university"] td:first-child:before{content:"\f19c"} +tr[data-simply-list-icon="fa-mortar-board"] td:first-child:before, +tr[data-simply-list-icon="fa-graduation-cap"] td:first-child:before{content:"\f19d"} +tr[data-simply-list-icon="fa-yahoo"] td:first-child:before{content:"\f19e"} +tr[data-simply-list-icon="fa-google"] td:first-child:before{content:"\f1a0"} +tr[data-simply-list-icon="fa-reddit"] td:first-child:before{content:"\f1a1"} +tr[data-simply-list-icon="fa-reddit-square"] td:first-child:before{content:"\f1a2"} +tr[data-simply-list-icon="fa-stumbleupon-circle"] td:first-child:before{content:"\f1a3"} +tr[data-simply-list-icon="fa-stumbleupon"] td:first-child:before{content:"\f1a4"} +tr[data-simply-list-icon="fa-delicious"] td:first-child:before{content:"\f1a5"} +tr[data-simply-list-icon="fa-digg"] td:first-child:before{content:"\f1a6"} +tr[data-simply-list-icon="fa-pied-piper"] td:first-child:before{content:"\f1a7"} +tr[data-simply-list-icon="fa-pied-piper-alt"] td:first-child:before{content:"\f1a8"} +tr[data-simply-list-icon="fa-drupal"] td:first-child:before{content:"\f1a9"} +tr[data-simply-list-icon="fa-joomla"] td:first-child:before{content:"\f1aa"} +tr[data-simply-list-icon="fa-language"] td:first-child:before{content:"\f1ab"} +tr[data-simply-list-icon="fa-fax"] td:first-child:before{content:"\f1ac"} +tr[data-simply-list-icon="fa-building"] td:first-child:before{content:"\f1ad"} +tr[data-simply-list-icon="fa-child"] td:first-child:before{content:"\f1ae"} +tr[data-simply-list-icon="fa-paw"] td:first-child:before{content:"\f1b0"} +tr[data-simply-list-icon="fa-spoon"] td:first-child:before{content:"\f1b1"} +tr[data-simply-list-icon="fa-cube"] td:first-child:before{content:"\f1b2"} +tr[data-simply-list-icon="fa-cubes"] td:first-child:before{content:"\f1b3"} +tr[data-simply-list-icon="fa-behance"] td:first-child:before{content:"\f1b4"} +tr[data-simply-list-icon="fa-behance-square"] td:first-child:before{content:"\f1b5"} +tr[data-simply-list-icon="fa-steam"] td:first-child:before{content:"\f1b6"} +tr[data-simply-list-icon="fa-steam-square"] td:first-child:before{content:"\f1b7"} +tr[data-simply-list-icon="fa-recycle"] td:first-child:before{content:"\f1b8"} +tr[data-simply-list-icon="fa-automobile"] td:first-child:before, +tr[data-simply-list-icon="fa-car"] td:first-child:before{content:"\f1b9"} +tr[data-simply-list-icon="fa-cab"] td:first-child:before, +tr[data-simply-list-icon="fa-taxi"] td:first-child:before{content:"\f1ba"} +tr[data-simply-list-icon="fa-tree"] td:first-child:before{content:"\f1bb"} +tr[data-simply-list-icon="fa-spotify"] td:first-child:before{content:"\f1bc"} +tr[data-simply-list-icon="fa-deviantart"] td:first-child:before{content:"\f1bd"} +tr[data-simply-list-icon="fa-soundcloud"] td:first-child:before{content:"\f1be"} +tr[data-simply-list-icon="fa-database"] td:first-child:before{content:"\f1c0"} +tr[data-simply-list-icon="fa-file-pdf-o"] td:first-child:before{content:"\f1c1"} +tr[data-simply-list-icon="fa-file-word-o"] td:first-child:before{content:"\f1c2"} +tr[data-simply-list-icon="fa-file-excel-o"] td:first-child:before{content:"\f1c3"} +tr[data-simply-list-icon="fa-file-powerpoint-o"] td:first-child:before{content:"\f1c4"} +tr[data-simply-list-icon="fa-file-photo-o"] td:first-child:before, +tr[data-simply-list-icon="fa-file-picture-o"] td:first-child:before, +tr[data-simply-list-icon="fa-file-image-o"] td:first-child:before{content:"\f1c5"} +tr[data-simply-list-icon="fa-file-zip-o"] td:first-child:before, +tr[data-simply-list-icon="fa-file-archive-o"] td:first-child:before{content:"\f1c6"} +tr[data-simply-list-icon="fa-file-sound-o"] td:first-child:before, +tr[data-simply-list-icon="fa-file-audio-o"] td:first-child:before{content:"\f1c7"} +tr[data-simply-list-icon="fa-file-movie-o"] td:first-child:before, +tr[data-simply-list-icon="fa-file-video-o"] td:first-child:before{content:"\f1c8"} +tr[data-simply-list-icon="fa-file-code-o"] td:first-child:before{content:"\f1c9"} +tr[data-simply-list-icon="fa-vine"] td:first-child:before{content:"\f1ca"} +tr[data-simply-list-icon="fa-codepen"] td:first-child:before{content:"\f1cb"} +tr[data-simply-list-icon="fa-jsfiddle"] td:first-child:before{content:"\f1cc"} +tr[data-simply-list-icon="fa-life-bouy"] td:first-child:before, +tr[data-simply-list-icon="fa-life-buoy"] td:first-child:before, +tr[data-simply-list-icon="fa-life-saver"] td:first-child:before, +tr[data-simply-list-icon="fa-support"] td:first-child:before, +tr[data-simply-list-icon="fa-life-ring"] td:first-child:before{content:"\f1cd"} +tr[data-simply-list-icon="fa-circle-o-notch"] td:first-child:before{content:"\f1ce"} +tr[data-simply-list-icon="fa-ra"] td:first-child:before, +tr[data-simply-list-icon="fa-rebel"] td:first-child:before{content:"\f1d0"} +tr[data-simply-list-icon="fa-ge"] td:first-child:before, +tr[data-simply-list-icon="fa-empire"] td:first-child:before{content:"\f1d1"} +tr[data-simply-list-icon="fa-git-square"] td:first-child:before{content:"\f1d2"} +tr[data-simply-list-icon="fa-git"] td:first-child:before{content:"\f1d3"} +tr[data-simply-list-icon="fa-y-combinator-square"] td:first-child:before, +tr[data-simply-list-icon="fa-yc-square"] td:first-child:before, +tr[data-simply-list-icon="fa-hacker-news"] td:first-child:before{content:"\f1d4"} +tr[data-simply-list-icon="fa-tencent-weibo"] td:first-child:before{content:"\f1d5"} +tr[data-simply-list-icon="fa-qq"] td:first-child:before{content:"\f1d6"} +tr[data-simply-list-icon="fa-wechat"] td:first-child:before, +tr[data-simply-list-icon="fa-weixin"] td:first-child:before{content:"\f1d7"} +tr[data-simply-list-icon="fa-send"] td:first-child:before, +tr[data-simply-list-icon="fa-paper-plane"] td:first-child:before{content:"\f1d8"} +tr[data-simply-list-icon="fa-send-o"] td:first-child:before, +tr[data-simply-list-icon="fa-paper-plane-o"] td:first-child:before{content:"\f1d9"} +tr[data-simply-list-icon="fa-history"] td:first-child:before{content:"\f1da"} +tr[data-simply-list-icon="fa-circle-thin"] td:first-child:before{content:"\f1db"} +tr[data-simply-list-icon="fa-header"] td:first-child:before{content:"\f1dc"} +tr[data-simply-list-icon="fa-paragraph"] td:first-child:before{content:"\f1dd"} +tr[data-simply-list-icon="fa-sliders"] td:first-child:before{content:"\f1de"} +tr[data-simply-list-icon="fa-share-alt"] td:first-child:before{content:"\f1e0"} +tr[data-simply-list-icon="fa-share-alt-square"] td:first-child:before{content:"\f1e1"} +tr[data-simply-list-icon="fa-bomb"] td:first-child:before{content:"\f1e2"} +tr[data-simply-list-icon="fa-soccer-ball-o"] td:first-child:before, +tr[data-simply-list-icon="fa-futbol-o"] td:first-child:before{content:"\f1e3"} +tr[data-simply-list-icon="fa-tty"] td:first-child:before{content:"\f1e4"} +tr[data-simply-list-icon="fa-binoculars"] td:first-child:before{content:"\f1e5"} +tr[data-simply-list-icon="fa-plug"] td:first-child:before{content:"\f1e6"} +tr[data-simply-list-icon="fa-slideshare"] td:first-child:before{content:"\f1e7"} +tr[data-simply-list-icon="fa-twitch"] td:first-child:before{content:"\f1e8"} +tr[data-simply-list-icon="fa-yelp"] td:first-child:before{content:"\f1e9"} +tr[data-simply-list-icon="fa-newspaper-o"] td:first-child:before{content:"\f1ea"} +tr[data-simply-list-icon="fa-wifi"] td:first-child:before{content:"\f1eb"} +tr[data-simply-list-icon="fa-calculator"] td:first-child:before{content:"\f1ec"} +tr[data-simply-list-icon="fa-paypal"] td:first-child:before{content:"\f1ed"} +tr[data-simply-list-icon="fa-google-wallet"] td:first-child:before{content:"\f1ee"} +tr[data-simply-list-icon="fa-cc-visa"] td:first-child:before{content:"\f1f0"} +tr[data-simply-list-icon="fa-cc-mastercard"] td:first-child:before{content:"\f1f1"} +tr[data-simply-list-icon="fa-cc-discover"] td:first-child:before{content:"\f1f2"} +tr[data-simply-list-icon="fa-cc-amex"] td:first-child:before{content:"\f1f3"} +tr[data-simply-list-icon="fa-cc-paypal"] td:first-child:before{content:"\f1f4"} +tr[data-simply-list-icon="fa-cc-stripe"] td:first-child:before{content:"\f1f5"} +tr[data-simply-list-icon="fa-bell-slash"] td:first-child:before{content:"\f1f6"} +tr[data-simply-list-icon="fa-bell-slash-o"] td:first-child:before{content:"\f1f7"} +tr[data-simply-list-icon="fa-trash"] td:first-child:before{content:"\f1f8"} +tr[data-simply-list-icon="fa-copyright"] td:first-child:before{content:"\f1f9"} +tr[data-simply-list-icon="fa-at"] td:first-child:before{content:"\f1fa"} +tr[data-simply-list-icon="fa-eyedropper"] td:first-child:before{content:"\f1fb"} +tr[data-simply-list-icon="fa-paint-brush"] td:first-child:before{content:"\f1fc"} +tr[data-simply-list-icon="fa-birthday-cake"] td:first-child:before{content:"\f1fd"} +tr[data-simply-list-icon="fa-area-chart"] td:first-child:before{content:"\f1fe"} +tr[data-simply-list-icon="fa-pie-chart"] td:first-child:before{content:"\f200"} +tr[data-simply-list-icon="fa-line-chart"] td:first-child:before{content:"\f201"} +tr[data-simply-list-icon="fa-lastfm"] td:first-child:before{content:"\f202"} +tr[data-simply-list-icon="fa-lastfm-square"] td:first-child:before{content:"\f203"} +tr[data-simply-list-icon="fa-toggle-off"] td:first-child:before{content:"\f204"} +tr[data-simply-list-icon="fa-toggle-on"] td:first-child:before{content:"\f205"} +tr[data-simply-list-icon="fa-bicycle"] td:first-child:before{content:"\f206"} +tr[data-simply-list-icon="fa-bus"] td:first-child:before{content:"\f207"} +tr[data-simply-list-icon="fa-ioxhost"] td:first-child:before{content:"\f208"} +tr[data-simply-list-icon="fa-angellist"] td:first-child:before{content:"\f209"} +tr[data-simply-list-icon="fa-cc"] td:first-child:before{content:"\f20a"} +tr[data-simply-list-icon="fa-shekel"] td:first-child:before, +tr[data-simply-list-icon="fa-sheqel"] td:first-child:before, +tr[data-simply-list-icon="fa-ils"] td:first-child:before{content:"\f20b"} +tr[data-simply-list-icon="fa-meanpath"] td:first-child:before{content:"\f20c"} +tr[data-simply-list-icon="fa-buysellads"] td:first-child:before{content:"\f20d"} +tr[data-simply-list-icon="fa-connectdevelop"] td:first-child:before{content:"\f20e"} +tr[data-simply-list-icon="fa-dashcube"] td:first-child:before{content:"\f210"} +tr[data-simply-list-icon="fa-forumbee"] td:first-child:before{content:"\f211"} +tr[data-simply-list-icon="fa-leanpub"] td:first-child:before{content:"\f212"} +tr[data-simply-list-icon="fa-sellsy"] td:first-child:before{content:"\f213"} +tr[data-simply-list-icon="fa-shirtsinbulk"] td:first-child:before{content:"\f214"} +tr[data-simply-list-icon="fa-simplybuilt"] td:first-child:before{content:"\f215"} +tr[data-simply-list-icon="fa-skyatlas"] td:first-child:before{content:"\f216"} +tr[data-simply-list-icon="fa-cart-plus"] td:first-child:before{content:"\f217"} +tr[data-simply-list-icon="fa-cart-arrow-down"] td:first-child:before{content:"\f218"} +tr[data-simply-list-icon="fa-diamond"] td:first-child:before{content:"\f219"} +tr[data-simply-list-icon="fa-ship"] td:first-child:before{content:"\f21a"} +tr[data-simply-list-icon="fa-user-secret"] td:first-child:before{content:"\f21b"} +tr[data-simply-list-icon="fa-motorcycle"] td:first-child:before{content:"\f21c"} +tr[data-simply-list-icon="fa-street-view"] td:first-child:before{content:"\f21d"} +tr[data-simply-list-icon="fa-heartbeat"] td:first-child:before{content:"\f21e"} +tr[data-simply-list-icon="fa-venus"] td:first-child:before{content:"\f221"} +tr[data-simply-list-icon="fa-mars"] td:first-child:before{content:"\f222"} +tr[data-simply-list-icon="fa-mercury"] td:first-child:before{content:"\f223"} +tr[data-simply-list-icon="fa-intersex"] td:first-child:before, +tr[data-simply-list-icon="fa-transgender"] td:first-child:before{content:"\f224"} +tr[data-simply-list-icon="fa-transgender-alt"] td:first-child:before{content:"\f225"} +tr[data-simply-list-icon="fa-venus-double"] td:first-child:before{content:"\f226"} +tr[data-simply-list-icon="fa-mars-double"] td:first-child:before{content:"\f227"} +tr[data-simply-list-icon="fa-venus-mars"] td:first-child:before{content:"\f228"} +tr[data-simply-list-icon="fa-mars-stroke"] td:first-child:before{content:"\f229"} +tr[data-simply-list-icon="fa-mars-stroke-v"] td:first-child:before{content:"\f22a"} +tr[data-simply-list-icon="fa-mars-stroke-h"] td:first-child:before{content:"\f22b"} +tr[data-simply-list-icon="fa-neuter"] td:first-child:before{content:"\f22c"} +tr[data-simply-list-icon="fa-genderless"] td:first-child:before{content:"\f22d"} +tr[data-simply-list-icon="fa-facebook-official"] td:first-child:before{content:"\f230"} +tr[data-simply-list-icon="fa-pinterest-p"] td:first-child:before{content:"\f231"} +tr[data-simply-list-icon="fa-whatsapp"] td:first-child:before{content:"\f232"} +tr[data-simply-list-icon="fa-server"] td:first-child:before{content:"\f233"} +tr[data-simply-list-icon="fa-user-plus"] td:first-child:before{content:"\f234"} +tr[data-simply-list-icon="fa-user-times"] td:first-child:before{content:"\f235"} +tr[data-simply-list-icon="fa-hotel"] td:first-child:before, +tr[data-simply-list-icon="fa-bed"] td:first-child:before{content:"\f236"} +tr[data-simply-list-icon="fa-viacoin"] td:first-child:before{content:"\f237"} +tr[data-simply-list-icon="fa-train"] td:first-child:before{content:"\f238"} +tr[data-simply-list-icon="fa-subway"] td:first-child:before{content:"\f239"} +tr[data-simply-list-icon="fa-medium"] td:first-child:before{content:"\f23a"} +tr[data-simply-list-icon="fa-yc"] td:first-child:before, +tr[data-simply-list-icon="fa-y-combinator"] td:first-child:before{content:"\f23b"} +tr[data-simply-list-icon="fa-optin-monster"] td:first-child:before{content:"\f23c"} +tr[data-simply-list-icon="fa-opencart"] td:first-child:before{content:"\f23d"} +tr[data-simply-list-icon="fa-expeditedssl"] td:first-child:before{content:"\f23e"} +tr[data-simply-list-icon="fa-battery-4"] td:first-child:before, +tr[data-simply-list-icon="fa-battery-full"] td:first-child:before{content:"\f240"} +tr[data-simply-list-icon="fa-battery-3"] td:first-child:before, +tr[data-simply-list-icon="fa-battery-three-quarters"] td:first-child:before{content:"\f241"} +tr[data-simply-list-icon="fa-battery-2"] td:first-child:before, +tr[data-simply-list-icon="fa-battery-half"] td:first-child:before{content:"\f242"} +tr[data-simply-list-icon="fa-battery-1"] td:first-child:before, +tr[data-simply-list-icon="fa-battery-quarter"] td:first-child:before{content:"\f243"} +tr[data-simply-list-icon="fa-battery-0"] td:first-child:before, +tr[data-simply-list-icon="fa-battery-empty"] td:first-child:before{content:"\f244"} +tr[data-simply-list-icon="fa-mouse-pointer"] td:first-child:before{content:"\f245"} +tr[data-simply-list-icon="fa-i-cursor"] td:first-child:before{content:"\f246"} +tr[data-simply-list-icon="fa-object-group"] td:first-child:before{content:"\f247"} +tr[data-simply-list-icon="fa-object-ungroup"] td:first-child:before{content:"\f248"} +tr[data-simply-list-icon="fa-sticky-note"] td:first-child:before{content:"\f249"} +tr[data-simply-list-icon="fa-sticky-note-o"] td:first-child:before{content:"\f24a"} +tr[data-simply-list-icon="fa-cc-jcb"] td:first-child:before{content:"\f24b"} +tr[data-simply-list-icon="fa-cc-diners-club"] td:first-child:before{content:"\f24c"} +tr[data-simply-list-icon="fa-clone"] td:first-child:before{content:"\f24d"} +tr[data-simply-list-icon="fa-balance-scale"] td:first-child:before{content:"\f24e"} +tr[data-simply-list-icon="fa-hourglass-o"] td:first-child:before{content:"\f250"} +tr[data-simply-list-icon="fa-hourglass-1"] td:first-child:before, +tr[data-simply-list-icon="fa-hourglass-start"] td:first-child:before{content:"\f251"} +tr[data-simply-list-icon="fa-hourglass-2"] td:first-child:before, +tr[data-simply-list-icon="fa-hourglass-half"] td:first-child:before{content:"\f252"} +tr[data-simply-list-icon="fa-hourglass-3"] td:first-child:before, +tr[data-simply-list-icon="fa-hourglass-end"] td:first-child:before{content:"\f253"} +tr[data-simply-list-icon="fa-hourglass"] td:first-child:before{content:"\f254"} +tr[data-simply-list-icon="fa-hand-grab-o"] td:first-child:before, +tr[data-simply-list-icon="fa-hand-rock-o"] td:first-child:before{content:"\f255"} +tr[data-simply-list-icon="fa-hand-stop-o"] td:first-child:before, +tr[data-simply-list-icon="fa-hand-paper-o"] td:first-child:before{content:"\f256"} +tr[data-simply-list-icon="fa-hand-scissors-o"] td:first-child:before{content:"\f257"} +tr[data-simply-list-icon="fa-hand-lizard-o"] td:first-child:before{content:"\f258"} +tr[data-simply-list-icon="fa-hand-spock-o"] td:first-child:before{content:"\f259"} +tr[data-simply-list-icon="fa-hand-pointer-o"] td:first-child:before{content:"\f25a"} +tr[data-simply-list-icon="fa-hand-peace-o"] td:first-child:before{content:"\f25b"} +tr[data-simply-list-icon="fa-trademark"] td:first-child:before{content:"\f25c"} +tr[data-simply-list-icon="fa-registered"] td:first-child:before{content:"\f25d"} +tr[data-simply-list-icon="fa-creative-commons"] td:first-child:before{content:"\f25e"} +tr[data-simply-list-icon="fa-gg"] td:first-child:before{content:"\f260"} +tr[data-simply-list-icon="fa-gg-circle"] td:first-child:before{content:"\f261"} +tr[data-simply-list-icon="fa-tripadvisor"] td:first-child:before{content:"\f262"} +tr[data-simply-list-icon="fa-odnoklassniki"] td:first-child:before{content:"\f263"} +tr[data-simply-list-icon="fa-odnoklassniki-square"] td:first-child:before{content:"\f264"} +tr[data-simply-list-icon="fa-get-pocket"] td:first-child:before{content:"\f265"} +tr[data-simply-list-icon="fa-wikipedia-w"] td:first-child:before{content:"\f266"} +tr[data-simply-list-icon="fa-safari"] td:first-child:before{content:"\f267"} +tr[data-simply-list-icon="fa-chrome"] td:first-child:before{content:"\f268"} +tr[data-simply-list-icon="fa-firefox"] td:first-child:before{content:"\f269"} +tr[data-simply-list-icon="fa-opera"] td:first-child:before{content:"\f26a"} +tr[data-simply-list-icon="fa-internet-explorer"] td:first-child:before{content:"\f26b"} +tr[data-simply-list-icon="fa-tv"] td:first-child:before, +tr[data-simply-list-icon="fa-television"] td:first-child:before{content:"\f26c"} +tr[data-simply-list-icon="fa-contao"] td:first-child:before{content:"\f26d"} +tr[data-simply-list-icon="fa-500px"] td:first-child:before{content:"\f26e"} +tr[data-simply-list-icon="fa-amazon"] td:first-child:before{content:"\f270"} +tr[data-simply-list-icon="fa-calendar-plus-o"] td:first-child:before{content:"\f271"} +tr[data-simply-list-icon="fa-calendar-minus-o"] td:first-child:before{content:"\f272"} +tr[data-simply-list-icon="fa-calendar-times-o"] td:first-child:before{content:"\f273"} +tr[data-simply-list-icon="fa-calendar-check-o"] td:first-child:before{content:"\f274"} +tr[data-simply-list-icon="fa-industry"] td:first-child:before{content:"\f275"} +tr[data-simply-list-icon="fa-map-pin"] td:first-child:before{content:"\f276"} +tr[data-simply-list-icon="fa-map-signs"] td:first-child:before{content:"\f277"} +tr[data-simply-list-icon="fa-map-o"] td:first-child:before{content:"\f278"} +tr[data-simply-list-icon="fa-map"] td:first-child:before{content:"\f279"} +tr[data-simply-list-icon="fa-commenting"] td:first-child:before{content:"\f27a"} +tr[data-simply-list-icon="fa-commenting-o"] td:first-child:before{content:"\f27b"} +tr[data-simply-list-icon="fa-houzz"] td:first-child:before{content:"\f27c"} +tr[data-simply-list-icon="fa-vimeo"] td:first-child:before{content:"\f27d"} +tr[data-simply-list-icon="fa-black-tie"] td:first-child:before{content:"\f27e"} +tr[data-simply-list-icon="fa-fonticons"] td:first-child:before{content:"\f280"} diff --git a/www/simply/databind.js b/www/simply/databind.js new file mode 100644 index 0000000..70ddf12 --- /dev/null +++ b/www/simply/databind.js @@ -0,0 +1,1037 @@ +/* + Two way databinding between a data object and DOM element(s). + A databinding is attached to one data object. It can be bound to one or more elements. + Changes in the element are resolved every x ms; + Changes in the data are resolved to the element directly; + + config options: + data: the data object to be used for databinding. Note that this is the 'outer' object, the databinding itself will be set on data[key]; + key: the key within the data object to be bound + setter: a function that sets the data on the element. A simple example would take the provided value and set it as innerHTML. + getter: a function that fetches the data from an element. Simple example would be "return target.innerHTML"; + mode: "list" of "field"; the only difference between the two is the listeners that are applied to the supplied element. + "list" listens on attribute changes, node insertions and node removals. + "field" listens on attribute changes, subtree modifications. + parentKey: an additional pointer to where the data is bound without your datastructure; use this to keep track of nesting within your data. + attributeFilter: a blacklist of attributes that should not trigger a change in data; + resolve: a function that is called _after_ a change in data has been resolved. The arguments provided to the function are: dataBinding, key, value, oldValue + + Basic usage usage: + var data = { + "title" : "foo" + }; + + var dataBinding = new databinding({ + data : data, + key : title, + setter : function(value) { + this.innerHTML = value; + }, + getter: function() { + return this.innerHTML; + } + }); + + + dataBinding.bind(document.getElementById('title')); + + console.log(data.title); // "foo" + data.title = "Hello world"; // innerHTML for title is changed to 'Hello world'; + console.log(data.title); // "Hello world" + document.getElementById('title').innerHTML = "Bar"; + console.log(data.title); // "Bar" +*/ + +elementBinding = function(element, config, dataBinding) { + var self = this; + this.element = element; + this.dataBinding = dataBinding; + this.element.dataBinding = dataBinding; + this.element.elementBinding = this; + + this.dataBindingConfig = config; + this.unbind = function() { + if (this.dataBinding) { + this.dataBinding.unbind(this); + } + }; + element.dataBindingPaused = 0; + this.elementGetter = (config && typeof config.getter === "function") ? config.getter : this.dataBinding.getter; + this.elementSetter = (config && typeof config.setter === "function") ? config.setter : this.dataBinding.setter; + element.getter = this.elementGetter; + element.setter = this.elementSetter; + + this.getter = function() { + return this.elementGetter.call(element); + }; + this.setter = function(data) { + return this.elementSetter.call(element, data); + }; + + this.addListeners = function() { + this.removeListeners(); + if (typeof this.element.mutationObserver === "undefined") { + this.element.mutationHandler = this.getMutationHandler(this.element); + this.element.mutationObserver = new MutationObserver(this.element.mutationHandler); + } + if (this.dataBinding.mode == "field") { + if (this.element.mutationObserver) { + this.element.mutationObserverConfig = { + attributes: true, + characterData: true, + subtree: true, + childList: true + }; + if (this.element.dataBindingPaused === 0) { + this.element.mutationObserver.observe(this.element, this.element.mutationObserverConfig); + } + } + this.element.addEventListener("change", this.handleEvent); + } + if (this.dataBinding.mode == "list") { + if (this.element.mutationObserver) { + this.element.mutationObserverConfig = { + attributes: true, + childList: true + }; + if (this.element.dataBindingPaused === 0) { + this.element.mutationObserver.observe(this.element, this.element.mutationObserverConfig); + } + } + } + this.element.addEventListener("databinding:valuechanged", this.handleEvent); + this.element.addEventListener("databinding:pause", function() { + this.elementBinding.pauseListeners(); + }); + this.element.addEventListener("databinding:resume", function() { + this.elementBinding.resumeListeners(); + }); + this.element.addEventListener("databind:pause", function() { + this.elementBinding.pauseListeners(); + }); + this.element.addEventListener("databind:resume", function() { + this.elementBinding.resumeListeners(); + }); + }; + + this.removeListeners = function() { + if (this.dataBinding.mode == "field") { + if (this.element.mutationObserver) { + this.element.mutationObserver.disconnect(); + } + this.element.removeEventListener("change", this.handleEvent); + } + if (this.dataBinding.mode == "list") { + if (this.element.mutationObserver) { + this.element.mutationObserver.disconnect(); + } + } + this.element.removeEventListener("databinding:valuechanged", this.handleEvent); + }; + + this.resumeListeners = function() { + this.element.dataBindingPaused--; + if (this.element.dataBindingPaused < 0) { + console.log("Warning: resume called of non-paused databinding"); + this.element.dataBindingPaused = 0; + } + if (this.element.dataBindingPaused === 0) { + if (this.element.mutationObserver) { + this.element.mutationObserver.status = "observing"; + this.element.mutationObserver.observe(this.element, this.element.mutationObserverConfig); + } else { + console.log("Warning: no mutation observer found"); + } + } + }; + this.pauseListeners = function() { + if (this.element.mutationObserver) { + // Disconnecting will flush the queue of records and trash them - if we have things that we need to handle, do so. + this.element.mutationHandler(this.element.mutationObserver.takeRecords()); + this.element.mutationObserver.status = "disconnected"; + this.element.mutationObserver.disconnect(); + } + this.element.dataBindingPaused++; + }; + + this.getMutationHandler = function(target) { + return function(mutations) { + mutations.forEach(function(mutation) { + if (!target.dataBinding) { + return; + } + if (target.dataBindingPaused) { + return; + } + + if (target.dataBinding.paused) { + return; + } + var elementBinding = target.elementBinding; + elementBinding.pauseListeners(); + + if (target.dataBinding.mode == "field") { + switch (mutation.type) { + case "attributes": + if (target.dataBinding.attributeFilter.indexOf(mutation.attributeName) !== -1) { + break; // only handle the attribute mutation if the attribute changed is in our set + } + elementBinding.dataBinding.set(elementBinding.getter()); + break; + case "childList": + break; + default: + // there are needed to keep the focus in an element while typing; + dataBinding.set(elementBinding.getter()); + break; + } + } + if (target.dataBinding.mode == "list") { + switch (mutation.type) { + case "attributes": + if (target.dataBinding.attributeFilter.indexOf(mutation.attributeName) !== -1) { + break; // only handle the attribute mutation if the attribute changed is in our set + } + elementBinding.dataBinding.set(elementBinding.getter()); + break; + case "childList": + mutation.removedNodes.forEach(function(removedNode) { + if (removedNode.nodeType != document.ELEMENT_NODE) { + return; + } + if (removedNode.simplyRemoved) { + return; + } + if (typeof removedNode.simplyListIndex === "undefined") { + return; + } + removedNode.simplyRemoved = true; + // find the index of the removed target node; + data = target.dataBinding.get(); + items = target.querySelectorAll(":scope > [data-simply-list-item]"); + //for (i=0; i [data-simply-list-item]"); + for (i=0; i " + newparent); + value._bindings_[subbinding].parentKey = newparent; + if (value[subbinding] && value[subbinding].length && (typeof value[subbinding] !== "string")) { + for (var i=0; i 5) { + console.log("Warning: databinding resolve loop detected!"); + window.setTimeout(function() { + binding.resolveCounter = 0; + }, 300); // 300 is a guess; could be any other number. It needs to be long enough so that everyone can settle down before we start resolving again. + return true; + } + return false; + }; + + var setElements = function() { + if (binding.elementTimer) { + window.clearTimeout(binding.elementTimer); + } + for (var i=0; i -1) { + element.removeListeners(); + binding.elements.splice(binding.elements.indexOf(element), 1); + } + }; + + this.cleanupBindings = function() { + if (binding.elements.length < 2) { + return; + } + + binding.elements.forEach(function(element) { + if (!element.isInDocument()) { + element.markedForRemoval = true; + } else { + element.markedForRemoval = false; + } + }); + + if (binding.cleanupTimer) { + clearTimeout(binding.cleanupTimer); + } + + binding.cleanupTimer = window.setTimeout(function() { + binding.elements.filter(function(element) { + if (element.markedForRemoval && !element.isInDocument()) { + element.dataBinding.unbind(element); + return false; + } + element.markedForRemoval = false; + return true; + }); + }, 1000); // If after 1 second the element is still not in the dom, remove the binding; + }; + + initBindings(data, key); + // Call the custom init function, if it is there; + if (typeof binding.config.init === "function") { + binding.config.init.call(binding); + } + + if (binding.mode == "list") { + document.addEventListener("databind:resolved", function() { + if (!binding.skipOldValueUpdate) { + oldValue = dereference(binding.get()); + } + }); + } +}; + +dataBinding.prototype.resumeListeners = function(element) { + element.dataBindingPaused--; + if (element.dataBindingPaused < 0) { + console.log("Warning: resume called of non-paused databinding"); + element.dataBindingPaused = 0; + } + if (element.dataBindingPaused === 0) { + if (element.mutationObserver) { + element.mutationObserver.observe(element, element.mutationObserverConfig); + element.mutationObserver.status = "observing"; + } else { + console.log("Warning: no mutation observer found"); + } + } +}; +dataBinding.prototype.pauseListeners = function(element) { + element.dataBindingPaused++; + if (element.mutationObserver) { + element.mutationObserver.status = "disconnected"; + element.mutationObserver.disconnect(); + } +}; + +// Housekeeping, remove references to deleted nodes +var removalObserver = new MutationObserver(function(mutations) { + mutations.forEach(function(mutation) { + if (mutation.type == "childList") { + mutation.removedNodes.forEach(function(target) { + if (target.nodeType != document.ELEMENT_NODE) { // We don't care about removed text nodes; + return; + } + if (!target.dataBinding) { // nor any element that doesn't have a databinding; + return; + } + window.setTimeout(function() { // chrome sometimes 'helpfully' removes the element and then inserts it back, probably as a rendering optimalization. We're fine cleaning up in a bit, if still needed. + if (!target.parentNode && target.dataBinding && target.elementBinding) { + target.dataBinding.unbind(target.elementBinding); + // if (target.dataBinding.mode == "field") { + // target.dataBinding.set(); + // } + delete target.dataBinding; + } + }, 400); + }); + } + }); +}); + +removalObserver.observe(document.body, { + "childList" : true, + "subtree" : true +}); + +// polyfill to add :scope selector for IE +(function() { + if (!HTMLElement.prototype.querySelectorAll) { + throw new Error('rootedQuerySelectorAll: This polyfill can only be used with browsers that support querySelectorAll'); + } + + // A temporary element to query against for elements not currently in the DOM + // We'll also use this element to test for :scope support + var container = document.createElement('div'); + + // Check if the browser supports :scope + try { + // Browser supports :scope, do nothing + container.querySelectorAll(':scope *'); + } + catch (e) { + // Match usage of scope + var scopeRE = /\s*:scope/gi; + + // Overrides + function overrideNodeMethod(prototype, methodName) { + // Store the old method for use later + var oldMethod = prototype[methodName]; + + // Override the method + prototype[methodName] = function(query) { + var nodeList, + gaveId = false, + gaveContainer = false; + + if (query.match(scopeRE)) { + if (!this.parentNode) { + // Add to temporary container + container.appendChild(this); + gaveContainer = true; + } + + parentNode = this.parentNode; + + if (!this.id) { + // Give temporary ID + this.id = 'rootedQuerySelector_id_'+(new Date()).getTime(); + gaveId = true; + } + + // Remove :scope + query = query.replace(scopeRE, '#' + this.id + " "); + + // Find elements against parent node + // nodeList = oldMethod.call(parentNode, '#'+this.id+' '+query); + nodeList = parentNode[methodName](query); + // Reset the ID + if (gaveId) { + this.id = ''; + } + + // Remove from temporary container + if (gaveContainer) { + container.removeChild(this); + } + + return nodeList; + } + else { + // No immediate child selector used + return oldMethod.call(this, query); + } + }; + } + + // Browser doesn't support :scope, add polyfill + overrideNodeMethod(HTMLElement.prototype, 'querySelector'); + overrideNodeMethod(HTMLElement.prototype, 'querySelectorAll'); + } +}()); diff --git a/www/simply/diff_match_patch.js b/www/simply/diff_match_patch.js new file mode 100644 index 0000000..0428b18 --- /dev/null +++ b/www/simply/diff_match_patch.js @@ -0,0 +1,76 @@ +/** + * Diff Match and Patch + * + * Copyright 2006 Google Inc. + * http://code.google.com/p/google-diff-match-patch/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @fileoverview Computes the difference between two texts to create a patch. + * Applies the patch onto another text, allowing for errors. + * @author fraser@google.com (Neil Fraser) + */ + +// jshint ignore: start + +(function(){function diff_match_patch(){this.Diff_Timeout=1;this.Diff_EditCost=4;this.Match_Threshold=0.5;this.Match_Distance=1E3;this.Patch_DeleteThreshold=0.5;this.Patch_Margin=4;this.Match_MaxBits=32} +diff_match_patch.prototype.diff_main=function(a,b,c,d){"undefined"==typeof d&&(d=0>=this.Diff_Timeout?Number.MAX_VALUE:(new Date).getTime()+1E3*this.Diff_Timeout);if(null==a||null==b)throw Error("Null input. (diff_main)");if(a==b)return a?[[0,a]]:[];"undefined"==typeof c&&(c=!0);var e=c,f=this.diff_commonPrefix(a,b);c=a.substring(0,f);a=a.substring(f);b=b.substring(f);var f=this.diff_commonSuffix(a,b),g=a.substring(a.length-f);a=a.substring(0,a.length-f);b=b.substring(0,b.length-f);a=this.diff_compute_(a, +b,e,d);c&&a.unshift([0,c]);g&&a.push([0,g]);this.diff_cleanupMerge(a);return a}; +diff_match_patch.prototype.diff_compute_=function(a,b,c,d){if(!a)return[[1,b]];if(!b)return[[-1,a]];var e=a.length>b.length?a:b,f=a.length>b.length?b:a,g=e.indexOf(f);return-1!=g?(c=[[1,e.substring(0,g)],[0,f],[1,e.substring(g+f.length)]],a.length>b.length&&(c[0][0]=c[2][0]=-1),c):1==f.length?[[-1,a],[1,b]]:(e=this.diff_halfMatch_(a,b))?(f=e[0],a=e[1],g=e[2],b=e[3],e=e[4],f=this.diff_main(f,g,c,d),c=this.diff_main(a,b,c,d),f.concat([[0,e]],c)):c&&100c);v++){for(var n=-v+r;n<=v-t;n+=2){var l=g+n,m;m=n==-v||n!=v&&j[l-1]d)t+=2;else if(s>e)r+=2;else if(q&&(l=g+k-n,0<=l&&l= +u)return this.diff_bisectSplit_(a,b,m,s,c)}}for(n=-v+p;n<=v-w;n+=2){l=g+n;u=n==-v||n!=v&&i[l-1]d)w+=2;else if(m>e)p+=2;else if(!q&&(l=g+k-n,0<=l&&(l=u)))return this.diff_bisectSplit_(a,b,m,s,c)}}return[[-1,a],[1,b]]}; +diff_match_patch.prototype.diff_bisectSplit_=function(a,b,c,d,e){var f=a.substring(0,c),g=b.substring(0,d);a=a.substring(c);b=b.substring(d);f=this.diff_main(f,g,!1,e);e=this.diff_main(a,b,!1,e);return f.concat(e)}; +diff_match_patch.prototype.diff_linesToChars_=function(a,b){function c(a){for(var b="",c=0,f=-1,g=d.length;fd?a=a.substring(c-d):c=a.length?[h,j,n,l,g]:null}if(0>=this.Diff_Timeout)return null; +var d=a.length>b.length?a:b,e=a.length>b.length?b:a;if(4>d.length||2*e.lengthd[4].length?g:d:d:g;var j;a.length>b.length?(g=h[0],d=h[1],e=h[2],j=h[3]):(e=h[0],j=h[1],g=h[2],d=h[3]);h=h[4];return[g,d,e,j,h]}; +diff_match_patch.prototype.diff_cleanupSemantic=function(a){for(var b=!1,c=[],d=0,e=null,f=0,g=0,h=0,j=0,i=0;f=e){if(d>=b.length/2||d>=c.length/2)a.splice(f,0,[0,c.substring(0,d)]),a[f-1][1]=b.substring(0,b.length-d),a[f+1][1]=c.substring(d),f++}else if(e>=b.length/2||e>=c.length/2)a.splice(f,0,[0,b.substring(0,e)]),a[f-1][0]=1,a[f-1][1]=c.substring(0,c.length-e),a[f+1][0]=-1,a[f+1][1]=b.substring(e),f++;f++}f++}}; +diff_match_patch.prototype.diff_cleanupSemanticLossless=function(a){function b(a,b){if(!a||!b)return 6;var c=a.charAt(a.length-1),d=b.charAt(0),e=c.match(diff_match_patch.nonAlphaNumericRegex_),f=d.match(diff_match_patch.nonAlphaNumericRegex_),g=e&&c.match(diff_match_patch.whitespaceRegex_),h=f&&d.match(diff_match_patch.whitespaceRegex_),c=g&&c.match(diff_match_patch.linebreakRegex_),d=h&&d.match(diff_match_patch.linebreakRegex_),i=c&&a.match(diff_match_patch.blanklineEndRegex_),j=d&&b.match(diff_match_patch.blanklineStartRegex_); +return i||j?5:c||d?4:e&&!g&&h?3:g||h?2:e||f?1:0}for(var c=1;c=i&&(i=k,g=d,h=e,j=f)}a[c-1][1]!=g&&(g?a[c-1][1]=g:(a.splice(c-1,1),c--),a[c][1]= +h,j?a[c+1][1]=j:(a.splice(c+1,1),c--))}c++}};diff_match_patch.nonAlphaNumericRegex_=/[^a-zA-Z0-9]/;diff_match_patch.whitespaceRegex_=/\s/;diff_match_patch.linebreakRegex_=/[\r\n]/;diff_match_patch.blanklineEndRegex_=/\n\r?\n$/;diff_match_patch.blanklineStartRegex_=/^\r?\n\r?\n/; +diff_match_patch.prototype.diff_cleanupEfficiency=function(a){for(var b=!1,c=[],d=0,e=null,f=0,g=!1,h=!1,j=!1,i=!1;fb)break;e=c;f=d}return a.length!=g&&-1===a[g][0]?f:f+(b-e)}; +diff_match_patch.prototype.diff_prettyHtml=function(a){for(var b=[],c=/&/g,d=//g,f=/\n/g,g=0;g");switch(h){case 1:b[g]=''+j+"";break;case -1:b[g]=''+j+"";break;case 0:b[g]=""+j+""}}return b.join("")}; +diff_match_patch.prototype.diff_text1=function(a){for(var b=[],c=0;cthis.Match_MaxBits)throw Error("Pattern too long for this browser.");var e=this.match_alphabet_(b),f=this,g=this.Match_Threshold,h=a.indexOf(b,c);-1!=h&&(g=Math.min(d(0,h),g),h=a.lastIndexOf(b,c+b.length),-1!=h&&(g=Math.min(d(0,h),g)));for(var j=1<=i;p--){var w=e[a.charAt(p-1)];k[p]=0===t?(k[p+1]<<1|1)&w:(k[p+1]<<1|1)&w|((r[p+1]|r[p])<<1|1)|r[p+1];if(k[p]&j&&(w=d(t,p-1),w<=g))if(g=w,h=p-1,h>c)i=Math.max(1,2*c-h);else break}if(d(t+1,c)>g)break;r=k}return h}; +diff_match_patch.prototype.match_alphabet_=function(a){for(var b={},c=0;c=2*this.Patch_Margin&& +e&&(this.patch_addContext_(a,h),c.push(a),a=new diff_match_patch.patch_obj,e=0,h=d,f=g)}1!==i&&(f+=k.length);-1!==i&&(g+=k.length)}e&&(this.patch_addContext_(a,h),c.push(a));return c};diff_match_patch.prototype.patch_deepCopy=function(a){for(var b=[],c=0;cthis.Match_MaxBits){if(j=this.match_main(b,h.substring(0,this.Match_MaxBits),g),-1!=j&&(i=this.match_main(b,h.substring(h.length-this.Match_MaxBits),g+h.length-this.Match_MaxBits),-1==i||j>=i))j=-1}else j=this.match_main(b,h,g); +if(-1==j)e[f]=!1,d-=a[f].length2-a[f].length1;else if(e[f]=!0,d=j-g,g=-1==i?b.substring(j,j+h.length):b.substring(j,i+this.Match_MaxBits),h==g)b=b.substring(0,j)+this.diff_text2(a[f].diffs)+b.substring(j+h.length);else if(g=this.diff_main(h,g,!1),h.length>this.Match_MaxBits&&this.diff_levenshtein(g)/h.length>this.Patch_DeleteThreshold)e[f]=!1;else{this.diff_cleanupSemanticLossless(g);for(var h=0,k,i=0;ie[0][1].length){var f=b-e[0][1].length;e[0][1]=c.substring(e[0][1].length)+e[0][1];d.start1-=f;d.start2-=f;d.length1+=f;d.length2+=f}d=a[a.length-1];e=d.diffs;0==e.length||0!=e[e.length-1][0]?(e.push([0, +c]),d.length1+=b,d.length2+=b):b>e[e.length-1][1].length&&(f=b-e[e.length-1][1].length,e[e.length-1][1]+=c.substring(0,f),d.length1+=f,d.length2+=f);return c}; +diff_match_patch.prototype.patch_splitMax=function(a){for(var b=this.Match_MaxBits,c=0;c2*b?(h.length1+=i.length,e+=i.length,j=!1,h.diffs.push([g,i]),d.diffs.shift()):(i=i.substring(0,b-h.length1-this.Patch_Margin),h.length1+=i.length,e+=i.length,0===g?(h.length2+=i.length,f+=i.length):j=!1,h.diffs.push([g,i]),i==d.diffs[0][1]?d.diffs.shift():d.diffs[0][1]=d.diffs[0][1].substring(i.length))}g=this.diff_text2(h.diffs);g=g.substring(g.length-this.Patch_Margin);i=this.diff_text1(d.diffs).substring(0,this.Patch_Margin);""!==i&& +(h.length1+=i.length,h.length2+=i.length,0!==h.diffs.length&&0===h.diffs[h.diffs.length-1][0]?h.diffs[h.diffs.length-1][1]+=i:h.diffs.push([0,i]));j||a.splice(++c,0,h)}}};diff_match_patch.prototype.patch_toText=function(a){for(var b=[],c=0;c toolbar.simply-basepack.html \ No newline at end of file diff --git a/www/simply/plugin.simply-about.html b/www/simply/plugin.simply-about.html new file mode 100755 index 0000000..29f5a29 --- /dev/null +++ b/www/simply/plugin.simply-about.html @@ -0,0 +1,191 @@ +
+
+
    +
  • +
  • +
  • +
  • +
  • +
+
+
+ +
+
+
Your key
+
Valid for
+
+ +
+
+
+ +
+
+
+ + + +
+ +
+
+
+ + diff --git a/www/simply/plugin.simply-baseurl.html b/www/simply/plugin.simply-baseurl.html new file mode 100644 index 0000000..cd4b12f --- /dev/null +++ b/www/simply/plugin.simply-baseurl.html @@ -0,0 +1,52 @@ + \ No newline at end of file diff --git a/www/simply/plugin.simply-browse.html b/www/simply/plugin.simply-browse.html new file mode 100644 index 0000000..fc7bd62 --- /dev/null +++ b/www/simply/plugin.simply-browse.html @@ -0,0 +1,934 @@ + +
+
+
    + +
  • +
  • +
  • +
  • + + +
  • + + +
  • +
  • +
+
+
+
+
+ + diff --git a/www/simply/plugin.simply-diff.html b/www/simply/plugin.simply-diff.html new file mode 100644 index 0000000..8448424 --- /dev/null +++ b/www/simply/plugin.simply-diff.html @@ -0,0 +1,284 @@ + +
+
+
    +
  • +
  • +
  • +
  • + +
  • + +
+
+
+
+
Theirs
+
Mine
+
+
+
+
    +
  • Review the differences and choose which of them to use.
  • +
  • +
+
+
+ diff --git a/www/simply/plugin.simply-dropbox.html b/www/simply/plugin.simply-dropbox.html new file mode 100644 index 0000000..60a86f8 --- /dev/null +++ b/www/simply/plugin.simply-dropbox.html @@ -0,0 +1,48 @@ + + \ No newline at end of file diff --git a/www/simply/plugin.simply-htmlsource.html b/www/simply/plugin.simply-htmlsource.html new file mode 100644 index 0000000..f5069fe --- /dev/null +++ b/www/simply/plugin.simply-htmlsource.html @@ -0,0 +1,190 @@ +
+
+
    +
  • + +
  • +
  • +
+
+
+ +
+
+
    + +
  • +
+
+
+ + diff --git a/www/simply/plugin.simply-keyboard.html b/www/simply/plugin.simply-keyboard.html new file mode 100644 index 0000000..1c349bc --- /dev/null +++ b/www/simply/plugin.simply-keyboard.html @@ -0,0 +1,170 @@ + \ No newline at end of file diff --git a/www/simply/plugin.simply-login.html b/www/simply/plugin.simply-login.html new file mode 100644 index 0000000..b3957c7 --- /dev/null +++ b/www/simply/plugin.simply-login.html @@ -0,0 +1,67 @@ +
+
+

+
+
+ + +
+
+ + +
+ +
+
+ diff --git a/www/simply/plugin.simply-meta.html b/www/simply/plugin.simply-meta.html new file mode 100644 index 0000000..bc0f961 --- /dev/null +++ b/www/simply/plugin.simply-meta.html @@ -0,0 +1,143 @@ +
+
+
    +
  • +
  • +
  • +
+ +
+
+
    +
  • +
+
+
+ + \ No newline at end of file diff --git a/www/simply/plugin.simply-paste.html b/www/simply/plugin.simply-paste.html new file mode 100644 index 0000000..4be5315 --- /dev/null +++ b/www/simply/plugin.simply-paste.html @@ -0,0 +1,362 @@ + \ No newline at end of file diff --git a/www/simply/plugin.simply-paste.html.krak b/www/simply/plugin.simply-paste.html.krak new file mode 100644 index 0000000..57522ff --- /dev/null +++ b/www/simply/plugin.simply-paste.html.krak @@ -0,0 +1,351 @@ + \ No newline at end of file diff --git a/www/simply/plugin.simply-plain.html b/www/simply/plugin.simply-plain.html new file mode 100644 index 0000000..72d4c66 --- /dev/null +++ b/www/simply/plugin.simply-plain.html @@ -0,0 +1,62 @@ + \ No newline at end of file diff --git a/www/simply/plugin.simply-save.html b/www/simply/plugin.simply-save.html new file mode 100644 index 0000000..1f95452 --- /dev/null +++ b/www/simply/plugin.simply-save.html @@ -0,0 +1,86 @@ +
+
+ +
Saving...
+
Please wait...
+
+
+ + diff --git a/www/simply/plugin.simply-scaler.html b/www/simply/plugin.simply-scaler.html new file mode 100644 index 0000000..61882b9 --- /dev/null +++ b/www/simply/plugin.simply-scaler.html @@ -0,0 +1,221 @@ + diff --git a/www/simply/plugin.simply-symbol.html b/www/simply/plugin.simply-symbol.html new file mode 100644 index 0000000..91ac743 --- /dev/null +++ b/www/simply/plugin.simply-symbol.html @@ -0,0 +1,133 @@ +
+
+
    +
  • +
  • +
+
+
+
+
+ + \ No newline at end of file diff --git a/www/simply/plugin.simply-template.html b/www/simply/plugin.simply-template.html new file mode 100644 index 0000000..6beabc2 --- /dev/null +++ b/www/simply/plugin.simply-template.html @@ -0,0 +1,134 @@ +
+
+
    +
  • +
  • +
  • +
+
+
+ + +
+
+ +
+
+
+
+
    +
  • +
+
+
+ + \ No newline at end of file diff --git a/www/simply/plugin.simply-undo-redo.html b/www/simply/plugin.simply-undo-redo.html new file mode 100644 index 0000000..88bb5f1 --- /dev/null +++ b/www/simply/plugin.simply-undo-redo.html @@ -0,0 +1,233 @@ + \ No newline at end of file diff --git a/www/simply/plugin.toolbar-scroll.html b/www/simply/plugin.toolbar-scroll.html new file mode 100644 index 0000000..82e9eec --- /dev/null +++ b/www/simply/plugin.toolbar-scroll.html @@ -0,0 +1,103 @@ + \ No newline at end of file diff --git a/www/simply/scripts.js b/www/simply/scripts.js new file mode 100644 index 0000000..384e55b --- /dev/null +++ b/www/simply/scripts.js @@ -0,0 +1,2325 @@ +/* + core javascript library for muze modules + ---------------------------------------- + + object namespace(string module, function implementaion) + This method checks if the namespace 'module' is available, and if not + creates it and registers it. It returns the object the namespace points + to, so you can create a shorthand for it. + If you specify an implementation method, this method will be called with + 'this' pointing to the namespace object. + examples: + muze.namespace('muze.test'); + + var myMod = muze.namespace('muze.temp.my.module.with.a.long.name'); + + muze.namespace('muze.test', function() { this.test = function() { alert 'test'; } } ); + + object require(mixed modules, function continuation) + This method checks if the given module is available (registered). + If not, it will try to load the module, if it can or throw an error with the + missing module, and return false. + If it is available, it will return the module object, for a single module. + If a continuation function is supplied, that function will be called if and when the + required namespaces are available. + If you require multiple modules, pass an array with all required modules or a string + with all modules seperated with a ','. Extra spaces will be trimmed of. + You can specify a url for any given module instead of a module name or in addition of + a module name by seperating them with a '|' character: + muze.require('jquery|//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js', ...) + muze.require('//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js', ...) + + muze.require('module.not.available'); + + will throw an error, so you can do this: + + try { + muze.require('muze.event'); + // do stuff + } catch(e) { + // module is not available + } + + or: + + muze.require('muze.event, muze.env', function() { + // do stuff, this function is called in the global scope + }); + + object include(string url, string namespace) + This method checks whether the given namespace is already registered. If + so it doesn't do anything. + If the namespace is not registered (or not entered), it dynamically loads + the url as a javascript object (script tag). + In both cases the method returns the onload handler object. This object + has one method 'onload', which allows you to specify a function that should + be run when the javascript is loaded. This function is also run if the + javascript was already loaded and include didn't actually do anything. + examples: + // this will only load muze.test.js if namespace muze.test isn't already + // loaded and muze.test.js isn't already loaded + muze.include('muze.test.js', 'muze.test').onload(function() { + muze.test.run(); + }); + + // this will load muze.test.js, even if muze.test is already available + // if muze.test.js uses the muze.namespace() method correctly, it + // can then extend muze.test + muze.include('muze.test.js').onload(...); + + // this will load the script if the url isn't already loaded + muze.include('random.script.js').onload(function() { + // script is available but is not registered with a namespace + }) + + mixed load(string url, bool waitforme, bool cached) + This method allows you to easily do ajax calls. If 'waitforme' is true, + the ajax call is done synchronously, and load will return the responseText. + Otherwise the call is done asynchronously, and load will return an onload + handler object, just like include, only in this case the function you + specify in onload will be called with one argument, namely the responseText. + If you set 'cached' to true, the url won't be extended with a timestamp, + allowing the browser to cache the response. + examples: + var response = muze.load('ajax.call.html', true); + + muze.load('ajax.call.html') + .onload(function(response) { + myDiv.innerHTML = response; + }) + .ontimeout( 1000, function() { + myDiv.innerHTML = 'timed out'; + this.clear(); + } ); + + object loader(object) + This method allows you to easily implement your own loader handler, with onload and + ontimeout methods. If you pass an object to loader, the onload handler will be called + with that object defined as this. The ontimeout handler won't, it will allways use the loader as this. + You must keep an internal reference to the loader object and call loader.loaded() manually + to trigger the onload. Any arguments passed to loaded() will be passed on to an onload handler + set throught loader.onload. + If a timeout handler is set through loader.ontimeout(timer, method) than it will be called if + the loader.loaded() method isn't called before the timeout. + example: + function myAjaxyThing() { + var loader = muze.loader(); + // do some stuff + mything.onload = function() { + loader.loaded(response); + } + return loader; + } + methods: + onload(callback) + ontimeout(timer, callback) + loaded() + clear() +*/ + +var muze = this.muze = {}; +muze.global = this; +muze.url = (function() { + var scripts = document.getElementsByTagName('script'); + var index = scripts.length - 1; + var urlHelper = document.createElement('a'); + urlHelper.href = scripts[index].src; + return urlHelper; +})(); + +(function() { + + /* private methods */ + + function _getHTTPObject(cors) { //FIXME: check if rearranged thing work + var xmlhttp = null; + if (typeof XMLHttpRequest == 'undefined') { + if (typeof ActiveXObject != 'undefined') { + try { + xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); + } catch (e) { + try { + xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); + } catch (E) { + xmlhttp = null; + } + } + } + } else { + try { + if ( cors && typeof XDomainRequest != 'undefined' ) { + xmlhttp = new XDomainRequest(); + } else { + xmlhttp = new XMLHttpRequest(); + } + } catch (e) { + xmlhttp = null; + } + } + return xmlhttp; + } + + function _namespaceWalk( module, handler ) { + var rest = module.replace(/^\s+|\s+$/g, ''); //trim + var name = ''; + var temp = muze.global; + var i = rest.indexOf( '.' ); + while ( i != -1 ) { + name = rest.substring( 0, i ); + if ( !temp[name]) { + temp = handler(temp, name); + if (!temp) { + return temp; + } + } + temp = temp[name]; + rest = rest.substring( i + 1 ); + i = rest.indexOf( '.' ); + } + if ( rest ) { + if ( !temp[rest] ) { + temp = handler(temp, rest); + if (!temp) { + return temp; + } + } + temp = temp[rest]; + } + return temp; + } + + function _namespaceSet( module, object ) { + var rest = module.replace(/^\s+|\s+$/g, ''); //trim + var name = ''; + var temp = muze.global; + var i = rest.indexOf( '.' ); + while ( i != -1 ) { + name = rest.substring( 0, i ); + if ( !temp[name]) { + temp = handler(temp, name); + if (!temp) { + return temp; + } + } + temp = temp[name]; + rest = rest.substring( i + 1 ); + i = rest.indexOf( '.' ); + } + if ( rest ) { + temp[rest] = object; + } + } + + /* private variables */ + + var included = {}; + var registered = {}; + var dependencies= []; + + muze.namespace = function( module, implementation ) { + var moduleInstance = _namespaceWalk( module, function(ob, name) { + ob[name] = {}; + return ob; + }); + registered[module]=true; + if (typeof implementation == 'function') { + var result = implementation.call(moduleInstance); + if ( result ) { + _namespaceSet( module, result ); + moduleInstance = result; + } + } + // call other continuations that depend on this module + // only after remaining code in this module has had a chance to run + // not all modules use an implementation callback method + for ( var p in moduleInstance ) { + if ( moduleInstance.hasOwnProperty(p) ) { + // module is initialized + checkDependencies(); + return moduleInstance; + } + } + // module not yet initialized, so give it time. + muze.global.setTimeout(function() { + checkDependencies(); + }, 1); + return moduleInstance; + }; + + function _parseModuleInfo( moduleInfo ) { + var pipePos = moduleInfo.indexOf('|'); + var slashPos = moduleInfo.indexOf('/'); + var module, url; + + if ( pipePos != -1 ) { + module = moduleInfo.substring(0, pipePos); + url = moduleInfo.substring(pipePos+1); + } else if ( slashPos != -1 ) { + module = false; + url = moduleInfo; + } else { + module = moduleInfo; + url = document.createElement('a'); + url.href = muze.url.href; + if ( url.search.match('muze') ) { + url.search = '?'+module; + } else if ( url.pathname.match('muze.js') ) { + url.pathname = url.pathname.replace('muze.js', module.replace('.','/')+'.js' ); + } else { + url.href = ''; + } + url = url.href; + } + return { + module: module, + url: url + }; + } + + function _parseModulesList( modules ) { + // the continuation is a function which is only run if all requirements are met + var modulesList; + if (typeof modules == 'string') { + modulesList = (/,/.test(modules)) ? modules.split(',') : [ modules ]; + } else if (typeof modules.length != 'undefined') { + modulesList = modules; + } else { + throw('Incorrect argument 1 (required modules): '+modules); + } + var scriptsToCheck = []; + for ( var i=0; i=0; i-- ) { + if ( dependencies[i].continuation ) { + for ( var ii=dependencies[i].scriptsToLoad.length-1; ii>=0; ii-- ) { + var module = dependencies[i].scriptsToLoad[ii].module; + if ( registered[module] ) { + dependencies[i].scriptsToLoad.splice(ii, 1); + // delete dependencies[i].scriptsToLoad[ii]; + } + } + if ( dependencies[i].scriptsToLoad.length === 0 ) { + var continuation = dependencies[i].continuation; + dependencies[i].continuation = false; + continuation.call(muze.global); + } + } + } + } + + muze.require = function( modules, continuation ) { + modules = _parseModulesList( modules ); + var scriptsToLoad = []; + var moduleInstance; + + var moduleWalker = function(module) { + if (module.module) { + moduleInstance = _namespaceWalk( module.module, function(ob, name) { + if (typeof continuation == 'undefined' || !module.url ) { + throw 'namespace ' + name + ' not found '; + } else { + scriptsToLoad[ scriptsToLoad.length ] = module; + } + }); + } else if ( !included[ module.url ] ) { + if (typeof continuation == 'undefined' || !module.url ) { + throw 'namespace ' + name + ' not found '; + } else { + scriptsToLoad[ scriptsToLoad.length ] = module; + } + } + return moduleInstance; + }; + + var result; + for (var i=0; i 1){ + for(var i=1, len=parts.length; i < len; i++){ + camel += parts[i].charAt(0).toUpperCase() + parts[i].substring(1); + } + } + //Cache it and return it + cache[str] = camel; + } + } + return cache[str]; + }; + })(); + + //First argument is the style to be tested (opacity, minHeight, etc.) + //The second argument is an optional argument to test support for a style value (position: fixed) + return function(style, value){ + //get the key that will be used for caching + var key = getKey(style, value); + if(key in cache){ + //If the key exists within the cache, return the held value + return cache[key]; + }else{ + //Default to false, support must be proven + var supported = false; + //Camel-case the style for use against raw objects + var camel = toCamelCase(style); + //If the native runtime style exists than proceed (IE) + if(el.runtimeStyle){ + //We use a try-catch block because IE will throw an error on unsupported style values + try{ + //We set the style against the elements style object and if the value is not supplied we + //default to an empty string (works against all styles) + el.style[camel] = value || ""; + //Unsupported styles and style values will always return undefined + supported = !Env.isUndefined(el.runtimeStyle[camel]); + }catch(e){} + }else{ + //Must be a standards compliant browser (FF, Opera, Safari, Chrome, etc.) + //Set the elements style, if value is not supplied we default to inherit which is supported + //by all standards compliant browsers + el.style[style] = value || "inherit"; + //Get the view for a little short form + var view = document.defaultView; + //If the browser supportes document.defaultView and its getComputedStyle method than proceed + //Currently there is not fallback for this + if(view && view.getComputedStyle){ + //Get the computed style + var cs = view.getComputedStyle(el, "")[camel]; + //Unsupported styles always return undefined + supported = !Env.isUndefined(cs); + //If a value was supplied than we have to test it separately because the getComputedStyle method will often parse the value into + //something much harder to detect i.e. (color: 1px returns rgb(0,0,0)) + if(value){ + //We create a new div as the innerHTML within our main element + //Any hyphenated styles must be supplied in that fashion for these tests(vertical-align not verticalAlign) + //a little syntastic sugar too + el.innerHTML = '
'; + //Unsupported style values will always return an empty string + supported = supported && el.firstChild.style[camel] !== ""; + } + } + } + //Cache the value and return it + cache[key] = supported; + return cache[key]; + } + }; + })(); + + //Does the browser support cookies + //Env.support.cookies = !!navigator.cookieEnabled && navigator.cookieEnabled; + //The above check generates a security violation in IE when used inside a Modal Dialog, hence the adjusted check below + Env.support.cookies = false; + try { + document.cookie="muzeEnvTestCookie=1; path=/"; + Env.support.cookies = (document.cookie.indexOf("muzeEnvTestCookie") != -1) ? true : false; + } catch(e) { + // ipad security error weirdness + } + + //Is the browser in standards mode or quirks mode + Env.support.strict = !!document.compatMode && document.compatMode == "CSS1Compat"; + //Is the current page hosted on a secure server + Env.support.secure = !!window.location.href && window.location.href.toLowerCase().indexOf("https") === 0; + //Does the browser support canvas + Env.support.canvas = !!document.createElement("canvas").getContext; + //Does the browser support SVG + Env.support.svg = !!(document.createElementNS && document.createElementNS('http://www.w3.org/2000/svg', 'svg').width); + //Does the browser XPath queries on the HTML/XHTML document + Env.support.xpath = !!document.evaluate; + + //Does the browser support VML (vector graphics) + //Inspired by Google Maps (http://maps.google.com/intl/en_ALL/mapfiles/73/maps2.api/main.js) + Env.support.vml = (function(){ + //Create an element to act as a container + var el = document.createElement('div'); + //Try adding a VML object via element's innerHTML + el.innerHTML = ''; + //Get the VML object + var vml = el.firstChild; + //Declare VML bevaviour + vml.style.behavior = "url(#default#VML)"; + //If the VML object exists and the attribute is an object than VML is supported + return vml && Env.isObject(vml.adj); + })(); + + //Does the browser support flash + Env.support.flash = (function(){ + //Check for ActiveX first because some versions of IE support navigator.plugins, just not the same as other browsers + if(window.ActiveXObject){ + try{ + //try to create a flash instance + new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); + return true; + }catch(e){} + //If the try-catch fails, return false + return false; + }else if(navigator.plugins){ + //Loop through all the plugins + for(var i=0, length = navigator.plugins.length; i < length; i++){ + //test to see if any plugin names contain the word flash, if so it must support it - return true + if((/flash/gi).test(navigator.plugins[i].name)){ + return true; + } + } + //return false if no plugins match + return false; + } + //Return false if ActiveX and nagivator.plugins are not supported + return false; + })(); + + //Can the browser convert array-like objects (nodelist, arguments) to an array using native methods + Env.support.nativeArrayConversion = (function(){ + try{ + //get the child nodes of the html element + var children = document.documentElement.childNodes; + //hijack the slice and use it for the conversion - make sure the result is an array + return Env.isArray(Array.prototype.slice.call(children)); + }catch(e){} + //return false if the try-catch block fails + return false; + })(); + + //Does the string replace method support functions as a second argument (Safari 2.0.2) + Env.support.stringReplaceFunction = (function(){ + var str = ""; + if(str.replace){ + //If the string equals success as returned by the function, then the replace method of strings must + //accept functions as second parameters, otherwise it is false + return str.replace(str, function(){return 'success';}) === 'success'; + }else{ + //Return false if the strings to not support a replace method + return false; + } + })(); + + //Does the browser allow textnode appending, and eval the text + Env.support.scriptEval = (function(){ + //Create a script element + var script = document.createElement("script"); + try{ + //Try to append a textnode that will hopefully be evaluated and create a new property on the Env namespace + script.appendChild(document.createTextNode("muze.env.test = true;")); + }catch(e){ + //If an exception is caught, it must be IE and not supported + return false; + } + //Append the script to the root element () to allow an eval + document.documentElement.appendChild(script); + //Quickly remove the script + document.documentElement.removeChild(script); + //We are done with the script so we null it out to save memory + script = null; + //Was the eval successful? Does the property exist + var supported = !!Env.test; + //Delete the property + delete Env.test; + //Return the supported value + return supported; + })(); + + //Does the browser allow DOM manipulation of tables via innerHTML + Env.bugs.tableInnerHTML = (function(){ + //Create the table + var el = document.createElement("table"); + try{ + //Use a try catch block because IE throws errors + //Append a row to the innerHTML of the table + el.innerHTML = "test"; + //Query the table for a td element to check if the insert worked + return el.getElementsByTagName('td').length === 0; + }catch(e){} + //The try-catch block fails, there must be a bug + return true; + })(); + + //Does the browser allow DOM manipulation of selects via innerHTML + Env.bugs.selectInnerHTML = (function(){ + //Create the select + var el = document.createElement("select"); + //Try appending to the innerHTML + el.innerHTML = ''; + if(el.options && el.options[0]){ + //Does the option exist within the select, if not there is a bug + return el.options[0].nodeName.toUpperCase() !== "OPTION"; + }else{ + //If no options are found, the insert must have failed + return true; + } + })(); + + Env.bugs.getElementById = (function(){ + //Create a container for everything + var el = document.createElement('div'); + //Create a unique ID for the input we are about to create + var id = "input" + new Date().getTime(); + //Add an input to test a bug with getElementById + el.innerHTML = ''; + //Get the head element + var head = document.getElementsByTagName('head')[0]; + //append the container element to the head + head.appendChild(el); + //Does getElementById return elements with the same defined name + var supported = !Env.isNull(document.getElementById(id)); + //remove the el from the head + head.removeChild(el); + //we are done with the test, null out the element and save memory + el = null; + //return the supported value + return supported; + })(); + + //Create an element to perform various DOM and CSS related capabilities tests against + var el = document.createElement("div"); + //Add an attribute which will later be changed to trigger a mutation event + el.id = new Date().getTime() + Math.random(); + //Quickly create a child node that will be used to test various CSS styles + el.innerHTML = '
'; + //Add a comment node to the element + el.appendChild(document.createComment('test')); + + //Does the browser support cssFloat as the proxy for CSS float + Env.support.cssFloat = "cssFloat" in el.style; + //Does the browser support CSS transforms + Env.support.cssTransform = "WebkitTransform" in el.style || "MozTransform" in el.style; + + + //Change the id to trigger the DOMAttrModified and DOMSubtreeModified (except in Safari) event if it is supported + el.id = new Date().getTime() + Math.random(); + //Create a form element to test a bug in IE + //Alternatively, appending a new element will trigger the DOMSubtreeModified event is it is supported (Safari); + var form = el.appendChild(document.createElement('form')); + //Add an input to test a bug with setting the name attribute + form.innerHTML = ''; + //Get the input element for testing + var input = el.getElementsByTagName('input')[0]; + //try to set the name of the input via setAttribute + input.setAttribute('name', 'test'); + + + //Does getElementsByTagName return comment nodes (IE) + Env.bugs.getElementsByTagName = (function(){ + //Get all descending elements of the root element via "*" + var elements = el.getElementsByTagName('*'); + //Loop the elements and look for comment nodes + for(var i=0, length = elements.length; i < length; i++){ + if(elements[i].nodeType == document.COMMENT_NODE){ + //If a comment node is found, its a bug + return true; + } + } + //If the loop completes without finding any comment nodes then no bug + return false; + })(); + + Env.bugs.querySelectorAll = (function(){ + //Does this browser support querySelectorAll + if(el.querySelectorAll){ + //Safari sometimes doesn't respond to case sensitivity + return el.querySelectorAll(".TEST").length === 0; + }else{ + //If querySelectorAll isn't supported return false for no bug + return false; + } + })(); + + Env.bugs.getElementsByClassName = (function(){ + //Does this browser support getElementsByClassName + if(el.getElementsByClassName){ + //Opera 9.6 doesn't find elements by their second class name + return el.getElementsByClassName("unique").length === 0; + }else{ + //if getElementsByClassName isn't supported return false for no bug + return false; + } + })(); + + Env.bugs.cachedClassNames = (function(){ + //Does this browser support getElementsByClassName + if(el.getElementsByClassName){ + //change the class name of the last element to test + el.firstChild.className = "random"; + //Safari 3.2 caches class names + return el.getElementsByClassName("random").length === 1; + }else{ + //If getElementsByClassName isn't supported return false for no bug + return false; + } + })(); + + + //These tests can only be determined once they are included in the DOM and rendered + //For now we just set them to false, they must be proven + + Env.support.boxModel = false; + Env.bugs.setNameAttribute = false; + + //Env is not ready until a few tests involving insertion into the DOM are performed + Env.ready = false; + //Certain properties need to be added to the DOM and rendered to be tested accurately + //This method can be called manually in your scripts once the DOM has finished loading or it can be left up to the automatic polling for DOM completion + //The option is available because in some cases where the DOM is small (low bytes and less to load time), the poll will not trigger the method and complete + //the tests until, in some cases, after window.onload is fired, so we provide this method to manually invoke the method as a last resort in such a case + Env.onReady = function(){ + if(!Env.ready){ + //Query the DOM for the body + var body = document.getElementsByTagName('body')[0]; + //If the body and appendChild and removeChild methods are recognized, than proceed + if(body && body.appendChild && body.removeChild){ + //append the element to the DOM + body.appendChild(el); + //Is the box model support + Env.support.boxModel = el.firstChild.offsetWidth === 4; + //Query for the input based on the name to see if setAttribute on the name worked + Env.bugs.setNameAttribute = form.elements ? Env.isUndefined(form.elements.test) : false; + //Remove the element from the dom + body.removeChild(el); + //clear the interval + clearTimeout(poll); + //make the elements and the interval null to save memory + el = poll = null; + //All tests are done and Env is ready to be used + Env.ready = true; + } + } + }; + + //poll Env.ready + var poll = setTimeout(Env.onReady, 1); + + //Helper functions purely for testing support of the mutation events + function handler(e){ + Env.support[e.type] = true; + removeEvent(e.target, e.type, arguments.callee); + } + + function addEvent(el, type, fn){ + if(el.addEventListener){ + el.addEventListener(type, fn, false); + }else if(el.attachEvent){ + el.attachEvent("on" + type, fn); + }else{ + el["on"+type] = fn; + } + } + + function removeEvent(el, type, fn){ + if(el.removeEventListener){ + el.removeEventListener(type, fn, false); + }else if(el.detachEvent){ + el.detachEvent('on' + type, fn); + }else{ + el["on"+type] = null; + delete el["on"+type]; + } + } + return Env; +})(); +/* + FIXME: event add/remove via array index laten werken, geen directe functie pointers, alleen indexes in handles array + op die manier krijg je geen circulaire referenties via closures + + javascript events library for muze modules + ---------------------------------------- + + object get(object evt) + This method returns the event object cross browser. You only need this if you don't + use muze.event.attach() to attach your event handler, since it already does this for + you. + + examples: + function myEventHandler(evt) { + evt = muze.event.get(evt); + .... + } + + bool cancel(object evt) + This method cancels the event, stops propagation, prevents default, in short it kills + the event dead. Cross browser. It also returns false, so you may assign it directly + to events you want killed. + + examples: + function myEventHandler(evt) { + ... + if (killEvent == true) { + return muze.event.cancel(evt); + } + ... + } + + document.body.onMouseDown = muze.event.cancel; + + + bool pass(object evt) + This method returns true. So you may use it to make explicit that you don't cancel an event. + + mixed attach(object obj, string event, object handler, bool useCapture) + This method attaches an event handler to an event on an object. It makes sure the event + gets cleaned on unload, so you won't get memory leaks. It makes sure that 'this' points + to the object the event is defined on. Important: Returns the handler required for detaching + the event. This is not the same handler as passed to the attach function! + arguments: + obj DOM object on which to catch the event + event name of the event to catch, e.g. 'load', 'click', etc. + handler function that handles the event. + useCapture Mozilla's useCapture option to addEventListener + examples: + + ... + var detachHandler = muze.event.attach(document.body, 'load', function() { alert(this.innerHTML); }); + ... + + bool detach(object obj, string event, object, handler, bool useCapture) + This method detaches an event handler from an event on an object. + arguments: + obj DOM objeect on which the event handler was attached + event name of the event to remove, e.g. 'load', 'click', etc. + handler handler to detach. + useCapture Mozilla's useCapture option to addEventListener + examples: + + ... + var detachHandler = muze.event.attach(document.body, 'click', function() { alert('we have a click'); }); + ... + muze.event.detach(document.body, 'click', detachHandler); + ... + + + void clean() + This method cleans/removes all attached event handlers. It is automatically run on unload of document, if needed. + + TODO: + custom events met trigger en bind achtige functie, misschien in eigen namespace + +*/ + +muze.require('muze.env', function() { + +muze.namespace('muze.event', function() { + + /* private methods */ + + /* private variables */ + var event = this; + + + var evt; + if (muze.env.isHostMethod(document, 'createEvent')) { + event.create = function( name, maskEvt, win ) { + if (!win) { + win = muze.global; + } + var type = 'HTMLEvents'; + var init = function(evt, mask) { + evt.initEvent(name, mask ? mask.bubbles : true, mask ? mask.cancelable : true); + }; + switch (name) { + case 'click' : + case 'dblclick': + case 'mousedown': + case 'mousemove': + case 'mouseout': + case 'mouseover': + case 'mouseup': + case 'mousewheel': + case 'contextmenu': + case 'DOMMouseScroll': + case 'drag': + case 'dragdrop': + case 'dragend': + case 'dragenter': + case 'dragover': + case 'dragexit': + case 'dragleave': + case 'dragstart': + case 'drop': + type = 'MouseEvents'; + init = function(evt, mask) { + if (mask) { + evt.initMouseEvent(name, mask.bubbles, mask.cancelable, mask.view, mask.detail, mask.screenX, mask.screenY, mask.clientX, mask.clientY, mask.ctrlKey, mask.altKey, mask.shiftKey, mask.metaKey, mask.button, mask.relatedTarget); + } else { + evt.initMouseEvent(name, true, true, win, 0, 0, 0, 0, 0, false, false, false, false, 0, null); + } + }; + break; + case 'DOMFocusIn': + case 'DOMFocusOut': + case 'DOMActivate': + type = 'UIEvents'; + init = function(evt, mask) { + if (mask) { + evt.initUIEvent(name, mask.bubbles, mask.cancelable, mask.view, mask.detail); + } else { + evt.initUIEvent(name, true, true, win, 1); + } + }; + break; + case 'keypress': + case 'keydown': + case 'keyup': + type = 'KeyboardEvents'; + evt = win.document.createEvent( type ); + if (muze.env.isHostMethod(evt, 'initKeyboardEvent')) { + init = function(evt, mask) { + if (mask) { + var modifiers = ''; + if (mask.altKey) { + modifiers += 'Alt '; + } + if (mask.ctrlKey) { + modifiers += 'Control '; + } + if (mask.shiftKey) { + modifiers += 'Shift '; + } + if (mask.metaKey) { + modifiers += 'Meta '; + } + evt.initKeyboardEvent(name, !!mask.bubbles, !!mask.cancelable, mask.view, mask.keyIdentifier, mask.keyLocation, modifiers); + } else { + evt.initKeyboardEvent(name, true, true, win, '', 0, ''); + } + }; + } else if (muze.env.isHostMethod(evt, 'initKeyEvent')) { + init = function(evt, mask) { + if (mask) { + evt.initKeyEvent(name, !!mask.bubbles, !!mask.cancelable, mask.view, mask.ctrlKey, mask.altKey, mask.shiftKey, mask.metaKey, mask.keyCode, mask.charCode); + } else { + evt.initKeyEvent(name, true, true, win, false, false, false, false, 0, 0); + } + }; + } + break; + case 'message': + type = 'MessageEvent'; + init = function(evt, mask) { + if (mask) { + evt.initMessageEvent(name, mask.bubbles, mask.cancelable, mask.data, mask.origin, mask.lastEventId, mask.source, mask.ports); + } else { + evt.initMessageEvent(name, true, true, '', '', '', '', null); + } + }; + break; + } + evt = win.document.createEvent(type); + init(evt, maskEvt); + return evt; + }; + } else if (muze.env.isHostMethod(document, 'createEventObject') ) { + event.create = function( name, evt, win ) { + if (!win) { + win = muze.global; + } + evt = win.document.createEventObject(name, evt); + return evt; + }; + } else { + event.create = false; + } + + if (muze.env.isHostMethod(document, 'dispatchEvent')) { + event.fire = function(el, name, evt) { + var win = muze.global; + if (el.ownerDocument && el.ownerDocument.defaultView) { + win = el.ownerDocument.defaultView; + } else if (el.ownerDocument && el.ownerDocument.parentWindow) { + win = el.ownerDocument.parentWindow; + } + evt = muze.event.create(name, evt, win); + el.dispatchEvent(evt); + }; + } else if (muze.env.isHostMethod(document, 'fireEvent')) { + event.fire = function(el, name, evt) { + if (name.substr(0,3)!=='DOM') { + name = 'on'+name; + } + el.fireEvent(name, evt); + }; + } else { + event.fire = false; + } + + event.get = function(evt, win) { + if ( !win ) { + win = muze.global; + } + if ( !evt ) { + evt = win.event; + } + return evt; + }; + + event.cancel = function(evt) { + event.preventDefault(evt); + event.stopPropagation(evt); + return false; + }; + + event.stopPropagation = function(evt) { + evt = event.get(evt); + if (muze.env.isHostMethod(evt, 'stopPropagation')) { + evt.stopPropagation(); + } else { + evt.cancelBubble = true; + } + }; + + event.preventDefault = function(evt) { + evt = event.get(evt); + if (muze.env.isHostMethod(evt, 'preventDefault')) { + evt.preventDefault(); + } else { + evt.returnValue=false; + } + }; + + event.pass = function(evt) { + return true; + }; + + event.target = function(evt) { + evt = event.get(evt); + if (muze.env.isHostObject(evt, 'target') ) { + return evt.target; + } else if (muze.env.isHostObject(evt, 'srcElement') ) { + return evt.srcElement; + } else { + return null; + } + }; + + event.getCharCode = function(evt) { + evt = event.get(evt); + if (evt.type=='keypress' || evt.type=='onkeypress') { + return (evt.charCode ? evt.charCode : ((evt.keyCode) ? evt.keyCode : evt.which)); + } else { + return false; + } + }; + + var docEl = document.documentElement; + var listeners = []; + + var getWrapper = function( id ) { + return function(evt) { + var win; + var o = listeners[id].el; + if (o.ownerDocument) { + win = o.ownerDocument.defaultView ? o.ownerDocument.defaultView : o.ownerDocument.parentWindow; + } else if (o.defaultView) { + win = o.defaultView; + } else if (o.parentWindow) { + win = o.parentWindow; + } else if (o.document) { + win = o; + } else { + win = muze.global; + } + evt = event.get(evt, win); + var f = listeners[id].listener; + f.call(o, evt); + }; + }; + + if (muze.env.isHostMethod(docEl, 'addEventListener')) { + event.attach = function(o, sEvent, fListener, useCapture) { + if ( !muze.env.isFunction(fListener) ) { + throw { + el : o, + message : 'listener is not a method', + event : sEvent + }; + } + var listenerID = listeners.push( { + el : o, + listener : fListener + } ) - 1; + var wrapped = getWrapper(listenerID); + o.addEventListener(sEvent, wrapped, !!useCapture); + return wrapped; + }; + } else if (muze.env.isHostMethod(docEl, 'attachEvent')) { + event.attach = function(o, sEvent, fListener, useCapture) { + if (!muze.env.isFunction(fListener)) { + throw { + el : o, + message : 'listener is not a method', + event : sEvent + }; + } + var listenerID = listeners.push( { + el : o, + listener : fListener + } ) - 1; + if (sEvent.substr(0,3)!='DOM') { + sEvent = 'on' + sEvent; + } + var wrapped = getWrapper(listenerID); + o.attachEvent(sEvent, wrapped); + return wrapped; + }; + } else { + event.attach = false; + } + + + if (muze.env.isHostMethod(docEl, 'removeEventListener') ) { + event.detach = function(o, sEvent, handle, useCapture) { + if (o && sEvent) { + var result = o.removeEventListener(sEvent, handle, !!useCapture); + return result; + } else { + return false; + } + }; + } else if (muze.env.isHostMethod(docEl, 'detachEvent') ) { + event.detach = function(o, sEvent, handle, useCapture) { + if (o && sEvent) { + var result = o.detachEvent('on'+sEvent, handle); + return result; + } else { + return false; + } + }; + } else { + event.detach = false; + } + + event.clean = function() { }; + +}); + +}); + +muze.namespace('muze.html', function() { + var getType = function(obj) { + return ({}).toString.call(obj).match(/\s([a-z|A-Z]+)/)[1].toLowerCase(); + }; + + var setAttr = function(el, name, value) { + if ( name == 'style' ) { + for (var ii in value ) { + el.style[ii] = value[ii]; + } + } else { + switch(name) { + case 'class': + name = 'className'; + break; + case 'for': + name = 'htmlFor'; + break; + } + el[ name ] = value; + } + }; + + this.el = function(tagName) { //, attributes, children) { + var i; + var el = muze.global.document.createElement(tagName); + var next = 1; + var attributes = arguments[1]; + if (attributes && getType(attributes)=='object') { + next = 2; + try { + for (i in attributes ) { + setAttr(el, i, attributes[i]); + } + } catch(e) { + if ( /input/i.test(tagName) ) { + var elString = '<'+tagName; + for ( i in attributes ) { + if ( getType(attributes[i])=='string' ) { + elString += ' '+i+'="'+escape(attributes[i])+'"'; + } + } + elString += '>'; + el = muze.global.document.createElement(elString); + for ( i in attributes ) { + if ( getType(attributes[i])!='string' ) { + setAttr(el, i, attributes[i]); + } + } + } + } + } + for (i=next, l=arguments.length; i 0 ) { + return useWin.getSelection().getRangeAt(0); + } else { + return useWin.document.createRange(); + } + } else { + return useWin.document.selection.createRange(); + } + }, + backwards : function( useWin ) { + if ( !useWin ) { + useWin = win; + } + if (w3c) { + var sel = useWin.getSelection(); + if (!sel.anchorNode) { + return false; + } + var position = sel.anchorNode.compareDocumentPosition(sel.focusNode); + if (position === 0) { + return (sel.anchorOffset > sel.focusOffset); + } else if (position == 4) { // Node.DOCUMENT_POSITION_PRECEDING) { + return false; + } else { + return true; + } + } else { + // FIXME: Old IE compat goes here; + return false; + } + }, + collapse : function(range, left) { + if (left!==false) { + left=true; + } + range.collapse(left); + return range; + }, + + clone : function(range) { + if (w3c) { + return range.cloneRange(); + } else { + return range.duplicate(); + } + }, + + select : function(range) { + if( w3c ) { + var node = self.getNode(range); + if (node && node.ownerDocument) { + var sel = node.ownerDocument.defaultView.getSelection(); + sel.removeAllRanges(); + sel.addRange(range); + } + } else { + try { + range.select(); // IE is sometimes buggy and likes to barf on you + } catch( e ) { } + } + return range; + }, + + selectNode : function(range, el, select) { + if( w3c ) { + range.selectNodeContents(el); + } else { + range.moveToElementText(el); + } + if( select ) { + self.select(range); + } + return range; + }, + + selectRange : function(range, left, right, select) { + if( w3c ) { + range.setStart(left.startContainer, left.startOffset); + if(!right) { + range.setEnd(left.endContainer, left.endOffset); + } else { + range.setEnd(right.startContainer, right.startOffset); + } + } else { + range.setEndPoint('StartToStart', left); + if (!right) { + range.setEndPoint('EndToEnd', left); + } else { + range.setEndPoint('EndToStart', right); + } + } + if( select ) { + self.select(range); + } + return range; + }, + + parentNode : function(range) { + if( w3c ) { + var parent = false; + if( range.collapsed || range.startContainer == range.endContainer ) { + parent = range.startContainer; + } else { + parent = range.commonAncestorContainer; + } + while( parent.nodeType == document.TEXT_NODE ) { // text node + parent = parent.parentNode; + } + return parent; + } else { + return range.item ? range.item(0) : range.parentElement(); + } + }, + + getNode : function(range) { + var node; + if( w3c ) { + node = range.commonAncestorContainer; + if( !range.collapsed ) { + /* + | | + | Beide textnodes zijn optioneel, die hoeven er niet te staan. + */ + + if( range.startContainer == range.endContainer && range.startOffset - range.endOffset < 2 && range.startContainer.hasChildNodes() ) { + // Case 1: geen tekstnodes. + // start en eind punt van selectie zitten in dezelfde node en de node heeft kinderen - dus geen text node - en de offset verschillen + // precies 1 - dus er is exact 1 node geselecteerd. + node = range.startContainer.childNodes[range.startOffset]; // image achtige control selections. + } else if ( range.startContainer.nodeType == document.TEXT_NODE && range.startOffset == range.startContainer.data.length && + range.endContainer.nodeType != document.TEXT_NODE && range.endContainer == range.startContainer.parentNode ) + { + // Case 2: tekstnode er voor, niet er achter. + // start punt zit in een tekst node maar wel helemaal aan het eind. eindpunt zit in dezelfde container waar de textnode ook in zit. + node = range.endContainer.childNodes[ range.endOffset - 1 ]; + } else if ( range.endContainer.nodeType == document.TEXT_NODE && range.endOffset === 0 && + range.startContainer.nodeType != document.TEXT_NODE && range.startContainer == range.endContainer.parentNode ) + { + // Case 3: tekstnode er achter, niet er voor; + // Eindpunt zit in een textnode helemaal aan het begin. Startpunt zit in dezelfde container waar de eindpunt-textnode ook in zit + node = range.startContainer.childNodes[ range.startOffset ]; + } else if ( range.startContainer.nodeType == document.TEXT_NODE && range.endContainer.nodeType == document.TEXT_NODE && + range.startOffset == range.startContainer.data.length && range.endOffset === 0 && + range.startContainer.nextSibling == range.endContainer.previousSibling ) + { + // Case 4: tekstnode voor en achter + // start zit in een tekstnode helemaal aan het eind. eind zit in een tekstnode helemaal aan het begin. + node = range.startContainer.nextSibling; + } else if( range.startContainer == range.endContainer ) { + // Case 5: bijv. 1 tekstnode met geselecteerde tekst - hierna wordt dan de parentNode als node gezet + node = range.startContainer; + } + } else { + if( range.startContainer == range.endContainer && range.startOffset - range.endOffset < 2 && range.startContainer.hasChildNodes() ) { + // Case 1: geen tekstnodes. + // start en eind punt van selectie zitten in dezelfde node en de node heeft kinderen - dus geen text node - en de offset verschillen + // precies 1 - dus er is exact 1 node geselecteerd. + if (range.startContainer.childNodes[range.startOffset-1]) { + node = range.startContainer.childNodes[range.startOffset-1]; // image achtige control selections. cursor is na de image dus pak de node voor de cursor + } else { + node = range.startContainer.childNodes[range.startOffset]; // er is geen node voor de cursor, dus pak dan maar die er na staat. + } + } + } + + while( node && (node.nodeType == document.TEXT_NODE || node.nodeType == document.DOCUMENT_TYPE_NODE)) { + node = node.parentNode; + } + return node; + } else { + node = range.item ? range.item(0) : range.parentElement(); + while (node && (node.nodeType == document.TEXT_NODE || node.nodeType == document.DOCUMENT_TYPE_NODE)) { + node = node.parentNode; + } + return node; + } + }, + + isEmpty : function(range) { + return self.getHTMLText(range) === ''; + }, + + getHTMLText : function(range) { + if( w3c ) { + var frag = range.cloneContents(); + var div = range.startContainer.ownerDocument.createElement('div'); + div.appendChild(frag); + var result = div.innerHTML; + div = null; + return result; + } else { + if( range.item ) { + var control = range.item(0); + var textrange = control.ownerDocument.body.createTextRange(); + textrange.moveToElementText(control); + return textrange.htmlText; + } else { + return range.htmlText; + } + } + }, + + setHTMLText : function(range, htmltext) { + if( w3c ) { + var div = range.startContainer.ownerDocument.createElement('div'); + div.innerHTML = htmltext; + var frag = range.startContainer.ownerDocument.createDocumentFragment(); + for (var i=0; i < div.childNodes.length; i++) { + var node = div.childNodes[i].cloneNode(true); + frag.appendChild(node); + } + div = null; + range = self.replace(range, frag); + } else { + if( range.item ) { // control range + var control = range.item(0); + var textrange = control.ownerDocument.body.createTextRange(); + textrange.moveToElementText(control); + range.execCommand('delete', false); + range = textrange; + } + range.pasteHTML(htmltext); + } + return range; + }, + + replace : function(range, el) { + if( w3c ) { + range.deleteContents(); + range.insertNode(el); + // FIXME: definately betere check gebruiken waar de cursor moet komen, gaat mis als je over meer dan 1 textnode een selectie hebt + if( range.startContainer && range.startContainer.nextSibling ) { // ie behaviour simulatie + range.selectNode(range.startContainer.nextSibling); + } + range.collapse(false); + } else { + self.setHTMLText(range, el.outerHTML); + } + return range; + } + + }; + return self; + + })(); + + return dom; +})(simply.dom || {}); + + +simply.util = ( function(util) { + util.base64 = ( function() { + + /** + * + * Base64 encode / decode + * http://www.webtoolkit.info/ + * + **/ + + var base64 = { + + // private property + _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", + + // public method for encoding + encode : function (input) { + var output = ""; + var chr1, chr2, chr3, enc1, enc2, enc3, enc4; + var i = 0; + + input = base64._utf8_encode(input); + + while (i < input.length) { + + chr1 = input.charCodeAt(i++); + chr2 = input.charCodeAt(i++); + chr3 = input.charCodeAt(i++); + + enc1 = chr1 >> 2; + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); + enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); + enc4 = chr3 & 63; + + if (isNaN(chr2)) { + enc3 = enc4 = 64; + } else if (isNaN(chr3)) { + enc4 = 64; + } + + output = output + + this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) + + this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4); + + } + + return output; + }, + + // public method for decoding + decode : function (input) { + var output = ""; + var chr1, chr2, chr3; + var enc1, enc2, enc3, enc4; + var i = 0; + + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); + + while (i < input.length) { + + enc1 = this._keyStr.indexOf(input.charAt(i++)); + enc2 = this._keyStr.indexOf(input.charAt(i++)); + enc3 = this._keyStr.indexOf(input.charAt(i++)); + enc4 = this._keyStr.indexOf(input.charAt(i++)); + + chr1 = (enc1 << 2) | (enc2 >> 4); + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; + + output = output + String.fromCharCode(chr1); + + if (enc3 != 64) { + output = output + String.fromCharCode(chr2); + } + if (enc4 != 64) { + output = output + String.fromCharCode(chr3); + } + + } + + output = base64._utf8_decode(output); + + return output; + + }, + + // private method for UTF-8 encoding + _utf8_encode : function (string) { + string = string.replace(/\r\n/g,"\n"); + var utftext = ""; + + for (var n = 0; n < string.length; n++) { + + var c = string.charCodeAt(n); + + if (c < 128) { + utftext += String.fromCharCode(c); + } + else if((c > 127) && (c < 2048)) { + utftext += String.fromCharCode((c >> 6) | 192); + utftext += String.fromCharCode((c & 63) | 128); + } + else { + utftext += String.fromCharCode((c >> 12) | 224); + utftext += String.fromCharCode(((c >> 6) & 63) | 128); + utftext += String.fromCharCode((c & 63) | 128); + } + + } + + return utftext; + }, + + // private method for UTF-8 decoding + _utf8_decode : function (utftext) { + var string = ""; + var i = 0; + var c = 0; + var c1 = 0; + var c2 = 0; + + while ( i < utftext.length ) { + + c = utftext.charCodeAt(i); + + if (c < 128) { + string += String.fromCharCode(c); + i++; + } + else if((c > 191) && (c < 224)) { + c2 = utftext.charCodeAt(i+1); + string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); + i += 2; + } + else { + c2 = utftext.charCodeAt(i+1); + c3 = utftext.charCodeAt(i+2); + string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); + i += 3; + } + + } + + return string; + } + }; + + return base64; + })(); + return util; +})(simply.util || {}); + + +simply.editor = ( function(editor) { + editor.selectionchange = (function (undefined) { + + var MAC = /^Mac/.test(navigator.platform); + var MAC_MOVE_KEYS = [65, 66, 69, 70, 78, 80]; // A, B, E, F, P, N from support.apple.com/en-ie/HT201236 + var SELECT_ALL_MODIFIER = MAC ? 'metaKey' : 'ctrlKey'; + var RANGE_PROPS = ['startContainer', 'startOffset', 'endContainer', 'endOffset']; + var HAS_OWN_SELECTION = {INPUT: 1, TEXTAREA: 1}; + + var ranges; + + return { + start: function (doc) { + var d = doc || document; + if (ranges || !hasNativeSupport(d) && (ranges = newWeakMap())) { + if (!ranges.has(d)) { + ranges.set(d, getSelectionRange(d)); + on(d, 'input', onInput); + on(d, 'keydown', onKeyDown); + on(d, 'mousedown', onMouseDown); + on(d, 'mousemove', onMouseMove); + on(d, 'mouseup', onMouseUp); + on(d.defaultView, 'focus', onFocus); + } + } + }, + stop: function (doc) { + var d = doc || document; + if (ranges && ranges.has(d)) { + ranges['delete'](d); + off(d, 'input', onInput); + off(d, 'keydown', onKeyDown); + off(d, 'mousedown', onMouseDown); + off(d, 'mousemove', onMouseMove); + off(d, 'mouseup', onMouseUp); + off(d.defaultView, 'focus', onFocus); + } + } + }; + + function hasNativeSupport(doc) { + var osc = doc.onselectionchange; + if (osc !== undefined) { + try { + doc.onselectionchange = 0; + return doc.onselectionchange === null; + } catch (e) { + } finally { + doc.onselectionchange = osc; + } + } + return false; + } + + function newWeakMap() { + if (typeof WeakMap !== 'undefined') { + return new WeakMap(); + } else { + console.error('selectionchange: WeakMap not supported'); + return null; + } + } + + function getSelectionRange(doc) { + var s = doc.getSelection(); + return s.rangeCount ? s.getRangeAt(0) : null; + } + + function on(el, eventType, handler) { + el.addEventListener(eventType, handler, true); + } + + function off(el, eventType, handler) { + el.removeEventListener(eventType, handler, true); + } + + function onInput(e) { + if (!HAS_OWN_SELECTION[e.target.tagName]) { + dispatchIfChanged(this, true); + } + } + + function onKeyDown(e) { + var code = e.keyCode; + if (code === 65 && e[SELECT_ALL_MODIFIER] && !e.shiftKey && !e.altKey || // Ctrl-A or Cmd-A + code >= 37 && code <= 40 || // arrow key + e.ctrlKey && MAC && MAC_MOVE_KEYS.indexOf(code) >= 0) { + if (!HAS_OWN_SELECTION[e.target.tagName]) { + setTimeout(dispatchIfChanged.bind(null, this), 0); + } + } + } + + function onMouseDown(e) { + if (e.button === 0) { + on(this, 'mousemove', onMouseMove); + setTimeout(dispatchIfChanged.bind(null, this), 0); + } + } + + function onMouseMove(e) { // only needed while primary button is down + if (e.buttons & 1) { + dispatchIfChanged(this); + } else { + off(this, 'mousemove', onMouseMove); + } + } + + function onMouseUp(e) { + if (e.button === 0) { + setTimeout(dispatchIfChanged.bind(null, this), 0); + } else { + off(this, 'mousemove', onMouseMove); + } + } + + function onFocus() { + setTimeout(dispatchIfChanged.bind(null, this.document), 0); + } + + function dispatchIfChanged(doc, force) { + var r = getSelectionRange(doc); + if (force || !sameRange(r, ranges.get(doc))) { + ranges.set(doc, r); + setTimeout(doc.dispatchEvent.bind(doc, new Event('selectionchange')), 0); + } + } + + function sameRange(r1, r2) { + return r1 === r2 || r1 && r2 && RANGE_PROPS.every(function (prop) { + return r1[prop] === r2[prop]; + }); + } + })(); + + editor.selection = ( function() { + + var win = window; + var savedRange = null; + var domSelection = simply.dom.selection; + + var controlTags = { + IMG : true, + OBJECT : true, + EMBED : true + }; + + function isUneditable( node ) { + return node.getAttribute('contentEditable') == 'false'; + } + + function isControlTag( node ) { + var tag = node.tagName.toUpperCase(); + return ( controlTags[tag] ? true : false ); + } + + var self = { + init : function( useWin ) { + win = useWin; + }, + save : function( range ) { + if( !range ) { + range = domSelection.get(win); + } + savedRange = range; + }, + restore : function( range ) { + if( !range ) { + range = savedRange; + } + if( range ) { + domSelection.select(range); + } + }, + get : function() { + return savedRange ? savedRange : domSelection.get(win); + }, + getControlNode : function( range ) { + if( !range ) { + range = self.get(); + } + if( range ) { + var node = domSelection.getNode(range); + if( isControlTag(node) || isUneditable(node) ) { // this could use a lot more probably + return node; + } + } + return false; + }, + remove : function() { + savedRange = null; + } + }; + + return self; + + })(); + + return editor; +})(simply.editor || {}); + + +// polyfill to add :scope selector for IE +(function() { + if (!HTMLElement.prototype.querySelectorAll) { + throw new Error('rootedQuerySelectorAll: This polyfill can only be used with browsers that support querySelectorAll'); + } + + // A temporary element to query against for elements not currently in the DOM + // We'll also use this element to test for :scope support + var container = document.createElement('div'); + + // Check if the browser supports :scope + try { + // Browser supports :scope, do nothing + container.querySelectorAll(':scope *'); + } + catch (e) { + // Match usage of scope + var scopeRE = /^\s*:scope/gi; + + // Overrides + function overrideNodeMethod(prototype, methodName) { + // Store the old method for use later + var oldMethod = prototype[methodName]; + + // Override the method + prototype[methodName] = function(query) { + var nodeList, + gaveId = false, + gaveContainer = false; + + if (query.match(scopeRE)) { + // Remove :scope + query = query.replace(scopeRE, ''); + + if (!this.parentNode) { + // Add to temporary container + container.appendChild(this); + gaveContainer = true; + } + + parentNode = this.parentNode; + + if (!this.id) { + // Give temporary ID + this.id = 'rootedQuerySelector_id_'+(new Date()).getTime(); + gaveId = true; + } + + // Find elements against parent node + nodeList = oldMethod.call(parentNode, '#'+this.id+' '+query); + + // Reset the ID + if (gaveId) { + this.id = ''; + } + + // Remove from temporary container + if (gaveContainer) { + container.removeChild(this); + } + + return nodeList; + } + else { + // No immediate child selector used + return oldMethod.call(this, query); + } + }; + } + + // Browser doesn't support :scope, add polyfill + overrideNodeMethod(HTMLElement.prototype, 'querySelector'); + overrideNodeMethod(HTMLElement.prototype, 'querySelectorAll'); + } +}()); + diff --git a/www/simply/simply.elementBinding.js b/www/simply/simply.elementBinding.js new file mode 100644 index 0000000..c6c57f3 --- /dev/null +++ b/www/simply/simply.elementBinding.js @@ -0,0 +1,697 @@ +(function(global) { + var dataBinding = function(dataParent, path) { + if (dataParent.hasOwnProperty("_bindings_") && dataParent._bindings_[path]) { + return dataParent._bindings_[path]; + } + + var self = this; + + var setup = function(dataParent, path) { + path = "" + path; + /* + resolve binding to field.subfield.key, adding databindings along the data path; + */ + var keys = path.split("."); + var key = keys.pop(); + var parentBinding; + var currentParent = dataParent; + keys.forEach(function(parentKey) { + if (!currentParent[parentKey]) { + currentParent[parentKey] = {}; + } + parentBinding = simply.databind.create(currentParent, parentKey); + currentParent = currentParent[parentKey]; + }); + if (!currentParent[key]) { + currentParent[key] = undefined; + // if twoWay -> set value to current element value (getter?) -> initialize later (on bind) if undefined + } +// return { parentBinding: parentBinding, dataParent: dataParent, key: key}; +/* oude code hieronder */ + + self.parentBinding = parentBinding; //setup(dataParent, key); + self.dataParent = currentParent; + self.key = key; + self.elements = []; + self.changeStack = []; + + registerBinding(self.dataParent, self.key); + }; + + var addShadowValue = function() { + if (!self.hasOwnProperty("shadowValue")) { + var shadowValue; + Object.defineProperty(self, "shadowValue", { + get : function() { + return shadowValue; + }, + set : function(value) { + if (isEqual(shadowValue, value)) { + return; + } + + var previousValue = shadowValue; + shadowValue = value; + + if (shadowValue instanceof Array) { + overrideArrayFunctions(shadowValue); + } + if (typeof shadowValue === "object") { + monitorChildData(shadowValue); + } + + if (previousValue && shadowValue) { + transferBindings(previousValue, shadowValue); + } + } + }); + } + }; + + var transferBindings = function(oldValue, newValue) { + if (!oldValue._bindings_) { + return; + } + var oldBindings = oldValue._bindings_; + var newBindings = newValue._bindings_; + for (var key in oldBindings) { + if (newBindings && newBindings[key]) { + transferBoundElements(oldBindings[key], newBindings[key]); + } else { + setReconnectTrigger(newValue, key, oldBindings[key]); + } + } + }; + + var transferBoundElements = function(oldBinding, newBinding) { + oldBinding.elements.forEach(function(element) { + if (element.listItemDataBinding && (element.listItemDataBinding.binding === oldBinding)) { + var getter = element.listItemDataBinding.getter; + var setter = element.listItemDataBinding.setter; + oldBinding.unbind(element); + newBinding.bind(element, getter, setter); + } else if (element.dataBinding && (element.dataBinding.binding === oldBinding)) { + if (oldBinding.parentBinding && oldBinding.parentBinding.key == -1) { + // when the key is -1, the element was removed so no need to worry about it; + return; + } + var getter = element.dataBinding.getter; + var setter = element.dataBinding.setter; + oldBinding.unbind(element); + newBinding.bind(element, getter, setter); + } + }); + }; + + var setReconnectTrigger = function(dataParent, key, previousBinding) { + var reconnectChildren = function(value, previousData) { + var previousDescriptors = Object.getOwnPropertyDescriptors(previousData); + for (var i in previousDescriptors) { + if (typeof previousDescriptors[i].get !== "function" && typeof previousDescriptors[i].set === "function") { + var newBinding = previousDescriptors[i].set({}); // set it just to fetch the previous binding, so we can add a reconnect trigger for it; + setReconnectTrigger(value, i, newBinding); + } + } + if (typeof value === "undefined") { + return; + } + if (previousData && previousData._bindings_) { + for (var i in previousData._bindings_) { + if (typeof value[i] === "undefined") { + setReconnectTrigger(value, i, previousData._bindings_[i]); + } else { + // there is no databinding on the new value yet - add it and transfer the bindings/elements; + var newBinding = new dataBinding(value, i); + reconnectChildren(value[i], previousData[i]); + transferBindings(previousData[i], value[i]); + if (newBinding) { + transferBoundElements(previousData._bindings_[i], newBinding); + } + } + } + } + }; + + var reconnectBinding = function(value) { + if (typeof value !== 'undefined') { + newBinding = new dataBinding(dataParent, key); + reconnectChildren(value, previousBinding.shadowValue); + dataParent[key] = value; + transferBindings(previousBinding.shadowValue, value); + transferBoundElements(previousBinding, newBinding); + return newBinding; + } + }; + Object.defineProperty(dataParent, key, { + set : reconnectBinding, + configurable: true + }); + }; + + var addParentKey = function() { + if (!self.hasOwnProperty("parentKey")) { + Object.defineProperty(self, "parentKey", { + get : function() { + var parentKeys = []; + + var binding = self.parentBinding; + while(binding) { + parentKeys.unshift(binding.key); + binding = binding.parentBinding; + } + + parentKeys.unshift(""); // root node + parentKeys.push(""); // end node + + return parentKeys.join("/"); //TODO: SWITCH TO '.' + } + }); + } + }; + + var addPath = function() { + if (!self.hasOwnProperty("path")) { + Object.defineProperty(self, "path", { + get : function() { + var parentKeys = []; + + var binding = self.parentBinding; + while(binding) { + parentKeys.unshift(binding.key); + binding = binding.parentBinding; + } + + parentKeys.unshift(""); // root node + parentKeys.push(self.key); // end node + + return parentKeys.join("/"); //TODO: switch to '.' + } + }); + } + }; + + var addBindings = function(dataParent) { + if (!dataParent.hasOwnProperty("_bindings_")) { + var bindings = {}; + Object.defineProperty(dataParent, "_bindings_", { + get : function() { + return bindings; + } + }); + } + }; + + var registerBinding = function(dataParent, key) { + + addShadowValue(); + self.shadowValue = dataParent[key]; + + addParentKey(); + + addPath(); + + addBindings(dataParent); + dataParent._bindings_[key] = self; + + Object.defineProperty(dataParent, key, { + set : function(value) { + self.set(value, self); + // FIXME: run upwards on parentBindings; + }, + get : function() { + return self.shadowValue; + }, + enumerable: true + }); + }; + + var overrideArrayFunction = function(shadowValue, name) { + if (shadowValue.hasOwnProperty(name)) { + return; // we already did this; + } + Object.defineProperty(shadowValue, name, { + value : function() { + self.resolve(); // make sure the shadowValue is in sync with the latest state; + var result = Array.prototype[name].apply(shadowValue, arguments); + + + // for (var i in shadowValue) { + // shadowValue[i] = shadowValue[i]; // this will force a renumber/reindex for the parentKeys; + // } + + self.set(shadowValue, self); + + monitorChildData(shadowValue); // we might have new children that we need to watch as well; + return result; + } + }); + }; + + var overrideArrayFunctions = function(shadowValue) { + ['pop','push','shift','unshift','splice'].forEach(function(fn) { + overrideArrayFunction(shadowValue, fn); + }); + }; + + var monitorChildData = function(shadowValue) { + var monitor = function(shadowValue, key) { + var childBinding = new dataBinding(shadowValue, key); + if (!childBinding.parentBinding) { + childBinding.parentBinding = self; + } + }; + + for (var key in shadowValue) { + monitor(shadowValue, key); + } + }; + +/* + var info = setup(dataParent, path); +console.log(info); + this.parentBinding = info.parentbinding; //setup(dataParent, key); + this.dataParent = info.dataParent; + this.key = info.key; + this.elements = []; + this.elementIndex = new WeakMap(); + this.changeStack = []; + + registerBinding(this.dataParent, this.key); +*/ + setup(dataParent, path); + }; + + dataBinding.prototype.bind = function(element, getter, setter) { + var index = this.elements.push(element); + + // change this to non enumerable property + var elementBinding = { + setter : setter, + getter : getter, + binding : this, + observer: null, + observerPaused: 0 + }; + if (this.dataParent instanceof Array) { + if (element.listItemDataBinding) { + element.listItemDataBinding.binding.unbind(element); + } + element.listItemDataBinding = elementBinding; + } else { + if (element.dataBinding) { + element.dataBinding.binding.unbind(element); + } + element.dataBinding = elementBinding; + } + if (typeof this.shadowValue === 'undefined') { + this.set(getter(element), element); + } else { + setter(element, this.shadowValue); + } + this.addListeners(element); + }; + + dataBinding.prototype.bindOneWay = function(element, setter) { + if (element.dataBinding) { + element.dataBinding.binding.unbind(element); + } + var index = this.elements.push(element); + element.dataBinding = { + setter : setter, + binding : this + }; + if (typeof this.shadowValue !== 'undefined') { + setter(element, this.shadowValue); // or try to set an empty value? + } + }; + + dataBinding.prototype.set = function(value, source) { + // using a changeStack here for debugging - if different pieces of code + // change a value within one resolve cycle, this allows you to see + // what caused this and if your change was actually registered + this.changeStack.push({value: value, source: source}); + this.resolve(); // must run immediately or this.get will return old values + + // update the parentBindings to reconnect to it, in case we got lost + this.updateParent(value, source); + }; + + dataBinding.prototype.updateParent = function(value, source) { + if (this.parentBinding) { + if (this.parentBinding.dataParent[this.parentBinding.key] !== this.dataParent) { + this.parentBinding.dataParent[this.parentBinding.key][this.key] = value; + } + this.parentBinding.updateParent(this.dataParent, source); + } + }; + + dataBinding.prototype.get = function() { + return this.shadowValue; + }; + + dataBinding.prototype.resolve = function() { + var self = this; + if (this.resolveTimer) { + clearTimeout(this.resolveTimer); + } + if (!this.changeStack.length) { + return; + } + // we only need the last change + // stack is useful for debugging purposes only + var change = this.changeStack.pop(); + this.changeStack = []; + + var oldValue = this.shadowValue; + this.shadowValue = change.value; + var newValue = this.shadowValue; + + // event / callback voor wijziging in data zelf hier toevoegen + // of in updateElements als je throttle wil hebben. + self.updateElements(change); + this.fireEvent("databind:resolved", document, {dataBinding: this, arguments:{oldValue: oldValue, newValue: newValue}}); + }; + dataBinding.prototype.getElementBinding = function(element) { + if (element.dataBinding && (element.dataBinding.binding === this)) { + return element.dataBinding; + } else if (element.listItemDataBinding && (element.listItemDataBinding.binding === this)) { + return element.listItemDataBinding; + } + }; + dataBinding.prototype.updateElement = function(element) { + var elementBinding = this.getElementBinding(element); + if (!elementBinding) { + return; + } + elementBinding.idleCallback = false; + this.pauseListeners(element); + elementBinding.setter(element, this.get()); + this.resumeListeners(element); + this.fireEvent("databind:elementresolved", element); + }; + + dataBinding.prototype.updateElements = function(change) { + var isElementXPercentInViewport = function(el, percentVisible) { + var rect = el.getBoundingClientRect(); + var windowHeight = (window.innerHeight || document.documentElement.clientHeight); + + return !( + Math.floor(100 - (((rect.top >= 0 ? 0 : rect.top) / +-(rect.height / 1)) * 100)) < percentVisible || + Math.floor(100 - ((rect.bottom - windowHeight) / rect.height) * 100) < percentVisible + ) + }; + + var visibilityPercentage = function(el) { + var rect = el.getBoundingClientRect(); + var windowHeight = (window.innerHeight || document.documentElement.clientHeight); + + return windowHeight / Math.min( + Math.abs(Math.floor(100 - (((rect.top >= 0 ? 0 : rect.top) / +-(rect.height / 1)) * 100))), + Math.abs(Math.floor(100 - ((rect.bottom - windowHeight) / rect.height) * 100)) + ); + }; + + var self = this; + this.elements.forEach(function(element, index) { + if (change.source != element) { + var elementBinding = self.getElementBinding(element); + if (!elementBinding) { + return; + } + + if (elementBinding.idleCallback) { + return; // + } + + if (isElementXPercentInViewport(element, 50)) { + self.updateElement(element); + } else { + if (elementBinding.idleCallback) { + cancelIdleCallback(elementBinding.idleCallback); + }; + elementBinding.idleCallback = requestIdleCallback(function() { + self.updateElement(element); + }, {timeout: 10 * parseInt(visibilityPercentage(element) * 50)}); + // spread out the timeout for the elements so they don't clog the browser because they update all at once. + // elements that are closer to be on screen are done before the elements that are far away. + } + } + }); + + if (!self.handleScreenUpdate) { + self.handleScreenUpdate = function() { + self.elements.forEach(function(element, index) { + var elementBinding = self.getElementBinding(element); + if (!elementBinding) { + return; + } + if (elementBinding.idleCallback && isElementXPercentInViewport(element, 50)) { + console.log("updating element that has idle callback and is now in view"); + cancelIdleCallback(elementBinding.idleCallback); + self.updateElement(element); + } + }); + }; + } + + window.removeEventListener("scroll", self.handleScreenUpdate); + window.addEventListener("scroll", self.handleScreenUpdate); + }; + + dataBinding.prototype.unbind = function(element) { + // change elements to Set() + if (this.elements.indexOf(element) > -1) { + this.removeListeners(element); + this.elements.splice(this.elements.indexOf(element), 1); + if (element.dataBinding && (element.dataBinding.binding === this)) { + delete element.dataBinding; + } else if (element.listItemDataBinding && (element.listItemDataBinding.binding === this)) { + delete element.listItemDataBinding; + } + return true; + } + return false; + }; + + var isEqual = function(data1, data2) { + return JSON.stringify(data1) == JSON.stringify(data2); + }; + dataBinding.prototype.updateFrom = function(element) { + if (element.dataBinding) { + elementValue = element.dataBinding.getter(element); + if (!isEqual(elementValue, this.shadowValue)) { + this.set(elementValue, element); + } + } + }; + + dataBinding.prototype.addListeners = function(element) { + var dataBinding = element.dataBinding; + if (!dataBinding) { + dataBinding = element.listItemDataBinding; + } + if (dataBinding) { + if (dataBinding.observer) { + this.removeListeners(element); + } + var self = this; + dataBinding.observer = new MutationObserver( + getChangeHandler(element) + ); + // FIXME: doesn't trigger when element itself is removed from the dom + dataBinding.observer.observe(element, { + characterData: true, + subtree: true, + childList: true, + attributes: true + }); + } + // FIXME: the mutationObserver is slow to pick up on node insert/node remove changes + }; + + dataBinding.prototype.pauseListeners = function(element) { + if (element.dataBinding && element.dataBinding.observer) { + element.dataBinding.observer.disconnect(); + element.dataBinding.observerPaused++; + } + }; + + dataBinding.prototype.resumeListeners = function(element) { + if (element.dataBinding && element.dataBinding.observerPaused) { + element.dataBinding.observerPaused--; + if (!element.dataBinding.observerPaused) { + element.dataBinding.observer.observe(element, { + characterData: true, + subtree: true, + childList: true, + attributes: true + }); + } + } + if (element.listItemDataBinding && element.listItemDataBinding.observerPaused) { + element.listItemDataBinding.observerPaused--; + if (!element.listItemDataBinding.observerPaused) { + element.listItemDataBinding.observer.observe(element, { + characterData: true, + subtree: true, + childList: true, + attributes: true + }); + } + } + }; + + dataBinding.prototype.fireEvent = function(evtname, target, eventData) { + var event; // The custom event that will be created + if (document.createEvent) { + event = document.createEvent("HTMLEvents"); + event.initEvent(evtname, true, true); + } else { + event = document.createEventObject(); + event.eventType = evtname; + } + + event.data = eventData; + event.eventName = evtname; + + if (document.createEvent) { + target.dispatchEvent(event); + } else { + // target.fireEvent("on" + event.eventType, event); + } + return event; + }; + + dataBinding.prototype.removeListeners = function(element) { + if (element.dataBinding && element.dataBinding.observer) { + element.dataBinding.observer.disconnect(); + } + if (element.listItemDataBinding && element.listItemDataBinding.observer) { + element.listItemDataBinding.observer.disconnect(); + } + }; + + /** + * returns a function that updates the data from a + * target element. This function is passed on to the + * mutation observer so we don't need to search for the + * bound element there. + * @param target DomElement the bound element + * @return void + */ + function getChangeHandler(target) { + return function(mutations) { + if (target.dataBinding && target.dataBinding.binding) { + if (target.dataBinding.binding.shadowValue instanceof Array) { + mutations.forEach(function(mutation) { + if (mutation.type == "childList" && mutation.target == target) { + mutation.removedNodes.forEach(function(node) { + if (node.nodeType != document.ELEMENT_NODE) { + return; + } + if (!node.listItemDataBinding) { + return; + } + var index = parseInt(node.listItemDataBinding.binding.key); + if (index < 0) { + return; + } + var listItemParent = node.listItemDataBinding.binding.dataParent; + console.log("remove childNode, value before splice " + JSON.stringify(listItemParent)); + listItemParent._bindings_[index].key = -1; + + node.listItemDataBinding.simplyData = Array.prototype['splice'].call( + listItemParent, index, 1 + )[0]; + + delete listItemParent._bindings_[index]; + + var counter = 0; + for (i in listItemParent._bindings_) { + listItemParent._bindings_[counter] = listItemParent._bindings_[i]; + console.log("renumbering " + listItemParent._bindings_[counter].key + " to " + counter); + listItemParent._bindings_[counter].key = counter; + delete listItemParent._bindings_[i]; + counter++; + } + console.log("remove childNode, value after splice " + JSON.stringify(listItemParent)); + }); + + mutation.addedNodes.forEach(function(node) { + if (node.nodeType != document.ELEMENT_NODE) { + return; + } + var index = 0; + if (mutation.previousSibling) { + if (!mutation.previousSibling.listItemDataBinding) { + return; + } + index = parseInt(mutation.previousSibling.listItemDataBinding.binding.key) + 1; + } + if (!node.parentNode) { + // node was already removed, carry on; + return; + } + var listItemParent = node.parentNode.dataBinding.binding.get(); + console.log("add childNode, value before splice " + JSON.stringify(listItemParent)); + + Array.prototype['splice'].call( + listItemParent, + // listDataBinding can be empty if we clone a list item and append it to the list; + // the data change will be picked up by the list getter instead; + index, 0, (node.listItemDataBinding ? node.listItemDataBinding.simplyData :null) + ); + + var counter = 0; + node.parentNode.childNodes.forEach(function(listItem) { + if (listItem.listItemDataBinding) { + console.log("renumbering " + listItem.listItemDataBinding.binding.key + " to " + counter); + listItemParent._bindings_[counter] = listItem.listItemDataBinding.binding; + listItem.listItemDataBinding.binding.key = counter; + counter++; + } + }); + console.log("add childNode, value after splice " + JSON.stringify(listItemParent)); + }); + } + }); + } + + target.dataBinding.binding.updateFrom(target); + } + }; + } + + var databind = { + create: function(dataParent, path) { + if (typeof dataParent != "object") { + console.log("Attempted to bind on a non-object data for " + path); + return; + } + // If we already have a databinding on this data[key], re-use that one instead of creating a new one; + if (dataParent.hasOwnProperty("_bindings_") && dataParent._bindings_[path]) { + return dataParent._bindings_[path]; + } + return new dataBinding(dataParent, path); + }, + debug: function(on) { + debugMode = Boolean(on); + // log change/resolve changes value and source + }, + sync: function(data) { + // stel ik delete een entry uit een array met 'delete arr[2]' + // dan wil ik 'simply.databind.sync(arr)' kunnen doen om alsnog + // de change te triggeren... hoe doe ik dat? + } + }; + + if (typeof module !== 'undefined' && typeof module.exports != 'undefined') { + module.exports = databind; + } else { + if (!global.simply) { + global.simply = {}; + } + global.simply.databind = databind; + } + +})(this); diff --git a/www/simply/simply.tripleBinding.js b/www/simply/simply.tripleBinding.js new file mode 100644 index 0000000..7060e49 --- /dev/null +++ b/www/simply/simply.tripleBinding.js @@ -0,0 +1,575 @@ +var resolveNameSpace = function(property) { + var namespace = "xmlns:" + property.split(":")[0]; + var namespaceElement = document.body.closest("[" + CSS.escape(namespace) + "]"); + if (namespaceElement) { + return namespaceElement.getAttribute(namespace) + property.split(":")[1]; + } + return property; +}; + +tripleBinding = function(triple, dataBinding) { + /* + Triple is an object: + { + store : rdfStore, + subject : rdfSubject, + predicate : rdfPredicate + } + */ + + + var self = this; + this.triple = triple; + this.dataBinding = dataBinding; + this.triple.dataBinding = dataBinding; + this.triple.tripleBinding = this; + this.simplyDataBindingElement = true; + + this.triple.predicate = resolveNameSpace(this.triple.predicate); + + if (typeof this.triple.store.simplyDataBindings === "undefined") { + this.triple.store.simplyDataBindings = {}; + } + if (typeof this.triple.store.simplyDataBindings[this.triple.subject] === "undefined") { + this.triple.store.simplyDataBindings[this.triple.subject] = {}; + } + if (typeof this.triple.store.simplyDataBindings[this.triple.subject][this.triple.predicate] === "undefined") { + this.triple.store.simplyDataBindings[this.triple.subject][this.triple.predicate] = this; + } else { + console.log("Warning: binding to the same subject/predicate twice"); + var previousBinding = this.triple.store.simplyDataBindings[this.triple.subject][this.triple.predicate]; + previousBinding.isInDocument = function() { + return false; + }; + this.dataBinding.unbind(previousBinding); + this.triple.store.simplyDataBindings[this.triple.subject][this.triple.predicate] = this; + } + this.unbind = function() { + if (this.dataBinding) { + this.dataBinding.unbind(this); + } + }; + this.dataBindingPaused = 0; + + this.getBlankNode = function(self, subject) { + var result = {}; + if (!self.triple.store.subjectIndex[subject]) { + subject = "_:" + subject; + } + if (!self.triple.store.subjectIndex[subject]) { + return; + } + self.triple.store.subjectIndex[subject].forEach(function(triple) { + if (typeof result[triple.predicate.value] === "undefined") { + result[triple.predicate.value] = []; + } + result[triple.predicate.value].push(triple.object); + }); + return result; + }; + this.getNamedNode = function(self, subject) { + var result = {}; + if (!self.triple.store.subjectIndex[subject]) { + subject = "<" + subject + ">"; + } + if (!self.triple.store.subjectIndex[subject]) { + return; + } + self.triple.store.subjectIndex[subject].forEach(function(triple) { + if (typeof result[triple.predicate.value] === "undefined") { + result[triple.predicate.value] = []; + } + result[triple.predicate.value].push(triple.object); + }); + return result; + }; + + this.getObjects = function() { + var triples = this.getTriples(); + var objects = []; + triples.forEach(function(triple) { + if (triple.object.termType == "Collection") { + triple.object.elements.forEach(function(item) { + objects.push(item); + }); + } else { + objects.push(triple.object); + } + }); + return objects; + }; + + this.getTriples = function() { + var triples = []; + var subject = this.triple.subject; + var predicate = this.triple.predicate; + var store = this.triple.store; + var self = this; + + if (!this.triple.store.subjectIndex[subject]) { + if (this.triple.store.subjectIndex["<" + subject + ">"]) { + subject = "<" + subject + ">"; + } else if (this.triple.store.subjectIndex[subject.replace(/^\[(.*)\]$/, "$1")]) { + subject = subject.replace(/^\[(.*)\]$/, "$1"); + } + } + if (!this.triple.store.subjectIndex[subject]) { + return []; + } + this.triple.store.subjectIndex[subject].forEach(function(triple) { + if (triple.predicate.value != predicate) { + return; + } + if ((triple.object.termType == "Collection") && (triple.object.elements.length == 0)) { + return; // empty collection, no need to add + } + triples.push(triple); + }); + return triples; + }; + + this.getter = function() { + var self = this; + var objects = this.getObjects(); + if (!objects) { + return; + } + if (this.dataBinding.mode == "field") { + if (objects.length) { + return objects[0].isBlank ? "[_:" + objects[0].value + "]" : objects[0].value; + // follows the format as described in https://www.w3.org/TR/2008/REC-rdfa-syntax-20081014/#sec_5.4.5. + } + return; + } else { + var result = objects.map(function(object) { + switch (object.termType) { + case "Collection": + return object.elements.map(function(item) { + if (item.isBlank) { + item.contents = self.getBlankNode(self, item.value); + } + return { + value : (item.isBlank ? "[_:" + item.value + "]" : item.value), + contents: item.contents + }; + }); + // break; + case "Literal": + return object; + // break; + case "BlankNode": + return { + value: "[_:" + object.value + "]", + contents: self.getBlankNode(self, object.value) + }; + // break; + case "NamedNode": + return { + value: object.value, + contents: self.getNamedNode(self, object.value) + }; + // break; + } + }); + return result; + } + }; + + this.getFirstElementBinding = function(dataBinding) { + for (var i=0; i 0) { // move value to the front so we handle that first, setting the about value for the other fields + var index = keys.indexOf("value"); + keys.splice(index, 1); + keys.unshift("value"); + } + var blankNode = new $rdf.BlankNode(); + item.value = "[_:" + blankNode.value + "]"; + // console.log("created blank node " + blankNode.value + " as parent"); + var predicate = self.getFirstElementBinding(item._bindings_.value).element.getAttribute("property"); + if (!predicate) { + predicate = self.getFirstElementBinding(item._bindings_.value).element.parentNode.getAttribute("property"); + } + if (!predicate) { + return; + } + predicate = resolveNameSpace(predicate); + + self.triple.store.add(blankNode, $rdf.sym("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"), $rdf.sym(resolveNameSpace(self.getFirstElementBinding(item._bindings_.value).element.getAttribute("typeof")))); + self.triple.store.subjectIndex[subject].every(function(triple) { + if (triple.predicate.value != predicate) { + return true; // continue + } + if (triple.object.termType === "Collection") { + triple.object.append(blankNode); + } else { + self.triple.store.add(self.triple.store.subjectIndex[subject][0].subject, $rdf.sym(predicate), blankNode); + } + return false; // stop loop after first time we added it; + }); + + bindChildren(item, blankNode); + setTimeout(function() { + keys.forEach(function(key) { + if (!item._bindings_ || !item._bindings_[key]) { + return; + } + if (!item._bindings_[key].elements.length) { + return; + } + var subject = self.getFirstElementBinding(item._bindings_[key]).element.closest("[about]").getAttribute("about"); + if (!self.triple.store.subjectIndex[subject]) { + if (self.triple.store.subjectIndex["<" + subject + ">"]) { + subject = "<" + subject + ">"; + } else if (self.triple.store.subjectIndex[subject.replace(/^\[(.*)\]$/, "$1")]) { + subject = subject.replace(/^\[(.*)\]$/, "$1"); + } + } + if (!self.triple.store.subjectIndex[subject]) { + return; + } + subject = self.triple.store.subjectIndex[subject][0].subject; + var predicate = self.getFirstElementBinding(item._bindings_[key]).element.getAttribute("property"); + if (!predicate) { + predicate = self.getFirstElementBinding(item._bindings_[key]).element.parentNode.getAttribute("property"); + } + if (!predicate) { + return; + } + predicate = resolveNameSpace(predicate); + var value = item[key]; + if ((subject.isBlank ? "[_:" + subject.value + "]" : subject.value) === value) { + return; + } + + if (value && value.length && typeof value !== "object") { + // console.log("adding " + predicate + " to " + subject); + self.triple.store.add(subject, $rdf.sym(predicate), value); + } else { + if (!value || typeof value.forEach !== "function") { + return; + } + bindParents(value, subject); + } + + var triple = new tripleBinding( + { + store : self.triple.store, + subject : (subject.isBlank ? "[_:" + subject.value + "]" : subject.value), + predicate: predicate, + initFromStore : self.triple.initFromStore + }, + item._bindings_[key] + ); + item._bindings_[key].bind(triple); + }); + }, 10); // needs a bit to let the 'about' property get set; + } + }); + } + + this.deleteBlankNode = function(store, node) { + while (store.subjectIndex["_:" + node].length) { + subEntry = store.subjectIndex["_:" + node][0]; + store.removeStatement(subEntry); + if (subEntry.object.termType === "BlankNode") { + this.deleteBlankNode(store, subEntry.object.value); + } + } + }; + + this.setter = function(data) { + try { + if (this.getFirstElementBinding(this.triple.dataBinding).element.closest("[about]").getAttribute("about") !== this.triple.subject) { + // 'about' changed, update to reflect; + console.log("Updating subject from: " + this.triple.subject); + delete this.triple.store.simplyDataBindings[this.triple.subject][this.triple.predicate]; + this.triple.subject = this.getFirstElementBinding(this.triple.dataBinding).element.closest("[about]").getAttribute("about"); + console.log("Updating subject to: " + this.triple.subject); + this.triple.store.simplyDataBindings[this.triple.subject][this.triple.predicate] = this; + } + } catch (e) { + } + + if ((typeof data === "object") && (typeof data.about !== "undefined") && (data.about === null)) { + return; + } + var subject = this.triple.subject; + var objects = this.getObjects(); + if (this.dataBinding.mode == "field") { + /* + if (data.indexOf("http") === 0) { // make it a symbol if it is a url + data = $rdf.sym(data); + } + */ + if (objects.length) { + if ((data !== null) && (typeof data !== "undefined") && data !== "") { + switch (data.termType) { + case "Literal": + objects[0] = data; + break; + default: + if (objects[0].termType === "BlankNode") { + data = data.replace(/^\[_:(.*)\]$/, "$1"); + } + objects[0].value = data; + break; + } + } else { + this.triple.store.removeStatement(this.getTriples()[0]); + } + } else { + if (this.triple.subject == data) { + return; // skip descriptions for ourself + } + if (data == "") { + return; // skip creation of empty data + } + if ((typeof data.about === "object") && (data.about === null)) { + return; // no known about, skip it + } + + console.log("create a new triple for value"); + console.log(data); + console.log(this.triple); + if (!this.triple.store.subjectIndex[subject]) { + if (this.triple.store.subjectIndex["<" + subject + ">"]) { + subject = "<" + subject + ">"; + } else if (this.triple.store.subjectIndex[subject.replace(/^\[(.*)\]$/, "$1")]) { + subject = subject.replace(/^\[(.*)\]$/, "$1"); + } + } + if (!this.triple.store.subjectIndex[subject]) { + try { + subject = $rdf.sym(subject); + } catch (e) { + return; + } + } else { + subject = this.triple.store.subjectIndex[subject][0].subject; + } + if ((data !== null) && (typeof data !== "undefined") && data !== "") { + if ((typeof data.about !== "undefined") && (subject.isBlank) && ("[_:" + subject.value + "]" == data.about)) { + console.log("skip adding about self"); + } else { + this.triple.store.add(subject, $rdf.sym(this.triple.predicate), data); + } + } + } + } else { + var self = this; + if (!this.triple.store.subjectIndex[subject]) { + if (this.triple.store.subjectIndex["<" + subject + ">"]) { + subject = "<" + subject + ">"; + } else if (this.triple.store.subjectIndex[subject.replace(/^\[(.*)\]$/, "$1")]) { + subject = subject.replace(/^\[(.*)\]$/, "$1"); + } + } + if (!this.triple.store.subjectIndex[subject]) { + return; + } + var dataNodes = data.map(function(entry) { + return entry.value; + }); + + var triples = this.getTriples(); + if (triples.length === 0 && dataNodes.length > 0) { + self.triple.store.add($rdf.sym(self.triple.subject), $rdf.sym(self.triple.predicate), new $rdf.Collection()); + } + + triples.forEach(function(entry) { + switch (entry.object.termType) { + case "Collection": + entry.object.elements.forEach(function(item, index, elements) { + if (dataNodes.indexOf(item.isBlank ? "[_:" + item.value + "]" : item.value) === -1) { + // node was removed; + // console.log("remove node"); + // console.log(self.triple.subject); + // console.log(self.triple.predicate); + // console.log(item.value); + // self.triple.store.removeStatement(item); + elements.splice(index, 1); // remove it from the collection; + if (item.termType === "BlankNode") { + self.deleteBlankNode(self.triple.store, item.value); + } + } + }); + entry.object.elements.sort(function(a, b) { + aIndex = dataNodes.indexOf(a.isBlank ? "[_:" + a.value + "]" : a.value); + bIndex = dataNodes.indexOf(b.isBlank ? "[_:" + b.value + "]" : b.value); + if (aIndex > bIndex) { + return 1; + } else if (aIndex < bIndex) { + return -1; + } else { + return 0; + } + }); + break; + case "BlankNode": + if (dataNodes.indexOf("[_:" + entry.object.value + "]" ) === -1) { + self.triple.store.removeStatement(entry); + self.deleteBlankNode(self.triple.store, entry.object.value); + } + break; + default: + if (dataNodes.indexOf(entry.object.value) === -1) { + self.triple.store.removeStatement(entry); + } + break; + } + }); + setTimeout(function() { + bindParents(data, subject); + }); + } + return data; + }; + + this.addListeners = function() { + }; + + this.removeListeners = function() { + }; + + this.resumeListeners = function() { + this.triple.dataBindingPaused--; + if (this.triple.dataBindingPaused < 0) { + console.log("Warning: resume called of non-paused databinding"); + this.triple.dataBindingPaused = 0; + } + }; + this.pauseListeners = function() { + this.triple.dataBindingPaused++; + }; + + this.fireEvent = function(event) { + }; + this.isInDocument = function() { + return true; + }; + + + // Init triples from the rdfStore to start with; + if (this.triple.initFromStore) { + var storeValue = this.getter(); + if (Array.isArray(storeValue) && !storeValue.length) { + return; + } + if (!storeValue) { + return; + } + this.dataBinding.set(this.getter()); + this.dataBinding.resolve(true); + } +}; + +editor.field.storedInit = editor.field.init; +editor.list.storedInit = editor.list.init; + +window.simplyBlankNodeCount = 1; + +var initRdflibTriple = function(element) { + var fieldName = element.getAttribute("data-simply-field"); + if (!fieldName) { + fieldName = element.getAttribute("data-simply-list"); + } + + var about = element.closest("[about]"); + if (!about) { + window.setTimeout(function() { + initRdflibTriple(element); + }, 10); + return; + } + + var subject = about.getAttribute("about"); + if (element.hasAttribute("typeof")) { + if (subject.indexOf("[") !== 0) { // skip blank nodes; FIXME: do we need a better way to exclude them? + // Only add the type if it is not already set; + var currentType = simplyApp.rdfStore.match($rdf.sym(subject), $rdf.sym("http://www.w3.org/1999/02/22-rdf-syntax-ns#type")); + if (currentType.length) { + element.setAttribute("typeof", currentType[0].object.value); + } else { + simplyApp.rdfStore.add($rdf.sym(subject), $rdf.sym("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"), $rdf.sym(resolveNameSpace(element.getAttribute("typeof")))); + } + } + } + + if (!element.hasAttribute("property")) { + return; + } + + var property = element.getAttribute("property"); + var initFromStore = true; + if (element.getAttribute("data-set-to-store")) { + initFromStore = false; + } + if (element.dataBinding) { + if ( + !simplyApp.rdfStore.simplyDataBindings || + !simplyApp.rdfStore.simplyDataBindings[subject] || + !simplyApp.rdfStore.simplyDataBindings[subject][property] + ) { + element.dataBinding.bind( + new tripleBinding( + { + store: simplyApp.rdfStore, + subject : subject, + predicate : property, + initFromStore: initFromStore + }, + element.dataBinding + ) + ); + } + } +}; + +editor.field.init = function(field, dataParent, useDataBinding) { + editor.field.storedInit(field, dataParent, useDataBinding); + initRdflibTriple(field); +}; +editor.list.init = function(list, dataParent, useDataBinding) { + editor.list.storedInit(list, dataParent, useDataBinding); + initRdflibTriple(list); +}; diff --git a/www/simply/slip.js b/www/simply/slip.js new file mode 100644 index 0000000..4790df5 --- /dev/null +++ b/www/simply/slip.js @@ -0,0 +1,1095 @@ +/* Slip - swiping and reordering in lists of elements on touch screens, no fuss. + + Fires these events on list elements: + + • slip:swipe + When swipe has been done and user has lifted finger off the screen. + If you execute event.preventDefault() the element will be animated back to original position. + Otherwise it will be animated off the list and set to display:none. + + • slip:beforeswipe + Fired before first swipe movement starts. + If you execute event.preventDefault() then element will not move at all. + + • slip:reorder + Element has been dropped in new location. event.detail contains the location: + • insertBefore: DOM node before which element has been dropped (null is the end of the list). Use with node.insertBefore(). + • spliceIndex: Index of element before which current element has been dropped, not counting the element iself. + For use with Array.splice() if the list is reflecting objects in some array. + + • slip:beforereorder + When reordering movement starts. + Element being reordered gets class `slip-reordering`. + If you execute event.preventDefault() then element will not move at all. + + • slip:beforewait + If you execute event.preventDefault() then reordering will begin immediately, blocking ability to scroll the page. + + • slip:tap + When element was tapped without being swiped/reordered. + + • slip:cancelswipe + Fired when the user stops dragging and the element returns to its original position. + + + Usage: + + CSS: + You should set `user-select:none` (and WebKit prefixes, sigh) on list elements, + otherwise unstoppable and glitchy text selection in iOS will get in the way. + + You should set `overflow-x: hidden` on the container or body to prevent horizontal scrollbar + appearing when elements are swiped off the list. + + + var list = document.querySelector('ul#slippylist'); + new Slip(list); + + list.addEventListener('slip:beforeswipe', function(e) { + if (shouldNotSwipe(e.target)) e.preventDefault(); + }); + + list.addEventListener('slip:swipe', function(e) { + // e.target swiped + if (thatWasSwipeToRemove) { + e.target.parentNode.removeChild(e.target); + } else { + e.preventDefault(); // will animate back to original position + } + }); + + list.addEventListener('slip:beforereorder', function(e) { + if (shouldNotReorder(e.target)) e.preventDefault(); + }); + + list.addEventListener('slip:reorder', function(e) { + // e.target reordered. + if (reorderedOK) { + e.target.parentNode.insertBefore(e.target, e.detail.insertBefore); + } else { + e.preventDefault(); + } + }); + + Requires: + • Touch events + • CSS transforms + • Function.bind() + + Caveats: + • Elements must not change size while reordering or swiping takes place (otherwise it will be visually out of sync) +*/ +/*! @license + Slip.js 1.2.0 + + © 2014 Kornel Lesiński . All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and + the following disclaimer in the documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +window['Slip'] = (function(){ + 'use strict'; + + var damnYouChrome = /Chrome\/[34]/.test(navigator.userAgent); // For bugs that can't be programmatically detected :( Intended to catch all versions of Chrome 30-40 + var needsBodyHandlerHack = damnYouChrome; // Otherwise I _sometimes_ don't get any touchstart events and only clicks instead. + + /* When dragging elements down in Chrome (tested 34-37) dragged element may appear below stationary elements. + Looks like WebKit bug #61824, but iOS Safari doesn't have that problem. */ + var compositorDoesNotOrderLayers = damnYouChrome; + + // -webkit-mess + var testElement = document.createElement('div'); + + var transitionPrefix = "webkitTransition" in testElement.style ? "webkitTransition" : "transition"; + var transformPrefix = "webkitTransform" in testElement.style ? "webkitTransform" : "transform"; + var transformProperty = transformPrefix === "webkitTransform" ? "-webkit-transform" : "transform"; + var userSelectPrefix = "webkitUserSelect" in testElement.style ? "webkitUserSelect" : "userSelect"; + + testElement.style[transformPrefix] = 'translateZ(0)'; + var hwLayerMagic = testElement.style[transformPrefix] ? 'translateZ(0) ' : ''; + var hwTopLayerMagic = testElement.style[transformPrefix] ? 'translateZ(1px) ' : ''; + testElement = null; + + var globalInstances = 0; + var attachedBodyHandlerHack = false; + var nullHandler = function(){}; + + function Slip(container, options) { + if ('string' === typeof container) container = document.querySelector(container); + if (!container || !container.addEventListener) throw new Error("Please specify DOM node to attach to"); + + if (!this || this === window) return new Slip(container, options); + + this.options = options; + + // Functions used for as event handlers need usable `this` and must not change to be removable + this.cancel = this.setState.bind(this, this.states.idle); + this.onTouchStart = this.onTouchStart.bind(this); + this.onTouchMove = this.onTouchMove.bind(this); + this.onTouchEnd = this.onTouchEnd.bind(this); + this.onMouseDown = this.onMouseDown.bind(this); + this.onMouseMove = this.onMouseMove.bind(this); + this.onMouseUp = this.onMouseUp.bind(this); + this.onMouseLeave = this.onMouseLeave.bind(this); + this.onSelection = this.onSelection.bind(this); + this.onScroll = this.onScroll.bind(this); + + this.setState(this.states.idle); + this.attach(container); + } + + function getTransform(node) { + var transform = node.style[transformPrefix]; + if (transform) { + return { + value:transform, + original:transform, + }; + } + + if (window.getComputedStyle) { + var style = window.getComputedStyle(node).getPropertyValue(transformProperty); + if (style && style !== 'none') return {value:style, original:''}; + } + return {value:'', original:''}; + } + + function findIndex(target, nodes) { + var originalIndex = 0; + var listCount = 0; + + for (var i=0; i < nodes.length; i++) { + if (nodes[i].nodeType === 1) { + listCount++; + if (nodes[i] === target.node) { + originalIndex = listCount-1; + } + } + } + + return originalIndex; + } + + /* Helper functions to improve on getBoundingClientRect - also works + * for elements that are collapsed because all the child elements + * have float: styles. */ + + function getNodeBounds(el) { + var minTop; + var maxBottom; + var minLeft; + var maxRight; + + if (el.offsetHeight > 0) { + return el.getBoundingClientRect(); + } + + // Its a collapsed element, probably because of floating child elements. + for (var i=0; i rects.top) { + minTop = rects.top; + } + + if (typeof maxBottom === "undefined") { + maxBottom = rects.bottom; + } else if (maxBottom < rects.bottom) { + maxBottom = rects.bottom; + } + + if (typeof minLeft === "undefined") { + minLeft = rects.left; + } else if (minLeft > rects.left) { + minLeft = rects.left; + } + + if (typeof maxRight === "undefined") { + maxRight = rects.right; + } else if (maxRight < rects.right) { + maxRight = rects.right; + } + } + } + return { + top : minTop, + bottom : maxBottom, + left : minLeft, + right: maxRight + } + } + + function getNodeHeight(el) { + if (el.offsetHeight > 0) { + return el.offsetHeight; + } + if (el.childNodes.length) { + var nodeBounds = getNodeBounds(el); + return nodeBounds.bottom - nodeBounds.top; + } + return 0; + } + function getNodeWidth(el) { + if (el.offsetHeight > 0) { + return el.offsetWidth; + } + if (el.childNodes.length) { + var nodeBounds = getNodeBounds(el); + return nodeBounds.right - nodeBounds.left; + } + return 0; + } + function getNodeLeft(el) { + if (el.offsetHeight > 0) { + return el.offsetLeft; + } + if (el.childNodes.length) { + var nodeBounds = getNodeBounds(el); + return nodeBounds.left; + } + return 0; + } + function getNodeTop(el) { + if (el.offsetHeight > 0) { + return el.offsetTop; + } + if (el.childNodes.length) { + var nodeBounds = getNodeBounds(el); + return nodeBounds.top; + } + return 0; + } + + + // All functions in states are going to be executed in context of Slip object + Slip.prototype = { + + container: null, + options: {}, + state: null, + + target: null, // the tapped/swiped/reordered node with height and backed up styles + + usingTouch: false, // there's no good way to detect touchscreen preference other than receiving a touch event (really, trust me). + mouseHandlersAttached: false, + + startPosition: null, // x,y,time where first touch began + latestPosition: null, // x,y,time where the finger is currently + previousPosition: null, // x,y,time where the finger was ~100ms ago (for velocity calculation) + + canPreventScrolling: false, + + states: { + idle: function idleStateInit() { + this.target = null; + this.usingTouch = false; + this.removeMouseHandlers(); + + return { + allowTextSelection: true, + }; + }, + + undecided: function undecidedStateInit() { + this.target.height = this.target.node.offsetHeight; + this.target.node.style[transitionPrefix] = ''; + + if (!this.dispatch(this.target.originalTarget, 'beforewait')) { + if (this.dispatch(this.target.originalTarget, 'beforereorder')) { + this.setState(this.states.reorder); + } + } else { + var holdTimer = setTimeout(function(){ + var move = this.getAbsoluteMovement(); + if (this.canPreventScrolling && move.x < 15 && move.y < 25 && !this.selectionChanged) { + if (this.dispatch(this.target.originalTarget, 'beforereorder')) { + this.setState(this.states.reorder); + } + } + }.bind(this), 300); + } + + return { + leaveState: function() { + clearTimeout(holdTimer); + }, + + onMove: function() { + var move = this.getAbsoluteMovement(); + + if (move.x > 20 && move.y < Math.max(100, this.target.height)) { + if (this.dispatch(this.target.originalTarget, 'beforeswipe')) { + this.setState(this.states.swipe); + return false; + } else { + this.setState(this.states.idle); + } + } + if (move.x > 20) { + this.setState(this.states.idle); + } + if (move.y > 20) { + this.setState(this.states.idle); + } + + // Chrome likes sideways scrolling :( + if (move.x > move.y*1.2) return false; + }, + + onLeave: function() { + this.setState(this.states.idle); + }, + + onEnd: function() { + var allowDefault = this.dispatch(this.target.originalTarget, 'tap'); + this.setState(this.states.idle); + return allowDefault; + }, + }; + }, + + swipe: function swipeStateInit() { + var swipeSuccess = false; + var container = this.container; + + var originalIndex = findIndex(this.target, this.container.childNodes); + + container.className += ' slip-swiping-container'; + function removeClass() { + container.className = container.className.replace(/(?:^| )slip-swiping-container/,''); + } + + this.target.height = this.target.node.offsetHeight; + + return { + leaveState: function() { + if (swipeSuccess) { + this.animateSwipe(function(target){ + target.node.style[transformPrefix] = target.baseTransform.original; + target.node.style[transitionPrefix] = ''; + if (this.dispatch(target.node, 'afterswipe')) { + removeClass(); + return true; + } else { + this.animateToZero(undefined, target); + } + }.bind(this)); + } else { + this.animateToZero(removeClass); + this.dispatch(this.target.node, 'cancelswipe'); + } + }, + + onMove: function() { + var move = this.getTotalMovement(); + + if (Math.abs(move.y) < this.target.height+20) { + this.target.node.style[transformPrefix] = 'translate(' + move.x + 'px,0) ' + hwLayerMagic + this.target.baseTransform.value; + return false; + } else { + this.setState(this.states.idle); + } + }, + + onLeave: function() { + this.state.onEnd.call(this); + }, + + onEnd: function() { + var dx = this.latestPosition.x - this.previousPosition.x; + var dy = this.latestPosition.y - this.previousPosition.y; + var velocity = Math.sqrt(dx*dx + dy*dy) / (this.latestPosition.time - this.previousPosition.time + 1); + + var move = this.getAbsoluteMovement(); + var swiped = velocity > 0.6 && move.time > 110; + + var direction; + if (dx > 0) { + direction = "right"; + } else { + direction = "left"; + } + + if (swiped) { + if (this.dispatch(this.target.node, 'swipe', {direction: direction, originalIndex: originalIndex})) { + swipeSuccess = true; // can't animate here, leaveState overrides anim + } + } + this.setState(this.states.idle); + return !swiped; + }, + }; + }, + + reorder: function reorderStateInit() { + + this.target.height = getNodeHeight(this.target.node); + this.target.width = getNodeWidth(this.target.node); + + var nodes = this.container.childNodes; + var originalIndex = findIndex(this.target, nodes); + var mouseOutsideTimer; + var zeroY = getNodeTop(this.target.node) + this.target.height/2; + var zeroX = getNodeLeft(this.target.node) + this.target.width/2; + + this.target.rects = getNodeBounds(this.target.node); + this.target.node.rects = this.target.rects; + + this.target.parentList = Array.prototype.slice.call(this.target.node.parentNode.children); + + var otherNodes = []; + var variationInX = false; + var variationInY = false; + + for(var i=0; i < nodes.length; i++) { + if (nodes[i].nodeType != 1 || nodes[i] === this.target.node) continue; + var t = getNodeTop(nodes[i]); + var l = getNodeLeft(nodes[i]); + + nodes[i].style[transitionPrefix] = transformProperty + ' 0.2s ease-in-out'; + if (nodes[i].offsetParent) { + otherNodes.push({ + node: nodes[i], + baseTransform: getTransform(nodes[i]), + rects : getNodeBounds(nodes[i]), + posY: t + (t < zeroY ? getNodeHeight(nodes[i]) : 0) - zeroY, + posX: l + (l < zeroX ? getNodeWidth(nodes[i]) : 0) - zeroX, + }); + nodes[i].rects = getNodeBounds(nodes[i]); + + if (otherNodes[0].posX != otherNodes[otherNodes.length-1].posX) { + variationInX = true; + } + if (otherNodes[0].posY != otherNodes[otherNodes.length-1].posY) { + variationInY = true; + } + if (t != getNodeTop(this.target.node)) { + variationInY = true; + } + if (l != getNodeLeft(this.target.node)) { + variationInX = true; + } + } + } + + this.target.node.className += ' slip-reordering'; + this.target.node.style.zIndex = '99999'; + this.target.node.style[userSelectPrefix] = 'none'; + if (compositorDoesNotOrderLayers) { + // Chrome's compositor doesn't sort 2D layers + this.container.style.webkitTransformStyle = 'preserve-3d'; + } + this.container.origTransform = this.container.style[transformPrefix]; + this.container.origTransformOrigin = this.container.style[transformPrefix + "Origin"]; + this.container.origTransition = this.container.style[transitionPrefix]; + + var containerRects = this.container.getBoundingClientRect(); + if ( + (window.innerHeight < containerRects.height) || + (window.innerWidth < containerRects.width) + ) { + this.container.scale = Math.min( + (window.innerHeight-100)/containerRects.height, + (window.innerWidth)/containerRects.width + ); + + if (this.container.scale < 0.4) { + this.container.scale = 0.4; + }; + + this.container.style[transitionPrefix] = transformProperty + " .3s ease-in-out"; + this.container.style[transformPrefix + "Origin"] = (this.startPosition.x - containerRects.left) + "px " + (this.startPosition.y - containerRects.top) + "px"; + this.container.style[transformPrefix] = "scale(" + this.container.scale + ")"; + document.addEventListener("focus", this.preventFocus, true); + } + + function setPosition() { + /*jshint validthis:true */ + + if (mouseOutsideTimer) { + // don't care where the mouse is as long as it moves + clearTimeout(mouseOutsideTimer); mouseOutsideTimer = null; + } + + var move = this.getTotalMovement(); + if (!variationInX) { + move.x = 0; + } + if (!variationInY) { + move.y = 0; + } + + var targetRects = getNodeBounds(this.target.node); + this.target.node.focus(); + + var yAngleCorrection = Math.sin(2 * Math.PI / 180) * (move.x); + move.y -= yAngleCorrection; + +// this.target.node.style[transformPrefix] = 'translate(0,' + move.y + 'px) ' + hwTopLayerMagic + this.target.baseTransform.value; + this.target.node.style[transformPrefix] = 'rotate(2deg) translate(' + move.x + 'px,' + move.y + 'px) ' + hwTopLayerMagic + this.target.baseTransform.value; + this.target.node.style["animationName"] = 'none'; // FIXME; + // rotate around the position of the mouse to prevent the rotation from selecting text; + // this.target.node.style[transformPrefix + "Origin"] = (this.startPosition.x - targetRects.left) + "px " + (this.startPosition.y - targetRects.top) + "px"; + this.target.node.style[transformPrefix + "Origin"] = this.startOrigin; + + var height = this.target.height; + var width = this.target.width; + var currentTarget = this.target; + + // Set to the middle of the dragged element; + var currentRect = { + top : (currentTarget.rects.top + currentTarget.rects.bottom) / 2, + bottom: (currentTarget.rects.top + currentTarget.rects.bottom) / 2, + left : (currentTarget.rects.left + currentTarget.rects.right) / 2, + right: (currentTarget.rects.left + currentTarget.rects.right) / 2 + }; + + // Offset the mouse position; + currentRect.top += move.y; + currentRect.bottom += move.y; + currentRect.left += move.x; + currentRect.right += move.x; + + var hoverTarget; + + otherNodes.forEach(function(o){ + if ( + (currentRect.right > o.rects.left) && + (currentRect.left < o.rects.right) && + (currentRect.top < o.rects.bottom) && + (currentRect.bottom > o.rects.top) + ) { + hoverTarget = o; + } + return; + }); + + if (!hoverTarget) { + if ( + (currentRect.right > currentTarget.rects.left) && + (currentRect.left < currentTarget.rects.right) && + (currentRect.top < currentTarget.rects.bottom) && + (currentRect.bottom > currentTarget.rects.top) + ) { + // We are hovering over our old spot; + hoverTarget = currentTarget; + } else { + // No target is an exact match, find the closest one; + var bestDeltaMatch = currentTarget; + var delta1, delta2; + + otherNodes.forEach(function(o){ + delta1 = Math.pow((o.rects.top - currentRect.top), 2) + Math.pow((o.rects.right - currentRect.right), 2); + delta2 = Math.pow((bestDeltaMatch.rects.top - currentRect.top), 2) + Math.pow((bestDeltaMatch.rects.right - currentRect.right), 2); + if (delta1 < delta2) { + bestDeltaMatch = o; + } + + return; + }); + hoverTarget = bestDeltaMatch; + } + } + + if (hoverTarget) { + var hoverTargetIndex = currentTarget.parentList.indexOf(hoverTarget.node); + var currentTargetIndex = currentTarget.parentList.indexOf(currentTarget.node); + var beginIndex = Math.min(hoverTargetIndex, currentTargetIndex); + var endIndex = Math.max(hoverTargetIndex, currentTargetIndex); + + for (var i=0; i= beginIndex && index <= endIndex) { + var node1, node2; + if (hoverTargetIndex > currentTargetIndex) { + node1 = currentTarget.parentList[i+1]; + node2 = currentTarget.parentList[i]; + // console.log("swap " + (i+1) + " to " + (i)); + } else { + node1 = currentTarget.parentList[i]; + node2 = currentTarget.parentList[i+1]; + // console.log("swap " + (i) + " to " + (i+1)); + } + + var offY = node2.rects.top - node1.rects.top; + var offX = node2.rects.left - node1.rects.left; + + if (offX === 0) { + offY = (offY > 0) ? currentTarget.height : -currentTarget.height; + } + if (offY === 0) { + offX = (offX > 0) ? currentTarget.width: -currentTarget.width; + } + + // FIXME: should change accelerated/non-accelerated state lazily + // node1.node.style[transformPrefix] = off ? 'translate(0,'+off+'px) ' + hwLayerMagic + o.baseTransform.value : o.baseTransform.original; + otherNodes[i].node.style[transformPrefix] = (offX || offY) ? 'translate('+offX+'px,'+offY+'px) ' + hwLayerMagic + otherNodes[i].baseTransform.value : otherNodes[i].baseTransform.original; + otherNodes[i].node.style["animationName"] = "none"; + } + } + currentTarget.hoverTarget = hoverTarget; + } else { + for (var i=0; i index2) { + this.dispatch(this.target.node, 'reorder', {spliceIndex:index2, insertBefore:currentTarget.parentList[index2], originalIndex: originalIndex}); + } else { + this.dispatch(this.target.node, 'reorder', {spliceIndex:index2+1, insertBefore:currentTarget.parentList[index2+1], originalIndex: originalIndex}); + } + + this.setState(this.states.idle); + return false; + }, + }; + }, + }, + + attach: function(container) { + globalInstances++; + if (this.container) this.detach(); + + // In some cases taps on list elements send *only* click events and no touch events. Spotted only in Chrome 32+ + // Having event listener on body seems to solve the issue (although AFAIK may disable smooth scrolling as a side-effect) + if (!attachedBodyHandlerHack && needsBodyHandlerHack) { + attachedBodyHandlerHack = true; + document.body.addEventListener('touchstart', nullHandler, false); + } + + this.container = container; + this.otherNodes = []; + + document.addEventListener("selectionchange", this.onSelection, false); + + // cancel is called e.g. when iOS detects multitasking gesture + this.container.addEventListener('touchcancel', this.cancel, false); + this.container.addEventListener('touchstart', this.onTouchStart, false); + this.container.addEventListener('touchmove', this.onTouchMove, false); + this.container.addEventListener('touchend', this.onTouchEnd, false); + this.container.addEventListener('mousedown', this.onMouseDown, false); + // mousemove and mouseup are attached dynamically + }, + + detach: function() { + this.cancel(); + + this.container.removeEventListener('mousedown', this.onMouseDown, false); + this.container.removeEventListener('touchend', this.onTouchEnd, false); + this.container.removeEventListener('touchmove', this.onTouchMove, false); + this.container.removeEventListener('touchstart', this.onTouchStart, false); + this.container.removeEventListener('touchcancel', this.cancel, false); + + document.removeEventListener("selectionchange", this.onSelection, false); + + globalInstances--; + if (!globalInstances && attachedBodyHandlerHack) { + attachedBodyHandlerHack = false; + document.body.removeEventListener('touchstart', nullHandler, false); + } + }, + + setState: function(newStateCtor){ + if (this.state) { + if (this.state.ctor === newStateCtor) return; + if (this.state.leaveState) this.state.leaveState.call(this); + } + + // Must be re-entrant in case ctor changes state + var prevState = this.state; + var nextState = newStateCtor.call(this); + if (this.state === prevState) { + nextState.ctor = newStateCtor; + this.state = nextState; + } + }, + + findTargetNode: function(targetNode) { + while(targetNode && targetNode.parentNode !== this.container) { + targetNode = targetNode.parentNode; + } + return targetNode; + }, + + onSelection: function(e) { + var isRelated = e.target === document || this.findTargetNode(e); + if (!isRelated) return; + + this.selectionChanged = true; + }, + + addMouseHandlers: function() { + // unlike touch events, mousemove/up is not conveniently fired on the same element, + // but I don't need to listen to unrelated events all the time + if (!this.mouseHandlersAttached) { + this.mouseHandlersAttached = true; + document.documentElement.addEventListener('mouseleave', this.onMouseLeave, false); + window.addEventListener('mousemove', this.onMouseMove, true); + window.addEventListener('mouseup', this.onMouseUp, true); + window.addEventListener('blur', this.cancel, false); + window.addEventListener("scroll", this.onScroll); + + } + }, + + removeMouseHandlers: function() { + if (this.mouseHandlersAttached) { + this.mouseHandlersAttached = false; + document.documentElement.removeEventListener('mouseleave', this.onMouseLeave, false); + window.removeEventListener('mousemove', this.onMouseMove, true); + window.removeEventListener('mouseup', this.onMouseUp, true); + window.removeEventListener('blur', this.cancel, false); + window.removeEventListener("scroll", this.onScroll); + } + }, + + onMouseLeave: function(e) { + if (this.usingTouch) return; + + if (e.target === document.documentElement || e.relatedTarget === document.documentElement) { + if (this.state.onLeave) { + this.state.onLeave.call(this); + } + } + }, + preventDragStart : function(e) { + e.preventDefault(); + return false; + }, + preventFocus : function(e) { + e.stopPropagation(); + e.target.blur(); + }, + onMouseDown: function(e) { + if (this.usingTouch || e.button != 0 || !this.setTarget(e)) return; + + document.addEventListener("dragstart", this.preventDragStart); + + this.addMouseHandlers(); // mouseup, etc. + + this.canPreventScrolling = true; // or rather it doesn't apply to mouse + + this.startAtPosition({ + x: e.clientX, + y: e.clientY, + time: e.timeStamp, + }); + }, + + onTouchStart: function(e) { + this.usingTouch = true; + this.canPreventScrolling = true; + + // This implementation cares only about single touch + if (e.touches.length > 1) { + this.setState(this.states.idle); + return; + } + + if (!this.setTarget(e)) return; + + this.startAtPosition({ + x: e.touches[0].clientX, + y: e.touches[0].clientY, + time: e.timeStamp, + }); + }, + + setTarget: function(e) { + var targetNode = this.findTargetNode(e.target); + if (!targetNode) { + this.setState(this.states.idle); + return false; + } + + //check for a scrollable parent + var scrollContainer = targetNode.parentNode; + while (scrollContainer){ + if (scrollContainer.scrollHeight > scrollContainer.clientHeight && window.getComputedStyle(scrollContainer)['overflow-y'] != 'visible') break; + else scrollContainer = scrollContainer.parentNode; + } + + this.target = { + originalTarget: e.target, + node: targetNode, + scrollContainer: scrollContainer, + baseTransform: getTransform(targetNode), + }; + return true; + }, + + startAtPosition: function(pos) { + this.startPosition = this.previousPosition = this.latestPosition = pos; + + var targetRects = this.target.node.getBoundingClientRect(); + this.startOrigin = (this.startPosition.x - targetRects.left) + "px " + (this.startPosition.y - targetRects.top) + "px"; + var self = this; + window.setTimeout(function() { + self.selectionChanged = false; + }, 5); + this.setState(this.states.undecided); + var scrollable = this.target.scrollContainer || document.body; + this.scrollTopStart = scrollable.scrollTop; + this.scrollLeftStart = scrollable.scrollLeft; + this.scrollTopDelta = 0; + this.scrollLeftDelta = 0; + }, + + updatePosition: function(e, pos) { + if(this.target == null) + return; + this.latestPosition = pos; + + var triggerOffset = 40, + offset = 0; + + var scrollable = this.target.scrollContainer || document.body, + containerRect = scrollable.getBoundingClientRect(), + targetRect = this.target.node.getBoundingClientRect(), + bottomOffset = Math.min(containerRect.bottom, window.innerHeight) - targetRect.bottom, + topOffset = targetRect.top - Math.max(containerRect.top, 0); + + if (bottomOffset < triggerOffset){ + offset = triggerOffset - bottomOffset; + } + else if (topOffset < triggerOffset){ + offset = topOffset - triggerOffset; + } + + var prevScrollTop = scrollable.scrollTop; +// scrollable.scrollTop += offset; // commented out, this causes issues it seems. When the editor is scrolled down, dragging a form element would cause the page to scroll to top; removing this line prevents that. + if (prevScrollTop != scrollable.scrollTop) this.startPosition.y += prevScrollTop-scrollable.scrollTop; + + if (this.state.onMove) { + if (this.state.onMove.call(this) === false) { + e.preventDefault(); + } + } + + // sample latestPosition 100ms for velocity + if (this.latestPosition.time - this.previousPosition.time > 100) { + this.previousPosition = this.latestPosition; + } + }, + + onScroll : function(e) { + var scrollable = this.target.scrollContainer || document.body; + + this.scrollTopDelta = this.scrollTopStart - scrollable.scrollTop; + this.scrollLeftDelta = this.scrollLeftStart - scrollable.scrollLeft; + + this.updatePosition(e, this.latestPosition); + }, + + onMouseMove: function(e) { + this.updatePosition(e, { + x: e.clientX, + y: e.clientY, + time: e.timeStamp, + }); + }, + + onTouchMove: function(e) { + this.updatePosition(e, { + x: e.touches[0].clientX, + y: e.touches[0].clientY, + time: e.timeStamp, + }); + + // In Apple's touch model only the first move event after touchstart can prevent scrolling (and event.cancelable is broken) + this.canPreventScrolling = false; + }, + + onMouseUp: function(e) { + if (this.usingTouch || e.button !== 0) return; + + if (this.state.onEnd && false === this.state.onEnd.call(this)) { + e.preventDefault(); + } + + document.removeEventListener("dragstart", this.preventDragStart); + document.removeEventListener("focus", this.preventFocus, true); + }, + + onTouchEnd: function(e) { + if (e.touches.length > 1) { + this.cancel(); + } else if (this.state.onEnd && false === this.state.onEnd.call(this)) { + e.preventDefault(); + } + document.removeEventListener("focus", this.preventFocus, true); + }, + + getTotalMovement: function() { + var scale = this.container.scale; + if (typeof scale === "undefined") { + scale = 1; + } + + return { + x:(this.latestPosition.x - this.startPosition.x - this.scrollLeftDelta)/scale, + y:(this.latestPosition.y - this.startPosition.y - this.scrollTopDelta)/scale, + }; + }, + + getAbsoluteMovement: function() { + var scale = this.container.scale; + if (typeof scale === "undefined") { + scale = 1; + } + return { + x: Math.abs(this.latestPosition.x - this.startPosition.x)/scale, + y: Math.abs(this.latestPosition.y - this.startPosition.y)/scale, + time:this.latestPosition.time - this.startPosition.time, + }; + }, + + dispatch: function(targetNode, eventName, detail) { + var event = document.createEvent('CustomEvent'); + if (event && event.initCustomEvent) { + event.initCustomEvent('slip:' + eventName, true, true, detail); + } else { + event = document.createEvent('Event'); + event.initEvent('slip:' + eventName, true, true); + event.detail = detail; + } + return targetNode.dispatchEvent(event); + }, + + getSiblings: function(target) { + var siblings = []; + var tmp = target.node.nextSibling; + while(tmp) { + if (tmp.nodeType == 1) siblings.push({ + node: tmp, + baseTransform: getTransform(tmp), + }); + tmp = tmp.nextSibling; + } + return siblings; + }, + + animateToZero: function(callback, target) { + // save, because this.target/container could change during animation + target = target || this.target; + + target.node.style[transitionPrefix] = transformProperty + ' 0.1s ease-out'; + target.node.style[transformPrefix] = 'translate(0,0) ' + hwLayerMagic + target.baseTransform.value; + setTimeout(function(){ + target.node.style[transitionPrefix] = ''; + target.node.style[transformPrefix] = target.baseTransform.original; + if (callback) callback.call(this, target); + }.bind(this), 101); + }, + + animateSwipe: function(callback) { + var target = this.target; + var siblings = this.getSiblings(target); + var emptySpaceTransform = 'translate(0,' + this.target.height + 'px) ' + hwLayerMagic + ' '; + + // FIXME: animate with real velocity + target.node.style[transitionPrefix] = 'all 0.1s linear'; + target.node.style[transformPrefix] = ' translate(' + (this.getTotalMovement().x > 0 ? '' : '-') + '100%,0) ' + hwLayerMagic + target.baseTransform.value; + + setTimeout(function(){ + if (callback.call(this, target)) { + siblings.forEach(function(o){ + o.node.style[transitionPrefix] = ''; + o.node.style[transformPrefix] = emptySpaceTransform + o.baseTransform.value; + }); + setTimeout(function(){ + siblings.forEach(function(o){ + o.node.style[transitionPrefix] = transformProperty + ' 0.1s ease-in-out'; + o.node.style[transformPrefix] = 'translate(0,0) ' + hwLayerMagic + o.baseTransform.value; + }); + setTimeout(function(){ + siblings.forEach(function(o){ + o.node.style[transitionPrefix] = ''; + o.node.style[transformPrefix] = o.baseTransform.original; + }); + },101); + }, 1); + } + }.bind(this), 101); + }, + }; + + // AMD + if ('function' === typeof define && define.amd) { + define(function(){ + return Slip; + }); + } + return Slip; +})(); \ No newline at end of file diff --git a/www/simply/toolbar.simply-basepack.html b/www/simply/toolbar.simply-basepack.html new file mode 100644 index 0000000..06ab6e9 --- /dev/null +++ b/www/simply/toolbar.simply-basepack.html @@ -0,0 +1,5371 @@ +
+
+
    +
  • + +
  • +
  • + +
  • +
  • + +
  • +
  • + +
  • +
+
+
+
+

*HTML Toolbar for Text Cursor*

+
+
    +
  • +
  • +
  • +
  • +
  • +
+
+
    +
  • +
+
    +
  • +
  • +
  • +
  • +
+
+
+
+
+
    +
  • +
  • +
  • +
  • +
  • +
+
+
+
    +
  • +
  • +
+
+
+
+
+

*HTML Toolbar for Text Selection*

+
+
    +
  • +
  • +
  • +
  • +
  • +
  • +
+
+
    +
  • +
+
    +
  • +
  • +
  • +
  • +
+
+
+
+ +
+
    +
  • +
  • +
  • +
  • +
  • +
+
+
+
    +
  • +
  • +
+
+
+
+ +
+

HTML Image Toolbar

+
+
    +
  • +
  • +
  • +
  • +
  • +
  • +
+
+
+
+
    +
  • +
  • +
  • +
+
    +
  • +
  • +
  • +
  • +
+
+
+
+
+
+
+ +
+
+
+

HTML Image Toolbar

+
+
    +
  • +
  • +
+
+
+
+
+
+
+
+
+
+ + +
+
+
    + +
  • +
  • +
  • +
  • + + +
  • + + +
  • +
  • +
+
+
+
+
+ + +
+

HTML Iframe Toolbar

+
+
    +
  • +
+
+
+
+
+
+
+

*Objectlist Toolbar*

+
+
    +
  • +
  • +
  • +
+
+
    +
  • +
+
+
+
    +
  • +
+
+
+
+
+

*Objectlist Toolbar*

+
+
    +
  • +
+
+
    +
  • +
+
+
+
+
+

*Objectlist Toolbar*

+
+
    +
  • +
  • +
  • +
  • +
+
+
    +
  • +
+
+
+
    +
  • +
+
+
+
    +
  • +
+
+
+
+
+

Insert icon toolbar

+
+
    +
  • +
+
+
+
+
+
    +
  • +
  • +
  • +
+
+
+ + +
+
+ +
+
+
+
+
    +
  • +
+
+
+ +
+
+ +
Saving...
+
Please wait...
+
+
+ + +
+
+
    +
  • +
  • +
  • +
+ +
+
+
    +
  • +
+
+
+ +
+
+
    +
  • + +
  • +
  • +
+
+
+ +
+
+
    + +
  • +
+
+
+ + +
+
+
    +
  • +
  • +
+
+
+
+
+ + +
+
+
    +
  • +
  • +
  • +
  • + +
  • + +
+
+
+
+
Theirs
+
Mine
+
+
+
+
    +
  • Review the differences and choose which of them to use.
  • +
  • +
+
+
+ +
+
+
    +
  • +
  • +
  • +
  • +
  • +
+
+
+ +
+
+
Your key
+
Valid for
+
+ +
+
+
+ +
+
+
+ + + +
+ +
+
+
+ + diff --git a/www/simply/toolbar.simply-basepack.html.foo b/www/simply/toolbar.simply-basepack.html.foo new file mode 100644 index 0000000..34b7d37 --- /dev/null +++ b/www/simply/toolbar.simply-basepack.html.foo @@ -0,0 +1,5354 @@ +
+
+
    +
  • + +
  • +
  • + +
  • +
  • + +
  • +
  • + +
  • +
+
+
+
+

*HTML Toolbar for Text Cursor*

+
+
    +
  • +
  • +
  • +
  • +
  • +
+
+
    +
  • +
+
    +
  • +
  • +
  • +
  • +
+
+
+
+
+
    +
  • +
  • +
  • +
  • +
  • +
+
+
+
    +
  • +
  • +
+
+
+
+
+

*HTML Toolbar for Text Selection*

+
+
    +
  • +
  • +
  • +
  • +
  • +
  • +
+
+
    +
  • +
+
    +
  • +
  • +
  • +
  • +
+
+
+
+ +
+
    +
  • +
  • +
  • +
  • +
  • +
+
+
+
    +
  • +
  • +
+
+
+
+ +
+

HTML Image Toolbar

+
+
    +
  • +
  • +
  • +
  • +
  • +
  • +
+
+
+
+
    +
  • +
  • +
  • +
+
    +
  • +
  • +
  • +
  • +
+
+
+
+
+
+
+ +
+
+
+

HTML Image Toolbar

+
+
    +
  • +
  • +
+
+
+
+
+
+
+
+
+
+ + +
+
+
    + +
  • +
  • +
  • +
  • + + +
  • + + +
  • +
  • +
+
+
+
+
+ + +
+

HTML Iframe Toolbar

+
+
    +
  • +
+
+
+
+
+
+
+

*Objectlist Toolbar*

+
+
    +
  • +
  • +
  • +
+
+
    +
  • +
+
+
+
    +
  • +
+
+
+
+
+

*Objectlist Toolbar*

+
+
    +
  • +
+
+
    +
  • +
+
+
+
+
+

*Objectlist Toolbar*

+
+
    +
  • +
  • +
  • +
  • +
+
+
    +
  • +
+
+
+
    +
  • +
+
+
+
    +
  • +
+
+
+
+
+

Insert icon toolbar

+
+
    +
  • +
+
+
+
+
+
    +
  • +
  • +
  • +
+
+
+ + +
+
+ +
+
+
+
+
    +
  • +
+
+
+ +
+
+ +
Saving...
+
Please wait...
+
+
+ + +
+
+
    +
  • +
  • +
  • +
+ +
+
+
    +
  • +
+
+
+ +
+
+
    +
  • + +
  • +
  • +
+
+
+ +
+
+
    + +
  • +
+
+
+ + +
+
+
    +
  • +
  • +
+
+
+
+
+ + +
+
+
    +
  • +
  • +
  • +
  • + +
  • + +
+
+
+
+
Theirs
+
Mine
+
+
+
+
    +
  • Review the differences and choose which of them to use.
  • +
  • +
+
+
+ +
+
+
    +
  • +
  • +
  • +
  • +
  • +
+
+
+ +
+
+
Your key
+
Valid for
+
+ +
+
+
+ +
+
+
+ + + +
+ +
+
+
+ + diff --git a/www/simply/toolbar.simply-icon.html b/www/simply/toolbar.simply-icon.html new file mode 100644 index 0000000..ae99d37 --- /dev/null +++ b/www/simply/toolbar.simply-icon.html @@ -0,0 +1,16 @@ +
+

Insert icon toolbar

+
+
    +
  • +
+
+
+ \ No newline at end of file diff --git a/www/simply/toolbar.simply-iframe.html b/www/simply/toolbar.simply-iframe.html new file mode 100644 index 0000000..c90bb69 --- /dev/null +++ b/www/simply/toolbar.simply-iframe.html @@ -0,0 +1,82 @@ +
+

HTML Iframe Toolbar

+
+
    +
  • +
+
+
+
+
+
+ \ No newline at end of file diff --git a/www/simply/toolbar.simply-image.html b/www/simply/toolbar.simply-image.html new file mode 100644 index 0000000..9e40ba3 --- /dev/null +++ b/www/simply/toolbar.simply-image.html @@ -0,0 +1,673 @@ +
+

HTML Image Toolbar

+
+
    +
  • +
  • +
  • +
  • +
  • +
  • +
+
+
+
+
    +
  • +
  • +
  • +
+
    +
  • +
  • +
  • +
  • +
+
+
+
+
+
+
+ +
+
+
+

HTML Image Toolbar

+
+
    +
  • +
  • +
+
+
+
+
+
+
+
+
+
+ + \ No newline at end of file diff --git a/www/simply/toolbar.simply-list.html b/www/simply/toolbar.simply-list.html new file mode 100755 index 0000000..b731669 --- /dev/null +++ b/www/simply/toolbar.simply-list.html @@ -0,0 +1,448 @@ +
+

*Objectlist Toolbar*

+
+
    +
  • +
  • +
  • +
+
+
    +
  • +
+
+
+
    +
  • +
+
+
+
+
+

*Objectlist Toolbar*

+
+
    +
  • +
+
+
    +
  • +
+
+
+
+
+

*Objectlist Toolbar*

+
+
    +
  • +
  • +
  • +
  • +
+
+
    +
  • +
+
+
+
    +
  • +
+
+
+
    +
  • +
+
+
+
+ \ No newline at end of file diff --git a/www/simply/toolbar.simply-main-toolbar.html b/www/simply/toolbar.simply-main-toolbar.html new file mode 100755 index 0000000..710bba1 --- /dev/null +++ b/www/simply/toolbar.simply-main-toolbar.html @@ -0,0 +1,38 @@ +
+
+
    +
  • + +
  • +
  • + +
  • +
  • + +
  • +
  • + +
  • +
+
+
+ \ No newline at end of file diff --git a/www/simply/toolbar.simply-selectable.html b/www/simply/toolbar.simply-selectable.html new file mode 100644 index 0000000..c6e19df --- /dev/null +++ b/www/simply/toolbar.simply-selectable.html @@ -0,0 +1,167 @@ + \ No newline at end of file diff --git a/www/simply/toolbar.simply-text.html b/www/simply/toolbar.simply-text.html new file mode 100644 index 0000000..76693c5 --- /dev/null +++ b/www/simply/toolbar.simply-text.html @@ -0,0 +1,998 @@ +
+

*HTML Toolbar for Text Cursor*

+
+
    +
  • +
  • +
  • +
  • +
  • +
+
+
    +
  • +
+
    +
  • +
  • +
  • +
  • +
+
+
+
+
+
    +
  • +
  • +
  • +
  • +
  • +
+
+
+
    +
  • +
  • +
+
+
+
+
+

*HTML Toolbar for Text Selection*

+
+
    +
  • +
  • +
  • +
  • +
  • +
  • +
+
+
    +
  • +
+
    +
  • +
  • +
  • +
  • +
+
+
+
+ +
+
    +
  • +
  • +
  • +
  • +
  • +
+
+
+
    +
  • +
  • +
+
+
+
+ + \ No newline at end of file diff --git a/www/simply/toolbars.js b/www/simply/toolbars.js new file mode 100755 index 0000000..d01c6e9 --- /dev/null +++ b/www/simply/toolbars.js @@ -0,0 +1,1303 @@ + editor.toolbar = { + getToolbarEl : function(el) { + while ( el && el.tagName!='div' && !/\bsimply-toolbar\b/.test(el.className) ) { + el = el.parentNode; + } + return el; + }, + getSectionEl : function(el) { + while ( el && el.tagName!='div' && !/\bsimply-toolbar-section\b/.test(el.className) ) { + el = el.parentNode; + } + return el; + }, + getDialogEl : function(el) { + while ( el && el.tagName!='div' && !/\bsimply-dialog\b/.test(el.className) ) { + el = el.parentNode; + } + return el; + }, + handleButton : function(el) { + var toolbar = editor.toolbar.getToolbarEl(el); + var section = editor.toolbar.getSectionEl(el); + var i; + var l; + var selectedSectionButtons; + + if (el.getAttribute("disabled")) { + return true; + } + if ( toolbar ) { + if ( !section ) { + var sections = toolbar.querySelectorAll('.simply-toolbar-section.simply-selected, .simply-toolbar-status'); + for ( i=0, l=sections.length; i/g, ">") + .replace(/"/g, """) + .replace(/'/g, "'"); + }, + findClassNode : function(node, selector) { + // Helper function to find the node for a class + // selector; It searches starting on the given node + // and goes upwards to find the specific node; Only + // parents of the starting node are valid results; + + if (!selector) { + selector = hope.render.html.rules.nestingSets.block.join(","); // default to blocks only + } + var parents = editor.node.parents(node); + var query = ":scope > " + selector.replace(/,/, ', :scope >'); + for (var i=0; i -1) { + return targets[j]; + } + } + } + } + return false; + } + }; + + editor.context = { + touching : false, + skipUpdate : false, + explain : {}, + weigh : function(filter, targets) { + var sel = vdSelectionState.get(); + + var target = targets.shift(); + + var listBonus = false; + if (target && target.clickStart) { + listBonus = true; + } + + if (!filter.context) { + filter.context = "parent"; + } + + if (typeof editor.context.explain[filter.context] === "undefined") { + editor.context.explain[filter.context] = []; + } + editor.context.explain[filter.context].push({ + "filter" : filter, + "targets" : targets + }); + + while (target) { + var tempNode = document.createElement("DIV"); + tempNode.appendChild(target.cloneNode(false)); + + if (typeof editor.context.explain[filter.context] === "undefined") { + editor.context.explain[filter.context] = []; + } + + var result = 0; + if ( + ( (typeof filter.selector !== 'undefined') ? tempNode.querySelectorAll(":scope > " + filter.selector).length : true) && + ( (typeof filter["sel-collapsed"] !== 'undefined') ? (sel.collapsed == filter["sel-collapsed"]) : true) + ) { + editor.context.explain[filter.context].push("click depth score, +" + (50 * (targets.length+1)) + " points"); + result += 50 * (targets.length+1); // tagName weight + if (typeof filter.selector !== 'undefined') { + editor.context.explain[filter.context].push("class selector bonus, +" + (2*(filter.selector.split(".").length-1)) + " points"); + result += 2*(filter.selector.split(".").length-1); // Add the number of class selectors; + editor.context.explain[filter.context].push("attribute selectors bonus, +" + (2*(filter.selector.split("[").length-1)) + " points"); + result += 2*(filter.selector.split("[").length-1); // Add the number of attribute selectors + } + + if (listBonus) { + var rect = target.getBoundingClientRect(); + if ( + target.clickStart.x > rect.left && + target.clickStart.x < rect.right && + target.clickStart.y < rect.bottom && + target.clickStart.y > rect.top + ) { + // click was in the element; less value for lists and list items; + if (target.getAttribute("contenteditable") && filter.context && (typeof filter["list-bonus"] !== 'undefined')) { + editor.context.explain[filter.context].push("filter has list-bonus, but click was in the element, -5 points"); + result -= 5; + } + } else { + // click was outside the element; more value for lists and list items; + if (typeof filter["list-bonus"] !== 'undefined') { + editor.context.explain[filter.context].push("filter has list-bonus, click was outside the element; +" + 50 * (targets.length) + " points"); + result += 50 * (targets.length); + } + } + } + + if (typeof filter["sel-collapsed"] !== 'undefined') { + editor.context.explain[filter.context].push("filters on selection collapsed, +1 point"); + result += 1; + } + if (typeof filter.parent == 'undefined') { + editor.context.explain[filter.context].push("result = " + result); + return result; + } else { + var parentResult = editor.context.weigh(filter.parent, targets); + if (parentResult) { + editor.context.explain[filter.context].push("has parent filter value, +" + parentResult + " points"); + editor.context.explain[filter.context].push(editor.context.explain.parent); + editor.context.explain[filter.context].push("result = " + parseInt(result + parentResult)); + return result + parentResult; + } else { + editor.context.explain[filter.context].push("parent filter did not match, result = 0"); + return 0; + } + } + } + if (!(target.tagName.toLowerCase() == "td" && target.parentNode && target.parentNode.getAttribute("data-simply-list-item"))) { + // Special case for td, because the :before for the list item is set on the TD instead of the TR; We need to keep the list bonus one cycle longer; + listBonus = false; + } + target = targets.shift(); + } + editor.context.explain[filter.context].push("result = 0"); + return 0; + }, + get : function() { + editor.context.explain = {}; + + var sel = vdSelectionState ? vdSelectionState.get() : false; + + if (sel) { + var parent = vdSelection.getNode(sel); + + if ((parent && parent.getAttribute && (parent.getAttribute("contenteditable") || parent.getAttribute("data-simply-selectable"))) || editor.node.hasEditableParent(parent)) { + if (parent || parent.getAttribute || parent.getAttribute("contenteditable")) { + var validFilters = {}; + var bestFilter = false; + var bestFilterWeight = 0; + for (var i in editor.contextFilters) { + var filter = editor.contextFilters[i]; + var filterWeight = editor.context.weigh(filter, editor.node.parents(parent)); + + if (filterWeight) { + validFilters[i] = filterWeight; + if (filterWeight > bestFilterWeight) { + bestFilter = filter.context; + bestFilterWeight = filterWeight; + } + } + } + editor.context.explain.validFilters = validFilters; + + return bestFilter; + } else { + if (sel.collapsed) { + editor.context.explain['simply-text-cursor'] = ["cursor is in a contentEditable field and selection is collapsed."]; + return "simply-text-cursor"; + } else { + editor.context.explain['simply-text-selection'] = ["cursor is in a contentEditable field and selection is not collapsed."]; + return "simply-text-selection"; + } + } + } else { + editor.context.explain['simply-no-context'] = ["selection parent is not editable, not selectable and does not have an editable parent"]; + return "simply-no-context"; + } + } + }, + toolbar : { + getPosition : function(sel, useCursor) { + var ltop, lleft, rleft, rtop, top, left; + + var range = sel; //.getRangeAt(0); + if ( !range ) { + return null; + } + var rects = range.getClientRects(); + var parent = vdSelection.getNode(sel); + + if ( !rects.length ) { + muze.event.fire(range.startContainer, "databinding:pause"); + var focusedElement = document.querySelector(":focus"); + var selStart = focusedElement ? focusedElement.selectionStart : 0; + var selEnd = focusedElement ? focusedElement.selectionEnd : selStart; + + // insert element at range and get its position, other options aren't exact enough + var span = document.createElement('span'); + if ( span.getClientRects ) { + // Ensure span has dimensions and position by + // adding a zero-width space character + try { + span.appendChild( document.createTextNode("\u200b") ); + range.insertNode(span); + rects = span.getClientRects(); + var spanParent = span.parentNode; + spanParent.removeChild(span); + // Glue any broken text nodes back together + spanParent.normalize(); + } catch(e) { + console.log(e); + } + if (focusedElement) { + focusedElement.focus(); // Restore focus after chrome lost it when inserting the span. + focusedElement.selectionStart = selStart; + focusedElement.selectionEnd = selEnd; + } + } + + + muze.event.fire(range.startContainer, "databinding:resume"); + } + if ( rects.length ) { + ltop = rects[0].top; + lleft = rects[0].left; + rleft = rects[rects.length-1].right; + rtop = rects[rects.length-1].bottom; + } + if ( parent && ( !rects.length || (parent.getAttribute("data-simply-selectable") ) ) ) { + pos = parent && parent.getBoundingClientRect ? parent.getBoundingClientRect() : { left: 0, top: 0, right: 0, bottom: 0}; + lleft = pos.left; + ltop = pos.top; + rleft = pos.right; + rtop = pos.bottom; + } + // fallback... if nothing else works + if ( lleft === 0 && rleft === 0 && ltop === 0 && rtop === 0 ) { + parent = vdSelection.parentNode(sel); + if ( !parent || !parent.getBoundingClientRect ) { + return false; + } + pos = parent.getBoundingClientRect(); + lleft = pos.left; + ltop = pos.top; + rleft = pos.right; + rtop = pos.bottom; + } + + if (window.getComputedStyle(document.body).position == "static") { + ltop += Math.max(document.body.scrollTop, document.documentElement.scrollTop); + lleft += Math.max(document.body.scrollLeft, document.documentElement.scrollLeft); + rtop += Math.max(document.body.scrollTop, document.documentElement.scrollTop); + rleft += Math.max(document.body.scrollLeft, document.documentElement.scrollLeft); + } else { + ltop -= document.body.getClientRects()[0].top; + rtop -= document.body.getClientRects()[0].top; + } + + top = Math.max(ltop, rtop); + left = lleft + ((rleft - lleft) / 2); + + return { top: top, left: left, ltop: ltop, lleft: lleft, rtop: rtop, rleft: rleft }; + }, + reposition : function() { + var markerLeft, scrollHeight, scrollTop; + + var sel = vdSelectionState.get(); + var currentContext = editor.context.get(); + var activeSection = editor.toolbarsContainer.getElementById(currentContext); + var pos = editor.context.toolbar.getPosition(sel); + if ( !pos || !activeSection ) { + // editor.context.toolbar.hide = true; + return; + } + + // skip repositioning if the element is + // returning all 0 values, this happens when + // the selection element is no longer in + // view (for instance, pulldown menu element + // which is no longer active). It is better + // to leave the toolbar where it is in this + // case; + if (pos.top === 0 && pos.left === 0 && pos.ltop === 0 && pos.lleft === 0 && pos.rtop === 0 && pos.rleft === 0) { + return; + } + + var top = pos.top; + var left = pos.left; + var activeToolbar = activeSection.querySelector("div.simply-toolbar"); + top += document.body.offsetTop; + var newleft = left - (activeToolbar.offsetWidth/2); + + // Recalculate toolbar position if it is off-screen left/right + if (newleft < document.body.scrollLeft) { + markerLeft = Math.max(activeToolbar.offsetWidth/2 + newleft - document.body.scrollLeft, 20) + "px"; + } else if (newleft + activeToolbar.offsetWidth > document.body.offsetWidth + document.body.scrollLeft) { + var delta = newleft + activeToolbar.offsetWidth - document.body.offsetWidth - document.body.scrollLeft; + markerLeft = Math.min(activeToolbar.offsetWidth/2 + delta, activeToolbar.offsetWidth - 20) + "px"; + } else { + markerLeft = "50%"; + } + activeToolbar.getElementsByClassName("marker")[0].style.left = markerLeft; + + // Recalculate toolbar position if it is off-screen left/right + if (newleft < document.body.scrollLeft) { + newleft = document.body.scrollLeft; + } else if (newleft + activeToolbar.offsetWidth > document.body.offsetWidth + document.body.scrollLeft) { + newleft = document.body.offsetWidth - activeToolbar.offsetWidth + document.body.scrollLeft; + } else { + } + + // Recalculate the toolbar width, the browser messes this up because the buttons are floating; + var buttons = activeToolbar.querySelectorAll("ul.simply-buttons > li"); + var width = activeToolbar.offsetWidth; + var newWidth = 0; + for (var i=0; i editPaneRect.height ) { + // toolbar extends beyond bottom edge if not repositioned + var mintop = Math.min(pos.ltop, pos.rtop); + if ( mintop + toolbarRect.height <= editPaneRect.height ) { + // toolbar can be repositioned + // FIXME: min top should be position of the cursor, not selection + top = editPaneRect.height - toolbarRect.height - 32; // 32 to allow space for scrollbars; + } else { + top = mintop; + scrollHeight = Math.max(document.body.scrollHeight, document.body.clientHeight); + scrollTop = Math.max(document.body.scrollTop, document.documentElement.scrollTop); + if ( scrollTop >= (scrollHeight - document.body.clientHeight - toolbarRect.height ) ) { + // no more scroll space, so add it. + document.body.classList.add('simply-footer-space'); + } + + /* + if ( top + toolbarRect.height > editPaneRect.height ) { + // FIXME: even after adding footer space, we still don't fit. Now what? + } + */ + } + } + + if ( document.body.classList.contains('simply-footer-space') ) { + scrollHeight = Math.max(document.body.scrollHeight, document.body.clientHeight); + scrollTop = Math.max(document.body.scrollTop, document.documentElement.scrollTop); + if ( scrollTop < (scrollHeight - document.body.clientHeight - toolbarRect.height - 132 )) { + document.body.classList.remove('simply-footer-space'); + } + } + activeSection.style.top = top + 10 + "px"; // 10 is the height of the marker arrow + activeSection.style.left = newleft + "px"; + } + }, + show : function() { + var currentContext = editor.context.get(); + + var sections = editor.toolbarsContainer.querySelectorAll("section.simply-section"); + for (var i=0; i -1) { + sections[j].style.left = "-10000px"; + } + } + } + }; + //window.setTimeout(hideIt, 200); + + var activeSection = editor.toolbarsContainer.getElementById(currentContext); + // console.log(activeSection); + + if (activeSection && !editor.context.toolbar.hide) { + var htmlContext = activeSection.querySelectorAll("div.simply-toolbar-status")[0]; + if ( htmlContext ) { + if (!htmlContext.classList.contains("simply-selected")) { + htmlContext.classList.add("simply-selected"); + } + } + // activeSection.style.display = "block"; + activeSection.className += " active"; + hideIt(); // window.setTimeout(hideIt, 200); + + + var sel = vdSelectionState.get(); + var parent = vdSelection.getNode(sel); + if (parent == document) { + return; + } + + editor.context.toolbar.reposition(); + + if (editor.context.touching) { + // FIXME: Android fix here + // restore selection triggers contextupdate, which triggers restore selection - this hopefully prevents that loop. + editor.context.skipUpdate = true; + if (!sel.collapsed) { + // FIXME: This reverses the + // current selection, which + // causes problems selecting + // from right to left; It is + // needed to allow text + // selection on android. + vdSelectionState.restore(sel); + } + window.setTimeout(function() { editor.context.skipUpdate = false;}, 20); + } + } else { + hideIt(); + } + + if (editor.toolbarsContainer.getElementById("VD_DETAILS")) { + if (showBorders) { + editor.toolbarsContainer.getElementById('VD_DETAILS').classList.add('simply-selected'); + } else { + editor.toolbarsContainer.getElementById('VD_DETAILS').classList.remove('simply-selected'); + } + } + + if (editor.toolbarsContainer.getElementById('vdShowTagBoundaries')) { + if (showTagBoundaries) { + editor.toolbarsContainer.getElementById('vdShowTagBoundaries').classList.add('simply-selected'); + } else { + editor.toolbarsContainer.getElementById('vdShowTagBoundaries').classList.remove('simply-selected'); + } + } + + if (editor.toolbarsContainer.getElementById('vdShowTagStack')) { + if (showTagStack) { + editor.toolbarsContainer.getElementById('vdShowTagStack').classList.add('simply-selected'); + } else { + editor.toolbarsContainer.getElementById('vdShowTagStack').classList.remove('simply-selected'); + } + } + }, + initProperties : function(context) { + switch (context) { + case "simply-text-selection" : + case "simply-table-cell-selection": + case "simply-image" : + case "simply-hyperlink" : + editor.context.toolbar.hide = false; + break; + default: + break; + } + + if (editor.toolbars[context] && editor.toolbars[context].update) { + editor.toolbar.updating = true; + editor.toolbars[context].update(editor.toolbarsContainer.getElementById(context)); + editor.toolbar.updating = false; + } + }, + fixSelection : function() { + // check the current selection and update it if necessary + var sel = vdSelectionState.get(); + var parent = vdSelection.getNode(sel); + + // console.log(parent); + var selParent = editor.node.getUneditableParent(parent); + if (selParent) { + // console.log(selParent); + // Selection if part of something uneditable + sel.selectNode(selParent); + sel.startContainer.ownerDocument.defaultView.getSelection().removeAllRanges(); + sel.startContainer.ownerDocument.defaultView.getSelection().addRange(sel); + vdSelectionState.save(sel); + sel.startContainer.ownerDocument.defaultView.getSelection().removeAllRanges(); + } + + }, + getTagStack : function() { + var sel = vdSelectionState.get(); + var parent = vdSelection.getNode(sel); + var newContextStack = []; + + if (sel) { + while (parent && editor.node.hasEditableParent(parent) && parent.parentNode) { + newContextStack.push(parent); + parent=parent.parentNode; + } + } + + return newContextStack; + }, + update : function() { + // Check if the current selection is part of an uneditable thing, if so, move the selection to that parent; + var sel = vdSelectionState.get(); + var parent = vdSelection.getNode(sel); + + // Skip the update when the selection is within a toolbar; + if (editor.node.hasToolbarParent(parent)) { + return; + } + if (document.querySelector(":focus") && editor.node.hasToolbarParent(document.querySelector(":focus"))) { + return; + } + if (editor.context.skipUpdate) { + return; + } + if (editor.context.touching) { + return; + } + if (editor.toolbarsContainer.querySelector(".simply-dialog.active")) { + return; + } + + var field = editor.node.getEditableField(); + hopeEditor = field.hopeEditor; + editor.context.fixSelection(); + if ((typeof hopeEditor !== "undefined") && hopeEditor.needsUpdate) { + hopeEditor.selection.updateRange(); + hopeEditor.parseHTML(); // FIXME: This causes flickering in Firefox and random cursor movement; + hopeEditor.needsUpdate = false; + } + editor.context.show(); + vdHtmlContextStack = editor.context.getTagStack(); + } + }; + + editor.plugins.dialog = { + backdrop : null, + open : function(target, callback) { + vdSelectionState.save(vdSelectionState.get()); + editor.plugins.dialog.selectionIsCollapsed = window.getSelection().isCollapsed; + + if (!editor.plugins.dialog.backdrop) { + editor.plugins.dialog.createBackdrop(); + } + document.body.classList.add("simply-overflow-hidden"); + editor.plugins.dialog.backdrop.style.display = "block"; + target.classList.add("active"); + + editor.plugins.dialog.currentField = editor.node.getEditableField(); + if (editor.plugins.dialog.currentField.hopeEditor) { + editor.plugins.dialog.currentField.hopeEditor.selection.updateRange(); + var range = editor.plugins.dialog.currentField.hopeEditor.selection.getRange(); + editor.plugins.dialog.currentField.hopeEditor.currentRange = range; + } + + if (typeof callback == "function") { + callback(); + } + window.setTimeout(function() { + var sel = window.getSelection(); + sel.removeAllRanges(); + }, 10); + }, + close : function(callback) { + target = editor.toolbarsContainer.querySelector(".simply-dialog.active"); + editor.plugins.dialog.backdrop.style.display = "none"; + document.body.classList.remove("simply-overflow-hidden"); + target.classList.remove("active"); + + var hopeEditor = editor.plugins.dialog.currentField.hopeEditor; + if (hopeEditor) { + editor.fireEvent("databinding:pause", editor.plugins.dialog.currentField); + hopeEditor.parseHTML(); + hopeEditor.update(); + hopeEditor.selection.updateRange(hopeEditor.currentRange.start, hopeEditor.currentRange.end); + hopeEditor.showCursor(); + editor.fireEvent("databinding:resume", editor.plugins.dialog.currentField); + } else { + vdSelectionState.restore(vdSelectionState.get()); + if (editor.plugins.dialog.selectionIsCollapsed) { + window.setTimeout(function() { + var sel = window.getSelection(); + sel.removeAllRanges(); + }, 10); + } + } + vdSelectionState.remove(); + if (typeof callback == "function") { + callback(); + } + }, + createBackdrop : function() { + if (!editor.plugins.dialog.backdrop) { + backdrop = document.createElement("IFRAME"); + backdrop.className = "simply-dialog-backdrop"; + backdrop.style.display = "none"; + backdrop.style.width = "100%"; + backdrop.style.height = "100%"; + backdrop.style.top = 0; + backdrop.style.left = 0; + backdrop.style.position = "fixed"; + backdrop.style.zIndex = 100001; + backdrop.style.border = 0; + backdrop.style.backgroundColor = "rgba(255,255,255,0.7)"; + document.body.appendChild(backdrop); + editor.plugins.dialog.backdrop = backdrop; + } + }, + fullscreen : function(button) { + var dialog = editor.plugins.dialog.getDialogEl(button); + if (dialog.classList.contains("fullscreen")) { + button.classList.remove("simply-selected"); + dialog.classList.remove("fullscreen"); + } else { + button.classList.add("simply-selected"); + dialog.classList.add("fullscreen"); + } + editor.fireEvent("resize", document); + }, + getDialogEl : function(el) { + while ( el && el.tagName!='div' && !/\bsimply-dialog\b/.test(el.className) ) { + el = el.parentNode; + } + return el; + } + }; + editor.addAction("simply-dialog-fullscreen", editor.plugins.dialog.fullscreen); + editor.addAction("simply-dialog-close", editor.plugins.dialog.close); + editor.addAction("simply-main-collapse", function() { + editor.toolbarsContainer.querySelector("#simply-main-toolbar").classList.toggle("simply-collapse"); + }); + + editor.context.toolbar.hide = false; + + document.addEventListener("click", function(event) { + var target = muze.event.target(event); + if( target.tagName.toLowerCase() === 'img' ) { + var range = document.createRange(); + range.selectNode(target); + var sel = window.getSelection(); + sel.removeAllRanges(); + sel.addRange(range); + if (focus in target) { + target.focus(); + } + editor.context.update(); + } + }); + + function monitorIframe() { + // monitor for iframes that get focus; + if (editor.monitor) { + // already monitoring iframes; + return; + } + + editor.monitor = setInterval(function(){ + var elem = document.activeElement; + if(elem && elem.tagName == 'IFRAME'){ + if (editor.context.currentIframe != elem) { + editor.context.currentIframe = elem; + var sel = vdSelectionState.get(); + sel.selectNode(elem); + sel.startContainer.ownerDocument.defaultView.getSelection().removeAllRanges(); + sel.startContainer.ownerDocument.defaultView.getSelection().addRange(sel); + vdSelectionState.save(sel); + sel.startContainer.ownerDocument.defaultView.getSelection().removeAllRanges(); + editor.context.update(); + } + } else { + if (editor.context.currentIframe) { + vdSelectionState.remove(); + vdSelectionState.restore(); + editor.context.update(); + editor.context.currentIframe = null; + } + } + }, 100); + } + + var vdSelection, vdSelectionState; + var initSelections = function() { + if (typeof simply === "undefined" || typeof simply.editor === "undefined") { + window.setTimeout(initSelections, 100); + return; + } + vdSelectionState = simply.editor.selection; + vdSelection = simply.dom.selection; + vdSelectionState.init(window); + simply.editor.selectionchange.start(document); // onselectionchange event for Firefox + + editor.selectionChangeTimer = false; + + muze.event.attach( document, 'selectionchange', function() { + if (editor.selectionChangeTimer) { + return; + } + // throttle selection changed - only execute this once in one loop; + editor.selectionChangeTimer = window.setTimeout(function() { + editor.selectionChangeTimer = false; + var field = editor.node.getEditableField(); + var hopeEditor = field.hopeEditor; + if (hopeEditor) { + if (hopeEditor.field == editor.node.getSimplyParent(document.activeElement)) { + editor.context.hopeEditor = hopeEditor; + hopeEditor.selection.updateRange(); + var range = hopeEditor.selection.getRange(); + hopeEditor.currentRange = range; + } + } + + if (editor.context.touching) { + editor.context.touching = false; // force update when selection changed; + editor.context.update(); + editor.context.touching = true; + } else { + // editor.context.update(); // removed; the update will be triggered by the mouseup/keyup events; + } + }, 0); + }); + + muze.event.attach( document, 'keyup', function(evt) { + // skip context updates when the keyup event is coming from autofilled (username/password) inputs, to prevent looping in chrome when credentials are saved. + try { + if (evt.target && evt.target.matches && evt.target.matches(":-webkit-autofill")) { + return; + } + } catch(e) { + if (e.code !== e.SYNTAX_ERR) { + throw e; + } + if (!e.message.match(":-webkit-autofill")) { + throw e; + } + // catch the error for SyntaxError: ':-webkit-autofill' is not a valid selector, let the rest bubble up; + } + editor.context.update(); + }); + + muze.event.attach( document, 'mouseup', function(evt) { + if (!document.querySelector(":focus")) { + // firefox on mac doesn't set focus for the mouseup until after the event; + evt.target.focus(); + } + editor.context.toolbar.hide = false; + editor.context.update(); + }); + + muze.event.attach( document, 'scroll', editor.context.toolbar.reposition ); + muze.event.attach( document, 'touchstart', function(evt) { + editor.context.touching = true; + }); + muze.event.attach( document, 'touchend', function(evt) { + window.setTimeout(function() { + editor.context.touching = false; + }, 1); + }); + + monitorIframe(); + }; + + initSelections(); \ No newline at end of file From e4c5b43b1771d6bca071f507b9b82e0844bd1013 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Tue, 11 Jun 2024 12:32:02 +0200 Subject: [PATCH 16/28] rename .sb, --sb classes to simplycode --- .../commands/autoRunPreviews.js | 10 +- .../automatic-tests/commands/autoRunTests.js | 2 +- .../codemirror/commands/codeMirrorInit.js | 2 +- .../1-styling/componentCss/1-style.css | 56 +- .../componentTemplates/componentActions.html | 32 +- .../componentTemplates/componentBodyHtml.html | 26 +- .../componentTemplates/componentCommands.html | 32 +- .../componentComponentCss.html | 26 +- .../componentComponentTemplate.html | 32 +- .../componentTemplates/componentDataApi.html | 26 +- .../componentDataSources.html | 44 +- .../componentDescription.html | 2 +- .../componentTemplates/componentFootHtml.html | 26 +- .../componentTemplates/componentHeadHtml.html | 26 +- .../componentTemplates/componentPageCss.html | 26 +- .../componentPageFrame.html | 38 +- .../componentPageTemplate.html | 32 +- .../componentQUnitTests.html | 22 +- .../componentTemplates/componentRawApi.html | 26 +- .../componentTemplates/componentRoutes.html | 28 +- .../componentTemplates/componentSorters.html | 26 +- .../componentTransformers.html | 32 +- .../componentCss/code-method block.css | 14 +- .../componentCss/deleted-parts.css | 2 +- .../dragdrop/componentCss/simply dragdrop.css | 4 +- .../header/componentTemplates/header.html | 4 +- .../componentCss/HTML validator.css | 14 +- .../componentHtmlValidator.html | 4 +- .../transformers/validateHtml-render.js | 4 +- .../componentCss/App full preview.css | 20 +- .../componentTemplates/componentPreview.html | 8 +- .../componentTemplates/fullAppPreview.html | 6 +- .../componentTemplates/pagePreview.html | 8 +- www/api/data/generated.html | 760 +++++++++--------- .../pageTemplates/Edit base component.html | 8 +- .../pageTemplates/Base components.html | 18 +- .../pageTemplates/List components.html | 18 +- .../pageTemplates/Edit component.html | 8 +- .../pageTemplates/Edit page frame.html | 6 +- .../pages/page/pageTemplates/Edit page.html | 8 +- .../data/pages/pages/pageTemplates/Pages.html | 18 +- .../preview/pageCss/sb-fullscreen-preview.css | 14 - .../pageCss/simplycode-fullscreen-preview.css | 14 + .../preview/pageTemplates/preview-app.html | 2 +- .../pageTemplates/preview-component.html | 2 +- .../pages/publish/commands/saveAppHtml.js | 2 +- .../publish/pageTemplates/Publish App.html | 2 +- 47 files changed, 770 insertions(+), 770 deletions(-) delete mode 100644 www/api/data/pages/preview/pageCss/sb-fullscreen-preview.css create mode 100644 www/api/data/pages/preview/pageCss/simplycode-fullscreen-preview.css diff --git a/www/api/data/base-components/automatic-preview/commands/autoRunPreviews.js b/www/api/data/base-components/automatic-preview/commands/autoRunPreviews.js index dc228c0..ca87fee 100644 --- a/www/api/data/base-components/automatic-preview/commands/autoRunPreviews.js +++ b/www/api/data/base-components/automatic-preview/commands/autoRunPreviews.js @@ -1,25 +1,25 @@ function(el) { - var previewRunners = document.querySelectorAll("iframe.sb-full-preview"); + var previewRunners = document.querySelectorAll("iframe.simplycode-full-preview"); previewRunners.forEach(function(previewRunner) { previewRunner.contentWindow.document.previewRunner = previewRunner; simplyApp.commands.resetPreview(previewRunner) .then(function(previewRunner) { previewRunner.contentWindow.document.open(); - previewRunner.contentWindow.document.write(previewRunner.parentNode.querySelector(".sb-preview-code").innerText); + previewRunner.contentWindow.document.write(previewRunner.parentNode.querySelector(".simplycode-preview-code").innerText); previewRunner.contentWindow.document.close(); }); }); - var previewRunners = document.querySelectorAll("iframe.sb-component-preview"); + var previewRunners = document.querySelectorAll("iframe.simplycode-component-preview"); previewRunners.forEach(function(previewRunner) { previewRunner.contentWindow.document.previewRunner = previewRunner; simplyApp.commands.resetPreview(previewRunner) .then(function(previewRunner) { previewRunner.contentWindow.document.open(); - previewRunner.contentWindow.document.write(previewRunner.parentNode.querySelector(".sb-preview-code").innerText); + previewRunner.contentWindow.document.write(previewRunner.parentNode.querySelector(".simplycode-preview-code").innerText); previewRunner.contentWindow.document.close(); previewRunner.contentWindow.addEventListener("simply-content-loaded", function() { - var previewData = previewRunner.parentNode.querySelector(".sb-preview-data").innerText; + var previewData = previewRunner.parentNode.querySelector(".simplycode-preview-data").innerText; try { previewData = JSON.parse(previewData); } catch(e) { diff --git a/www/api/data/base-components/automatic-tests/commands/autoRunTests.js b/www/api/data/base-components/automatic-tests/commands/autoRunTests.js index 6ae3b8c..b3e2ad8 100644 --- a/www/api/data/base-components/automatic-tests/commands/autoRunTests.js +++ b/www/api/data/base-components/automatic-tests/commands/autoRunTests.js @@ -1,5 +1,5 @@ function(el) { - var testRunners = document.querySelectorAll(".sb-component[open] iframe.qunit"); + var testRunners = document.querySelectorAll(".simplycode-component[open] iframe.qunit"); testRunners.forEach(function(testRunner) { testRunner.contentWindow.document.testRunner = testRunner; testRunner.contentWindow.document.open(); diff --git a/www/api/data/base-components/codemirror/commands/codeMirrorInit.js b/www/api/data/base-components/codemirror/commands/codeMirrorInit.js index c6cde72..43897a9 100644 --- a/www/api/data/base-components/codemirror/commands/codeMirrorInit.js +++ b/www/api/data/base-components/codemirror/commands/codeMirrorInit.js @@ -1,5 +1,5 @@ function() { - var textareas = document.querySelectorAll(".sb-component[open] textarea[data-codemirror-mode]:not([style])"); + var textareas = document.querySelectorAll(".simplycode-component[open] textarea[data-codemirror-mode]:not([style])"); textareas.forEach(function(textarea) { var mode = "javascript"; if (textarea.hasAttribute("data-codemirror-mode")) { diff --git a/www/api/data/components/1-styling/componentCss/1-style.css b/www/api/data/components/1-styling/componentCss/1-style.css index 9e93fbf..298a1ee 100644 --- a/www/api/data/components/1-styling/componentCss/1-style.css +++ b/www/api/data/components/1-styling/componentCss/1-style.css @@ -77,8 +77,8 @@ a:visited { /* custom styling for custom elements */ -.sb-button, -a.sb-button { +.simplycode-button, +a.simplycode-button { background: var(--support-background); color: var(--support-color); padding: 0.3em 0.5em; @@ -87,13 +87,13 @@ a.sb-button { text-decoration: none; } -.sb-button:first-child { +.simplycode-button:first-child { margin-left: 0; } -.sb-button:last-child { +.simplycode-button:last-child { margin-right: 0; } -.sb-button.highlight { +.simplycode-button.highlight { background: var(--highlight-background); color: var(--highlight-color); } @@ -125,7 +125,7 @@ body > nav { body > div.main { grid-area: pane; } -nav ul ul .sb-expand { +nav ul ul .simplycode-expand { display: none; padding: 0 1.7em; } @@ -146,18 +146,18 @@ nav > ul > li[data-simply-command=expandMenu]::before { content: "[+] "; font-family: monospace; } -.sb-part { +.simplycode-part { margin-top: 1em; } -.sb-part-header { +.simplycode-part-header { display: grid; grid-template-columns: 1fr 1fr; } -.sb-part-header .sb-options { +.simplycode-part-header .simplycode-options { text-align: right; } -.sb-part .sb-tab { +.simplycode-part .simplycode-tab { padding: 10px 5px; margin: 0; background-color: #151515; @@ -166,54 +166,54 @@ nav > ul > li[data-simply-command=expandMenu]::before { text-align: center; margin-right: 5px; } -.sb-part .sb-tab input[type=radio] { +.simplycode-part .simplycode-tab input[type=radio] { display: none; } -.sb-part .sb-tab input[type=radio]:checked ~ span { +.simplycode-part .simplycode-tab input[type=radio]:checked ~ span { font-weight: bold; border-bottom: 2px solid var(--support-background); } -.sb-part .sb-editor-code { +.simplycode-part .simplycode-editor-code { display: grid; grid-template-columns: 1fr; } -.sb-part .sb-dual { +.simplycode-part .simplycode-dual { display: grid; grid-template-columns: 1fr 1fr; } -.sb-part .sb-dual-preview { +.simplycode-part .simplycode-dual-preview { display: grid; grid-template-columns: auto 480px; } -.sb-test-header { +.simplycode-test-header { display: grid; grid-template-columns: 1fr 1fr; } -.sb-test-header .sb-options { +.simplycode-test-header .simplycode-options { text-align: right; } -.sb-component summary { +.simplycode-component summary { font-size: 1.2em; } -.sb-component { +.simplycode-component { margin: 10px 0px; } -.sb-header { +.simplycode-header { display: grid; grid-template-columns: 3fr 1fr; vertical-align: middle; } -.sb-header .sb-controls { +.simplycode-header .simplycode-controls { text-align: right; } -.sb-header h1 span { +.simplycode-header h1 span { white-space: nowrap; } -.sb-component summary .sb-controls { +.simplycode-component summary .simplycode-controls { display: none; margin-left: 1em; } -.sb-component[open] summary .sb-controls { +.simplycode-component[open] summary .simplycode-controls { display: inline-block; } header { @@ -231,16 +231,16 @@ header { header h1 { margin: 0; } -header .sb-controls { +header .simplycode-controls { padding-top: 5px; padding-right: 5px; text-align: right; } -.sb-editor-code textarea { +.simplycode-editor-code textarea { margin-top: -1px; } -ul.sb-components-list { +ul.simplycode-components-list { list-style: none; padding: 0; margin: 0; @@ -249,7 +249,7 @@ ul.sb-components-list { gap: 10px; margin-bottom: 1em; } -ul.sb-components-list li { +ul.simplycode-components-list li { border: 1px solid #555; background-color: #2a2a2a; padding: 10px; diff --git a/www/api/data/components/component-actions/componentTemplates/componentActions.html b/www/api/data/components/component-actions/componentTemplates/componentActions.html index ba36bd4..a60b912 100644 --- a/www/api/data/components/component-actions/componentTemplates/componentActions.html +++ b/www/api/data/components/component-actions/componentTemplates/componentActions.html @@ -1,41 +1,41 @@ -
+
Actions - - + + -
+