├── .gitignore ├── README.md ├── requirements.txt ├── setup.py ├── test_project ├── __init__.py ├── manage.py ├── requirements.txt ├── settings.py ├── static │ └── ace │ │ ├── LICENSE │ │ ├── ace-uncompressed.js │ │ ├── ace.js │ │ ├── keybinding-emacs.js │ │ ├── keybinding-vim.js │ │ ├── mode-c_cpp.js │ │ ├── mode-clojure.js │ │ ├── mode-coffee.js │ │ ├── mode-csharp.js │ │ ├── mode-css.js │ │ ├── mode-groovy.js │ │ ├── mode-html.js │ │ ├── mode-java.js │ │ ├── mode-javascript.js │ │ ├── mode-json.js │ │ ├── mode-lua.js │ │ ├── mode-markdown.js │ │ ├── mode-ocaml.js │ │ ├── mode-perl.js │ │ ├── mode-php.js │ │ ├── mode-python.js │ │ ├── mode-ruby.js │ │ ├── mode-scad.js │ │ ├── mode-scala.js │ │ ├── mode-scss.js │ │ ├── mode-svg.js │ │ ├── mode-textile.js │ │ ├── mode-xml.js │ │ ├── theme-clouds.js │ │ ├── theme-clouds_midnight.js │ │ ├── theme-cobalt.js │ │ ├── theme-crimson_editor.js │ │ ├── theme-dawn.js │ │ ├── theme-eclipse.js │ │ ├── theme-idle_fingers.js │ │ ├── theme-kr_theme.js │ │ ├── theme-merbivore.js │ │ ├── theme-merbivore_soft.js │ │ ├── theme-mono_industrial.js │ │ ├── theme-monokai.js │ │ ├── theme-pastel_on_dark.js │ │ ├── theme-solarized_dark.js │ │ ├── theme-solarized_light.js │ │ ├── theme-textmate.js │ │ ├── theme-twilight.js │ │ ├── theme-vibrant_ink.js │ │ ├── worker-coffee.js │ │ ├── worker-css.js │ │ └── worker-javascript.js ├── templates │ └── base.html ├── urls.py └── views.py └── themes ├── __init__.py ├── admin.py ├── app_settings.py ├── engines.py ├── exceptions.py ├── loaders.py ├── middleware.py ├── models.py ├── packaging.py ├── registration.py ├── templates └── themes │ ├── base.html │ ├── home.html │ ├── theme.html │ └── theme_up_file.html ├── templatetags ├── __init__.py └── themes_tags.py ├── tests ├── 01.basic.txt ├── 02-models.txt ├── 03-template-loader.txt ├── 04-template-tags.txt ├── 05-django-engine.txt ├── 06-jinja2-engine.txt-disabled ├── 07-middleware.txt ├── 08-packaging.txt ├── 09-security.txt └── middleware_funcs.py ├── urls.py └── views.py /.gitignore: -------------------------------------------------------------------------------- 1 | env 2 | *.pyc 3 | .DS_Store 4 | .*.swp 5 | .coverage 6 | data.db 7 | local_settings.py 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Overview on django-themes 2 | 3 | This is a pluggable application for theme supporting on Django. But together with the themes, it is 4 | a good way to support templates stored in database by an easy way. 5 | 6 | ## How it works 7 | 8 | Basically: 9 | 10 | - the applications register their templates they are able to load from Themes (this is important 11 | for security, but there's a setting to allow not registered templates with standard configuration); 12 | - each Theme has the templates the project registered; 13 | - a Theme is set as default Theme, but a function can set it dinamically from the current request; 14 | - when a template is required, our template loader tries to load it from current Theme, if it finds, 15 | so returns that template (instead from file system); 16 | - you can upload static files for the themes; 17 | - you can download and import themes; 18 | - works with Django's template renderer and Jinja2 (still in development). 19 | 20 | ## Testing 21 | 22 | If you want to test, do this (somewhere): 23 | 24 | $ git clone git://github.com/marinho/django-themes.git 25 | $ cd django-themes 26 | $ virtualenv env 27 | $ source env/bin/activate 28 | $ pip install -r test_project/requirements.txt 29 | $ cd test_project 30 | $ ln -s ../themes . 31 | $ # run syncdb and create a superuser when asked 32 | $ python manage.py syncdb 33 | $ python manage.py runserver 34 | 35 | So you are able to visit in the browser: 36 | 37 | - http://localhost:8000/ - firstly this will show a "Template not found" error 38 | - http://localhost:8000/admin/ - log in using the admin interface 39 | - http://localhost:8000/themes/ - here you can create your first template. Save as the home template and set the theme as default 40 | - http://localhost:8000/ - come back here to see it working 41 | 42 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | django==1.3 2 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import themes 2 | import os 3 | 4 | # Downloads setuptools if not find it before try to import 5 | try: 6 | import ez_setup 7 | ez_setup.use_setuptools() 8 | except ImportError: 9 | pass 10 | 11 | from setuptools import setup 12 | 13 | def fullsplit(path, result=None): 14 | """ 15 | Split a pathname into components (the opposite of os.path.join) in a 16 | platform-neutral way. Copied from Django. 17 | """ 18 | if result is None: 19 | result = [] 20 | head, tail = os.path.split(path) 21 | if head == '': 22 | return [tail] + result 23 | if head == path: 24 | return result 25 | return fullsplit(head, [tail] + result) 26 | 27 | packages = [] 28 | data_files = [] 29 | app_dir = 'themes' 30 | 31 | for dirpath, dirnames, filenames in os.walk(app_dir): 32 | for i, dirname in enumerate(dirnames): 33 | if dirname.startswith('.'): del dirnames[i] 34 | 35 | if '__init__.py' in filenames: 36 | packages.append('.'.join(fullsplit(dirpath))) 37 | 38 | elif filenames: 39 | data_files.append([dirpath, [os.path.join(dirpath, f) for f in filenames]]) 40 | 41 | setup( 42 | name='django-themes', 43 | version=themes.__version__, 44 | url=themes.__url__, 45 | author=themes.__author__, 46 | license=themes.__license__, 47 | packages=packages, 48 | data_files=data_files, 49 | ) 50 | 51 | -------------------------------------------------------------------------------- /test_project/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marinho/django-themes/4d86f0d4134989995490f6f2f5ec0e8d05d3ff5a/test_project/__init__.py -------------------------------------------------------------------------------- /test_project/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from django.core.management import execute_manager 3 | import imp 4 | try: 5 | imp.find_module('settings') # Assumed to be in the same directory. 6 | except ImportError: 7 | import sys 8 | sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n" % __file__) 9 | sys.exit(1) 10 | 11 | import settings 12 | 13 | if __name__ == "__main__": 14 | execute_manager(settings) 15 | -------------------------------------------------------------------------------- /test_project/requirements.txt: -------------------------------------------------------------------------------- 1 | django==1.3 2 | coverage==3.5 3 | nose==1.1.2 4 | django_nose==0.1.3 5 | django-plus==1.2.11 6 | Jinja2==2.6 7 | psycopg2==2.4.1 8 | -------------------------------------------------------------------------------- /test_project/settings.py: -------------------------------------------------------------------------------- 1 | # Django settings for test_project project. 2 | import os 3 | PROJECT_ROOT_PATH = os.path.dirname(os.path.abspath(__file__)) 4 | 5 | LOCAL = True 6 | DEBUG = True 7 | TEMPLATE_DEBUG = DEBUG 8 | 9 | ADMINS = ( 10 | # ('Your Name', 'your_email@example.com'), 11 | ) 12 | 13 | MANAGERS = ADMINS 14 | 15 | DATABASES = { 16 | 'default': { 17 | 'ENGINE': 'django.db.backends.sqlite3', 18 | 'NAME': os.path.join(PROJECT_ROOT_PATH, 'data.db'), 19 | 'USER': '', 20 | 'PASSWORD': '', 21 | 'HOST': '', 22 | 'PORT': '', 23 | } 24 | } 25 | 26 | # Local time zone for this installation. Choices can be found here: 27 | # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name 28 | # although not all choices may be available on all operating systems. 29 | # On Unix systems, a value of None will cause Django to use the same 30 | # timezone as the operating system. 31 | # If running in a Windows environment this must be set to the same as your 32 | # system time zone. 33 | TIME_ZONE = 'America/Sao_Paulo' 34 | 35 | # Language code for this installation. All choices can be found here: 36 | # http://www.i18nguy.com/unicode/language-identifiers.html 37 | LANGUAGE_CODE = 'en-us' 38 | 39 | SITE_ID = 1 40 | 41 | # If you set this to False, Django will make some optimizations so as not 42 | # to load the internationalization machinery. 43 | USE_I18N = True 44 | 45 | # If you set this to False, Django will not format dates, numbers and 46 | # calendars according to the current locale 47 | USE_L10N = True 48 | 49 | # Absolute filesystem path to the directory that will hold user-uploaded files. 50 | # Example: "/home/media/media.lawrence.com/media/" 51 | MEDIA_ROOT = os.path.join(PROJECT_ROOT_PATH, 'static', 'uploads') 52 | 53 | # URL that handles the media served from MEDIA_ROOT. Make sure to use a 54 | # trailing slash. 55 | # Examples: "http://media.lawrence.com/media/", "http://example.com/media/" 56 | MEDIA_URL = '/static/uploads/' 57 | 58 | # Absolute path to the directory static files should be collected to. 59 | # Don't put anything in this directory yourself; store your static files 60 | # in apps' "static/" subdirectories and in STATICFILES_DIRS. 61 | # Example: "/home/media/media.lawrence.com/static/" 62 | STATIC_ROOT = os.path.join(PROJECT_ROOT_PATH, 'static2') 63 | 64 | # URL prefix for static files. 65 | # Example: "http://media.lawrence.com/static/" 66 | STATIC_URL = '/static/' 67 | 68 | # URL prefix for admin static files -- CSS, JavaScript and images. 69 | # Make sure to use a trailing slash. 70 | # Examples: "http://foo.com/static/admin/", "/static/admin/". 71 | ADMIN_MEDIA_PREFIX = '/static/admin/' 72 | 73 | # Additional locations of static files 74 | STATICFILES_DIRS = ( 75 | os.path.join(PROJECT_ROOT_PATH, 'static'), 76 | ) 77 | 78 | # List of finder classes that know how to find static files in 79 | # various locations. 80 | STATICFILES_FINDERS = ( 81 | 'django.contrib.staticfiles.finders.FileSystemFinder', 82 | 'django.contrib.staticfiles.finders.AppDirectoriesFinder', 83 | 'django.contrib.staticfiles.finders.DefaultStorageFinder', 84 | ) 85 | 86 | # Make this unique, and don't share it with anybody. 87 | SECRET_KEY = 'omuj=4ohe%2rru_n5hh#&q5=8b@i6#iz@u5o0__g5#c+3=&aq!' 88 | 89 | # List of callables that know how to import templates from various sources. 90 | TEMPLATE_LOADERS = ( 91 | 'themes.loaders.Loader', 92 | 'django.template.loaders.filesystem.Loader', 93 | 'django.template.loaders.app_directories.Loader', 94 | # 'django.template.loaders.eggs.Loader', 95 | ) 96 | 97 | MIDDLEWARE_CLASSES = ( 98 | 'django.middleware.common.CommonMiddleware', 99 | 'django.contrib.sessions.middleware.SessionMiddleware', 100 | 'django.middleware.csrf.CsrfViewMiddleware', 101 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 102 | 'django.contrib.messages.middleware.MessageMiddleware', 103 | 'themes.middleware.ThemeMiddleware', 104 | 'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware', 105 | 'django.middleware.transaction.TransactionMiddleware', 106 | ) 107 | 108 | ROOT_URLCONF = 'urls' 109 | 110 | TEMPLATE_DIRS = ( 111 | os.path.join(PROJECT_ROOT_PATH, 'templates') 112 | ) 113 | 114 | INSTALLED_APPS = ( 115 | 'django.contrib.auth', 116 | 'django.contrib.contenttypes', 117 | 'django.contrib.sessions', 118 | 'django.contrib.sites', 119 | 'django.contrib.messages', 120 | 'django.contrib.staticfiles', 121 | 'django.contrib.admin', 122 | 'django.contrib.flatpages', 123 | 124 | 'django_nose', 125 | 'djangoplus', 126 | 'themes', 127 | ) 128 | 129 | # A sample logging configuration. The only tangible logging 130 | # performed by this configuration is to send an email to 131 | # the site admins on every HTTP 500 error. 132 | # See http://docs.djangoproject.com/en/dev/topics/logging for 133 | # more details on how to customize your logging configuration. 134 | LOGGING = { 135 | 'version': 1, 136 | 'disable_existing_loggers': False, 137 | 'handlers': { 138 | 'mail_admins': { 139 | 'level': 'ERROR', 140 | 'class': 'django.utils.log.AdminEmailHandler' 141 | } 142 | }, 143 | 'loggers': { 144 | 'django.request': { 145 | 'handlers': ['mail_admins'], 146 | 'level': 'ERROR', 147 | 'propagate': True, 148 | }, 149 | } 150 | } 151 | 152 | TEST_RUNNER = 'django_nose.NoseTestSuiteRunner' 153 | NOSE_ARGS = ['--with-coverage', '--with-doctest', '--doctest-tests', '--doctest-extension=txt'] 154 | 155 | THEMES_CHOOSING_FUNCTION = 'themes.views.choose_theme' 156 | #THEMES_EXCLUDED_VARIABLES = ('perms',) 157 | 158 | try: 159 | from local_settings import * 160 | except ImportError: 161 | pass 162 | 163 | 164 | -------------------------------------------------------------------------------- /test_project/static/ace/keybinding-emacs.js: -------------------------------------------------------------------------------- 1 | define("ace/keyboard/keybinding/emacs",["require","exports","module","ace/keyboard/state_handler"],function(a,b,c){var d=a("ace/keyboard/state_handler").StateHandler,e=a("ace/keyboard/state_handler").matchCharacterOnly,f={start:[{key:"ctrl-x",then:"c-x"},{regex:["(?:command-([0-9]*))*","(down|ctrl-n)"],exec:"golinedown",params:[{name:"times",match:1,type:"number",defaultValue:1}]},{regex:["(?:command-([0-9]*))*","(right|ctrl-f)"],exec:"gotoright",params:[{name:"times",match:1,type:"number",defaultValue:1}]},{regex:["(?:command-([0-9]*))*","(up|ctrl-p)"],exec:"golineup",params:[{name:"times",match:1,type:"number",defaultValue:1}]},{regex:["(?:command-([0-9]*))*","(left|ctrl-b)"],exec:"gotoleft",params:[{name:"times",match:1,type:"number",defaultValue:1}]},{comment:"This binding matches all printable characters except numbers as long as they are no numbers and print them n times.",regex:["(?:command-([0-9]*))","([^0-9]+)*"],match:e,exec:"inserttext",params:[{name:"times",match:1,type:"number",defaultValue:"1"},{name:"text",match:2}]},{comment:"This binding matches numbers as long as there is no meta_number in the buffer.",regex:["(command-[0-9]*)*","([0-9]+)"],match:e,disallowMatches:[1],exec:"inserttext",params:[{name:"text",match:2,type:"text"}]},{regex:["command-([0-9]*)","(command-[0-9]|[0-9])"],comment:"Stops execution if the regex /meta_[0-9]+/ matches to avoid resetting the buffer."}],"c-x":[{key:"ctrl-g",then:"start"},{key:"ctrl-s",exec:"save",then:"start"}]};b.Emacs=new d(f)}),define("ace/keyboard/state_handler",["require","exports","module"],function(a,b,c){function e(a){this.keymapping=this.$buildKeymappingRegex(a)}var d=!1;e.prototype={$buildKeymappingRegex:function(a){for(state in a)this.$buildBindingsRegex(a[state]);return a},$buildBindingsRegex:function(a){a.forEach(function(a){a.key?a.key=new RegExp("^"+a.key+"$"):Array.isArray(a.regex)?(a.key=new RegExp("^"+a.regex[1]+"$"),a.regex=new RegExp(a.regex.join("")+"$")):a.regex&&(a.regex=new RegExp(a.regex+"$"))})},$composeBuffer:function(a,b,c){if(a.state==null||a.buffer==null)a.state="start",a.buffer="";var d=[];b&1&&d.push("ctrl"),b&8&&d.push("command"),b&2&&d.push("option"),b&4&&d.push("shift"),c&&d.push(c);var e=d.join("-"),f=a.buffer+e;return b!=2&&(a.buffer=f),{bufferToUse:f,symbolicName:e}},$find:function(a,b,c,e,f){var g={};return this.keymapping[a.state].some(function(h){var i;if(h.key&&!h.key.test(c))return!1;if(h.regex&&!(i=h.regex.exec(b)))return!1;if(h.match&&!h.match(b,e,f,c))return!1;if(h.disallowMatches)for(var j=0;j"},{token:"keyword",regex:"(?:#include|#pragma|#line|#define|#undef|#ifdef|#else|#elif|#endif|#ifndef)"},{token:function(c){return c=="this"?"variable.language":a.hasOwnProperty(c)?"keyword":b.hasOwnProperty(c)?"constant.language":"identifier"},regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|==|=|!=|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|new|delete|typeof|void)"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",merge:!0,regex:".+"}],qqstring:[{token:"string",regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"',next:"start"},{token:"string",merge:!0,regex:".+"}],qstring:[{token:"string",regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'",next:"start"},{token:"string",merge:!0,regex:".+"}]},this.embedRules(f,"doc-",[(new f).getEndRule("start")])};d.inherits(h,g),b.c_cppHighlightRules=h}),define("ace/mode/doc_comment_highlight_rules",["require","exports","module","pilot/oop","ace/mode/text_highlight_rules"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text_highlight_rules").TextHighlightRules,f=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc",merge:!0,regex:"\\s+"},{token:"comment.doc",merge:!0,regex:"TODO"},{token:"comment.doc",merge:!0,regex:"[^@\\*]+"},{token:"comment.doc",merge:!0,regex:"."}]}};d.inherits(f,e),function(){this.getStartRule=function(a){return{token:"comment.doc",merge:!0,regex:"\\/\\*(?=\\*)",next:a}},this.getEndRule=function(a){return{token:"comment.doc",merge:!0,regex:"\\*\\/",next:a}}}.call(f.prototype),b.DocCommentHighlightRules=f}),define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(a,b,c){var d=a("ace/range").Range,e=function(){};(function(){this.checkOutdent=function(a,b){return/^\s+$/.test(a)?/^\s*\}/.test(b):!1},this.autoOutdent=function(a,b){var c=a.getLine(b),e=c.match(/^(\s*\})/);if(!e)return 0;var f=e[1].length,g=a.findMatchingBracket({row:b,column:f});if(!g||g.row==b)return 0;var h=this.$getIndent(a.getLine(g.row));a.replace(new d(b,0,b,f-1),h)},this.$getIndent=function(a){var b=a.match(/^(\s+)/);return b?b[1]:""}}).call(e.prototype),b.MatchingBraceOutdent=e}),define("ace/mode/behaviour/cstyle",["require","exports","module","pilot/oop","ace/mode/behaviour"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/behaviour").Behaviour,f=function(){this.add("braces","insertion",function(a,b,c,d,e){if(e=="{"){var f=c.getSelectionRange(),g=d.doc.getTextRange(f);return g!==""?{text:"{"+g+"}",selection:!1}:{text:"{}",selection:[1,1]}}if(e=="}"){var h=c.getCursorPosition(),i=d.doc.getLine(h.row),j=i.substring(h.column,h.column+1);if(j=="}"){var k=d.$findOpeningBracket("}",{column:h.column+1,row:h.row});if(k!==null)return{text:"",selection:[1,1]}}}else if(e=="\n"){var h=c.getCursorPosition(),i=d.doc.getLine(h.row),j=i.substring(h.column,h.column+1);if(j=="}"){var l=d.findMatchingBracket({row:h.row,column:h.column+1});if(!l)return!1;var m=this.getNextLineIndent(a,i.substring(0,i.length-1),d.getTabString()),n=this.$getIndent(d.doc.getLine(l.row));return{text:"\n"+m+"\n"+n,selection:[1,m.length,1,m.length]}}}return!1}),this.add("braces","deletion",function(a,b,c,d,e){var f=d.doc.getTextRange(e);if(!e.isMultiLine()&&f=="{"){var g=d.doc.getLine(e.start.row),h=g.substring(e.end.column,e.end.column+1);if(h=="}")return e.end.column++,e}return!1}),this.add("parens","insertion",function(a,b,c,d,e){if(e=="("){var f=c.getSelectionRange(),g=d.doc.getTextRange(f);return g!==""?{text:"("+g+")",selection:!1}:{text:"()",selection:[1,1]}}if(e==")"){var h=c.getCursorPosition(),i=d.doc.getLine(h.row),j=i.substring(h.column,h.column+1);if(j==")"){var k=d.$findOpeningBracket(")",{column:h.column+1,row:h.row});if(k!==null)return{text:"",selection:[1,1]}}}return!1}),this.add("parens","deletion",function(a,b,c,d,e){var f=d.doc.getTextRange(e);if(!e.isMultiLine()&&f=="("){var g=d.doc.getLine(e.start.row),h=g.substring(e.start.column+1,e.start.column+2);if(h==")")return e.end.column++,e}return!1}),this.add("string_dquotes","insertion",function(a,b,c,d,e){if(e=='"'){var f=c.getSelectionRange(),g=d.doc.getTextRange(f);if(g!=="")return{text:'"'+g+'"',selection:!1};var h=c.getCursorPosition(),i=d.doc.getLine(h.row),j=i.substring(h.column-1,h.column);if(j=="\\")return!1;var k=d.getTokens(f.start.row,f.start.row)[0].tokens,l=0,m,n=-1;for(var o=0;of.start.column)break;l+=k[o].value.length}if(!m||n<0&&m.type!=="comment"&&(m.type!=="string"||f.start.column!==m.value.length+l-1&&m.value.lastIndexOf('"')===m.value.length-1))return{text:'""',selection:[1,1]};if(m&&m.type==="string"){var p=i.substring(h.column,h.column+1);if(p=='"')return{text:"",selection:[1,1]}}}return!1}),this.add("string_dquotes","deletion",function(a,b,c,d,e){var f=d.doc.getTextRange(e);if(!e.isMultiLine()&&f=='"'){var g=d.doc.getLine(e.start.row),h=g.substring(e.start.column+1,e.start.column+2);if(h=='"')return e.end.column++,e}return!1})};d.inherits(f,e),b.CstyleBehaviour=f}) -------------------------------------------------------------------------------- /test_project/static/ace/mode-clojure.js: -------------------------------------------------------------------------------- 1 | define("ace/mode/clojure",["require","exports","module","pilot/oop","ace/mode/text","ace/tokenizer","ace/mode/clojure_highlight_rules","ace/mode/matching_parens_outdent","ace/range"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text").Mode,f=a("ace/tokenizer").Tokenizer,g=a("ace/mode/clojure_highlight_rules").ClojureHighlightRules,h=a("ace/mode/matching_parens_outdent").MatchingParensOutdent,i=a("ace/range").Range,j=function(){this.$tokenizer=new f((new g).getRules()),this.$outdent=new h};d.inherits(j,e),function(){this.toggleCommentLines=function(a,b,c,d){var e=!0,f=[],g=/^(\s*)#/;for(var h=c;h<=d;h++)if(!g.test(b.getLine(h))){e=!1;break}if(e){var j=new i(0,0,0,0);for(var h=c;h<=d;h++){var k=b.getLine(h),l=k.match(g);j.start.row=h,j.end.row=h,j.end.column=l[0].length,b.replace(j,l[1])}}else b.indentRows(c,d,";")},this.getNextLineIndent=function(a,b,c){var d=this.$getIndent(b),e=d,f=this.$tokenizer.getLineTokens(b,a),g=f.tokens,h=f.state;if(g.length&&g[g.length-1].type=="comment")return d;if(a=="start"){var i=b.match(/[\(\[]/);i&&(d+=" "),i=b.match(/[\)]/),i&&(d="")}return d},this.checkOutdent=function(a,b,c){return this.$outdent.checkOutdent(b,c)},this.autoOutdent=function(a,b,c){this.$outdent.autoOutdent(b,c)}}.call(j.prototype),b.Mode=j}),define("ace/mode/clojure_highlight_rules",["require","exports","module","pilot/oop","pilot/lang","ace/mode/text_highlight_rules"],function(a,b,c){var d=a("pilot/oop"),e=a("pilot/lang"),f=a("ace/mode/text_highlight_rules").TextHighlightRules,g=function(){var a=e.arrayToMap("* *1 *2 *3 *agent* *allow-unresolved-vars* *assert* *clojure-version* *command-line-args* *compile-files* *compile-path* *e *err* *file* *flush-on-newline* *in* *macro-meta* *math-context* *ns* *out* *print-dup* *print-length* *print-level* *print-meta* *print-readably* *read-eval* *source-path* *use-context-classloader* *warn-on-reflection* + - -> -> ->> ->> .. / < < <= <= = == > > >= >= accessor aclone add-classpath add-watch agent agent-errors aget alength alias all-ns alter alter-meta! alter-var-root amap ancestors and apply areduce array-map aset aset-boolean aset-byte aset-char aset-double aset-float aset-int aset-long aset-short assert assoc assoc! assoc-in associative? atom await await-for await1 bases bean bigdec bigint binding bit-and bit-and-not bit-clear bit-flip bit-not bit-or bit-set bit-shift-left bit-shift-right bit-test bit-xor boolean boolean-array booleans bound-fn bound-fn* butlast byte byte-array bytes cast char char-array char-escape-string char-name-string char? chars chunk chunk-append chunk-buffer chunk-cons chunk-first chunk-next chunk-rest chunked-seq? class class? clear-agent-errors clojure-version coll? comment commute comp comparator compare compare-and-set! compile complement concat cond condp conj conj! cons constantly construct-proxy contains? count counted? create-ns create-struct cycle dec decimal? declare definline defmacro defmethod defmulti defn defn- defonce defstruct delay delay? deliver deref derive descendants destructure disj disj! dissoc dissoc! distinct distinct? doall doc dorun doseq dosync dotimes doto double double-array doubles drop drop-last drop-while empty empty? ensure enumeration-seq eval even? every? false? ffirst file-seq filter find find-doc find-ns find-var first float float-array float? floats flush fn fn? fnext for force format future future-call future-cancel future-cancelled? future-done? future? gen-class gen-interface gensym get get-in get-method get-proxy-class get-thread-bindings get-validator hash hash-map hash-set identical? identity if-let if-not ifn? import in-ns inc init-proxy instance? int int-array integer? interleave intern interpose into into-array ints io! isa? iterate iterator-seq juxt key keys keyword keyword? last lazy-cat lazy-seq let letfn line-seq list list* list? load load-file load-reader load-string loaded-libs locking long long-array longs loop macroexpand macroexpand-1 make-array make-hierarchy map map? mapcat max max-key memfn memoize merge merge-with meta method-sig methods min min-key mod name namespace neg? newline next nfirst nil? nnext not not-any? not-empty not-every? not= ns ns-aliases ns-imports ns-interns ns-map ns-name ns-publics ns-refers ns-resolve ns-unalias ns-unmap nth nthnext num number? odd? or parents partial partition pcalls peek persistent! pmap pop pop! pop-thread-bindings pos? pr pr-str prefer-method prefers primitives-classnames print print-ctor print-doc print-dup print-method print-namespace-doc print-simple print-special-doc print-str printf println println-str prn prn-str promise proxy proxy-call-with-super proxy-mappings proxy-name proxy-super push-thread-bindings pvalues quot rand rand-int range ratio? rational? rationalize re-find re-groups re-matcher re-matches re-pattern re-seq read read-line read-string reduce ref ref-history-count ref-max-history ref-min-history ref-set refer refer-clojure release-pending-sends rem remove remove-method remove-ns remove-watch repeat repeatedly replace replicate require reset! reset-meta! resolve rest resultset-seq reverse reversible? rseq rsubseq second select-keys send send-off seq seq? seque sequence sequential? set set-validator! set? short short-array shorts shutdown-agents slurp some sort sort-by sorted-map sorted-map-by sorted-set sorted-set-by sorted? special-form-anchor special-symbol? split-at split-with str stream? string? struct struct-map subs subseq subvec supers swap! symbol symbol? sync syntax-symbol-anchor take take-last take-nth take-while test the-ns time to-array to-array-2d trampoline transient tree-seq true? type unchecked-add unchecked-dec unchecked-divide unchecked-inc unchecked-multiply unchecked-negate unchecked-remainder unchecked-subtract underive unquote unquote-splicing update-in update-proxy use val vals var-get var-set var? vary-meta vec vector vector? when when-first when-let when-not while with-bindings with-bindings* with-in-str with-loading-context with-local-vars with-meta with-open with-out-str with-precision xml-seq zero? zipmap ".split(" ")),b=e.arrayToMap("def do fn if let loop monitor-enter monitor-exit new quote recur set! throw try var".split(" ")),c=e.arrayToMap("true false nil".split(" "));this.$rules={start:[{token:"comment",regex:";.*$"},{token:"comment",regex:"^=begin$",next:"comment"},{token:"keyword",regex:"[\\(|\\)]"},{token:"keyword",regex:"[\\'\\(]"},{token:"keyword",regex:"[\\[|\\]]"},{token:"keyword",regex:"[\\{|\\}|\\#\\{|\\#\\}]"},{token:"keyword",regex:"[\\&]"},{token:"keyword",regex:"[\\#\\^\\{]"},{token:"keyword",regex:"[\\%]"},{token:"keyword",regex:"[@]"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"constant.language",regex:"[!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+||=|!=|<=|>=|<>|<|>|!|&&]"},{token:function(d){return b.hasOwnProperty(d)?"keyword":c.hasOwnProperty(d)?"constant.language":a.hasOwnProperty(d)?"support.function":"identifier"},regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"[:](?:[a-zA-Z]|d)+"},{token:"string.regexp",regex:'/#"(?:.|(\\")|[^""\n])*"/g'}],comment:[{token:"comment",regex:"^=end$",next:"start"},{token:"comment",merge:!0,regex:".+"}]}};d.inherits(g,f),b.ClojureHighlightRules=g}),define("ace/mode/matching_parens_outdent",["require","exports","module","ace/range"],function(a,b,c){var d=a("ace/range").Range,e=function(){};(function(){this.checkOutdent=function(a,b){return/^\s+$/.test(a)?/^\s*\)/.test(b):!1},this.autoOutdent=function(a,b){var c=a.getLine(b),e=c.match(/^(\s*\))/);if(!e)return 0;var f=e[1].length,g=a.findMatchingBracket({row:b,column:f});if(!g||g.row==b)return 0;var h=this.$getIndent(a.getLine(g.row));a.replace(new d(b,0,b,f-1),h)},this.$getIndent=function(a){var b=a.match(/^(\s+)/);return b?b[1]:""}}).call(e.prototype),b.MatchingParensOutdent=e}) -------------------------------------------------------------------------------- /test_project/static/ace/mode-coffee.js: -------------------------------------------------------------------------------- 1 | define("ace/mode/coffee",["require","exports","module","ace/tokenizer","ace/mode/coffee_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/mode/text","ace/worker/worker_client","pilot/oop"],function(a,b,c){function k(){this.$tokenizer=new d((new e).getRules()),this.$outdent=new f}var d=a("ace/tokenizer").Tokenizer,e=a("ace/mode/coffee_highlight_rules").CoffeeHighlightRules,f=a("ace/mode/matching_brace_outdent").MatchingBraceOutdent,g=a("ace/range").Range,h=a("ace/mode/text").Mode,i=a("ace/worker/worker_client").WorkerClient,j=a("pilot/oop");j.inherits(k,h),function(){var a=/(?:[({[=:]|[-=]>|\b(?:else|switch|try|catch(?:\s*[$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*)?|finally))\s*$/,b=/^(\s*)#/,c=/^\s*###(?!#)/,d=/^\s*/;this.getNextLineIndent=function(b,c,d){var e=this.$getIndent(c),f=this.$tokenizer.getLineTokens(c,b).tokens;return(!f.length||f[f.length-1].type!=="comment")&&b==="start"&&a.test(c)&&(e+=d),e},this.toggleCommentLines=function(a,e,f,h){console.log("toggle");var i=new g(0,0,0,0);for(var j=f;j<=h;++j){var k=e.getLine(j);if(c.test(k))continue;b.test(k)?k=k.replace(b,"$1"):k=k.replace(d,"$&#"),i.end.row=i.start.row=j,i.end.column=k.length+1,e.replace(i,k)}},this.checkOutdent=function(a,b,c){return this.$outdent.checkOutdent(b,c)},this.autoOutdent=function(a,b,c){this.$outdent.autoOutdent(b,c)},this.createWorker=function(a){var b=a.getDocument(),c=new i(["ace","pilot"],"worker-coffee.js","ace/mode/coffee_worker","Worker");c.call("setValue",[b.getValue()]),b.on("change",function(a){a.range={start:a.data.range.start,end:a.data.range.end},c.emit("change",a)}),c.on("error",function(b){a.setAnnotations([b.data])}),c.on("ok",function(b){a.clearAnnotations()})}}.call(k.prototype),b.Mode=k}),define("ace/mode/coffee_highlight_rules",["require","exports","module","pilot/oop","ace/mode/text_highlight_rules"],function(a,b,c){function d(){var a="[$A-Za-z_\\x7f-\\uffff][$\\w\\x7f-\\uffff]*",b="(?![$\\w]|\\s*:)",c={token:"string",merge:!0,regex:".+"};this.$rules={start:[{token:"identifier",regex:"(?:@|(?:\\.|::)\\s*)"+a},{token:"keyword",regex:"(?:t(?:h(?:is|row|en)|ry|ypeof)|s(?:uper|witch)|return|b(?:reak|y)|c(?:ontinue|atch|lass)|i(?:n(?:stanceof)?|s(?:nt)?|f)|e(?:lse|xtends)|f(?:or (?:own)?|inally|unction)|wh(?:ile|en)|n(?:ew|ot?)|d(?:e(?:lete|bugger)|o)|loop|o(?:ff?|[rn])|un(?:less|til)|and|yes)"+b},{token:"constant.language",regex:"(?:true|false|null|undefined)"+b},{token:"invalid.illegal",regex:"(?:c(?:ase|onst)|default|function|v(?:ar|oid)|with|e(?:num|xport)|i(?:mplements|nterface)|let|p(?:ackage|r(?:ivate|otected)|ublic)|static|yield|__(?:hasProp|extends|slice|bind|indexOf))"+b},{token:"language.support.class",regex:"(?:Array|Boolean|Date|Function|Number|Object|R(?:e(?:gExp|ferenceError)|angeError)|S(?:tring|yntaxError)|E(?:rror|valError)|TypeError|URIError)"+b},{token:"language.support.function",regex:"(?:Math|JSON|is(?:NaN|Finite)|parse(?:Int|Float)|encodeURI(?:Component)?|decodeURI(?:Component)?)"+b},{token:"identifier",regex:a},{token:"constant.numeric",regex:"(?:0x[\\da-fA-F]+|(?:\\d+(?:\\.\\d+)?|\\.\\d+)(?:[eE][+-]?\\d+)?)"},{token:"string",merge:!0,regex:"'''",next:"qdoc"},{token:"string",merge:!0,regex:'"""',next:"qqdoc"},{token:"string",merge:!0,regex:"'",next:"qstring"},{token:"string",merge:!0,regex:'"',next:"qqstring"},{token:"string",merge:!0,regex:"`",next:"js"},{token:"string.regex",merge:!0,regex:"///",next:"heregex"},{token:"string.regex",regex:"/(?!\\s)[^[/\\n\\\\]*(?: (?:\\\\.|\\[[^\\]\\n\\\\]*(?:\\\\.[^\\]\\n\\\\]*)*\\])[^[/\\n\\\\]*)*/[imgy]{0,4}(?!\\w)"},{token:"comment",merge:!0,regex:"###(?!#)",next:"comment"},{token:"comment",regex:"#.*"},{token:"lparen",regex:"[({[]"},{token:"rparen",regex:"[\\]})]"},{token:"keyword.operator",regex:"\\S+"},{token:"text",regex:"\\s+"}],qdoc:[{token:"string",regex:".*?'''",next:"start"},c],qqdoc:[{token:"string",regex:'.*?"""',next:"start"},c],qstring:[{token:"string",regex:"[^\\\\']*(?:\\\\.[^\\\\']*)*'",next:"start"},c],qqstring:[{token:"string",regex:'[^\\\\"]*(?:\\\\.[^\\\\"]*)*"',next:"start"},c],js:[{token:"string",merge:!0,regex:"[^\\\\`]*(?:\\\\.[^\\\\`]*)*`",next:"start"},c],heregex:[{token:"string.regex",regex:".*?///[imgy]{0,4}",next:"start"},{token:"comment.regex",regex:"\\s+(?:#.*)?"},{token:"string.regex",merge:!0,regex:"\\S+"}],comment:[{token:"comment",regex:".*?###",next:"start"},{token:"comment",merge:!0,regex:".+"}]}}a("pilot/oop").inherits(d,a("ace/mode/text_highlight_rules").TextHighlightRules),b.CoffeeHighlightRules=d}),define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(a,b,c){var d=a("ace/range").Range,e=function(){};(function(){this.checkOutdent=function(a,b){return/^\s+$/.test(a)?/^\s*\}/.test(b):!1},this.autoOutdent=function(a,b){var c=a.getLine(b),e=c.match(/^(\s*\})/);if(!e)return 0;var f=e[1].length,g=a.findMatchingBracket({row:b,column:f});if(!g||g.row==b)return 0;var h=this.$getIndent(a.getLine(g.row));a.replace(new d(b,0,b,f-1),h)},this.$getIndent=function(a){var b=a.match(/^(\s+)/);return b?b[1]:""}}).call(e.prototype),b.MatchingBraceOutdent=e}),define("ace/worker/worker_client",["require","exports","module","pilot/oop","pilot/event_emitter"],function(a,b,c){var d=a("pilot/oop"),e=a("pilot/event_emitter").EventEmitter,f=function(b,c,d,e){this.callbacks=[];if(a.packaged)var f=this.$guessBasePath(),g=this.$worker=new Worker(f+c);else{var h=this.$normalizePath(a.nameToUrl("ace/worker/worker",null,"_")),g=this.$worker=new Worker(h),i={};for(var j=0;j=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",merge:!0,regex:".+"}]},this.embedRules(f,"doc-",[(new f).getEndRule("start")])};d.inherits(h,g),b.CSharpHighlightRules=h}),define("ace/mode/doc_comment_highlight_rules",["require","exports","module","pilot/oop","ace/mode/text_highlight_rules"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text_highlight_rules").TextHighlightRules,f=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc",merge:!0,regex:"\\s+"},{token:"comment.doc",merge:!0,regex:"TODO"},{token:"comment.doc",merge:!0,regex:"[^@\\*]+"},{token:"comment.doc",merge:!0,regex:"."}]}};d.inherits(f,e),function(){this.getStartRule=function(a){return{token:"comment.doc",merge:!0,regex:"\\/\\*(?=\\*)",next:a}},this.getEndRule=function(a){return{token:"comment.doc",merge:!0,regex:"\\*\\/",next:a}}}.call(f.prototype),b.DocCommentHighlightRules=f}),define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(a,b,c){var d=a("ace/range").Range,e=function(){};(function(){this.checkOutdent=function(a,b){return/^\s+$/.test(a)?/^\s*\}/.test(b):!1},this.autoOutdent=function(a,b){var c=a.getLine(b),e=c.match(/^(\s*\})/);if(!e)return 0;var f=e[1].length,g=a.findMatchingBracket({row:b,column:f});if(!g||g.row==b)return 0;var h=this.$getIndent(a.getLine(g.row));a.replace(new d(b,0,b,f-1),h)},this.$getIndent=function(a){var b=a.match(/^(\s+)/);return b?b[1]:""}}).call(e.prototype),b.MatchingBraceOutdent=e}),define("ace/mode/behaviour/cstyle",["require","exports","module","pilot/oop","ace/mode/behaviour"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/behaviour").Behaviour,f=function(){this.add("braces","insertion",function(a,b,c,d,e){if(e=="{"){var f=c.getSelectionRange(),g=d.doc.getTextRange(f);return g!==""?{text:"{"+g+"}",selection:!1}:{text:"{}",selection:[1,1]}}if(e=="}"){var h=c.getCursorPosition(),i=d.doc.getLine(h.row),j=i.substring(h.column,h.column+1);if(j=="}"){var k=d.$findOpeningBracket("}",{column:h.column+1,row:h.row});if(k!==null)return{text:"",selection:[1,1]}}}else if(e=="\n"){var h=c.getCursorPosition(),i=d.doc.getLine(h.row),j=i.substring(h.column,h.column+1);if(j=="}"){var l=d.findMatchingBracket({row:h.row,column:h.column+1});if(!l)return!1;var m=this.getNextLineIndent(a,i.substring(0,i.length-1),d.getTabString()),n=this.$getIndent(d.doc.getLine(l.row));return{text:"\n"+m+"\n"+n,selection:[1,m.length,1,m.length]}}}return!1}),this.add("braces","deletion",function(a,b,c,d,e){var f=d.doc.getTextRange(e);if(!e.isMultiLine()&&f=="{"){var g=d.doc.getLine(e.start.row),h=g.substring(e.end.column,e.end.column+1);if(h=="}")return e.end.column++,e}return!1}),this.add("parens","insertion",function(a,b,c,d,e){if(e=="("){var f=c.getSelectionRange(),g=d.doc.getTextRange(f);return g!==""?{text:"("+g+")",selection:!1}:{text:"()",selection:[1,1]}}if(e==")"){var h=c.getCursorPosition(),i=d.doc.getLine(h.row),j=i.substring(h.column,h.column+1);if(j==")"){var k=d.$findOpeningBracket(")",{column:h.column+1,row:h.row});if(k!==null)return{text:"",selection:[1,1]}}}return!1}),this.add("parens","deletion",function(a,b,c,d,e){var f=d.doc.getTextRange(e);if(!e.isMultiLine()&&f=="("){var g=d.doc.getLine(e.start.row),h=g.substring(e.start.column+1,e.start.column+2);if(h==")")return e.end.column++,e}return!1}),this.add("string_dquotes","insertion",function(a,b,c,d,e){if(e=='"'){var f=c.getSelectionRange(),g=d.doc.getTextRange(f);if(g!=="")return{text:'"'+g+'"',selection:!1};var h=c.getCursorPosition(),i=d.doc.getLine(h.row),j=i.substring(h.column-1,h.column);if(j=="\\")return!1;var k=d.getTokens(f.start.row,f.start.row)[0].tokens,l=0,m,n=-1;for(var o=0;of.start.column)break;l+=k[o].value.length}if(!m||n<0&&m.type!=="comment"&&(m.type!=="string"||f.start.column!==m.value.length+l-1&&m.value.lastIndexOf('"')===m.value.length-1))return{text:'""',selection:[1,1]};if(m&&m.type==="string"){var p=i.substring(h.column,h.column+1);if(p=='"')return{text:"",selection:[1,1]}}}return!1}),this.add("string_dquotes","deletion",function(a,b,c,d,e){var f=d.doc.getTextRange(e);if(!e.isMultiLine()&&f=='"'){var g=d.doc.getLine(e.start.row),h=g.substring(e.start.column+1,e.start.column+2);if(h=='"')return e.end.column++,e}return!1})};d.inherits(f,e),b.CstyleBehaviour=f}) -------------------------------------------------------------------------------- /test_project/static/ace/mode-css.js: -------------------------------------------------------------------------------- 1 | define("ace/mode/css",["require","exports","module","pilot/oop","ace/mode/text","ace/tokenizer","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text").Mode,f=a("ace/tokenizer").Tokenizer,g=a("ace/mode/css_highlight_rules").CssHighlightRules,h=a("ace/mode/matching_brace_outdent").MatchingBraceOutdent,i=a("ace/worker/worker_client").WorkerClient,j=function(){this.$tokenizer=new f((new g).getRules()),this.$outdent=new h};d.inherits(j,e),function(){this.getNextLineIndent=function(a,b,c){var d=this.$getIndent(b),e=this.$tokenizer.getLineTokens(b,a).tokens;if(e.length&&e[e.length-1].type=="comment")return d;var f=b.match(/^.*\{\s*$/);return f&&(d+=c),d},this.checkOutdent=function(a,b,c){return this.$outdent.checkOutdent(b,c)},this.autoOutdent=function(a,b,c){this.$outdent.autoOutdent(b,c)},this.createWorker=function(a){var b=a.getDocument(),c=new i(["ace","pilot"],"worker-css.js","ace/mode/css_worker","Worker");c.call("setValue",[b.getValue()]),b.on("change",function(a){a.range={start:a.data.range.start,end:a.data.range.end},c.emit("change",a)}),c.on("csslint",function(b){var c=[];b.data.forEach(function(a){c.push({row:a.line-1,column:a.col-1,text:a.message,type:a.type,lint:a})}),a.setAnnotations(c)})}}.call(j.prototype),b.Mode=j}),define("ace/mode/css_highlight_rules",["require","exports","module","pilot/oop","pilot/lang","ace/mode/text_highlight_rules"],function(a,b,c){var d=a("pilot/oop"),e=a("pilot/lang"),f=a("ace/mode/text_highlight_rules").TextHighlightRules,g=function(){function g(a){var b=[],c=a.split("");for(var d=0;df.start.column)break;l+=k[o].value.length}if(!m||n<0&&m.type!=="comment"&&(m.type!=="string"||f.start.column!==m.value.length+l-1&&m.value.lastIndexOf('"')===m.value.length-1))return{text:'""',selection:[1,1]};if(m&&m.type==="string"){var p=i.substring(h.column,h.column+1);if(p=='"')return{text:"",selection:[1,1]}}}return!1}),this.add("string_dquotes","deletion",function(a,b,c,d,e){var f=d.doc.getTextRange(e);if(!e.isMultiLine()&&f=='"'){var g=d.doc.getLine(e.start.row),h=g.substring(e.start.column+1,e.start.column+2);if(h=='"')return e.end.column++,e}return!1})};d.inherits(f,e),b.CstyleBehaviour=f}) -------------------------------------------------------------------------------- /test_project/static/ace/mode-lua.js: -------------------------------------------------------------------------------- 1 | define("ace/mode/lua",["require","exports","module","pilot/oop","ace/mode/text","ace/tokenizer","ace/mode/lua_highlight_rules","ace/range"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text").Mode,f=a("ace/tokenizer").Tokenizer,g=a("ace/mode/lua_highlight_rules").LuaHighlightRules,h=a("ace/range").Range,i=function(){this.$tokenizer=new f((new g).getRules())};d.inherits(i,e),function(){this.getNextLineIndent=function(a,b,c){var d=this.$getIndent(b),e=this.$tokenizer.getLineTokens(b,a),f=e.tokens,g=e.state,h=["function","then","do","repeat"];if(a=="start"){var i=b.match(/^.*[\{\(\[]\s*$/);if(i)d+=c;else for(var j in f){var k=f[j];if(k.type!="keyword")continue;var l=h.indexOf(k.value);if(l!=-1){d+=c;break}}}return d}}.call(i.prototype),b.Mode=i}),define("ace/mode/lua_highlight_rules",["require","exports","module","pilot/oop","pilot/lang","ace/mode/text_highlight_rules"],function(a,b,c){var d=a("pilot/oop"),e=a("pilot/lang"),f=a("ace/mode/text_highlight_rules").TextHighlightRules,g=function(){var a=e.arrayToMap("break|do|else|elseif|end|for|function|if|in|local|repeat|return|then|until|while|or|and|not".split("|")),b=e.arrayToMap("true|false|nil|_G|_VERSION".split("|")),c=e.arrayToMap("string|xpcall|package|tostring|print|os|unpack|require|getfenv|setmetatable|next|assert|tonumber|io|rawequal|collectgarbage|getmetatable|module|rawset|math|debug|pcall|table|newproxy|type|coroutine|_G|select|gcinfo|pairs|rawget|loadstring|ipairs|_VERSION|dofile|setfenv|load|error|loadfile|sub|upper|len|gfind|rep|find|match|char|dump|gmatch|reverse|byte|format|gsub|lower|preload|loadlib|loaded|loaders|cpath|config|path|seeall|exit|setlocale|date|getenv|difftime|remove|time|clock|tmpname|rename|execute|lines|write|close|flush|open|output|type|read|stderr|stdin|input|stdout|popen|tmpfile|log|max|acos|huge|ldexp|pi|cos|tanh|pow|deg|tan|cosh|sinh|random|randomseed|frexp|ceil|floor|rad|abs|sqrt|modf|asin|min|mod|fmod|log10|atan2|exp|sin|atan|getupvalue|debug|sethook|getmetatable|gethook|setmetatable|setlocal|traceback|setfenv|getinfo|setupvalue|getlocal|getregistry|getfenv|setn|insert|getn|foreachi|maxn|foreach|concat|sort|remove|resume|yield|status|wrap|create|running".split("|")),d=e.arrayToMap("string|package|os|io|math|debug|table|coroutine".split("|")),f=e.arrayToMap("__add|__sub|__mod|__unm|__concat|__lt|__index|__call|__gc|__metatable|__mul|__div|__pow|__len|__eq|__le|__newindex|__tostring|__mode|__tonumber".split("|")),g=e.arrayToMap("".split("|")),h=e.arrayToMap("setn|foreach|foreachi|gcinfo|log10|maxn".split("|")),i="",j="(?:(?:[1-9]\\d*)|(?:0))",k="(?:0[xX][\\dA-Fa-f]+)",l="(?:"+j+"|"+k+")",m="(?:\\.\\d+)",n="(?:\\d+)",o="(?:(?:"+n+"?"+m+")|(?:"+n+"\\.))",p="(?:"+o+")",q=[];this.$rules={start:[{token:"comment",regex:i+"\\-\\-\\[\\[.*\\]\\]"},{token:"comment",regex:i+"\\-\\-\\[\\=\\[.*\\]\\=\\]"},{token:"comment",regex:i+"\\-\\-\\[\\={2}\\[.*\\]\\={2}\\]"},{token:"comment",regex:i+"\\-\\-\\[\\={3}\\[.*\\]\\={3}\\]"},{token:"comment",regex:i+"\\-\\-\\[\\={4}\\[.*\\]\\={4}\\]"},{token:"comment",regex:i+"\\-\\-\\[\\={5}\\=*\\[.*\\]\\={5}\\=*\\]"},{token:"comment",regex:i+"\\-\\-\\[\\[.*$",merge:!0,next:"qcomment"},{token:"comment",regex:i+"\\-\\-\\[\\=\\[.*$",merge:!0,next:"qcomment1"},{token:"comment",regex:i+"\\-\\-\\[\\={2}\\[.*$",merge:!0,next:"qcomment2"},{token:"comment",regex:i+"\\-\\-\\[\\={3}\\[.*$",merge:!0,next:"qcomment3"},{token:"comment",regex:i+"\\-\\-\\[\\={4}\\[.*$",merge:!0,next:"qcomment4"},{token:function(a){var b=/\-\-\[(\=+)\[/,c;return(c=b.exec(a))!=null&&(c=c[1])!=undefined&&q.push(c.length),"comment"},regex:i+"\\-\\-\\[\\={5}\\=*\\[.*$",merge:!0,next:"qcomment5"},{token:"comment",regex:"\\-\\-.*$"},{token:"string",regex:i+"\\[\\[.*\\]\\]"},{token:"string",regex:i+"\\[\\=\\[.*\\]\\=\\]"},{token:"string",regex:i+"\\[\\={2}\\[.*\\]\\={2}\\]"},{token:"string",regex:i+"\\[\\={3}\\[.*\\]\\={3}\\]"},{token:"string",regex:i+"\\[\\={4}\\[.*\\]\\={4}\\]"},{token:"string",regex:i+"\\[\\={5}\\=*\\[.*\\]\\={5}\\=*\\]"},{token:"string",regex:i+"\\[\\[.*$",merge:!0,next:"qstring"},{token:"string",regex:i+"\\[\\=\\[.*$",merge:!0,next:"qstring1"},{token:"string",regex:i+"\\[\\={2}\\[.*$",merge:!0,next:"qstring2"},{token:"string",regex:i+"\\[\\={3}\\[.*$",merge:!0,next:"qstring3"},{token:"string",regex:i+"\\[\\={4}\\[.*$",merge:!0,next:"qstring4"},{token:function(a){var b=/\[(\=+)\[/,c;return(c=b.exec(a))!=null&&(c=c[1])!=undefined&&q.push(c.length),"string"},regex:i+"\\[\\={5}\\=*\\[.*$",merge:!0,next:"qstring5"},{token:"string",regex:i+'"(?:[^\\\\]|\\\\.)*?"'},{token:"string",regex:i+"'(?:[^\\\\]|\\\\.)*?'"},{token:"constant.numeric",regex:p},{token:"constant.numeric",regex:l+"\\b"},{token:function(e){return a.hasOwnProperty(e)?"keyword":b.hasOwnProperty(e)?"constant.language":g.hasOwnProperty(e)?"invalid.illegal":d.hasOwnProperty(e)?"constant.library":h.hasOwnProperty(e)?"invalid.deprecated":c.hasOwnProperty(e)?"support.function":f.hasOwnProperty(e)?"support.function":"identifier"},regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\+|\\-|\\*|\\/|%|\\#|\\^|~|<|>|<=|=>|==|~=|=|\\:|\\.\\.\\.|\\.\\."},{token:"lparen",regex:"[\\[\\(\\{]"},{token:"rparen",regex:"[\\]\\)\\}]"},{token:"text",regex:"\\s+"}],qcomment:[{token:"comment",regex:"(?:[^\\\\]|\\\\.)*?\\]\\]",next:"start"},{token:"comment",merge:!0,regex:".+"}],qcomment1:[{token:"comment",regex:"(?:[^\\\\]|\\\\.)*?\\]\\=\\]",next:"start"},{token:"comment",merge:!0,regex:".+"}],qcomment2:[{token:"comment",regex:"(?:[^\\\\]|\\\\.)*?\\]\\={2}\\]",next:"start"},{token:"comment",merge:!0,regex:".+"}],qcomment3:[{token:"comment",regex:"(?:[^\\\\]|\\\\.)*?\\]\\={3}\\]",next:"start"},{token:"comment",merge:!0,regex:".+"}],qcomment4:[{token:"comment",regex:"(?:[^\\\\]|\\\\.)*?\\]\\={4}\\]",next:"start"},{token:"comment",merge:!0,regex:".+"}],qcomment5:[{token:function(a){var b=/\](\=+)\]/,c=this.rules.qcomment5[0],d;c.next="start";if((d=b.exec(a))!=null&&(d=d[1])!=undefined){var e=d.length,f;(f=q.pop())!=e&&(q.push(f),c.next="qcomment5")}return"comment"},regex:"(?:[^\\\\]|\\\\.)*?\\]\\={5}\\=*\\]",next:"start"},{token:"comment",merge:!0,regex:".+"}],qstring:[{token:"string",regex:"(?:[^\\\\]|\\\\.)*?\\]\\]",next:"start"},{token:"string",merge:!0,regex:".+"}],qstring1:[{token:"string",regex:"(?:[^\\\\]|\\\\.)*?\\]\\=\\]",next:"start"},{token:"string",merge:!0,regex:".+"}],qstring2:[{token:"string",regex:"(?:[^\\\\]|\\\\.)*?\\]\\={2}\\]",next:"start"},{token:"string",merge:!0,regex:".+"}],qstring3:[{token:"string",regex:"(?:[^\\\\]|\\\\.)*?\\]\\={3}\\]",next:"start"},{token:"string",merge:!0,regex:".+"}],qstring4:[{token:"string",regex:"(?:[^\\\\]|\\\\.)*?\\]\\={4}\\]",next:"start"},{token:"string",merge:!0,regex:".+"}],qstring5:[{token:function(a){var b=/\](\=+)\]/,c=this.rules.qstring5[0],d;c.next="start";if((d=b.exec(a))!=null&&(d=d[1])!=undefined){var e=d.length,f;(f=q.pop())!=e&&(q.push(f),c.next="qstring5")}return"string"},regex:"(?:[^\\\\]|\\\\.)*?\\]\\={5}\\=*\\]",next:"start"},{token:"string",merge:!0,regex:".+"}]}};d.inherits(g,f),b.LuaHighlightRules=g}) -------------------------------------------------------------------------------- /test_project/static/ace/mode-perl.js: -------------------------------------------------------------------------------- 1 | define("ace/mode/perl",["require","exports","module","pilot/oop","ace/mode/text","ace/tokenizer","ace/mode/perl_highlight_rules","ace/mode/matching_brace_outdent","ace/range"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text").Mode,f=a("ace/tokenizer").Tokenizer,g=a("ace/mode/perl_highlight_rules").PerlHighlightRules,h=a("ace/mode/matching_brace_outdent").MatchingBraceOutdent,i=a("ace/range").Range,j=function(){this.$tokenizer=new f((new g).getRules()),this.$outdent=new h};d.inherits(j,e),function(){this.toggleCommentLines=function(a,b,c,d){var e=!0,f=[],g=/^(\s*)#/;for(var h=c;h<=d;h++)if(!g.test(b.getLine(h))){e=!1;break}if(e){var j=new i(0,0,0,0);for(var h=c;h<=d;h++){var k=b.getLine(h),l=k.match(g);j.start.row=h,j.end.row=h,j.end.column=l[0].length,b.replace(j,l[1])}}else b.indentRows(c,d,"#")},this.getNextLineIndent=function(a,b,c){var d=this.$getIndent(b),e=this.$tokenizer.getLineTokens(b,a),f=e.tokens,g=e.state;if(f.length&&f[f.length-1].type=="comment")return d;if(a=="start"){var h=b.match(/^.*[\{\(\[\:]\s*$/);h&&(d+=c)}return d},this.checkOutdent=function(a,b,c){return this.$outdent.checkOutdent(b,c)},this.autoOutdent=function(a,b,c){this.$outdent.autoOutdent(b,c)}}.call(j.prototype),b.Mode=j}),define("ace/mode/perl_highlight_rules",["require","exports","module","pilot/oop","pilot/lang","ace/mode/text_highlight_rules"],function(a,b,c){var d=a("pilot/oop"),e=a("pilot/lang"),f=a("ace/mode/text_highlight_rules").TextHighlightRules,g=function(){var a=e.arrayToMap("base|constant|continue|else|elsif|for|foreach|format|goto|if|last|local|my|next|no|package|parent|redo|require|scalar|sub|unless|until|while|use|vars".split("|")),b=e.arrayToMap("ARGV|ENV|INC|SIG".split("|")),c=e.arrayToMap("getprotobynumber|getprotobyname|getservbyname|gethostbyaddr|gethostbyname|getservbyport|getnetbyaddr|getnetbyname|getsockname|getpeername|setpriority|getprotoent|setprotoent|getpriority|endprotoent|getservent|setservent|endservent|sethostent|socketpair|getsockopt|gethostent|endhostent|setsockopt|setnetent|quotemeta|localtime|prototype|getnetent|endnetent|rewinddir|wantarray|getpwuid|closedir|getlogin|readlink|endgrent|getgrgid|getgrnam|shmwrite|shutdown|readline|endpwent|setgrent|readpipe|formline|truncate|dbmclose|syswrite|setpwent|getpwnam|getgrent|getpwent|ucfirst|sysread|setpgrp|shmread|sysseek|sysopen|telldir|defined|opendir|connect|lcfirst|getppid|binmode|syscall|sprintf|getpgrp|readdir|seekdir|waitpid|reverse|unshift|symlink|dbmopen|semget|msgrcv|rename|listen|chroot|msgsnd|shmctl|accept|unpack|exists|fileno|shmget|system|unlink|printf|gmtime|msgctl|semctl|values|rindex|substr|splice|length|msgget|select|socket|return|caller|delete|alarm|ioctl|index|undef|lstat|times|srand|chown|fcntl|close|write|umask|rmdir|study|sleep|chomp|untie|print|utime|mkdir|atan2|split|crypt|flock|chmod|BEGIN|bless|chdir|semop|shift|reset|link|stat|chop|grep|fork|dump|join|open|tell|pipe|exit|glob|warn|each|bind|sort|pack|eval|push|keys|getc|kill|seek|sqrt|send|wait|rand|tied|read|time|exec|recv|eof|chr|int|ord|exp|pos|pop|sin|log|abs|oct|hex|tie|cos|vec|END|ref|map|die|uc|lc|do".split("|"));this.$rules={start:[{token:"comment",regex:"#.*$"},{token:"string.regexp",regex:"[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",merge:!0,regex:'["].*\\\\$',next:"qqstring"},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"string",merge:!0,regex:"['].*\\\\$",next:"qstring"},{token:"constant.numeric",regex:"0x[0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:function(d){return a.hasOwnProperty(d)?"keyword":b.hasOwnProperty(d)?"constant.language":c.hasOwnProperty(d)?"support.function":"identifier"},regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\.\\.\\.|\\|\\|=|>>=|<<=|<=>|&&=|=>|!~|\\^=|&=|\\|=|\\.=|x=|%=|\\/=|\\*=|\\-=|\\+=|=~|\\*\\*|\\-\\-|\\.\\.|\\|\\||&&|\\+\\+|\\->|!=|==|>=|<=|>>|<<|,|=|\\?\\:|\\^|\\||x|%|\\/|\\*|<|&|\\\\|~|!|>|\\.|\\-|\\+|\\-C|\\-b|\\-S|\\-u|\\-t|\\-p|\\-l|\\-d|\\-f|\\-g|\\-s|\\-z|\\-k|\\-e|\\-O|\\-T|\\-B|\\-M|\\-A|\\-X|\\-W|\\-c|\\-R|\\-o|\\-x|\\-w|\\-r|\\b(?:and|cmp|eq|ge|gt|le|lt|ne|not|or|xor)"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],qqstring:[{token:"string",regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"',next:"start"},{token:"string",merge:!0,regex:".+"}],qstring:[{token:"string",regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'",next:"start"},{token:"string",merge:!0,regex:".+"}]}};d.inherits(g,f),b.PerlHighlightRules=g}),define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(a,b,c){var d=a("ace/range").Range,e=function(){};(function(){this.checkOutdent=function(a,b){return/^\s+$/.test(a)?/^\s*\}/.test(b):!1},this.autoOutdent=function(a,b){var c=a.getLine(b),e=c.match(/^(\s*\})/);if(!e)return 0;var f=e[1].length,g=a.findMatchingBracket({row:b,column:f});if(!g||g.row==b)return 0;var h=this.$getIndent(a.getLine(g.row));a.replace(new d(b,0,b,f-1),h)},this.$getIndent=function(a){var b=a.match(/^(\s+)/);return b?b[1]:""}}).call(e.prototype),b.MatchingBraceOutdent=e}) -------------------------------------------------------------------------------- /test_project/static/ace/mode-python.js: -------------------------------------------------------------------------------- 1 | define("ace/mode/python",["require","exports","module","pilot/oop","ace/mode/text","ace/tokenizer","ace/mode/python_highlight_rules","ace/mode/matching_brace_outdent","ace/range"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text").Mode,f=a("ace/tokenizer").Tokenizer,g=a("ace/mode/python_highlight_rules").PythonHighlightRules,h=a("ace/mode/matching_brace_outdent").MatchingBraceOutdent,i=a("ace/range").Range,j=function(){this.$tokenizer=new f((new g).getRules())};d.inherits(j,e),function(){this.toggleCommentLines=function(a,b,c,d){var e=!0,f=[],g=/^(\s*)#/;for(var h=c;h<=d;h++)if(!g.test(b.getLine(h))){e=!1;break}if(e){var j=new i(0,0,0,0);for(var h=c;h<=d;h++){var k=b.getLine(h),l=k.match(g);j.start.row=h,j.end.row=h,j.end.column=l[0].length,b.replace(j,l[1])}}else b.indentRows(c,d,"#")},this.getNextLineIndent=function(a,b,c){var d=this.$getIndent(b),e=this.$tokenizer.getLineTokens(b,a),f=e.tokens,g=e.state;if(f.length&&f[f.length-1].type=="comment")return d;if(a=="start"){var h=b.match(/^.*[\{\(\[\:]\s*$/);h&&(d+=c)}return d};var a={pass:1,"return":1,raise:1,"break":1,"continue":1};this.checkOutdent=function(b,c,d){if(d!=="\r\n"&&d!=="\r"&&d!=="\n")return!1;var e=this.$tokenizer.getLineTokens(c.trim(),b).tokens;if(!e)return!1;do var f=e.pop();while(f&&(f.type=="comment"||f.type=="text"&&f.value.match(/^\s+$/)));return f?f.type=="keyword"&&a[f.value]:!1},this.autoOutdent=function(a,b,c){c+=1;var d=this.$getIndent(b.getLine(c)),e=b.getTabString();d.slice(-e.length)==e&&b.remove(new i(c,d.length-e.length,c,d.length))}}.call(j.prototype),b.Mode=j}),define("ace/mode/python_highlight_rules",["require","exports","module","pilot/oop","pilot/lang","ace/mode/text_highlight_rules"],function(a,b,c){var d=a("pilot/oop"),e=a("pilot/lang"),f=a("ace/mode/text_highlight_rules").TextHighlightRules,g=function(){var a=e.arrayToMap("and|as|assert|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|not|or|pass|print|raise|return|try|while|with|yield".split("|")),b=e.arrayToMap("True|False|None|NotImplemented|Ellipsis|__debug__".split("|")),c=e.arrayToMap("abs|divmod|input|open|staticmethod|all|enumerate|int|ord|str|any|eval|isinstance|pow|sum|basestring|execfile|issubclass|print|super|binfile|iter|property|tuple|bool|filter|len|range|type|bytearray|float|list|raw_input|unichr|callable|format|locals|reduce|unicode|chr|frozenset|long|reload|vars|classmethod|getattr|map|repr|xrange|cmp|globals|max|reversed|zip|compile|hasattr|memoryview|round|__import__|complex|hash|min|set|apply|delattr|help|next|setattr|buffer|dict|hex|object|slice|coerce|dir|id|oct|sorted|intern".split("|")),d=e.arrayToMap("".split("|")),f="(?:r|u|ur|R|U|UR|Ur|uR)?",g="(?:(?:[1-9]\\d*)|(?:0))",h="(?:0[oO]?[0-7]+)",i="(?:0[xX][\\dA-Fa-f]+)",j="(?:0[bB][01]+)",k="(?:"+g+"|"+h+"|"+i+"|"+j+")",l="(?:[eE][+-]?\\d+)",m="(?:\\.\\d+)",n="(?:\\d+)",o="(?:(?:"+n+"?"+m+")|(?:"+n+"\\.))",p="(?:(?:"+o+"|"+n+")"+l+")",q="(?:"+p+"|"+o+")";this.$rules={start:[{token:"comment",regex:"#.*$"},{token:"string",regex:f+'"{3}(?:[^\\\\]|\\\\.)*?"{3}'},{token:"string",merge:!0,regex:f+'"{3}.*$',next:"qqstring"},{token:"string",regex:f+'"(?:[^\\\\]|\\\\.)*?"'},{token:"string",regex:f+"'{3}(?:[^\\\\]|\\\\.)*?'{3}"},{token:"string",merge:!0,regex:f+"'{3}.*$",next:"qstring"},{token:"string",regex:f+"'(?:[^\\\\]|\\\\.)*?'"},{token:"constant.numeric",regex:"(?:"+q+"|\\d+)[jJ]\\b"},{token:"constant.numeric",regex:q},{token:"constant.numeric",regex:k+"[lL]\\b"},{token:"constant.numeric",regex:k+"\\b"},{token:function(e){return a.hasOwnProperty(e)?"keyword":b.hasOwnProperty(e)?"constant.language":d.hasOwnProperty(e)?"invalid.illegal":c.hasOwnProperty(e)?"support.function":e=="debugger"?"invalid.deprecated":"identifier"},regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\+|\\-|\\*|\\*\\*|\\/|\\/\\/|%|<<|>>|&|\\||\\^|~|<|>|<=|=>|==|!=|<>|="},{token:"lparen",regex:"[\\[\\(\\{]"},{token:"rparen",regex:"[\\]\\)\\}]"},{token:"text",regex:"\\s+"}],qqstring:[{token:"string",regex:'(?:[^\\\\]|\\\\.)*?"{3}',next:"start"},{token:"string",merge:!0,regex:".+"}],qstring:[{token:"string",regex:"(?:[^\\\\]|\\\\.)*?'{3}",next:"start"},{token:"string",merge:!0,regex:".+"}]}};d.inherits(g,f),b.PythonHighlightRules=g}),define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(a,b,c){var d=a("ace/range").Range,e=function(){};(function(){this.checkOutdent=function(a,b){return/^\s+$/.test(a)?/^\s*\}/.test(b):!1},this.autoOutdent=function(a,b){var c=a.getLine(b),e=c.match(/^(\s*\})/);if(!e)return 0;var f=e[1].length,g=a.findMatchingBracket({row:b,column:f});if(!g||g.row==b)return 0;var h=this.$getIndent(a.getLine(g.row));a.replace(new d(b,0,b,f-1),h)},this.$getIndent=function(a){var b=a.match(/^(\s+)/);return b?b[1]:""}}).call(e.prototype),b.MatchingBraceOutdent=e}) -------------------------------------------------------------------------------- /test_project/static/ace/mode-ruby.js: -------------------------------------------------------------------------------- 1 | define("ace/mode/ruby",["require","exports","module","pilot/oop","ace/mode/text","ace/tokenizer","ace/mode/ruby_highlight_rules","ace/mode/matching_brace_outdent","ace/range"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text").Mode,f=a("ace/tokenizer").Tokenizer,g=a("ace/mode/ruby_highlight_rules").RubyHighlightRules,h=a("ace/mode/matching_brace_outdent").MatchingBraceOutdent,i=a("ace/range").Range,j=function(){this.$tokenizer=new f((new g).getRules()),this.$outdent=new h};d.inherits(j,e),function(){this.toggleCommentLines=function(a,b,c,d){var e=!0,f=[],g=/^(\s*)#/;for(var h=c;h<=d;h++)if(!g.test(b.getLine(h))){e=!1;break}if(e){var j=new i(0,0,0,0);for(var h=c;h<=d;h++){var k=b.getLine(h),l=k.match(g);j.start.row=h,j.end.row=h,j.end.column=l[0].length,b.replace(j,l[1])}}else b.indentRows(c,d,"#")},this.getNextLineIndent=function(a,b,c){var d=this.$getIndent(b),e=this.$tokenizer.getLineTokens(b,a),f=e.tokens,g=e.state;if(f.length&&f[f.length-1].type=="comment")return d;if(a=="start"){var h=b.match(/^.*[\{\(\[]\s*$/);h&&(d+=c)}return d},this.checkOutdent=function(a,b,c){return this.$outdent.checkOutdent(b,c)},this.autoOutdent=function(a,b,c){this.$outdent.autoOutdent(b,c)}}.call(j.prototype),b.Mode=j}),define("ace/mode/ruby_highlight_rules",["require","exports","module","pilot/oop","pilot/lang","ace/mode/text_highlight_rules"],function(a,b,c){var d=a("pilot/oop"),e=a("pilot/lang"),f=a("ace/mode/text_highlight_rules").TextHighlightRules,g=function(){var a=e.arrayToMap("abort|Array|assert|assert_equal|assert_not_equal|assert_same|assert_not_same|assert_nil|assert_not_nil|assert_match|assert_no_match|assert_in_delta|assert_throws|assert_raise|assert_nothing_raised|assert_instance_of|assert_kind_of|assert_respond_to|assert_operator|assert_send|assert_difference|assert_no_difference|assert_recognizes|assert_generates|assert_response|assert_redirected_to|assert_template|assert_select|assert_select_email|assert_select_rjs|assert_select_encoded|css_select|at_exit|attr|attr_writer|attr_reader|attr_accessor|attr_accessible|autoload|binding|block_given?|callcc|caller|catch|chomp|chomp!|chop|chop!|defined?|delete_via_redirect|eval|exec|exit|exit!|fail|Float|flunk|follow_redirect!|fork|form_for|form_tag|format|gets|global_variables|gsub|gsub!|get_via_redirect|h|host!|https?|https!|include|Integer|lambda|link_to|link_to_unless_current|link_to_function|link_to_remote|load|local_variables|loop|open|open_session|p|print|printf|proc|putc|puts|post_via_redirect|put_via_redirect|raise|rand|raw|readline|readlines|redirect?|request_via_redirect|require|scan|select|set_trace_func|sleep|split|sprintf|srand|String|stylesheet_link_tag|syscall|system|sub|sub!|test|throw|trace_var|trap|untrace_var|atan2|cos|exp|frexp|ldexp|log|log10|sin|sqrt|tan|render|javascript_include_tag|csrf_meta_tag|label_tag|text_field_tag|submit_tag|check_box_tag|content_tag|radio_button_tag|text_area_tag|password_field_tag|hidden_field_tag|fields_for|select_tag|options_for_select|options_from_collection_for_select|collection_select|time_zone_select|select_date|select_time|select_datetime|date_select|time_select|datetime_select|select_year|select_month|select_day|select_hour|select_minute|select_second|file_field_tag|file_field|respond_to|skip_before_filter|around_filter|after_filter|verify|protect_from_forgery|rescue_from|helper_method|redirect_to|before_filter|send_data|send_file|validates_presence_of|validates_uniqueness_of|validates_length_of|validates_format_of|validates_acceptance_of|validates_associated|validates_exclusion_of|validates_inclusion_of|validates_numericality_of|validates_with|validates_each|authenticate_or_request_with_http_basic|authenticate_or_request_with_http_digest|filter_parameter_logging|match|get|post|resources|redirect|scope|assert_routing|translate|localize|extract_locale_from_tld|t|l|caches_page|expire_page|caches_action|expire_action|cache|expire_fragment|expire_cache_for|observe|cache_sweeper|has_many|has_one|belongs_to|has_and_belongs_to_many".split("|")),b=e.arrayToMap("alias|and|BEGIN|begin|break|case|class|def|defined|do|else|elsif|END|end|ensure|__FILE__|finally|for|gem|if|in|__LINE__|module|next|not|or|private|protected|public|redo|rescue|retry|return|super|then|undef|unless|until|when|while|yield".split("|")),c=e.arrayToMap("true|TRUE|false|FALSE|nil|NIL|ARGF|ARGV|DATA|ENV|RUBY_PLATFORM|RUBY_RELEASE_DATE|RUBY_VERSION|STDERR|STDIN|STDOUT|TOPLEVEL_BINDING".split("|")),d=e.arrayToMap("$DEBUG|$defout|$FILENAME|$LOAD_PATH|$SAFE|$stdin|$stdout|$stderr|$VERBOSE|$!|root_url|flash|session|cookies|params|request|response|logger".split("|"));this.$rules={start:[{token:"comment",regex:"#.*$"},{token:"comment",merge:!0,regex:"^=begin$",next:"comment"},{token:"string.regexp",regex:"[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"string",regex:"[`](?:(?:\\\\.)|(?:[^'\\\\]))*?[`]"},{token:"text",regex:"::"},{token:"variable.instancce",regex:"@{1,2}(?:[a-zA-Z_]|d)+"},{token:"variable.class",regex:"[A-Z](?:[a-zA-Z_]|d)+"},{token:"string",regex:"[:](?:[A-Za-z_]|[@$](?=[a-zA-Z0-9_]))[a-zA-Z0-9_]*[!=?]?"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F](?:[0-9a-fA-F]|_(?=[0-9a-fA-F]))*\\b"},{token:"constant.numeric",regex:"[+-]?\\d(?:\\d|_(?=\\d))*(?:(?:\\.\\d(?:\\d|_(?=\\d))*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:function(e){return e=="self"?"variable.language":b.hasOwnProperty(e)?"keyword":c.hasOwnProperty(e)?"constant.language":d.hasOwnProperty(e)?"variable.language":a.hasOwnProperty(e)?"support.function":e=="debugger"?"invalid.deprecated":"identifier"},regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:"^=end$",next:"start"},{token:"comment",merge:!0,regex:".+"}]}};d.inherits(g,f),b.RubyHighlightRules=g}),define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(a,b,c){var d=a("ace/range").Range,e=function(){};(function(){this.checkOutdent=function(a,b){return/^\s+$/.test(a)?/^\s*\}/.test(b):!1},this.autoOutdent=function(a,b){var c=a.getLine(b),e=c.match(/^(\s*\})/);if(!e)return 0;var f=e[1].length,g=a.findMatchingBracket({row:b,column:f});if(!g||g.row==b)return 0;var h=this.$getIndent(a.getLine(g.row));a.replace(new d(b,0,b,f-1),h)},this.$getIndent=function(a){var b=a.match(/^(\s+)/);return b?b[1]:""}}).call(e.prototype),b.MatchingBraceOutdent=e}) -------------------------------------------------------------------------------- /test_project/static/ace/mode-scad.js: -------------------------------------------------------------------------------- 1 | define("ace/mode/scad",["require","exports","module","pilot/oop","ace/mode/text","ace/tokenizer","ace/mode/scad_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/mode/behaviour/cstyle"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text").Mode,f=a("ace/tokenizer").Tokenizer,g=a("ace/mode/scad_highlight_rules").scadHighlightRules,h=a("ace/mode/matching_brace_outdent").MatchingBraceOutdent,i=a("ace/range").Range,j=a("ace/mode/behaviour/cstyle").CstyleBehaviour,k=function(){this.$tokenizer=new f((new g).getRules()),this.$outdent=new h,this.$behaviour=new j};d.inherits(k,e),function(){this.toggleCommentLines=function(a,b,c,d){var e=!0,f=[],g=/^(\s*)\/\//;for(var h=c;h<=d;h++)if(!g.test(b.getLine(h))){e=!1;break}if(e){var j=new i(0,0,0,0);for(var h=c;h<=d;h++){var k=b.getLine(h),l=k.match(g);j.start.row=h,j.end.row=h,j.end.column=l[0].length,b.replace(j,l[1])}}else b.indentRows(c,d,"//")},this.getNextLineIndent=function(a,b,c){var d=this.$getIndent(b),e=this.$tokenizer.getLineTokens(b,a),f=e.tokens,g=e.state;if(f.length&&f[f.length-1].type=="comment")return d;if(a=="start"){var h=b.match(/^.*[\{\(\[]\s*$/);h&&(d+=c)}else if(a=="doc-start"){if(g=="start")return"";var h=b.match(/^\s*(\/?)\*/);h&&(h[1]&&(d+=" "),d+="* ")}return d},this.checkOutdent=function(a,b,c){return this.$outdent.checkOutdent(b,c)},this.autoOutdent=function(a,b,c){this.$outdent.autoOutdent(b,c)}}.call(k.prototype),b.Mode=k}),define("ace/mode/scad_highlight_rules",["require","exports","module","pilot/oop","pilot/lang","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(a,b,c){var d=a("pilot/oop"),e=a("pilot/lang"),f=a("ace/mode/doc_comment_highlight_rules").DocCommentHighlightRules,g=a("ace/mode/text_highlight_rules").TextHighlightRules,h=function(){var a=e.arrayToMap("module|if|else|for".split("|")),b=e.arrayToMap("NULL".split("|"));this.$rules={start:[{token:"comment",regex:"\\/\\/.*$"},(new f).getStartRule("start"),{token:"comment",merge:!0,regex:"\\/\\*",next:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:'["].*\\\\$',next:"qqstring"},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"string",regex:"['].*\\\\$",next:"qstring"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"constant",regex:"<[a-zA-Z0-9.]+>"},{token:"keyword",regex:"(?:use|include)"},{token:function(c){return c=="this"?"variable.language":a.hasOwnProperty(c)?"keyword":b.hasOwnProperty(c)?"constant.language":"identifier"},regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|==|=|!=|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|new|delete|typeof|void)"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",merge:!0,regex:".+"}],qqstring:[{token:"string",regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"',next:"start"},{token:"string",merge:!0,regex:".+"}],qstring:[{token:"string",regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'",next:"start"},{token:"string",merge:!0,regex:".+"}]},this.embedRules(f,"doc-",[(new f).getEndRule("start")])};d.inherits(h,g),b.scadHighlightRules=h}),define("ace/mode/doc_comment_highlight_rules",["require","exports","module","pilot/oop","ace/mode/text_highlight_rules"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text_highlight_rules").TextHighlightRules,f=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc",merge:!0,regex:"\\s+"},{token:"comment.doc",merge:!0,regex:"TODO"},{token:"comment.doc",merge:!0,regex:"[^@\\*]+"},{token:"comment.doc",merge:!0,regex:"."}]}};d.inherits(f,e),function(){this.getStartRule=function(a){return{token:"comment.doc",merge:!0,regex:"\\/\\*(?=\\*)",next:a}},this.getEndRule=function(a){return{token:"comment.doc",merge:!0,regex:"\\*\\/",next:a}}}.call(f.prototype),b.DocCommentHighlightRules=f}),define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(a,b,c){var d=a("ace/range").Range,e=function(){};(function(){this.checkOutdent=function(a,b){return/^\s+$/.test(a)?/^\s*\}/.test(b):!1},this.autoOutdent=function(a,b){var c=a.getLine(b),e=c.match(/^(\s*\})/);if(!e)return 0;var f=e[1].length,g=a.findMatchingBracket({row:b,column:f});if(!g||g.row==b)return 0;var h=this.$getIndent(a.getLine(g.row));a.replace(new d(b,0,b,f-1),h)},this.$getIndent=function(a){var b=a.match(/^(\s+)/);return b?b[1]:""}}).call(e.prototype),b.MatchingBraceOutdent=e}),define("ace/mode/behaviour/cstyle",["require","exports","module","pilot/oop","ace/mode/behaviour"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/behaviour").Behaviour,f=function(){this.add("braces","insertion",function(a,b,c,d,e){if(e=="{"){var f=c.getSelectionRange(),g=d.doc.getTextRange(f);return g!==""?{text:"{"+g+"}",selection:!1}:{text:"{}",selection:[1,1]}}if(e=="}"){var h=c.getCursorPosition(),i=d.doc.getLine(h.row),j=i.substring(h.column,h.column+1);if(j=="}"){var k=d.$findOpeningBracket("}",{column:h.column+1,row:h.row});if(k!==null)return{text:"",selection:[1,1]}}}else if(e=="\n"){var h=c.getCursorPosition(),i=d.doc.getLine(h.row),j=i.substring(h.column,h.column+1);if(j=="}"){var l=d.findMatchingBracket({row:h.row,column:h.column+1});if(!l)return!1;var m=this.getNextLineIndent(a,i.substring(0,i.length-1),d.getTabString()),n=this.$getIndent(d.doc.getLine(l.row));return{text:"\n"+m+"\n"+n,selection:[1,m.length,1,m.length]}}}return!1}),this.add("braces","deletion",function(a,b,c,d,e){var f=d.doc.getTextRange(e);if(!e.isMultiLine()&&f=="{"){var g=d.doc.getLine(e.start.row),h=g.substring(e.end.column,e.end.column+1);if(h=="}")return e.end.column++,e}return!1}),this.add("parens","insertion",function(a,b,c,d,e){if(e=="("){var f=c.getSelectionRange(),g=d.doc.getTextRange(f);return g!==""?{text:"("+g+")",selection:!1}:{text:"()",selection:[1,1]}}if(e==")"){var h=c.getCursorPosition(),i=d.doc.getLine(h.row),j=i.substring(h.column,h.column+1);if(j==")"){var k=d.$findOpeningBracket(")",{column:h.column+1,row:h.row});if(k!==null)return{text:"",selection:[1,1]}}}return!1}),this.add("parens","deletion",function(a,b,c,d,e){var f=d.doc.getTextRange(e);if(!e.isMultiLine()&&f=="("){var g=d.doc.getLine(e.start.row),h=g.substring(e.start.column+1,e.start.column+2);if(h==")")return e.end.column++,e}return!1}),this.add("string_dquotes","insertion",function(a,b,c,d,e){if(e=='"'){var f=c.getSelectionRange(),g=d.doc.getTextRange(f);if(g!=="")return{text:'"'+g+'"',selection:!1};var h=c.getCursorPosition(),i=d.doc.getLine(h.row),j=i.substring(h.column-1,h.column);if(j=="\\")return!1;var k=d.getTokens(f.start.row,f.start.row)[0].tokens,l=0,m,n=-1;for(var o=0;of.start.column)break;l+=k[o].value.length}if(!m||n<0&&m.type!=="comment"&&(m.type!=="string"||f.start.column!==m.value.length+l-1&&m.value.lastIndexOf('"')===m.value.length-1))return{text:'""',selection:[1,1]};if(m&&m.type==="string"){var p=i.substring(h.column,h.column+1);if(p=='"')return{text:"",selection:[1,1]}}}return!1}),this.add("string_dquotes","deletion",function(a,b,c,d,e){var f=d.doc.getTextRange(e);if(!e.isMultiLine()&&f=='"'){var g=d.doc.getLine(e.start.row),h=g.substring(e.start.column+1,e.start.column+2);if(h=='"')return e.end.column++,e}return!1})};d.inherits(f,e),b.CstyleBehaviour=f}) -------------------------------------------------------------------------------- /test_project/static/ace/mode-scss.js: -------------------------------------------------------------------------------- 1 | define("ace/mode/scss",["require","exports","module","pilot/oop","ace/mode/text","ace/tokenizer","ace/mode/scss_highlight_rules","ace/mode/matching_brace_outdent"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text").Mode,f=a("ace/tokenizer").Tokenizer,g=a("ace/mode/scss_highlight_rules").ScssHighlightRules,h=a("ace/mode/matching_brace_outdent").MatchingBraceOutdent,i=function(){this.$tokenizer=new f((new g).getRules()),this.$outdent=new h};d.inherits(i,e),function(){this.getNextLineIndent=function(a,b,c){var d=this.$getIndent(b),e=this.$tokenizer.getLineTokens(b,a).tokens;if(e.length&&e[e.length-1].type=="comment")return d;var f=b.match(/^.*\{\s*$/);return f&&(d+=c),d},this.checkOutdent=function(a,b,c){return this.$outdent.checkOutdent(b,c)},this.autoOutdent=function(a,b,c){this.$outdent.autoOutdent(b,c)}}.call(i.prototype),b.Mode=i}),define("ace/mode/scss_highlight_rules",["require","exports","module","pilot/oop","pilot/lang","ace/mode/text_highlight_rules"],function(a,b,c){var d=a("pilot/oop"),e=a("pilot/lang"),f=a("ace/mode/text_highlight_rules").TextHighlightRules,g=function(){function i(a){var b=[],c=a.split("");for(var d=0;d|<=|>=|==|!=|-|%|#|\\+|\\$|\\+|\\*"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",merge:!0,regex:".+"}],qqstring:[{token:"string",regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"',next:"start"},{token:"string",merge:!0,regex:".+"}],qstring:[{token:"string",regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'",next:"start"},{token:"string",merge:!0,regex:".+"}]}};d.inherits(g,f),b.ScssHighlightRules=g}),define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(a,b,c){var d=a("ace/range").Range,e=function(){};(function(){this.checkOutdent=function(a,b){return/^\s+$/.test(a)?/^\s*\}/.test(b):!1},this.autoOutdent=function(a,b){var c=a.getLine(b),e=c.match(/^(\s*\})/);if(!e)return 0;var f=e[1].length,g=a.findMatchingBracket({row:b,column:f});if(!g||g.row==b)return 0;var h=this.$getIndent(a.getLine(g.row));a.replace(new d(b,0,b,f-1),h)},this.$getIndent=function(a){var b=a.match(/^(\s+)/);return b?b[1]:""}}).call(e.prototype),b.MatchingBraceOutdent=e}) -------------------------------------------------------------------------------- /test_project/static/ace/mode-textile.js: -------------------------------------------------------------------------------- 1 | define("ace/mode/textile",["require","exports","module","pilot/oop","ace/mode/text","ace/tokenizer","ace/mode/textile_highlight_rules","ace/mode/matching_brace_outdent","ace/range"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text").Mode,f=a("ace/tokenizer").Tokenizer,g=a("ace/mode/textile_highlight_rules").TextileHighlightRules,h=a("ace/mode/matching_brace_outdent").MatchingBraceOutdent,i=a("ace/range").Range,j=function(){this.$tokenizer=new f((new g).getRules()),this.$outdent=new h};d.inherits(j,e),function(){this.getNextLineIndent=function(a,b,c){return a=="intag"?c:""},this.checkOutdent=function(a,b,c){return this.$outdent.checkOutdent(b,c)},this.autoOutdent=function(a,b,c){this.$outdent.autoOutdent(b,c)}}.call(j.prototype),b.Mode=j}),define("ace/mode/textile_highlight_rules",["require","exports","module","pilot/oop","ace/mode/text_highlight_rules"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text_highlight_rules").TextHighlightRules,f=function(){this.$rules={start:[{token:"keyword",token:function(a){return a.match(/^h\d$/)?"markup.heading."+a.charAt(1):"markup.heading"},regex:"h1|h2|h3|h4|h5|h6|bq|p|bc|pre",next:"blocktag"},{token:"keyword",regex:"[\\*]+|[#]+"},{token:"text",regex:".+"}],blocktag:[{token:"keyword",regex:"\\. ",next:"start"},{token:"keyword",regex:"\\(",next:"blocktagproperties"}],blocktagproperties:[{token:"keyword",regex:"\\)",next:"blocktag"},{token:"string",regex:"[a-zA-Z0-9\\-_]+"},{token:"keyword",regex:"#"}]}};d.inherits(f,e),b.TextileHighlightRules=f}),define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(a,b,c){var d=a("ace/range").Range,e=function(){};(function(){this.checkOutdent=function(a,b){return/^\s+$/.test(a)?/^\s*\}/.test(b):!1},this.autoOutdent=function(a,b){var c=a.getLine(b),e=c.match(/^(\s*\})/);if(!e)return 0;var f=e[1].length,g=a.findMatchingBracket({row:b,column:f});if(!g||g.row==b)return 0;var h=this.$getIndent(a.getLine(g.row));a.replace(new d(b,0,b,f-1),h)},this.$getIndent=function(a){var b=a.match(/^(\s+)/);return b?b[1]:""}}).call(e.prototype),b.MatchingBraceOutdent=e}) -------------------------------------------------------------------------------- /test_project/static/ace/mode-xml.js: -------------------------------------------------------------------------------- 1 | define("ace/mode/xml",["require","exports","module","pilot/oop","ace/mode/text","ace/tokenizer","ace/mode/xml_highlight_rules","ace/mode/behaviour/xml"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text").Mode,f=a("ace/tokenizer").Tokenizer,g=a("ace/mode/xml_highlight_rules").XmlHighlightRules,h=a("ace/mode/behaviour/xml").XmlBehaviour,i=function(){this.$tokenizer=new f((new g).getRules()),this.$behaviour=new h};d.inherits(i,e),function(){this.getNextLineIndent=function(a,b,c){return this.$getIndent(b)}}.call(i.prototype),b.Mode=i}),define("ace/mode/xml_highlight_rules",["require","exports","module","pilot/oop","ace/mode/text_highlight_rules"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text_highlight_rules").TextHighlightRules,f=function(){this.$rules={start:[{token:"text",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:"xml_pe",regex:"<\\?.*?\\?>"},{token:"comment",merge:!0,regex:"<\\!--",next:"comment"},{token:"text",regex:"<\\/?",next:"tag"},{token:"text",regex:"\\s+"},{token:"text",regex:"[^<]+"}],tag:[{token:"text",regex:">",next:"start"},{token:"keyword",regex:"[-_a-zA-Z0-9:]+"},{token:"text",regex:"\\s+"},{token:"string",regex:'".*?"'},{token:"string",merge:!0,regex:'["].*$',next:"qqstring"},{token:"string",regex:"'.*?'"},{token:"string",merge:!0,regex:"['].*$",next:"qstring"}],qstring:[{token:"string",regex:".*'",next:"tag"},{token:"string",merge:!0,regex:".+"}],qqstring:[{token:"string",regex:'.*"',next:"tag"},{token:"string",merge:!0,regex:".+"}],cdata:[{token:"text",regex:"\\]\\]>",next:"start"},{token:"text",regex:"\\s+"},{token:"text",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment",regex:".*?-->",next:"start"},{token:"comment",merge:!0,regex:".+"}]}};d.inherits(f,e),b.XmlHighlightRules=f}),define("ace/mode/behaviour/xml",["require","exports","module","pilot/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/behaviour").Behaviour,f=a("ace/mode/behaviour/cstyle").CstyleBehaviour,g=function(){this.inherit(f,["string_dquotes"]),this.add("brackets","insertion",function(a,b,c,d,e){if(e=="<"){var f=c.getSelectionRange(),g=d.doc.getTextRange(f);return g!==""?!1:{text:"<>",selection:[1,1]}}if(e==">"){var h=c.getCursorPosition(),i=d.doc.getLine(h.row),j=i.substring(h.column,h.column+1);if(j==">")return{text:"",selection:[1,1]}}else if(e=="\n"){var h=c.getCursorPosition(),i=d.doc.getLine(h.row),k=i.substring(h.column,h.column+2);if(k=="f.start.column)break;l+=k[o].value.length}if(!m||n<0&&m.type!=="comment"&&(m.type!=="string"||f.start.column!==m.value.length+l-1&&m.value.lastIndexOf('"')===m.value.length-1))return{text:'""',selection:[1,1]};if(m&&m.type==="string"){var p=i.substring(h.column,h.column+1);if(p=='"')return{text:"",selection:[1,1]}}}return!1}),this.add("string_dquotes","deletion",function(a,b,c,d,e){var f=d.doc.getTextRange(e);if(!e.isMultiLine()&&f=='"'){var g=d.doc.getLine(e.start.row),h=g.substring(e.start.column+1,e.start.column+2);if(h=='"')return e.end.column++,e}return!1})};d.inherits(f,e),b.CstyleBehaviour=f}) -------------------------------------------------------------------------------- /test_project/static/ace/theme-clouds.js: -------------------------------------------------------------------------------- 1 | define("ace/theme/clouds",["require","exports","module"],function(a,b,c){var d=a("pilot/dom"),e=".ace-clouds .ace_editor { border: 2px solid rgb(159, 159, 159);}.ace-clouds .ace_editor.ace_focus { border: 2px solid #327fbd;}.ace-clouds .ace_gutter { width: 50px; background: #e8e8e8; color: #333; overflow : hidden;}.ace-clouds .ace_gutter-layer { width: 100%; text-align: right;}.ace-clouds .ace_gutter-layer .ace_gutter-cell { padding-right: 6px;}.ace-clouds .ace_print_margin { width: 1px; background: #e8e8e8;}.ace-clouds .ace_scroller { background-color: #FFFFFF;}.ace-clouds .ace_text-layer { cursor: text; color: #000000;}.ace-clouds .ace_cursor { border-left: 2px solid #000000;}.ace-clouds .ace_cursor.ace_overwrite { border-left: 0px; border-bottom: 1px solid #000000;} .ace-clouds .ace_marker-layer .ace_selection { background: #BDD5FC;}.ace-clouds .ace_marker-layer .ace_step { background: rgb(198, 219, 174);}.ace-clouds .ace_marker-layer .ace_bracket { margin: -1px 0 0 -1px; border: 1px solid #BFBFBF;}.ace-clouds .ace_marker-layer .ace_active_line { background: #FFFBD1;} .ace-clouds .ace_invisible { color: #BFBFBF;}.ace-clouds .ace_keyword { color:#AF956F;}.ace-clouds .ace_keyword.ace_operator { color:#484848;}.ace-clouds .ace_constant { }.ace-clouds .ace_constant.ace_language { color:#39946A;}.ace-clouds .ace_constant.ace_library { }.ace-clouds .ace_constant.ace_numeric { color:#46A609;}.ace-clouds .ace_invalid { background-color:#FF002A;}.ace-clouds .ace_invalid.ace_illegal { }.ace-clouds .ace_invalid.ace_deprecated { }.ace-clouds .ace_support { }.ace-clouds .ace_support.ace_function { color:#C52727;}.ace-clouds .ace_function.ace_buildin { }.ace-clouds .ace_string { color:#5D90CD;}.ace-clouds .ace_string.ace_regexp { }.ace-clouds .ace_comment { color:#BCC8BA;}.ace-clouds .ace_comment.ace_doc { }.ace-clouds .ace_comment.ace_doc.ace_tag { }.ace-clouds .ace_variable { }.ace-clouds .ace_variable.ace_language { }.ace-clouds .ace_xml_pe { }.ace-clouds .ace_meta { }.ace-clouds .ace_meta.ace_tag { }.ace-clouds .ace_meta.ace_tag.ace_input { }.ace-clouds .ace_entity.ace_other.ace_attribute-name { color:#606060;}.ace-clouds .ace_markup.ace_underline { text-decoration:underline;}.ace-clouds .ace_markup.ace_heading { }.ace-clouds .ace_markup.ace_heading.ace_1 { }.ace-clouds .ace_markup.ace_heading.ace_2 { }.ace-clouds .ace_markup.ace_heading.ace_3 { }.ace-clouds .ace_markup.ace_heading.ace_4 { }.ace-clouds .ace_markup.ace_heading.ace_5 { }.ace-clouds .ace_markup.ace_heading.ace_6 { }.ace-clouds .ace_markup.ace_list { }.ace-clouds .ace_collab.ace_user1 { }";d.importCssString(e),b.cssClass="ace-clouds"}) -------------------------------------------------------------------------------- /test_project/static/ace/theme-clouds_midnight.js: -------------------------------------------------------------------------------- 1 | define("ace/theme/clouds_midnight",["require","exports","module"],function(a,b,c){var d=a("pilot/dom"),e=".ace-clouds-midnight .ace_editor { border: 2px solid rgb(159, 159, 159);}.ace-clouds-midnight .ace_editor.ace_focus { border: 2px solid #327fbd;}.ace-clouds-midnight .ace_gutter { width: 50px; background: #e8e8e8; color: #333; overflow : hidden;}.ace-clouds-midnight .ace_gutter-layer { width: 100%; text-align: right;}.ace-clouds-midnight .ace_gutter-layer .ace_gutter-cell { padding-right: 6px;}.ace-clouds-midnight .ace_print_margin { width: 1px; background: #e8e8e8;}.ace-clouds-midnight .ace_scroller { background-color: #191919;}.ace-clouds-midnight .ace_text-layer { cursor: text; color: #929292;}.ace-clouds-midnight .ace_cursor { border-left: 2px solid #7DA5DC;}.ace-clouds-midnight .ace_cursor.ace_overwrite { border-left: 0px; border-bottom: 1px solid #7DA5DC;} .ace-clouds-midnight .ace_marker-layer .ace_selection { background: #000000;}.ace-clouds-midnight .ace_marker-layer .ace_step { background: rgb(198, 219, 174);}.ace-clouds-midnight .ace_marker-layer .ace_bracket { margin: -1px 0 0 -1px; border: 1px solid #BFBFBF;}.ace-clouds-midnight .ace_marker-layer .ace_active_line { background: rgba(215, 215, 215, 0.031);} .ace-clouds-midnight .ace_invisible { color: #BFBFBF;}.ace-clouds-midnight .ace_keyword { color:#927C5D;}.ace-clouds-midnight .ace_keyword.ace_operator { color:#4B4B4B;}.ace-clouds-midnight .ace_constant { }.ace-clouds-midnight .ace_constant.ace_language { color:#39946A;}.ace-clouds-midnight .ace_constant.ace_library { }.ace-clouds-midnight .ace_constant.ace_numeric { color:#46A609;}.ace-clouds-midnight .ace_invalid { color:#FFFFFF;background-color:#E92E2E;}.ace-clouds-midnight .ace_invalid.ace_illegal { }.ace-clouds-midnight .ace_invalid.ace_deprecated { }.ace-clouds-midnight .ace_support { }.ace-clouds-midnight .ace_support.ace_function { color:#E92E2E;}.ace-clouds-midnight .ace_function.ace_buildin { }.ace-clouds-midnight .ace_string { color:#5D90CD;}.ace-clouds-midnight .ace_string.ace_regexp { }.ace-clouds-midnight .ace_comment { color:#3C403B;}.ace-clouds-midnight .ace_comment.ace_doc { }.ace-clouds-midnight .ace_comment.ace_doc.ace_tag { }.ace-clouds-midnight .ace_variable { }.ace-clouds-midnight .ace_variable.ace_language { }.ace-clouds-midnight .ace_xml_pe { }.ace-clouds-midnight .ace_meta { }.ace-clouds-midnight .ace_meta.ace_tag { }.ace-clouds-midnight .ace_meta.ace_tag.ace_input { }.ace-clouds-midnight .ace_entity.ace_other.ace_attribute-name { color:#606060;}.ace-clouds-midnight .ace_markup.ace_underline { text-decoration:underline;}.ace-clouds-midnight .ace_markup.ace_heading { }.ace-clouds-midnight .ace_markup.ace_heading.ace_1 { }.ace-clouds-midnight .ace_markup.ace_heading.ace_2 { }.ace-clouds-midnight .ace_markup.ace_heading.ace_3 { }.ace-clouds-midnight .ace_markup.ace_heading.ace_4 { }.ace-clouds-midnight .ace_markup.ace_heading.ace_5 { }.ace-clouds-midnight .ace_markup.ace_heading.ace_6 { }.ace-clouds-midnight .ace_markup.ace_list { }.ace-clouds-midnight .ace_collab.ace_user1 { }";d.importCssString(e),b.cssClass="ace-clouds-midnight"}) -------------------------------------------------------------------------------- /test_project/static/ace/theme-cobalt.js: -------------------------------------------------------------------------------- 1 | define("ace/theme/cobalt",["require","exports","module"],function(a,b,c){var d=a("pilot/dom"),e=".ace-cobalt .ace_editor { border: 2px solid rgb(159, 159, 159);}.ace-cobalt .ace_editor.ace_focus { border: 2px solid #327fbd;}.ace-cobalt .ace_gutter { width: 50px; background: #e8e8e8; color: #333; overflow : hidden;}.ace-cobalt .ace_gutter-layer { width: 100%; text-align: right;}.ace-cobalt .ace_gutter-layer .ace_gutter-cell { padding-right: 6px;}.ace-cobalt .ace_print_margin { width: 1px; background: #e8e8e8;}.ace-cobalt .ace_scroller { background-color: #002240;}.ace-cobalt .ace_text-layer { cursor: text; color: #FFFFFF;}.ace-cobalt .ace_cursor { border-left: 2px solid #FFFFFF;}.ace-cobalt .ace_cursor.ace_overwrite { border-left: 0px; border-bottom: 1px solid #FFFFFF;} .ace-cobalt .ace_marker-layer .ace_selection { background: rgba(179, 101, 57, 0.75);}.ace-cobalt .ace_marker-layer .ace_step { background: rgb(198, 219, 174);}.ace-cobalt .ace_marker-layer .ace_bracket { margin: -1px 0 0 -1px; border: 1px solid rgba(255, 255, 255, 0.15);}.ace-cobalt .ace_marker-layer .ace_active_line { background: rgba(0, 0, 0, 0.35);} .ace-cobalt .ace_invisible { color: rgba(255, 255, 255, 0.15);}.ace-cobalt .ace_keyword { color:#FF9D00;}.ace-cobalt .ace_keyword.ace_operator { }.ace-cobalt .ace_constant { color:#FF628C;}.ace-cobalt .ace_constant.ace_language { }.ace-cobalt .ace_constant.ace_library { }.ace-cobalt .ace_constant.ace_numeric { }.ace-cobalt .ace_invalid { color:#F8F8F8;background-color:#800F00;}.ace-cobalt .ace_invalid.ace_illegal { }.ace-cobalt .ace_invalid.ace_deprecated { }.ace-cobalt .ace_support { color:#80FFBB;}.ace-cobalt .ace_support.ace_function { color:#FFB054;}.ace-cobalt .ace_function.ace_buildin { }.ace-cobalt .ace_string { }.ace-cobalt .ace_string.ace_regexp { color:#80FFC2;}.ace-cobalt .ace_comment { font-style:italic;color:#0088FF;}.ace-cobalt .ace_comment.ace_doc { }.ace-cobalt .ace_comment.ace_doc.ace_tag { }.ace-cobalt .ace_variable { color:#CCCCCC;}.ace-cobalt .ace_variable.ace_language { color:#FF80E1;}.ace-cobalt .ace_xml_pe { }.ace-cobalt .ace_meta { }.ace-cobalt .ace_meta.ace_tag { color:#9EFFFF;}.ace-cobalt .ace_meta.ace_tag.ace_input { }.ace-cobalt .ace_entity.ace_other.ace_attribute-name { }.ace-cobalt .ace_markup.ace_underline { text-decoration:underline;}.ace-cobalt .ace_markup.ace_heading { color:#C8E4FD;background-color:#001221;}.ace-cobalt .ace_markup.ace_heading.ace_1 { }.ace-cobalt .ace_markup.ace_heading.ace_2 { }.ace-cobalt .ace_markup.ace_heading.ace_3 { }.ace-cobalt .ace_markup.ace_heading.ace_4 { }.ace-cobalt .ace_markup.ace_heading.ace_5 { }.ace-cobalt .ace_markup.ace_heading.ace_6 { }.ace-cobalt .ace_markup.ace_list { background-color:#130D26;}.ace-cobalt .ace_collab.ace_user1 { }";d.importCssString(e),b.cssClass="ace-cobalt"}) -------------------------------------------------------------------------------- /test_project/static/ace/theme-crimson_editor.js: -------------------------------------------------------------------------------- 1 | define("ace/theme/crimson_editor",["require","exports","module"],function(a,b,c){var d=a("pilot/dom"),e=".ace-crimson-editor .ace_editor { border: 2px solid rgb(159, 159, 159);}.ace-crimson-editor .ace_editor.ace_focus { border: 2px solid #327fbd;}.ace-crimson-editor .ace_gutter { width: 50px; background: #e8e8e8; color: #333; overflow : hidden;}.ace-crimson-editor .ace_gutter-layer { width: 100%; text-align: right;}.ace-crimson-editor .ace_gutter-layer .ace_gutter-cell { padding-right: 6px;}.ace-crimson-editor .ace_print_margin { width: 1px; background: #e8e8e8;}.ace-crimson-editor .ace_text-layer { cursor: text; color: rgb(64, 64, 64);}.ace-crimson-editor .ace_cursor { border-left: 2px solid black;}.ace-crimson-editor .ace_cursor.ace_overwrite { border-left: 0px; border-bottom: 1px solid black;}.ace-crimson-editor .ace_line .ace_invisible { color: rgb(191, 191, 191);}.ace-crimson-editor .ace_line .ace_identifier { color: black;}.ace-crimson-editor .ace_line .ace_keyword { color: blue;}.ace-crimson-editor .ace_line .ace_constant.ace_buildin { color: rgb(88, 72, 246);}.ace-crimson-editor .ace_line .ace_constant.ace_language { color: rgb(255, 156, 0);}.ace-crimson-editor .ace_line .ace_constant.ace_library { color: rgb(6, 150, 14);}.ace-crimson-editor .ace_line .ace_invalid { text-decoration: line-through; color: rgb(224, 0, 0);}.ace-crimson-editor .ace_line .ace_fold { background-color: #E4E4E4; border-radius: 3px;}.ace-crimson-editor .ace_line .ace_support.ace_function { color: rgb(192, 0, 0);}.ace-crimson-editor .ace_line .ace_support.ace_constant { color: rgb(6, 150, 14);}.ace-crimson-editor .ace_line .ace_support.ace_type,.ace-crimson-editor .ace_line .ace_support.ace_class { color: rgb(109, 121, 222);}.ace-crimson-editor .ace_line .ace_keyword.ace_operator { color: rgb(49, 132, 149);}.ace-crimson-editor .ace_line .ace_string { color: rgb(128, 0, 128);}.ace-crimson-editor .ace_line .ace_comment { color: rgb(76, 136, 107);}.ace-crimson-editor .ace_line .ace_comment.ace_doc { color: rgb(0, 102, 255);}.ace-crimson-editor .ace_line .ace_comment.ace_doc.ace_tag { color: rgb(128, 159, 191);}.ace-crimson-editor .ace_line .ace_constant.ace_numeric { color: rgb(0, 0, 64);}.ace-crimson-editor .ace_line .ace_variable { color: rgb(0, 64, 128);}.ace-crimson-editor .ace_line .ace_xml_pe { color: rgb(104, 104, 91);}.ace-crimson-editor .ace_marker-layer .ace_selection { background: rgb(181, 213, 255);}.ace-crimson-editor .ace_marker-layer .ace_step { background: rgb(252, 255, 0);}.ace-crimson-editor .ace_marker-layer .ace_stack { background: rgb(164, 229, 101);}.ace-crimson-editor .ace_marker-layer .ace_bracket { margin: -1px 0 0 -1px; border: 1px solid rgb(192, 192, 192);}.ace-crimson-editor .ace_marker-layer .ace_active_line { background: rgb(232, 242, 254);}.ace-crimson-editor .ace_meta.ace_tag { color:rgb(28, 2, 255);}.ace-crimson-editor .ace_marker-layer .ace_selected_word { background: rgb(250, 250, 255); border: 1px solid rgb(200, 200, 250);}.ace-crimson-editor .ace_string.ace_regex { color: rgb(192, 0, 192);}";d.importCssString(e),b.cssClass="ace-crimson-editor"}) -------------------------------------------------------------------------------- /test_project/static/ace/theme-dawn.js: -------------------------------------------------------------------------------- 1 | define("ace/theme/dawn",["require","exports","module"],function(a,b,c){var d=a("pilot/dom"),e=".ace-dawn .ace_editor { border: 2px solid rgb(159, 159, 159);}.ace-dawn .ace_editor.ace_focus { border: 2px solid #327fbd;}.ace-dawn .ace_gutter { width: 50px; background: #e8e8e8; color: #333; overflow : hidden;}.ace-dawn .ace_gutter-layer { width: 100%; text-align: right;}.ace-dawn .ace_gutter-layer .ace_gutter-cell { padding-right: 6px;}.ace-dawn .ace_print_margin { width: 1px; background: #e8e8e8;}.ace-dawn .ace_scroller { background-color: #F9F9F9;}.ace-dawn .ace_text-layer { cursor: text; color: #080808;}.ace-dawn .ace_cursor { border-left: 2px solid #000000;}.ace-dawn .ace_cursor.ace_overwrite { border-left: 0px; border-bottom: 1px solid #000000;} .ace-dawn .ace_marker-layer .ace_selection { background: rgba(39, 95, 255, 0.30);}.ace-dawn .ace_marker-layer .ace_step { background: rgb(198, 219, 174);}.ace-dawn .ace_marker-layer .ace_bracket { margin: -1px 0 0 -1px; border: 1px solid rgba(75, 75, 126, 0.50);}.ace-dawn .ace_marker-layer .ace_active_line { background: rgba(36, 99, 180, 0.12);} .ace-dawn .ace_invisible { color: rgba(75, 75, 126, 0.50);}.ace-dawn .ace_keyword { color:#794938;}.ace-dawn .ace_keyword.ace_operator { }.ace-dawn .ace_constant { color:#811F24;}.ace-dawn .ace_constant.ace_language { }.ace-dawn .ace_constant.ace_library { }.ace-dawn .ace_constant.ace_numeric { }.ace-dawn .ace_invalid { }.ace-dawn .ace_invalid.ace_illegal { text-decoration:underline;font-style:italic;color:#F8F8F8;background-color:#B52A1D;}.ace-dawn .ace_invalid.ace_deprecated { text-decoration:underline;font-style:italic;color:#B52A1D;}.ace-dawn .ace_support { color:#691C97;}.ace-dawn .ace_support.ace_function { color:#693A17;}.ace-dawn .ace_function.ace_buildin { }.ace-dawn .ace_string { color:#0B6125;}.ace-dawn .ace_string.ace_regexp { color:#CF5628;}.ace-dawn .ace_comment { font-style:italic;color:#5A525F;}.ace-dawn .ace_comment.ace_doc { }.ace-dawn .ace_comment.ace_doc.ace_tag { }.ace-dawn .ace_variable { color:#234A97;}.ace-dawn .ace_variable.ace_language { }.ace-dawn .ace_xml_pe { }.ace-dawn .ace_meta { }.ace-dawn .ace_meta.ace_tag { }.ace-dawn .ace_meta.ace_tag.ace_input { }.ace-dawn .ace_entity.ace_other.ace_attribute-name { }.ace-dawn .ace_markup.ace_underline { text-decoration:underline;}.ace-dawn .ace_markup.ace_heading { color:#19356D;}.ace-dawn .ace_markup.ace_heading.ace_1 { }.ace-dawn .ace_markup.ace_heading.ace_2 { }.ace-dawn .ace_markup.ace_heading.ace_3 { }.ace-dawn .ace_markup.ace_heading.ace_4 { }.ace-dawn .ace_markup.ace_heading.ace_5 { }.ace-dawn .ace_markup.ace_heading.ace_6 { }.ace-dawn .ace_markup.ace_list { color:#693A17;}.ace-dawn .ace_collab.ace_user1 { }";d.importCssString(e),b.cssClass="ace-dawn"}) -------------------------------------------------------------------------------- /test_project/static/ace/theme-eclipse.js: -------------------------------------------------------------------------------- 1 | define("ace/theme/eclipse",["require","exports","module"],function(a,b,c){var d=a("pilot/dom"),e=".ace-eclipse .ace_editor { border: 2px solid rgb(159, 159, 159);}.ace-eclipse .ace_editor.ace_focus { border: 2px solid #327fbd;}.ace-eclipse .ace_gutter { width: 50px; background: rgb(227, 227, 227); border-right: 1px solid rgb(159, 159, 159);\t color: rgb(136, 136, 136);}.ace-eclipse .ace_gutter-layer { width: 100%; text-align: right;}.ace-eclipse .ace_gutter-layer .ace_gutter-cell { padding-right: 6px;}.ace-eclipse .ace_text-layer { cursor: text;}.ace-eclipse .ace_cursor { border-left: 1px solid black;}.ace-eclipse .ace_line .ace_keyword, .ace-eclipse .ace_line .ace_variable { color: rgb(127, 0, 85);}.ace-eclipse .ace_line .ace_constant.ace_buildin { color: rgb(88, 72, 246);}.ace-eclipse .ace_line .ace_constant.ace_library { color: rgb(6, 150, 14);}.ace-eclipse .ace_line .ace_function { color: rgb(60, 76, 114);}.ace-eclipse .ace_line .ace_string { color: rgb(42, 0, 255);}.ace-eclipse .ace_line .ace_comment { color: rgb(63, 127, 95);}.ace-eclipse .ace_line .ace_comment.ace_doc { color: rgb(63, 95, 191);}.ace-eclipse .ace_line .ace_comment.ace_doc.ace_tag { color: rgb(127, 159, 191);}.ace-eclipse .ace_line .ace_constant.ace_numeric {}.ace-eclipse .ace_line .ace_tag { color: rgb(63, 127, 127);}.ace-eclipse .ace_line .ace_type { color: rgb(127, 0, 127);}.ace-eclipse .ace_line .ace_xml_pe { color: rgb(104, 104, 91);}.ace-eclipse .ace_marker-layer .ace_selection { background: rgb(181, 213, 255);}.ace-eclipse .ace_marker-layer .ace_bracket { margin: -1px 0 0 -1px; border: 1px solid rgb(192, 192, 192);}.ace-eclipse .ace_line .ace_meta.ace_tag { color:rgb(63, 127, 127);}.ace-eclipse .ace_entity.ace_other.ace_attribute-name { color:rgb(127, 0, 127);}.ace-eclipse .ace_marker-layer .ace_active_line { background: rgb(232, 242, 254);}";d.importCssString(e),b.cssClass="ace-eclipse"}) -------------------------------------------------------------------------------- /test_project/static/ace/theme-idle_fingers.js: -------------------------------------------------------------------------------- 1 | define("ace/theme/idle_fingers",["require","exports","module"],function(a,b,c){var d=a("pilot/dom"),e=".ace-idle-fingers .ace_editor { border: 2px solid rgb(159, 159, 159);}.ace-idle-fingers .ace_editor.ace_focus { border: 2px solid #327fbd;}.ace-idle-fingers .ace_gutter { width: 50px; background: #e8e8e8; color: #333; overflow : hidden;}.ace-idle-fingers .ace_gutter-layer { width: 100%; text-align: right;}.ace-idle-fingers .ace_gutter-layer .ace_gutter-cell { padding-right: 6px;}.ace-idle-fingers .ace_print_margin { width: 1px; background: #e8e8e8;}.ace-idle-fingers .ace_scroller { background-color: #323232;}.ace-idle-fingers .ace_text-layer { cursor: text; color: #FFFFFF;}.ace-idle-fingers .ace_cursor { border-left: 2px solid #91FF00;}.ace-idle-fingers .ace_cursor.ace_overwrite { border-left: 0px; border-bottom: 1px solid #91FF00;} .ace-idle-fingers .ace_marker-layer .ace_selection { background: rgba(90, 100, 126, 0.88);}.ace-idle-fingers .ace_marker-layer .ace_step { background: rgb(198, 219, 174);}.ace-idle-fingers .ace_marker-layer .ace_bracket { margin: -1px 0 0 -1px; border: 1px solid #404040;}.ace-idle-fingers .ace_marker-layer .ace_active_line { background: #353637;} .ace-idle-fingers .ace_invisible { color: #404040;}.ace-idle-fingers .ace_keyword { color:#CC7833;}.ace-idle-fingers .ace_keyword.ace_operator { }.ace-idle-fingers .ace_constant { color:#6C99BB;}.ace-idle-fingers .ace_constant.ace_language { }.ace-idle-fingers .ace_constant.ace_library { }.ace-idle-fingers .ace_constant.ace_numeric { }.ace-idle-fingers .ace_invalid { color:#FFFFFF;background-color:#FF0000;}.ace-idle-fingers .ace_invalid.ace_illegal { }.ace-idle-fingers .ace_invalid.ace_deprecated { }.ace-idle-fingers .ace_support { }.ace-idle-fingers .ace_support.ace_function { color:#B83426;}.ace-idle-fingers .ace_function.ace_buildin { }.ace-idle-fingers .ace_string { color:#A5C261;}.ace-idle-fingers .ace_string.ace_regexp { color:#CCCC33;}.ace-idle-fingers .ace_comment { font-style:italic;color:#BC9458;}.ace-idle-fingers .ace_comment.ace_doc { }.ace-idle-fingers .ace_comment.ace_doc.ace_tag { }.ace-idle-fingers .ace_variable { }.ace-idle-fingers .ace_variable.ace_language { }.ace-idle-fingers .ace_xml_pe { }.ace-idle-fingers .ace_meta { }.ace-idle-fingers .ace_meta.ace_tag { color:#FFE5BB;}.ace-idle-fingers .ace_meta.ace_tag.ace_input { }.ace-idle-fingers .ace_entity.ace_other.ace_attribute-name { }.ace-idle-fingers .ace_markup.ace_underline { text-decoration:underline;}.ace-idle-fingers .ace_markup.ace_heading { }.ace-idle-fingers .ace_markup.ace_heading.ace_1 { }.ace-idle-fingers .ace_markup.ace_heading.ace_2 { }.ace-idle-fingers .ace_markup.ace_heading.ace_3 { }.ace-idle-fingers .ace_markup.ace_heading.ace_4 { }.ace-idle-fingers .ace_markup.ace_heading.ace_5 { }.ace-idle-fingers .ace_markup.ace_heading.ace_6 { }.ace-idle-fingers .ace_markup.ace_list { }.ace-idle-fingers .ace_collab.ace_user1 { color:#323232;background-color:#FFF980; }";d.importCssString(e),b.cssClass="ace-idle-fingers"}) -------------------------------------------------------------------------------- /test_project/static/ace/theme-kr_theme.js: -------------------------------------------------------------------------------- 1 | define("ace/theme/kr_theme",["require","exports","module"],function(a,b,c){var d=a("pilot/dom"),e=".ace-kr-theme .ace_editor { border: 2px solid rgb(159, 159, 159);}.ace-kr-theme .ace_editor.ace_focus { border: 2px solid #327fbd;}.ace-kr-theme .ace_gutter { width: 50px; background: #e8e8e8; color: #333; overflow : hidden;}.ace-kr-theme .ace_gutter-layer { width: 100%; text-align: right;}.ace-kr-theme .ace_gutter-layer .ace_gutter-cell { padding-right: 6px;}.ace-kr-theme .ace_print_margin { width: 1px; background: #e8e8e8;}.ace-kr-theme .ace_scroller { background-color: #0B0A09;}.ace-kr-theme .ace_text-layer { cursor: text; color: #FCFFE0;}.ace-kr-theme .ace_cursor { border-left: 2px solid #FF9900;}.ace-kr-theme .ace_cursor.ace_overwrite { border-left: 0px; border-bottom: 1px solid #FF9900;} .ace-kr-theme .ace_marker-layer .ace_selection { background: rgba(170, 0, 255, 0.45);}.ace-kr-theme .ace_marker-layer .ace_step { background: rgb(198, 219, 174);}.ace-kr-theme .ace_marker-layer .ace_bracket { margin: -1px 0 0 -1px; border: 1px solid rgba(255, 177, 111, 0.32);}.ace-kr-theme .ace_marker-layer .ace_active_line { background: #38403D;} .ace-kr-theme .ace_invisible { color: rgba(255, 177, 111, 0.32);}.ace-kr-theme .ace_keyword { color:#949C8B;}.ace-kr-theme .ace_keyword.ace_operator { }.ace-kr-theme .ace_constant { color:rgba(210, 117, 24, 0.76);}.ace-kr-theme .ace_constant.ace_language { }.ace-kr-theme .ace_constant.ace_library { }.ace-kr-theme .ace_constant.ace_numeric { }.ace-kr-theme .ace_invalid { color:#F8F8F8;background-color:#A41300;}.ace-kr-theme .ace_invalid.ace_illegal { }.ace-kr-theme .ace_invalid.ace_deprecated { }.ace-kr-theme .ace_support { color:#9FC28A;}.ace-kr-theme .ace_support.ace_function { color:#85873A;}.ace-kr-theme .ace_function.ace_buildin { }.ace-kr-theme .ace_string { }.ace-kr-theme .ace_string.ace_regexp { color:rgba(125, 255, 192, 0.65);}.ace-kr-theme .ace_comment { font-style:italic;color:#706D5B;}.ace-kr-theme .ace_comment.ace_doc { }.ace-kr-theme .ace_comment.ace_doc.ace_tag { }.ace-kr-theme .ace_variable { color:#D1A796;}.ace-kr-theme .ace_variable.ace_language { color:#FF80E1;}.ace-kr-theme .ace_xml_pe { }.ace-kr-theme .ace_meta { }.ace-kr-theme .ace_meta.ace_tag { color:#BABD9C;}.ace-kr-theme .ace_meta.ace_tag.ace_input { }.ace-kr-theme .ace_entity.ace_other.ace_attribute-name { }.ace-kr-theme .ace_markup.ace_underline { text-decoration:underline;}.ace-kr-theme .ace_markup.ace_heading { }.ace-kr-theme .ace_markup.ace_heading.ace_1 { }.ace-kr-theme .ace_markup.ace_heading.ace_2 { }.ace-kr-theme .ace_markup.ace_heading.ace_3 { }.ace-kr-theme .ace_markup.ace_heading.ace_4 { }.ace-kr-theme .ace_markup.ace_heading.ace_5 { }.ace-kr-theme .ace_markup.ace_heading.ace_6 { }.ace-kr-theme .ace_markup.ace_list { background-color:#0F0040;}.ace-kr-theme .ace_collab.ace_user1 { }";d.importCssString(e),b.cssClass="ace-kr-theme"}) -------------------------------------------------------------------------------- /test_project/static/ace/theme-merbivore.js: -------------------------------------------------------------------------------- 1 | define("ace/theme/merbivore",["require","exports","module"],function(a,b,c){var d=a("pilot/dom"),e=".ace-merbivore .ace_editor { border: 2px solid rgb(159, 159, 159);}.ace-merbivore .ace_editor.ace_focus { border: 2px solid #327fbd;}.ace-merbivore .ace_gutter { width: 50px; background: #e8e8e8; color: #333; overflow : hidden;}.ace-merbivore .ace_gutter-layer { width: 100%; text-align: right;}.ace-merbivore .ace_gutter-layer .ace_gutter-cell { padding-right: 6px;}.ace-merbivore .ace_print_margin { width: 1px; background: #e8e8e8;}.ace-merbivore .ace_scroller { background-color: #161616;}.ace-merbivore .ace_text-layer { cursor: text; color: #E6E1DC;}.ace-merbivore .ace_cursor { border-left: 2px solid #FFFFFF;}.ace-merbivore .ace_cursor.ace_overwrite { border-left: 0px; border-bottom: 1px solid #FFFFFF;} .ace-merbivore .ace_marker-layer .ace_selection { background: #454545;}.ace-merbivore .ace_marker-layer .ace_step { background: rgb(198, 219, 174);}.ace-merbivore .ace_marker-layer .ace_bracket { margin: -1px 0 0 -1px; border: 1px solid #FCE94F;}.ace-merbivore .ace_marker-layer .ace_active_line { background: #333435;} .ace-merbivore .ace_invisible { color: #404040;}.ace-merbivore .ace_keyword { color:#FC6F09;}.ace-merbivore .ace_keyword.ace_operator { }.ace-merbivore .ace_constant { color:#1EDAFB;}.ace-merbivore .ace_constant.ace_language { color:#FDC251;}.ace-merbivore .ace_constant.ace_library { color:#8DFF0A;}.ace-merbivore .ace_constant.ace_numeric { color:#58C554;}.ace-merbivore .ace_invalid { color:#FFFFFF;background-color:#990000;}.ace-merbivore .ace_invalid.ace_illegal { }.ace-merbivore .ace_invalid.ace_deprecated { color:#FFFFFF; background-color:#990000;}.ace-merbivore .ace_support { }.ace-merbivore .ace_support.ace_function { color:#FC6F09;}.ace-merbivore .ace_function.ace_buildin { }.ace-merbivore .ace_string { color:#8DFF0A;}.ace-merbivore .ace_string.ace_regexp { }.ace-merbivore .ace_comment { color:#AD2EA4;}.ace-merbivore .ace_comment.ace_doc { }.ace-merbivore .ace_comment.ace_doc.ace_tag { }.ace-merbivore .ace_variable { }.ace-merbivore .ace_variable.ace_language { }.ace-merbivore .ace_xml_pe { }.ace-merbivore .ace_meta { }.ace-merbivore .ace_meta.ace_tag { color:#FC6F09;}.ace-merbivore .ace_meta.ace_tag.ace_input { }.ace-merbivore .ace_entity.ace_other.ace_attribute-name { color:#FFFF89;}.ace-merbivore .ace_markup.ace_underline { text-decoration:underline;}.ace-merbivore .ace_markup.ace_heading { }.ace-merbivore .ace_markup.ace_heading.ace_1 { }.ace-merbivore .ace_markup.ace_heading.ace_2 { }.ace-merbivore .ace_markup.ace_heading.ace_3 { }.ace-merbivore .ace_markup.ace_heading.ace_4 { }.ace-merbivore .ace_markup.ace_heading.ace_5 { }.ace-merbivore .ace_markup.ace_heading.ace_6 { }.ace-merbivore .ace_markup.ace_list { }.ace-merbivore .ace_collab.ace_user1 { }";d.importCssString(e),b.cssClass="ace-merbivore"}) -------------------------------------------------------------------------------- /test_project/static/ace/theme-merbivore_soft.js: -------------------------------------------------------------------------------- 1 | define("ace/theme/merbivore_soft",["require","exports","module"],function(a,b,c){var d=a("pilot/dom"),e=".ace-merbivore-soft .ace_editor { border: 2px solid rgb(159, 159, 159);}.ace-merbivore-soft .ace_editor.ace_focus { border: 2px solid #327fbd;}.ace-merbivore-soft .ace_gutter { width: 50px; background: #e8e8e8; color: #333; overflow : hidden;}.ace-merbivore-soft .ace_gutter-layer { width: 100%; text-align: right;}.ace-merbivore-soft .ace_gutter-layer .ace_gutter-cell { padding-right: 6px;}.ace-merbivore-soft .ace_print_margin { width: 1px; background: #e8e8e8;}.ace-merbivore-soft .ace_scroller { background-color: #1C1C1C;}.ace-merbivore-soft .ace_text-layer { cursor: text; color: #E6E1DC;}.ace-merbivore-soft .ace_cursor { border-left: 2px solid #FFFFFF;}.ace-merbivore-soft .ace_cursor.ace_overwrite { border-left: 0px; border-bottom: 1px solid #FFFFFF;} .ace-merbivore-soft .ace_marker-layer .ace_selection { background: #494949;}.ace-merbivore-soft .ace_marker-layer .ace_step { background: rgb(198, 219, 174);}.ace-merbivore-soft .ace_marker-layer .ace_bracket { margin: -1px 0 0 -1px; border: 1px solid #FCE94F;}.ace-merbivore-soft .ace_marker-layer .ace_active_line { background: #333435;} .ace-merbivore-soft .ace_invisible { color: #404040;}.ace-merbivore-soft .ace_keyword { color:#FC803A;}.ace-merbivore-soft .ace_keyword.ace_operator { }.ace-merbivore-soft .ace_constant { color:#68C1D8;}.ace-merbivore-soft .ace_constant.ace_language { color:#E1C582;}.ace-merbivore-soft .ace_constant.ace_library { color:#8EC65F;}.ace-merbivore-soft .ace_constant.ace_numeric { color:#7FC578;}.ace-merbivore-soft .ace_invalid { color:#FFFFFF;background-color:#FE3838;}.ace-merbivore-soft .ace_invalid.ace_illegal { }.ace-merbivore-soft .ace_invalid.ace_deprecated { color:#FFFFFF; background-color:#FE3838;}.ace-merbivore-soft .ace_support { }.ace-merbivore-soft .ace_support.ace_function { color:#FC803A;}.ace-merbivore-soft .ace_function.ace_buildin { }.ace-merbivore-soft .ace_string { color:#8EC65F;}.ace-merbivore-soft .ace_string.ace_regexp { }.ace-merbivore-soft .ace_comment { color:#AC4BB8;}.ace-merbivore-soft .ace_comment.ace_doc { }.ace-merbivore-soft .ace_comment.ace_doc.ace_tag { }.ace-merbivore-soft .ace_variable { }.ace-merbivore-soft .ace_variable.ace_language { }.ace-merbivore-soft .ace_xml_pe { }.ace-merbivore-soft .ace_meta { }.ace-merbivore-soft .ace_meta.ace_tag { color:#FC803A;}.ace-merbivore-soft .ace_meta.ace_tag.ace_input { }.ace-merbivore-soft .ace_entity.ace_other.ace_attribute-name { color:#EAF1A3;}.ace-merbivore-soft .ace_markup.ace_underline { text-decoration:underline;}.ace-merbivore-soft .ace_markup.ace_heading { }.ace-merbivore-soft .ace_markup.ace_heading.ace_1 { }.ace-merbivore-soft .ace_markup.ace_heading.ace_2 { }.ace-merbivore-soft .ace_markup.ace_heading.ace_3 { }.ace-merbivore-soft .ace_markup.ace_heading.ace_4 { }.ace-merbivore-soft .ace_markup.ace_heading.ace_5 { }.ace-merbivore-soft .ace_markup.ace_heading.ace_6 { }.ace-merbivore-soft .ace_markup.ace_list { }.ace-merbivore-soft .ace_collab.ace_user1 { }";d.importCssString(e),b.cssClass="ace-merbivore-soft"}) -------------------------------------------------------------------------------- /test_project/static/ace/theme-mono_industrial.js: -------------------------------------------------------------------------------- 1 | define("ace/theme/mono_industrial",["require","exports","module"],function(a,b,c){var d=a("pilot/dom"),e=".ace-mono-industrial .ace_editor { border: 2px solid rgb(159, 159, 159);}.ace-mono-industrial .ace_editor.ace_focus { border: 2px solid #327fbd;}.ace-mono-industrial .ace_gutter { width: 50px; background: #e8e8e8; color: #333; overflow : hidden;}.ace-mono-industrial .ace_gutter-layer { width: 100%; text-align: right;}.ace-mono-industrial .ace_gutter-layer .ace_gutter-cell { padding-right: 6px;}.ace-mono-industrial .ace_print_margin { width: 1px; background: #e8e8e8;}.ace-mono-industrial .ace_scroller { background-color: #222C28;}.ace-mono-industrial .ace_text-layer { cursor: text; color: #FFFFFF;}.ace-mono-industrial .ace_cursor { border-left: 2px solid #FFFFFF;}.ace-mono-industrial .ace_cursor.ace_overwrite { border-left: 0px; border-bottom: 1px solid #FFFFFF;} .ace-mono-industrial .ace_marker-layer .ace_selection { background: rgba(145, 153, 148, 0.40);}.ace-mono-industrial .ace_marker-layer .ace_step { background: rgb(198, 219, 174);}.ace-mono-industrial .ace_marker-layer .ace_bracket { margin: -1px 0 0 -1px; border: 1px solid rgba(102, 108, 104, 0.50);}.ace-mono-industrial .ace_marker-layer .ace_active_line { background: rgba(12, 13, 12, 0.25);} .ace-mono-industrial .ace_invisible { color: rgba(102, 108, 104, 0.50);}.ace-mono-industrial .ace_keyword { color:#A39E64;}.ace-mono-industrial .ace_keyword.ace_operator { color:#A8B3AB;}.ace-mono-industrial .ace_constant { color:#E98800;}.ace-mono-industrial .ace_constant.ace_language { }.ace-mono-industrial .ace_constant.ace_library { }.ace-mono-industrial .ace_constant.ace_numeric { color:#E98800;}.ace-mono-industrial .ace_invalid { color:#FFFFFF;background-color:rgba(153, 0, 0, 0.68);}.ace-mono-industrial .ace_invalid.ace_illegal { }.ace-mono-industrial .ace_invalid.ace_deprecated { }.ace-mono-industrial .ace_support { }.ace-mono-industrial .ace_support.ace_function { color:#588E60;}.ace-mono-industrial .ace_function.ace_buildin { }.ace-mono-industrial .ace_string { }.ace-mono-industrial .ace_string.ace_regexp { }.ace-mono-industrial .ace_comment { color:#666C68;background-color:#151C19;}.ace-mono-industrial .ace_comment.ace_doc { }.ace-mono-industrial .ace_comment.ace_doc.ace_tag { }.ace-mono-industrial .ace_variable { }.ace-mono-industrial .ace_variable.ace_language { color:#648BD2;}.ace-mono-industrial .ace_xml_pe { }.ace-mono-industrial .ace_meta { }.ace-mono-industrial .ace_meta.ace_tag { }.ace-mono-industrial .ace_meta.ace_tag.ace_input { }.ace-mono-industrial .ace_entity.ace_other.ace_attribute-name { color:#909993;}.ace-mono-industrial .ace_markup.ace_underline { text-decoration:underline;}.ace-mono-industrial .ace_markup.ace_heading { }.ace-mono-industrial .ace_markup.ace_heading.ace_1 { }.ace-mono-industrial .ace_markup.ace_heading.ace_2 { }.ace-mono-industrial .ace_markup.ace_heading.ace_3 { }.ace-mono-industrial .ace_markup.ace_heading.ace_4 { }.ace-mono-industrial .ace_markup.ace_heading.ace_5 { }.ace-mono-industrial .ace_markup.ace_heading.ace_6 { }.ace-mono-industrial .ace_markup.ace_list { }.ace-mono-industrial .ace_collab.ace_user1 { }";d.importCssString(e),b.cssClass="ace-mono-industrial"}) -------------------------------------------------------------------------------- /test_project/static/ace/theme-monokai.js: -------------------------------------------------------------------------------- 1 | define("ace/theme/monokai",["require","exports","module"],function(a,b,c){var d=a("pilot/dom"),e=".ace-monokai .ace_editor { border: 2px solid rgb(159, 159, 159);}.ace-monokai .ace_editor.ace_focus { border: 2px solid #327fbd;}.ace-monokai .ace_gutter { width: 50px; background: #e8e8e8; color: #333; overflow : hidden;}.ace-monokai .ace_gutter-layer { width: 100%; text-align: right;}.ace-monokai .ace_gutter-layer .ace_gutter-cell { padding-right: 6px;}.ace-monokai .ace_print_margin { width: 1px; background: #e8e8e8;}.ace-monokai .ace_scroller { background-color: #272822;}.ace-monokai .ace_text-layer { cursor: text; color: #F8F8F2;}.ace-monokai .ace_cursor { border-left: 2px solid #F8F8F0;}.ace-monokai .ace_cursor.ace_overwrite { border-left: 0px; border-bottom: 1px solid #F8F8F0;} .ace-monokai .ace_marker-layer .ace_selection { background: #49483E;}.ace-monokai .ace_marker-layer .ace_step { background: rgb(198, 219, 174);}.ace-monokai .ace_marker-layer .ace_bracket { margin: -1px 0 0 -1px; border: 1px solid #49483E;}.ace-monokai .ace_marker-layer .ace_active_line { background: #49483E;} .ace-monokai .ace_invisible { color: #49483E;}.ace-monokai .ace_keyword { color:#F92672;}.ace-monokai .ace_keyword.ace_operator { }.ace-monokai .ace_constant { }.ace-monokai .ace_constant.ace_language { color:#AE81FF;}.ace-monokai .ace_constant.ace_library { }.ace-monokai .ace_constant.ace_numeric { color:#AE81FF;}.ace-monokai .ace_invalid { color:#F8F8F0;background-color:#F92672;}.ace-monokai .ace_invalid.ace_illegal { }.ace-monokai .ace_invalid.ace_deprecated { color:#F8F8F0;background-color:#AE81FF;}.ace-monokai .ace_support { }.ace-monokai .ace_support.ace_function { color:#66D9EF;}.ace-monokai .ace_function.ace_buildin { }.ace-monokai .ace_string { color:#E6DB74;}.ace-monokai .ace_string.ace_regexp { }.ace-monokai .ace_comment { color:#75715E;}.ace-monokai .ace_comment.ace_doc { }.ace-monokai .ace_comment.ace_doc.ace_tag { }.ace-monokai .ace_variable { }.ace-monokai .ace_variable.ace_language { }.ace-monokai .ace_xml_pe { }.ace-monokai .ace_meta { }.ace-monokai .ace_meta.ace_tag { }.ace-monokai .ace_meta.ace_tag.ace_input { }.ace-monokai .ace_entity.ace_other.ace_attribute-name { color:#A6E22E;}.ace-monokai .ace_markup.ace_underline { text-decoration:underline;}.ace-monokai .ace_markup.ace_heading { }.ace-monokai .ace_markup.ace_heading.ace_1 { }.ace-monokai .ace_markup.ace_heading.ace_2 { }.ace-monokai .ace_markup.ace_heading.ace_3 { }.ace-monokai .ace_markup.ace_heading.ace_4 { }.ace-monokai .ace_markup.ace_heading.ace_5 { }.ace-monokai .ace_markup.ace_heading.ace_6 { }.ace-monokai .ace_markup.ace_list { }.ace-monokai .ace_collab.ace_user1 { }";d.importCssString(e),b.cssClass="ace-monokai"}) -------------------------------------------------------------------------------- /test_project/static/ace/theme-pastel_on_dark.js: -------------------------------------------------------------------------------- 1 | define("ace/theme/pastel_on_dark",["require","exports","module"],function(a,b,c){var d=a("pilot/dom"),e=".ace-pastel-on-dark .ace_editor { border: 2px solid rgb(159, 159, 159);}.ace-pastel-on-dark .ace_editor.ace_focus { border: 2px solid #327fbd;}.ace-pastel-on-dark .ace_gutter { width: 50px; background: #e8e8e8; color: #333; overflow : hidden;}.ace-pastel-on-dark .ace_gutter-layer { width: 100%; text-align: right;}.ace-pastel-on-dark .ace_gutter-layer .ace_gutter-cell { padding-right: 6px;}.ace-pastel-on-dark .ace_print_margin { width: 1px; background: #e8e8e8;}.ace-pastel-on-dark .ace_scroller { background-color: #2c2828;}.ace-pastel-on-dark .ace_text-layer { cursor: text; color: #8f938f;}.ace-pastel-on-dark .ace_cursor { border-left: 2px solid #A7A7A7;}.ace-pastel-on-dark .ace_cursor.ace_overwrite { border-left: 0px; border-bottom: 1px solid #A7A7A7;} .ace-pastel-on-dark .ace_marker-layer .ace_selection { background: rgba(221, 240, 255, 0.20);}.ace-pastel-on-dark .ace_marker-layer .ace_step { background: rgb(198, 219, 174);}.ace-pastel-on-dark .ace_marker-layer .ace_bracket { margin: -1px 0 0 -1px; border: 1px solid rgba(255, 255, 255, 0.25);}.ace-pastel-on-dark .ace_marker-layer .ace_active_line { background: rgba(255, 255, 255, 0.031);} .ace-pastel-on-dark .ace_invisible { color: rgba(255, 255, 255, 0.25);}.ace-pastel-on-dark .ace_keyword { color:#757ad8;}.ace-pastel-on-dark .ace_keyword.ace_operator { color:#797878;}.ace-pastel-on-dark .ace_constant { color:#4fb7c5;}.ace-pastel-on-dark .ace_constant.ace_language { }.ace-pastel-on-dark .ace_constant.ace_library { }.ace-pastel-on-dark .ace_constant.ace_numeric { }.ace-pastel-on-dark .ace_invalid { }.ace-pastel-on-dark .ace_invalid.ace_illegal { color:#F8F8F8;background-color:rgba(86, 45, 86, 0.75);}.ace-pastel-on-dark .ace_invalid.ace_deprecated { text-decoration:underline;font-style:italic;color:#D2A8A1;}.ace-pastel-on-dark .ace_support { color:#9a9a9a;}.ace-pastel-on-dark .ace_support.ace_function { color:#aeb2f8;}.ace-pastel-on-dark .ace_function.ace_buildin { }.ace-pastel-on-dark .ace_string { color:#66a968;}.ace-pastel-on-dark .ace_string.ace_regexp { color:#E9C062;}.ace-pastel-on-dark .ace_comment { color:#656865;}.ace-pastel-on-dark .ace_comment.ace_doc { color:A6C6FF;}.ace-pastel-on-dark .ace_comment.ace_doc.ace_tag { color:A6C6FF;}.ace-pastel-on-dark .ace_variable { color:#bebf55;}.ace-pastel-on-dark .ace_variable.ace_language { color:#bebf55;}.ace-pastel-on-dark .ace_markup.ace_underline { text-decoration:underline;}.ace-pastel-on-dark .ace_xml_pe { color:#494949;}";d.importCssString(e),b.cssClass="ace-pastel-on-dark"}) -------------------------------------------------------------------------------- /test_project/static/ace/theme-solarized_dark.js: -------------------------------------------------------------------------------- 1 | define("ace/theme/solarized_dark",["require","exports","module"],function(a,b,c){var d=a("pilot/dom"),e=".ace-solarized-dark .ace_editor { border: 2px solid rgb(159, 159, 159);}.ace-solarized-dark .ace_editor.ace_focus { border: 2px solid #327fbd;}.ace-solarized-dark .ace_gutter { width: 50px; background: #e8e8e8; color: #333; overflow : hidden;}.ace-solarized-dark .ace_gutter-layer { width: 100%; text-align: right;}.ace-solarized-dark .ace_gutter-layer .ace_gutter-cell { padding-right: 6px;}.ace-solarized-dark .ace_print_margin { width: 1px; background: #e8e8e8;}.ace-solarized-dark .ace_scroller { background-color: #002B36;}.ace-solarized-dark .ace_text-layer { cursor: text; color: #93A1A1;}.ace-solarized-dark .ace_cursor { border-left: 2px solid #D30102;}.ace-solarized-dark .ace_cursor.ace_overwrite { border-left: 0px; border-bottom: 1px solid #D30102;} .ace-solarized-dark .ace_marker-layer .ace_selection { background: #073642;}.ace-solarized-dark .ace_marker-layer .ace_step { background: rgb(198, 219, 174);}.ace-solarized-dark .ace_marker-layer .ace_bracket { margin: -1px 0 0 -1px; border: 1px solid rgba(147, 161, 161, 0.50);}.ace-solarized-dark .ace_marker-layer .ace_active_line { background: #073642;} .ace-solarized-dark .ace_invisible { color: rgba(147, 161, 161, 0.50);}.ace-solarized-dark .ace_keyword { color:#859900;}.ace-solarized-dark .ace_keyword.ace_operator { }.ace-solarized-dark .ace_constant { }.ace-solarized-dark .ace_constant.ace_language { color:#B58900;}.ace-solarized-dark .ace_constant.ace_library { }.ace-solarized-dark .ace_constant.ace_numeric { color:#D33682;}.ace-solarized-dark .ace_invalid { }.ace-solarized-dark .ace_invalid.ace_illegal { }.ace-solarized-dark .ace_invalid.ace_deprecated { }.ace-solarized-dark .ace_support { }.ace-solarized-dark .ace_support.ace_function { color:#268BD2;}.ace-solarized-dark .ace_function.ace_buildin { }.ace-solarized-dark .ace_string { color:#2AA198;}.ace-solarized-dark .ace_string.ace_regexp { color:#D30102;}.ace-solarized-dark .ace_comment { font-style:italic;color:#657B83;}.ace-solarized-dark .ace_comment.ace_doc { }.ace-solarized-dark .ace_comment.ace_doc.ace_tag { }.ace-solarized-dark .ace_variable { }.ace-solarized-dark .ace_variable.ace_language { color:#268BD2;}.ace-solarized-dark .ace_xml_pe { }.ace-solarized-dark .ace_meta { }.ace-solarized-dark .ace_meta.ace_tag { }.ace-solarized-dark .ace_meta.ace_tag.ace_input { }.ace-solarized-dark .ace_entity.ace_other.ace_attribute-name { color:#93A1A1;}.ace-solarized-dark .ace_markup.ace_underline { text-decoration:underline;}.ace-solarized-dark .ace_markup.ace_heading { }.ace-solarized-dark .ace_markup.ace_heading.ace_1 { }.ace-solarized-dark .ace_markup.ace_heading.ace_2 { }.ace-solarized-dark .ace_markup.ace_heading.ace_3 { }.ace-solarized-dark .ace_markup.ace_heading.ace_4 { }.ace-solarized-dark .ace_markup.ace_heading.ace_5 { }.ace-solarized-dark .ace_markup.ace_heading.ace_6 { }.ace-solarized-dark .ace_markup.ace_list { }.ace-solarized-dark .ace_collab.ace_user1 { }";d.importCssString(e),b.cssClass="ace-solarized-dark"}) -------------------------------------------------------------------------------- /test_project/static/ace/theme-solarized_light.js: -------------------------------------------------------------------------------- 1 | define("ace/theme/solarized_light",["require","exports","module"],function(a,b,c){var d=a("pilot/dom"),e=".ace-solarized-light .ace_editor { border: 2px solid rgb(159, 159, 159);}.ace-solarized-light .ace_editor.ace_focus { border: 2px solid #327fbd;}.ace-solarized-light .ace_gutter { width: 50px; background: #e8e8e8; color: #333; overflow : hidden;}.ace-solarized-light .ace_gutter-layer { width: 100%; text-align: right;}.ace-solarized-light .ace_gutter-layer .ace_gutter-cell { padding-right: 6px;}.ace-solarized-light .ace_print_margin { width: 1px; background: #e8e8e8;}.ace-solarized-light .ace_scroller { background-color: #FDF6E3;}.ace-solarized-light .ace_text-layer { cursor: text; color: #586E75;}.ace-solarized-light .ace_cursor { border-left: 2px solid #000000;}.ace-solarized-light .ace_cursor.ace_overwrite { border-left: 0px; border-bottom: 1px solid #000000;} .ace-solarized-light .ace_marker-layer .ace_selection { background: #073642;}.ace-solarized-light .ace_marker-layer .ace_step { background: rgb(198, 219, 174);}.ace-solarized-light .ace_marker-layer .ace_bracket { margin: -1px 0 0 -1px; border: 1px solid rgba(147, 161, 161, 0.50);}.ace-solarized-light .ace_marker-layer .ace_active_line { background: #EEE8D5;} .ace-solarized-light .ace_invisible { color: rgba(147, 161, 161, 0.50);}.ace-solarized-light .ace_keyword { color:#859900;}.ace-solarized-light .ace_keyword.ace_operator { }.ace-solarized-light .ace_constant { }.ace-solarized-light .ace_constant.ace_language { color:#B58900;}.ace-solarized-light .ace_constant.ace_library { }.ace-solarized-light .ace_constant.ace_numeric { color:#D33682;}.ace-solarized-light .ace_invalid { }.ace-solarized-light .ace_invalid.ace_illegal { }.ace-solarized-light .ace_invalid.ace_deprecated { }.ace-solarized-light .ace_support { }.ace-solarized-light .ace_support.ace_function { color:#268BD2;}.ace-solarized-light .ace_function.ace_buildin { }.ace-solarized-light .ace_string { color:#2AA198;}.ace-solarized-light .ace_string.ace_regexp { color:#D30102;}.ace-solarized-light .ace_comment { color:#93A1A1;}.ace-solarized-light .ace_comment.ace_doc { }.ace-solarized-light .ace_comment.ace_doc.ace_tag { }.ace-solarized-light .ace_variable { }.ace-solarized-light .ace_variable.ace_language { color:#268BD2;}.ace-solarized-light .ace_xml_pe { }.ace-solarized-light .ace_meta { }.ace-solarized-light .ace_meta.ace_tag { }.ace-solarized-light .ace_meta.ace_tag.ace_input { }.ace-solarized-light .ace_entity.ace_other.ace_attribute-name { color:#93A1A1;}.ace-solarized-light .ace_markup.ace_underline { text-decoration:underline;}.ace-solarized-light .ace_markup.ace_heading { }.ace-solarized-light .ace_markup.ace_heading.ace_1 { }.ace-solarized-light .ace_markup.ace_heading.ace_2 { }.ace-solarized-light .ace_markup.ace_heading.ace_3 { }.ace-solarized-light .ace_markup.ace_heading.ace_4 { }.ace-solarized-light .ace_markup.ace_heading.ace_5 { }.ace-solarized-light .ace_markup.ace_heading.ace_6 { }.ace-solarized-light .ace_markup.ace_list { }.ace-solarized-light .ace_collab.ace_user1 { }";d.importCssString(e),b.cssClass="ace-solarized-light"}) -------------------------------------------------------------------------------- /test_project/static/ace/theme-textmate.js: -------------------------------------------------------------------------------- 1 | define("ace/theme/textmate",["require","exports","module"],function(a,b,c){var d=a("pilot/dom"),e=".ace-tm .ace_editor { border: 2px solid rgb(159, 159, 159);}.ace-tm .ace_editor.ace_focus { border: 2px solid #327fbd;}.ace-tm .ace_gutter { width: 50px; background: #e8e8e8; color: #333; overflow : hidden;}.ace-tm .ace_gutter-layer { width: 100%; text-align: right;}.ace-tm .ace_gutter-layer .ace_gutter-cell { padding-right: 6px;}.ace-tm .ace_print_margin { width: 1px; background: #e8e8e8;}.ace-tm .ace_text-layer { cursor: text;}.ace-tm .ace_cursor { border-left: 2px solid black;}.ace-tm .ace_cursor.ace_overwrite { border-left: 0px; border-bottom: 1px solid black;} .ace-tm .ace_line .ace_invisible { color: rgb(191, 191, 191);}.ace-tm .ace_line .ace_keyword { color: blue;}.ace-tm .ace_line .ace_constant.ace_buildin { color: rgb(88, 72, 246);}.ace-tm .ace_line .ace_constant.ace_language { color: rgb(88, 92, 246);}.ace-tm .ace_line .ace_constant.ace_library { color: rgb(6, 150, 14);}.ace-tm .ace_line .ace_invalid { background-color: rgb(153, 0, 0); color: white;}.ace-tm .ace_line .ace_fold { background-color: #E4E4E4; border-radius: 3px;}.ace-tm .ace_line .ace_support.ace_function { color: rgb(60, 76, 114);}.ace-tm .ace_line .ace_support.ace_constant { color: rgb(6, 150, 14);}.ace-tm .ace_line .ace_support.ace_type,.ace-tm .ace_line .ace_support.ace_class { color: rgb(109, 121, 222);}.ace-tm .ace_line .ace_keyword.ace_operator { color: rgb(104, 118, 135);}.ace-tm .ace_line .ace_string { color: rgb(3, 106, 7);}.ace-tm .ace_line .ace_comment { color: rgb(76, 136, 107);}.ace-tm .ace_line .ace_comment.ace_doc { color: rgb(0, 102, 255);}.ace-tm .ace_line .ace_comment.ace_doc.ace_tag { color: rgb(128, 159, 191);}.ace-tm .ace_line .ace_constant.ace_numeric { color: rgb(0, 0, 205);}.ace-tm .ace_line .ace_variable { color: rgb(49, 132, 149);}.ace-tm .ace_line .ace_xml_pe { color: rgb(104, 104, 91);}.ace-tm .ace_markup.ace_underline { text-decoration:underline;}.ace-tm .ace_markup.ace_heading { color: rgb(12, 7, 255);}.ace-tm .ace_markup.ace_list { color:rgb(185, 6, 144);}.ace-tm .ace_marker-layer .ace_selection { background: rgb(181, 213, 255);}.ace-tm .ace_marker-layer .ace_step { background: rgb(252, 255, 0);}.ace-tm .ace_marker-layer .ace_stack { background: rgb(164, 229, 101);}.ace-tm .ace_marker-layer .ace_bracket { margin: -1px 0 0 -1px; border: 1px solid rgb(192, 192, 192);}.ace-tm .ace_marker-layer .ace_active_line { background: rgba(0, 0, 0, 0.07);}.ace-tm .ace_marker-layer .ace_selected_word { background: rgb(250, 250, 255); border: 1px solid rgb(200, 200, 250);}.ace-tm .ace_meta.ace_tag { color:rgb(28, 2, 255);}.ace-tm .ace_string.ace_regex { color: rgb(255, 0, 0)}";d.importCssString(e),b.cssClass="ace-tm"}) -------------------------------------------------------------------------------- /test_project/static/ace/theme-twilight.js: -------------------------------------------------------------------------------- 1 | define("ace/theme/twilight",["require","exports","module"],function(a,b,c){var d=a("pilot/dom"),e=".ace-twilight .ace_editor { border: 2px solid rgb(159, 159, 159);}.ace-twilight .ace_editor.ace_focus { border: 2px solid #327fbd;}.ace-twilight .ace_gutter { width: 50px; background: #e8e8e8; color: #333; overflow : hidden;}.ace-twilight .ace_gutter-layer { width: 100%; text-align: right;}.ace-twilight .ace_gutter-layer .ace_gutter-cell { padding-right: 6px;}.ace-twilight .ace_print_margin { width: 1px; background: #e8e8e8;}.ace-twilight .ace_scroller { background-color: #141414;}.ace-twilight .ace_text-layer { cursor: text; color: #F8F8F8;}.ace-twilight .ace_cursor { border-left: 2px solid #A7A7A7;}.ace-twilight .ace_cursor.ace_overwrite { border-left: 0px; border-bottom: 1px solid #A7A7A7;} .ace-twilight .ace_marker-layer .ace_selection { background: rgba(221, 240, 255, 0.20);}.ace-twilight .ace_marker-layer .ace_step { background: rgb(198, 219, 174);}.ace-twilight .ace_marker-layer .ace_bracket { margin: -1px 0 0 -1px; border: 1px solid rgba(255, 255, 255, 0.25);}.ace-twilight .ace_marker-layer .ace_active_line { background: rgba(255, 255, 255, 0.031);} .ace-twilight .ace_invisible { color: rgba(255, 255, 255, 0.25);}.ace-twilight .ace_keyword { color:#CDA869;}.ace-twilight .ace_keyword.ace_operator { }.ace-twilight .ace_constant { color:#CF6A4C;}.ace-twilight .ace_constant.ace_language { }.ace-twilight .ace_constant.ace_library { }.ace-twilight .ace_constant.ace_numeric { }.ace-twilight .ace_invalid { }.ace-twilight .ace_invalid.ace_illegal { color:#F8F8F8;background-color:rgba(86, 45, 86, 0.75);}.ace-twilight .ace_invalid.ace_deprecated { text-decoration:underline;font-style:italic;color:#D2A8A1;}.ace-twilight .ace_support { color:#9B859D;}.ace-twilight .ace_support.ace_function { color:#DAD085;}.ace-twilight .ace_function.ace_buildin { }.ace-twilight .ace_string { color:#8F9D6A;}.ace-twilight .ace_string.ace_regexp { color:#E9C062;}.ace-twilight .ace_comment { font-style:italic;color:#5F5A60;}.ace-twilight .ace_comment.ace_doc { }.ace-twilight .ace_comment.ace_doc.ace_tag { }.ace-twilight .ace_variable { color:#7587A6;}.ace-twilight .ace_variable.ace_language { }.ace-twilight .ace_xml_pe { color:#494949;}.ace-twilight .ace_meta { }.ace-twilight .ace_meta.ace_tag { color:#AC885B;}.ace-twilight .ace_meta.ace_tag.ace_input { }.ace-twilight .ace_entity.ace_other.ace_attribute-name { }.ace-twilight .ace_markup.ace_underline { text-decoration:underline;}.ace-twilight .ace_markup.ace_heading { color:#CF6A4C;}.ace-twilight .ace_markup.ace_heading.ace_1 { }.ace-twilight .ace_markup.ace_heading.ace_2 { }.ace-twilight .ace_markup.ace_heading.ace_3 { }.ace-twilight .ace_markup.ace_heading.ace_4 { }.ace-twilight .ace_markup.ace_heading.ace_5 { }.ace-twilight .ace_markup.ace_heading.ace_6 { }.ace-twilight .ace_markup.ace_list { color:#F9EE98;}.ace-twilight .ace_collab.ace_user1 { }";d.importCssString(e),b.cssClass="ace-twilight"}) -------------------------------------------------------------------------------- /test_project/static/ace/theme-vibrant_ink.js: -------------------------------------------------------------------------------- 1 | define("ace/theme/vibrant_ink",["require","exports","module"],function(a,b,c){var d=a("pilot/dom"),e=".ace-vibrant-ink .ace_editor { border: 2px solid rgb(159, 159, 159);}.ace-vibrant-ink .ace_editor.ace_focus { border: 2px solid #327fbd;}.ace-vibrant-ink .ace_gutter { width: 50px; background: #e8e8e8; color: #333; overflow : hidden;}.ace-vibrant-ink .ace_gutter-layer { width: 100%; text-align: right;}.ace-vibrant-ink .ace_gutter-layer .ace_gutter-cell { padding-right: 6px;}.ace-vibrant-ink .ace_print_margin { width: 1px; background: #e8e8e8;}.ace-vibrant-ink .ace_scroller { background-color: #0F0F0F;}.ace-vibrant-ink .ace_text-layer { cursor: text; color: #FFFFFF;}.ace-vibrant-ink .ace_cursor { border-left: 2px solid #FFFFFF;}.ace-vibrant-ink .ace_cursor.ace_overwrite { border-left: 0px; border-bottom: 1px solid #FFFFFF;} .ace-vibrant-ink .ace_marker-layer .ace_selection { background: #6699CC;}.ace-vibrant-ink .ace_marker-layer .ace_step { background: rgb(198, 219, 174);}.ace-vibrant-ink .ace_marker-layer .ace_bracket { margin: -1px 0 0 -1px; border: 1px solid #99CC99;}.ace-vibrant-ink .ace_marker-layer .ace_active_line { background: #333333;} .ace-vibrant-ink .ace_invisible { color: #404040;}.ace-vibrant-ink .ace_keyword { color:#FF6600;}.ace-vibrant-ink .ace_keyword.ace_operator { }.ace-vibrant-ink .ace_constant { }.ace-vibrant-ink .ace_constant.ace_language { color:#339999;}.ace-vibrant-ink .ace_constant.ace_library { }.ace-vibrant-ink .ace_constant.ace_numeric { color:#99CC99;}.ace-vibrant-ink .ace_invalid { color:#CCFF33; background-color:#000000;}.ace-vibrant-ink .ace_invalid.ace_illegal { }.ace-vibrant-ink .ace_invalid.ace_deprecated { color:#CCFF33; background-color:#000000;}.ace-vibrant-ink .ace_support { }.ace-vibrant-ink .ace_support.ace_function { color:#FFCC00;}.ace-vibrant-ink .ace_function.ace_buildin { }.ace-vibrant-ink .ace_string { color:#66FF00;}.ace-vibrant-ink .ace_string.ace_regexp { color:#44B4CC;}.ace-vibrant-ink .ace_comment { color:#9933CC;}.ace-vibrant-ink .ace_comment.ace_doc { }.ace-vibrant-ink .ace_comment.ace_doc.ace_tag { }.ace-vibrant-ink .ace_variable { }.ace-vibrant-ink .ace_variable.ace_language { }.ace-vibrant-ink .ace_xml_pe { }.ace-vibrant-ink .ace_meta { }.ace-vibrant-ink .ace_meta.ace_tag { }.ace-vibrant-ink .ace_meta.ace_tag.ace_input { }.ace-vibrant-ink .ace_entity.ace_other.ace_attribute-name { font-style:italic;color:#99CC99;}.ace-vibrant-ink .ace_markup.ace_underline { text-decoration:underline;}.ace-vibrant-ink .ace_markup.ace_heading { }.ace-vibrant-ink .ace_markup.ace_heading.ace_1 { }.ace-vibrant-ink .ace_markup.ace_heading.ace_2 { }.ace-vibrant-ink .ace_markup.ace_heading.ace_3 { }.ace-vibrant-ink .ace_markup.ace_heading.ace_4 { }.ace-vibrant-ink .ace_markup.ace_heading.ace_5 { }.ace-vibrant-ink .ace_markup.ace_heading.ace_6 { }.ace-vibrant-ink .ace_markup.ace_list { }.ace-vibrant-ink .ace_collab.ace_user1 { }";d.importCssString(e),b.cssClass="ace-vibrant-ink"}) -------------------------------------------------------------------------------- /test_project/templates/base.html: -------------------------------------------------------------------------------- 1 | Title here. 2 | 3 | {% block content %}Comes before {% endblock %} 4 | -------------------------------------------------------------------------------- /test_project/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls.defaults import patterns, include, url 2 | from django.contrib.staticfiles.urls import staticfiles_urlpatterns 3 | from django.conf import settings 4 | 5 | from django.contrib import admin 6 | admin.autodiscover() 7 | 8 | import views 9 | 10 | urlpatterns = patterns('', 11 | url(r'^admin/', include(admin.site.urls)), 12 | url(r'^themes/', include('themes.urls')), 13 | url(r'^$', views.home, name='home'), 14 | ) 15 | 16 | #urlpatterns += staticfiles_urlpatterns() 17 | urlpatterns += patterns('', 18 | (r'^static/(?P.*)$', 'django.views.static.serve', 19 | {'document_root': settings.STATICFILES_DIRS[0], 'show_indexes': True}), 20 | ) 21 | 22 | -------------------------------------------------------------------------------- /test_project/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render_to_response 2 | from django.template import RequestContext 3 | 4 | from themes.registration import register_template 5 | from themes.models import Theme 6 | 7 | def home(request): 8 | return render_to_response('%s:home'%request.theme.name, {}, 9 | context_instance=RequestContext(request)) 10 | 11 | register_template('base', mirroring='base.html') 12 | register_template('home') 13 | register_template('contact') 14 | register_template('about') 15 | 16 | def choose_theme(request): 17 | if request.user.is_authenticated(): 18 | try: 19 | return Theme.objects.filter(is_default=False)[0] 20 | except IndexError: 21 | return None 22 | 23 | -------------------------------------------------------------------------------- /themes/__init__.py: -------------------------------------------------------------------------------- 1 | __version__ = '0.1' 2 | __author__ = 'Marinho Brandao' 3 | __url__ = 'https://github.com/marinho/django-themes' 4 | __license__ = 'MIT' 5 | 6 | -------------------------------------------------------------------------------- /themes/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | from models import Theme, ThemeTemplate, ThemeStaticFile 4 | 5 | class AdminTheme(admin.ModelAdmin): 6 | list_filters = ('is_default',) 7 | list_display = ('name','verbose_name','is_default',) 8 | admin.site.register(Theme, AdminTheme) 9 | 10 | class AdminThemeTemplate(admin.ModelAdmin): 11 | list_filters = ('theme',) 12 | list_display = ('name','theme',) 13 | admin.site.register(ThemeTemplate, AdminThemeTemplate) 14 | 15 | class AdminThemeStaticFile(admin.ModelAdmin): 16 | list_filters = ('theme',) 17 | list_display = ('name','theme',) 18 | admin.site.register(ThemeStaticFile, AdminThemeStaticFile) 19 | 20 | -------------------------------------------------------------------------------- /themes/app_settings.py: -------------------------------------------------------------------------------- 1 | try: 2 | from django.conf import settings 3 | except ImportError: 4 | settings = None 5 | 6 | # It could be 'jinja2.Template' or any other 7 | DEFAULT_ENGINE = getattr(settings, 'THEMES_DEFAULT_ENGINE', 'themes.engines.DjangoTemplate') 8 | 9 | BASE_TEMPLATE = getattr(settings, 'THEMES_BASE_TEMPLATE', 'base_themes.html') 10 | AVAILABLE_LOADS = getattr(settings, 'THEMES_AVAILABLE_LOADS', '*') # or a tuple 11 | AVAILABLE_TAGS = getattr(settings, 'THEMES_AVAILABLE_TAGS', '*') # or a tuple 12 | AVAILABLE_FILTERS = getattr(settings, 'THEMES_AVAILABLE_FILTERS', '*') # or a tuple 13 | AVAILABLE_INCLUDES = getattr(settings, 'THEMES_AVAILABLE_INCLUDES', '*') # or a tuple 14 | 15 | # Used to block variable from template context processors to ensure security 16 | EXCLUDED_VARIABLES = getattr(settings, 'THEMES_EXCLUDED_VARIABLES', None) # or a tuple 17 | 18 | # If True, returns '' instead of TemplateDoesNotExist 19 | STATIC_NOT_FOUND_RETURNS_EMPTY = getattr(settings, 'THEMES_STATIC_NOT_FOUND_RETURNS_EMPTY', False) 20 | 21 | # A string with the path of a function to receive the request as argument and return the current 22 | # Theme. This is important to choose which Theme must be used in the request (for instance, the 23 | # developer can use the URL pattern, the host name, or any other criteria for that. 24 | CHOOSING_FUNCTION = getattr(settings, 'THEMES_CHOOSING_FUNCTION', 'themes.views.choose_theme') 25 | CURRENT_THEME_COOKIE = getattr(settings, 'THEMES_CURRENT_THEME_COOKIE', '_current_theme') 26 | 27 | CACHE_EXPIRATION = getattr(settings, 'THEMES_CACHE_EXPIRATION', 1) #60 * 60 * 24) 28 | 29 | ALLOW_NOT_REGISTERED = getattr(settings, 'THEMES_ALLOW_NOT_REGISTERED', False) 30 | 31 | -------------------------------------------------------------------------------- /themes/engines.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | from django.template import get_library, import_library, InvalidTemplateLibrary, Template 4 | from django.template.context import RequestContext 5 | 6 | import app_settings 7 | from registration import get_registered_template 8 | from exceptions import UnavailableLoad, UnavailableTag, UnavailableFilter, UnavailableInclude 9 | 10 | EXP_TAGS = re.compile('({%[ ]*(extends|include|theme_static_file)[ ]+"(.+?)"[ ]*%})') 11 | EXP_THEME_TAG = re.compile('{%[ ]*load[ ]+theme_static_file[ ]+.+?%}') # FIXME: This is not perfect (the optional space before the %}) 12 | EXP_EXTENDS = re.compile('({%[ ]*extends[ ]+.*?%})') 13 | EXP_AV_LOAD = re.compile('{%[ ]*load[ ]+([\w_ -]+)[ ]*%}') 14 | EXP_AV_TAG = re.compile('{%[ ]*([\w_]+)? ') 15 | EXP_AV_FILTER = re.compile('{{[^}|]+\|([^ %}]+)') 16 | EXP_AV_INCLUDE = re.compile('{%[ ]*include[ ]+"(.+?)"[ ]*%}') 17 | ALL = '*' 18 | DEFAULT_TAGS_NODES = { 19 | 'for': ['endfor','empty'], 20 | 'ifequal': ['else','endifequal'], 21 | 'with': ['endwith'], 22 | 'ifnotequal': ['else','endifnotequal'], 23 | 'ifchanged': ['else','endifchanged'], 24 | 'filter': ['endfilter'], 25 | 'if': ['else','endif'], 26 | 'spaceless': ['endspaceless'], 27 | 'block': ['endblock'], 28 | 'comment': ['endcomment'], 29 | 30 | # i18n 31 | 'blocktrans': ['endblocktrans'], 32 | 33 | # cache 34 | 'cache': ['endcache'], 35 | } 36 | 37 | class DjangoTemplate(Template): 38 | registered_template = None 39 | 40 | def __init__(self, template_string, origin=None, name=''): 41 | self.theme_name, self.template_name = name.split(':') 42 | self.registered_template = get_registered_template(self.template_name, {}) 43 | force_themes_tags = False 44 | 45 | # Treat the values for tags 'extends', 'include' and 'theme_static_file'. 46 | for full, tag, value in EXP_TAGS.findall(template_string): 47 | if ':' not in value: 48 | new_value = full.replace('"'+value+'"', '"%s:%s"'%(self.theme_name, value)) 49 | template_string = template_string.replace(full, new_value) 50 | 51 | if tag == 'theme_static_file': 52 | force_themes_tags = True 53 | 54 | # Forces {% load themes_tag %} if any of its tags are used but there is not loading 55 | if force_themes_tags and not EXP_THEME_TAG.findall(template_string): 56 | # The following 2 lines ensures the {% load %} comes after an {% extends %} tag 57 | f = EXP_EXTENDS.findall(template_string) 58 | pos = (template_string.index(f[0]) + len(f[0])) if f else 0 59 | template_string = template_string[:pos] + '{% load themes_tags %}' + template_string[pos:] 60 | 61 | self.check_allowed_template(template_string) 62 | 63 | super(DjangoTemplate, self).__init__(template_string, origin, name) 64 | 65 | def check_allowed_template(self, template_string): 66 | # Blocks unavailable loads (template tags libraries) 67 | available_loads = (self.registered_template.get('available_loads', None) or 68 | app_settings.AVAILABLE_LOADS or []) 69 | if available_loads != ALL: 70 | available_loads = list(available_loads) 71 | 72 | found = EXP_AV_LOAD.findall(template_string) 73 | if found: 74 | libs = reduce(lambda a,b: a+b, [i.strip().split() for i in found]) 75 | diff = set(filter(bool, libs)).difference(set(filter(bool, available_loads))) 76 | if diff: 77 | raise UnavailableLoad('The load of libraries "%s" is not available.'%'", "'.join(diff)) 78 | 79 | # Blocks unavailable template tags 80 | available_tags = (self.registered_template.get('available_tags', None) or 81 | app_settings.AVAILABLE_TAGS or []) 82 | if available_tags != ALL: 83 | available_tags = list(available_tags) 84 | 85 | # Loads node lists for default tags 86 | for tag in available_tags: 87 | if DEFAULT_TAGS_NODES.get(tag, None): 88 | available_tags.extend(DEFAULT_TAGS_NODES[tag]) 89 | 90 | found = EXP_AV_TAG.findall(template_string) 91 | if found: 92 | diff = set(filter(bool, found)).difference(set(filter(bool, available_tags))) 93 | if diff: 94 | raise UnavailableTag('The template tags "%s" are not available.'%'", "'.join(diff)) 95 | 96 | # Blocks unavailable template filters 97 | available_filters = (self.registered_template.get('available_filters', None) or 98 | app_settings.AVAILABLE_FILTERS or []) 99 | if available_filters != ALL: 100 | available_filters = list(available_filters) 101 | 102 | found = EXP_AV_FILTER.findall(template_string) 103 | if found: 104 | filters = reduce(lambda a,b: a+b, [i.strip().split('|') for i in found]) 105 | filters = filter(bool, [f.split(':')[0] for f in filters]) 106 | diff = set(filter(bool, filters)).difference(set(filter(bool, available_filters))) 107 | if diff: 108 | raise UnavailableFilter('The template filters "%s" are not available.'%'", "'.join(diff)) 109 | 110 | # Blocks unavailable includes 111 | available_includes = (self.registered_template.get('available_includes', None) or 112 | app_settings.AVAILABLE_INCLUDES or []) 113 | if available_includes != ALL: 114 | available_includes = list(available_includes) 115 | 116 | found = EXP_AV_INCLUDE.findall(template_string) 117 | if found: 118 | found = [i.split(':')[-1] for i in found] 119 | diff = set(filter(bool, found)).difference(set(filter(bool, available_includes))) 120 | if diff: 121 | raise UnavailableInclude('The include of template "%s" is not available.'%'", "'.join(diff)) 122 | 123 | def render(self, context): 124 | """ 125 | This is important to treat the block context variables. 126 | """ 127 | 128 | # Creates a new context for this rendering, removing excluded variables 129 | new_context = context.__copy__() 130 | exc_vars = (self.registered_template.get('excluded_variables', None) or 131 | app_settings.EXCLUDED_VARIABLES) 132 | for k in (exc_vars or []): 133 | for d in new_context.dicts: 134 | if k in d: 135 | del d[k] 136 | 137 | return super(DjangoTemplate, self).render(new_context) 138 | 139 | #--------------------------------------------------------------------------------------------- 140 | # The code using Jinja2 was partially copied from the package "django-jinja2loader": 141 | # 142 | # https://github.com/nathforge/django-jinja2loader/blob/master/src/jinja2loader/__init__.py 143 | #--------------------------------------------------------------------------------------------- 144 | 145 | try: 146 | import jinja2 147 | except ImportError: 148 | jinja2 = None 149 | 150 | if jinja2: 151 | def load_django_filters(filters, library_names, use_default_filters): 152 | 153 | if use_default_filters: 154 | library = import_library('django.template.defaultfilters') 155 | 156 | if not library: 157 | raise InvalidTemplateLibrary('Couldn\'t load django.template.defaultfilters') 158 | 159 | # Update the dict for filters that don't already exist, i.e 160 | # jinja2's built-in filters. 161 | filters.update(dict( 162 | (name, value) 163 | for (name, value) 164 | in library.filters.iteritems() 165 | if name not in filters 166 | )) 167 | 168 | for name in library_names: 169 | filters.update(get_library(name).filters) 170 | 171 | 172 | class Jinja2Template(jinja2.Template): 173 | def render(self, context): 174 | context_dict = {} 175 | for dct in context.dicts: 176 | context_dict.update(dct) 177 | return super(Jinja2Template, self).render(context_dict) 178 | 179 | #jinja2_env = jinja2.Environment( 180 | # loader=jinja2.FileSystemLoader(TEMPLATE_DIRS), 181 | # extensions=EXTENSIONS, 182 | # autoescape=True, 183 | #) 184 | # 185 | #load_django_filters( 186 | # jinja2_env.filters, 187 | # library_names=DJANGO_FILTER_LIBRARIES, 188 | # use_default_filters=USE_DEFAULT_DJANGO_FILTERS, 189 | #) 190 | # 191 | #jinja2_env.globals.update(GLOBALS) 192 | #jinja2_env.template_class = Template 193 | 194 | 195 | -------------------------------------------------------------------------------- /themes/exceptions.py: -------------------------------------------------------------------------------- 1 | class NotAllowedTemplate(Exception): pass 2 | class UnavailableLoad(NotAllowedTemplate): pass 3 | class UnavailableTag(NotAllowedTemplate): pass 4 | class UnavailableFilter(NotAllowedTemplate): pass 5 | class UnavailableInclude(NotAllowedTemplate): pass 6 | -------------------------------------------------------------------------------- /themes/loaders.py: -------------------------------------------------------------------------------- 1 | from django.template.loader import BaseLoader, make_origin, get_template 2 | from django.template.base import TemplateDoesNotExist 3 | from django.conf import settings 4 | from django.core.cache import cache 5 | from django.utils.importlib import import_module 6 | from django.core.exceptions import ImproperlyConfigured 7 | 8 | import app_settings 9 | from models import Theme, ThemeTemplate 10 | from registration import get_registered_template 11 | 12 | class Loader(BaseLoader): 13 | is_usable = True 14 | 15 | def load_template(self, template_name, template_dirs=None): 16 | if ':' in template_name: 17 | active_theme, template_name = template_name.split(':', 1) 18 | else: 19 | active_theme = cache.get('themes:active', None) if app_settings.CACHE_EXPIRATION else None 20 | if not active_theme: 21 | try: 22 | theme = Theme.objects.get(is_default=True) 23 | if app_settings.CACHE_EXPIRATION: 24 | cache.set('themes:active', theme.name, app_settings.CACHE_EXPIRATION) 25 | active_theme = theme.name 26 | except Theme.DoesNotExist: 27 | raise TemplateDoesNotExist('There\'s no active theme.') 28 | 29 | try: 30 | reg_template = get_registered_template(template_name) 31 | except KeyError: 32 | if app_settings.ALLOW_NOT_REGISTERED: 33 | reg_template = {} 34 | else: 35 | raise TemplateDoesNotExist('Template "%s" is not registered.'%template_name) 36 | 37 | content = None 38 | full_name = None 39 | engine = None 40 | try: 41 | # Using cache to restore/store template content 42 | cache_key = 'themes:%s|%s'%(active_theme, template_name) 43 | content = cache.get(cache_key, None) if app_settings.CACHE_EXPIRATION else None 44 | 45 | if not content: 46 | tpl = ThemeTemplate.objects.get(theme__name=active_theme, name=template_name) 47 | engine = tpl.engine 48 | content = tpl.content 49 | if app_settings.CACHE_EXPIRATION: 50 | cache.set(cache_key, 'engine:%s;%s'%(engine,content), app_settings.CACHE_EXPIRATION) 51 | 52 | full_name = '%s:%s'%(active_theme, template_name) 53 | except ThemeTemplate.DoesNotExist: 54 | content = None 55 | 56 | if not content: 57 | if reg_template and reg_template.get('mirroring', None): 58 | ret = get_template(reg_template['mirroring']) 59 | content, origin = ret if isinstance(ret, (list,tuple)) else (ret, None) 60 | return content, origin 61 | else: 62 | raise TemplateDoesNotExist('Template "%s" doesn\'t exist in active theme.'%template_name) 63 | 64 | if content.startswith('engine:'): 65 | engine, content = content.split(';', 1) 66 | engine = engine.split(':')[1] 67 | 68 | origin = None 69 | 70 | try: 71 | template_class = get_engine_class(engine or app_settings.DEFAULT_ENGINE) 72 | template = template_class(content, origin, full_name) 73 | 74 | return template, None 75 | except TemplateDoesNotExist: 76 | return content, origin 77 | 78 | 79 | def get_engine_class(path): 80 | if isinstance(path, basestring): 81 | module, attr = path.rsplit('.', 1) 82 | 83 | try: 84 | mod = import_module(module) 85 | except ImportError, e: 86 | raise ImproperlyConfigured('Template engine "%s" was not found.'%path) 87 | 88 | try: 89 | return getattr(mod, attr) 90 | except AttributeError: 91 | raise ImproperlyConfigured('Template engine "%s" was not found.'%path) 92 | 93 | 94 | -------------------------------------------------------------------------------- /themes/middleware.py: -------------------------------------------------------------------------------- 1 | from django.utils.importlib import import_module 2 | from django.core.exceptions import ImproperlyConfigured 3 | 4 | import app_settings 5 | from models import Theme 6 | 7 | class ThemeMiddleware(object): 8 | """Sets the current theme.""" 9 | 10 | def process_request(self, request): 11 | if app_settings.CHOOSING_FUNCTION: 12 | try: 13 | path, func_name = app_settings.CHOOSING_FUNCTION.rsplit('.', 1) 14 | except ValueError: 15 | raise ImproperlyConfigured("Setting THEMES_CHOOSING_FUNCTION has '%s' with a unknown function path."%app_settings.CHOOSING_FUNCTION) 16 | 17 | try: 18 | mod = import_module(path) 19 | except ImportError: 20 | raise ImproperlyConfigured("Module '%s' wasn't found."%path) 21 | 22 | try: 23 | func = getattr(mod, func_name) 24 | except AttributeError: 25 | raise ImproperlyConfigured("Module '%s' hasn't a function called."%func_name) 26 | 27 | request.theme = func(request) 28 | 29 | if not getattr(request, 'theme', None): 30 | try: 31 | request.theme = Theme.objects.get(is_default=True) 32 | except Theme.DoesNotExist: 33 | request.theme = None 34 | 35 | -------------------------------------------------------------------------------- /themes/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.core.cache import cache 3 | from django.utils.translation import ugettext_lazy as _ 4 | 5 | from registration import list_registered_templates 6 | import app_settings 7 | 8 | class ThemeManager(models.Manager): 9 | def get_current(self): 10 | return self.get(is_default=True) # FIXME 11 | 12 | def get_by_natural_key(self, name): 13 | return self.get(name=name) 14 | 15 | class Theme(models.Model): 16 | class Meta: 17 | ordering = ('verbose_name','name',) 18 | permissions = ( 19 | ('import_theme', 'Can import Theme'), 20 | ('download_theme', 'Can download Theme'), 21 | ('set_default_theme', 'Can set default Theme'), 22 | ) 23 | 24 | objects = _default_manager = ThemeManager() 25 | 26 | name = models.CharField(max_length=50, unique=True) 27 | verbose_name = models.CharField(max_length=50, blank=True) 28 | is_default = models.BooleanField(default=False, db_index=True) 29 | 30 | def __unicode__(self): 31 | return self.verbose_name or self.name 32 | 33 | def create_templates(self): 34 | """Creates a template instance for every registered templates.""" 35 | for name, params in list_registered_templates(): 36 | self.templates.get_or_create(name=name) 37 | 38 | def natural_key(self): 39 | return (self.name,) 40 | 41 | 42 | class ThemeTemplateManager(models.Manager): 43 | def get_by_natural_key(self, theme, name): 44 | return self.get(theme__name=theme, name=name) 45 | 46 | class ThemeTemplate(models.Model): 47 | class Meta: 48 | unique_together = (('theme','name'),) 49 | ordering = ('name',) 50 | 51 | objects = _default_manager = ThemeTemplateManager() 52 | 53 | theme = models.ForeignKey('Theme', related_name='templates') 54 | name = models.CharField(max_length=200) 55 | notes = models.TextField(blank=True) 56 | content = models.TextField(blank=True) 57 | engine = models.CharField(max_length=50, blank=True, help_text='A class path string, like "themes.engines.DjangoTemplate" or "themes.engines.Jinja2Template". If empty, setting THEMES_DEFAULT_ENGINE assumes.') 58 | 59 | def __unicode__(self): 60 | return self.name 61 | 62 | def natural_key(self): 63 | return (self.theme.name, self.name) 64 | 65 | class ThemeStaticFileManager(models.Manager): 66 | def get_by_natural_key(self, theme, name): 67 | return self.get(theme__name=theme, name=name) 68 | 69 | class ThemeStaticFile(models.Model): 70 | class Meta: 71 | unique_together = (('theme','name'),) 72 | ordering = ('name',) 73 | 74 | objects = _default_manager = ThemeStaticFileManager() 75 | 76 | theme = models.ForeignKey('Theme', related_name='static_files') 77 | name = models.CharField(max_length=50) 78 | url = models.CharField(max_length=200, blank=True) 79 | file = models.FileField(upload_to='theme-static-files', blank=True, null=True) 80 | mime_type = models.CharField(max_length=50, blank=True) 81 | 82 | def __unicode__(self): 83 | return self.name 84 | 85 | def get_url(self): 86 | return self.url if self.url else self.file.url 87 | 88 | def get_type(self): 89 | return 'url' if self.url else 'file' 90 | 91 | def natural_key(self): 92 | return (self.theme.name, self.name) 93 | 94 | # SIGNALS 95 | from django.db.models import signals 96 | 97 | def theme_post_save(instance, sender, **kwargs): 98 | # Sets the other themes "non-default" if this instance is default. 99 | if instance.is_default: 100 | sender.objects.exclude(pk=instance.pk).update(is_default=False) 101 | 102 | # Creates the available templates for this theme 103 | instance.create_templates() 104 | signals.post_save.connect(theme_post_save, sender=Theme) 105 | 106 | def themetemplate_post_save(instance, sender, **kwargs): 107 | # Cache invalidation 108 | cache_key = 'themes:%s|%s'%(instance.theme.name, instance.name) 109 | if app_settings.CACHE_EXPIRATION and cache.get(cache_key): 110 | cache.set(cache_key, None, 1) # Expires fastly, to clear cache storage 111 | signals.post_save.connect(themetemplate_post_save, sender=ThemeTemplate) 112 | 113 | -------------------------------------------------------------------------------- /themes/packaging.py: -------------------------------------------------------------------------------- 1 | import zipfile 2 | import os 3 | import random 4 | import shutil 5 | import glob 6 | 7 | from django.utils import simplejson 8 | from django.utils.translation import ugettext as _ 9 | from django.core.files.base import ContentFile 10 | 11 | from models import Theme 12 | 13 | def dump_file_name(sf): 14 | try: 15 | return os.path.split(sf.file.name)[-1] 16 | except ValueError: 17 | return None 18 | 19 | def export_theme(theme): 20 | """ 21 | Outputs a zipfile with the theme, its templates and static files. 22 | """ 23 | dir_name = ''.join([random.choice('abcdefghijklmnopqrstuvwxyz') for n in range(20)]) 24 | work_dir = os.path.join('/tmp/', dir_name) 25 | os.makedirs(work_dir) 26 | os.chdir(work_dir) 27 | 28 | zipf_path = os.path.join(work_dir, 'theme-%s.zip'%theme.name) 29 | zipf = zipfile.ZipFile(zipf_path, 'w') 30 | 31 | json = { 32 | 'name': theme.name, 33 | 'verbose_name': theme.verbose_name, 34 | 'templates': [{ 35 | 'name': tpl.name, 36 | 'notes': tpl.notes, 37 | 'content': tpl.content, 38 | 'engine': tpl.engine, 39 | } for tpl in theme.templates.all()], 40 | 'static_files': [{ 41 | 'name': sf.name, 42 | 'url': sf.url, 43 | 'file': dump_file_name(sf), 44 | 'mime_type': sf.mime_type, 45 | } for sf in theme.static_files.all()], 46 | } 47 | jsonf_path = 'details.json' 48 | json_fp = file(jsonf_path, 'w') 49 | json_fp.write(simplejson.dumps(json)) 50 | json_fp.close() 51 | 52 | zipf.write(jsonf_path) 53 | 54 | for sf in theme.static_files.exclude(file__isnull=True).exclude(file=''): 55 | try: 56 | f_name = dump_file_name(sf) 57 | shutil.copyfile(sf.file.path, os.path.join(work_dir, f_name)) 58 | zipf.write(f_name) 59 | except ValueError: 60 | pass 61 | 62 | zipf.close() 63 | 64 | return zipf_path 65 | 66 | def import_theme(zipfp): 67 | # Initializes the working area 68 | dir_name = ''.join([random.choice('abcdefghijklmnopqrstuvwxyz') for n in range(20)]) 69 | work_dir = os.path.join('/tmp/', dir_name) 70 | os.makedirs(work_dir) 71 | os.chdir(work_dir) 72 | 73 | # Opens and extracts the zip file 74 | zipf = zipfile.ZipFile(zipfp) 75 | zipf.extractall() 76 | 77 | # Loads driver JSON file 78 | json_fp = file('details.json') 79 | json = simplejson.loads(json_fp.read()) 80 | json_fp.close() 81 | 82 | # Doesn't allow import existing theme (must delete before) 83 | if Theme.objects.filter(name=json['name']).count(): 84 | raise ValueError(_('Theme "%s" already exists.')%json['name']) 85 | 86 | # Creates the new theme 87 | theme = Theme.objects.create(name=json['name'], verbose_name=json['verbose_name']) 88 | 89 | # Creates the new templates 90 | for json_tpl in json['templates']: 91 | tpl, new = theme.templates.get_or_create(name=json_tpl['name']) 92 | tpl.content = json_tpl['content'] 93 | tpl.notes = json_tpl['notes'] 94 | tpl.engine = json_tpl['engine'] 95 | tpl.save() 96 | 97 | # Creates the new static files 98 | for json_sf in json['static_files']: 99 | sf = theme.static_files.create( 100 | name=json_sf['name'], 101 | url=json_sf['url'], 102 | mime_type=json_sf['mime_type'], 103 | ) 104 | 105 | if json_sf['file']: 106 | fp = file(json_sf['file']) 107 | content = ContentFile(fp.read()) 108 | fp.close() 109 | 110 | file_name = json_sf['file'] 111 | while os.path.exists(file_name): 112 | file_name += '_' 113 | 114 | sf.file.save(file_name, content) 115 | sf.save() 116 | 117 | return theme 118 | 119 | -------------------------------------------------------------------------------- /themes/registration.py: -------------------------------------------------------------------------------- 1 | import app_settings 2 | 3 | _registered_templates = {} 4 | 5 | def register_template(name, **kwargs): 6 | """ 7 | Function responsible to register a template in the _registered_templates dictionary. 8 | 9 | Once a template is registered, the template loader recognizes it and controls its 10 | permissions and available stuff. 11 | 12 | The recognized named arguments are: 13 | 14 | - verbose_name - Default: assumes the name 15 | - default_base_template - Default: assumes app_settings.BASE_TEMPLATE 16 | - mirroring - Default: assumes empty 17 | - available_blocks - Default: assumes empty 18 | - available_vars - Default: assumes empty 19 | - available_loads - Default: assumes app_settings.AVAILABLE_LOADS 20 | - available_tags - Default: assumes app_settings.AVAILABLE_TAGS 21 | - available_filters - Default: assumes app_settings.AVAILABLE_FILTERS 22 | - available_includes - Default: assumes app_settings.AVAILABLE_INCLUDES 23 | - excluded_vars - Default: assumes none (that means all of them are accessible 24 | """ 25 | kwargs['name'] = name 26 | _registered_templates[name] = kwargs 27 | 28 | def get_registered_template(name, *args): 29 | return _registered_templates.get(name, *args) 30 | 31 | def list_registered_templates(): 32 | return _registered_templates.items() 33 | 34 | -------------------------------------------------------------------------------- /themes/templates/themes/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% block title %}{% endblock %} - Themes 5 | 6 | 7 | 8 | 9 | 12 | 13 | {% block extra_head %}{% endblock %} 14 | 15 | 16 | 17 |
    18 | {% for msg in messages %}
  • {{ msg }}
  • {% endfor %} 19 |
