├── apps ├── __init__.py ├── core │ ├── __init__.py │ ├── templatetags │ │ ├── __init__.py │ │ └── footer.py │ ├── templates │ │ ├── banned.html │ │ ├── includes │ │ │ ├── footer.html │ │ │ └── navbar.html │ │ ├── base.html │ │ ├── terms_of_service.html │ │ └── index.html │ ├── admin.py │ ├── tests.py │ ├── forms.py │ ├── static │ │ └── js │ │ │ ├── vendor │ │ │ └── xml2json.js │ │ │ └── components │ │ │ └── newsfeed.js │ └── views.py ├── rest │ ├── __init__.py │ ├── urls.py │ ├── serializers.py │ └── views.py ├── accounts │ ├── __init__.py │ ├── migrations │ │ ├── __init__.py │ │ ├── 0002_elementaluser_banned.py │ │ ├── 0005_elementaluser_deleted.py │ │ ├── 0009_auto_20160312_1331.py │ │ ├── 0007_elementaluser_about_me.py │ │ ├── 0006_elementaluser_ip.py │ │ ├── 0008_elementaluser_working_on.py │ │ ├── 0003_elementaluser_can_share_projects.py │ │ ├── 0004_auto_20150725_1206.py │ │ └── 0001_initial.py │ ├── templatetags │ │ ├── __init__.py │ │ └── addcss.py │ ├── templates │ │ ├── user_settings.html │ │ ├── login.html │ │ ├── register.html │ │ └── profile.html │ ├── urls.py │ ├── mixins.py │ ├── static │ │ └── js │ │ │ └── profile.js │ ├── forms.py │ ├── admin.py │ ├── models.py │ ├── views.py │ └── tests.py ├── galleries │ ├── __init__.py │ ├── migrations │ │ ├── __init__.py │ │ ├── 0002_usertogallery.py │ │ └── 0001_initial.py │ ├── admin.py │ └── models.py └── projects │ ├── __init__.py │ ├── migrations │ ├── __init__.py │ ├── 0002_remove_project_shared.py │ ├── 0003_project_shared.py │ ├── 0006_project_deleted.py │ ├── 0005_auto_20150902_1930.py │ ├── 0004_project_data.py │ ├── 0007_project_thumbnail.py │ ├── 0010_project_featured.py │ ├── 0008_project_updated.py │ ├── 0009_project_created.py │ └── 0001_initial.py │ ├── static │ ├── img │ │ ├── trash_open.png │ │ ├── trash_closed.png │ │ ├── diagonalTexture.png │ │ └── nav-search-glass.png │ ├── css │ │ ├── editor │ │ │ ├── helpers.scss │ │ │ ├── menus.scss │ │ │ ├── blocks.scss │ │ │ └── style.scss │ │ └── my-stuff.css │ └── js │ │ ├── editor │ │ ├── siteIntegrations.js │ │ ├── fileManagement.js │ │ ├── cssAttributes.js │ │ ├── script.js │ │ ├── vendor │ │ │ ├── filesaver.min.js │ │ │ ├── htmljson.js │ │ │ ├── cssjson.js │ │ │ └── htmlparser.js │ │ ├── blockAttributes.js │ │ └── block2json.js │ │ └── components │ │ └── projectSettings.html │ ├── admin.py │ ├── urls.py │ ├── models.py │ ├── templates │ ├── my_projects.html │ ├── my-things-mockup.html │ └── proof-of-concept.html │ ├── views.py │ └── tests.py ├── runtime.txt ├── LICENSE ├── Procfile ├── Procfile.windows ├── static ├── variables.css ├── favicon.ico ├── resources │ ├── navbarimg1.png │ ├── navbarimg2.png │ ├── elemental--base.png │ ├── front-about-code.png │ ├── front-about-learn.png │ └── front-about-share.png ├── typography.scss ├── typography.css ├── variables.scss ├── grid.css ├── grid.scss ├── nav.scss ├── nav.css ├── footer.scss ├── footer.css ├── helpers.scss ├── helpers.css ├── homepage.css └── homepage.scss ├── .gitignore ├── requirements.txt ├── manage.py ├── circle.yml ├── wsgi.py ├── urls.py ├── README.md └── settings.py /apps/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/core/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/rest/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/accounts/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/galleries/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/projects/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /runtime.txt: -------------------------------------------------------------------------------- 1 | python-2.7.9 2 | -------------------------------------------------------------------------------- /apps/accounts/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/accounts/templatetags/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/core/templatetags/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/galleries/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/projects/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2015 ElementalCode 2 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: gunicorn wsgi --log-file - 2 | -------------------------------------------------------------------------------- /apps/core/templates/banned.html: -------------------------------------------------------------------------------- 1 | YOU HAVE BEEN BANNED 2 | MUAHAHA -------------------------------------------------------------------------------- /Procfile.windows: -------------------------------------------------------------------------------- 1 | web: python manage.py runserver 0.0.0.0:5000 2 | -------------------------------------------------------------------------------- /static/variables.css: -------------------------------------------------------------------------------- 1 | 2 | 3 | /*# sourceMappingURL=variables.css.map */ 4 | -------------------------------------------------------------------------------- /apps/core/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ElementalCode/elemental/HEAD/static/favicon.ico -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | venv 2 | *.pyc 3 | staticfiles 4 | .env 5 | db.sqlite3 6 | *.db 7 | .sass-cache/ 8 | *.map 9 | *.bat -------------------------------------------------------------------------------- /static/resources/navbarimg1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ElementalCode/elemental/HEAD/static/resources/navbarimg1.png -------------------------------------------------------------------------------- /static/resources/navbarimg2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ElementalCode/elemental/HEAD/static/resources/navbarimg2.png -------------------------------------------------------------------------------- /apps/galleries/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from .models import Gallery 3 | 4 | admin.site.register(Gallery) -------------------------------------------------------------------------------- /static/resources/elemental--base.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ElementalCode/elemental/HEAD/static/resources/elemental--base.png -------------------------------------------------------------------------------- /static/resources/front-about-code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ElementalCode/elemental/HEAD/static/resources/front-about-code.png -------------------------------------------------------------------------------- /apps/projects/static/img/trash_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ElementalCode/elemental/HEAD/apps/projects/static/img/trash_open.png -------------------------------------------------------------------------------- /static/resources/front-about-learn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ElementalCode/elemental/HEAD/static/resources/front-about-learn.png -------------------------------------------------------------------------------- /static/resources/front-about-share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ElementalCode/elemental/HEAD/static/resources/front-about-share.png -------------------------------------------------------------------------------- /apps/projects/static/img/trash_closed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ElementalCode/elemental/HEAD/apps/projects/static/img/trash_closed.png -------------------------------------------------------------------------------- /apps/projects/static/img/diagonalTexture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ElementalCode/elemental/HEAD/apps/projects/static/img/diagonalTexture.png -------------------------------------------------------------------------------- /apps/projects/static/img/nav-search-glass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ElementalCode/elemental/HEAD/apps/projects/static/img/nav-search-glass.png -------------------------------------------------------------------------------- /apps/projects/static/css/editor/helpers.scss: -------------------------------------------------------------------------------- 1 | .fake-hidden { 2 | position: absolute; 3 | top: -9999px; 4 | left: -9999px; 5 | opacity: 0; 6 | } 7 | .hidden { 8 | display: none; 9 | } -------------------------------------------------------------------------------- /apps/accounts/templates/user_settings.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block content %} 4 |
9 | {% endblock %} -------------------------------------------------------------------------------- /apps/accounts/templatetags/addcss.py: -------------------------------------------------------------------------------- 1 | from django.template import Library 2 | register = Library() 3 | 4 | @register.filter(name='addcss') 5 | def addcss(value, arg): 6 | value.field.widget.attrs['class'] = arg 7 | return value -------------------------------------------------------------------------------- /apps/projects/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from .models import Project 3 | 4 | class ProjectAdmin(admin.ModelAdmin): 5 | readonly_fields = ('created', 'updated', ) 6 | 7 | admin.site.register(Project, ProjectAdmin) -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | dj-database-url==0.3.0 2 | Django==1.9.4 3 | djangorestframework==3.3.2 4 | gunicorn==19.3.0 5 | psycopg2==2.6 6 | SQLAlchemy==1.0.4 7 | whitenoise==1.0.6 8 | django-flat-theme==0.9.5 9 | django-recaptcha==1.0.5 10 | -------------------------------------------------------------------------------- /static/typography.scss: -------------------------------------------------------------------------------- 1 | @import "variables"; 2 | 3 | span { 4 | &.smalltext { 5 | font-size: 12px; 6 | } 7 | } 8 | 9 | .text--right { text-align: right!important; } 10 | .text--left { text-align: left!important; } -------------------------------------------------------------------------------- /static/typography.css: -------------------------------------------------------------------------------- 1 | span.smalltext { 2 | font-size: 12px; } 3 | 4 | .text--right { 5 | text-align: right !important; } 6 | 7 | .text--left { 8 | text-align: left !important; } 9 | 10 | /*# sourceMappingURL=typography.css.map */ 11 | -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings") 7 | 8 | from django.core.management import execute_from_command_line 9 | 10 | execute_from_command_line(sys.argv) 11 | -------------------------------------------------------------------------------- /static/variables.scss: -------------------------------------------------------------------------------- 1 | $footer-height: 130px; 2 | 3 | $base-spacing-unit: 35px; 4 | 5 | $colors: ( 6 | seafoam: #42BA92, 7 | seafoam-dark: #319E7A, 8 | coral: #ff7f50, 9 | ); 10 | 11 | // colors 12 | @function color($color-name) { 13 | @return map-get($colors, $color-name); 14 | } -------------------------------------------------------------------------------- /static/grid.css: -------------------------------------------------------------------------------- 1 | .grid .half { 2 | width: 50%; } 3 | .grid .one-third { 4 | width: 33%; } 5 | .grid .two-third { 6 | width: 66%; } 7 | .grid .one-fourth { 8 | width: 25%; } 9 | .grid .three-fourth { 10 | width: 75%; } 11 | .grid .one-fifth { 12 | width: 20%; } 13 | 14 | /*# sourceMappingURL=grid.css.map */ 15 | -------------------------------------------------------------------------------- /circle.yml: -------------------------------------------------------------------------------- 1 | deployment: 2 | production: 3 | branch: master 4 | commands: 5 | - git push git@heroku.com:elementalcode.git $CIRCLE_SHA1:master 6 | - heroku run python manage.py migrate --app elementalcode 7 | 8 | notify: 9 | webhooks: 10 | - url: https://webhooks.gitter.im/e/588b954a8e591bb172ea -------------------------------------------------------------------------------- /apps/core/tests.py: -------------------------------------------------------------------------------- 1 | from django.core.urlresolvers import reverse 2 | from django.conf import settings 3 | from django.test import TestCase, override_settings, Client, RequestFactory 4 | 5 | class CoreTestCases(TestCase): 6 | 7 | @override_settings(AUTH_USER_MODEL=settings.AUTH_USER_MODEL) 8 | def setUp(self): 9 | self.client = Client() -------------------------------------------------------------------------------- /static/grid.scss: -------------------------------------------------------------------------------- 1 | .grid { 2 | .half { 3 | width: 50%; 4 | } 5 | .one-third { 6 | width: 33%; 7 | } 8 | .two-third { 9 | width: 66%; 10 | } 11 | .one-fourth { 12 | width: 25%; 13 | } 14 | .three-fourth { 15 | width: 75%; 16 | } 17 | .one-fifth { 18 | width: 20%; 19 | } 20 | } -------------------------------------------------------------------------------- /apps/core/templates/includes/footer.html: -------------------------------------------------------------------------------- 1 | {% load footer %} 2 | 11 | -------------------------------------------------------------------------------- /apps/rest/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import include, url 2 | 3 | from .views import ProjectDetail, UserDetail, ProjectCreate 4 | 5 | urlpatterns = [ 6 | # nothing 7 | url(r'^(?i)users/user/(?P
73 | // add last parents
74 | var last = bufArray.last();
75 | if (!(last.child instanceof Array)) {
76 | last.child = [];
77 | }
78 | last.child.push(buf);
79 | } else {
80 | bufArray.push(buf);
81 | }
82 | }
83 | },
84 | end: function(tag) {
85 | if (inline[tag]) {
86 | // if end of inline tag
87 | // inlineBuf is now 'inline tag'
260 | // },{
261 | // tag: 'pre',
262 | // attr: {
263 | // id: 'demo',
264 | // class: ['foo', 'bar']
265 | // }
266 | // },{
267 | // tag: 'pre',
268 | // attr: {
269 | // id: 'output',
270 | // class: ['goo']
271 | // }
272 | // },{
273 | // tag: 'input',
274 | // attr: {
275 | // id: 'execute',
276 | // type: 'button',
277 | // value: 'execute'
278 | // }
279 | // }]
280 | // };
--------------------------------------------------------------------------------
/apps/projects/static/js/editor/vendor/cssjson.js:
--------------------------------------------------------------------------------
1 | /**
2 | * CSS-JSON Converter for JavaScript
3 | * Converts CSS to JSON and back.
4 | * Version 2.1
5 | *
6 | * Released under the MIT license.
7 | *
8 | * Copyright (c) 2013 Aram Kocharyan, http://aramk.com/
9 |
10 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
11 | documentation files (the "Software"), to deal in the Software without restriction, including without limitation
12 | the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
13 | to permit persons to whom the Software is furnished to do so, subject to the following conditions:
14 |
15 | The above copyright notice and this permission notice shall be included in all copies or substantial portions
16 | of the Software.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
19 | THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | THE SOFTWARE.
23 | */
24 |
25 | var CSSJSON = new function () {
26 |
27 | var base = this;
28 |
29 | base.init = function () {
30 | // String functions
31 | String.prototype.trim = function () {
32 | return this.replace(/^\s+|\s+$/g, '');
33 | };
34 |
35 | String.prototype.repeat = function (n) {
36 | return new Array(1 + n).join(this);
37 | };
38 | };
39 | base.init();
40 |
41 | var selX = /([^\s\;\{\}][^\;\{\}]*)\{/g;
42 | var endX = /\}/g;
43 | var lineX = /([^\;\{\}]*)\;/g;
44 | var commentX = /\/\*[\s\S]*?\*\//g;
45 | var lineAttrX = /([^\:]+):([^\;]*);/;
46 |
47 | // This is used, a concatenation of all above. We use alternation to
48 | // capture.
49 | var altX = /(\/\*[\s\S]*?\*\/)|([^\s\;\{\}][^\;\{\}]*(?=\{))|(\})|([^\;\{\}]+\;(?!\s*\*\/))/gmi;
50 |
51 | // Capture groups
52 | var capComment = 1;
53 | var capSelector = 2;
54 | var capEnd = 3;
55 | var capAttr = 4;
56 |
57 | var isEmpty = function (x) {
58 | return typeof x == 'undefined' || x.length == 0 || x == null;
59 | };
60 |
61 | /**
62 | * Input is css string and current pos, returns JSON object
63 | *
64 | * @param cssString
65 | * The CSS string.
66 | * @param args
67 | * An optional argument object. ordered: Whether order of
68 | * comments and other nodes should be kept in the output. This
69 | * will return an object where all the keys are numbers and the
70 | * values are objects containing "name" and "value" keys for each
71 | * node. comments: Whether to capture comments. split: Whether to
72 | * split each comma separated list of selectors.
73 | */
74 | base.toJSON = function (cssString, args) {
75 | var node = {
76 | children: {},
77 | attributes: {}
78 | };
79 | var match = null;
80 | var count = 0;
81 |
82 | if (typeof args == 'undefined') {
83 | var args = {
84 | ordered: false,
85 | comments: false,
86 | stripComments: false,
87 | split: false
88 | };
89 | }
90 | if (args.stripComments) {
91 | args.comments = false;
92 | cssString = cssString.replace(commentX, '');
93 | }
94 |
95 | while ((match = altX.exec(cssString)) != null) {
96 | if (!isEmpty(match[capComment]) && args.comments) {
97 | // Comment
98 | var add = match[capComment].trim();
99 | node[count++] = add;
100 | } else if (!isEmpty(match[capSelector])) {
101 | // New node, we recurse
102 | var name = match[capSelector].trim();
103 | // This will return when we encounter a closing brace
104 | var newNode = base.toJSON(cssString, args);
105 | if (args.ordered) {
106 | var obj = {};
107 | obj['name'] = name;
108 | obj['value'] = newNode;
109 | // Since we must use key as index to keep order and not
110 | // name, this will differentiate between a Rule Node and an
111 | // Attribute, since both contain a name and value pair.
112 | obj['type'] = 'rule';
113 | node[count++] = obj;
114 | } else {
115 | if (args.split) {
116 | var bits = name.split(',');
117 | } else {
118 | var bits = [name];
119 | }
120 | for (i in bits) {
121 | var sel = bits[i].trim();
122 | if (sel in node.children) {
123 | for (var att in newNode.attributes) {
124 | node.children[sel].attributes[att] = newNode.attributes[att];
125 | }
126 | } else {
127 | node.children[sel] = newNode;
128 | }
129 | }
130 | }
131 | } else if (!isEmpty(match[capEnd])) {
132 | // Node has finished
133 | return node;
134 | } else if (!isEmpty(match[capAttr])) {
135 | var line = match[capAttr].trim();
136 | var attr = lineAttrX.exec(line);
137 | if (attr) {
138 | // Attribute
139 | var name = attr[1].trim();
140 | var value = attr[2].trim();
141 | if (args.ordered) {
142 | var obj = {};
143 | obj['name'] = name;
144 | obj['value'] = value;
145 | obj['type'] = 'attr';
146 | node[count++] = obj;
147 | } else {
148 | if (name in node.attributes) {
149 | var currVal = node.attributes[name];
150 | if (!(currVal instanceof Array)) {
151 | node.attributes[name] = [currVal];
152 | }
153 | node.attributes[name].push(value);
154 | } else {
155 | node.attributes[name] = value;
156 | }
157 | }
158 | } else {
159 | // Semicolon terminated line
160 | node[count++] = line;
161 | }
162 | }
163 | }
164 |
165 | return node;
166 | };
167 |
168 | /**
169 | * @param node
170 | * A JSON node.
171 | * @param depth
172 | * The depth of the current node; used for indentation and
173 | * optional.
174 | * @param breaks
175 | * Whether to add line breaks in the output.
176 | */
177 | base.toCSS = function (node, depth, breaks) {
178 | var cssString = '';
179 | if (typeof depth == 'undefined') {
180 | depth = 0;
181 | }
182 | if (typeof breaks == 'undefined') {
183 | breaks = false;
184 | }
185 | if (node.attributes) {
186 | for (i in node.attributes) {
187 | var att = node.attributes[i];
188 | if (att instanceof Array) {
189 | for (var j = 0; j < att.length; j++) {
190 | cssString += strAttr(i, att[j], depth);
191 | }
192 | } else {
193 | cssString += strAttr(i, att, depth);
194 | }
195 | }
196 | }
197 | if (node.children) {
198 | var first = true;
199 | for (i in node.children) {
200 | if (breaks && !first) {
201 | cssString += '\n';
202 | } else {
203 | first = false;
204 | }
205 | cssString += strNode(i, node.children[i], depth);
206 | }
207 | }
208 | return cssString;
209 | };
210 |
211 | // Helpers
212 |
213 | var strAttr = function (name, value, depth) {
214 | return '\t'.repeat(depth) + name + ': ' + value + ';\n';
215 | };
216 |
217 | var strNode = function (name, value, depth) {
218 | var cssString = '\t'.repeat(depth) + name + ' {\n';
219 | cssString += base.toCSS(value, depth + 1);
220 | cssString += '\t'.repeat(depth) + '}\n';
221 | return cssString;
222 | };
223 |
224 | };
--------------------------------------------------------------------------------
/static/homepage.css:
--------------------------------------------------------------------------------
1 | .centered, .carousel {
2 | width: 90%;
3 | max-width: 900px;
4 | margin: 0 auto; }
5 |
6 | /* == Logged out user things == */
7 | .logged-out-header .logged-out-header-inner {
8 | width: 40%; }
9 | .logged-out-header .header-text {
10 | color: white;
11 | text-align: center;
12 | font-family: 'Source Sans Pro', sans-serif;
13 | font-weight: bold;
14 | font-size: 44px;
15 | text-shadow: 0 2px 2px rgba(37, 46, 53, 0.6);
16 | margin: 0 auto 30px auto;
17 | padding-top: 20px; }
18 |
19 | .showcase {
20 | height: 40.8%;
21 | margin: 0 auto;
22 | position: relative;
23 | /* for the abs-positioned image */
24 | cursor: default;
25 | -webkit-touch-callout: none;
26 | /* iOS Safari */
27 | -webkit-user-select: none;
28 | /* Chrome/Safari/Opera */
29 | -khtml-user-select: none;
30 | /* Konqueror */
31 | -moz-user-select: none;
32 | /* Firefox */
33 | -ms-user-select: none;
34 | /* IE/Edge */
35 | user-select: none;
36 | /* non-prefixed version, currently
37 | not supported by any browser */ }
38 | .showcase .showcase-img {
39 | width: 100%;
40 | border-radius: 5px;
41 | box-shadow: 0 1px 8px -1px #252E35; }
42 | .showcase .showcase-callout {
43 | z-index: 8888;
44 | color: white;
45 | position: absolute;
46 | height: 35px;
47 | box-sizing: border-box;
48 | font-family: 'Source Sans Pro', sans-serif;
49 | font-weight: bold;
50 | font-size: 16px;
51 | letter-spacing: 1px;
52 | white-space: nowrap;
53 | padding: 8px 30px;
54 | border-radius: 500px;
55 | background-color: #252E35; }
56 | .showcase .showcase-callout:after {
57 | content: "";
58 | display: block;
59 | width: 0px;
60 | height: 0px;
61 | border-left: 10px solid #252E35;
62 | border-top: 10px solid #252E35;
63 | border-right: 10px solid transparent;
64 | border-bottom: 10px solid transparent;
65 | transform: translate(20px, -37px) rotate(45deg);
66 | position: relative;
67 | top: 1px; }
68 | .showcase .showcase-callout.arrowplacement2 {
69 | transform: translate(-90%, 0); }
70 | .showcase .showcase-callout.arrowplacement2:after {
71 | transform: translate(240px, -37px) rotate(45deg); }
72 |
73 | .showcase-pocket {
74 | display: block;
75 | background: #444C54;
76 | height: 34px;
77 | position: relative;
78 | z-index: 5555;
79 | top: -30px;
80 | box-shadow: 0 -17px 20px -13px rgba(68, 76, 84, 0.9), 0 -5px 4px -5px rgba(0, 0, 0, 0.5);
81 | width: calc(40% + 100px);
82 | margin: 0 auto; }
83 |
84 | .cta-wrapper {
85 | text-align: center; }
86 |
87 | .cta-button {
88 | display: inline-block;
89 | color: white;
90 | text-decoration: none;
91 | font-family: 'Source Sans Pro', sans-serif;
92 | font-size: 20px;
93 | font-weight: bold;
94 | padding: 18px 38px;
95 | background: #42BA92;
96 | border-radius: 4px;
97 | line-height: 1; }
98 | .cta-button span {
99 | font-size: 16px;
100 | color: rgba(37, 46, 53, 0.85);
101 | font-weight: normal;
102 | /*&:before {
103 | content:' ';
104 | display:block;
105 | width:24px;
106 | margin-left:-12px;
107 | height:0;
108 | border-top:1px solid rgba(37,46,53,0.2);
109 |
110 | position:absolute;
111 | top:-1px;
112 | left:50%;
113 | }*/ }
114 |
115 | .or-separator {
116 | display: inline-block;
117 | color: white;
118 | font-family: 'Source Sans Pro', sans-serif;
119 | position: relative;
120 | bottom: 12px;
121 | margin: 0 20px;
122 | cursor: default; }
123 | .or-separator:before {
124 | content: " ";
125 | display: block;
126 | width: 0;
127 | height: 8px;
128 | border-right: 1px solid rgba(255, 255, 255, 0.3);
129 | position: relative;
130 | left: 7px; }
131 | .or-separator:after {
132 | content: " ";
133 | display: block;
134 | width: 0;
135 | height: 8px;
136 | border-right: 1px solid rgba(255, 255, 255, 0.3);
137 | position: relative;
138 | left: 7px;
139 | top: 4px; }
140 |
141 | /* == Responsibly responsive == */
142 | @media screen and (max-width: 1634px) {
143 | .logged-out-header .header-text {
144 | font-size: 2.65vw; } }
145 | @media screen and (max-width: 850px) {
146 | .showcase, .showcase-pocket {
147 | display: none; }
148 |
149 | .logged-out-header .logged-out-header-inner {
150 | width: 80%; }
151 |
152 | .logged-out-header .header-text {
153 | font-size: 5.05vw; } }
154 | @media screen and (max-width: 570px) {
155 | .cta-button {
156 | display: block;
157 | margin: 10px 0; }
158 |
159 | .or-separator {
160 | display: none; } }
161 | /* == Carousels == */
162 | .carousel-wrapper {
163 | padding: 30px 0; }
164 | .carousel-wrapper.gray {
165 | background: #ddd; }
166 |
167 | .carousel {
168 | font-family: 'Source Sans Pro', sans-serif; }
169 | .carousel .carousel-title {
170 | font-size: 42px;
171 | margin: 0;
172 | color: #42BA92;
173 | line-height: 0.8;
174 | margin-bottom: 10px; }
175 | .carousel .carousel-content {
176 | display: flex;
177 | width: 100%;
178 | border-radius: 4px;
179 | overflow: hidden; }
180 | .carousel .carousel-content .carousel-link {
181 | margin-bottom: -4px;
182 | text-decoration: none;
183 | flex-shrink: 1;
184 | flex-grow: 1;
185 | flex-basis: 0;
186 | position: relative; }
187 | .carousel .carousel-content .carousel-image {
188 | width: 100%; }
189 | .carousel .carousel-content .carousel-info {
190 | width: 100%;
191 | height: 0;
192 | padding-bottom: 100%;
193 | position: absolute;
194 | top: 0;
195 | left: 0;
196 | background: -moz-linear-gradient(top, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.5) 100%);
197 | background: -webkit-linear-gradient(top, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.5) 100%);
198 | background: linear-gradient(to bottom, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.5) 100%);
199 | opacity: 0;
200 | overflow: hidden;
201 | transition: 0.4s; }
202 | .carousel .carousel-content .carousel-info:hover {
203 | opacity: 1; }
204 | .carousel .carousel-content .carousel-header {
205 | font-size: 20px;
206 | max-width: 100%;
207 | position: absolute;
208 | top: 15px;
209 | left: 15px;
210 | margin: 0;
211 | margin-right: 15px;
212 | line-height: 1;
213 | opacity: 1;
214 | color: white; }
215 |
216 | /* putting my css down here, easier to edit (also I don't do scss) */
217 | .showcase-callout {
218 | -webkit-transition: opacity .4s;
219 | transition: opacity .4s;
220 | opacity: 0; }
221 |
222 | /*.showcase-callout:hover {
223 | opacity: .8;
224 | }*/
225 | .bordered-link {
226 | -webkit-transition: background .5s, color .2s;
227 | transition: background .5s, color .2s; }
228 |
229 | .unbordered-link {
230 | transition: background .5s, color .2s;
231 | padding: 6px 14px;
232 | border-radius: 4px;
233 | color: white; }
234 |
235 | .unbordered-link:hover {
236 | background: white;
237 | color: #444C54 !important; }
238 |
239 | .showcase-trigger {
240 | border-radius: 10px;
241 | width: 15px;
242 | height: 15px;
243 | background-color: #0074D9;
244 | z-index: 8888;
245 | position: absolute;
246 | opacity: .8;
247 | box-shadow: 0px 0px 5px #0074D9;
248 | transition: opacity ease-out 0.2s, width ease-out 0.2s, height ease-out 0.2s, transform ease-out 0.2s;
249 | transform: translate(0, 0); }
250 |
251 | .showcase-trigger:hover + .showcase-callout {
252 | opacity: 1; }
253 |
254 | .showcase-trigger::after {
255 | animation: pulsate 3s 1s ease-out infinite;
256 | background: transparent;
257 | border-radius: 10px;
258 | width: 15px;
259 | height: 15px;
260 | position: absolute;
261 | left: 0;
262 | top: 0;
263 | box-sizing: border-box;
264 | border: 2px solid #0074D9;
265 | position: absolute;
266 | display: block;
267 | content: "";
268 | opacity: 0; }
269 |
270 | .showcase-trigger:hover {
271 | opacity: 0.3;
272 | width: 20px;
273 | height: 20px;
274 | border-radius: 100%;
275 | transform: translate(-3.5px, -3.5px);
276 | box-shadow: none; }
277 |
278 | .showcase-trigger:hover::after {
279 | animation: none;
280 | display: none; }
281 |
282 | /* transition things */
283 | @-webkit-keyframes pulsate {
284 | 0% {
285 | -webkit-transform: scale(1);
286 | opacity: 0.8; }
287 | 30% {
288 | -webkit-transform: scale(2);
289 | opacity: 0; }
290 | 100% {
291 | -webkit-transform: scale(2);
292 | opacity: 0; } }
293 | @-moz-keyframes pulsate {
294 | 0% {
295 | -moz-transform: scale(1);
296 | opacity: 0.8; }
297 | 30% {
298 | -moz-transform: scale(2);
299 | opacity: 0; }
300 | 100% {
301 | -moz-transform: scale(2);
302 | opacity: 0; } }
303 | @keyframes pulsate {
304 | 0% {
305 | -webkit-transform: scale(1);
306 | -moz-transform: scale(1);
307 | -ms-transform: scale(1);
308 | -o-transform: scale(1);
309 | transform: scale(1);
310 | opacity: 0.8; }
311 | 30% {
312 | -webkit-transform: scale(2);
313 | -moz-transform: scale(2);
314 | -ms-transform: scale(2);
315 | -o-transform: scale(2);
316 | transform: scale(2);
317 | opacity: 0; }
318 | 100% {
319 | -webkit-transform: scale(2);
320 | -moz-transform: scale(2);
321 | -ms-transform: scale(2);
322 | -o-transform: scale(2);
323 | transform: scale(2);
324 | opacity: 0; } }
325 |
326 | /*# sourceMappingURL=homepage.css.map */
327 |
--------------------------------------------------------------------------------
/static/homepage.scss:
--------------------------------------------------------------------------------
1 | // TODO: Make media quieries for really small screens (< 850px width)
2 |
3 | .centered {
4 | width:90%;
5 | max-width:900px;
6 | margin:0 auto;
7 | }
8 |
9 | /* == Logged out user things == */
10 | // Is it possible to only serve these when the user is logged out?
11 | .logged-out-header {
12 |
13 | .logged-out-header-inner {
14 | width:40%;
15 | }
16 | .header-text {
17 | color:white;
18 | text-align:center;
19 | font-family:'Source Sans Pro', sans-serif;
20 | font-weight: bold;
21 | font-size:44px;
22 | text-shadow:0 2px 2px rgba(37,46,53, 0.6);
23 | margin:0 auto 30px auto;
24 | padding-top:20px;
25 | }
26 | }
27 | .showcase {
28 | height: 40.8%;
29 | margin: 0 auto;
30 | position: relative; /* for the abs-positioned image */
31 | cursor:default;
32 | -webkit-touch-callout: none; /* iOS Safari */
33 | -webkit-user-select: none; /* Chrome/Safari/Opera */
34 | -khtml-user-select: none; /* Konqueror */
35 | -moz-user-select: none; /* Firefox */
36 | -ms-user-select: none; /* IE/Edge */
37 | user-select: none; /* non-prefixed version, currently
38 | not supported by any browser */
39 |
40 | .showcase-img {
41 | width: 100%;
42 |
43 | border-radius: 5px;
44 | box-shadow: 0 1px 8px -1px #252E35;
45 | }
46 |
47 | .showcase-callout {
48 | z-index: 8888;
49 | color: white;
50 | position: absolute;
51 | height: 35px;
52 | box-sizing: border-box;
53 | font-family:'Source Sans Pro', sans-serif;
54 | font-weight: bold;
55 | font-size:16px;
56 | letter-spacing: 1px;
57 | white-space: nowrap;
58 | padding: 8px 30px;
59 | border-radius: 500px;
60 | background-color: #252E35;
61 |
62 | &:after {
63 | content:"";
64 | display: block;
65 | width: 0px;
66 | height: 0px;
67 | border-left: 10px solid #252E35;
68 | border-top: 10px solid #252E35;
69 | border-right: 10px solid transparent;
70 | border-bottom: 10px solid transparent;
71 | transform: translate(20px,-37px) rotate(45deg);
72 | position:relative;
73 | top:1px;
74 | }
75 | &.arrowplacement2 {
76 | transform:translate(-90%, 0);
77 | }
78 | &.arrowplacement2:after {
79 | transform: translate(240px,-37px) rotate(45deg);
80 | }
81 | }
82 | }
83 | .showcase-pocket {
84 | display:block;
85 | background:#444C54;
86 | height:34px;
87 | position:relative;
88 | z-index:5555;
89 | top:-30px;
90 | box-shadow: 0 -17px 20px -13px rgba(68,76,84,0.9), 0 -5px 4px -5px rgba(0,0,0,0.5);
91 | width:calc(40% + 100px);
92 | margin:0 auto;
93 | }
94 | .cta-wrapper {
95 | text-align:center;
96 | }
97 | .cta-button {
98 | display:inline-block;
99 | color:white;
100 | text-decoration:none;
101 | font-family:'Source Sans Pro', sans-serif;
102 | font-size:20px;
103 | font-weight:bold;
104 | padding:18px 38px;
105 | background:#42BA92;
106 | border-radius:4px;
107 | line-height:1;
108 |
109 | span {
110 | font-size:16px;
111 | color:rgba(37,46,53,0.85);
112 | font-weight:normal;
113 |
114 | /*&:before {
115 | content:' ';
116 | display:block;
117 | width:24px;
118 | margin-left:-12px;
119 | height:0;
120 | border-top:1px solid rgba(37,46,53,0.2);
121 |
122 | position:absolute;
123 | top:-1px;
124 | left:50%;
125 | }*/
126 | }
127 | }
128 | .or-separator {
129 | display:inline-block;
130 | color:white;
131 | font-family:'Source Sans Pro', sans-serif;
132 | position:relative;
133 | bottom:12px;
134 | margin:0 20px;
135 | cursor:default;
136 |
137 | &:before {
138 | content:" ";
139 | display:block;
140 | width:0;
141 | height:8px;
142 | border-right:1px solid rgba(255,255,255,0.3);
143 | position:relative;
144 | left:7px;
145 | }
146 | &:after {
147 | content:" ";
148 | display:block;
149 | width:0;
150 | height:8px;
151 | border-right:1px solid rgba(255,255,255,0.3);
152 | position:relative;
153 | left:7px;
154 | top:4px;
155 | }
156 | }
157 |
158 | /* == Responsibly responsive == */
159 | @media screen and (max-width:1634px) {
160 | .logged-out-header .header-text {
161 | font-size:2.65vw;
162 | }
163 | }
164 | @media screen and (max-width:850px) {
165 | .showcase, .showcase-pocket {
166 | display:none;
167 | }
168 | .logged-out-header .logged-out-header-inner {
169 | width:80%;
170 | }
171 | .logged-out-header .header-text {
172 | font-size:5.05vw;
173 | }
174 | }
175 | @media screen and (max-width:570px) {
176 | .cta-button {
177 | display:block;
178 |
179 | margin:10px 0;
180 | }
181 | .or-separator {
182 | display:none;
183 | }
184 | }
185 | /* == Carousels == */
186 | .carousel-wrapper {
187 | padding:30px 0;
188 |
189 | &.gray {
190 | background:#ddd;
191 | }
192 | }
193 | .carousel {
194 | @extend .centered;
195 | font-family:'Source Sans Pro', sans-serif;
196 |
197 | .carousel-title {
198 | font-size:42px;
199 | margin:0;
200 | color:#42BA92;
201 | line-height:0.8;
202 | margin-bottom:10px;
203 | }
204 |
205 | .carousel-content {
206 | display:flex;
207 | width:100%;
208 | border-radius:4px;
209 | overflow:hidden;
210 |
211 | .carousel-link {
212 | margin-bottom:-4px; // Account for inline-block spacing struggles
213 | text-decoration:none;
214 | flex-shrink:1;
215 | flex-grow:1;
216 | flex-basis:0;
217 |
218 | position:relative;
219 | }
220 | .carousel-image {
221 | width:100%;
222 | }
223 | .carousel-info {
224 | width:100%;
225 | height:0;
226 | padding-bottom:100%; // Doctors hate this one weird trick!
227 | position:absolute;
228 | top:0;
229 | left:0;
230 | background: -moz-linear-gradient(top, rgba(0,0,0,0.75) 0%, rgba(0,0,0,0.5) 100%);
231 | background: -webkit-linear-gradient(top, rgba(0,0,0,0.75) 0%,rgba(0,0,0,0.5) 100%);
232 | background: linear-gradient(to bottom, rgba(0,0,0,0.75) 0%,rgba(0,0,0,0.5) 100%);
233 | opacity:0;
234 | overflow:hidden;
235 |
236 | transition:0.4s;
237 |
238 | &:hover {
239 | opacity:1;
240 | }
241 | }
242 | .carousel-header {
243 | font-size:20px;
244 | max-width:100%;
245 | position:absolute;
246 | top:15px;
247 | left:15px;
248 | margin:0;
249 | margin-right:15px;
250 | line-height:1;
251 | opacity:1;
252 | color:white;
253 | }
254 | }
255 | }
256 |
257 | /* putting my css down here, easier to edit (also I don't do scss) */
258 | .showcase-callout {
259 | -webkit-transition: opacity .4s;
260 | transition: opacity .4s;
261 | opacity: 0;
262 | }
263 |
264 | /*.showcase-callout:hover {
265 | opacity: .8;
266 | }*/
267 |
268 | .bordered-link {
269 | -webkit-transition: background .5s, color .2s;
270 | transition: background .5s, color .2s;
271 | }
272 |
273 | .unbordered-link {
274 | transition: background .5s, color .2s;
275 | padding: 6px 14px;
276 | border-radius: 4px;
277 | color: white;
278 | }
279 |
280 | .unbordered-link:hover {
281 | background: white;
282 | color: #444C54 !important;
283 | }
284 |
285 | .showcase-trigger {
286 | border-radius: 10px;
287 | width: 15px;
288 | height: 15px;
289 | background-color: #0074D9;
290 | z-index: 8888;
291 | position: absolute;
292 | opacity: .8;
293 | box-shadow: 0px 0px 5px #0074D9;
294 | transition: opacity ease-out 0.2s, width ease-out 0.2s, height ease-out 0.2s, transform ease-out 0.2s;
295 | transform: translate(0, 0);
296 | }
297 |
298 | .showcase-trigger:hover + .showcase-callout {
299 | opacity: 1;
300 | }
301 | .showcase-trigger::after {
302 | animation: pulsate 3s 1s ease-out infinite;
303 | background: transparent;
304 | border-radius: 10px;
305 | width: 15px;
306 | height: 15px;
307 | position: absolute;
308 | left: 0;
309 | top: 0;
310 | box-sizing: border-box;
311 | border: 2px solid #0074D9;
312 | position: absolute;
313 | display: block;
314 | content: "";
315 | opacity: 0;
316 | }
317 |
318 | .showcase-trigger:hover {
319 | opacity: 0.3;
320 | width: 20px;
321 | height: 20px;
322 | border-radius: 100%;
323 | transform:translate(-3.5px, -3.5px);
324 | box-shadow: none;
325 | }
326 |
327 | .showcase-trigger:hover::after {
328 | animation: none;
329 | display: none;
330 | }
331 |
332 |
333 |
334 | /* transition things */
335 | @-webkit-keyframes pulsate {
336 | 0% {
337 | -webkit-transform:scale(1);
338 | opacity:0.8
339 | }
340 | 30% {
341 | -webkit-transform:scale(2);
342 | opacity:0
343 | }
344 | 100% {
345 | -webkit-transform:scale(2);
346 | opacity:0
347 | }
348 | }
349 | @-moz-keyframes pulsate {
350 | 0% {
351 | -moz-transform:scale(1);
352 | opacity:0.8
353 | }
354 | 30% {
355 | -moz-transform:scale(2);
356 | opacity:0
357 | }
358 | 100% {
359 | -moz-transform:scale(2);
360 | opacity:0
361 | }
362 | }
363 | @keyframes pulsate {
364 | 0% {
365 | -webkit-transform:scale(1);
366 | -moz-transform:scale(1);
367 | -ms-transform:scale(1);
368 | -o-transform:scale(1);
369 | transform:scale(1);
370 | opacity:0.8
371 | }
372 | 30% {
373 | -webkit-transform:scale(2);
374 | -moz-transform:scale(2);
375 | -ms-transform:scale(2);
376 | -o-transform:scale(2);
377 | transform:scale(2);
378 | opacity:0
379 | }
380 | 100% {
381 | -webkit-transform:scale(2);
382 | -moz-transform:scale(2);
383 | -ms-transform:scale(2);
384 | -o-transform:scale(2);
385 | transform:scale(2);
386 | opacity:0
387 | }
388 | }
389 |
--------------------------------------------------------------------------------
/apps/projects/static/js/editor/vendor/htmlparser.js:
--------------------------------------------------------------------------------
1 | /*
2 | * HTML5 Parser By Sam Blowes
3 | *
4 | * Designed for HTML5 documents
5 | *
6 | * Original code by John Resig (ejohn.org)
7 | * http://ejohn.org/blog/pure-javascript-html-parser/
8 | * Original code by Erik Arvidsson, Mozilla Public License
9 | * http://erik.eae.net/simplehtmlparser/simplehtmlparser.js
10 | *
11 | * // Use like so:
12 | * HTMLParser(htmlString, {
13 | * start: function(tag, attrs, unary) {},
14 | * end: function(tag) {},
15 | * chars: function(text) {},
16 | * comment: function(text) {}
17 | * });
18 | *
19 | * // or to get an XML string:
20 | * HTMLtoXML(htmlString);
21 | *
22 | * // or to get an XML DOM Document
23 | * HTMLtoDOM(htmlString);
24 | *
25 | * // or to inject into an existing document/DOM node
26 | * HTMLtoDOM(htmlString, document);
27 | * HTMLtoDOM(htmlString, document.body);
28 | *
29 | */
30 |
31 | (function () {
32 |
33 | // Regular Expressions for parsing tags and attributes
34 | var startTag = /^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/,
35 | endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/,
36 | attr = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g;
37 |
38 | // Empty Elements - HTML 5
39 | var empty = makeMap("area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr");
40 |
41 | // Block Elements - HTML 5
42 | var block = makeMap("address,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,ins,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video");
43 |
44 | // Inline Elements - HTML 5
45 | var inline = makeMap("a,abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var");
46 |
47 | // Elements that you can, intentionally, leave open
48 | // (and which close themselves)
49 | var closeSelf = makeMap("colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr");
50 |
51 | // Attributes that have their values filled in disabled="disabled"
52 | var fillAttrs = makeMap("checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected");
53 |
54 | // Special Elements (can contain anything)
55 | var special = makeMap("script,style");
56 |
57 | var HTMLParser = this.HTMLParser = function (html, handler) {
58 | var index, chars, match, stack = [], last = html;
59 | stack.last = function () {
60 | return this[this.length - 1];
61 | };
62 |
63 | while (html) {
64 | chars = true;
65 |
66 | // Make sure we're not in a script or style element
67 | if (!stack.last() || !special[stack.last()]) {
68 |
69 | // Comment
70 | if (html.indexOf("");
72 |
73 | if (index >= 0) {
74 | if (handler.comment)
75 | handler.comment(html.substring(4, index));
76 | html = html.substring(index + 3);
77 | chars = false;
78 | }
79 |
80 | // end tag
81 | } else if (html.indexOf("") == 0) {
82 | match = html.match(endTag);
83 |
84 | if (match) {
85 | html = html.substring(match[0].length);
86 | match[0].replace(endTag, parseEndTag);
87 | chars = false;
88 | }
89 |
90 | // start tag
91 | } else if (html.indexOf("<") == 0) {
92 | match = html.match(startTag);
93 |
94 | if (match) {
95 | html = html.substring(match[0].length);
96 | match[0].replace(startTag, parseStartTag);
97 | chars = false;
98 | }
99 | }
100 |
101 | if (chars) {
102 | index = html.indexOf("<");
103 |
104 | var text = index < 0 ? html : html.substring(0, index);
105 | html = index < 0 ? "" : html.substring(index);
106 |
107 | if (handler.chars)
108 | handler.chars(text);
109 | }
110 |
111 | } else {
112 | html = html.replace(new RegExp("([\\s\\S]*?)<\/" + stack.last() + "[^>]*>"), function (all, text) {
113 | text = text.replace(/|/g, "$1$2");
114 | if (handler.chars)
115 | handler.chars(text);
116 |
117 | return "";
118 | });
119 |
120 | parseEndTag("", stack.last());
121 | }
122 |
123 | if (html == last)
124 | throw "Parse Error: " + html;
125 | last = html;
126 | }
127 |
128 | // Clean up any remaining tags
129 | parseEndTag();
130 |
131 | function parseStartTag(tag, tagName, rest, unary) {
132 | tagName = tagName.toLowerCase();
133 |
134 | if (block[tagName]) {
135 | while (stack.last() && inline[stack.last()]) {
136 | parseEndTag("", stack.last());
137 | }
138 | }
139 |
140 | if (closeSelf[tagName] && stack.last() == tagName) {
141 | parseEndTag("", tagName);
142 | }
143 |
144 | unary = empty[tagName] || !!unary;
145 |
146 | if (!unary)
147 | stack.push(tagName);
148 |
149 | if (handler.start) {
150 | var attrs = [];
151 |
152 | rest.replace(attr, function (match, name) {
153 | var value = arguments[2] ? arguments[2] :
154 | arguments[3] ? arguments[3] :
155 | arguments[4] ? arguments[4] :
156 | fillAttrs[name] ? name : "";
157 |
158 | attrs.push({
159 | name: name,
160 | value: value,
161 | escaped: value.replace(/(^|[^\\])"/g, '$1\\\"') //"
162 | });
163 | });
164 |
165 | if (handler.start)
166 | handler.start(tagName, attrs, unary);
167 | }
168 | }
169 |
170 | function parseEndTag(tag, tagName) {
171 | // If no tag name is provided, clean shop
172 | if (!tagName)
173 | var pos = 0;
174 |
175 | // Find the closest opened tag of the same type
176 | else
177 | for (var pos = stack.length - 1; pos >= 0; pos--)
178 | if (stack[pos] == tagName)
179 | break;
180 |
181 | if (pos >= 0) {
182 | // Close all the open elements, up the stack
183 | for (var i = stack.length - 1; i >= pos; i--)
184 | if (handler.end)
185 | handler.end(stack[i]);
186 |
187 | // Remove the open elements from the stack
188 | stack.length = pos;
189 | }
190 | }
191 | };
192 |
193 | this.HTMLtoXML = function (html) {
194 | var results = "";
195 |
196 | HTMLParser(html, {
197 | start: function (tag, attrs, unary) {
198 | results += "<" + tag;
199 |
200 | for (var i = 0; i < attrs.length; i++)
201 | results += " " + attrs[i].name + '="' + attrs[i].escaped + '"';
202 | results += ">";
203 | },
204 | end: function (tag) {
205 | results += "" + tag + ">";
206 | },
207 | chars: function (text) {
208 | results += text;
209 | },
210 | comment: function (text) {
211 | results += "";
212 | }
213 | });
214 |
215 | return results;
216 | };
217 |
218 | this.HTMLtoDOM = function (html, doc) {
219 | // There can be only one of these elements
220 | var one = makeMap("html,head,body,title");
221 |
222 | // Enforce a structure for the document
223 | var structure = {
224 | link: "head",
225 | base: "head"
226 | };
227 |
228 | if (!doc) {
229 | if (typeof DOMDocument != "undefined")
230 | doc = new DOMDocument();
231 | else if (typeof document != "undefined" && document.implementation && document.implementation.createDocument)
232 | doc = document.implementation.createDocument("", "", null);
233 | else if (typeof ActiveX != "undefined")
234 | doc = new ActiveXObject("Msxml.DOMDocument");
235 |
236 | } else
237 | doc = doc.ownerDocument ||
238 | doc.getOwnerDocument && doc.getOwnerDocument() ||
239 | doc;
240 |
241 | var elems = [],
242 | documentElement = doc.documentElement ||
243 | doc.getDocumentElement && doc.getDocumentElement();
244 |
245 | // If we're dealing with an empty document then we
246 | // need to pre-populate it with the HTML document structure
247 | if (!documentElement && doc.createElement) (function () {
248 | var html = doc.createElement("html");
249 | var head = doc.createElement("head");
250 | head.appendChild(doc.createElement("title"));
251 | html.appendChild(head);
252 | html.appendChild(doc.createElement("body"));
253 | doc.appendChild(html);
254 | })();
255 |
256 | // Find all the unique elements
257 | if (doc.getElementsByTagName)
258 | for (var i in one)
259 | one[i] = doc.getElementsByTagName(i)[0];
260 |
261 | // If we're working with a document, inject contents into
262 | // the body element
263 | var curParentNode = one.body;
264 |
265 | HTMLParser(html, {
266 | start: function (tagName, attrs, unary) {
267 | // If it's a pre-built element, then we can ignore
268 | // its construction
269 | if (one[tagName]) {
270 | curParentNode = one[tagName];
271 | if (!unary) {
272 | elems.push(curParentNode);
273 | }
274 | return;
275 | }
276 |
277 | var elem = doc.createElement(tagName);
278 |
279 | for (var attr in attrs)
280 | elem.setAttribute(attrs[attr].name, attrs[attr].value);
281 |
282 | if (structure[tagName] && typeof one[structure[tagName]] != "boolean")
283 | one[structure[tagName]].appendChild(elem);
284 |
285 | else if (curParentNode && curParentNode.appendChild)
286 | curParentNode.appendChild(elem);
287 |
288 | if (!unary) {
289 | elems.push(elem);
290 | curParentNode = elem;
291 | }
292 | },
293 | end: function (tag) {
294 | elems.length -= 1;
295 |
296 | // Init the new parentNode
297 | curParentNode = elems[elems.length - 1];
298 | },
299 | chars: function (text) {
300 | curParentNode.appendChild(doc.createTextNode(text));
301 | },
302 | comment: function (text) {
303 | // create comment node
304 | }
305 | });
306 |
307 | return doc;
308 | };
309 |
310 | function makeMap(str) {
311 | var obj = {}, items = str.split(",");
312 | for (var i = 0; i < items.length; i++)
313 | obj[items[i]] = true;
314 | return obj;
315 | }
316 | })();
--------------------------------------------------------------------------------
/apps/projects/static/css/editor/style.scss:
--------------------------------------------------------------------------------
1 | $nav_grad_top: #42BA92;
2 | $nav_grad_bottom: #27ae60;
3 | $borders_color: #252E35;
4 | $right_background: #444C54;
5 | $right_transparent: rgba(68,76,84, 0.6);
6 | $right_texture: "/static/img/diagonalTexture.png";
7 | $top_bar_text_shadow: rgba(0,0,0,0.5);
8 | $menu_drop_back: #fff;
9 | $menu_drop_hover: #58B2C8;
10 | $menu_drop_text: #333;
11 | $search_icon_url: "/static/img/nav-search-glass.png";
12 |
13 | @import "blocks";
14 | @import "menus";
15 | @import "helpers";
16 |
17 | @import url(http://fonts.googleapis.com/css?family=Source+Sans+Pro:400,700);
18 |
19 | body {
20 | margin: 0px;
21 | overflow: hidden;
22 | }
23 |
24 | html, body {
25 | height: 100%;
26 | }
27 |
28 | .scriptingArea {
29 | height: calc(100% - 200px - 12px);
30 | min-width: 100%;
31 | overflow: auto;
32 | position: relative;
33 |
34 | //for some reason this is cutting off the hat block ::after element...
35 | background: linear-gradient($right_transparent, $right_transparent), url($right_texture);
36 | z-index: 1;
37 | }
38 |
39 | .topBar {
40 | /* Monster Gradient: */
41 | background: $nav_grad_top;
42 | //border-bottom: 1px solid $borders_color;
43 | color: #efefef;
44 | font-family: 'Source Sans Pro', sans-serif;
45 | padding: 15px 24px;
46 | position:relative;
47 | z-index:999;
48 | }
49 |
50 | .left {
51 | display: inline-block;
52 | }
53 |
54 | .logo {
55 | color: white;
56 | font-size: 20px;
57 | font-weight: bold;
58 | //text-shadow: 0px 1px 1px $top_bar_text_shadow;
59 | vertical-align: middle;
60 | }
61 |
62 | .menus {
63 | display: inline-block;
64 | margin-left: 30px;
65 | vertical-align: middle;
66 | }
67 |
68 | .menu {
69 | display: inline-block;
70 | margin-right: 20px;
71 | position: relative;
72 | top: 1px;
73 | }
74 | .menuTitle:hover + .menuContents, .menuContents:hover {
75 | display: block;
76 | }
77 |
78 | .menuTitle {
79 | cursor: default;
80 | position: relative;
81 | z-index: 999;
82 | }
83 |
84 | .menuContents {
85 | background: $menu_drop_back;
86 | border-radius: 3px;
87 | display: none;
88 | left: 0px;
89 | list-style: none;
90 | margin: 0px;
91 | padding: 0px;
92 | position: absolute;
93 | top: 30px;
94 | width: 145px;
95 | z-index: 5;
96 | border:1px solid $borders_color;
97 | }
98 |
99 | .menuContents:before {
100 | background: $menu_drop_back;
101 | content: ' ';
102 | display: block;
103 | width: 12px;
104 | height: 12px;
105 | left: 5px;
106 | position: absolute;
107 | top: -7px;
108 | z-index: -8;
109 | border:1px solid $borders_color;
110 | border-bottom-color:transparent;
111 | border-right-color:transparent;
112 |
113 | -ms-transform: rotate(45deg); /* IE 9 */
114 | -webkit-transform: rotate(45deg); /* Chrome, Safari, Opera */
115 | transform: rotate(45deg);
116 | }
117 |
118 | .menuContents:after {
119 | content: ' ';
120 | display: block;
121 | height: 130%;
122 | height: calc(100% + 40px);
123 | left: -10px;
124 | position: absolute;
125 | top: -30px;
126 | width: 120%;
127 | /* For older browsers */
128 | width: calc(100% + 20px);
129 | z-index: -1;
130 | }
131 |
132 | .menuContents li {
133 | color: $menu_drop_text;
134 | cursor: pointer;
135 | padding: 10px 20px;
136 | }
137 |
138 | .menuContents li:first-of-type {
139 | border-top-left-radius: 2px;
140 | border-top-right-radius: 2px;
141 | }
142 |
143 | .menuContents li:last-of-type {
144 | border-bottom-left-radius: 2px;
145 | border-bottom-right-radius: 2px;
146 | }
147 |
148 | .menuContents li:hover {
149 | background: $menu_drop_hover;
150 | }
151 |
152 | .mainArea {
153 | align-content: stretch;
154 | display: flex;
155 | height: calc(100% - 45px);
156 | }
157 |
158 | .leftSide {
159 | border-right: 4px solid $borders_color;
160 | box-sizing: border-box;
161 | flex: 0 0 400px;
162 | height: 100%;
163 | max-width: 100%;
164 | overflow-x: hidden;
165 | .pagePreview {
166 | height: calc(100% - 200px);
167 | .previewBody {
168 | background: white;
169 | height: 100%;
170 | width: 100%;
171 | border: none;
172 | }
173 | }
174 | .filePane {
175 | height: 200px;
176 | background-color: white;
177 | box-sizing: border-box;
178 | border-top: 5px solid #BFBFBF;
179 | padding: 5px;
180 | overflow-y: scroll;
181 | .file,
182 | .add-file {
183 | width: 100px;
184 | height: 100px;
185 | border: 4px solid #BFBFBF;
186 | border-radius: 3px;
187 | display: inline-block;
188 | text-align: center;
189 | margin: 0px;
190 | margin-right: 10px;
191 | margin-bottom: 10px;
192 | }
193 | .file {
194 | &-name {
195 | position: relative;
196 | top: 50%;
197 | transform: translateY(-50%);
198 | font-family: 'Source Sans Pro', sans-serif;
199 | }
200 | &.selected {
201 | border-color:#989898;
202 | }
203 | }
204 | }
205 | }
206 |
207 | .rightSide {
208 | flex-grow: 1;
209 | flex-shrink: 1;
210 | height: 100%;
211 | width: 100%;
212 |
213 | .upperArea {
214 | border-bottom: 2px solid $borders_color;
215 | display: flex;
216 | height: 200px;
217 | width: 100%;
218 | }
219 | }
220 |
221 | .upperArea .paletteSelect {
222 | background: $right_background;
223 | border-right: 2px solid $borders_color;
224 | flex: 0 0 250px;
225 | overflow-y: auto;
226 | padding: 20px;
227 | }
228 |
229 | .upperArea .allBlocks {
230 | background: $right_background;
231 | height: 100%;
232 | overflow-x: hidden;
233 | overflow-y: auto;
234 | position: relative;
235 | /* For child positioning (absolute) */
236 | width: 100%;
237 | }
238 |
239 | .paletteColumn {
240 | width: 83px;
241 | margin: 0px 15px;
242 | padding: 0px;
243 | text-align: left;
244 | display: inline-block;
245 | position: relative;
246 | left: -3px;
247 |
248 | .paletteOptionWrap:last-of-type {
249 | margin-bottom: 0px;
250 | }
251 | }
252 |
253 | .paletteOptionWrap {
254 | display: inline-block;
255 | border: 1px solid #505E77;
256 | /* Massive gradient code: */
257 | background: rgb(255,255,255);
258 | border-radius: 999px;
259 | padding: 3px 12px;
260 | font-family: 'Source Sans Pro', sans-serif;
261 | cursor: pointer;
262 | width: 100%;
263 | margin-bottom: 15px;
264 | position: relative;
265 |
266 | input[type=radio] {
267 | display: none;
268 | }
269 | }
270 |
271 | .paletteColorIndicator {
272 | display: block;
273 | width: 20px;
274 | height: 20px;
275 | background: rgb(222,42,51);
276 | position: absolute;
277 | top: 3px;
278 | right: 4px;
279 | border-radius: 999px;
280 | }
281 |
282 | .paletteColorIndicator:after {
283 | content: ' ';
284 | //display: block;
285 | display:none;
286 | width: 20px;
287 | height: 26px;
288 | background: -moz-linear-gradient(top, rgba(0,0,0,0) 0%, rgba(0,0,0,0.12) 100%);
289 | /* FF3.6+ */
290 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(0,0,0,0)), color-stop(100%,rgba(0,0,0,0.12)));
291 | /* Chrome,Safari4+ */
292 | background: -webkit-linear-gradient(top, rgba(0,0,0,0) 0%,rgba(0,0,0,0.12) 100%);
293 | /* Chrome10+,Safari5.1+ */
294 | background: -o-linear-gradient(top, rgba(0,0,0,0) 0%,rgba(0,0,0,0.12) 100%);
295 | /* Opera 11.10+ */
296 | background: -ms-linear-gradient(top, rgba(0,0,0,0) 0%,rgba(0,0,0,0.12) 100%);
297 | /* IE10+ */
298 | background: linear-gradient(to bottom, rgba(0,0,0,0) 0%,rgba(0,0,0,0.12) 100%);
299 | /* W3C */
300 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00000000', endColorstr='#1f000000',GradientType=0 );
301 | /* IE6-9 */
302 | position: absolute;
303 | top: 0px;
304 | right: 0px;
305 | border-radius: 0px 999px 999px 0px;
306 | border: 1px solid rgba(0,0,0,0.15);
307 | border-left-color: transparent;
308 | }
309 |
310 | .paletteOptionWrap:hover {
311 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0);
312 | }
313 |
314 | #searchBar {
315 | position: absolute;
316 | top: 0px;
317 | right: 57px;
318 | border-radius: 0px 0px 5px 5px;
319 | border: 1px solid $borders_color;
320 | border-top: none;
321 | outline: none;
322 | padding: 8px 10px 8px 26px;
323 | background-image: url($search_icon_url);
324 | background-repeat: no-repeat;
325 | background-position: 8px 9px;
326 | cursor: pointer;
327 | width: 0px;
328 | padding-right: 4px;
329 | opacity: 0.7;
330 | transition: width 0.2s,
331 | padding 0.2s;
332 | }
333 |
334 | #searchBar:hover, #searchBar:focus {
335 | opacity: 1;
336 | }
337 |
338 | #searchBar:focus {
339 | cursor: auto;
340 | width: 170px;
341 | }
342 |
343 | .infoText {
344 | color:#ddd;
345 | font-family:'Source Code Pro', sans-serif;
346 | }
347 |
348 | .upperArea .allBlocks .blockArea {
349 | /*
350 | display: flex;
351 | flex-direction: column;
352 | flex-wrap: wrap;
353 | */
354 | height: 100%;
355 | height: calc(100% - 64px);
356 | overflow-x: hidden;
357 | overflow-y: auto;
358 | justify-content: flex-start;
359 | padding: 32px;
360 | .stack, .c-wrapper {
361 | margin:6px 0px;
362 | }
363 | }
364 |
365 | .trashCan {
366 | display: none;
367 | position: fixed;
368 | top: 56px;
369 | left: calc(130px + 50%);
370 | width: 140px;
371 | height: 180px;
372 | z-index: 800;
373 | background-size: 100% auto;
374 | background-image: url("/static/img/trash_closed.png");
375 | cursor: default;
376 | &:hover,
377 | &.hovering {
378 | background-image: url("/static/img/trash_open.png");
379 | }
380 | &.showing {
381 | display: block;
382 | }
383 | }
384 |
385 | .trashCan2 {
386 | display: block;
387 | position: fixed;
388 | bottom: 10px;
389 | right: 20px;
390 | width: 70px;
391 | height: 90px;
392 | z-index: 800;
393 | background-size: 100% auto;
394 | background-image: url("/static/img/trash_closed.png");
395 | cursor: default;
396 | &:hover,
397 | &.hovering {
398 | background-image: url("/static/img/trash_open.png");
399 | }
400 | }
401 |
402 | @media (max-width:450px) {
403 | .advanceWrap {
404 | display: none;
405 | }
406 | }
--------------------------------------------------------------------------------