20 | 21 | {% block content %}{% endblock %} 22 | 23 | {% block body_scripts %}{% endblock %} 24 | 25 | 26 | -------------------------------------------------------------------------------- /themes/templates/themes/home.html: -------------------------------------------------------------------------------- 1 | {% extends "themes/base.html" %} 2 | 3 | {% load i18n %} 4 | 5 | {% block title %}Home{% endblock %} 6 | 7 | {% block extra_head %}{{ block.super }} 8 | 13 | {% endblock extra_head %} 14 | 15 | {% block content %} 16 |

Themes

17 | 18 |
19 |
20 |
21 |

{% trans "New theme" %}:

22 | {% csrf_token %} 23 | 24 | 25 |
26 | 27 |
28 |

{% trans "Import theme" %}:

29 | {% csrf_token %} 30 | 31 | 32 |
33 |
34 | 35 |
    36 | {% for theme in themes %} 37 |
  • {{ theme }} {% if theme.is_default%}- default{% endif %}
  • 38 | {% endfor %} 39 |
40 | 41 | {% if previewing %} 42 |

43 | {% trans "Previewing" %} - {% trans "Disable previewing mode." %} 44 |

45 | {% endif %} 46 |
47 | 48 | 51 | {% endblock content %} 52 | 53 | {% block body_scripts %}{% endblock %} 54 | 55 | -------------------------------------------------------------------------------- /themes/templates/themes/theme_up_file.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 11 | 12 | 27 | 28 | 29 | 30 |
31 | 32 | Drop files here 33 |
34 | 35 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /themes/templatetags/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marinho/django-themes/4d86f0d4134989995490f6f2f5ec0e8d05d3ff5a/themes/templatetags/__init__.py -------------------------------------------------------------------------------- /themes/templatetags/themes_tags.py: -------------------------------------------------------------------------------- 1 | from django import template 2 | 3 | from themes.models import Theme, ThemeStaticFile 4 | from themes import app_settings 5 | 6 | register = template.Library() 7 | 8 | class ThemeStaticFileNode(template.Node): 9 | name = None 10 | 11 | def __init__(self, name): 12 | self.name = template.Variable(name) 13 | 14 | def render(self, context): 15 | name = self.name.resolve(context) 16 | 17 | if ':' in name: 18 | theme, name = name.split(':', 1) 19 | theme = Theme.objects.get(name=theme) 20 | elif 'request' in context and getattr(context['request'], 'theme', None): 21 | theme = context['request'].theme 22 | else: 23 | theme = Theme.objects.get_current() 24 | 25 | try: 26 | static_file = theme.static_files.get(name=name) 27 | except ThemeStaticFile.DoesNotExist: 28 | if app_settings.STATIC_NOT_FOUND_RETURNS_EMPTY: 29 | return '' 30 | else: 31 | raise 32 | 33 | return static_file.get_url() 34 | 35 | def do_theme_static_file(parser, token): 36 | """ 37 | Examples: 38 | 39 | {% theme_static_file "logo.gif" %} 40 | {% theme_static_file "theme-name:logo.gif" %} 41 | """ 42 | bits = token.split_contents() 43 | return ThemeStaticFileNode(bits[1]) 44 | register.tag('theme_static_file', do_theme_static_file) 45 | 46 | -------------------------------------------------------------------------------- /themes/tests/01.basic.txt: -------------------------------------------------------------------------------- 1 | BASIC 2 | ===== 3 | 4 | The most basic thing is that a project must register the templates it uses. This is 5 | important for security and for a reliable usage of them, because, templates can be 6 | generated and the user is able to know which templates he/she must creates and which 7 | variables are available for each one of them. This ensures as well that the template 8 | loader will load only the theme templates for registered templates, so, it's safer. 9 | 10 | The internal variable to store registered templates is this: 11 | 12 | >>> from djangoplus.test_utils import assert_equal 13 | 14 | >>> from themes.registration import _registered_templates 15 | >>> _registered_templates 16 | {} 17 | 18 | But this is not useful for the developer. He/she must know the function to register them: 19 | 20 | >>> from themes.registration import register_template 21 | 22 | When your project or application registers a template, it just means it needs that 23 | template for something, and it sets everything that template "offers" for theme templates 24 | to be able to use. The "implemented" template is the "Theme Template", used to fill this 25 | registered template for the active theme. 26 | 27 | The most simple template registration is this: 28 | 29 | >>> register_template('contact') 30 | >>> _registered_templates['contact'] 31 | {'name': 'contact'} 32 | 33 | That means it just uses the project's default settings and isn't mirroring any "physical" 34 | template. 35 | 36 | A template mirroring a physical template means that physical one will assume while that 37 | template has not a theme template to assume. 38 | 39 | >>> register_template('about', mirroring='about.html', available_vars=('company_name',)) 40 | >>> _registered_templates['about'] 41 | {'available_vars': ('company_name',), 'name': 'about', 'mirroring': 'about.html'} 42 | 43 | A full example of template registration 44 | 45 | >>> register_template( 46 | ... name='address', 47 | ... verbose_name='Address Page', 48 | ... default_base_template='public/base.html', 49 | ... mirroring='public/address.html', 50 | ... available_blocks=('extra_head', 'title', 'content', 'body_scripts'), 51 | ... available_vars=('form_contact', 'user', 'messages', 'STATIC_URL'), 52 | ... available_loads=('i18n', 'comments'), 53 | ... available_tags=('for', 'if', 'with', 'include', 'extends', 'block'), 54 | ... available_filters='*', 55 | ... available_includes=('user-box', 'messages-box'), 56 | ... excluded_vars=('request', 'perms'), 57 | ... ) 58 | >>> assert_equal(_registered_templates['address'], { 59 | ... 'available_vars': ('form_contact', 'user', 'messages', 'STATIC_URL'), 60 | ... 'available_filters': '*', 'name': 'address', 61 | ... 'available_blocks': ('extra_head', 'title', 'content', 'body_scripts'), 62 | ... 'available_includes': ('user-box', 'messages-box'), 'available_loads': ('i18n', 'comments'), 63 | ... 'mirroring': 'public/address.html', 'default_base_template': 'public/base.html', 64 | ... 'available_tags': ('for', 'if', 'with', 'include', 'extends', 'block'), 65 | ... 'excluded_vars': ('request', 'perms'), 'verbose_name': 'Address Page'}) 66 | 67 | 68 | -------------------------------------------------------------------------------- /themes/tests/02-models.txt: -------------------------------------------------------------------------------- 1 | MODELS 2 | =====- 3 | 4 | The models are structured on 3 model classes: 5 | 6 | --------- 7 | | Theme | 8 | --------- 9 | ^ ^ 10 | 1| |1 11 | ----------- ------------ 12 | *| |* 13 | ----------------- ------------------- 14 | | ThemeTemplate | | ThemeStaticFile | 15 | ----------------- ------------------- 16 | 17 | >>> from djangoplus.test_utils import assert_equal, model_has_fields 18 | 19 | Theme 20 | ----- 21 | 22 | A theme is a set of templates and static files for a defined design style. In CMS systems, 23 | themes usually have names like "White Ivory", "Forest Green", "Matrix", "Technology", 24 | "Modern", etc. But they are more useful for project supporting many different layouts. 25 | 26 | For example: a website with many blogs, each one with a different layout. So, any "layout" 27 | should b a theme. Or a project with multiple sites could vary their themes as well. 28 | 29 | >>> from themes.models import Theme 30 | >>> model_has_fields(Theme, ['name','verbose_name','is_default']) 31 | [] 32 | 33 | >>> theme1 = Theme() 34 | >>> theme1.name = 'default' 35 | >>> theme1.verbose_name = 'Default' 36 | >>> theme1.save() 37 | 38 | >>> print theme1 39 | Default 40 | 41 | >>> theme1.is_default 42 | False 43 | 44 | Only one theme can be default at once. If you set another theme as default, the old one 45 | must change to be 'not' default. 46 | 47 | >>> theme1.is_default = True 48 | >>> theme1.save() 49 | 50 | >>> theme2 = Theme() 51 | >>> theme2.name = 'another-theme' 52 | >>> theme2.verbose_name = 'AnotherTheme' 53 | >>> theme2.is_default = True 54 | >>> theme2.save() 55 | 56 | >>> theme1 = Theme.objects.get(pk=theme1.pk) 57 | 58 | >>> theme1.is_default 59 | False 60 | 61 | ThemeTemplate 62 | ------------- 63 | 64 | Function to create registered templates for a given Theme 65 | 66 | >>> theme1.create_templates() 67 | 68 | >>> theme1.templates.values_list('name', flat=True) 69 | [u'about', u'address', u'contact'] 70 | 71 | Theme template fields 72 | 73 | >>> from themes.models import ThemeTemplate 74 | >>> model_has_fields(ThemeTemplate, ['theme','name','notes','content']) 75 | [] 76 | 77 | Changing the created ones for theme 1 78 | 79 | >>> tpl_about_1 = theme1.templates.get(name='about') 80 | >>> tpl_about_1.content = 'THis is about us' 81 | >>> tpl_about_1.save() 82 | 83 | >>> tpl_address_1 = theme1.templates.get(name='address') 84 | >>> tpl_address_1.content = 'Our address is: 290 Broomhouse Ln' 85 | >>> tpl_address_1.save() 86 | 87 | >>> tpl_contact_1 = theme1.templates.get(name='contact') 88 | >>> tpl_contact_1.content = 'Contact us by e-mail.' 89 | >>> tpl_contact_1.save() 90 | 91 | Changing the created ones for theme 2 92 | 93 | >>> theme2.create_templates() 94 | 95 | >>> tpl_about_2 = theme2.templates.get(name='about') 96 | >>> tpl_about_2.content = 'We are a big company named "{{ company_name }}" working for you' 97 | >>> tpl_about_2.save() 98 | 99 | >>> tpl_address_2 = theme2.templates.get(name='address') 100 | >>> tpl_address_2.content = 'Our store 1 is in the Downtow Shopping Centre' 101 | >>> tpl_address_2.save() 102 | 103 | >>> tpl_contact_2 = theme2.templates.get(name='contact') 104 | >>> tpl_contact_2.content = 'Contact us by phone.' 105 | >>> tpl_contact_2.save() 106 | 107 | ThemeStaticFile 108 | --------------- 109 | 110 | >>> from themes.models import ThemeStaticFile 111 | >>> model_has_fields(ThemeStaticFile, ['theme','name','url','file']) 112 | [] 113 | 114 | >>> st1 = ThemeStaticFile() 115 | >>> st1.theme = theme1 116 | >>> st1.name = 'logo.png' 117 | >>> st1.url = 'http://static.alatazan.com/media2/img/logo-84.png' 118 | >>> st1.save() 119 | 120 | >>> st2 = ThemeStaticFile() 121 | >>> st2.theme = theme2 122 | >>> st2.name = 'logo.png' 123 | >>> st2.url = 'http://media.djangobrasil.org/djangobrasil/images/djangobrasil.png' 124 | >>> st2.save() 125 | 126 | -------------------------------------------------------------------------------- /themes/tests/03-template-loader.txt: -------------------------------------------------------------------------------- 1 | TEMPLATE LOADER 2 | =============== 3 | 4 | The theme template loader is responsible to come before the defautl loaders to recognize 5 | existing templates in the current project (and its applications) and load them for the active 6 | theme (or the mirrored respective ones). 7 | 8 | >>> from djangoplus.test_utils import assert_equal 9 | 10 | >>> from django.template.loader import get_template 11 | >>> about_tpl = get_template('about') 12 | >>> assert_equal(about_tpl.name, 'another-theme:about') 13 | 14 | >>> from django.template.loader import render_to_string 15 | >>> print render_to_string('about', {'company_name': 'Mochii Ltd.'}) 16 | We are a big company named "Mochii Ltd." working for you 17 | 18 | Templates in cache 19 | ------------------ 20 | 21 | >>> from django.core.cache import cache 22 | 23 | Existing in cache 24 | 25 | >>> print cache.get('themes:another-theme|about') 26 | engine:;We are a big company named "{{ company_name }}" working for you 27 | 28 | Forces cache invalidate 29 | 30 | >>> from themes.models import ThemeTemplate 31 | >>> model_tpl = ThemeTemplate.objects.get(theme__is_default=True, name='about') 32 | >>> model_tpl.save() 33 | 34 | Check empty cache 35 | 36 | >>> assert_equal(cache.get('themes:another-theme|about'), None) 37 | 38 | Renders again to check it in cache 39 | 40 | >>> print render_to_string('about', {'company_name': 'Mochii Ltd.'}) 41 | We are a big company named "Mochii Ltd." working for you 42 | 43 | >>> print cache.get('themes:another-theme|about') 44 | engine:;We are a big company named "{{ company_name }}" working for you 45 | 46 | Theme name can be set as a prefix in the template name, followed by a ":" sign 47 | 48 | >>> print render_to_string('default:about') 49 | THis is about us 50 | 51 | -------------------------------------------------------------------------------- /themes/tests/04-template-tags.txt: -------------------------------------------------------------------------------- 1 | TEMPLATE TAGS 2 | ============= 3 | 4 | >>> from django.template.loader import render_to_string 5 | >>> from themes.models import ThemeTemplate 6 | 7 | Template tag 'theme_static_file' 8 | ------------------------------------ 9 | 10 | >>> print render_to_string('default:contact') 11 | Contact us by e-mail. 12 | 13 | >>> tpl = ThemeTemplate.objects.get(theme__name='default', name='contact') 14 | >>> tpl.content = '{% load themes_tags %}' 15 | >>> tpl.save() 16 | 17 | >>> print render_to_string('default:contact') 18 | 19 | 20 | -------------------------------------------------------------------------------- /themes/tests/05-django-engine.txt: -------------------------------------------------------------------------------- 1 | DJANGO TEMPLATE RENDERER 2 | ======================== 3 | 4 | This app is able to work with different template engines at once. For that, it's necessary 5 | just to inform the engine class for that. 6 | 7 | Because we have to treat and prepare things before to render, the template class must be 8 | ours, but it just will encapsulate the original one, controlling which variables are going 9 | to the context. 10 | 11 | Default engine comes from app_settings.DEFAULT_ENGINE (settings.THEMES_DEFAULT_ENGINE) 12 | 13 | >>> from djangoplus.test_utils import assert_equal 14 | 15 | >>> from themes.models import ThemeTemplate 16 | >>> from themes.app_settings import DEFAULT_ENGINE 17 | 18 | >>> print DEFAULT_ENGINE 19 | themes.engines.DjangoTemplate 20 | 21 | >>> from django.template.loader import render_to_string 22 | 23 | >>> print render_to_string('default:address') 24 | Our address is: 290 Broomhouse Ln 25 | 26 | >>> tpl1 = ThemeTemplate.objects.get(theme__name='default', name='address') 27 | >>> tpl1.content = """{% extends "base" %} 28 | ... {% block content %}{{ block.super }}Just testing{% endblock %}""" 29 | >>> tpl1.save() 30 | 31 | >>> base_tpl = tpl1.theme.templates.create( 32 | ... name='base', 33 | ... content='Title here.{% block content %}Comes before {% endblock %}', 34 | ... ) 35 | >>> from themes.registration import register_template 36 | >>> register_template('base') 37 | 38 | >>> assert_equal(list(tpl1.theme.templates.values_list('name', flat=True)), 39 | ... [u'about', u'address', u'base', u'contact']) 40 | 41 | >>> print render_to_string('default:address') 42 | Title here.Comes before Just testing 43 | 44 | -------------------------------------------------------------------------------- /themes/tests/06-jinja2-engine.txt-disabled: -------------------------------------------------------------------------------- 1 | JINJA2 TEMPLATE RENDERER 2 | ======================== 3 | 4 | Jinja2 is a similar template renderer compatible with Django, with similar syntax, but hugely 5 | faster. So, it's a better idea when the developer wants a faster application, using less 6 | resources. 7 | 8 | >>> from django.template.loader import render_to_string 9 | >>> from themes.models import ThemeTemplate 10 | 11 | >>> tpl1 = ThemeTemplate.objects.get(theme__name='default', name='address') 12 | >>> tpl1.engine = 'themes.engines.Jinja2Template' 13 | >>> tpl1.content = """{% extends "default:base" %} 14 | ... {% block content %}{{ super() }}Just testing{% endblock %}""" 15 | >>> tpl1.save() 16 | 17 | >>> base_tpl = ThemeTemplate.objects.get(theme__name='default', name='base') 18 | >>> base_tpl.engine = 'themes.engines.Jinja2Template' 19 | >>> base_tpl.save() 20 | 21 | >>> print render_to_string('default:address') 22 | Title here. 23 | Comes before Just testing 24 | 25 | -------------------------------------------------------------------------------- /themes/tests/07-middleware.txt: -------------------------------------------------------------------------------- 1 | MIDDLEWARE 2 | ========== 3 | 4 | That's a middleware to choose the current theme and set it to the current request. 5 | 6 | For that, it uses a function set in settings, so the developer can set it as he/she wants, 7 | based on criteria he/she needs. 8 | 9 | >>> from djangoplus.test_utils import assert_equal 10 | 11 | >>> from django.test.client import Client 12 | >>> cl = Client() 13 | 14 | >>> from themes import app_settings 15 | >>> assert_equal(app_settings.CHOOSING_FUNCTION, 'themes.views.choose_theme') 16 | 17 | >>> app_settings.CHOOSING_FUNCTION = 'views.choose_theme' 18 | 19 | >>> from themes.models import ThemeTemplate, Theme 20 | 21 | The default theme 22 | 23 | >>> theme1 = Theme.objects.get(name='default') 24 | >>> theme1.is_default = True 25 | >>> theme1.save() 26 | 27 | >>> home1, new = theme1.templates.get_or_create(name='home') 28 | >>> home1.content = 'Just testing this home page.' 29 | >>> home1.save() 30 | 31 | >>> resp = cl.get('/') 32 | >>> assert_equal(resp.content, 'Just testing this home page.') 33 | 34 | The other theme 35 | 36 | >>> theme2 = Theme.objects.get(name='another-theme') 37 | 38 | >>> home2, new = theme2.templates.get_or_create(name='home') 39 | >>> home2.content = 'This is another theme' 40 | >>> home2.save() 41 | 42 | Now changing the choose function to choose another theme 43 | 44 | >>> app_settings.CHOOSING_FUNCTION = 'middleware_funcs.choose_theme' 45 | 46 | >>> from themes import app_settings 47 | >>> assert_equal(app_settings.CHOOSING_FUNCTION, 'middleware_funcs.choose_theme') 48 | 49 | >>> resp = cl.get('/') 50 | >>> assert_equal(resp.content, 'This is another theme') 51 | 52 | -------------------------------------------------------------------------------- /themes/tests/08-packaging.txt: -------------------------------------------------------------------------------- 1 | PACKAGING THEMES 2 | ================ 3 | 4 | This app supports exporting and importing themes using zip-compressed files, including their 5 | templates and uploaded static files. 6 | 7 | >>> from djangoplus.test_utils import assert_equal 8 | >>> from themes.models import Theme 9 | 10 | Creating a basic theme to export 11 | 12 | >>> new_theme = Theme.objects.create(name='new-theme', verbose_name='New Theme') 13 | 14 | >>> tpl1 = new_theme.templates.create(name='landing', content='Text here') 15 | >>> tpl2 = new_theme.templates.create(name='ideas', content='First page') 16 | 17 | >>> sf1 = new_theme.static_files.create(url='http://static.alatazan.com/media2/img/logo-84.png', 18 | ... name='logo.png', mime_type='image/png') 19 | >>> sf2 = new_theme.static_files.create(url='http://static.alatazan.com/media2/css/layout.css', 20 | ... name='layout.css', mime_type='text/css') 21 | 22 | >>> from django.core.files.base import ContentFile 23 | >>> sf3 = new_theme.static_files.create(name='main.js', mime_type='text/javascript') 24 | >>> sf3_content = ContentFile('function a(m) { alert(m); }') 25 | >>> sf3.file.save('main.js', sf3_content) 26 | 27 | Export function (used for download) 28 | ----------------------------------- 29 | 30 | >>> from themes.packaging import export_theme 31 | >>> file_path = export_theme(new_theme) 32 | 33 | Deleting theme and its children 34 | 35 | >>> for sf in new_theme.static_files.all(): 36 | ... if not sf.url: 37 | ... sf.file.delete() 38 | ... sf.delete() 39 | 40 | >>> new_theme.templates.all().delete() 41 | >>> new_theme.delete() 42 | 43 | Import function 44 | --------------- 45 | 46 | >>> from themes.packaging import import_theme 47 | 48 | >>> fp = file(file_path) 49 | >>> imp_theme = import_theme(fp) 50 | 51 | >>> assert_equal(imp_theme.name, new_theme.name) 52 | >>> assert_equal(imp_theme.verbose_name, new_theme.verbose_name) 53 | >>> assert_equal(list(imp_theme.templates.values_list('name', flat=True)), 54 | ... [u'about', u'address', u'base', u'contact', u'home', u'ideas', u'landing']) 55 | >>> assert_equal(list(imp_theme.static_files.values_list('name', flat=True)), 56 | ... [u'layout.css', u'logo.png', u'main.js']) 57 | >>> assert_equal(imp_theme.static_files.get(name='main.js').file.read(), 58 | ... 'function a(m) { alert(m); }') 59 | 60 | -------------------------------------------------------------------------------- /themes/tests/09-security.txt: -------------------------------------------------------------------------------- 1 | SECURITY FEATURES 2 | ================= 3 | 4 | As a tool that allows end users writing themes and templates, it's necessary to ensure 5 | the security on some functions. 6 | 7 | Basic stuff 8 | 9 | >>> from djangoplus.test_utils import assert_equal 10 | >>> from themes import app_settings 11 | >>> app_settings.CACHE_EXPIRATION = None 12 | 13 | >>> from themes import registration 14 | >>> registration._registered_templates = {} 15 | 16 | >>> from themes.models import Theme 17 | >>> theme1 = Theme.objects.create(name='safe-theme', verbose_name='Safe Theme', is_default=True) 18 | >>> assert_equal(list(theme1.templates.values_list('name', flat=True)), []) 19 | 20 | >>> tpl1 = theme1.templates.create(name='home') 21 | 22 | >>> tpl1.content = 'The most basic one.' 23 | >>> tpl1.save() 24 | 25 | >>> from django.template.loader import render_to_string 26 | 27 | Default settings 28 | ---------------- 29 | 30 | The registered and not registered templates use default settings if they don't declare 31 | them especifically. 32 | 33 | >>> registration.register_template('home') 34 | >>> print render_to_string('home') 35 | The most basic one. 36 | 37 | >>> registration.register_template('box-to-include') 38 | >>> tpl2 = theme1.templates.create(name='box-to-include', content='Included') 39 | 40 | Available loads 41 | 42 | >>> from themes.exceptions import UnavailableLoad 43 | 44 | >>> app_settings.AVAILABLE_LOADS = ['i18n'] 45 | 46 | >>> tpl1.content = '{% load i18n %}The most basic one.' 47 | >>> tpl1.save() 48 | >>> print render_to_string('home') 49 | The most basic one. 50 | 51 | >>> tpl1.content = '{% load flatpages %}The most basic one.' 52 | >>> tpl1.save() 53 | >>> try: 54 | ... render_to_string('home') 55 | ... except UnavailableLoad, e: 56 | ... print e 57 | The load of libraries "flatpages" is not available. 58 | 59 | >>> app_settings.AVAILABLE_LOADS = ['i18n','flatpages'] 60 | >>> print render_to_string('home') 61 | The most basic one. 62 | 63 | >>> app_settings.AVAILABLE_LOADS = '*' 64 | >>> print render_to_string('home') 65 | The most basic one. 66 | 67 | Available tags 68 | 69 | >>> from themes.exceptions import UnavailableTag 70 | 71 | >>> app_settings.AVAILABLE_TAGS = ['if','for','extends'] 72 | 73 | >>> tpl1.content = '{% if 1 %}True{% else %}False{% endif %}' 74 | >>> tpl1.save() 75 | >>> print render_to_string('home') 76 | True 77 | 78 | >>> tpl1.content = 'Just this.{% comment %}My comment about{% endcomment%}' 79 | >>> tpl1.save() 80 | >>> try: 81 | ... render_to_string('home') 82 | ... except UnavailableTag, e: 83 | ... print e 84 | The template tags "comment" are not available. 85 | 86 | >>> app_settings.AVAILABLE_TAGS = ['if','for','extends','comment'] 87 | >>> print render_to_string('home') 88 | Just this. 89 | 90 | Available filters 91 | 92 | >>> from themes.exceptions import UnavailableFilter 93 | 94 | >>> app_settings.AVAILABLE_FILTERS = ['upper','length'] 95 | 96 | >>> tpl1.content = 'Look:{{ name|upper }}' 97 | >>> tpl1.save() 98 | >>> print render_to_string('home', {'name':'LeTiCiA'}) 99 | Look:LETICIA 100 | 101 | >>> tpl1.content = 'Look:{{ name|lower|yesno:"yeah,no,maybe" }}' 102 | >>> tpl1.save() 103 | >>> try: 104 | ... render_to_string('home', {'name':'LeTiCiA'}) 105 | ... except UnavailableFilter, e: 106 | ... print e 107 | The template filters "lower", "yesno" are not available. 108 | 109 | >>> app_settings.AVAILABLE_FILTERS = ['upper','length','lower','yesno'] 110 | 111 | >>> tpl1.content = 'Look:{{ name|lower|yesno:"yeah,no,maybe" }}' 112 | >>> tpl1.save() 113 | >>> print render_to_string('home', {'name':'LeTiCiA'}) 114 | Look:yeah 115 | 116 | Available includes 117 | 118 | >>> from themes.exceptions import UnavailableInclude 119 | 120 | >>> app_settings.AVAILABLE_TAGS = '*' 121 | >>> app_settings.AVAILABLE_INCLUDES = ['box-to-include'] 122 | 123 | >>> tpl1.content = 'Before {% include "box-to-include" %} After' 124 | >>> tpl1.save() 125 | >>> print render_to_string('home') 126 | Before Included After 127 | 128 | >>> app_settings.AVAILABLE_INCLUDES = ['another'] 129 | >>> tpl1.content = 'Before {% include "box-to-include" %} After' 130 | >>> tpl1.save() 131 | >>> try: 132 | ... render_to_string('home') 133 | ... except UnavailableInclude, e: 134 | ... print e 135 | The include of template "box-to-include" is not available. 136 | 137 | Excluded variables 138 | 139 | >>> app_settings.EXCLUDED_VARIABLES = None 140 | 141 | >>> tpl1.content = 'Username: {{ user.username }}.' 142 | >>> tpl1.save() 143 | >>> print render_to_string('home', {'user': {'username':'Ryan'}}) 144 | Username: Ryan. 145 | 146 | >>> app_settings.EXCLUDED_VARIABLES = ['user'] 147 | 148 | >>> tpl1.content = 'Username: {{ user.username }}.' 149 | >>> tpl1.save() 150 | >>> print render_to_string('home', {'user': {'username':'Ryan'}}) 151 | Username: . 152 | 153 | Allowing not registered templates 154 | 155 | >>> from django.template.base import TemplateDoesNotExist 156 | >>> app_settings.ALLOW_NOT_REGISTERED = False 157 | >>> try: 158 | ... render_to_string('new') 159 | ... except TemplateDoesNotExist, e: 160 | ... print e 161 | new 162 | 163 | >>> app_settings.ALLOW_NOT_REGISTERED = True 164 | >>> tpl3 = theme1.templates.create(name='new', content='New template.') 165 | >>> print render_to_string('new') 166 | New template. 167 | 168 | Registered templates 169 | -------------------- 170 | 171 | Registering a template ensures it will do only what it is allowed to do. 172 | 173 | Available loads 174 | Available tags 175 | Available filters 176 | Available includes 177 | Available variables 178 | Available blocks 179 | Excluded variables 180 | Allowing not registered templates 181 | 182 | User permissions 183 | ---------------- 184 | 185 | The interface tools are allowed only for users with permission to use them. 186 | 187 | Creating themes 188 | Creating templates 189 | Creating static files 190 | Changing themes 191 | Changing templates 192 | Changing static files 193 | Deleting themes 194 | Deleting templates 195 | Deleting static files 196 | Downloading themes 197 | Importing themes 198 | Setting a default theme 199 | 200 | Not existing returns empty 201 | -------------------------- 202 | 203 | The setting 'THEMES_STATIC_NOT_FOUND_RETURNS_EMPTY' (default False) can be set to return empty 204 | instead of raising error if that item doesn't exist. 205 | 206 | Static files 207 | 208 | >>> from django.template import TemplateSyntaxError 209 | >>> app_settings.STATIC_NOT_FOUND_RETURNS_EMPTY = False 210 | >>> tpl1.content = '{% load themes_tags %}{% theme_static_file "test.png" %}' 211 | >>> tpl1.save() 212 | >>> try: 213 | ... render_to_string('home') 214 | ... except TemplateSyntaxError, e: 215 | ... print e 216 | Caught DoesNotExist while rendering: ThemeStaticFile matching query does not exist. 217 | 218 | >>> app_settings.STATIC_NOT_FOUND_RETURNS_EMPTY = True 219 | >>> tpl1.content = '{% load themes_tags %}{% theme_static_file "test.png" %}' 220 | >>> tpl1.save() 221 | >>> assert_equal(render_to_string('home'), '') 222 | 223 | -------------------------------------------------------------------------------- /themes/tests/middleware_funcs.py: -------------------------------------------------------------------------------- 1 | from themes.models import Theme 2 | 3 | def choose_theme(request): 4 | return Theme.objects.exclude(is_default=True).order_by('pk')[0] 5 | 6 | -------------------------------------------------------------------------------- /themes/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls.defaults import patterns, include, url 2 | 3 | import views 4 | 5 | urlpatterns = patterns('', 6 | url(r'^$', views.home, name='themes_home'), 7 | url(r'^import/$', views.theme_import, name='themes_import'), 8 | url(r'^disable-preview/$', views.theme_preview, name='themes_disable_preview'), 9 | url(r'^([\w\-_]+)/$', views.theme, name='themes_theme'), 10 | url(r'^([\w\-_]+)/delete/$', views.theme_delete, name='themes_delete'), 11 | url(r'^([\w\-_]+)/set-default/$', views.theme_set_default, name='themes_set_default'), 12 | url(r'^([\w\-_]+)/preview/$', views.theme_preview, name='themes_preview'), 13 | url(r'^([\w\-_]+)/rename/$', views.theme_rename, name='themes_rename'), 14 | url(r'^([\w\-_]+)/save-as/$', views.theme_save_as, name='themes_save_as'), 15 | url(r'^([\w\-_]+)/up-file/$', views.theme_up_file, name='themes_up_file'), 16 | url(r'^([\w\-_]+)/edit-child/$', views.theme_edit_child, name='themes_edit_child'), 17 | url(r'^([\w\-_]+)/delete-child/$', views.theme_delete_child, name='themes_delete_child'), 18 | url(r'^([\w\-_]+)/create-template/$', views.theme_create_template, name='themes_create_template'), 19 | url(r'^([\w\-_]+)/create-static-file/$', views.theme_create_static_file, name='themes_create_static_file'), 20 | url(r'^([\w\-_]+)/download/$', views.theme_download, name='themes_download'), 21 | ) 22 | 23 | --------------------------------------------------------------------------------