diff --git a/.gitignore b/.gitignore index ebf06998b14cf4df495642ea82941da6c79fc4aa..ef28575da5b34683aa4dcce46ff8339bd5401148 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ log/ reports/ /src/ \#*\# +*.egg-info diff --git a/lms/djangoapps/track/__init__.py b/cms/__init__.py similarity index 100% rename from lms/djangoapps/track/__init__.py rename to cms/__init__.py diff --git a/lms/lib/cache_toolbox/templatetags/__init__.py b/cms/djangoapps/contentstore/__init__.py similarity index 100% rename from lms/lib/cache_toolbox/templatetags/__init__.py rename to cms/djangoapps/contentstore/__init__.py diff --git a/lms/lib/django_future/__init__.py b/cms/djangoapps/contentstore/management/__init__.py similarity index 100% rename from lms/lib/django_future/__init__.py rename to cms/djangoapps/contentstore/management/__init__.py diff --git a/lms/lib/util/__init__.py b/cms/djangoapps/contentstore/management/commands/__init__.py similarity index 100% rename from lms/lib/util/__init__.py rename to cms/djangoapps/contentstore/management/commands/__init__.py diff --git a/cms/djangoapps/contentstore/management/commands/import.py b/cms/djangoapps/contentstore/management/commands/import.py new file mode 100644 index 0000000000000000000000000000000000000000..d6064e1e3d242b53d781e140243dc11f606f3ffb --- /dev/null +++ b/cms/djangoapps/contentstore/management/commands/import.py @@ -0,0 +1,167 @@ +### +### One-off script for importing courseware form XML format +### + + +#import mitxmako.middleware +#from courseware import content_parser +#from django.contrib.auth.models import User +import os.path +from StringIO import StringIO +from mako.template import Template +from mako.lookup import TemplateLookup + +from django.core.management.base import BaseCommand +from keystore.django import keystore + +from lxml import etree + +class Command(BaseCommand): + help = \ +''' Run FTP server.''' + def handle(self, *args, **options): + print args + data_dir = args[0] + + parser = etree.XMLParser(remove_comments = True) + + lookup = TemplateLookup(directories=[data_dir]) + template = lookup.get_template("course.xml") + course_string = template.render(groups=[]) + course = etree.parse(StringIO(course_string), parser=parser) + + elements = list(course.iter()) + + tag_to_category = { + # Custom tags + 'videodev': 'Custom', + 'slides': 'Custom', + 'book': 'Custom', + 'image': 'Custom', + 'discuss': 'Custom', + # Simple lists + 'chapter': 'Week', + 'course': 'Course', + 'sequential': 'LectureSequence', + 'vertical': 'ProblemSet', + 'section': { + 'Lab': 'Lab', + 'Lecture Sequence': 'LectureSequence', + 'Homework': 'Homework', + 'Tutorial Index': 'TutorialIndex', + 'Video': 'VideoSegment', + 'Midterm': 'Exam', + 'Final': 'Exam', + None: 'Section', + }, + # True types + 'video': 'VideoSegment', + 'html': 'HTML', + 'problem': 'Problem', + } + + name_index = 0 + for e in elements: + name = e.attrib.get('name', None) + for f in elements: + if f != e and f.attrib.get('name', None) == name: + name = None + if not name: + name = "{tag}_{index}".format(tag=e.tag, index=name_index) + name_index = name_index + 1 + if e.tag in tag_to_category: + category = tag_to_category[e.tag] + if isinstance(category, dict): + category = category[e.get('format')] + category = category.replace('/', '-') + name = name.replace('/', '-') + e.set('url', 'i4x://mit.edu/6002xs12/{category}/{name}'.format( + category=category, + name=name)) + + + def handle_skip(e): + print "Skipping ", e + + results = {} + + def handle_custom(e): + data = {'type':'i4x://mit.edu/6002xs12/tag/{tag}'.format(tag=e.tag), + 'attrib':dict(e.attrib)} + results[e.attrib['url']] = {'data':data} + + def handle_list(e): + if e.attrib.get("class", None) == "tutorials": + return + children = [le.attrib['url'] for le in e.getchildren()] + results[e.attrib['url']] = {'children':children} + + def handle_video(e): + url = e.attrib['url'] + clip_url = url.replace('VideoSegment', 'VideoClip') + # Take: 0.75:izygArpw-Qo,1.0:p2Q6BrNhdh8,1.25:1EeWXzPdhSA,1.50:rABDYkeK0x8 + # Make: [(0.75, 'izygArpw-Qo'), (1.0, 'p2Q6BrNhdh8'), (1.25, '1EeWXzPdhSA'), (1.5, 'rABDYkeK0x8')] + youtube_str = e.attrib['youtube'] + youtube_list = [(float(x), y) for x,y in map(lambda x:x.split(':'), youtube_str.split(','))] + clip_infos = [{ "status": "ready", + "format": "youtube", + "sane": True, + "location": "youtube", + "speed": speed, + "id": youtube_id, + "size": None} \ + for (speed, youtube_id) \ + in youtube_list] + results[clip_url] = {'data':{'clip_infos':clip_infos}} + results[url] = {'children' : [{'url':clip_url}]} + + def handle_html(e): + if 'src' in e.attrib: + text = open(data_dir+'html/'+e.attrib['src']).read() + else: + textlist=[e.text]+[etree.tostring(elem) for elem in e]+[e.tail] + textlist=[i for i in textlist if type(i)==str] + text = "".join(textlist) + + results[e.attrib['url']] = {'data':{'text':text}} + + def handle_problem(e): + data = open(os.path.join(data_dir, 'problems', e.attrib['filename']+'.xml')).read() + results[e.attrib['url']] = {'data':{'statement':data}} + + element_actions = {# Inside HTML ==> Skip these + 'a': handle_skip, + 'h1': handle_skip, + 'h2': handle_skip, + 'hr': handle_skip, + 'strong': handle_skip, + 'ul': handle_skip, + 'li': handle_skip, + 'p': handle_skip, + # Custom tags + 'videodev': handle_custom, + 'slides': handle_custom, + 'book': handle_custom, + 'image': handle_custom, + 'discuss': handle_custom, + # Simple lists + 'chapter': handle_list, + 'course': handle_list, + 'sequential': handle_list, + 'vertical': handle_list, + 'section': handle_list, + # True types + 'video': handle_video, + 'html': handle_html, + 'problem': handle_problem, + } + + for e in elements: + element_actions[e.tag](e) + + for k in results: + keystore().create_item(k, 'Piotr Mitros') + if 'data' in results[k]: + keystore().update_item(k, results[k]['data']) + if 'children' in results[k]: + keystore().update_children(k, results[k]['children']) diff --git a/lms/djangoapps/track/tests.py b/cms/djangoapps/contentstore/tests.py similarity index 100% rename from lms/djangoapps/track/tests.py rename to cms/djangoapps/contentstore/tests.py diff --git a/cms/djangoapps/contentstore/views.py b/cms/djangoapps/contentstore/views.py new file mode 100644 index 0000000000000000000000000000000000000000..e29c41ea592f3922b1abcc40dbbf9623c5cf5917 --- /dev/null +++ b/cms/djangoapps/contentstore/views.py @@ -0,0 +1,12 @@ +from mitxmako.shortcuts import render_to_response +from keystore.django import keystore +from django.contrib.auth.decorators import login_required + + +def index(request): + # FIXME (cpennington): These need to be read in from the active user + org = 'mit.edu' + course = '6002xs12' + course = keystore().get_item(['i4x', org, course, 'Course', None]) + weeks = course.get_children() + return render_to_response('index.html', {'weeks': weeks}) diff --git a/cms/envs/__init__.py b/cms/envs/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/cms/envs/common.py b/cms/envs/common.py new file mode 100644 index 0000000000000000000000000000000000000000..8d402b6fa9592c54fd0e6f7c54ea428ed0bd8d81 --- /dev/null +++ b/cms/envs/common.py @@ -0,0 +1,149 @@ +""" +This is the common settings file, intended to set sane defaults. If you have a +piece of configuration that's dependent on a set of feature flags being set, +then create a function that returns the calculated value based on the value of +MITX_FEATURES[...]. Modules that extend this one can change the feature +configuration in an environment specific config file and re-calculate those +values. + +We should make a method that calls all these config methods so that you just +make one call at the end of your site-specific dev file to reset all the +dependent variables (like INSTALLED_APPS) for you. + +Longer TODO: +1. Right now our treatment of static content in general and in particular + course-specific static content is haphazard. +2. We should have a more disciplined approach to feature flagging, even if it + just means that we stick them in a dict called MITX_FEATURES. +3. We need to handle configuration for multiple courses. This could be as + multiple sites, but we do need a way to map their data assets. +""" + +import sys +import tempfile +from path import path + +############################# SET PATH INFORMATION ############################# +PROJECT_ROOT = path(__file__).abspath().dirname().dirname() # /mitx/cms +COMMON_ROOT = PROJECT_ROOT.dirname() / "common" +ENV_ROOT = PROJECT_ROOT.dirname().dirname() # virtualenv dir /mitx is in +ASKBOT_ROOT = ENV_ROOT / "askbot-devel" +COURSES_ROOT = ENV_ROOT / "data" + +# FIXME: To support multiple courses, we should walk the courses dir at startup +DATA_DIR = COURSES_ROOT + +sys.path.append(ENV_ROOT) +sys.path.append(ASKBOT_ROOT) +sys.path.append(ASKBOT_ROOT / "askbot" / "deps") +sys.path.append(PROJECT_ROOT / 'djangoapps') +sys.path.append(PROJECT_ROOT / 'lib') +sys.path.append(COMMON_ROOT / 'djangoapps') +sys.path.append(COMMON_ROOT / 'lib') + + +############################# WEB CONFIGURATION ############################# +# This is where we stick our compiled template files. +MAKO_MODULE_DIR = tempfile.mkdtemp('mako') +MAKO_TEMPLATES = {} +MAKO_TEMPLATES['main'] = [PROJECT_ROOT / 'templates'] + +MITX_ROOT_URL = '' + +TEMPLATE_CONTEXT_PROCESSORS = ( + 'django.core.context_processors.request', + 'django.core.context_processors.static', + 'django.contrib.messages.context_processors.messages', + 'django.core.context_processors.auth', # this is required for admin + 'django.core.context_processors.csrf', # necessary for csrf protection +) + +################################# Middleware ################################### +# List of finder classes that know how to find static files in +# various locations. +STATICFILES_FINDERS = ( + 'django.contrib.staticfiles.finders.FileSystemFinder', + 'django.contrib.staticfiles.finders.AppDirectoriesFinder', +) + +# List of callables that know how to import templates from various sources. +TEMPLATE_LOADERS = ( + 'django.template.loaders.filesystem.Loader', + 'django.template.loaders.app_directories.Loader', +) + +MIDDLEWARE_CLASSES = ( + 'django.middleware.cache.UpdateCacheMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + + # Instead of AuthenticationMiddleware, we use a cached backed version + 'cache_toolbox.middleware.CacheBackedAuthenticationMiddleware', + + 'django.contrib.messages.middleware.MessageMiddleware', + 'track.middleware.TrackMiddleware', + 'mitxmako.middleware.MakoMiddleware', + + 'django.middleware.transaction.TransactionMiddleware', +) + +############################ SIGNAL HANDLERS ################################ +import monitoring.exceptions # noqa + +############################ DJANGO_BUILTINS ################################ +# Change DEBUG/TEMPLATE_DEBUG in your environment settings files, not here +DEBUG = False +TEMPLATE_DEBUG = False + +# Site info +SITE_ID = 1 +SITE_NAME = "localhost:8000" +HTTPS = 'on' +ROOT_URLCONF = 'mitx.cms.urls' +IGNORABLE_404_ENDS = ('favicon.ico') + +# Email +EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' +DEFAULT_FROM_EMAIL = 'registration@mitx.mit.edu' +DEFAULT_FEEDBACK_EMAIL = 'feedback@mitx.mit.edu' +ADMINS = ( + ('MITx Admins', 'admin@mitx.mit.edu'), +) +MANAGERS = ADMINS + +# Static content +STATIC_URL = '/static/' +ADMIN_MEDIA_PREFIX = '/static/admin/' +STATIC_ROOT = ENV_ROOT / "staticfiles" + +# FIXME: We should iterate through the courses we have, adding the static +# contents for each of them. (Right now we just use symlinks.) +STATICFILES_DIRS = [ + PROJECT_ROOT / "static", + +# This is how you would use the textbook images locally +# ("book", ENV_ROOT / "book_images") +] + +# Locale/Internationalization +TIME_ZONE = 'America/New_York' # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name +LANGUAGE_CODE = 'en' # http://www.i18nguy.com/unicode/language-identifiers.html +USE_I18N = True +USE_L10N = True + +# Messages +MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage' + +############################ APPS ##################################### + +INSTALLED_APPS = ( + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.sites', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'contentstore', + 'instructor', +) diff --git a/cms/envs/dev.py b/cms/envs/dev.py new file mode 100644 index 0000000000000000000000000000000000000000..332f52f1458d1905d4d6419dc37f854f4fa96854 --- /dev/null +++ b/cms/envs/dev.py @@ -0,0 +1,43 @@ +""" +This config file runs the simplest dev environment""" + +from .common import * + +DEBUG = True +TEMPLATE_DEBUG = DEBUG + +KEYSTORE = { + 'host': 'localhost', + 'db': 'mongo_base', + 'collection': 'key_store', +} + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': ENV_ROOT / "db" / "mitx.db", + } +} + +CACHES = { + # This is the cache used for most things. Askbot will not work without a + # functioning cache -- it relies on caching to load its settings in places. + # In staging/prod envs, the sessions also live here. + 'default': { + 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', + 'LOCATION': 'mitx_loc_mem_cache', + 'KEY_FUNCTION': 'util.memcache.safe_key', + }, + + # The general cache is what you get if you use our util.cache. It's used for + # things like caching the course.xml file for different A/B test groups. + # We set it to be a DummyCache to force reloading of course.xml in dev. + # In staging environments, we would grab VERSION from data uploaded by the + # push process. + 'general': { + 'BACKEND': 'django.core.cache.backends.dummy.DummyCache', + 'KEY_PREFIX': 'general', + 'VERSION': 4, + 'KEY_FUNCTION': 'util.memcache.safe_key', + } +} diff --git a/cms/envs/test.py b/cms/envs/test.py new file mode 100644 index 0000000000000000000000000000000000000000..1a20d9e6f8f88fef9a3e34d88eba8c3a57d5569a --- /dev/null +++ b/cms/envs/test.py @@ -0,0 +1,54 @@ +""" +This config file runs the simplest dev environment using sqlite, and db-based +sessions. Assumes structure: + +/envroot/ + /db # This is where it'll write the database file + /mitx # The location of this repo + /log # Where we're going to write log files +""" +from .common import * +import os + +# Nose Test Runner +INSTALLED_APPS += ('django_nose',) +NOSE_ARGS = ['--cover-erase', '--with-xunit', '--with-xcoverage', '--cover-html', '--cover-inclusive'] +for app in os.listdir(PROJECT_ROOT / 'djangoapps'): + NOSE_ARGS += ['--cover-package', app] +TEST_RUNNER = 'django_nose.NoseTestSuiteRunner' + +KEYSTORE = { + 'host': 'localhost', + 'db': 'mongo_base', + 'collection': 'key_store', +} + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': ENV_ROOT / "db" / "mitx.db", + } +} + +CACHES = { + # This is the cache used for most things. Askbot will not work without a + # functioning cache -- it relies on caching to load its settings in places. + # In staging/prod envs, the sessions also live here. + 'default': { + 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', + 'LOCATION': 'mitx_loc_mem_cache', + 'KEY_FUNCTION': 'util.memcache.safe_key', + }, + + # The general cache is what you get if you use our util.cache. It's used for + # things like caching the course.xml file for different A/B test groups. + # We set it to be a DummyCache to force reloading of course.xml in dev. + # In staging environments, we would grab VERSION from data uploaded by the + # push process. + 'general': { + 'BACKEND': 'django.core.cache.backends.dummy.DummyCache', + 'KEY_PREFIX': 'general', + 'VERSION': 4, + 'KEY_FUNCTION': 'util.memcache.safe_key', + } +} diff --git a/cms/manage.py b/cms/manage.py new file mode 100644 index 0000000000000000000000000000000000000000..3e4eedc9ff5862c99e999b544a5b34c4e9af877a --- /dev/null +++ b/cms/manage.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python +from django.core.management import execute_manager +import imp +try: + imp.find_module('settings') # Assumed to be in the same directory. +except ImportError: + import sys + 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__) + sys.exit(1) + +import settings + +if __name__ == "__main__": + execute_manager(settings) diff --git a/cms/models.py b/cms/models.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/cms/static/css/base-style.css b/cms/static/css/base-style.css new file mode 100644 index 0000000000000000000000000000000000000000..9ebc6bd839a1c6055d58706ee65be2065aac8724 --- /dev/null +++ b/cms/static/css/base-style.css @@ -0,0 +1,1071 @@ +html, body, div, span, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +abbr, address, cite, code, +del, dfn, em, img, ins, kbd, q, samp, +small, strong, sub, sup, var, +b, i, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, figcaption, figure, +footer, header, hgroup, menu, nav, section, summary, +time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + outline: 0; + vertical-align: baseline; + background: transparent; } + +html, body { + font-size: 100%; } + +article, aside, details, figcaption, figure, footer, header, hgroup, nav, section { + display: block; } + +audio, canvas, video { + display: inline-block; } + +audio:not([controls]) { + display: none; } + +[hidden] { + display: none; } + +html { + font-size: 100%; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; } + +html, button, input, select, textarea { + font-family: sans-serif; } + +a:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; } +a:hover, a:active { + outline: 0; } + +abbr[title] { + border-bottom: 1px dotted; } + +b, strong { + font-weight: bold; } + +blockquote { + margin: 1em 40px; } + +dfn { + font-style: italic; } + +mark { + background: #ff0; + color: #000; } + +pre, code, kbd, samp { + font-family: monospace, serif; + _font-family: 'courier new', monospace; + font-size: 1em; } + +pre { + white-space: pre; + white-space: pre-wrap; + word-wrap: break-word; } + +blockquote, q { + quotes: none; } + blockquote:before, blockquote:after, q:before, q:after { + content: ''; + content: none; } + +small { + font-size: 75%; } + +sub, sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; } + +sup { + top: -0.5em; } + +sub { + bottom: -0.25em; } + +nav ul, nav ol { + list-style: none; + list-style-image: none; } + +img { + border: 0; + height: auto; + max-width: 100%; + -ms-interpolation-mode: bicubic; } + +svg:not(:root) { + overflow: hidden; } + +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; } + +legend { + border: 0; + padding: 0; + white-space: normal; } + +button, input, select, textarea { + font-size: 100%; + margin: 0; + vertical-align: baseline; } + +button, input { + line-height: normal; } + +button, input[type="button"], input[type="reset"], input[type="submit"] { + cursor: pointer; + -webkit-appearance: button; } + +button[disabled], input[disabled] { + cursor: default; } + +input[type="checkbox"], input[type="radio"] { + box-sizing: border-box; + padding: 0; } + +input[type="search"] { + -webkit-appearance: textfield; + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; + box-sizing: content-box; } + +input[type="search"]::-webkit-search-decoration, input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; } + +button::-moz-focus-inner, input::-moz-focus-inner { + border: 0; + padding: 0; } + +textarea { + overflow: auto; + vertical-align: top; } + +table { + border-collapse: collapse; + border-spacing: 0; } + +html { + height: 100%; } + +body { + zoom: 1; + height: 100%; + font: 14px "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Geneva, Verdana, sans-serif; } + body:before, body:after { + content: ""; + display: table; } + body:after { + clear: both; } + body > section { + display: table; + width: 100%; } + body > header { + background: #000; + color: #fff; + display: block; + float: none; + padding: 6px 20px; + width: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; } + body > header nav { + zoom: 1; } + body > header nav:before, body > header nav:after { + content: ""; + display: table; } + body > header nav:after { + clear: both; } + body > header nav h2 { + font-size: 14px; + text-transform: uppercase; + float: left; } + body > header nav ul { + float: left; } + body > header nav ul.user-nav { + float: right; } + body > header nav ul li { + display: -moz-inline-box; + -moz-box-orient: vertical; + display: inline-block; + vertical-align: baseline; + zoom: 1; + *display: inline; + *vertical-align: auto; + margin-left: 15px; } + body.content section.main-content { + border-left: 2px solid #000; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + width: 74.423%; + float: left; + -webkit-box-shadow: -2px 0 3px #dddddd; + -moz-box-shadow: -2px 0 3px #dddddd; + box-shadow: -2px 0 3px #dddddd; } + +a { + text-decoration: none; + color: #888; } + +input { + font-family: "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Geneva, Verdana, sans-serif; } + +input[type="submit"], .button, section.cal section.new-section > a, section.week-edit > section.content > div section.modules.empty a, +section.week-new > section.content > div section.modules.empty a, +section.sequence-edit > section.content > div section.modules.empty a, section.week-edit > section.content > div section.scratch-pad ol li ul li.empty a, +section.week-new > section.content > div section.scratch-pad ol li ul li.empty a, +section.sequence-edit > section.content > div section.scratch-pad ol li ul li.empty a, section.video-new > section section.upload a.upload-button, section.video-edit > section section.upload a.upload-button, section.video-new > section a.save-update, section.video-edit > section a.save-update, section.problem-new > section a.save, section.problem-edit > section a.save { + border: 1px solid #ccc; + background: #efefef; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + -ms-border-radius: 3px; + -o-border-radius: 3px; + border-radius: 3px; + padding: 6px; } + +.new-module { + position: relative; } + .new-module a { + padding: 6px; + display: block; } + .new-module ul.new-dropdown { + list-style: none; + position: absolute; } + .new-module ul.new-dropdown li { + display: none; + padding: 6px; } + .new-module:hover ul.new-dropdown { + display: block; } + +.draggable { + width: 7px; + min-height: 14px; + background: url("../img/drag-handle.png") no-repeat center; + text-indent: -9999px; + display: block; + float: right; } + +section.cal { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 25px; + zoom: 1; } + section.cal:before, section.cal:after { + content: ""; + display: table; } + section.cal:after { + clear: both; } + section.cal > header { + zoom: 1; + margin-bottom: 10px; + background: #efefef; + border: 1px solid #ddd; } + section.cal > header:before, section.cal > header:after { + content: ""; + display: table; } + section.cal > header:after { + clear: both; } + section.cal > header h2 { + display: -moz-inline-box; + -moz-box-orient: vertical; + display: inline-block; + vertical-align: baseline; + zoom: 1; + *display: inline; + *vertical-align: auto; + text-transform: uppercase; + letter-spacing: 1px; + font-size: 14px; + padding: 6px; + margin-left: 6px; + font-size: 12px; } + section.cal > header ul { + display: -moz-inline-box; + -moz-box-orient: vertical; + display: inline-block; + vertical-align: baseline; + zoom: 1; + *display: inline; + *vertical-align: auto; } + section.cal > header ul li { + display: -moz-inline-box; + -moz-box-orient: vertical; + display: inline-block; + vertical-align: baseline; + zoom: 1; + *display: inline; + *vertical-align: auto; + margin-left: 6px; + padding-left: 6px; + border-left: 1px solid #ddd; + padding: 6px; } + section.cal > header ul li a { + display: -moz-inline-box; + -moz-box-orient: vertical; + display: inline-block; + vertical-align: baseline; + zoom: 1; + *display: inline; + *vertical-align: auto; } + section.cal > header ul li ul { + display: -moz-inline-box; + -moz-box-orient: vertical; + display: inline-block; + vertical-align: baseline; + zoom: 1; + *display: inline; + *vertical-align: auto; } + section.cal > header ul li ul li { + display: -moz-inline-box; + -moz-box-orient: vertical; + display: inline-block; + vertical-align: baseline; + zoom: 1; + *display: inline; + *vertical-align: auto; + padding: 0; + border-left: 0; } + section.cal ol { + list-style: none; + zoom: 1; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + border-left: 1px solid #333; + border-top: 1px solid #333; + width: 100%; } + section.cal ol:before, section.cal ol:after { + content: ""; + display: table; } + section.cal ol:after { + clear: both; } + section.cal ol > li { + border-right: 1px solid #333; + border-bottom: 1px solid; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + float: left; + width: 25.0%; } + section.cal ol > li header { + border-bottom: 1px solid #000; + -webkit-box-shadow: 0 1px 2px #aaaaaa; + -moz-box-shadow: 0 1px 2px #aaaaaa; + box-shadow: 0 1px 2px #aaaaaa; + display: block; + margin-bottom: 2px; } + section.cal ol > li header h1 { + font-size: 14px; + text-transform: uppercase; + border-bottom: 1px solid #ccc; + padding: 6px; } + section.cal ol > li header h1 a { + color: #000; + display: block; } + section.cal ol > li header ul li { + background: #fff; + color: #888; + border-bottom: 0; + font-size: 12px; } + section.cal ol > li ul { + list-style: none; + margin-bottom: 1px; } + section.cal ol > li ul li { + background: #efefef; + border-bottom: 1px solid #666; + padding: 6px; } + section.cal ol > li ul li.create-module { + position: relative; } + section.cal ol > li ul li.create-module > div { + display: none; + position: absolute; + top: 30px; + width: 90%; + background: rgba(0, 0, 0, 0.9); + padding: 10px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + -ms-border-radius: 3px; + -o-border-radius: 3px; + border-radius: 3px; + z-index: 99; } + section.cal ol > li ul li.create-module > div:before { + content: " "; + display: block; + background: rgba(0, 0, 0, 0.8); + width: 10px; + height: 10px; + position: absolute; + top: -5px; + left: 50%; + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -ms-transform: rotate(45deg); + -o-transform: rotate(45deg); + transform: rotate(45deg); } + section.cal ol > li ul li.create-module > div ul li { + border-bottom: 0; + background: none; } + section.cal ol > li ul li.create-module > div ul li input { + width: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + border-color: #000; + padding: 6px; } + section.cal ol > li ul li.create-module > div ul li select { + width: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; } + section.cal ol > li ul li.create-module > div ul li select option { + font-size: 14px; } + section.cal ol > li ul li.create-module > div ul li a { + float: right; } + section.cal ol > li ul li.create-module > div ul li a:first-child { + float: left; } + section.cal ol > li ul li.create-module:hover div { + display: block; } + section.cal section.new-section { + margin-top: 10px; + display: -moz-inline-box; + -moz-box-orient: vertical; + display: inline-block; + vertical-align: baseline; + zoom: 1; + *display: inline; + *vertical-align: auto; + position: relative; } + section.cal section.new-section > a { + display: block; } + section.cal section.new-section section { + display: none; + position: absolute; + top: 30px; + background: rgba(0, 0, 0, 0.8); + min-width: 300px; + padding: 10px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + -ms-border-radius: 3px; + -o-border-radius: 3px; + border-radius: 3px; + z-index: 99; } + section.cal section.new-section section:before { + content: " "; + display: block; + background: rgba(0, 0, 0, 0.8); + width: 10px; + height: 10px; + position: absolute; + top: -5px; + left: 20%; + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -ms-transform: rotate(45deg); + -o-transform: rotate(45deg); + transform: rotate(45deg); } + section.cal section.new-section section form ul { + list-style: none; } + section.cal section.new-section section form ul li { + border-bottom: 0; + background: none; + margin-bottom: 6px; } + section.cal section.new-section section form ul li input { + width: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + border-color: #000; + padding: 6px; } + section.cal section.new-section section form ul li select { + width: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; } + section.cal section.new-section section form ul li select option { + font-size: 14px; } + section.cal section.new-section section form ul li a { + float: right; } + section.cal section.new-section section form ul li a:first-child { + float: left; } + section.cal section.new-section:hover section { + display: block; } + +body.content +section.cal { + width: 25.577%; + float: left; + overflow: scroll; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + opacity: .4; + -webkit-transition-property: all; + -moz-transition-property: all; + -ms-transition-property: all; + -o-transition-property: all; + transition-property: all; + -webkit-transition-duration: 0.15s; + -moz-transition-duration: 0.15s; + -ms-transition-duration: 0.15s; + -o-transition-duration: 0.15s; + transition-duration: 0.15s; + -webkit-transition-timing-function: ease-out; + -moz-transition-timing-function: ease-out; + -ms-transition-timing-function: ease-out; + -o-transition-timing-function: ease-out; + transition-timing-function: ease-out; + -webkit-transition-delay: 0; + -moz-transition-delay: 0; + -ms-transition-delay: 0; + -o-transition-delay: 0; + transition-delay: 0; } + body.content + section.cal > header ul { + display: none; } + body.content + section.cal:hover { + opacity: 1; } + body.content + section.cal ol li { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + width: 100%; } + body.content + section.cal ol li.create-module { + display: none; } + +section.week-edit > header, +section.week-new > header, +section.sequence-edit > header { + border-bottom: 2px solid #333; + zoom: 1; } + section.week-edit > header:before, section.week-edit > header:after, + section.week-new > header:before, + section.week-new > header:after, + section.sequence-edit > header:before, + section.sequence-edit > header:after { + content: ""; + display: table; } + section.week-edit > header:after, + section.week-new > header:after, + section.sequence-edit > header:after { + clear: both; } + section.week-edit > header div, + section.week-new > header div, + section.sequence-edit > header div { + zoom: 1; + padding: 6px 20px; } + section.week-edit > header div:before, section.week-edit > header div:after, + section.week-new > header div:before, + section.week-new > header div:after, + section.sequence-edit > header div:before, + section.sequence-edit > header div:after { + content: ""; + display: table; } + section.week-edit > header div:after, + section.week-new > header div:after, + section.sequence-edit > header div:after { + clear: both; } + section.week-edit > header div h1, + section.week-new > header div h1, + section.sequence-edit > header div h1 { + font-size: 18px; + text-transform: uppercase; + letter-spacing: 1px; + float: left; } + section.week-edit > header div p, + section.week-new > header div p, + section.sequence-edit > header div p { + float: right; } + section.week-edit > header div.week, + section.week-new > header div.week, + section.sequence-edit > header div.week { + background: #eee; + font-size: 12px; + border-bottom: 1px solid #ccc; } + section.week-edit > header div.week h2, + section.week-new > header div.week h2, + section.sequence-edit > header div.week h2 { + font-size: 12px; + display: -moz-inline-box; + -moz-box-orient: vertical; + display: inline-block; + vertical-align: baseline; + zoom: 1; + *display: inline; + *vertical-align: auto; + margin-right: 20px; } + section.week-edit > header div.week ul, + section.week-new > header div.week ul, + section.sequence-edit > header div.week ul { + list-style: none; + display: -moz-inline-box; + -moz-box-orient: vertical; + display: inline-block; + vertical-align: baseline; + zoom: 1; + *display: inline; + *vertical-align: auto; } + section.week-edit > header div.week ul li, + section.week-new > header div.week ul li, + section.sequence-edit > header div.week ul li { + display: -moz-inline-box; + -moz-box-orient: vertical; + display: inline-block; + vertical-align: baseline; + zoom: 1; + *display: inline; + *vertical-align: auto; + margin-right: 10px; } + section.week-edit > header div.week ul li p, + section.week-new > header div.week ul li p, + section.sequence-edit > header div.week ul li p { + float: none; } + section.week-edit > header section.goals, + section.week-new > header section.goals, + section.sequence-edit > header section.goals { + background: #eee; + padding: 6px 20px; + border-top: 1px solid #ccc; } + section.week-edit > header section.goals ul, + section.week-new > header section.goals ul, + section.sequence-edit > header section.goals ul { + list-style: none; + color: #999; } + section.week-edit > header section.goals ul li, + section.week-new > header section.goals ul li, + section.sequence-edit > header section.goals ul li { + margin-bottom: 6px; } + section.week-edit > header section.goals ul li:last-child, + section.week-new > header section.goals ul li:last-child, + section.sequence-edit > header section.goals ul li:last-child { + margin-bottom: 0; } +section.week-edit > section.content, +section.week-new > section.content, +section.sequence-edit > section.content { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 20px; } + section.week-edit > section.content section.filters, + section.week-new > section.content section.filters, + section.sequence-edit > section.content section.filters { + zoom: 1; + margin-bottom: 10px; + background: #efefef; + border: 1px solid #ddd; } + section.week-edit > section.content section.filters:before, section.week-edit > section.content section.filters:after, + section.week-new > section.content section.filters:before, + section.week-new > section.content section.filters:after, + section.sequence-edit > section.content section.filters:before, + section.sequence-edit > section.content section.filters:after { + content: ""; + display: table; } + section.week-edit > section.content section.filters:after, + section.week-new > section.content section.filters:after, + section.sequence-edit > section.content section.filters:after { + clear: both; } + section.week-edit > section.content section.filters ul, + section.week-new > section.content section.filters ul, + section.sequence-edit > section.content section.filters ul { + zoom: 1; + list-style: none; + padding: 6px; } + section.week-edit > section.content section.filters ul:before, section.week-edit > section.content section.filters ul:after, + section.week-new > section.content section.filters ul:before, + section.week-new > section.content section.filters ul:after, + section.sequence-edit > section.content section.filters ul:before, + section.sequence-edit > section.content section.filters ul:after { + content: ""; + display: table; } + section.week-edit > section.content section.filters ul:after, + section.week-new > section.content section.filters ul:after, + section.sequence-edit > section.content section.filters ul:after { + clear: both; } + section.week-edit > section.content section.filters ul li, + section.week-new > section.content section.filters ul li, + section.sequence-edit > section.content section.filters ul li { + display: -moz-inline-box; + -moz-box-orient: vertical; + display: inline-block; + vertical-align: baseline; + zoom: 1; + *display: inline; + *vertical-align: auto; } + section.week-edit > section.content section.filters ul li.advanced, + section.week-new > section.content section.filters ul li.advanced, + section.sequence-edit > section.content section.filters ul li.advanced { + float: right; } + section.week-edit > section.content > div, + section.week-new > section.content > div, + section.sequence-edit > section.content > div { + display: table; + border: 1px solid; + width: 100%; } + section.week-edit > section.content > div section header, + section.week-new > section.content > div section header, + section.sequence-edit > section.content > div section header { + background: #eee; + padding: 6px; + border-bottom: 1px solid #ccc; + zoom: 1; } + section.week-edit > section.content > div section header:before, section.week-edit > section.content > div section header:after, + section.week-new > section.content > div section header:before, + section.week-new > section.content > div section header:after, + section.sequence-edit > section.content > div section header:before, + section.sequence-edit > section.content > div section header:after { + content: ""; + display: table; } + section.week-edit > section.content > div section header:after, + section.week-new > section.content > div section header:after, + section.sequence-edit > section.content > div section header:after { + clear: both; } + section.week-edit > section.content > div section header h2, + section.week-new > section.content > div section header h2, + section.sequence-edit > section.content > div section header h2 { + text-transform: uppercase; + letter-spacing: 1px; + font-size: 12px; + float: left; } + section.week-edit > section.content > div section.modules, + section.week-new > section.content > div section.modules, + section.sequence-edit > section.content > div section.modules { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + display: table-cell; + width: 65.632%; + border-right: 1px solid #333; } + section.week-edit > section.content > div section.modules.empty, + section.week-new > section.content > div section.modules.empty, + section.sequence-edit > section.content > div section.modules.empty { + text-align: center; + vertical-align: middle; } + section.week-edit > section.content > div section.modules.empty a, + section.week-new > section.content > div section.modules.empty a, + section.sequence-edit > section.content > div section.modules.empty a { + display: -moz-inline-box; + -moz-box-orient: vertical; + display: inline-block; + vertical-align: baseline; + zoom: 1; + *display: inline; + *vertical-align: auto; + margin-top: 10px; } + section.week-edit > section.content > div section.modules ol, + section.week-new > section.content > div section.modules ol, + section.sequence-edit > section.content > div section.modules ol { + list-style: none; + border-bottom: 1px solid #333; } + section.week-edit > section.content > div section.modules ol li, + section.week-new > section.content > div section.modules ol li, + section.sequence-edit > section.content > div section.modules ol li { + border-bottom: 1px solid #333; } + section.week-edit > section.content > div section.modules ol li:last-child, + section.week-new > section.content > div section.modules ol li:last-child, + section.sequence-edit > section.content > div section.modules ol li:last-child { + border-bottom: 0; } + section.week-edit > section.content > div section.modules ol li a, + section.week-new > section.content > div section.modules ol li a, + section.sequence-edit > section.content > div section.modules ol li a { + color: #000; } + section.week-edit > section.content > div section.modules ol li ol, + section.week-new > section.content > div section.modules ol li ol, + section.sequence-edit > section.content > div section.modules ol li ol { + list-style: none; } + section.week-edit > section.content > div section.modules ol li ol li, + section.week-new > section.content > div section.modules ol li ol li, + section.sequence-edit > section.content > div section.modules ol li ol li { + padding: 6px; } + section.week-edit > section.content > div section.modules ol li ol li:hover a.draggable, + section.week-new > section.content > div section.modules ol li ol li:hover a.draggable, + section.sequence-edit > section.content > div section.modules ol li ol li:hover a.draggable { + opacity: 1; } + section.week-edit > section.content > div section.modules ol li ol li a.draggable, + section.week-new > section.content > div section.modules ol li ol li a.draggable, + section.sequence-edit > section.content > div section.modules ol li ol li a.draggable { + float: right; + opacity: .5; } + section.week-edit > section.content > div section.modules ol li ol li.group, + section.week-new > section.content > div section.modules ol li ol li.group, + section.sequence-edit > section.content > div section.modules ol li ol li.group { + padding: 0; } + section.week-edit > section.content > div section.modules ol li ol li.group header, + section.week-new > section.content > div section.modules ol li ol li.group header, + section.sequence-edit > section.content > div section.modules ol li ol li.group header { + padding: 6px; + background: none; } + section.week-edit > section.content > div section.modules ol li ol li.group header h3, + section.week-new > section.content > div section.modules ol li ol li.group header h3, + section.sequence-edit > section.content > div section.modules ol li ol li.group header h3 { + font-size: 14px; } + section.week-edit > section.content > div section.modules ol li ol li.group ol, + section.week-new > section.content > div section.modules ol li ol li.group ol, + section.sequence-edit > section.content > div section.modules ol li ol li.group ol { + border-left: 4px solid #999; + border-bottom: 0; } + section.week-edit > section.content > div section.modules ol li ol li.group ol li:last-child, + section.week-new > section.content > div section.modules ol li ol li.group ol li:last-child, + section.sequence-edit > section.content > div section.modules ol li ol li.group ol li:last-child { + border-bottom: 0; } + section.week-edit > section.content > div section.scratch-pad, + section.week-new > section.content > div section.scratch-pad, + section.sequence-edit > section.content > div section.scratch-pad { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + display: table-cell; + width: 34.368%; + vertical-align: top; } + section.week-edit > section.content > div section.scratch-pad ol, + section.week-new > section.content > div section.scratch-pad ol, + section.sequence-edit > section.content > div section.scratch-pad ol { + list-style: none; + border-bottom: 1px solid #999; } + section.week-edit > section.content > div section.scratch-pad ol li, + section.week-new > section.content > div section.scratch-pad ol li, + section.sequence-edit > section.content > div section.scratch-pad ol li { + border-bottom: 1px solid #999; + background: #f9f9f9; } + section.week-edit > section.content > div section.scratch-pad ol li:last-child, + section.week-new > section.content > div section.scratch-pad ol li:last-child, + section.sequence-edit > section.content > div section.scratch-pad ol li:last-child { + border-bottom: 0; } + section.week-edit > section.content > div section.scratch-pad ol li ul, + section.week-new > section.content > div section.scratch-pad ol li ul, + section.sequence-edit > section.content > div section.scratch-pad ol li ul { + list-style: none; } + section.week-edit > section.content > div section.scratch-pad ol li ul li, + section.week-new > section.content > div section.scratch-pad ol li ul li, + section.sequence-edit > section.content > div section.scratch-pad ol li ul li { + padding: 6px; } + section.week-edit > section.content > div section.scratch-pad ol li ul li:last-child, + section.week-new > section.content > div section.scratch-pad ol li ul li:last-child, + section.sequence-edit > section.content > div section.scratch-pad ol li ul li:last-child { + border-bottom: 0; } + section.week-edit > section.content > div section.scratch-pad ol li ul li:hover a.draggable, + section.week-new > section.content > div section.scratch-pad ol li ul li:hover a.draggable, + section.sequence-edit > section.content > div section.scratch-pad ol li ul li:hover a.draggable { + opacity: 1; } + section.week-edit > section.content > div section.scratch-pad ol li ul li.empty, + section.week-new > section.content > div section.scratch-pad ol li ul li.empty, + section.sequence-edit > section.content > div section.scratch-pad ol li ul li.empty { + padding: 12px; } + section.week-edit > section.content > div section.scratch-pad ol li ul li.empty a, + section.week-new > section.content > div section.scratch-pad ol li ul li.empty a, + section.sequence-edit > section.content > div section.scratch-pad ol li ul li.empty a { + display: block; + text-align: center; } + section.week-edit > section.content > div section.scratch-pad ol li ul li a.draggable, + section.week-new > section.content > div section.scratch-pad ol li ul li a.draggable, + section.sequence-edit > section.content > div section.scratch-pad ol li ul li a.draggable { + float: right; + opacity: .3; } + section.week-edit > section.content > div section.scratch-pad ol li ul li a, + section.week-new > section.content > div section.scratch-pad ol li ul li a, + section.sequence-edit > section.content > div section.scratch-pad ol li ul li a { + color: #000; } + +section.video-new > section section.upload, section.video-edit > section section.upload { + padding: 6px; + margin-bottom: 10px; + border: 1px solid #ddd; } + section.video-new > section section.upload a.upload-button, section.video-edit > section section.upload a.upload-button { + display: -moz-inline-box; + -moz-box-orient: vertical; + display: inline-block; + vertical-align: baseline; + zoom: 1; + *display: inline; + *vertical-align: auto; } +section.video-new > section section.in-use h2, section.video-edit > section section.in-use h2 { + font-size: 14px; } +section.video-new > section section.in-use div, section.video-edit > section section.in-use div { + background: #eee; + text-align: center; + padding: 6px; } +section.video-new > section a.save-update, section.video-edit > section a.save-update { + display: -moz-inline-box; + -moz-box-orient: vertical; + display: inline-block; + vertical-align: baseline; + zoom: 1; + *display: inline; + *vertical-align: auto; + margin-top: 20px; } + +section.problem-new > section textarea, section.problem-edit > section textarea { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + display: block; + width: 100%; } +section.problem-new > section div.preview, section.problem-edit > section div.preview { + background: #eee; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + height: 40px; + padding: 10px; + width: 100%; } +section.problem-new > section a.save, section.problem-edit > section a.save { + display: -moz-inline-box; + -moz-box-orient: vertical; + display: inline-block; + vertical-align: baseline; + zoom: 1; + *display: inline; + *vertical-align: auto; + margin-top: 20px; } + +section.video-new, section.video-edit, section.problem-new, section.problem-edit { + position: absolute; + top: 72px; + right: 0; + background: #fff; + width: 48.845%; + -webkit-box-shadow: 0 0 6px #666666; + -moz-box-shadow: 0 0 6px #666666; + box-shadow: 0 0 6px #666666; + border: 1px solid #333; + border-right: 0; + z-index: 4; } + section.video-new > header, section.video-edit > header, section.problem-new > header, section.problem-edit > header { + background: #666; + zoom: 1; + color: #fff; + padding: 6px; + border-bottom: 1px solid #333; + -webkit-font-smoothing: antialiased; } + section.video-new > header:before, section.video-new > header:after, section.video-edit > header:before, section.video-edit > header:after, section.problem-new > header:before, section.problem-new > header:after, section.problem-edit > header:before, section.problem-edit > header:after { + content: ""; + display: table; } + section.video-new > header:after, section.video-edit > header:after, section.problem-new > header:after, section.problem-edit > header:after { + clear: both; } + section.video-new > header h2, section.video-edit > header h2, section.problem-new > header h2, section.problem-edit > header h2 { + float: left; + font-size: 14px; } + section.video-new > header a, section.video-edit > header a, section.problem-new > header a, section.problem-edit > header a { + color: #fff; } + section.video-new > header a.save-update, section.video-edit > header a.save-update, section.problem-new > header a.save-update, section.problem-edit > header a.save-update { + float: right; } + section.video-new > header a.cancel, section.video-edit > header a.cancel, section.problem-new > header a.cancel, section.problem-edit > header a.cancel { + float: left; } + section.video-new > section, section.video-edit > section, section.problem-new > section, section.problem-edit > section { + padding: 20px; } + section.video-new > section > header h1, section.video-edit > section > header h1, section.problem-new > section > header h1, section.problem-edit > section > header h1 { + font-size: 24px; + margin: 12px 0; } + section.video-new > section > header section.status-settings ul, section.video-edit > section > header section.status-settings ul, section.problem-new > section > header section.status-settings ul, section.problem-edit > section > header section.status-settings ul { + list-style: none; + -webkit-border-radius: 2px; + -moz-border-radius: 2px; + -ms-border-radius: 2px; + -o-border-radius: 2px; + border-radius: 2px; + border: 1px solid #999; + display: -moz-inline-box; + -moz-box-orient: vertical; + display: inline-block; + vertical-align: baseline; + zoom: 1; + *display: inline; + *vertical-align: auto; } + section.video-new > section > header section.status-settings ul li, section.video-edit > section > header section.status-settings ul li, section.problem-new > section > header section.status-settings ul li, section.problem-edit > section > header section.status-settings ul li { + display: -moz-inline-box; + -moz-box-orient: vertical; + display: inline-block; + vertical-align: baseline; + zoom: 1; + *display: inline; + *vertical-align: auto; + border-right: 1px solid #999; + padding: 6px; } + section.video-new > section > header section.status-settings ul li:last-child, section.video-edit > section > header section.status-settings ul li:last-child, section.problem-new > section > header section.status-settings ul li:last-child, section.problem-edit > section > header section.status-settings ul li:last-child { + border-right: 0; } + section.video-new > section > header section.status-settings ul li.current, section.video-edit > section > header section.status-settings ul li.current, section.problem-new > section > header section.status-settings ul li.current, section.problem-edit > section > header section.status-settings ul li.current { + background: #eee; } + section.video-new > section > header section.status-settings a.settings, section.video-edit > section > header section.status-settings a.settings, section.problem-new > section > header section.status-settings a.settings, section.problem-edit > section > header section.status-settings a.settings { + display: -moz-inline-box; + -moz-box-orient: vertical; + display: inline-block; + vertical-align: baseline; + zoom: 1; + *display: inline; + *vertical-align: auto; + margin: 0 20px; + border: 1px solid #999; + padding: 6px; } + section.video-new > section > header section.status-settings select, section.video-edit > section > header section.status-settings select, section.problem-new > section > header section.status-settings select, section.problem-edit > section > header section.status-settings select { + float: right; } + section.video-new > section > header section.meta, section.video-edit > section > header section.meta, section.problem-new > section > header section.meta, section.problem-edit > section > header section.meta { + background: #eee; + padding: 10px; + margin: 20px 0; + zoom: 1; } + section.video-new > section > header section.meta:before, section.video-new > section > header section.meta:after, section.video-edit > section > header section.meta:before, section.video-edit > section > header section.meta:after, section.problem-new > section > header section.meta:before, section.problem-new > section > header section.meta:after, section.problem-edit > section > header section.meta:before, section.problem-edit > section > header section.meta:after { + content: ""; + display: table; } + section.video-new > section > header section.meta:after, section.video-edit > section > header section.meta:after, section.problem-new > section > header section.meta:after, section.problem-edit > section > header section.meta:after { + clear: both; } + section.video-new > section > header section.meta div, section.video-edit > section > header section.meta div, section.problem-new > section > header section.meta div, section.problem-edit > section > header section.meta div { + float: left; + margin-right: 20px; } + section.video-new > section > header section.meta div h2, section.video-edit > section > header section.meta div h2, section.problem-new > section > header section.meta div h2, section.problem-edit > section > header section.meta div h2 { + font-size: 14px; + display: -moz-inline-box; + -moz-box-orient: vertical; + display: inline-block; + vertical-align: baseline; + zoom: 1; + *display: inline; + *vertical-align: auto; } + section.video-new > section > header section.meta div p, section.video-edit > section > header section.meta div p, section.problem-new > section > header section.meta div p, section.problem-edit > section > header section.meta div p { + display: -moz-inline-box; + -moz-box-orient: vertical; + display: inline-block; + vertical-align: baseline; + zoom: 1; + *display: inline; + *vertical-align: auto; } + section.video-new > section section.notes, section.video-edit > section section.notes, section.problem-new > section section.notes, section.problem-edit > section section.notes { + margin-top: 20px; + padding: 6px; + background: #eee; + border: 1px solid #ccc; } + section.video-new > section section.notes textarea, section.video-edit > section section.notes textarea, section.problem-new > section section.notes textarea, section.problem-edit > section section.notes textarea { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + display: block; + width: 100%; } + section.video-new > section section.notes h2, section.video-edit > section section.notes h2, section.problem-new > section section.notes h2, section.problem-edit > section section.notes h2 { + font-size: 14px; + margin-bottom: 6px; } + section.video-new > section section.notes input[type="submit"], section.video-edit > section section.notes input[type="submit"], section.problem-new > section section.notes input[type="submit"], section.problem-edit > section section.notes input[type="submit"] { + margin-top: 10px; } diff --git a/cms/static/css/ie.css b/cms/static/css/ie.css new file mode 100644 index 0000000000000000000000000000000000000000..f497a329cfff7507c89cd77ff08dee4d302880f1 --- /dev/null +++ b/cms/static/css/ie.css @@ -0,0 +1,196 @@ +/* line 12, ../sass/_reset.scss */ +html, body, div, span, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +abbr, address, cite, code, +del, dfn, em, img, ins, kbd, q, samp, +small, strong, sub, sup, var, +b, i, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, figcaption, figure, +footer, header, hgroup, menu, nav, section, summary, +time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + outline: 0; + vertical-align: baseline; + background: transparent; } + +/* line 21, ../sass/_reset.scss */ +html, body { + font-size: 100%; } + +/* line 26, ../sass/_reset.scss */ +article, aside, details, figcaption, figure, footer, header, hgroup, nav, section { + display: block; } + +/* line 31, ../sass/_reset.scss */ +audio, canvas, video { + display: inline-block; } + +/* line 36, ../sass/_reset.scss */ +audio:not([controls]) { + display: none; } + +/* line 41, ../sass/_reset.scss */ +[hidden] { + display: none; } + +/* line 47, ../sass/_reset.scss */ +html { + font-size: 100%; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; } + +/* line 54, ../sass/_reset.scss */ +html, button, input, select, textarea { + font-family: sans-serif; } + +/* line 60, ../sass/_reset.scss */ +a:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; } +/* line 69, ../sass/_reset.scss */ +a:hover, a:active { + outline: 0; } + +/* line 75, ../sass/_reset.scss */ +abbr[title] { + border-bottom: 1px dotted; } + +/* line 80, ../sass/_reset.scss */ +b, strong { + font-weight: bold; } + +/* line 84, ../sass/_reset.scss */ +blockquote { + margin: 1em 40px; } + +/* line 89, ../sass/_reset.scss */ +dfn { + font-style: italic; } + +/* line 94, ../sass/_reset.scss */ +mark { + background: #ff0; + color: #000; } + +/* line 101, ../sass/_reset.scss */ +pre, code, kbd, samp { + font-family: monospace, serif; + _font-family: 'courier new', monospace; + font-size: 1em; } + +/* line 108, ../sass/_reset.scss */ +pre { + white-space: pre; + white-space: pre-wrap; + word-wrap: break-word; } + +/* line 115, ../sass/_reset.scss */ +blockquote, q { + quotes: none; } + /* line 117, ../sass/_reset.scss */ + blockquote:before, blockquote:after, q:before, q:after { + content: ''; + content: none; } + +/* line 123, ../sass/_reset.scss */ +small { + font-size: 75%; } + +/* line 127, ../sass/_reset.scss */ +sub, sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; } + +/* line 134, ../sass/_reset.scss */ +sup { + top: -0.5em; } + +/* line 138, ../sass/_reset.scss */ +sub { + bottom: -0.25em; } + +/* line 143, ../sass/_reset.scss */ +nav ul, nav ol { + list-style: none; + list-style-image: none; } + +/* line 150, ../sass/_reset.scss */ +img { + border: 0; + height: auto; + max-width: 100%; + -ms-interpolation-mode: bicubic; } + +/* line 158, ../sass/_reset.scss */ +svg:not(:root) { + overflow: hidden; } + +/* line 163, ../sass/_reset.scss */ +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; } + +/* line 169, ../sass/_reset.scss */ +legend { + border: 0; + padding: 0; + white-space: normal; } + +/* line 175, ../sass/_reset.scss */ +button, input, select, textarea { + font-size: 100%; + margin: 0; + vertical-align: baseline; } + +/* line 182, ../sass/_reset.scss */ +button, input { + line-height: normal; } + +/* line 186, ../sass/_reset.scss */ +button, input[type="button"], input[type="reset"], input[type="submit"] { + cursor: pointer; + -webkit-appearance: button; } + +/* line 192, ../sass/_reset.scss */ +button[disabled], input[disabled] { + cursor: default; } + +/* line 196, ../sass/_reset.scss */ +input[type="checkbox"], input[type="radio"] { + box-sizing: border-box; + padding: 0; } + +/* line 201, ../sass/_reset.scss */ +input[type="search"] { + -webkit-appearance: textfield; + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; + box-sizing: content-box; } + +/* line 209, ../sass/_reset.scss */ +input[type="search"]::-webkit-search-decoration, input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; } + +/* line 215, ../sass/_reset.scss */ +button::-moz-focus-inner, input::-moz-focus-inner { + border: 0; + padding: 0; } + +/* line 220, ../sass/_reset.scss */ +textarea { + overflow: auto; + vertical-align: top; } + +/* line 226, ../sass/_reset.scss */ +table { + border-collapse: collapse; + border-spacing: 0; } diff --git a/cms/static/css/style.css b/cms/static/css/style.css new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/cms/static/img/drag-handle.png b/cms/static/img/drag-handle.png new file mode 100644 index 0000000000000000000000000000000000000000..3c9c3c1ebcee37ec1fcfd82aa204228ecd629598 Binary files /dev/null and b/cms/static/img/drag-handle.png differ diff --git a/cms/static/img/indicator.gif b/cms/static/img/indicator.gif new file mode 100755 index 0000000000000000000000000000000000000000..085ccaecaf5fa5c34bc14cd2c2ed5cbbd8e25dcb Binary files /dev/null and b/cms/static/img/indicator.gif differ diff --git a/cms/static/img/video.jpg b/cms/static/img/video.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e92271c3ad5e23185f1fac4bbf5954df735d5949 Binary files /dev/null and b/cms/static/img/video.jpg differ diff --git a/cms/static/js/jquery.inlineedit.js b/cms/static/js/jquery.inlineedit.js new file mode 100755 index 0000000000000000000000000000000000000000..a6258c981e9c1d7bd68e258293abe0914b481ac9 --- /dev/null +++ b/cms/static/js/jquery.inlineedit.js @@ -0,0 +1,251 @@ +/* + * jQuery inlineEdit + * + * Copyright (c) 2009 Ca-Phun Ung <caphun at yelotofu dot com> + * Licensed under the MIT (MIT-LICENSE.txt) license. + * + * http://github.com/caphun/jquery.inlineedit/ + * + * Inline (in-place) editing. + */ + +(function($) { + +// cached values +var namespace = '.inlineedit', + placeholderClass = 'inlineEdit-placeholder'; + +// define inlineEdit method +$.fn.inlineEdit = function( options ) { + var self = this; + + return this + + .each( function() { + $.inlineEdit.getInstance( this, options ).initValue(); + }) + + .live( ['click', 'mouseenter','mouseleave'].join(namespace+' '), function( event ) { + + var widget = $.inlineEdit.getInstance( this, options ), + editableElement = widget.element.find( widget.options.control ), + mutated = !!editableElement.length; + + widget.element.removeClass( widget.options.hover ); + + if ( event.target !== editableElement[0] ) { + switch ( event.type ) { + case 'click': + widget[ mutated ? 'mutate' : 'init' ](); + break; + + case 'mouseover': // jquery 1.4.x + case 'mouseout': // jquery 1.4.x + case 'mouseenter': + case 'mouseleave': + if ( !mutated ) { + widget.hoverClassChange( event ); + } + break; + } + } + + }); +} + +// plugin constructor +$.inlineEdit = function( elem, options ) { + + // deep extend + this.options = $.extend( true, {}, $.inlineEdit.defaults, options ); + + // the original element + this.element = $( elem ); + +} + +// plugin instance +$.inlineEdit.getInstance = function( elem, options ) { + return ( $.inlineEdit.initialised( elem ) ) + ? $( elem ).data( 'widget' + namespace ) + : new $.inlineEdit( elem, options ); +} + +// check if plugin initialised +$.inlineEdit.initialised = function( elem ) { + var init = $( elem ).data( 'init' + namespace ); + return init !== undefined && init !== null ? true : false; +} + +// plugin defaults +$.inlineEdit.defaults = { + hover: 'ui-state-hover', + value: '', + save: '', + buttons: '<button class="save">✔</button> <button class="cancel">✘</button>', + placeholder: 'Click to edit', + control: 'input', + cancelOnBlur: false, + saveOnBlur: false +}; + +// plugin prototypes +$.inlineEdit.prototype = { + + // initialisation + init: function() { + + // set initialise flag + this.element.data( 'init' + namespace, true ); + + // initialise value + this.initValue(); + + // mutate + this.mutate(); + + // save widget data + this.element.data( 'widget' + namespace, this ); + + }, + + initValue: function() { + this.value( $.trim( this.element.text() ) || this.options.value ); + + if ( !this.value() ) { + this.element.html( $( this.placeholderHtml() ) ); + } else if ( this.options.value ) { + this.element.html( this.options.value ); + } + }, + + mutate: function() { + var self = this; + + return self + .element + .html( self.mutatedHtml( self.value() ) ) + .find( 'button.save' ) + .bind( 'click', function( event ) { + self.save( self.element, event ); + self.change( self.element, event ); + return false; + }) + .end() + .find( 'button.cancel' ) + .bind( 'click', function( event ) { + self.change( self.element, event ); + return false; + }) + .end() + .find( self.options.control ) + .bind( 'blur', function( event ) { + if (self.options.cancelOnBlur === true) + self.change( self.element, event ); + else if (self.options.saveOnBlur == true){ + self.save( self.element, event ); + self.change( self.element, event ); + } + }) + .bind( 'keyup', function( event ) { + switch ( event.keyCode ) { + case 13: // save on ENTER + if (self.options.control !== 'textarea') { + self.save( self.element, event ); + self.change( self.element, event ); + } + break; + case 27: // cancel on ESC + self.change( self.element, event ); + break; + } + }) + .focus() + .end(); + }, + + value: function( newValue ) { + if ( arguments.length ) { + var value = newValue === this.options.placeholder ? '' : newValue; + this.element.data( 'value' + namespace, $( '.' + placeholderClass, this ).length ? '' : value && this.encodeHtml( value.replace( /\n/g,"<br />" ) ) ); + } + return this.element.data( 'value' + namespace ); + }, + + mutatedHtml: function( value ) { + return this.controls[ this.options.control ].call( this, value ); + }, + + placeholderHtml: function() { + return '<span class="'+ placeholderClass +'">'+ this.options.placeholder +'</span>'; + }, + + buttonHtml: function( options ) { + var o = $.extend({}, { + before: ' ', + buttons: this.options.buttons, + after: '' + }, options); + + return o.before + o.buttons + o.after; + }, + + save: function( elem, event ) { + var $control = this.element.find( this.options.control ), + hash = { + value: this.encodeHtml( $control.val() ) + }; + + // save value back to control to avoid XSS + $control.val(hash.value); + + if ( ( $.isFunction( this.options.save ) && this.options.save.call( this.element[0], event, hash ) ) !== false || !this.options.save ) { + this.value( hash.value ); + } + }, + + change: function( elem, event ) { + var self = this; + + if ( this.timer ) { + window.clearTimeout( this.timer ); + } + + this.timer = window.setTimeout( function() { + self.element.html( self.value() || self.placeholderHtml() ); + self.element.removeClass( self.options.hover ); + }, 200 ); + + }, + + controls: { + textarea: function( value ) { + return '<textarea>'+ value.replace(/<br\s?\/?>/g,"\n") +'</textarea>' + this.buttonHtml( { before: '<br />' } ); + }, + input: function( value ) { + return '<input type="text" value="'+ value.replace(/(\u0022)+/g, '') +'">' + this.buttonHtml(); + } + }, + + hoverClassChange: function( event ) { + $( event.target )[ /mouseover|mouseenter/.test( event.type ) ? 'addClass':'removeClass']( this.options.hover ); + }, + + encodeHtml: function( s ) { + var encoding = [ + {key: /</g, value: '<'}, + {key: />/g, value: '>'}, + {key: /"/g, value: '"'} + ], + value = s; + + $.each(encoding, function(i,n) { + value = value.replace(n.key, n.value); + }); + + return value; + } + +}; + +})(jQuery); diff --git a/cms/static/js/jquery.leanModal.min.js b/cms/static/js/jquery.leanModal.min.js new file mode 100644 index 0000000000000000000000000000000000000000..a5772dd8e21829b610878a61dbb9f1f17170892e --- /dev/null +++ b/cms/static/js/jquery.leanModal.min.js @@ -0,0 +1,5 @@ +// leanModal v1.1 by Ray Stone - http://finelysliced.com.au +// Dual licensed under the MIT and GPL + +(function($){$.fn.extend({leanModal:function(options){var defaults={top:100,overlay:0.5,closeButton:null};var overlay=$("<div id='lean_overlay'></div>");$("body").append(overlay);options=$.extend(defaults,options);return this.each(function(){var o=options;$(this).click(function(e){var modal_id=$(this).attr("href");$("#lean_overlay").click(function(){close_modal(modal_id)});$(o.closeButton).click(function(){close_modal(modal_id)});var modal_height=$(modal_id).outerHeight();var modal_width=$(modal_id).outerWidth(); +$("#lean_overlay").css({"display":"block",opacity:0});$("#lean_overlay").fadeTo(200,o.overlay);$(modal_id).css({"display":"block","position":"fixed","opacity":0,"z-index":11000,"left":50+"%","margin-left":-(modal_width/2)+"px","top":o.top+"px"});$(modal_id).fadeTo(200,1);e.preventDefault()})});function close_modal(modal_id){$("#lean_overlay").fadeOut(200);$(modal_id).css({"display":"none"})}}})})(jQuery); diff --git a/cms/static/js/jquery.tablednd.js b/cms/static/js/jquery.tablednd.js new file mode 100644 index 0000000000000000000000000000000000000000..56413ccb085d48d024e5ae9e414e0b38c72079f6 --- /dev/null +++ b/cms/static/js/jquery.tablednd.js @@ -0,0 +1,257 @@ + +jQuery.tableDnD = { + /** Keep hold of the current table being dragged */ + currentTable : null, + /** Keep hold of the current drag object if any */ + dragObject: null, + /** The current mouse offset */ + mouseOffset: null, + /** Remember the old value of Y so that we don't do too much processing */ + oldY: 0, + + /** Actually build the structure */ + build: function(options) { + // Make sure options exists + options = options || {}; + // Set up the defaults if any + + this.each(function() { + // Remember the options + this.tableDnDConfig = { + onDragStyle: options.onDragStyle, + onDropStyle: options.onDropStyle, + // Add in the default class for whileDragging + onDragClass: options.onDragClass ? options.onDragClass : "dragged", + onDrop: options.onDrop, + onDragStart: options.onDragStart, + scrollAmount: options.scrollAmount ? options.scrollAmount : 5 + }; + // Now make the rows draggable + jQuery.tableDnD.makeDraggable(this); + }); + + // Now we need to capture the mouse up and mouse move event + // We can use bind so that we don't interfere with other event handlers + jQuery(document) + .bind('mousemove', jQuery.tableDnD.mousemove) + .bind('mouseup', jQuery.tableDnD.mouseup); + + // Don't break the chain + return this; + }, + + /** This function makes all the rows on the table draggable apart from those marked as "NoDrag" */ + makeDraggable: function(table) { + // Now initialise the rows + var rows = table.rows; //getElementsByTagName("tr") + var config = table.tableDnDConfig; + for (var i=0; i<rows.length; i++) { + // To make non-draggable rows, add the nodrag class (eg for Category and Header rows) + // inspired by John Tarr and Famic + var nodrag = $(rows[i]).hasClass("nodrag"); + if (! nodrag) { //There is no NoDnD attribute on rows I want to drag + jQuery(rows[i]).mousedown(function(ev) { + if (ev.target.tagName == "TD") { + jQuery.tableDnD.dragObject = this; + jQuery.tableDnD.currentTable = table; + jQuery.tableDnD.mouseOffset = jQuery.tableDnD.getMouseOffset(this, ev); + if (config.onDragStart) { + // Call the onDrop method if there is one + config.onDragStart(table, this); + } + return false; + } + }).css("cursor", "move"); // Store the tableDnD object + } + } + }, + + /** Get the mouse coordinates from the event (allowing for browser differences) */ + mouseCoords: function(ev){ + if(ev.pageX || ev.pageY){ + return {x:ev.pageX, y:ev.pageY}; + } + return { + x:ev.clientX + document.body.scrollLeft - document.body.clientLeft, + y:ev.clientY + document.body.scrollTop - document.body.clientTop + }; + }, + + /** Given a target element and a mouse event, get the mouse offset from that element. + To do this we need the element's position and the mouse position */ + getMouseOffset: function(target, ev) { + ev = ev || window.event; + + var docPos = this.getPosition(target); + var mousePos = this.mouseCoords(ev); + return {x:mousePos.x - docPos.x, y:mousePos.y - docPos.y}; + }, + + /** Get the position of an element by going up the DOM tree and adding up all the offsets */ + getPosition: function(e){ + var left = 0; + var top = 0; + /** Safari fix -- thanks to Luis Chato for this! */ + if (e.offsetHeight == 0) { + /** Safari 2 doesn't correctly grab the offsetTop of a table row + this is detailed here: + http://jacob.peargrove.com/blog/2006/technical/table-row-offsettop-bug-in-safari/ + the solution is likewise noted there, grab the offset of a table cell in the row - the firstChild. + note that firefox will return a text node as a first child, so designing a more thorough + solution may need to take that into account, for now this seems to work in firefox, safari, ie */ + e = e.firstChild; // a table cell + } + + while (e.offsetParent){ + left += e.offsetLeft; + top += e.offsetTop; + e = e.offsetParent; + } + + left += e.offsetLeft; + top += e.offsetTop; + + return {x:left, y:top}; + }, + + mousemove: function(ev) { + if (jQuery.tableDnD.dragObject == null) { + return; + } + + var dragObj = jQuery(jQuery.tableDnD.dragObject); + var config = jQuery.tableDnD.currentTable.tableDnDConfig; + var mousePos = jQuery.tableDnD.mouseCoords(ev); + var y = mousePos.y - jQuery.tableDnD.mouseOffset.y; + //auto scroll the window + var yOffset = window.pageYOffset; + if (document.all) { + // Windows version + //yOffset=document.body.scrollTop; + if (typeof document.compatMode != 'undefined' && + document.compatMode != 'BackCompat') { + yOffset = document.documentElement.scrollTop; + } + else if (typeof document.body != 'undefined') { + yOffset=document.body.scrollTop; + } + + } + + if (mousePos.y-yOffset < config.scrollAmount) { + window.scrollBy(0, -config.scrollAmount); + } else { + var windowHeight = window.innerHeight ? window.innerHeight + : document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight; + if (windowHeight-(mousePos.y-yOffset) < config.scrollAmount) { + window.scrollBy(0, config.scrollAmount); + } + } + + + if (y != jQuery.tableDnD.oldY) { + // work out if we're going up or down... + var movingDown = y > jQuery.tableDnD.oldY; + // update the old value + jQuery.tableDnD.oldY = y; + // update the style to show we're dragging + if (config.onDragClass) { + dragObj.addClass(config.onDragClass); + } else { + dragObj.css(config.onDragStyle); + } + // If we're over a row then move the dragged row to there so that the user sees the + // effect dynamically + var currentRow = jQuery.tableDnD.findDropTargetRow(dragObj, y); + if (currentRow) { + // TODO worry about what happens when there are multiple TBODIES + if (movingDown && jQuery.tableDnD.dragObject != currentRow) { + jQuery.tableDnD.dragObject.parentNode.insertBefore(jQuery.tableDnD.dragObject, currentRow.nextSibling); + } else if (! movingDown && jQuery.tableDnD.dragObject != currentRow) { + jQuery.tableDnD.dragObject.parentNode.insertBefore(jQuery.tableDnD.dragObject, currentRow); + } + } + } + + return false; + }, + + /** We're only worried about the y position really, because we can only move rows up and down */ + findDropTargetRow: function(draggedRow, y) { + var rows = jQuery.tableDnD.currentTable.rows; + for (var i=0; i<rows.length; i++) { + var row = rows[i]; + var rowY = this.getPosition(row).y; + var rowHeight = parseInt(row.offsetHeight)/2; + if (row.offsetHeight == 0) { + rowY = this.getPosition(row.firstChild).y; + rowHeight = parseInt(row.firstChild.offsetHeight)/2; + } + // Because we always have to insert before, we need to offset the height a bit + if ((y > rowY - rowHeight) && (y < (rowY + rowHeight))) { + // that's the row we're over + // If it's the same as the current row, ignore it + if (row == draggedRow) {return null;} + var config = jQuery.tableDnD.currentTable.tableDnDConfig; + if (config.onAllowDrop) { + if (config.onAllowDrop(draggedRow, row)) { + return row; + } else { + return null; + } + } else { + // If a row has nodrop class, then don't allow dropping (inspired by John Tarr and Famic) + var nodrop = $(row).hasClass("nodrop"); + if (! nodrop) { + return row; + } else { + return null; + } + } + return row; + } + } + return null; + }, + + mouseup: function(e) { + if (jQuery.tableDnD.currentTable && jQuery.tableDnD.dragObject) { + var droppedRow = jQuery.tableDnD.dragObject; + var config = jQuery.tableDnD.currentTable.tableDnDConfig; + // If we have a dragObject, then we need to release it, + // The row will already have been moved to the right place so we just reset stuff + if (config.onDragClass) { + jQuery(droppedRow).removeClass(config.onDragClass); + } else { + jQuery(droppedRow).css(config.onDropStyle); + } + jQuery.tableDnD.dragObject = null; + if (config.onDrop) { + // Call the onDrop method if there is one + config.onDrop(jQuery.tableDnD.currentTable, droppedRow); + } + jQuery.tableDnD.currentTable = null; // let go of the table too + } + }, + + serialize: function() { + if (jQuery.tableDnD.currentTable) { + var result = ""; + var tableId = jQuery.tableDnD.currentTable.id; + var rows = jQuery.tableDnD.currentTable.rows; + for (var i=0; i<rows.length; i++) { + if (result.length > 0) result += "&"; + result += tableId + '[]=' + rows[i].id; + } + return result; + } else { + return "Error: No Table id set, you need to set an id on your table and every row"; + } + } +} + +jQuery.fn.extend( + { + tableDnD : jQuery.tableDnD.build + } + ); diff --git a/cms/static/js/main.js b/cms/static/js/main.js new file mode 100644 index 0000000000000000000000000000000000000000..2d72edc4bf49c448091adce915dbd45d51b82792 --- /dev/null +++ b/cms/static/js/main.js @@ -0,0 +1,85 @@ +$(document).ready(function(){ + $('section.main-content').children().hide(); + + $(function(){ + $('.editable').inlineEdit(); + $('.editable-textarea').inlineEdit({control: 'textarea'}); + }); + + var heighest = 0; + $('.cal ol > li').each(function(){ + heighest = ($(this).height() > heighest) ? $(this).height() : heighest; + + }); + + $('.cal ol > li').css('height',heighest + 'px'); + + $('.add-new-section').click(function() { + return false; + }); + + $('.new-week .close').click( function(){ + $(this).parents('.new-week').hide(); + $('p.add-new-week').show(); + return false; + }); + + $('.save-update').click(function(){ + $(this).parent().parent().hide(); + return false; + }); + + setHeight = function(){ + var windowHeight = $(this).height(); + var contentHeight = windowHeight - 29; + + $('section.main-content > section').css('min-height', contentHeight); + $('body.content .cal').css('height', contentHeight); + + $('.edit-week').click( function() { + $('body').addClass('content'); + $('body.content .cal').css('height', contentHeight); + $('section.week-new').show(); + return false; + }); + + $('.cal ol li header h1 a').click( function() { + $('body').addClass('content'); + $('body.content .cal').css('height', contentHeight); + $('section.week-edit').show(); + return false; + }); + + $('a.sequence-edit').click(function(){ + $('body').addClass('content'); + $('body.content .cal').css('height', contentHeight); + $('section.sequence-edit').show(); + return false; + }); + } + + $(document).ready(setHeight); + $(window).bind('resize', setHeight); + + $('.video-new a').click(function(){ + $('section.video-new').show(); + return false; + }); + + $('a.video-edit').click(function(){ + $('section.video-edit').show(); + return false; + }); + + $('.problem-new a').click(function(){ + $('section.problem-new').show(); + return false; + }); + + $('a.problem-edit').click(function(){ + $('section.problem-edit').show(); + return false; + }); + +}); + diff --git a/cms/static/js/markitup/jquery.markitup.js b/cms/static/js/markitup/jquery.markitup.js new file mode 100644 index 0000000000000000000000000000000000000000..10add9d27c0c2a5ca565a86781e940b61e1f6b82 --- /dev/null +++ b/cms/static/js/markitup/jquery.markitup.js @@ -0,0 +1,593 @@ +// ---------------------------------------------------------------------------- +// markItUp! Universal MarkUp Engine, JQuery plugin +// v 1.1.x +// Dual licensed under the MIT and GPL licenses. +// ---------------------------------------------------------------------------- +// Copyright (C) 2007-2011 Jay Salvat +// http://markitup.jaysalvat.com/ +// ---------------------------------------------------------------------------- +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// ---------------------------------------------------------------------------- +(function($) { + $.fn.markItUp = function(settings, extraSettings) { + var options, ctrlKey, shiftKey, altKey; + ctrlKey = shiftKey = altKey = false; + + options = { id: '', + nameSpace: '', + root: '', + previewInWindow: '', // 'width=800, height=600, resizable=yes, scrollbars=yes' + previewAutoRefresh: true, + previewPosition: 'after', + previewTemplatePath: '~/templates/preview.html', + previewParser: false, + previewParserPath: '', + previewParserVar: 'data', + resizeHandle: true, + beforeInsert: '', + afterInsert: '', + onEnter: {}, + onShiftEnter: {}, + onCtrlEnter: {}, + onTab: {}, + markupSet: [ { /* set */ } ] + }; + $.extend(options, settings, extraSettings); + + // compute markItUp! path + if (!options.root) { + $('script').each(function(a, tag) { + miuScript = $(tag).get(0).src.match(/(.*)jquery\.markitup(\.pack)?\.js$/); + if (miuScript !== null) { + options.root = miuScript[1]; + } + }); + } + + return this.each(function() { + var $$, textarea, levels, scrollPosition, caretPosition, caretOffset, + clicked, hash, header, footer, previewWindow, template, iFrame, abort; + $$ = $(this); + textarea = this; + levels = []; + abort = false; + scrollPosition = caretPosition = 0; + caretOffset = -1; + + options.previewParserPath = localize(options.previewParserPath); + options.previewTemplatePath = localize(options.previewTemplatePath); + + // apply the computed path to ~/ + function localize(data, inText) { + if (inText) { + return data.replace(/("|')~\//g, "$1"+options.root); + } + return data.replace(/^~\//, options.root); + } + + // init and build editor + function init() { + id = ''; nameSpace = ''; + if (options.id) { + id = 'id="'+options.id+'"'; + } else if ($$.attr("id")) { + id = 'id="markItUp'+($$.attr("id").substr(0, 1).toUpperCase())+($$.attr("id").substr(1))+'"'; + + } + if (options.nameSpace) { + nameSpace = 'class="'+options.nameSpace+'"'; + } + $$.wrap('<div '+nameSpace+'></div>'); + $$.wrap('<div '+id+' class="markItUp"></div>'); + $$.wrap('<div class="markItUpContainer"></div>'); + $$.addClass("markItUpEditor"); + + // add the header before the textarea + header = $('<div class="markItUpHeader"></div>').insertBefore($$); + $(dropMenus(options.markupSet)).appendTo(header); + + // add the footer after the textarea + footer = $('<div class="markItUpFooter"></div>').insertAfter($$); + + // add the resize handle after textarea + if (options.resizeHandle === true && $.browser.safari !== true) { + resizeHandle = $('<div class="markItUpResizeHandle"></div>') + .insertAfter($$) + .bind("mousedown", function(e) { + var h = $$.height(), y = e.clientY, mouseMove, mouseUp; + mouseMove = function(e) { + $$.css("height", Math.max(20, e.clientY+h-y)+"px"); + return false; + }; + mouseUp = function(e) { + $("html").unbind("mousemove", mouseMove).unbind("mouseup", mouseUp); + return false; + }; + $("html").bind("mousemove", mouseMove).bind("mouseup", mouseUp); + }); + footer.append(resizeHandle); + } + + // listen key events + $$.keydown(keyPressed).keyup(keyPressed); + + // bind an event to catch external calls + $$.bind("insertion", function(e, settings) { + if (settings.target !== false) { + get(); + } + if (textarea === $.markItUp.focused) { + markup(settings); + } + }); + + // remember the last focus + $$.focus(function() { + $.markItUp.focused = this; + }); + } + + // recursively build header with dropMenus from markupset + function dropMenus(markupSet) { + var ul = $('<ul></ul>'), i = 0; + $('li:hover > ul', ul).css('display', 'block'); + $.each(markupSet, function() { + var button = this, t = '', title, li, j; + title = (button.key) ? (button.name||'')+' [Ctrl+'+button.key+']' : (button.name||''); + key = (button.key) ? 'accesskey="'+button.key+'"' : ''; + if (button.separator) { + li = $('<li class="markItUpSeparator">'+(button.separator||'')+'</li>').appendTo(ul); + } else { + i++; + for (j = levels.length -1; j >= 0; j--) { + t += levels[j]+"-"; + } + li = $('<li class="markItUpButton markItUpButton'+t+(i)+' '+(button.className||'')+'"><a href="" '+key+' title="'+title+'">'+(button.name||'')+'</a></li>') + .bind("contextmenu", function() { // prevent contextmenu on mac and allow ctrl+click + return false; + }).click(function() { + return false; + }).bind("focusin", function(){ + $$.focus(); + }).mouseup(function() { + if (button.call) { + eval(button.call)(); + } + setTimeout(function() { markup(button) },1); + return false; + }).hover(function() { + $('> ul', this).show(); + $(document).one('click', function() { // close dropmenu if click outside + $('ul ul', header).hide(); + } + ); + }, function() { + $('> ul', this).hide(); + } + ).appendTo(ul); + if (button.dropMenu) { + levels.push(i); + $(li).addClass('markItUpDropMenu').append(dropMenus(button.dropMenu)); + } + } + }); + levels.pop(); + return ul; + } + + // markItUp! markups + function magicMarkups(string) { + if (string) { + string = string.toString(); + string = string.replace(/\(\!\(([\s\S]*?)\)\!\)/g, + function(x, a) { + var b = a.split('|!|'); + if (altKey === true) { + return (b[1] !== undefined) ? b[1] : b[0]; + } else { + return (b[1] === undefined) ? "" : b[0]; + } + } + ); + // [![prompt]!], [![prompt:!:value]!] + string = string.replace(/\[\!\[([\s\S]*?)\]\!\]/g, + function(x, a) { + var b = a.split(':!:'); + if (abort === true) { + return false; + } + value = prompt(b[0], (b[1]) ? b[1] : ''); + if (value === null) { + abort = true; + } + return value; + } + ); + return string; + } + return ""; + } + + // prepare action + function prepare(action) { + if ($.isFunction(action)) { + action = action(hash); + } + return magicMarkups(action); + } + + // build block to insert + function build(string) { + var openWith = prepare(clicked.openWith); + var placeHolder = prepare(clicked.placeHolder); + var replaceWith = prepare(clicked.replaceWith); + var closeWith = prepare(clicked.closeWith); + var openBlockWith = prepare(clicked.openBlockWith); + var closeBlockWith = prepare(clicked.closeBlockWith); + var multiline = clicked.multiline; + + if (replaceWith !== "") { + block = openWith + replaceWith + closeWith; + } else if (selection === '' && placeHolder !== '') { + block = openWith + placeHolder + closeWith; + } else { + string = string || selection; + + var lines = selection.split(/\r?\n/), blocks = []; + + for (var l=0; l < lines.length; l++) { + line = lines[l]; + var trailingSpaces; + if (trailingSpaces = line.match(/ *$/)) { + blocks.push(openWith + line.replace(/ *$/g, '') + closeWith + trailingSpaces); + } else { + blocks.push(openWith + line + closeWith); + } + } + + block = blocks.join("\n"); + } + + block = openBlockWith + block + closeBlockWith; + + return { block:block, + openWith:openWith, + replaceWith:replaceWith, + placeHolder:placeHolder, + closeWith:closeWith + }; + } + + // define markup to insert + function markup(button) { + var len, j, n, i; + hash = clicked = button; + get(); + $.extend(hash, { line:"", + root:options.root, + textarea:textarea, + selection:(selection||''), + caretPosition:caretPosition, + ctrlKey:ctrlKey, + shiftKey:shiftKey, + altKey:altKey + } + ); + // callbacks before insertion + prepare(options.beforeInsert); + prepare(clicked.beforeInsert); + if ((ctrlKey === true && shiftKey === true) || button.multiline === true) { + prepare(clicked.beforeMultiInsert); + } + $.extend(hash, { line:1 }); + + if ((ctrlKey === true && shiftKey === true)) { + lines = selection.split(/\r?\n/); + for (j = 0, n = lines.length, i = 0; i < n; i++) { + if ($.trim(lines[i]) !== '') { + $.extend(hash, { line:++j, selection:lines[i] } ); + lines[i] = build(lines[i]).block; + } else { + lines[i] = ""; + } + } + string = { block:lines.join('\n')}; + start = caretPosition; + len = string.block.length + (($.browser.opera) ? n-1 : 0); + } else if (ctrlKey === true) { + string = build(selection); + start = caretPosition + string.openWith.length; + len = string.block.length - string.openWith.length - string.closeWith.length; + len = len - (string.block.match(/ $/) ? 1 : 0); + len -= fixIeBug(string.block); + } else if (shiftKey === true) { + string = build(selection); + start = caretPosition; + len = string.block.length; + len -= fixIeBug(string.block); + } else { + string = build(selection); + start = caretPosition + string.block.length ; + len = 0; + start -= fixIeBug(string.block); + } + if ((selection === '' && string.replaceWith === '')) { + caretOffset += fixOperaBug(string.block); + + start = caretPosition + string.openWith.length; + len = string.block.length - string.openWith.length - string.closeWith.length; + + caretOffset = $$.val().substring(caretPosition, $$.val().length).length; + caretOffset -= fixOperaBug($$.val().substring(0, caretPosition)); + } + $.extend(hash, { caretPosition:caretPosition, scrollPosition:scrollPosition } ); + + if (string.block !== selection && abort === false) { + insert(string.block); + set(start, len); + } else { + caretOffset = -1; + } + get(); + + $.extend(hash, { line:'', selection:selection }); + + // callbacks after insertion + if ((ctrlKey === true && shiftKey === true) || button.multiline === true) { + prepare(clicked.afterMultiInsert); + } + prepare(clicked.afterInsert); + prepare(options.afterInsert); + + // refresh preview if opened + if (previewWindow && options.previewAutoRefresh) { + refreshPreview(); + } + + // reinit keyevent + shiftKey = altKey = ctrlKey = abort = false; + } + + // Substract linefeed in Opera + function fixOperaBug(string) { + if ($.browser.opera) { + return string.length - string.replace(/\n*/g, '').length; + } + return 0; + } + // Substract linefeed in IE + function fixIeBug(string) { + if ($.browser.msie) { + return string.length - string.replace(/\r*/g, '').length; + } + return 0; + } + + // add markup + function insert(block) { + if (document.selection) { + var newSelection = document.selection.createRange(); + newSelection.text = block; + } else { + textarea.value = textarea.value.substring(0, caretPosition) + block + textarea.value.substring(caretPosition + selection.length, textarea.value.length); + } + } + + // set a selection + function set(start, len) { + if (textarea.createTextRange){ + // quick fix to make it work on Opera 9.5 + if ($.browser.opera && $.browser.version >= 9.5 && len == 0) { + return false; + } + range = textarea.createTextRange(); + range.collapse(true); + range.moveStart('character', start); + range.moveEnd('character', len); + range.select(); + } else if (textarea.setSelectionRange ){ + textarea.setSelectionRange(start, start + len); + } + textarea.scrollTop = scrollPosition; + textarea.focus(); + } + + // get the selection + function get() { + textarea.focus(); + + scrollPosition = textarea.scrollTop; + if (document.selection) { + selection = document.selection.createRange().text; + if ($.browser.msie) { // ie + var range = document.selection.createRange(), rangeCopy = range.duplicate(); + rangeCopy.moveToElementText(textarea); + caretPosition = -1; + while(rangeCopy.inRange(range)) { + rangeCopy.moveStart('character'); + caretPosition ++; + } + } else { // opera + caretPosition = textarea.selectionStart; + } + } else { // gecko & webkit + caretPosition = textarea.selectionStart; + + selection = textarea.value.substring(caretPosition, textarea.selectionEnd); + } + return selection; + } + + // open preview window + function preview() { + if (!previewWindow || previewWindow.closed) { + if (options.previewInWindow) { + previewWindow = window.open('', 'preview', options.previewInWindow); + $(window).unload(function() { + previewWindow.close(); + }); + } else { + iFrame = $('<iframe class="markItUpPreviewFrame"></iframe>'); + if (options.previewPosition == 'after') { + iFrame.insertAfter(footer); + } else { + iFrame.insertBefore(header); + } + previewWindow = iFrame[iFrame.length - 1].contentWindow || frame[iFrame.length - 1]; + } + } else if (altKey === true) { + if (iFrame) { + iFrame.remove(); + } else { + previewWindow.close(); + } + previewWindow = iFrame = false; + } + if (!options.previewAutoRefresh) { + refreshPreview(); + } + if (options.previewInWindow) { + previewWindow.focus(); + } + } + + // refresh Preview window + function refreshPreview() { + renderPreview(); + } + + function renderPreview() { + var phtml; + if (options.previewParser && typeof options.previewParser === 'function') { + var data = options.previewParser( $$.val() ); + writeInPreview( localize(data, 1) ); + } else if (options.previewParserPath !== '') { + $.ajax({ + type: 'POST', + dataType: 'text', + global: false, + url: options.previewParserPath, + data: options.previewParserVar+'='+encodeURIComponent($$.val()), + success: function(data) { + writeInPreview( localize(data, 1) ); + } + }); + } else { + if (!template) { + $.ajax({ + url: options.previewTemplatePath, + dataType: 'text', + global: false, + success: function(data) { + writeInPreview( localize(data, 1).replace(/<!-- content -->/g, $$.val()) ); + } + }); + } + } + return false; + } + + function writeInPreview(data) { + if (previewWindow.document) { + try { + sp = previewWindow.document.documentElement.scrollTop + } catch(e) { + sp = 0; + } + previewWindow.document.open(); + previewWindow.document.write(data); + previewWindow.document.close(); + previewWindow.document.documentElement.scrollTop = sp; + } + } + + // set keys pressed + function keyPressed(e) { + shiftKey = e.shiftKey; + altKey = e.altKey; + ctrlKey = (!(e.altKey && e.ctrlKey)) ? (e.ctrlKey || e.metaKey) : false; + + if (e.type === 'keydown') { + if (ctrlKey === true) { + li = $('a[accesskey="'+String.fromCharCode(e.keyCode)+'"]', header).parent('li'); + if (li.length !== 0) { + ctrlKey = false; + setTimeout(function() { + li.triggerHandler('mouseup'); + },1); + return false; + } + } + if (e.keyCode === 13 || e.keyCode === 10) { // Enter key + if (ctrlKey === true) { // Enter + Ctrl + ctrlKey = false; + markup(options.onCtrlEnter); + return options.onCtrlEnter.keepDefault; + } else if (shiftKey === true) { // Enter + Shift + shiftKey = false; + markup(options.onShiftEnter); + return options.onShiftEnter.keepDefault; + } else { // only Enter + markup(options.onEnter); + return options.onEnter.keepDefault; + } + } + if (e.keyCode === 9) { // Tab key + if (shiftKey == true || ctrlKey == true || altKey == true) { + return false; + } + if (caretOffset !== -1) { + get(); + caretOffset = $$.val().length - caretOffset; + set(caretOffset, 0); + caretOffset = -1; + return false; + } else { + markup(options.onTab); + return options.onTab.keepDefault; + } + } + } + } + + init(); + }); + }; + + $.fn.markItUpRemove = function() { + return this.each(function() { + var $$ = $(this).unbind().removeClass('markItUpEditor'); + $$.parent('div').parent('div.markItUp').parent('div').replaceWith($$); + } + ); + }; + + $.markItUp = function(settings) { + var options = { target:false }; + $.extend(options, settings); + if (options.target) { + return $(options.target).each(function() { + $(this).focus(); + $(this).trigger('insertion', [options]); + }); + } else { + $('textarea').trigger('insertion', [options]); + } + }; +})(jQuery); diff --git a/cms/static/js/markitup/sets/wiki/images/bold.png b/cms/static/js/markitup/sets/wiki/images/bold.png new file mode 100644 index 0000000000000000000000000000000000000000..889ae80e37b6167cc15f2a89e05a183815ec18b2 Binary files /dev/null and b/cms/static/js/markitup/sets/wiki/images/bold.png differ diff --git a/cms/static/js/markitup/sets/wiki/images/clean.png b/cms/static/js/markitup/sets/wiki/images/clean.png new file mode 100644 index 0000000000000000000000000000000000000000..7e7cefb8e174c738a84f8f3a6bf15d8e8f2c66d1 Binary files /dev/null and b/cms/static/js/markitup/sets/wiki/images/clean.png differ diff --git a/cms/static/js/markitup/sets/wiki/images/code.png b/cms/static/js/markitup/sets/wiki/images/code.png new file mode 100644 index 0000000000000000000000000000000000000000..63fe6ceff5bfcedb9670279d4bb8d25807f6ecee Binary files /dev/null and b/cms/static/js/markitup/sets/wiki/images/code.png differ diff --git a/cms/static/js/markitup/sets/wiki/images/h1.png b/cms/static/js/markitup/sets/wiki/images/h1.png new file mode 100644 index 0000000000000000000000000000000000000000..9c122e91e358860733eaf08fd543e5fc585d4cfd Binary files /dev/null and b/cms/static/js/markitup/sets/wiki/images/h1.png differ diff --git a/cms/static/js/markitup/sets/wiki/images/h2.png b/cms/static/js/markitup/sets/wiki/images/h2.png new file mode 100644 index 0000000000000000000000000000000000000000..fbd87657fbe001c0a78fb095284fffc32e739497 Binary files /dev/null and b/cms/static/js/markitup/sets/wiki/images/h2.png differ diff --git a/cms/static/js/markitup/sets/wiki/images/h3.png b/cms/static/js/markitup/sets/wiki/images/h3.png new file mode 100644 index 0000000000000000000000000000000000000000..c7836cf09e4565cc76c13bd14c13971c9e093c40 Binary files /dev/null and b/cms/static/js/markitup/sets/wiki/images/h3.png differ diff --git a/cms/static/js/markitup/sets/wiki/images/h4.png b/cms/static/js/markitup/sets/wiki/images/h4.png new file mode 100644 index 0000000000000000000000000000000000000000..4e929eaf583f10cf50eb1666ff6530b9d4cc7915 Binary files /dev/null and b/cms/static/js/markitup/sets/wiki/images/h4.png differ diff --git a/cms/static/js/markitup/sets/wiki/images/h5.png b/cms/static/js/markitup/sets/wiki/images/h5.png new file mode 100644 index 0000000000000000000000000000000000000000..30cabebf7445e168a0f31b0ed68c43d54eaf017d Binary files /dev/null and b/cms/static/js/markitup/sets/wiki/images/h5.png differ diff --git a/cms/static/js/markitup/sets/wiki/images/image.png b/cms/static/js/markitup/sets/wiki/images/image.png new file mode 100644 index 0000000000000000000000000000000000000000..fc3c393caa3bc4371d12d0c67ffd6d333ecf1d8e Binary files /dev/null and b/cms/static/js/markitup/sets/wiki/images/image.png differ diff --git a/cms/static/js/markitup/sets/wiki/images/italic.png b/cms/static/js/markitup/sets/wiki/images/italic.png new file mode 100644 index 0000000000000000000000000000000000000000..8482ac8cb1eb8bc8edbf64085108f0fbd204fadb Binary files /dev/null and b/cms/static/js/markitup/sets/wiki/images/italic.png differ diff --git a/cms/static/js/markitup/sets/wiki/images/link.png b/cms/static/js/markitup/sets/wiki/images/link.png new file mode 100644 index 0000000000000000000000000000000000000000..25eacb7c2524142262d68bf729c5e2b61adfd6d4 Binary files /dev/null and b/cms/static/js/markitup/sets/wiki/images/link.png differ diff --git a/cms/static/js/markitup/sets/wiki/images/list-bullet.png b/cms/static/js/markitup/sets/wiki/images/list-bullet.png new file mode 100644 index 0000000000000000000000000000000000000000..4a8672bde48f806d3d4d37db192588a9aa3eac10 Binary files /dev/null and b/cms/static/js/markitup/sets/wiki/images/list-bullet.png differ diff --git a/cms/static/js/markitup/sets/wiki/images/list-numeric.png b/cms/static/js/markitup/sets/wiki/images/list-numeric.png new file mode 100644 index 0000000000000000000000000000000000000000..33b0b8df394dd66b20f74b551d5d52eb53cf335d Binary files /dev/null and b/cms/static/js/markitup/sets/wiki/images/list-numeric.png differ diff --git a/cms/static/js/markitup/sets/wiki/images/picture.png b/cms/static/js/markitup/sets/wiki/images/picture.png new file mode 100644 index 0000000000000000000000000000000000000000..4a158fef7e0da8fd19525f574f2c4966443866cf Binary files /dev/null and b/cms/static/js/markitup/sets/wiki/images/picture.png differ diff --git a/cms/static/js/markitup/sets/wiki/images/preview.png b/cms/static/js/markitup/sets/wiki/images/preview.png new file mode 100644 index 0000000000000000000000000000000000000000..a9925a06ab02db30c1e7ead9c701c15bc63145cb Binary files /dev/null and b/cms/static/js/markitup/sets/wiki/images/preview.png differ diff --git a/cms/static/js/markitup/sets/wiki/images/quotes.png b/cms/static/js/markitup/sets/wiki/images/quotes.png new file mode 100644 index 0000000000000000000000000000000000000000..e54ebebafb5072fabac9a0f3d8a79fcee3265f9f Binary files /dev/null and b/cms/static/js/markitup/sets/wiki/images/quotes.png differ diff --git a/cms/static/js/markitup/sets/wiki/images/stroke.png b/cms/static/js/markitup/sets/wiki/images/stroke.png new file mode 100644 index 0000000000000000000000000000000000000000..612058a78eba4e3ca259aa13417fd60cd6cf2fbd Binary files /dev/null and b/cms/static/js/markitup/sets/wiki/images/stroke.png differ diff --git a/cms/static/js/markitup/sets/wiki/images/url.png b/cms/static/js/markitup/sets/wiki/images/url.png new file mode 100644 index 0000000000000000000000000000000000000000..b8edc1265db4bf69814875d1c10b8761f7009e23 Binary files /dev/null and b/cms/static/js/markitup/sets/wiki/images/url.png differ diff --git a/cms/static/js/markitup/sets/wiki/set.js b/cms/static/js/markitup/sets/wiki/set.js new file mode 100644 index 0000000000000000000000000000000000000000..895625621dcf426833864e403c76c4baf5242155 --- /dev/null +++ b/cms/static/js/markitup/sets/wiki/set.js @@ -0,0 +1,34 @@ +// ---------------------------------------------------------------------------- +// markItUp! +// ---------------------------------------------------------------------------- +// Copyright (C) 2008 Jay Salvat +// http://markitup.jaysalvat.com/ +// ---------------------------------------------------------------------------- +myWikiSettings = { + nameSpace: "wiki", // Useful to prevent multi-instances CSS conflict + previewParserPath: "~/sets/wiki/preview.php", + onShiftEnter: {keepDefault:false, replaceWith:'\n\n'}, + markupSet: [ + {name:'Heading 1', key:'1', openWith:'== ', closeWith:' ==', placeHolder:'Your title here...' }, + {name:'Heading 2', key:'2', openWith:'=== ', closeWith:' ===', placeHolder:'Your title here...' }, + {name:'Heading 3', key:'3', openWith:'==== ', closeWith:' ====', placeHolder:'Your title here...' }, + {name:'Heading 4', key:'4', openWith:'===== ', closeWith:' =====', placeHolder:'Your title here...' }, + {name:'Heading 5', key:'5', openWith:'====== ', closeWith:' ======', placeHolder:'Your title here...' }, + {separator:'---------------' }, + {name:'Bold', key:'B', openWith:"'''", closeWith:"'''"}, + {name:'Italic', key:'I', openWith:"''", closeWith:"''"}, + {name:'Stroke through', key:'S', openWith:'<s>', closeWith:'</s>'}, + {separator:'---------------' }, + {name:'Bulleted list', openWith:'(!(* |!|*)!)'}, + {name:'Numeric list', openWith:'(!(# |!|#)!)'}, + {separator:'---------------' }, + {name:'Picture', key:'P', replaceWith:'[[Image:[![Url:!:http://]!]|[![name]!]]]'}, + {name:'Link', key:'L', openWith:'[[![Link]!] ', closeWith:']', placeHolder:'Your text to link here...' }, + {name:'Url', openWith:'[[![Url:!:http://]!] ', closeWith:']', placeHolder:'Your text to link here...' }, + {separator:'---------------' }, + {name:'Quotes', openWith:'(!(> |!|>)!)'}, + {name:'Code', openWith:'(!(<source lang="[![Language:!:php]!]">|!|<pre>)!)', closeWith:'(!(</source>|!|</pre>)!)'}, + {separator:'---------------' }, + {name:'Preview', call:'preview', className:'preview'} + ] +} diff --git a/cms/static/js/markitup/sets/wiki/style.css b/cms/static/js/markitup/sets/wiki/style.css new file mode 100644 index 0000000000000000000000000000000000000000..0a26c698f5bc92ef488f2d0e100fbde24143c1c6 --- /dev/null +++ b/cms/static/js/markitup/sets/wiki/style.css @@ -0,0 +1,57 @@ +/* ------------------------------------------------------------------- +// markItUp! +// By Jay Salvat - http://markitup.jaysalvat.com/ +// ------------------------------------------------------------------*/ +.wiki .markItUpButton1 a { + background-image:url(images/h1.png); +} +.wiki .markItUpButton2 a { + background-image:url(images/h2.png); +} +.wiki .markItUpButton3 a { + background-image:url(images/h3.png); +} +.wiki .markItUpButton4 a { + background-image:url(images/h4.png); +} +.wiki .markItUpButton5 a { + background-image:url(images/h5.png); +} + +.wiki .markItUpButton6 a { + background-image:url(images/bold.png); +} +.wiki .markItUpButton7 a { + background-image:url(images/italic.png); +} +.wiki .markItUpButton8 a { + background-image:url(images/stroke.png); +} + +.wiki .markItUpButton9 a { + background-image:url(images/list-bullet.png); +} +.wiki .markItUpButton10 a { + background-image:url(images/list-numeric.png); +} + +.wiki .markItUpButton11 a { + background-image:url(images/picture.png); +} +.wiki .markItUpButton12 a { + background-image:url(images/link.png); +} +.wiki .markItUpButton13 a { + background-image:url(images/url.png); +} + +.wiki .markItUpButton14 a { + background-image:url(images/quotes.png); +} +.wiki .markItUpButton15 a { + background-image:url(images/code.png); +} + +.wiki .preview a { + background-image:url(images/preview.png); +} diff --git a/cms/static/js/markitup/skins/simple/images/handle.png b/cms/static/js/markitup/skins/simple/images/handle.png new file mode 100644 index 0000000000000000000000000000000000000000..3993b20337e33a36c9125d139f1f53a279a4c128 Binary files /dev/null and b/cms/static/js/markitup/skins/simple/images/handle.png differ diff --git a/cms/static/js/markitup/skins/simple/images/menu.png b/cms/static/js/markitup/skins/simple/images/menu.png new file mode 100644 index 0000000000000000000000000000000000000000..44a07afd30f499cdba30847094a1e92f13e1320e Binary files /dev/null and b/cms/static/js/markitup/skins/simple/images/menu.png differ diff --git a/cms/static/js/markitup/skins/simple/images/submenu.png b/cms/static/js/markitup/skins/simple/images/submenu.png new file mode 100644 index 0000000000000000000000000000000000000000..03d1977aecf31666578422805c60cf61562ceea1 Binary files /dev/null and b/cms/static/js/markitup/skins/simple/images/submenu.png differ diff --git a/cms/static/js/markitup/skins/simple/style.css b/cms/static/js/markitup/skins/simple/style.css new file mode 100644 index 0000000000000000000000000000000000000000..af8dc9cdb5a2c16966bc175b90cbff1c936dff6a --- /dev/null +++ b/cms/static/js/markitup/skins/simple/style.css @@ -0,0 +1,118 @@ +/* ------------------------------------------------------------------- +// markItUp! Universal MarkUp Engine, JQuery plugin +// By Jay Salvat - http://markitup.jaysalvat.com/ +// ------------------------------------------------------------------*/ +.markItUp * { + margin:0px; padding:0px; + outline:none; +} +.markItUp a:link, +.markItUp a:visited { + color:#000; + text-decoration:none; +} +.markItUp { + /* width:700px; */ + margin:5px 0 10px 0; +} +.markItUpContainer { + font:11px Verdana, Arial, Helvetica, sans-serif; +} +.markItUpEditor { + font:12px 'Courier New', Courier, monospace; + padding:5px; + /* width:690px; */ + height:320px; + clear:both; + line-height:18px; + overflow:auto; +} +.markItUpPreviewFrame { + overflow:auto; + background-color:#FFF; + width:99.9%; + height:300px; + margin:5px 0; +} +.markItUpFooter { + width:100%; +} +.markItUpResizeHandle { + overflow:hidden; + width:22px; height:5px; + margin-left:auto; + margin-right:auto; + background-image:url(images/handle.png); + cursor:n-resize; +} +/***************************************************************************************/ +/* first row of buttons */ +.markItUpHeader ul li { + list-style:none; + float:left; + position:relative; +} +.markItUpHeader ul li:hover > ul{ + display:block; +} +.markItUpHeader ul .markItUpDropMenu { + background:transparent url(images/menu.png) no-repeat 115% 50%; + margin-right:5px; +} +.markItUpHeader ul .markItUpDropMenu li { + margin-right:0px; +} +/* next rows of buttons */ +.markItUpHeader ul ul { + display:none; + position:absolute; + top:18px; left:0px; + background:#FFF; + border:1px solid #000; +} +.markItUpHeader ul ul li { + float:none; + border-bottom:1px solid #000; +} +.markItUpHeader ul ul .markItUpDropMenu { + background:#FFF url(images/submenu.png) no-repeat 100% 50%; +} +.markItUpHeader ul .markItUpSeparator { + margin:0 10px; + width:1px; + height:16px; + overflow:hidden; + background-color:#CCC; +} +.markItUpHeader ul ul .markItUpSeparator { + width:auto; height:1px; + margin:0px; +} +/* next rows of buttons */ +.markItUpHeader ul ul ul { + position:absolute; + top:-1px; left:150px; +} +.markItUpHeader ul ul ul li { + float:none; +} +.markItUpHeader ul a { + display:block; + width:16px; height:16px; + text-indent:-10000px; + background-repeat:no-repeat; + padding:3px; + margin:0px; +} +.markItUpHeader ul ul a { + display:block; + padding-left:0px; + text-indent:0; + width:120px; + padding:5px 5px 5px 25px; + background-position:2px 50%; +} +.markItUpHeader ul ul a:hover { + color:#FFF; + background-color:#000; +} diff --git a/cms/static/sass/README.txt b/cms/static/sass/README.txt new file mode 100644 index 0000000000000000000000000000000000000000..72225393e4ec2a95d7c6de7a1f5f21040dc24e89 --- /dev/null +++ b/cms/static/sass/README.txt @@ -0,0 +1,3 @@ +Sass Watch: + +sass --watch cms/static/sass:cms/static/css -r ./cms/static/sass/bourbon/lib/bourbon.rb diff --git a/cms/static/sass/_base.scss b/cms/static/sass/_base.scss new file mode 100644 index 0000000000000000000000000000000000000000..3a2ef86363e70f564a415187c456c0d26c3a28b0 --- /dev/null +++ b/cms/static/sass/_base.scss @@ -0,0 +1,113 @@ +$fg-column: 70px; +$fg-gutter: 26px; +$fg-max-columns: 12; +$body-font-family: "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Geneva, Verdana, sans-serif; + +html { + height: 100%; +} + +body { + @include clearfix(); + height: 100%; + font: 14px $body-font-family; + + > section { + display: table; + width: 100%; + } + + > header { + background: #000; + color: #fff; + display: block; + float: none; + padding: 6px 20px; + width: 100%; + @include box-sizing(border-box); + + nav { + @include clearfix; + + h2 { + font-size: 14px; + text-transform: uppercase; + float: left; + } + + ul { + float: left; + + &.user-nav { + float: right; + } + + li { + @include inline-block(); + margin-left: 15px; + } + } + } + } + + &.content { + section.main-content { + border-left: 2px solid #000; + @include box-sizing(border-box); + width: flex-grid(9); + float: left; + @include box-shadow( -2px 0 3px #ddd ); + } + } +} + +a { + text-decoration: none; + color: #888; +} + +input { + font-family: $body-font-family; +} + +input[type="submit"], .button { + border: 1px solid #ccc; + background: #efefef; + @include border-radius(3px); + padding: 6px; +} + +.new-module { + position: relative; + + a { + padding: 6px; + display: block; + } + + ul.new-dropdown { + list-style: none; + position: absolute; + + li { + display: none; + padding: 6px; + } + + } + + &:hover { + ul.new-dropdown { + display: block; + } + } +} + +.draggable { + width: 7px; + min-height: 14px; + background: url('../img/drag-handle.png') no-repeat center; + text-indent: -9999px; + display: block; + float: right; +} diff --git a/cms/static/sass/_calendar.scss b/cms/static/sass/_calendar.scss new file mode 100644 index 0000000000000000000000000000000000000000..fa10c659505c93e3c58b39fe0dd5c8ec63f143fa --- /dev/null +++ b/cms/static/sass/_calendar.scss @@ -0,0 +1,270 @@ +section.cal { + @include box-sizing(border-box); + padding: 25px; + @include clearfix; + + > header { + @include clearfix; + margin-bottom: 10px; + background: #efefef; + border: 1px solid #ddd; + + h2 { + @include inline-block(); + text-transform: uppercase; + letter-spacing: 1px; + font-size: 14px; + padding: 6px; + margin-left: 6px; + font-size: 12px; + } + + ul { + @include inline-block; + + li { + @include inline-block; + margin-left: 6px; + padding-left: 6px; + border-left: 1px solid #ddd; + padding: 6px; + + a { + @include inline-block(); + } + + ul { + @include inline-block(); + + li { + @include inline-block(); + padding: 0; + border-left: 0; + } + } + } + } + } + + ol { + list-style: none; + @include clearfix; + @include box-sizing(border-box); + border-left: 1px solid #333; + border-top: 1px solid #333; + width: 100%; + + > li { + border-right: 1px solid #333; + border-bottom: 1px solid; + @include box-sizing(border-box); + float: left; + width: flex-grid(3) + ((flex-gutter() * 3) / 4); + + header { + border-bottom: 1px solid #000; + @include box-shadow(0 1px 2px #aaa); + display: block; + margin-bottom: 2px; + + h1 { + font-size: 14px; + text-transform: uppercase; + border-bottom: 1px solid #ccc; + padding: 6px; + + a { + color: #000; + display: block; + } + } + + ul { + li { + background: #fff; + color: #888; + border-bottom: 0; + font-size: 12px; + } + } + } + + ul { + list-style: none; + margin-bottom: 1px; + + li { + background: #efefef; + border-bottom: 1px solid #666; + padding: 6px; + + &.create-module { + position: relative; + + > div { + display: none; + @include position(absolute, 30px 0 0 0); + width: 90%; + background: rgba(#000, .9); + padding: 10px; + @include box-sizing(border-box); + @include border-radius(3px); + z-index: 99; + + &:before { + content: " "; + display: block; + background: rgba(#000, .8); + width: 10px; + height: 10px; + @include position(absolute, -5px 0 0 50%); + @include transform(rotate(45deg)); + } + + ul { + li { + border-bottom: 0; + background: none; + + input { + width: 100%; + @include box-sizing(border-box); + border-color: #000; + padding: 6px; + } + + select { + width: 100%; + @include box-sizing(border-box); + + option { + font-size: 14px; + } + } + + a { + float: right; + + &:first-child { + float: left; + } + } + } + } + } + + &:hover { + div { + display: block; + } + } + } + } + } + } + } + + section.new-section { + margin-top: 10px; + @include inline-block(); + position: relative; + + > a { + @extend .button; + display: block; + } + + section { + display: none; + @include position(absolute, 30px 0 0 0); + background: rgba(#000, .8); + min-width: 300px; + padding: 10px; + @include box-sizing(border-box); + @include border-radius(3px); + z-index: 99; + + &:before { + content: " "; + display: block; + background: rgba(#000, .8); + width: 10px; + height: 10px; + @include position(absolute, -5px 0 0 20%); + @include transform(rotate(45deg)); + } + + form { + + ul { + list-style: none; + + li { + border-bottom: 0; + background: none; + margin-bottom: 6px; + + input { + width: 100%; + @include box-sizing(border-box); + border-color: #000; + padding: 6px; + } + + select { + width: 100%; + @include box-sizing(border-box); + + option { + font-size: 14px; + } + } + + a { + float: right; + + &:first-child { + float: left; + } + } + } + } + } + } + + &:hover { + section { + display: block; + } + } + } +} + +body.content +section.cal { + width: flex-grid(3) + flex-gutter(); + float: left; + overflow: scroll; + @include box-sizing(border-box); + opacity: .4; + @include transition(); + + > header ul { + display: none; + } + + &:hover { + opacity: 1; + } + + ol { + li { + @include box-sizing(border-box); + width: 100%; + + &.create-module { + display: none; + } + } + } +} diff --git a/cms/static/sass/_module-header.scss b/cms/static/sass/_module-header.scss new file mode 100644 index 0000000000000000000000000000000000000000..e2af2636188ee6d3e8162209b849fe3c2e10bf3c --- /dev/null +++ b/cms/static/sass/_module-header.scss @@ -0,0 +1,128 @@ +section.video-new, section.video-edit, section.problem-new, section.problem-edit { + position: absolute; + top: 72px; + right: 0; + background: #fff; + width: flex-grid(6); + @include box-shadow(0 0 6px #666); + border: 1px solid #333; + border-right: 0; + z-index: 4; + + > header { + background: #666; + @include clearfix; + color: #fff; + padding: 6px; + border-bottom: 1px solid #333; + -webkit-font-smoothing: antialiased; + + h2 { + float: left; + font-size: 14px; + } + + a { + color: #fff; + + &.save-update { + float: right; + } + + &.cancel { + float: left; + } + } + + } + + > section { + padding: 20px; + + > header { + h1 { + font-size: 24px; + margin: 12px 0; + } + + section { + &.status-settings { + ul { + list-style: none; + @include border-radius(2px); + border: 1px solid #999; + @include inline-block(); + + li { + @include inline-block(); + border-right: 1px solid #999; + padding: 6px; + + &:last-child { + border-right: 0; + } + + &.current { + background: #eee; + } + } + } + + a.settings { + @include inline-block(); + margin: 0 20px; + border: 1px solid #999; + padding: 6px; + } + + select { + float: right; + } + } + + &.meta { + background: #eee; + padding: 10px; + margin: 20px 0; + @include clearfix(); + + div { + float: left; + margin-right: 20px; + + h2 { + font-size: 14px; + @include inline-block(); + } + + p { + @include inline-block(); + } + } + } + } + } + + section.notes { + margin-top: 20px; + padding: 6px; + background: #eee; + border: 1px solid #ccc; + + textarea { + @include box-sizing(border-box); + display: block; + width: 100%; + } + + h2 { + font-size: 14px; + margin-bottom: 6px; + } + + input[type="submit"]{ + margin-top: 10px; + } + } + } +} diff --git a/cms/static/sass/_problem.scss b/cms/static/sass/_problem.scss new file mode 100644 index 0000000000000000000000000000000000000000..66acacf65c251eb6e77a63f889d9754e93042990 --- /dev/null +++ b/cms/static/sass/_problem.scss @@ -0,0 +1,24 @@ +section.problem-new, section.problem-edit { + > section { + textarea { + @include box-sizing(border-box); + display: block; + width: 100%; + } + + div.preview { + background: #eee; + @include box-sizing(border-box); + height: 40px; + padding: 10px; + width: 100%; + } + + a.save { + @extend .button; + @include inline-block(); + margin-top: 20px; + } + } +} + diff --git a/cms/static/sass/_reset.scss b/cms/static/sass/_reset.scss new file mode 100644 index 0000000000000000000000000000000000000000..bfe619c1b0ab9facd3ef43f53f5319d55a80b394 --- /dev/null +++ b/cms/static/sass/_reset.scss @@ -0,0 +1,229 @@ +html, body, div, span, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +abbr, address, cite, code, +del, dfn, em, img, ins, kbd, q, samp, +small, strong, sub, sup, var, +b, i, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, figcaption, figure, +footer, header, hgroup, menu, nav, section, summary, +time, mark, audio, video { + margin:0; + padding:0; + border:0; + outline:0; + vertical-align:baseline; + background:transparent; +} + +html,body { + font-size: 100%; +} + +// Corrects block display not defined in IE8/9 & FF3 +article, aside, details, figcaption, figure, footer, header, hgroup, nav, section { + display: block; +} + +// Corrects inline-block display not defined in IE8/9 & FF3 +audio, canvas, video { + display: inline-block; +} + +// Prevents modern browsers from displaying 'audio' without controls +audio:not([controls]) { + display: none; +} + +// Addresses styling for 'hidden' attribute not present in IE8/9, FF3, S4 +[hidden] { + display: none; +} + +// Prevents iOS text size adjust after orientation change, without disabling user zoom +// www.456bereastreet.com/archive/201012/controlling_text_size_in_safari_for_ios_without_disabling_user_zoom/ +html { + font-size: 100%; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} + +// Addresses font-family inconsistency between 'textarea' and other form elements. +html, button, input, select, textarea { + font-family: sans-serif; +} + +a { + // Addresses outline displayed oddly in Chrome + &:focus { + outline: thin dotted; + // Webkit + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; + } + + // Improves readability when focused and also mouse hovered in all browsers + // people.opera.com/patrickl/experiments/keyboard/test + &:hover, &:active { + outline: 0; + } +} + +// Addresses styling not present in IE8/9, S5, Chrome +abbr[title] { + border-bottom: 1px dotted; +} + +// Addresses style set to 'bolder' in FF3+, S4/5, Chrome +b, strong { + font-weight: bold; +} + +blockquote { + margin: 1em 40px; +} + +// Addresses styling not present in S5, Chrome +dfn { + font-style: italic; +} + +// Addresses styling not present in IE8/9 +mark { + background: #ff0; + color: #000; +} + +// Corrects font family set oddly in S4/5, Chrome +// en.wikipedia.org/wiki/User:Davidgothberg/Test59 +pre, code, kbd, samp { + font-family: monospace, serif; + _font-family: 'courier new', monospace; + font-size: 1em; +} + +// Improves readability of pre-formatted text in all browsers +pre { + white-space: pre; + white-space: pre-wrap; + word-wrap: break-word; +} + +// Addresses quote property not supported in S4 +blockquote, q { + quotes: none; + &:before, &:after { + content: ''; + content: none; + } +} + +small { + font-size: 75%; +} + +sub, sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +nav { + ul, ol { + list-style: none; + list-style-image: none; + } +} + +// Removes border when inside 'a' element in IE8/9, FF3 +img { + border: 0; + height: auto; + max-width: 100%; + -ms-interpolation-mode: bicubic; +} + +// Corrects overflow displayed oddly in IE9 +svg:not(:root) { + overflow: hidden; +} + +// Define consistent border, margin, and padding +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} + +legend { + border: 0; // Corrects color not being inherited in IE8/9 + padding: 0; + white-space: normal; // Corrects text not wrapping in FF3 +} + +button, input, select, textarea { + font-size: 100%; // Corrects font size not being inherited in all browsers + margin: 0; // Addresses margins set differently in FF3+, S5, Chrome + vertical-align: baseline; // Improves appearance and consistency in all browsers +} + +// Addresses FF3/4 setting line-height on 'input' using !important in the UA stylesheet +button, input { + line-height: normal; +} + +button, input[type="button"], input[type="reset"], input[type="submit"] { + cursor: pointer; // Improves usability and consistency of cursor style between image-type 'input' and others + -webkit-appearance: button; // Corrects inability to style clickable 'input' types in iOS +} + +// Re-set default cursor for disabled elements +button[disabled], input[disabled] { + cursor: default; +} + +input[type="checkbox"], input[type="radio"] { + box-sizing: border-box; // Addresses box sizing set to content-box in IE8/9 + padding: 0; //Removes excess padding in IE8/9 +} + +input[type="search"] { + -webkit-appearance: textfield; // Addresses appearance set to searchfield in S5, Chrome + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; // Addresses box-sizing set to border-box in S5, Chrome (-moz to future-proof) + box-sizing: content-box; +} + +// Removes inner padding and search cancel button in S5, Chrome on OS X +input[type="search"]::-webkit-search-decoration, input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +// Removes inner padding and border in FF3+ +// www.sitepen.com/blog/2008/05/14/the-devils-in-the-details-fixing-dojos-toolbar-buttons/ +button::-moz-focus-inner, input::-moz-focus-inner { + border: 0; + padding: 0; +} + +textarea { + overflow: auto; // Removes default vertical scrollbar in IE8/9 + vertical-align: top; // Improves readability and alignment in all browsers +} + +// Remove most spacing between table cells +table { + border-collapse: collapse; + border-spacing: 0; +} diff --git a/cms/static/sass/_video.scss b/cms/static/sass/_video.scss new file mode 100644 index 0000000000000000000000000000000000000000..b68176e2db25a59bf16e37de8f72f057f92a0ba5 --- /dev/null +++ b/cms/static/sass/_video.scss @@ -0,0 +1,33 @@ +section.video-new, section.video-edit { + > section { + + section.upload { + padding: 6px; + margin-bottom: 10px; + border: 1px solid #ddd; + + a.upload-button { + @extend .button; + @include inline-block(); + } + } + + section.in-use { + h2 { + font-size: 14px; + } + + div { + background: #eee; + text-align: center; + padding: 6px; + } + } + + a.save-update { + @extend .button; + @include inline-block(); + margin-top: 20px; + } + } +} diff --git a/cms/static/sass/_week.scss b/cms/static/sass/_week.scss new file mode 100644 index 0000000000000000000000000000000000000000..b638a36f5c6087f861ae98d02a2e4b5c9582f885 --- /dev/null +++ b/cms/static/sass/_week.scss @@ -0,0 +1,256 @@ +section.week-edit, +section.week-new, +section.sequence-edit { + + > header { + border-bottom: 2px solid #333; + @include clearfix(); + + div { + @include clearfix(); + padding: 6px 20px; + + h1 { + font-size: 18px; + text-transform: uppercase; + letter-spacing: 1px; + float: left; + } + + p { + float: right; + } + + &.week { + background: #eee; + font-size: 12px; + border-bottom: 1px solid #ccc; + + h2 { + font-size: 12px; + @include inline-block(); + margin-right: 20px; + } + + ul { + list-style: none; + @include inline-block(); + + li { + @include inline-block(); + margin-right: 10px; + + p { + float: none; + } + } + } + } + } + + section.goals { + background: #eee; + padding: 6px 20px; + border-top: 1px solid #ccc; + + ul { + list-style: none; + color: #999; + + li { + margin-bottom: 6px; + + &:last-child { + margin-bottom: 0; + } + } + } + } + } + + > section.content { + @include box-sizing(border-box); + padding: 20px; + + section.filters { + @include clearfix; + margin-bottom: 10px; + background: #efefef; + border: 1px solid #ddd; + + ul { + @include clearfix(); + list-style: none; + padding: 6px; + + li { + @include inline-block(); + + &.advanced { + float: right; + } + } + } + } + + > div { + display: table; + border: 1px solid; + width: 100%; + + section { + header { + background: #eee; + padding: 6px; + border-bottom: 1px solid #ccc; + @include clearfix; + + h2 { + text-transform: uppercase; + letter-spacing: 1px; + font-size: 12px; + float: left; + } + } + + &.modules { + @include box-sizing(border-box); + display: table-cell; + width: flex-grid(6, 9); + border-right: 1px solid #333; + + &.empty { + text-align: center; + vertical-align: middle; + + a { + @extend .button; + @include inline-block(); + margin-top: 10px; + } + } + + ol { + list-style: none; + border-bottom: 1px solid #333; + + li { + border-bottom: 1px solid #333; + + &:last-child{ + border-bottom: 0; + } + + a { + color: #000; + } + + ol { + list-style: none; + + li { + padding: 6px; + + &:hover { + a.draggable { + opacity: 1; + } + } + + a.draggable { + float: right; + opacity: .5; + } + + &.group { + padding: 0; + + header { + padding: 6px; + background: none; + + h3 { + font-size: 14px; + } + } + + + ol { + border-left: 4px solid #999; + border-bottom: 0; + + li { + &:last-child { + border-bottom: 0; + } + } + } + } + } + } + } + } + } + + &.scratch-pad { + @include box-sizing(border-box); + display: table-cell; + width: flex-grid(3, 9) + flex-gutter(9); + vertical-align: top; + + ol { + list-style: none; + border-bottom: 1px solid #999; + + li { + border-bottom: 1px solid #999; + background: #f9f9f9; + + &:last-child { + border-bottom: 0; + } + + ul { + list-style: none; + + li { + padding: 6px; + + &:last-child { + border-bottom: 0; + } + + &:hover { + a.draggable { + opacity: 1; + } + } + + &.empty { + padding: 12px; + + a { + @extend .button; + display: block; + text-align: center; + } + } + + a.draggable { + float: right; + opacity: .3; + } + + a { + color: #000; + } + } + } + + } + } + } + } + } + } +} diff --git a/cms/static/sass/base-style.scss b/cms/static/sass/base-style.scss new file mode 100644 index 0000000000000000000000000000000000000000..133e1bda1bd7c476b41dd2ed8741afbccca81a1f --- /dev/null +++ b/cms/static/sass/base-style.scss @@ -0,0 +1,6 @@ +@import 'bourbon/bourbon'; +@import 'reset'; + +@import 'base'; +@import 'calendar'; +@import 'week', 'video', 'problem', 'module-header'; diff --git a/cms/static/sass/bourbon/_bourbon.scss b/cms/static/sass/bourbon/_bourbon.scss new file mode 100644 index 0000000000000000000000000000000000000000..27b056e303e151bc9da8f591f6198ef2a2eb950d --- /dev/null +++ b/cms/static/sass/bourbon/_bourbon.scss @@ -0,0 +1,35 @@ +// Custom Functions +@import "functions/deprecated-webkit-gradient"; +@import "functions/flex-grid"; +@import "functions/grid-width"; +@import "functions/linear-gradient"; +@import "functions/modular-scale"; +@import "functions/radial-gradient"; +@import "functions/render-gradients"; +@import "functions/tint-shade"; + +// CSS3 Mixins +@import "css3/animation"; +@import "css3/appearance"; +@import "css3/background-image"; +@import "css3/background-size"; +@import "css3/border-image"; +@import "css3/border-radius"; +@import "css3/box-shadow"; +@import "css3/box-sizing"; +@import "css3/columns"; +@import "css3/flex-box"; +@import "css3/inline-block"; +@import "css3/linear-gradient"; +@import "css3/radial-gradient"; +@import "css3/transform"; +@import "css3/transition"; +@import "css3/user-select"; + +// Addons & other mixins +@import "addons/button"; +@import "addons/clearfix"; +@import "addons/font-family"; +@import "addons/html5-input-types"; +@import "addons/position"; +@import "addons/timing-functions"; diff --git a/cms/static/sass/bourbon/addons/_button.scss b/cms/static/sass/bourbon/addons/_button.scss new file mode 100644 index 0000000000000000000000000000000000000000..1d321251403bb9bb2252cd1c37057fa707277f0c --- /dev/null +++ b/cms/static/sass/bourbon/addons/_button.scss @@ -0,0 +1,267 @@ +@mixin button ($style: simple, $base-color: #4294f0) { + + @if type-of($style) == color { + $base-color: $style; + $style: simple; + } + + // Grayscale button + @if $base-color == grayscale($base-color) { + @if $style == simple { + @include simple($base-color, $grayscale: true); + } + + @else if $style == shiny { + @include shiny($base-color, $grayscale: true); + } + + @else if $style == pill { + @include pill($base-color, $grayscale: true); + } + } + + // Colored button + @else { + @if $style == simple { + @include simple($base-color); + } + + @else if $style == shiny { + @include shiny($base-color); + } + + @else if $style == pill { + @include pill($base-color); + } + } +} + + +// Simple Button +//************************************************************************// +@mixin simple($base-color, $grayscale: false) { + $color: hsl(0, 0, 100%); + $border: adjust-color($base-color, $saturation: 9%, $lightness: -14%); + $inset-shadow: adjust-color($base-color, $saturation: -8%, $lightness: 15%); + $stop-gradient: adjust-color($base-color, $saturation: 9%, $lightness: -11%); + $text-shadow: adjust-color($base-color, $saturation: 15%, $lightness: -18%); + + @if lightness($base-color) > 70% { + $color: hsl(0, 0, 20%); + $text-shadow: adjust-color($base-color, $saturation: 10%, $lightness: 4%); + } + + @if $grayscale == true { + $border: grayscale($border); + $inset-shadow: grayscale($inset-shadow); + $stop-gradient: grayscale($stop-gradient); + $text-shadow: grayscale($text-shadow); + } + + border: 1px solid $border; + @include border-radius (3px); + @include box-shadow (inset 0 1px 0 0 $inset-shadow); + color: $color; + display: inline; + font-size: 11px; + font-weight: bold; + @include linear-gradient ($base-color, $stop-gradient); + padding: 6px 18px 7px; + text-shadow: 0 1px 0 $text-shadow; + -webkit-background-clip: padding-box; + + &:hover { + $base-color-hover: adjust-color($base-color, $saturation: -4%, $lightness: -5%); + $inset-shadow-hover: adjust-color($base-color, $saturation: -7%, $lightness: 5%); + $stop-gradient-hover: adjust-color($base-color, $saturation: 8%, $lightness: -14%); + + @if $grayscale == true { + $base-color-hover: grayscale($base-color-hover); + $inset-shadow-hover: grayscale($inset-shadow-hover); + $stop-gradient-hover: grayscale($stop-gradient-hover); + } + + @include box-shadow (inset 0 1px 0 0 $inset-shadow-hover); + cursor: pointer; + @include linear-gradient ($base-color-hover, $stop-gradient-hover); + } + + &:active { + $border-active: adjust-color($base-color, $saturation: 9%, $lightness: -14%); + $inset-shadow-active: adjust-color($base-color, $saturation: 7%, $lightness: -17%); + + @if $grayscale == true { + $border-active: grayscale($border-active); + $inset-shadow-active: grayscale($inset-shadow-active); + } + + border: 1px solid $border-active; + @include box-shadow (inset 0 0 8px 4px $inset-shadow-active, inset 0 0 8px 4px $inset-shadow-active, 0 1px 1px 0 #eee); + } +} + + +// Shiny Button +//************************************************************************// +@mixin shiny($base-color, $grayscale: false) { + $color: hsl(0, 0, 100%); + $border: adjust-color($base-color, $red: -117, $green: -111, $blue: -81); + $border-bottom: adjust-color($base-color, $red: -126, $green: -127, $blue: -122); + $fourth-stop: adjust-color($base-color, $red: -79, $green: -70, $blue: -46); + $inset-shadow: adjust-color($base-color, $red: 37, $green: 29, $blue: 12); + $second-stop: adjust-color($base-color, $red: -56, $green: -50, $blue: -33); + $text-shadow: adjust-color($base-color, $red: -140, $green: -141, $blue: -114); + $third-stop: adjust-color($base-color, $red: -86, $green: -75, $blue: -48); + + @if lightness($base-color) > 70% { + $color: hsl(0, 0, 20%); + $text-shadow: adjust-color($base-color, $saturation: 10%, $lightness: 4%); + } + + @if $grayscale == true { + $border: grayscale($border); + $border-bottom: grayscale($border-bottom); + $fourth-stop: grayscale($fourth-stop); + $inset-shadow: grayscale($inset-shadow); + $second-stop: grayscale($second-stop); + $text-shadow: grayscale($text-shadow); + $third-stop: grayscale($third-stop); + } + + border: 1px solid $border; + border-bottom: 1px solid $border-bottom; + @include border-radius(5px); + @include box-shadow(inset 0 1px 0 0 $inset-shadow); + color: $color; + display: inline; + font-size: 14px; + font-weight: bold; + @include linear-gradient(top, $base-color 0%, $second-stop 50%, $third-stop 50%, $fourth-stop 100%); + padding: 7px 20px 8px; + text-align: center; + text-decoration: none; + text-shadow: 0 -1px 1px $text-shadow; + + &:hover { + $first-stop-hover: adjust-color($base-color, $red: -13, $green: -15, $blue: -18); + $second-stop-hover: adjust-color($base-color, $red: -66, $green: -62, $blue: -51); + $third-stop-hover: adjust-color($base-color, $red: -93, $green: -85, $blue: -66); + $fourth-stop-hover: adjust-color($base-color, $red: -86, $green: -80, $blue: -63); + + @if $grayscale == true { + $first-stop-hover: grayscale($first-stop-hover); + $second-stop-hover: grayscale($second-stop-hover); + $third-stop-hover: grayscale($third-stop-hover); + $fourth-stop-hover: grayscale($fourth-stop-hover); + } + + cursor: pointer; + @include linear-gradient(top, $first-stop-hover 0%, + $second-stop-hover 50%, + $third-stop-hover 50%, + $fourth-stop-hover 100%); + } + + &:active { + $inset-shadow-active: adjust-color($base-color, $red: -111, $green: -116, $blue: -122); + + @if $grayscale == true { + $inset-shadow-active: grayscale($inset-shadow-active); + } + + @include box-shadow(inset 0 0 20px 0 $inset-shadow-active, 0 1px 0 #fff); + } +} + + +// Pill Button +//************************************************************************// +@mixin pill($base-color, $grayscale: false) { + $color: hsl(0, 0, 100%); + $border-bottom: adjust-color($base-color, $hue: 8, $saturation: -11%, $lightness: -26%); + $border-sides: adjust-color($base-color, $hue: 4, $saturation: -21%, $lightness: -21%); + $border-top: adjust-color($base-color, $hue: -1, $saturation: -30%, $lightness: -15%); + $inset-shadow: adjust-color($base-color, $hue: -1, $saturation: -1%, $lightness: 7%); + $stop-gradient: adjust-color($base-color, $hue: 8, $saturation: 14%, $lightness: -10%); + $text-shadow: adjust-color($base-color, $hue: 5, $saturation: -19%, $lightness: -15%); + + @if lightness($base-color) > 70% { + $color: hsl(0, 0, 20%); + $text-shadow: adjust-color($base-color, $saturation: 10%, $lightness: 4%); + } + + @if $grayscale == true { + $border-bottom: grayscale($border-bottom); + $border-sides: grayscale($border-sides); + $border-top: grayscale($border-top); + $inset-shadow: grayscale($inset-shadow); + $stop-gradient: grayscale($stop-gradient); + $text-shadow: grayscale($text-shadow); + } + + border: 1px solid $border-top; + border-color: $border-top $border-sides $border-bottom; + @include border-radius(16px); + @include box-shadow(inset 0 1px 0 0 $inset-shadow, 0 1px 2px 0 #b3b3b3); + color: $color; + display: inline; + font-size: 11px; + font-weight: normal; + line-height: 1; + @include linear-gradient ($base-color, $stop-gradient); + padding: 3px 16px 5px; + text-align: center; + text-shadow: 0 -1px 1px $text-shadow; + -webkit-background-clip: padding-box; + + &:hover { + $base-color-hover: adjust-color($base-color, $lightness: -4.5%); + $border-bottom: adjust-color($base-color, $hue: 8, $saturation: 13.5%, $lightness: -32%); + $border-sides: adjust-color($base-color, $hue: 4, $saturation: -2%, $lightness: -27%); + $border-top: adjust-color($base-color, $hue: -1, $saturation: -17%, $lightness: -21%); + $inset-shadow-hover: adjust-color($base-color, $saturation: -1%, $lightness: 3%); + $stop-gradient-hover: adjust-color($base-color, $hue: 8, $saturation: -4%, $lightness: -15.5%); + $text-shadow-hover: adjust-color($base-color, $hue: 5, $saturation: -5%, $lightness: -22%); + + @if $grayscale == true { + $base-color-hover: grayscale($base-color-hover); + $border-bottom: grayscale($border-bottom); + $border-sides: grayscale($border-sides); + $border-top: grayscale($border-top); + $inset-shadow-hover: grayscale($inset-shadow-hover); + $stop-gradient-hover: grayscale($stop-gradient-hover); + $text-shadow-hover: grayscale($text-shadow-hover); + } + + border: 1px solid $border-top; + border-color: $border-top $border-sides $border-bottom; + @include box-shadow(inset 0 1px 0 0 $inset-shadow-hover); + cursor: pointer; + @include linear-gradient ($base-color-hover, $stop-gradient-hover); + text-shadow: 0 -1px 1px $text-shadow-hover; + -webkit-background-clip: padding-box; + } + + &:active { + $active-color: adjust-color($base-color, $hue: 4, $saturation: -12%, $lightness: -10%); + $border-active: adjust-color($base-color, $hue: 6, $saturation: -2.5%, $lightness: -30%); + $border-bottom-active: adjust-color($base-color, $hue: 11, $saturation: 6%, $lightness: -31%); + $inset-shadow-active: adjust-color($base-color, $hue: 9, $saturation: 2%, $lightness: -21.5%); + $text-shadow-active: adjust-color($base-color, $hue: 5, $saturation: -12%, $lightness: -21.5%); + + @if $grayscale == true { + $active-color: grayscale($active-color); + $border-active: grayscale($border-active); + $border-bottom-active: grayscale($border-bottom-active); + $inset-shadow-active: grayscale($inset-shadow-active); + $text-shadow-active: grayscale($text-shadow-active); + } + + background: $active-color; + border: 1px solid $border-active; + border-bottom: 1px solid $border-bottom-active; + @include box-shadow(inset 0 0 6px 3px $inset-shadow-active, 0 1px 0 0 #fff); + text-shadow: 0 -1px 1px $text-shadow-active; + } +} + diff --git a/cms/static/sass/bourbon/addons/_clearfix.scss b/cms/static/sass/bourbon/addons/_clearfix.scss new file mode 100644 index 0000000000000000000000000000000000000000..a9f6a795c57199eb6a4b6ab885bb9e3c62a64a30 --- /dev/null +++ b/cms/static/sass/bourbon/addons/_clearfix.scss @@ -0,0 +1,29 @@ +// Micro clearfix provides an easy way to contain floats without adding additional markup +// +// Example usage: +// +// // Contain all floats within .wrapper +// .wrapper { +// @include clearfix; +// .content, +// .sidebar { +// float : left; +// } +// } + +@mixin clearfix { + zoom: 1; + + &:before, + &:after { + content: ""; + display: table; + } + + &:after { + clear: both; + } +} + +// Acknowledgements +// Micro clearfix: [Nicolas Gallagher](http://nicolasgallagher.com/micro-clearfix-hack/) diff --git a/cms/static/sass/bourbon/addons/_font-family.scss b/cms/static/sass/bourbon/addons/_font-family.scss new file mode 100644 index 0000000000000000000000000000000000000000..df8a80ddfcfe8238a54285ca08b141f63cf04c8c --- /dev/null +++ b/cms/static/sass/bourbon/addons/_font-family.scss @@ -0,0 +1,5 @@ +$georgia: Georgia, Cambria, "Times New Roman", Times, serif; +$helvetica: "Helvetica Neue", Helvetica, Arial, sans-serif; +$lucida-grande: "Lucida Grande", Tahoma, Verdana, Arial, sans-serif; +$monospace: "Bitstream Vera Sans Mono", Consolas, Courier, monospace; +$verdana: Verdana, Geneva, sans-serif; diff --git a/cms/static/sass/bourbon/addons/_html5-input-types.scss b/cms/static/sass/bourbon/addons/_html5-input-types.scss new file mode 100644 index 0000000000000000000000000000000000000000..9d86fbb4d49b7a3cc30fb2583159b5973b9efad6 --- /dev/null +++ b/cms/static/sass/bourbon/addons/_html5-input-types.scss @@ -0,0 +1,36 @@ +//************************************************************************// +// Generate a variable ($all-text-inputs) with a list of all html5 +// input types that have a text-based input, excluding textarea. +// http://diveintohtml5.org/forms.html +//************************************************************************// +$inputs-list: 'input[type="email"]', + 'input[type="number"]', + 'input[type="password"]', + 'input[type="search"]', + 'input[type="tel"]', + 'input[type="text"]', + 'input[type="url"]', + + // Webkit & Gecko may change the display of these in the future + 'input[type="color"]', + 'input[type="date"]', + 'input[type="datetime"]', + 'input[type="datetime-local"]', + 'input[type="month"]', + 'input[type="time"]', + 'input[type="week"]'; + +$unquoted-inputs-list: (); + +@each $input-type in $inputs-list { + $unquoted-inputs-list: append($unquoted-inputs-list, unquote($input-type), comma); +} + +$all-text-inputs: $unquoted-inputs-list; + +// You must use interpolation on the variable: +// #{$all-text-inputs} +//************************************************************************// +// #{$all-text-inputs}, textarea { +// border: 1px solid red; +// } diff --git a/cms/static/sass/bourbon/addons/_position.scss b/cms/static/sass/bourbon/addons/_position.scss new file mode 100644 index 0000000000000000000000000000000000000000..6ad330f1dfe17846fda195bb49aa585b6f7342eb --- /dev/null +++ b/cms/static/sass/bourbon/addons/_position.scss @@ -0,0 +1,30 @@ +@mixin position ($position: relative, $coordinates: 0 0 0 0) { + + @if type-of($position) == list { + $coordinates: $position; + $position: relative; + } + + $top: nth($coordinates, 1); + $right: nth($coordinates, 2); + $bottom: nth($coordinates, 3); + $left: nth($coordinates, 4); + + position: $position; + + @if not(unitless($top)) { + top: $top; + } + + @if not(unitless($right)) { + right: $right; + } + + @if not(unitless($bottom)) { + bottom: $bottom; + } + + @if not(unitless($left)) { + left: $left; + } +} diff --git a/cms/static/sass/bourbon/addons/_timing-functions.scss b/cms/static/sass/bourbon/addons/_timing-functions.scss new file mode 100644 index 0000000000000000000000000000000000000000..51b241091490f662354435b5466c6f8db0ae662d --- /dev/null +++ b/cms/static/sass/bourbon/addons/_timing-functions.scss @@ -0,0 +1,32 @@ +// CSS cubic-bezier timing functions. Timing functions courtesy of jquery.easie (github.com/jaukia/easie) +// Timing functions are the same as demo'ed here: http://jqueryui.com/demos/effect/easing.html + +// EASE IN +$ease-in-quad: cubic-bezier(0.550, 0.085, 0.680, 0.530); +$ease-in-cubic: cubic-bezier(0.550, 0.055, 0.675, 0.190); +$ease-in-quart: cubic-bezier(0.895, 0.030, 0.685, 0.220); +$ease-in-quint: cubic-bezier(0.755, 0.050, 0.855, 0.060); +$ease-in-sine: cubic-bezier(0.470, 0.000, 0.745, 0.715); +$ease-in-expo: cubic-bezier(0.950, 0.050, 0.795, 0.035); +$ease-in-circ: cubic-bezier(0.600, 0.040, 0.980, 0.335); +$ease-in-back: cubic-bezier(0.600, -0.280, 0.735, 0.045); + +// EASE OUT +$ease-out-quad: cubic-bezier(0.250, 0.460, 0.450, 0.940); +$ease-out-cubic: cubic-bezier(0.215, 0.610, 0.355, 1.000); +$ease-out-quart: cubic-bezier(0.165, 0.840, 0.440, 1.000); +$ease-out-quint: cubic-bezier(0.230, 1.000, 0.320, 1.000); +$ease-out-sine: cubic-bezier(0.390, 0.575, 0.565, 1.000); +$ease-out-expo: cubic-bezier(0.190, 1.000, 0.220, 1.000); +$ease-out-circ: cubic-bezier(0.075, 0.820, 0.165, 1.000); +$ease-out-back: cubic-bezier(0.175, 0.885, 0.320, 1.275); + +// EASE IN OUT +$ease-in-out-quad: cubic-bezier(0.455, 0.030, 0.515, 0.955); +$ease-in-out-cubic: cubic-bezier(0.645, 0.045, 0.355, 1.000); +$ease-in-out-quart: cubic-bezier(0.770, 0.000, 0.175, 1.000); +$ease-in-out-quint: cubic-bezier(0.860, 0.000, 0.070, 1.000); +$ease-in-out-sine: cubic-bezier(0.445, 0.050, 0.550, 0.950); +$ease-in-out-expo: cubic-bezier(1.000, 0.000, 0.000, 1.000); +$ease-in-out-circ: cubic-bezier(0.785, 0.135, 0.150, 0.860); +$ease-in-out-back: cubic-bezier(0.680, -0.550, 0.265, 1.550); diff --git a/cms/static/sass/bourbon/css3/_animation.scss b/cms/static/sass/bourbon/css3/_animation.scss new file mode 100644 index 0000000000000000000000000000000000000000..f99e06eb6ff6c119f31c71386be502147394fbbd --- /dev/null +++ b/cms/static/sass/bourbon/css3/_animation.scss @@ -0,0 +1,171 @@ +// http://www.w3.org/TR/css3-animations/#the-animation-name-property- +// Each of these mixins support comma separated lists of values, which allows different transitions for individual properties to be described in a single style rule. Each value in the list corresponds to the value at that same position in the other properties. + +// Official animation shorthand property. +@mixin animation ($animation-1, + $animation-2: false, $animation-3: false, + $animation-4: false, $animation-5: false, + $animation-6: false, $animation-7: false, + $animation-8: false, $animation-9: false) + { + $full: compact($animation-1, $animation-2, $animation-3, $animation-4, + $animation-5, $animation-6, $animation-7, $animation-8, $animation-9); + + -webkit-animation: $full; + -moz-animation: $full; + animation: $full; +} + +// Individual Animation Properties +@mixin animation-name ($name-1, + $name-2: false, $name-3: false, + $name-4: false, $name-5: false, + $name-6: false, $name-7: false, + $name-8: false, $name-9: false) + { + $full: compact($name-1, $name-2, $name-3, $name-4, + $name-5, $name-6, $name-7, $name-8, $name-9); + + -webkit-animation-name: $full; + -moz-animation-name: $full; + animation-name: $full; +} + + +@mixin animation-duration ($time-1: 0, + $time-2: false, $time-3: false, + $time-4: false, $time-5: false, + $time-6: false, $time-7: false, + $time-8: false, $time-9: false) + { + $full: compact($time-1, $time-2, $time-3, $time-4, + $time-5, $time-6, $time-7, $time-8, $time-9); + + -webkit-animation-duration: $full; + -moz-animation-duration: $full; + animation-duration: $full; +} + + +@mixin animation-timing-function ($motion-1: ease, +// ease | linear | ease-in | ease-out | ease-in-out + $motion-2: false, $motion-3: false, + $motion-4: false, $motion-5: false, + $motion-6: false, $motion-7: false, + $motion-8: false, $motion-9: false) + { + $full: compact($motion-1, $motion-2, $motion-3, $motion-4, + $motion-5, $motion-6, $motion-7, $motion-8, $motion-9); + + -webkit-animation-timing-function: $full; + -moz-animation-timing-function: $full; + animation-timing-function: $full; +} + + +@mixin animation-iteration-count ($value-1: 1, +// infinite | <number> + $value-2: false, $value-3: false, + $value-4: false, $value-5: false, + $value-6: false, $value-7: false, + $value-8: false, $value-9: false) + { + $full: compact($value-1, $value-2, $value-3, $value-4, + $value-5, $value-6, $value-7, $value-8, $value-9); + + -webkit-animation-iteration-count: $full; + -moz-animation-iteration-count: $full; + animation-iteration-count: $full; +} + + +@mixin animation-direction ($direction-1: normal, +// normal | alternate + $direction-2: false, $direction-3: false, + $direction-4: false, $direction-5: false, + $direction-6: false, $direction-7: false, + $direction-8: false, $direction-9: false) + { + $full: compact($direction-1, $direction-2, $direction-3, $direction-4, + $direction-5, $direction-6, $direction-7, $direction-8, $direction-9); + + -webkit-animation-direction: $full; + -moz-animation-direction: $full; + animation-direction: $full; +} + + +@mixin animation-play-state ($state-1: running, +// running | paused + $state-2: false, $state-3: false, + $state-4: false, $state-5: false, + $state-6: false, $state-7: false, + $state-8: false, $state-9: false) + { + $full: compact($state-1, $state-2, $state-3, $state-4, + $state-5, $state-6, $state-7, $state-8, $state-9); + + -webkit-animation-play-state: $full; + -moz-animation-play-state: $full; + animation-play-state: $full; +} + + +@mixin animation-delay ($time-1: 0, + $time-2: false, $time-3: false, + $time-4: false, $time-5: false, + $time-6: false, $time-7: false, + $time-8: false, $time-9: false) + { + $full: compact($time-1, $time-2, $time-3, $time-4, + $time-5, $time-6, $time-7, $time-8, $time-9); + + -webkit-animation-delay: $full; + -moz-animation-delay: $full; + animation-delay: $full; +} + + +@mixin animation-fill-mode ($mode-1: none, +// http://goo.gl/l6ckm +// none | forwards | backwards | both + $mode-2: false, $mode-3: false, + $mode-4: false, $mode-5: false, + $mode-6: false, $mode-7: false, + $mode-8: false, $mode-9: false) + { + $full: compact($mode-1, $mode-2, $mode-3, $mode-4, + $mode-5, $mode-6, $mode-7, $mode-8, $mode-9); + + -webkit-animation-fill-mode: $full; + -moz-animation-fill-mode: $full; + animation-fill-mode: $full; +} + + +// Deprecated +@mixin animation-basic ($name, $time: 0, $motion: ease) { + $length-of-name: length($name); + $length-of-time: length($time); + $length-of-motion: length($motion); + + @if $length-of-name > 1 { + @include animation-name(zip($name)); + } @else { + @include animation-name( $name); + } + + @if $length-of-time > 1 { + @include animation-duration(zip($time)); + } @else { + @include animation-duration( $time); + } + + @if $length-of-motion > 1 { + @include animation-timing-function(zip($motion)); + } @else { + @include animation-timing-function( $motion); + } + @warn "The animation-basic mixin is deprecated. Use the animation mixin instead."; +} + diff --git a/cms/static/sass/bourbon/css3/_appearance.scss b/cms/static/sass/bourbon/css3/_appearance.scss new file mode 100644 index 0000000000000000000000000000000000000000..548767e16621ba3277ba6dd726c1ee794f276af4 --- /dev/null +++ b/cms/static/sass/bourbon/css3/_appearance.scss @@ -0,0 +1,7 @@ +@mixin appearance ($value) { + -webkit-appearance: $value; + -moz-appearance: $value; + -ms-appearance: $value; + -o-appearance: $value; + appearance: $value; +} diff --git a/cms/static/sass/bourbon/css3/_background-image.scss b/cms/static/sass/bourbon/css3/_background-image.scss new file mode 100644 index 0000000000000000000000000000000000000000..c23cef7c310fadb2d0f83720c5724c0e074be05c --- /dev/null +++ b/cms/static/sass/bourbon/css3/_background-image.scss @@ -0,0 +1,57 @@ +//************************************************************************// +// Background-image property for adding multiple background images with +// gradients, or for stringing multiple gradients together. +//************************************************************************// + +@mixin background-image( + $image-1 , $image-2: false, + $image-3: false, $image-4: false, + $image-5: false, $image-6: false, + $image-7: false, $image-8: false, + $image-9: false, $image-10: false +) { + $images: compact($image-1, $image-2, + $image-3, $image-4, + $image-5, $image-6, + $image-7, $image-8, + $image-9, $image-10); + + background-image: add-prefix($images, webkit); + background-image: add-prefix($images, moz); + background-image: add-prefix($images, ms); + background-image: add-prefix($images, o); + background-image: add-prefix($images); +} + + +@function add-prefix($images, $vendor: false) { + $images-prefixed: (); + + @for $i from 1 through length($images) { + $type: type-of(nth($images, $i)); // Get type of variable - List or String + + // If variable is a list - Gradient + @if $type == list { + $gradient-type: nth(nth($images, $i), 1); // Get type of gradient (linear || radial) + $gradient-args: nth(nth($images, $i), 2); // Get actual gradient (red, blue) + + $gradient: render-gradients($gradient-args, $gradient-type, $vendor); + $images-prefixed: append($images-prefixed, $gradient, comma); + } + + // If variable is a string - Image + @else if $type == string { + $images-prefixed: join($images-prefixed, nth($images, $i), comma); + } + } + @return $images-prefixed; +} + + + +//Examples: + //@include background-image(linear-gradient(top, orange, red)); + //@include background-image(radial-gradient(50% 50%, cover circle, orange, red)); + //@include background-image(url("/images/a.png"), linear-gradient(orange, red)); + //@include background-image(url("image.png"), linear-gradient(orange, red), url("image.png")); + //@include background-image(linear-gradient(hsla(0, 100%, 100%, 0.25) 0%, hsla(0, 100%, 100%, 0.08) 50%, transparent 50%), linear-gradient(orange, red); diff --git a/cms/static/sass/bourbon/css3/_background-size.scss b/cms/static/sass/bourbon/css3/_background-size.scss new file mode 100644 index 0000000000000000000000000000000000000000..4bba11027da2efb9481926d80b0899abbde4db52 --- /dev/null +++ b/cms/static/sass/bourbon/css3/_background-size.scss @@ -0,0 +1,15 @@ +@mixin background-size ($length-1, + $length-2: false, $length-3: false, + $length-4: false, $length-5: false, + $length-6: false, $length-7: false, + $length-8: false, $length-9: false) + { + $full: compact($length-1, $length-2, $length-3, $length-4, + $length-5, $length-6, $length-7, $length-8, $length-9); + + -webkit-background-size: $full; + -moz-background-size: $full; + -ms-background-size: $full; + -o-background-size: $full; + background-size: $full; +} diff --git a/cms/static/sass/bourbon/css3/_border-image.scss b/cms/static/sass/bourbon/css3/_border-image.scss new file mode 100644 index 0000000000000000000000000000000000000000..da4f20ba492c311c05a1d17ff5815502e454463c --- /dev/null +++ b/cms/static/sass/bourbon/css3/_border-image.scss @@ -0,0 +1,56 @@ +@mixin border-image($images) { + -webkit-border-image: border-add-prefix($images, webkit); + -moz-border-image: border-add-prefix($images, moz); + -o-border-image: border-add-prefix($images, o); + border-image: border-add-prefix($images); +} + +@function border-add-prefix($images, $vendor: false) { + $border-image: (); + $images-type: type-of(nth($images, 1)); + $first-var: nth(nth($images, 1), 1); // Get type of Gradient (Linear || radial) + + // If input is a gradient + @if $images-type == string { + @if ($first-var == "linear") or ($first-var == "radial") { + @for $i from 2 through length($images) { + $gradient-type: nth($images, 1); // Get type of gradient (linear || radial) + $gradient-args: nth($images, $i); // Get actual gradient (red, blue) + $border-image: render-gradients($gradient-args, $gradient-type, $vendor); + } + } + + // If input is a URL + @else { + $border-image: $images; + } + } + + // If input is gradient or url + additional args + @else if $images-type == list { + @for $i from 1 through length($images) { + $type: type-of(nth($images, $i)); // Get type of variable - List or String + + // If variable is a list - Gradient + @if $type == list { + $gradient-type: nth(nth($images, $i), 1); // Get type of gradient (linear || radial) + $gradient-args: nth(nth($images, $i), 2); // Get actual gradient (red, blue) + $border-image: render-gradients($gradient-args, $gradient-type, $vendor); + } + + // If variable is a string - Image or number + @else if ($type == string) or ($type == number) { + $border-image: append($border-image, nth($images, $i)); + } + } + } + @return $border-image; +} + +//Examples: +// @include border-image(url("image.png")); +// @include border-image(url("image.png") 20 stretch); +// @include border-image(linear-gradient(45deg, orange, yellow)); +// @include border-image(linear-gradient(45deg, orange, yellow) stretch); +// @include border-image(linear-gradient(45deg, orange, yellow) 20 30 40 50 stretch round); +// @include border-image(radial-gradient(top, cover, orange, yellow, orange)); diff --git a/cms/static/sass/bourbon/css3/_border-radius.scss b/cms/static/sass/bourbon/css3/_border-radius.scss new file mode 100644 index 0000000000000000000000000000000000000000..f24389ebbe5d9931071f625ddbf73d5acee672d2 --- /dev/null +++ b/cms/static/sass/bourbon/css3/_border-radius.scss @@ -0,0 +1,63 @@ +@mixin border-radius ($radii) { + -webkit-border-radius: $radii; + -moz-border-radius: $radii; + -ms-border-radius: $radii; + -o-border-radius: $radii; + border-radius: $radii; +} + +@mixin border-top-left-radius($radii) { + -webkit-border-top-left-radius: $radii; + -moz-border-top-left-radius: $radii; + -moz-border-radius-topleft: $radii; + -ms-border-top-left-radius: $radii; + -o-border-top-left-radius: $radii; + border-top-left-radius: $radii; +} + +@mixin border-top-right-radius($radii) { + -webkit-border-top-right-radius: $radii; + -moz-border-top-right-radius: $radii; + -moz-border-radius-topright: $radii; + -ms-border-top-right-radius: $radii; + -o-border-top-right-radius: $radii; + border-top-right-radius: $radii; +} + +@mixin border-bottom-left-radius($radii) { + -webkit-border-bottom-left-radius: $radii; + -moz-border-bottom-left-radius: $radii; + -moz-border-radius-bottomleft: $radii; + -ms-border-bottom-left-radius: $radii; + -o-border-bottom-left-radius: $radii; + border-bottom-left-radius: $radii; +} + +@mixin border-bottom-right-radius($radii) { + -webkit-border-bottom-right-radius: $radii; + -moz-border-bottom-right-radius: $radii; + -moz-border-radius-bottomright: $radii; + -ms-border-bottom-right-radius: $radii; + -o-border-bottom-right-radius: $radii; + border-bottom-right-radius: $radii; +} + +@mixin border-top-radius($radii) { + @include border-top-left-radius($radii); + @include border-top-right-radius($radii); +} + +@mixin border-right-radius($radii) { + @include border-top-right-radius($radii); + @include border-bottom-right-radius($radii); +} + +@mixin border-bottom-radius($radii) { + @include border-bottom-left-radius($radii); + @include border-bottom-right-radius($radii); +} + +@mixin border-left-radius($radii) { + @include border-top-left-radius($radii); + @include border-bottom-left-radius($radii); +} diff --git a/cms/static/sass/bourbon/css3/_box-shadow.scss b/cms/static/sass/bourbon/css3/_box-shadow.scss new file mode 100644 index 0000000000000000000000000000000000000000..327b66d251eb0760eb2c2ced63b4ddc0ed96c008 --- /dev/null +++ b/cms/static/sass/bourbon/css3/_box-shadow.scss @@ -0,0 +1,14 @@ +// Box-Shadow Mixin Requires Sass v3.1.1+ +@mixin box-shadow ($shadow-1, + $shadow-2: false, $shadow-3: false, + $shadow-4: false, $shadow-5: false, + $shadow-6: false, $shadow-7: false, + $shadow-8: false, $shadow-9: false) + { + $full: compact($shadow-1, $shadow-2, $shadow-3, $shadow-4, + $shadow-5, $shadow-6, $shadow-7, $shadow-8, $shadow-9); + + -webkit-box-shadow: $full; + -moz-box-shadow: $full; + box-shadow: $full; +} diff --git a/cms/static/sass/bourbon/css3/_box-sizing.scss b/cms/static/sass/bourbon/css3/_box-sizing.scss new file mode 100644 index 0000000000000000000000000000000000000000..3f3f7cca9aab21037da660286d3e7c9e1b490a26 --- /dev/null +++ b/cms/static/sass/bourbon/css3/_box-sizing.scss @@ -0,0 +1,6 @@ +@mixin box-sizing ($box) { +// content-box | border-box | inherit + -webkit-box-sizing: $box; + -moz-box-sizing: $box; + box-sizing: $box; +} diff --git a/cms/static/sass/bourbon/css3/_columns.scss b/cms/static/sass/bourbon/css3/_columns.scss new file mode 100644 index 0000000000000000000000000000000000000000..2896c91d7f25309fd222843f5535163df86ab207 --- /dev/null +++ b/cms/static/sass/bourbon/css3/_columns.scss @@ -0,0 +1,67 @@ +@mixin columns($arg: auto) { +// <column-count> || <column-width> + -webkit-columns: $arg; + -moz-columns: $arg; + columns: $arg; +} + +@mixin column-count($int: auto) { +// auto || integer + -webkit-column-count: $int; + -moz-column-count: $int; + column-count: $int; +} + +@mixin column-gap($length: normal) { +// normal || length + -webkit-column-gap: $length; + -moz-column-gap: $length; + column-gap: $length; +} + +@mixin column-fill($arg: auto) { +// auto || length + -webkit-columns-fill: $arg; + -moz-columns-fill: $arg; + columns-fill: $arg; +} + +@mixin column-rule($arg) { +// <border-width> || <border-style> || <color> + -webkit-column-rule: $arg; + -moz-column-rule: $arg; + column-rule: $arg; +} + +@mixin column-rule-color($color) { + -webkit-column-rule-color: $color; + -moz-column-rule-color: $color; + column-rule-color: $color; +} + +@mixin column-rule-style($style: none) { +// none | hidden | dashed | dotted | double | groove | inset | inset | outset | ridge | solid + -webkit-column-rule-style: $style; + -moz-column-rule-style: $style; + column-rule-style: $style; +} + +@mixin column-rule-width ($width: none) { + -webkit-column-rule-width: $width; + -moz-column-rule-width: $width; + column-rule-width: $width; +} + +@mixin column-span($arg: none) { +// none || all + -webkit-column-span: $arg; + -moz-column-span: $arg; + column-span: $arg; +} + +@mixin column-width($length: auto) { +// auto || length + -webkit-column-width: $length; + -moz-column-width: $length; + column-width: $length; +} diff --git a/cms/static/sass/bourbon/css3/_flex-box.scss b/cms/static/sass/bourbon/css3/_flex-box.scss new file mode 100644 index 0000000000000000000000000000000000000000..44c1dfd78996e9faf09a95c94e8b36689d43d92c --- /dev/null +++ b/cms/static/sass/bourbon/css3/_flex-box.scss @@ -0,0 +1,67 @@ +// CSS3 Flexible Box Model and property defaults + +// Custom shorthand notation for flexbox +@mixin box($orient: inline-axis, $pack: start, $align: stretch) { + @include display-box; + @include box-orient($orient); + @include box-pack($pack); + @include box-align($align); +} + +@mixin display-box { + display: -webkit-box; + display: -moz-box; + display: box; +} + +@mixin box-orient($orient: inline-axis) { +// horizontal|vertical|inline-axis|block-axis|inherit + -webkit-box-orient: $orient; + -moz-box-orient: $orient; + box-orient: $orient; +} + +@mixin box-pack($pack: start) { +// start|end|center|justify + -webkit-box-pack: $pack; + -moz-box-pack: $pack; + box-pack: $pack; +} + +@mixin box-align($align: stretch) { +// start|end|center|baseline|stretch + -webkit-box-align: $align; + -moz-box-align: $align; + box-align: $align; +} + +@mixin box-direction($direction: normal) { +// normal|reverse|inherit + -webkit-box-direction: $direction; + -moz-box-direction: $direction; + box-direction: $direction; +} +@mixin box-lines($lines: single) { +// single|multiple + -webkit-box-lines: $lines; + -moz-box-lines: $lines; + box-lines: $lines; +} + +@mixin box-ordinal-group($integer: 1) { + -webkit-box-ordinal-group: $integer; + -moz-box-ordinal-group: $integer; + box-ordinal-group: $integer; +} + +@mixin box-flex($value: 0.0) { + -webkit-box-flex: $value; + -moz-box-flex: $value; + box-flex: $value; +} + +@mixin box-flex-group($integer: 1) { + -webkit-box-flex-group: $integer; + -moz-box-flex-group: $integer; + box-flex-group: $integer; +} diff --git a/cms/static/sass/bourbon/css3/_inline-block.scss b/cms/static/sass/bourbon/css3/_inline-block.scss new file mode 100644 index 0000000000000000000000000000000000000000..d79a13c851bf4d0f597f5dd8f40a369fab15c43b --- /dev/null +++ b/cms/static/sass/bourbon/css3/_inline-block.scss @@ -0,0 +1,10 @@ +// Legacy support for inline-block in IE7 (maybe IE6) +@mixin inline-block { + display: -moz-inline-box; + -moz-box-orient: vertical; + display: inline-block; + vertical-align: baseline; + zoom: 1; + *display: inline; + *vertical-align: auto; +} diff --git a/cms/static/sass/bourbon/css3/_linear-gradient.scss b/cms/static/sass/bourbon/css3/_linear-gradient.scss new file mode 100644 index 0000000000000000000000000000000000000000..e366a299a9420cdbd3c27d22c7d987f8e4eb4952 --- /dev/null +++ b/cms/static/sass/bourbon/css3/_linear-gradient.scss @@ -0,0 +1,41 @@ +@mixin linear-gradient($pos, $G1, $G2: false, + $G3: false, $G4: false, + $G5: false, $G6: false, + $G7: false, $G8: false, + $G9: false, $G10: false, + $fallback: false) { + // Detect what type of value exists in $pos + $pos-type: type-of(nth($pos, 1)); + + // If $pos is missing from mixin, reassign vars and add default position + @if ($pos-type == color) or (nth($pos, 1) == "transparent") { + $G10: $G9; $G9: $G8; $G8: $G7; $G7: $G6; $G6: $G5; + $G5: $G4; $G4: $G3; $G3: $G2; $G2: $G1; $G1: $pos; + $pos: top; // Default position + } + + $full: compact($G1, $G2, $G3, $G4, $G5, $G6, $G7, $G8, $G9, $G10); + + // Set $G1 as the default fallback color + $fallback-color: nth($G1, 1); + + // If $fallback is a color use that color as the fallback color + @if (type-of($fallback) == color) or ($fallback == "transparent") { + $fallback-color: $fallback; + } + + background-color: $fallback-color; + background-image: deprecated-webkit-gradient(linear, $full); // Safari <= 5.0 + background-image: -webkit-linear-gradient($pos, $full); // Safari 5.1+, Chrome + background-image: -moz-linear-gradient($pos, $full); + background-image: -ms-linear-gradient($pos, $full); + background-image: -o-linear-gradient($pos, $full); + background-image: unquote("linear-gradient(#{$pos}, #{$full})"); +} + + +// Usage: Gradient position is optional, default is top. Position can be a degree. Color stops are optional as well. +// @include linear-gradient(#1e5799, #2989d8); +// @include linear-gradient(#1e5799, #2989d8, $fallback:#2989d8); +// @include linear-gradient(top, #1e5799 0%, #2989d8 50%); +// @include linear-gradient(50deg, rgba(10, 10, 10, 0.5) 0%, #2989d8 50%, #207cca 51%, #7db9e8 100%); diff --git a/cms/static/sass/bourbon/css3/_radial-gradient.scss b/cms/static/sass/bourbon/css3/_radial-gradient.scss new file mode 100644 index 0000000000000000000000000000000000000000..e83cab52342499de7e5a6ac04f6e8e72336d28a2 --- /dev/null +++ b/cms/static/sass/bourbon/css3/_radial-gradient.scss @@ -0,0 +1,31 @@ +// Requires Sass 3.1+ +@mixin radial-gradient($pos, $shape-size, + $G1, $G2, + $G3: false, $G4: false, + $G5: false, $G6: false, + $G7: false, $G8: false, + $G9: false, $G10: false, + $fallback: false) { + + $full: compact($G1, $G2, $G3, $G4, $G5, $G6, $G7, $G8, $G9, $G10); + + // Set $G1 as the default fallback color + $fallback-color: nth($G1, 1); + + // If $fallback is a color use that color as the fallback color + @if (type-of($fallback) == color) or ($fallback == "transparent") { + $fallback-color: $fallback; + } + + background-color: $fallback-color; + background-image: deprecated-webkit-gradient(radial, $full); // Safari <= 5.0 + background-image: -webkit-radial-gradient($pos, $shape-size, $full); + background-image: -moz-radial-gradient($pos, $shape-size, $full); + background-image: -ms-radial-gradient($pos, $shape-size, $full); + background-image: -o-radial-gradient($pos, $shape-size, $full); + background-image: unquote("radial-gradient(#{$pos}, #{$shape-size}, #{$full})"); +} + +// Usage: Gradient position and shape-size are required. Color stops are optional. +// @include radial-gradient(50% 50%, circle cover, #1e5799, #efefef); +// @include radial-gradient(50% 50%, circle cover, #eee 10%, #1e5799 30%, #efefef); diff --git a/cms/static/sass/bourbon/css3/_transform.scss b/cms/static/sass/bourbon/css3/_transform.scss new file mode 100644 index 0000000000000000000000000000000000000000..8d19e8b88de42242d77f0d413bea1f46cf16a246 --- /dev/null +++ b/cms/static/sass/bourbon/css3/_transform.scss @@ -0,0 +1,19 @@ +@mixin transform($property: none) { +// none | <transform-function> + -webkit-transform: $property; + -moz-transform: $property; + -ms-transform: $property; + -o-transform: $property; + transform: $property; +} + +@mixin transform-origin($axes: 50%) { +// x-axis - left | center | right | length | % +// y-axis - top | center | bottom | length | % +// z-axis - length + -webkit-transform-origin: $axes; + -moz-transform-origin: $axes; + -ms-transform-origin: $axes; + -o-transform-origin: $axes; + transform-origin: $axes; +} diff --git a/cms/static/sass/bourbon/css3/_transition.scss b/cms/static/sass/bourbon/css3/_transition.scss new file mode 100644 index 0000000000000000000000000000000000000000..058dbe0e33ea16336f3aefbc86cd2279e30e70c0 --- /dev/null +++ b/cms/static/sass/bourbon/css3/_transition.scss @@ -0,0 +1,104 @@ +// Shorthand mixin. Supports multiple parentheses-deliminated values for each variable. +// Example: @include transition (all, 2.0s, ease-in-out); +// @include transition ((opacity, width), (1.0s, 2.0s), ease-in, (0, 2s)); +// @include transition ($property:(opacity, width), $delay: (1.5s, 2.5s)); + +@mixin transition ($property: all, $duration: 0.15s, $timing-function: ease-out, $delay: 0) { + + // Detect # of args passed into each variable + $length-of-property: length($property); + $length-of-duration: length($duration); + $length-of-timing-function: length($timing-function); + $length-of-delay: length($delay); + + @if $length-of-property > 1 { + @include transition-property(zip($property)); } + @else { + @include transition-property( $property); + } + + @if $length-of-duration > 1 { + @include transition-duration(zip($duration)); } + @else { + @include transition-duration( $duration); + } + + @if $length-of-timing-function > 1 { + @include transition-timing-function(zip($timing-function)); } + @else { + @include transition-timing-function( $timing-function); + } + + @if $length-of-delay > 1 { + @include transition-delay(zip($delay)); } + @else { + @include transition-delay( $delay); + } +} + + +@mixin transition-property ($prop-1: all, + $prop-2: false, $prop-3: false, + $prop-4: false, $prop-5: false, + $prop-6: false, $prop-7: false, + $prop-8: false, $prop-9: false) + { + $full: compact($prop-1, $prop-2, $prop-3, $prop-4, $prop-5, + $prop-6, $prop-7, $prop-8, $prop-9); + + -webkit-transition-property: $full; + -moz-transition-property: $full; + -ms-transition-property: $full; + -o-transition-property: $full; + transition-property: $full; +} + +@mixin transition-duration ($time-1: 0, + $time-2: false, $time-3: false, + $time-4: false, $time-5: false, + $time-6: false, $time-7: false, + $time-8: false, $time-9: false) + { + $full: compact($time-1, $time-2, $time-3, $time-4, $time-5, + $time-6, $time-7, $time-8, $time-9); + + -webkit-transition-duration: $full; + -moz-transition-duration: $full; + -ms-transition-duration: $full; + -o-transition-duration: $full; + transition-duration: $full; +} + +@mixin transition-timing-function ($motion-1: ease, + $motion-2: false, $motion-3: false, + $motion-4: false, $motion-5: false, + $motion-6: false, $motion-7: false, + $motion-8: false, $motion-9: false) + { + $full: compact($motion-1, $motion-2, $motion-3, $motion-4, $motion-5, + $motion-6, $motion-7, $motion-8, $motion-9); + +// ease | linear | ease-in | ease-out | ease-in-out | cubic-bezier() + -webkit-transition-timing-function: $full; + -moz-transition-timing-function: $full; + -ms-transition-timing-function: $full; + -o-transition-timing-function: $full; + transition-timing-function: $full; +} + +@mixin transition-delay ($time-1: 0, + $time-2: false, $time-3: false, + $time-4: false, $time-5: false, + $time-6: false, $time-7: false, + $time-8: false, $time-9: false) + { + $full: compact($time-1, $time-2, $time-3, $time-4, $time-5, + $time-6, $time-7, $time-8, $time-9); + + -webkit-transition-delay: $full; + -moz-transition-delay: $full; + -ms-transition-delay: $full; + -o-transition-delay: $full; + transition-delay: $full; +} + diff --git a/cms/static/sass/bourbon/css3/_user-select.scss b/cms/static/sass/bourbon/css3/_user-select.scss new file mode 100644 index 0000000000000000000000000000000000000000..d5f5749431b070c0a6c68b311b2cbd989b0b8f63 --- /dev/null +++ b/cms/static/sass/bourbon/css3/_user-select.scss @@ -0,0 +1,6 @@ +@mixin user-select($arg: none) { + -webkit-user-select: $arg; + -moz-user-select: $arg; + -ms-user-select: $arg; + user-select: $arg; +} diff --git a/cms/static/sass/bourbon/functions/_deprecated-webkit-gradient.scss b/cms/static/sass/bourbon/functions/_deprecated-webkit-gradient.scss new file mode 100644 index 0000000000000000000000000000000000000000..1322f6f60e924423995ccd258733c820e2311e6a --- /dev/null +++ b/cms/static/sass/bourbon/functions/_deprecated-webkit-gradient.scss @@ -0,0 +1,36 @@ +// Render Deprecated Webkit Gradient - Linear || Radial +//************************************************************************// +@function deprecated-webkit-gradient($type, $full) { + $gradient-list: (); + $gradient: false; + $full-length: length($full); + $percentage: false; + $gradient-type: $type; + + @for $i from 1 through $full-length { + $gradient: nth($full, $i); + + @if length($gradient) == 2 { + $color-stop: color-stop(nth($gradient, 2), nth($gradient, 1)); + $gradient-list: join($gradient-list, $color-stop, comma); + } + @else { + @if $i == $full-length { + $percentage: 100%; + } + @else { + $percentage: ($i - 1) * (100 / ($full-length - 1)) + "%"; + } + $color-stop: color-stop(unquote($percentage), $gradient); + $gradient-list: join($gradient-list, $color-stop, comma); + } + } + + @if $type == radial { + $gradient: -webkit-gradient(radial, center center, 0, center center, 460, $gradient-list); + } + @else if $type == linear { + $gradient: -webkit-gradient(linear, left top, left bottom, $gradient-list); + } + @return $gradient; +} diff --git a/cms/static/sass/bourbon/functions/_flex-grid.scss b/cms/static/sass/bourbon/functions/_flex-grid.scss new file mode 100644 index 0000000000000000000000000000000000000000..707f994e15448b28cc3e8acf1889c08b322f17e9 --- /dev/null +++ b/cms/static/sass/bourbon/functions/_flex-grid.scss @@ -0,0 +1,35 @@ +// Flexible grid +@function flex-grid($columns, $container-columns: $fg-max-columns) { + $width: $columns * $fg-column + ($columns - 1) * $fg-gutter; + $container-width: $container-columns * $fg-column + ($container-columns - 1) * $fg-gutter; + @return percentage($width / $container-width); +} + +// Flexible gutter +@function flex-gutter($container-columns: $fg-max-columns, $gutter: $fg-gutter) { + $container-width: $container-columns * $fg-column + ($container-columns - 1) * $fg-gutter; + @return percentage($gutter / $container-width); +} + +// The $fg-column, $fg-gutter and $fg-max-columns variables must be defined in your base stylesheet to properly use the flex-grid function. +// This function takes the fluid grid equation (target / context = result) and uses columns to help define each. +// +// $fg-column: 60px; // Column Width +// $fg-gutter: 25px; // Gutter Width +// $fg-max-columns: 12; // Total Columns For Main Container +// +// div { +// width: flex-grid(4); // returns (315px / 1020px) = 30.882353%; +// margin-left: flex-gutter(); // returns (25px / 1020px) = 2.45098%; +// +// p { +// width: flex-grid(2, 4); // returns (145px / 315px) = 46.031746%; +// float: left; +// margin: flex-gutter(4); // returns (25px / 315px) = 7.936508%; +// } +// +// blockquote { +// float: left; +// width: flex-grid(2, 4); // returns (145px / 315px) = 46.031746%; +// } +// } diff --git a/cms/static/sass/bourbon/functions/_grid-width.scss b/cms/static/sass/bourbon/functions/_grid-width.scss new file mode 100644 index 0000000000000000000000000000000000000000..8e63d83d60239e28a3d360aea2fc571adcec82e9 --- /dev/null +++ b/cms/static/sass/bourbon/functions/_grid-width.scss @@ -0,0 +1,13 @@ +@function grid-width($n) { + @return $n * $gw-column + ($n - 1) * $gw-gutter; +} + +// The $gw-column and $gw-gutter variables must be defined in your base stylesheet to properly use the grid-width function. +// +// $gw-column: 100px; // Column Width +// $gw-gutter: 40px; // Gutter Width +// +// div { +// width: grid-width(4); // returns 520px; +// margin-left: $gw-gutter; // returns 40px; +// } diff --git a/cms/static/sass/bourbon/functions/_linear-gradient.scss b/cms/static/sass/bourbon/functions/_linear-gradient.scss new file mode 100644 index 0000000000000000000000000000000000000000..3b10ca82a6ea2d77d4e89de0b1747ec1dce2e1fb --- /dev/null +++ b/cms/static/sass/bourbon/functions/_linear-gradient.scss @@ -0,0 +1,23 @@ +@function linear-gradient($pos: top, $G1: false, $G2: false, + $G3: false, $G4: false, + $G5: false, $G6: false, + $G7: false, $G8: false, + $G9: false, $G10: false) { + + // Detect what type of value exists in $pos + $pos-type: type-of(nth($pos, 1)); + + // If $pos is missing from mixin, reassign vars and add default position + @if ($pos-type == color) or (nth($pos, 1) == "transparent") { + $G10: $G9; $G9: $G8; $G8: $G7; $G7: $G6; $G6: $G5; + $G5: $G4; $G4: $G3; $G3: $G2; $G2: $G1; $G1: $pos; + $pos: top; // Default position + } + + $type: linear; + $gradient: compact($pos, $G1, $G2, $G3, $G4, $G5, $G6, $G7, $G8, $G9, $G10); + $type-gradient: append($type, $gradient, comma); + + @return $type-gradient; +} + diff --git a/cms/static/sass/bourbon/functions/_modular-scale.scss b/cms/static/sass/bourbon/functions/_modular-scale.scss new file mode 100644 index 0000000000000000000000000000000000000000..dddccb522416baa3670757e705502a3d1f700337 --- /dev/null +++ b/cms/static/sass/bourbon/functions/_modular-scale.scss @@ -0,0 +1,40 @@ +@function modular-scale($value, $increment, $ratio) { + @if $increment > 0 { + @for $i from 1 through $increment { + $value: ($value * $ratio); + } + } + + @if $increment < 0 { + $increment: abs($increment); + @for $i from 1 through $increment { + $value: ($value / $ratio); + } + } + + @return $value; +} + +// div { +// Increment Up GR with positive value +// font-size: modular-scale(14px, 1, 1.618); // returns: 22.652px +// +// Increment Down GR with negative value +// font-size: modular-scale(14px, -1, 1.618); // returns: 8.653px +// +// Can be used with ceil(round up) or floor(round down) +// font-size: floor( modular-scale(14px, 1, 1.618) ); // returns: 22px +// font-size: ceil( modular-scale(14px, 1, 1.618) ); // returns: 23px +// } +// +// modularscale.com + +@function golden-ratio($value, $increment) { + @return modular-scale($value, $increment, 1.618) +} + +// div { +// font-size: golden-ratio(14px, 1); // returns: 22.652px +// } +// +// goldenratiocalculator.com diff --git a/cms/static/sass/bourbon/functions/_radial-gradient.scss b/cms/static/sass/bourbon/functions/_radial-gradient.scss new file mode 100644 index 0000000000000000000000000000000000000000..3d5461ad6e68b5c0b62fdd64a1eb773278976b8d --- /dev/null +++ b/cms/static/sass/bourbon/functions/_radial-gradient.scss @@ -0,0 +1,15 @@ +// This function is required and used by the background-image mixin. +@function radial-gradient($pos, $shape-size, + $G1, $G2, + $G3: false, $G4: false, + $G5: false, $G6: false, + $G7: false, $G8: false, + $G9: false, $G10: false) { + + $type: radial; + $gradient: compact($pos, $shape-size, $G1, $G2, $G3, $G4, $G5, $G6, $G7, $G8, $G9, $G10); + $type-gradient: append($type, $gradient, comma); + + @return $type-gradient; +} + diff --git a/cms/static/sass/bourbon/functions/_render-gradients.scss b/cms/static/sass/bourbon/functions/_render-gradients.scss new file mode 100644 index 0000000000000000000000000000000000000000..fe7c799ebe18e175eb1ffd8f9b00e94a3f6c3578 --- /dev/null +++ b/cms/static/sass/bourbon/functions/_render-gradients.scss @@ -0,0 +1,14 @@ +// User for linear and radial gradients within background-image or border-image properties + +@function render-gradients($gradients, $gradient-type, $vendor: false) { + $vendor-gradients: false; + @if $vendor { + $vendor-gradients: -#{$vendor}-#{$gradient-type}-gradient($gradients); + } + + @else if $vendor == false { + $vendor-gradients: "#{$gradient-type}-gradient(#{$gradients})"; + $vendor-gradients: unquote($vendor-gradients); + } + @return $vendor-gradients; +} diff --git a/cms/static/sass/bourbon/functions/_tint-shade.scss b/cms/static/sass/bourbon/functions/_tint-shade.scss new file mode 100644 index 0000000000000000000000000000000000000000..f7172004ac63383814f203a6d289c86ca4563b95 --- /dev/null +++ b/cms/static/sass/bourbon/functions/_tint-shade.scss @@ -0,0 +1,9 @@ +// Add percentage of white to a color +@function tint($color, $percent){ + @return mix(white, $color, $percent); +} + +// Add percentage of black to a color +@function shade($color, $percent){ + @return mix(black, $color, $percent); +} diff --git a/cms/static/sass/bourbon/lib/bourbon.rb b/cms/static/sass/bourbon/lib/bourbon.rb new file mode 100644 index 0000000000000000000000000000000000000000..1635be836de5973edcad9a644994def53fa05140 --- /dev/null +++ b/cms/static/sass/bourbon/lib/bourbon.rb @@ -0,0 +1,19 @@ +require "bourbon/generator" + +module Bourbon + if defined?(Rails) + class Engine < ::Rails::Engine + require 'bourbon/engine' + end + + module Rails + class Railtie < ::Rails::Railtie + rake_tasks do + load "tasks/install.rake" + end + end + end + end +end + +require File.join(File.dirname(__FILE__), "/bourbon/sass_extensions") diff --git a/cms/static/sass/bourbon/lib/bourbon/sass_extensions.rb b/cms/static/sass/bourbon/lib/bourbon/sass_extensions.rb new file mode 100644 index 0000000000000000000000000000000000000000..ad567200e3ebdc732dde3202cbc4a0177801b382 --- /dev/null +++ b/cms/static/sass/bourbon/lib/bourbon/sass_extensions.rb @@ -0,0 +1,6 @@ +module Bourbon::SassExtensions +end + +require "sass" + +require File.join(File.dirname(__FILE__), "/sass_extensions/functions") diff --git a/cms/static/sass/bourbon/lib/bourbon/sass_extensions/functions.rb b/cms/static/sass/bourbon/lib/bourbon/sass_extensions/functions.rb new file mode 100644 index 0000000000000000000000000000000000000000..daa877650e59fbea3f89ff80e146a393e952be65 --- /dev/null +++ b/cms/static/sass/bourbon/lib/bourbon/sass_extensions/functions.rb @@ -0,0 +1,13 @@ +module Bourbon::SassExtensions::Functions +end + +require File.join(File.dirname(__FILE__), "/functions/compact") + +module Sass::Script::Functions + include Bourbon::SassExtensions::Functions::Compact +end + +# Wierd that this has to be re-included to pick up sub-modules. Ruby bug? +class Sass::Script::Functions::EvaluationContext + include Sass::Script::Functions +end diff --git a/cms/static/sass/bourbon/lib/bourbon/sass_extensions/functions/compact.rb b/cms/static/sass/bourbon/lib/bourbon/sass_extensions/functions/compact.rb new file mode 100644 index 0000000000000000000000000000000000000000..5192e921e794e86a263f467224fa855b5c7b7c11 --- /dev/null +++ b/cms/static/sass/bourbon/lib/bourbon/sass_extensions/functions/compact.rb @@ -0,0 +1,13 @@ +# Compact function pulled from compass +module Bourbon::SassExtensions::Functions::Compact + + def compact(*args) + sep = :comma + if args.size == 1 && args.first.is_a?(Sass::Script::List) + args = args.first.value + sep = args.first.separator + end + Sass::Script::List.new(args.reject{|a| !a.to_bool}, sep) + end + +end diff --git a/cms/templates/base.html b/cms/templates/base.html new file mode 100644 index 0000000000000000000000000000000000000000..a23a31d9a59ea54cdfe335ed1843ff05e4870d04 --- /dev/null +++ b/cms/templates/base.html @@ -0,0 +1,30 @@ +<!doctype html> +<html> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> + + <link rel="stylesheet" href="${ STATIC_URL }/css/base-style.css"> + <link rel="stylesheet" type="text/css" href="${ STATIC_URL }/js/markitup/skins/simple/style.css" /> + <link rel="stylesheet" type="text/css" href="${ STATIC_URL }/js/markitup/sets/wiki/style.css" /> + <title><%block name="title"></%block></title> + <meta name="viewport" content="width=device-width,initial-scale=1"> + </head> + + <body> + + <%include file="widgets/header.html"/> + + <%block name="content"></%block> + + <script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> + <script type="text/javascript" src="${ STATIC_URL }/js/markitup/jquery.markitup.js"></script> + <script type="text/javascript" src="${ STATIC_URL }/js/markitup/sets/wiki/set.js"></script> + <script src="${ STATIC_URL }/js/main.js"></script> + <script src="${ STATIC_URL }/js/jquery.inlineedit.js"></script> + <script src="${ STATIC_URL }/js/jquery.leanModal.min.js"></script> + <script src="${ STATIC_URL }/js/jquery.tablednd.js"></script> + </body> +</html> + + diff --git a/cms/templates/index.html b/cms/templates/index.html new file mode 100644 index 0000000000000000000000000000000000000000..11c226ae3d1c5d42e656546542aeb9949f0b3216 --- /dev/null +++ b/cms/templates/index.html @@ -0,0 +1,20 @@ +<%inherit file="base.html" /> +<%block name="title">Course Manager</%block> + +<%block name="content"> +<section class="main-container"> + + <%include file="widgets/navigation.html"/> + + <section class="main-content"> + <%include file="widgets/week-edit.html"/> + <%include file="widgets/week-new.html"/> + <%include file="widgets/sequnce-edit.html"/> + <%include file="widgets/video-edit.html"/> + <%include file="widgets/video-new.html"/> + <%include file="widgets/problem-edit.html"/> + <%include file="widgets/problem-new.html"/> + </section> + +</section> +</%block> diff --git a/cms/templates/login.html b/cms/templates/login.html new file mode 100644 index 0000000000000000000000000000000000000000..03ea5f967c68f331b60728aa4254a7e25b4ae68c --- /dev/null +++ b/cms/templates/login.html @@ -0,0 +1,11 @@ +<form name="login" action="login", method="post"> + <input type="hidden" name="csrfmiddlewaretoken" value="${csrf_token}"/> + + % if next is not None: + <input type="hidden" name="next" value="${next}"/> + % endif + + Username: <input type="text" name="username" /> + Possword: <input type="password" name="password" /> + <input type="submit" value="Submit" /> +</form> diff --git a/cms/templates/widgets/captions.html b/cms/templates/widgets/captions.html new file mode 100644 index 0000000000000000000000000000000000000000..088beb7a33a8a7e94bbd0c5c47bb45cdbffbe9be --- /dev/null +++ b/cms/templates/widgets/captions.html @@ -0,0 +1,242 @@ +<ul class="tabs"> + <li class="active">English (main)</li> + <li>French</li> + <li>English v2</li> + <li>+</li> + </ul> + <textarea class="captions"> + { + "start": [ + 0, 2770, 5700, 7620, 10320, 12130, 13430, 15170, 17940, 20890, 22840, 26200, 28980, 30170, 32040, 33240, 36420, 37570, 41760, 44270, 48120, 50810, 52960, 54070, 56480, 58600, 59550, 62520, 67680, 69990, 74280, 77605, 81320, 85050, 88430, 92750, 96010, 99440, 103160, 106650, 110050, 114240, 118800, 120980, 122290, 125040, 127900, 130990, 133170, 134580, 139410, 143180, 144530, 147640, 150800, 153220, 156570, 161000, 162010, 162930, 164090, 165490, 167650, 170630, 172020, 174760, 178480, 181840, 185840, 188620, 194160, 196110, 199370, 201360, 204140, 209970, 211850, 215030, 218890, 221730, 225370, 228790, 231690, 234080, 236300, 237970, 240450, 244010, 247670, 251910, 253230, 260149, 263330, 266380, 269470, 273570, 278240, 280050, 282810, 288060, 292410, 297300, 298950, 300860, 302500, 304350, 309620, 312950, 318710, 322870, 323810, 328380, 332840, 334440, 338640, 341540, 345490, 348900, 350730, 354480, 357640, 362310, 365020, 366890, 368900, 373200, 374240, 379410, 381580, 381990, 385680, 389080, 390750, 393970, 395960, 397340, 401000, 403210, 405650, 408880, 411730, 415490, 421350, 425630, 427520, 430490, 435320, 436860, 439460, 443300, 447010, 450740, 453820, 456610, 460140, 463730, 466700, 471200, 472450, 475260, 476330, 480650, 483650, 486320, 489080, 491940, 496690, 501990, 502740, 507000, 511650, 513220, 517330, 519169, 524159, 528140, 529960, 531270, 535340, 541590, 543710, 545170, 550960, 551810, 555140, 556230, 557750, 560530, 564300, 566800, 567600, 569910, 573170, 578610, 580490, 585520, 586500, 589880, 591750, 596120, 597290, 600290, 602940, 606490, 608560, 610690, 612600, 613970, 616670, 621260, 622310, 624520, 626750, 629550, 632500, 635510, 637470, 638900, 640370, 644200, 647470, 648740, 652700, 653950 ], + "end": [ + 2770, 5700, 7620, 10320, 12130, 13430, 15170, 17940, 20890, 22840, 26200, 28980, 30170, 32040, 33240, 36420, 37570, 41760, 44269, 48120, 50809, 52960, 54070, 56480, 58599, 59550, 62519, 67680, 69990, 74280, 77605, 81320, 85050, 88429, 92750, 96010, 99440, 103160, 106649, 110050, 114240, 118800, 120980, 122290, 125040, 127900, 130990, 133170, 134579, 139410, 143180, 144530, 147640, 150799, 153220, 156570, 161000, 162010, 162929, 164090, 165490, 167650, 170630, 172019, 174760, 178480, 181840, 185840, 188620, 194160, 196109, 199370, 201360, 204140, 209970, 211850, 215030, 218890, 221730, 225369, 228790, 231690, 234079, 236300, 237970, 240450, 244010, 247670, 251910, 253230, 260149, 263330, 266380, 269469, 273570, 278240, 280050, 282810, 288060, 292410, 297300, 298950, 300860, 302500, 304350, 309620, 312950, 318710, 322870, 323810, 328380, 332840, 334440, 338640, 341539, 345490, 348900, 350729, 354480, 357640, 362310, 365020, 366890, 368900, 373200, 374240, 379410, 381580, 381990, 385680, 389080, 390750, 393970, 395960, 397340, 401000, 403210, 405650, 408880, 411730, 415490, 421350, 425630, 427520, 430490, 435320, 436860, 439460, 443299, 447010, 450740, 453820, 456610, 460140, 463729, 466700, 471200, 472450, 475260, 476330, 480650, 483650, 486320, 489080, 491940, 496690, 501990, 502740, 507000, 511650, 513220, 517330, 519169, 524159, 528140, 529960, 531270, 535340, 541590, 543710, 545170, 550959, 551810, 555140, 556230, 557750, 560530, 564300, 566800, 567599, 569910, 573170, 578610, 580490, 585520, 586500, 589880, 591750, 596120, 597290, 600290, 602939, 606490, 608560, 610689, 612600, 613970, 616670, 621260, 622310, 624520, 626750, 629550, 632500, 635510, 637470, 638900, 640370, 644200, 647470, 648740, 652700, 653950, 655050 ], + "text": [ + "SUBJECT 1: The various methods\nI'm going to show you--", + "in particular, the first method\none and method two for", + "solving non-linear equations--", + "are really just particular\nways of solving a pair of", + "equations where at least\none of each have some", + "non-linearity to them.", + "So let's start with the\ngraphical method.", + "And my circuit is on the\nright-hand side.", + "And I'm showing you the same\nvoltage source resistor--", + "the Thevenin pattern--", + "connected to Device D. And\nbelow that, I have the", + "equation iD equals ae\nraised to bvD, which", + "is the device equation.", + "So as before, let me\ngo ahead and do all", + "the first few steps.", + "I go ahead and write the\nnode equation at vD.", + "And I got that.", + "I go in and substitute, as I\nalways do, in the node method", + "for the current, using\nthe device relation.", + "And just for fun here, let me\nkeep that separate for now.", + "In the analytical method, notice\nthat you ended up with", + "these two equations, and\nyou had to solve", + "for these two unknowns.", + "And we did that using\nanalytical methods.", + "In this video, I'm going to\nsolve these using the", + "graphical method.", + "In order to do so here's what\nI'm going to do I want to", + "start by rearranging the terms\nin my equation 1 to make it a", + "little bit more convenient\nto draw the graph.", + "So notice in equation 2, I\nhave iD equals something.", + "And then I have an expression\nin vD and iD.", + "So what I'd like to do is let\nme start by taking this", + "equation here and expressing it\nin more of a standard form", + "so I can get something symmetric\nto equation 2.", + "So let me express this by\npulling iD to the left-hand", + "side all by itself, and so I\nget something like this.", + "So I get iD on the left-hand\nside, and then I'm going to", + "move vD minus V divided by\nr do the right hand side.", + "So let's start with minus V\ndivided by R, and when I move", + "that to the right-hand side, it\nbecomes V divided by R. And", + "then when I move vD over R to\nthe right-hand side, I get", + "minus vD over R. And I've simply\nnot done much here.", + "I just have done some\nrearranging of the terms in", + "equation 1.", + "And since I haven't done\nanything unique and different,", + "I'm just going to label\nthis as 1 prime.", + "So I just got this from equation\n1, and I just labeled", + "that as 1 prime.", + "Continuing with the method--", + "and now I'm summarizing for you\nequations 1 prime and 2--", + "we want both of them for iD on\nthe left-hand side expressed", + "as a function of vD.", + "And in equation 2,\nit is non-linear.", + "So the graphical method can\nbe summarized as follows.", + "To start, I want you to\nnotice something.", + "Essentially all we're trying to\ndo is find a solution, find", + "a value for vD and iD that\nsatisfies both equations, 1", + "prime and 2.", + "that's all we're trying to do.", + "It's just math here.", + "There's no circuits here.", + "We're just doing some relatively\nsimple math.", + "We just have to figure out what\niD and vD are, and we'll", + "use the graphical method.", + "So to do the graphical method,\nwhat I'm going to do is I'm", + "going to plot the two equations\nin a pair of graphs.", + "And let me first start by\nplotting equation 2.", + "And in equation 2, I'm going\nto plot iD equals a", + "raised to ae bvD.", + "I'm going to plot iD equals\na times e raised to bvD.", + "That's my equation 2.", + "And this is the plot\nthat I get for it.", + "It's a plot that I had before.", + "So that's my equation 2.", + "Notice that this plot here is\nsimply the constraint on iD", + "and vD imposed by the device.", + "This little circuit here\ncontaining the Thevenin", + "equivalent and connected to\nthe device, equation 2 is", + "simply the constraint imposed\nby the device.", + "The device properties are such\nthat it is going to constrain", + "iD and vD into some\nrelationship.", + "This constraint that I've\nplotted here as equation 2 is", + "simply the constraint imposed\nby this device.", + "OK, next, let me\ngo to 1 prime.", + "And in 1 prime, let\nme go ahead and", + "plot the 1 prime equation.", + "And that equation, as we\nrewrite that here, is V", + "divided by R minus vD divided\nby R. So I'm just going to", + "plot that equation for you\nin a second graph.", + "So how do I plot this?", + "So notice here that when vD is\n0, then iD is V divided by R.", + "So that is one point on\nthe straight line.", + "Notice that this is an equation\nfor a straight line.", + "It's a linear relationship\nbetween iD and vD.", + "Next, when iD is 0--\nso when iD is 0--", + "then notice that R and R can be\ncanceled out, and V will be", + "equal to vD.", + "So when iD is 0, V\nand vD are equal.", + "So therefore, vD equals V. So\nthis is the line when iD is 0.", + "And for that, vD equals V. So\nthen I get this [? long, ?]", + "straight line for the\nrelationship between vD and iD", + "according to 1 prime.", + "So what's the slope\nof this line here?", + "Can you tell me what the\nslope of this line is.", + "Let me give you a few seconds\nto think about it.", + null, + "OK, from the equation 1 prime--\nfrom this equation--", + "the slope is simply given by the\ncoefficient of vD, since", + "the slope is negative, which\nis why the line is inclined", + "the following way.", + "So the slope here is simply\nminus 1 divided by R.", + "So that is my constraint\nthat relates vD to iD.", + "And where did that constraint\ncome from?", + "That constraint is the\nconstraint on iD and vD that", + "has been imposed by the\nrest of the circuit.", + "So if the first constraint was\nimposed by the device, then", + "the second constraint is\nimposed by the Thevenin", + "equivalent that is connected\nto the device.", + "The Thevenin equivalent was\nthat V and R in series and", + "those two impose a Thevenin\nconstraint on the terminal", + "pair that relates vD and iD.", + "So now my next step is,\ngiven these two graphs", + "for iD versus vD--", + "and clearly those are\nmy two constraints.", + "Graph 2 says that iD and vD\nmust be somewhere on this", + "trajectory.", + "Graph 1 prime says, well, I'm\nnot going to let vD and iD be", + "anywhere else but\non this curve.", + "That's it.", + "Both of them are fighting with\neach other and telling each", + "other, nope, I'm not going to\nallow you to do anything.", + "You have to be on my curve.", + "So in this case, I have two\ncurves, and I need a point", + "that satisfies both curves.", + "And that is easy enough to do.", + "And I simply have to go\nand satisfy both these", + "constraints, and that will\ngive me the answer", + "for vD versus iD.", + "Before I do that, so I can go\nand solve it for you, let me", + "go and pick some values for\nthe various parameters.", + "So as before, I'm going to pick\nV equals 1 volt, R equals", + "1 ohm, a, a quarter of an amp,\nand b to be one volt inverse.", + "So I'll pick the same parameters\nas I had done when", + "I did the analytical method.", + "Next, what I'll do is I'll\nsubstitute these parameters", + "into the two equations 1 prime\nand 2 and rewrite them with", + "the parameters substituted.", + "So for 1 prime, I get iD.", + "Since V is 1 and R is 1, I get\nV divided by R equals 1.", + "And then since R is\n1, I get minus vD.", + "So this is 1 prime, once I've\nsubstituted the values.", + "And then for equation\n2, what do I get?", + "I get iD equals ae\nraised to bvD.", + "a is 1/4, so I write\nthat down.", + "b is 1, and so I\nget vD up here.", + "So I have my two equations in\nterms of the parameters I have", + "chosen, and now I can go ahead\nand plot the two equations and", + "see where they intersect.", + "I've given you the form of the\ngraph here, and so let me go", + "ahead and plot this.", + "Let me go ahead and plot 2\nfirst. 2 looks like this,", + "where this point is 1/4.", + "That was the a point.", + "As I said before, this curve\nis simply my Equation 2.", + "Then let me go ahead and\nplot equation 1 prime.", + "And as you recall, that looked\nsomething like this where the", + "vD intercept was V and the\ny-intercept was given by V", + "divided by R.", + "And in this case, it was\n1, and V was also 1.", + "So those are my two curves, and\nhere's the point where the", + "two coincide.", + "And then I just have to go and\nfind the values of iD and vD", + "where they two intersect.", + "So at this point, it will be\n0.56 volts, and this point", + "will be 0.44 amps.", + "It's the same as what\nI calculated in", + "the analytical method.", + "So let me go ahead and write\nthat down. iD equals, in this", + "case, 0.44 amps, and vD\nequals 0.56 volts.", + "So basically, I've just\ntaken the two graphs,", + "superimposed them.", + "This was 1 prime, and the\nnon-linear one was related to", + "Equation 2.", + "So before I jump off to one\nother thing, I can define", + "something for you.", + "Notice this curve here.", + "This is a straight line that\nreflects the Thevenin", + "constraint that I apply on\nmy non-linear device.", + "And I mentioned earlier we're\ngoing to do this again and", + "again and again.", + "I think you will see this at\nleast 10 more times in this", + "course where I take a Thevenin\nequivalent of the following", + "form, some voltage V, some R,\nand apply that in series", + "across something interesting.", + "So this line that I see here is\nthe constraint imposed by", + "the Thevenin equivalent.", + "And you can see that from\nthe equation 1 prime.", + "Now, there's a name\nfor this line.", + "So this line is called the "load\nline." You will see more", + "reasons for this later.", + "But this line is called\nthe "load line."", + "Let me show you one other little\ntrick, just in case you", + "didn't completely get how I\nsolved the graphical method.", + "But one little trick here.", + "If you like PowerPoint,\nyou will enjoy this.", + "And if you don't like\nPowerPoint, you", + "will hate me for it.", + "So if you look at these\ncurves, I have my two", + "equations in iD-- the 1 prime\nand 2-- and I've plotted them", + "for you here.", + "On the left-hand side,\nI plotted equation 2.", + "Right-hand side, I plotted\nequation 1.", + "And fundamentally, all that the\ngraphical method is doing", + "is simply superimposing\nthe two graphs.", + "And by superimposing the two\ngraphs, it is finding the", + "point where the two\ncurves intersect.", + "And this is what you get.", + "So let me do that again.", + "So I take one of the curves and\nsuperimpose it on top of", + "the other curve given the\nsame axes and the same", + "scales for the axes.", + "And then I go ahead and find\nthe solution for the point", + "where the two intersect.", + null + ] + } + + </textarea> + diff --git a/cms/templates/widgets/header.html b/cms/templates/widgets/header.html new file mode 100644 index 0000000000000000000000000000000000000000..49965e40268e6788c351af18268b2225a6e9745d --- /dev/null +++ b/cms/templates/widgets/header.html @@ -0,0 +1,21 @@ +<header> + <nav> + <h2><a href="/">6.002x circuits and electronics</a></h2> + <ul> + <li> + <a href="#" class="new-module">New Section</a> + </li> + <li> + <a href="#" class="new-module">New Module</a> + </li> + <li> + <a href="#" class="new-module">New Unit</a> + </li> + </ul> + + <ul class="user-nav"> + <li><a href="#">Tasks</a></li> + <li><a href="#">Settings</a></li> + </ul> + </nav> +</header> diff --git a/cms/templates/widgets/module-dropdown.html b/cms/templates/widgets/module-dropdown.html new file mode 100644 index 0000000000000000000000000000000000000000..7c6e1e068c69f2ad84e5ba7d4bc90bccaba3bf21 --- /dev/null +++ b/cms/templates/widgets/module-dropdown.html @@ -0,0 +1,28 @@ +<li class="create-module"> + <a href="#" class="new-module"> + + Add new module + </a> + <div> + <form> + <ul> + <li> + <input type="text" name="" id="" placeholder="Moldule title" /> + </li> + <li> + <select> + <option>Use template</option> + <option>Lecture Sequence</option> + <option>Use template</option> + </select> + </li> + <li> + <input type="submit" value="Create & Edit Module" /> + <div> + <a href="#">Save without edit</a> + <a href="#">Cancel</a> + </div> + </li> + </ul> + </form> + </div> +</li> diff --git a/cms/templates/widgets/navigation.html b/cms/templates/widgets/navigation.html new file mode 100644 index 0000000000000000000000000000000000000000..1f75dab470a9ff59b04c99b5b4c75022542cf164 --- /dev/null +++ b/cms/templates/widgets/navigation.html @@ -0,0 +1,115 @@ +<section class="cal"> + <header> + <h2>Filter content:</h2> + <ul> + <li> + <a href="#">Sequences</a> + + <ul> + <li>Hide all</li> + <li>Lectures</li> + <li>Labs</li> + <li>Homeworks</li> + <li>Exams</li> + </ul> + </li> + + <li> + <a href="#">Deadlines</a> + + <ul> + <li>Today</li> + <li>Tomorrow</li> + <li>This week</li> + <li>In 2 weeks</li> + <li>This month</li> + </ul> + </li> + <li> + <a href="#">Goals</a> + <ul> + <li>Hide</li> + </ul> + </li> + </ul> + </header> + + <ol> + % for week in weeks: + <li> + <header> + <h1><a href="#">${week.name}</a></h1> + <ul> + % for goal in week.get_goals(): + <li class="goal editable"><strong>${goal.name}:</strong>${goal.data}</li> + % endfor + </ul> + </header> + + <ul> + % for module in week.get_non_goals(): + <li class="${module.type}"> + <a href="#" class="${module.type}-edit">${module.name}</a> + <a href="#" class="draggable">handle</a> + </li> + % endfor + <%include file="module-dropdown.html"/> + </ul> + </li> + %endfor + <li> + <header> + <h1>Course Scratch Pad</h1> + </header> + + <ul> + <li> + <a href="#" class="problem-edit">Problem title 11</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit">Problem title 13 </a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit"> Problem title 14</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="" class="video-edit">Video 3</a> + <a href="#" class="draggable">handle</a> + </li> + </ul> + </li> + </ol> + + <section class="new-section"> + <a href="#" >+ Add New Section</a> + + <section> + <form> + <ul> + <li> + <input type="text" name="" id="" placeholder="Section title" /> + </li> + <li> + <select> + <option>Blank</option> + <option>6.002x</option> + <option>6.00x</option> + </select> + </li> + <li> + <input type="submit" value="Save and edit week" class="edit-week" /> + + <div> + <a href="#" class="close">Save without edit</a> + <a href="#" class="close">cancel</a> + </div> + </li> + </ul> + </form> + </section> + </section> +</section> + diff --git a/cms/templates/widgets/new-module.html b/cms/templates/widgets/new-module.html new file mode 100644 index 0000000000000000000000000000000000000000..8b12e5763a31a38f4571c80ffbc15064d10db5fe --- /dev/null +++ b/cms/templates/widgets/new-module.html @@ -0,0 +1,7 @@ +<a href="" class="default">+ add new</a> +<ul class="new-dropdown"> + <li class="import"><a href="#">Import from the edX library</a></li> + <li class="video-new"><a href="#">Create new video segment</a></li> + <li class="problem-new"><a href="#">Create new problem</a></li> + <li class="lab-lab"><a href="#">Create new lab</a></li> +</ul> diff --git a/cms/templates/widgets/problem-edit.html b/cms/templates/widgets/problem-edit.html new file mode 100644 index 0000000000000000000000000000000000000000..49f67e3e26839f1f452137b387b4aca8fedd89e3 --- /dev/null +++ b/cms/templates/widgets/problem-edit.html @@ -0,0 +1,73 @@ +<section class="problem-edit"> + <header> + <a href="#" class="cancel">Cancel</a> + <a href="#" class="save-update">Save & Update</a> + </header> + + <section> + <header> + <h1 class="editable">New Problem</h1> + <section class="author"> + <div> + <h2>Last modified:</h2> + <p>mm/dd/yy</p> + </div> + + <div> + <h2>By</h2> + <p>Anant Agarwal</p> + </div> + </section> + + <section class="status-settings"> + <ul> + <li><a href="#" class="current">Scrap</a></li> + <li><a href="#">Draft</a></li> + <li><a href="#">Proofed</a></li> + <li><a href="#">Published</a></li> + </ul> + <a href="#" class="settings">Settings</a> + + <select name="" id=""> + <option>Global</option> + </select> + </section> + <section class="meta"> + <div> + <h2>Tags:</h2> + <p class="editable">Click to edit</p> + </div> + + <div> + <h2>Goal</h2> + <p class="editable">Click to edit</p> + </div> + </section> + </header> + + <section> + <textarea name="" id= rows="8" cols="40">Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.</textarea> + <div class="preview"> + Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. + </div> + </section> + + <section class="notes"> + <h2>Add notes</h2> + <textarea name="" id= rows="8" cols="40"></textarea> + <input type="submit" name="" id="" value="post" /> + + <ul> + <li> + <p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.</p> + <p class="author">Anant Agarwal</p> + </li> + <li> + <p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.</p> + <p class="author">Anant Agarwal</p> + </li> + </ul> </section> + + <a href="" class="save-update">Save & Update</a> + </section> +</section> diff --git a/cms/templates/widgets/problem-new.html b/cms/templates/widgets/problem-new.html new file mode 100644 index 0000000000000000000000000000000000000000..d986f5a9ef1e054a4f92e4f80327b6536a8d01ea --- /dev/null +++ b/cms/templates/widgets/problem-new.html @@ -0,0 +1,51 @@ +<section class="problem-new"> + <header> + <a href="#" class="cancel">Cancel</a> + <a href="#" class="save-update">Save & Update</a> + </header> + + <section> + <header> + <h1 class="editable">New Problem</h1> + + <section class="status-settings"> + <ul> + <li><a href="#" class="current">Scrap</a></li> + <li><a href="#">Draft</a></li> + <li><a href="#">Proofed</a></li> + <li><a href="#">Published</a></li> + </ul> + <a href="#" class="settings">Settings</a> + + <select name="" id=""> + <option>Global</option> + </select> + </section> + <section class="meta"> + <div> + <h2>Tags:</h2> + <p class="editable">Click to edit</p> + </div> + + <div> + <h2>Goal</h2> + <p class="editable">Click to edit</p> + </div> + </section> + </header> + + <section> + <textarea name="" id= rows="8" cols="40"></textarea> + <div class="preview"> + </div> + </section> + + <section class="notes"> + <h2>Add notes</h2> + <textarea name="" id= rows="8" cols="40"></textarea> + <input type="submit" name="" id="" value="post" /> + </section> + + <a href="" class="save-update">Save & Update</a> + </section> +</section> diff --git a/cms/templates/widgets/raw-videos.html b/cms/templates/widgets/raw-videos.html new file mode 100644 index 0000000000000000000000000000000000000000..f466fd59bca97079acef8e67533516b92bd0820f --- /dev/null +++ b/cms/templates/widgets/raw-videos.html @@ -0,0 +1,3 @@ +<li> + <img src="http://placehold.it/300x180" alt="" /><h5>Video-file-name</h5> +</li> diff --git a/cms/templates/widgets/save-captions.html b/cms/templates/widgets/save-captions.html new file mode 100644 index 0000000000000000000000000000000000000000..87342f0cd004038cd208e205878056bf9a21bca8 --- /dev/null +++ b/cms/templates/widgets/save-captions.html @@ -0,0 +1,4 @@ +<section class="caption-save"> + <a href="#" class="close-box">Cancel</a> + <button class="close-box">Save changes</button> +</section> diff --git a/cms/templates/widgets/sequnce-edit.html b/cms/templates/widgets/sequnce-edit.html new file mode 100644 index 0000000000000000000000000000000000000000..b69b523bc445fa84715521c54199d43eba01995f --- /dev/null +++ b/cms/templates/widgets/sequnce-edit.html @@ -0,0 +1,187 @@ +<section class="sequence-edit"> + <header> + <div class="week"> + <h2><a href="">Week 1</a></h2> + <ul> + <li> + <p class="editable"><strong>Goal title:</strong> This is the goal body and is where the goal will be further explained</p> + </li> + </ul> + </div> + <div> + <h1 class="editable">Lecture sequence</h1> + <p><strong>Group type:</strong> Ordered Sequence</p> + </div> + </header> + + <section class="content"> + <section class="filters"> + <ul> + <li> + <label for="">Sort by</label> + <select> + <option value="">Recently Modified</option> + </select> + </li> + + <li> + <label for="">Display</label> + <select> + <option value="">All content</option> + </select> + </li> + <li> + <select> + <option value="">Internal Only</option> + </select> + </li> + + <li class="advanced"> + <a href="#">Advanced filters</a> + </li> + + <li> + <input type="search" name="" id="" value="" /> + </li> + </ul> + </section> + + <div> + <section class="modules"> + <ol> + <li> + <ol> + <li> + <a href="" class="problem-edit">Problem title 11</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="sequence-edit">Problem Group</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit">Problem title 14</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="video-edit">Video 3</a> + <a href="#" class="draggable">handle</a> + </li> + <li class="group"> + <header> + <h3> + <a href="#" class="problem-edit">Problem group</a> + <a href="#" class="draggable">handle</a> + </h3> + </header> + <ol> + <li> + <a href="#" class="problem-edit">Problem title 11</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit">Problem title 11</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit">Problem title 11</a> + <a href="#" class="draggable">handle</a> + </li> + </ol> + </li> + <li> + <a href="#" class="problem-edit">Problem title 13</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit">Problem title 14</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="video-edit">Video 3</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="" class="problem-edit">Problem title 11</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="sequence-edit">Problem Group</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit">Problem title 14</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="video-edit">Video 3</a> + <a href="#" class="draggable">handle</a> + </li> + </ol> + </li> + + <!-- <li class="new-module"> --> + <!-- <%include file="new-module.html"/> --> + <!-- </li> --> + </ol> + </section> + + <section class="scratch-pad"> + <ol> + <li> + <header> + <h2>Section Scratch</h2> + </header> + <ul> + <li> + <a href="#" class="problem-edit">Problem title 11</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit">Problem title 13 </a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit"> Problem title 14</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="" class="video-edit">Video 3</a> + <a href="#" class="draggable">handle</a> + </li> + </ul> + </li> + <li> + <header> + <h2>Course Scratch</h2> + </header> + + <ul> + <li> + <a href="#" class="problem-edit">Problem title 11</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit">Problem title 13 </a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit"> Problem title 14</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="" class="video-edit">Video 3</a> + <a href="#" class="draggable">handle</a> + </li> + </ul> + </li> + + <!-- <li class="new-module"> --> + <!-- <%include file="new-module.html"/> --> + <!-- </li> --> + </ol> + </section> + </div> + </section> +</section> + diff --git a/cms/templates/widgets/speed-tooltip.html b/cms/templates/widgets/speed-tooltip.html new file mode 100644 index 0000000000000000000000000000000000000000..2a82e237e76ad3a96bf37e3d0b4ead1ed89256e5 --- /dev/null +++ b/cms/templates/widgets/speed-tooltip.html @@ -0,0 +1,7 @@ +<div class="tooltip"> + <ul> + <li><a href="#view" rel="leanModal">View</a></li> + <li><a href="#">Download</a></li> + <li><a href="#" class="delete-speed">Delete</a></li> + </ul> +</div> diff --git a/cms/templates/widgets/video-box-unused.html b/cms/templates/widgets/video-box-unused.html new file mode 100644 index 0000000000000000000000000000000000000000..3d643ff3c9efd3704703cccf1b927d4b40cf94bb --- /dev/null +++ b/cms/templates/widgets/video-box-unused.html @@ -0,0 +1,38 @@ +<li class="video-box"> + + <div class="thumb"><img src="http://placehold.it/100x65" /></div> + + <div class="meta"> + <strong>video-name</strong> 236mb Uploaded 6 hours ago by <em>Anant Agrawal</em> + <p> + <ul class="speed-list"> + Speed + <li class="speed"> + 0.75x + <%include file="speed-tooltip.html"/> + </li> + <li class="speed">Normal + <%include file="speed-tooltip.html"/> + </li> + <li class="speed">1.25x + <%include file="speed-tooltip.html"/> + </li> + <li class="speed">1.5x + <%include file="speed-tooltip.html"/> + </li> + <li style="background: #eee;" ><a href="#upload" rel="leanModal" class="new-upload">+</a></li> + </ul> + </p> + <p> + <a href="#">Download All</a> — + <a href="#" style="color: brown;" class="remove">Delete All</a> — + <a href="#" class="edit-captions"> Edit Captions </a> — + <a href="#" class="use-video">Use clip ⬆</a> + </p> + </div> + <div class="caption-box"> + <%include file="captions.html"/> + <%include file="save-captions.html"/> + </div> +</li> + diff --git a/cms/templates/widgets/video-box.html b/cms/templates/widgets/video-box.html new file mode 100644 index 0000000000000000000000000000000000000000..1f17e33511631a93aee1c08a957fed304a1eef8a --- /dev/null +++ b/cms/templates/widgets/video-box.html @@ -0,0 +1,35 @@ +<li class="video-box"> + <div class="thumb"><img src="http://placehold.it/155x90" /></div> + + <div class="meta"> + <strong>video-name</strong> 236mb + <p>Uploaded 6 hours ago by <em>Anant Agrawal</em></p> + <p> + <ul class="speed-list"> + Speed + <li class="speed"> + 0.75x + <%include file="speed-tooltip.html"/> + </li> + <li class="speed">Normal + <%include file="speed-tooltip.html"/> + </li> + <li class="speed">1.25x + <%include file="speed-tooltip.html"/> + </li> + <li class="speed">1.5x + <%include file="speed-tooltip.html"/> + </li> + <li style="background: #eee;" ><a href="#upload" rel="leanModal" class="new-upload">+</a></li> + </ul> + </p> + <p> + <a href="#">Download all</a> — +<a href="#" stle="color: brown;" class="remove-video">Remove ⬇ </a> + + </p> + </div> + <div style="margin-top: 30px;"> + <%include file="captions.html"/> + </div> +</li> diff --git a/cms/templates/widgets/video-edit.html b/cms/templates/widgets/video-edit.html new file mode 100644 index 0000000000000000000000000000000000000000..0c82e743fe4ee337e01fc09f2154fdbbebb637c1 --- /dev/null +++ b/cms/templates/widgets/video-edit.html @@ -0,0 +1,59 @@ +<section class="video-new"> + <header> + <a href="#" class="cancel">Cancel</a> + <a href="#" class="save-update">Save & Update</a> + </header> + + <section> + <header> + <h1 class="editable">Untitled Video</h1> + + <section class="status-settings"> + <ul class="status"> + <li class="current"><a href="#">Scrap</a></li> + <li><a href="#">Draft</a></li> + <li><a href="#">Proofed</a></li> + <li><a href="#">Published</a></li + </ul> + + <a href="#" class="settings">Settings</a> + + <select name="" id=""> + <option>Global</option> + </select> + </section> + + <section class="meta"> + <div> + <h2>Tags:</h2> + <p class="editable">Click to edit</p> + </div> + <div> + <h2>Goal</h2> + <p class="editable">mitx, s4v1, circuits, anant</p> + </div> + </section> + </header> + + <section class="upload"> + <a href="#" class="upload-button">Upload new video clip</a> + Or + <a href="#">use an already uploaded one</a> + </section> + + <section class="in-use"> + <h2>Video in use</h2> + <div> + <p>No video clip used. <a href="">Select one</a> from the list below, <a href="">upload a new one</a> or <a href="">import already existing video</a></p> + </div> + </section> + + <section class="notes"> + <h2>Add notes</h2> + <textarea name="" id= rows="8" cols="40"></textarea> + <input type="submit" name="" id="" value="post" /> + </section> + + <a href="" class="save-update">Save & Update</a> + </section> +</section> diff --git a/cms/templates/widgets/video-new.html b/cms/templates/widgets/video-new.html new file mode 100644 index 0000000000000000000000000000000000000000..fecbaa423c5b898b947f94ad823122a0cff3146f --- /dev/null +++ b/cms/templates/widgets/video-new.html @@ -0,0 +1,85 @@ +<section class="video-new"> + <header> + <a href="#" class="cancel">Cancel</a> + <a href="#" class="save-update">Save & Update</a> + </header> + + <section> + <header> + <h1 class="editable">Untitled Video</h1> + + <section class="author"> + <div> + <h2>Last modified:</h2> + <p>mm/dd/yy</p> + </div> + + <div> + <h2>By</h2> + <p>Anant Agarwal</p> + </div> + </section> + + <section class="status-settings"> + <ul class="status"> + <li class="current"><a href="#">Scrap</a></li> + <li><a href="#">Draft</a></li> + <li><a href="#">Proofed</a></li> + <li><a href="#">Published</a></li> + </ul> + + <a href="#" class="settings">Settings</a> + + <select name="" id=""> + <option>Global</option> + </select> + </section> + + <section class="meta"> + <div> + <h2>Tags:</h2> + <p class="editable">mitx, s4v1, circuits, anant</p> + </div> + <div> + <h2>Goal</h2> + <p class="editable">Click to edit</p> + </div> + </section> + </header> + + <section class="upload"> + <a href="#" class="upload-button">Upload new video clip</a> + Or + <a href="#">use an already uploaded one</a> + + <section class="upload-video"> + <div> + <ul> + <li>video-name-@0-75x.extension</li> + <li>video-name-@1x.extension</li> + <li>video-name-@1-25x.extension</li> + <li>video-name-@1-5x.extension</li> + </ul> + </div> + <input type="file" /> + <input type="button" value="Upload" id="new-upload" style="float: right; margin-top: -4px;" /> + <a href="" id="new-upload" style="float: right; margin-right: 10px;">Cancel</a> + </section> + </section> + + <section class="in-use"> + <h2>Video in use</h2> + <div> + <p>No video clip used. <a href="">Select one</a> from the list below, <a href="">upload a new one</a> or <a href="">import already existing video</a></p> + </div> + </section> + + <section class="notes"> + <h2>Add notes</h2> + <textarea name="" id= rows="8" cols="40"></textarea> + <input type="submit" name="" id="" value="post" /> + </section> + + <a href="" class="save-update">Save & Update</a> + </section> +</section> diff --git a/cms/templates/widgets/week-edit.html b/cms/templates/widgets/week-edit.html new file mode 100644 index 0000000000000000000000000000000000000000..95ca631be0653d03e9e3792291df677dcd550ca1 --- /dev/null +++ b/cms/templates/widgets/week-edit.html @@ -0,0 +1,319 @@ +<section class="week-edit"> + <header> + <div> + <h1 class="editable">Week 3</h1> + <p><a href="#">+ new goal</a></p> + </div> + + <section class="goals"> + <ul> + <li> + <p class="editable"><strong>Goal title:</strong> This is the goal body and is where the goal will be further explained</p> + </li> + </ul> + </section> + </header> + + <section class="content"> + <section class="filters"> + <ul> + <li> + <label for="">Sort by</label> + <select> + <option value="">Recently Modified</option> + </select> + </li> + + <li> + <label for="">Display</label> + <select> + <option value="">All content</option> + </select> + </li> + <li> + <select> + <option value="">Internal Only</option> + </select> + </li> + + <li class="advanced"> + <a href="#">Advanced filters</a> + </li> + + <li> + <input type="search" name="" id="" value="" /> + </li> + </ul> + </section> + + <div> + <section class="modules"> + <ol> + <li> + <header> + <h2><a href="#">Lecture Sequence</a></h2> + <a href="#" class="draggable">handle</a> + </header> + + <ol> + <li> + <a href="" class="problem-edit">Problem title 11</a> + <a href="#" class="draggable">handle</a> + </li> + <li class="group"> + <header> + <h3> + <a href="#" class="problem-edit">Problem group</a> + <a href="#" class="draggable">handle</a> + </h3> + </header> + <ol> + <li> + <a href="#" class="problem-edit">Problem title 11</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit">Problem title 11</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit">Problem title 11</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit">Problem title 13</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit">Problem title 14</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="video-edit">Video 3</a> + <a href="#" class="draggable">handle</a> + </li> + </ol> + </li> <li> + <a href="#" class="sequence-edit">Problem Group</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit">Problem title 14</a> + <a href="#" class="draggable">handle</a> + </li> + <li class="group"> + <header> + <h3> + <a href="#" class="problem-edit">Problem group</a> + <a href="#" class="draggable">handle</a> + </h3> + </header> + <ol> + <li> + <a href="#" class="problem-edit">Problem title 11</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit">Problem title 11</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit">Problem title 11</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit">Problem title 13</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit">Problem title 14</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="video-edit">Video 3</a> + <a href="#" class="draggable">handle</a> + </li> + </ol> + </li> <li> + <a href="#" class="video-edit">Video 3</a> + <a href="#" class="draggable">handle</a> + </li> + <li class="group"> + <header> + <h3> + <a href="#" class="problem-edit">Problem group</a> + <a href="#" class="draggable">handle</a> + </h3> + </header> + <ol> + <li> + <a href="#" class="problem-edit">Problem title 11</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit">Problem title 11</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit">Problem title 11</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit">Problem title 13</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit">Problem title 14</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="video-edit">Video 3</a> + <a href="#" class="draggable">handle</a> + </li> + </ol> + </li> </ol> + </li> + <li> + <header> + <h2><a href="#">Lecture Sequence</a></h2> + <a href="#" class="draggable">handle</a> + </header> + + <ol> + <li class="group"> + <header> + <h3> + <a href="#" class="problem-edit">Problem group</a> + <a href="#" class="draggable">handle</a> + </h3> + </header> + <ol> + <li> + <a href="#" class="problem-edit">Problem title 11</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit">Problem title 11</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit">Problem title 11</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit">Problem title 13</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit">Problem title 14</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="video-edit">Video 3</a> + <a href="#" class="draggable">handle</a> + </li> + </ol> + </li> + <li> + <a href="#" class="problem-edit">Problem title 13</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit">Problem title 14</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="video-edit">Video 3</a> + <a href="#" class="draggable">handle</a> + </li> + </ol> + </li> + <li> + <header> + <h2><a href="#">Homework 1a</a></h2> + </header> + + <ol> + <li> + <a href="" class="problem-edit">Problem title 11</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="sequence-edit">Problem Group</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit">Problem title 14</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="video-edit">Video 3</a> + <a href="#" class="draggable">handle</a> + </li> + </ol> + </li> + + <!-- <li class="new-module"> --> + <!-- <%include file="new-module.html"/> --> + <!-- </li> --> + </ol> + </section> + + <section class="scratch-pad"> + <ol> + <li> + <header> + <h2>Section Scratch</h2> + </header> + <ul> + <li> + <a href="#" class="problem-edit">Problem title 11</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit">Problem title 13 </a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit"> Problem title 14</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="" class="video-edit">Video 3</a> + <a href="#" class="draggable">handle</a> + </li> + </ul> + </li> + <li> + <header> + <h2>Course Scratch</h2> + </header> + + <ul> + <li> + <a href="#" class="problem-edit">Problem title 11</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit">Problem title 13 </a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit"> Problem title 14</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="" class="video-edit">Video 3</a> + <a href="#" class="draggable">handle</a> + </li> + </ul> + </li> + + <!-- <li class="new-module"> --> + <!-- <%include file="new-module.html"/> --> + <!-- </li> --> + </ol> + </section> + </div> + </section> +</section> diff --git a/cms/templates/widgets/week-new.html b/cms/templates/widgets/week-new.html new file mode 100644 index 0000000000000000000000000000000000000000..c62730c1bc131cfd2280a445d36099eb33691783 --- /dev/null +++ b/cms/templates/widgets/week-new.html @@ -0,0 +1,99 @@ +<section class="week-new"> + <header> + <div> + <h1 class="editable">Week 3</h1> + <p><a href="#">+ new goal</a></p> + </div> + + <section class="goals"> + <ul> + <li> + <p><strong>Please add a goal for this section</strong> </p> + </li> + </ul> + </section> + </header> + + <section class="content"> + <section class="filters"> + <ul> + <li> + <label for="">Sort by</label> + <select> + <option value="">Recently Modified</option> + </select> + </li> + + <li> + <label for="">Display</label> + <select> + <option value="">All content</option> + </select> + </li> + <li> + <select> + <option value="">Internal Only</option> + </select> + </li> + + <li class="advanced"> + <a href="#">Advanced filters</a> + </li> + + <li> + <input type="search" name="" id="" value="" /> + </li> + </ul> + </section> + <div> + <section class="modules empty"> + <p>This are no groups or units in this section yet</p> + <a href="#">Add a Group</a> + <a href="#">Add a Unit</a> + </section> + + <section class="scratch-pad"> + <ol> + <li> + <header> + <h2>Section Scratch</h2> + </header> + <ul> + <li class="empty"> + <p><a href="#">There are no units in this scratch yet. Add one</a></p> + </li> + </ul> + </li> + <li> + <header> + <h2>Course Scratch</h2> + </header> + <ul> + <li> + <a href="" class="problem-edit">Problem title 11</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="sequence-edit">Problem Group</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="problem-edit">Problem title 14</a> + <a href="#" class="draggable">handle</a> + </li> + <li> + <a href="#" class="video-edit">Video 3</a> + <a href="#" class="draggable">handle</a> + </li> + </ul> + </li> + + <li class="new-module"> + <%include file="new-module.html"/> + </li> + </ol> + </section> + </div> + </section> +</section> + diff --git a/cms/urls.py b/cms/urls.py new file mode 100644 index 0000000000000000000000000000000000000000..781c2c261fc0de837768448ae3f95169e68dbc46 --- /dev/null +++ b/cms/urls.py @@ -0,0 +1,11 @@ +from django.conf.urls.defaults import patterns, url + +# Uncomment the next two lines to enable the admin: +# from django.contrib import admin +# admin.autodiscover() + +urlpatterns = patterns('', + url(r'^(?P<org>[^/]+)/(?P<course>[^/]+)/calendar/', 'contentstore.views.calendar', name='calendar'), + url(r'^accounts/login/', 'instructor.views.do_login', name='login'), + url(r'^$', 'contentstore.views.index', name='index'), +) diff --git a/lms/lib/cache_toolbox/COPYING b/common/djangoapps/cache_toolbox/COPYING similarity index 100% rename from lms/lib/cache_toolbox/COPYING rename to common/djangoapps/cache_toolbox/COPYING diff --git a/lms/lib/cache_toolbox/README.rst b/common/djangoapps/cache_toolbox/README.rst similarity index 100% rename from lms/lib/cache_toolbox/README.rst rename to common/djangoapps/cache_toolbox/README.rst diff --git a/lms/lib/cache_toolbox/__init__.py b/common/djangoapps/cache_toolbox/__init__.py similarity index 100% rename from lms/lib/cache_toolbox/__init__.py rename to common/djangoapps/cache_toolbox/__init__.py diff --git a/lms/lib/cache_toolbox/app_settings.py b/common/djangoapps/cache_toolbox/app_settings.py similarity index 100% rename from lms/lib/cache_toolbox/app_settings.py rename to common/djangoapps/cache_toolbox/app_settings.py diff --git a/lms/lib/cache_toolbox/core.py b/common/djangoapps/cache_toolbox/core.py similarity index 100% rename from lms/lib/cache_toolbox/core.py rename to common/djangoapps/cache_toolbox/core.py diff --git a/lms/lib/cache_toolbox/middleware.py b/common/djangoapps/cache_toolbox/middleware.py similarity index 100% rename from lms/lib/cache_toolbox/middleware.py rename to common/djangoapps/cache_toolbox/middleware.py diff --git a/lms/lib/cache_toolbox/model.py b/common/djangoapps/cache_toolbox/model.py similarity index 100% rename from lms/lib/cache_toolbox/model.py rename to common/djangoapps/cache_toolbox/model.py diff --git a/lms/lib/cache_toolbox/relation.py b/common/djangoapps/cache_toolbox/relation.py similarity index 100% rename from lms/lib/cache_toolbox/relation.py rename to common/djangoapps/cache_toolbox/relation.py diff --git a/common/djangoapps/cache_toolbox/templatetags/__init__.py b/common/djangoapps/cache_toolbox/templatetags/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/lms/lib/cache_toolbox/templatetags/cache_toolbox.py b/common/djangoapps/cache_toolbox/templatetags/cache_toolbox.py similarity index 100% rename from lms/lib/cache_toolbox/templatetags/cache_toolbox.py rename to common/djangoapps/cache_toolbox/templatetags/cache_toolbox.py diff --git a/common/djangoapps/django_future/__init__.py b/common/djangoapps/django_future/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/lms/lib/django_future/csrf.py b/common/djangoapps/django_future/csrf.py similarity index 100% rename from lms/lib/django_future/csrf.py rename to common/djangoapps/django_future/csrf.py diff --git a/common/djangoapps/monitoring/__init__.py b/common/djangoapps/monitoring/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/common/djangoapps/monitoring/exceptions.py b/common/djangoapps/monitoring/exceptions.py new file mode 100644 index 0000000000000000000000000000000000000000..6a34d9a38f077a9ec999f653a668580ad8ed1499 --- /dev/null +++ b/common/djangoapps/monitoring/exceptions.py @@ -0,0 +1,10 @@ +from django.core.signals import got_request_exception +from django.dispatch import receiver +import logging + + +@receiver(got_request_exception) +def record_request_exception(sender, **kwargs): + logging.exception("Uncaught exception from {sender}".format( + sender=sender + )) diff --git a/common/djangoapps/track/__init__.py b/common/djangoapps/track/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/lms/djangoapps/track/middleware.py b/common/djangoapps/track/middleware.py similarity index 100% rename from lms/djangoapps/track/middleware.py rename to common/djangoapps/track/middleware.py diff --git a/lms/djangoapps/track/models.py b/common/djangoapps/track/models.py similarity index 100% rename from lms/djangoapps/track/models.py rename to common/djangoapps/track/models.py diff --git a/lms/lib/util/tests.py b/common/djangoapps/track/tests.py similarity index 100% rename from lms/lib/util/tests.py rename to common/djangoapps/track/tests.py diff --git a/lms/djangoapps/track/views.py b/common/djangoapps/track/views.py similarity index 100% rename from lms/djangoapps/track/views.py rename to common/djangoapps/track/views.py diff --git a/common/djangoapps/util/__init__.py b/common/djangoapps/util/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/lms/lib/util/cache.py b/common/djangoapps/util/cache.py similarity index 100% rename from lms/lib/util/cache.py rename to common/djangoapps/util/cache.py diff --git a/lms/lib/util/memcache.py b/common/djangoapps/util/memcache.py similarity index 100% rename from lms/lib/util/memcache.py rename to common/djangoapps/util/memcache.py diff --git a/lms/lib/util/middleware.py b/common/djangoapps/util/middleware.py similarity index 100% rename from lms/lib/util/middleware.py rename to common/djangoapps/util/middleware.py diff --git a/lms/lib/util/models.py b/common/djangoapps/util/models.py similarity index 100% rename from lms/lib/util/models.py rename to common/djangoapps/util/models.py diff --git a/common/djangoapps/util/tests.py b/common/djangoapps/util/tests.py new file mode 100644 index 0000000000000000000000000000000000000000..501deb776c16733b19f3509d86e125df78958261 --- /dev/null +++ b/common/djangoapps/util/tests.py @@ -0,0 +1,16 @@ +""" +This file demonstrates writing tests using the unittest module. These will pass +when you run "manage.py test". + +Replace this with more appropriate tests for your application. +""" + +from django.test import TestCase + + +class SimpleTest(TestCase): + def test_basic_addition(self): + """ + Tests that 1 + 1 always equals 2. + """ + self.assertEqual(1 + 1, 2) diff --git a/lms/lib/util/views.py b/common/djangoapps/util/views.py similarity index 100% rename from lms/lib/util/views.py rename to common/djangoapps/util/views.py diff --git a/common/lib/keystore/__init__.py b/common/lib/keystore/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..61c797241d2ca9767d9c36e259b062151fb643e9 --- /dev/null +++ b/common/lib/keystore/__init__.py @@ -0,0 +1,113 @@ +""" +This module provides an abstraction for working objects that conceptually have +the following attributes: + + location: An identifier for an item, of which there might be many revisions + children: A list of urls for other items required to fully define this object + data: A set of nested data needed to define this object + editor: The editor/owner of the object + parents: Url pointers for objects that this object was derived from + revision: What revision of the item this is +""" + + +class Location(object): + ''' Encodes a location. + Can be: + * String (url) + * Tuple + * Dictionary + ''' + def __init__(self, location): + self.update(location) + + def update(self, location): + if isinstance(location, basestring): + self.tag = location.split('/')[0][:-1] + (self.org, self.course, self.category, self.name) = location.split('/')[2:] + elif isinstance(location, list): + (self.tag, self.org, self.course, self.category, self.name) = location + elif isinstance(location, dict): + self.tag = location['tag'] + self.org = location['org'] + self.course = location['course'] + self.category = location['category'] + self.name = location['name'] + elif isinstance(location, Location): + self.update(location.list()) + + def url(self): + return "{tag}://{org}/{course}/{category}/{name}".format(**self.dict()) + + def list(self): + return [self.tag, self.org, self.course, self.category, self.name] + + def dict(self): + return {'tag': self.tag, + 'org': self.org, + 'course': self.course, + 'category': self.category, + 'name': self.name} + + def to_json(self): + return self.dict() + + +class KeyStore(object): + def get_item(self, location): + """ + Returns an XModuleDescriptor instance for the item at location + + If no object is found at that location, raises keystore.exceptions.ItemNotFoundError + + Searches for all matches of a partially specifed location, but raises an + keystore.exceptions.InsufficientSpecificationError if more + than a single object matches the query. + + location: Something that can be passed to Location + """ + raise NotImplementedError + + def create_item(self, location, editor): + """ + Create an empty item at the specified location with the supplied editor + + location: Something that can be passed to Location + """ + raise NotImplementedError + + def update_item(self, location, data): + """ + Set the data in the item specified by the location to + data + + location: Something that can be passed to Location + data: A nested dictionary of problem data + """ + raise NotImplementedError + + def update_children(self, location, children): + """ + Set the children for the item specified by the location to + data + + location: Something that can be passed to Location + children: A list of child item identifiers + """ + raise NotImplementedError + + +class KeyStoreItem(object): + """ + An object from a KeyStore, which can be saved back to that keystore + """ + def __init__(self, location, children, data, editor, parents, revision): + self.location = location + self.children = children + self.data = data + self.editor = editor + self.parents = parents + self.revision = revision + + def save(self): + raise NotImplementedError diff --git a/common/lib/keystore/django.py b/common/lib/keystore/django.py new file mode 100644 index 0000000000000000000000000000000000000000..b88c74b8a3a085ef73418ba53d0c02008207327a --- /dev/null +++ b/common/lib/keystore/django.py @@ -0,0 +1,21 @@ +""" +Module that provides a connection to the keystore specified in the django settings. + +Passes settings.KEYSTORE as kwargs to MongoKeyStore +""" + +from __future__ import absolute_import + +from django.conf import settings +from .mongo import MongoKeyStore + +_KEYSTORE = None + + +def keystore(): + global _KEYSTORE + + if _KEYSTORE is None: + _KEYSTORE = MongoKeyStore(**settings.KEYSTORE) + + return _KEYSTORE diff --git a/common/lib/keystore/exceptions.py b/common/lib/keystore/exceptions.py new file mode 100644 index 0000000000000000000000000000000000000000..08fd9b11d0fe5b63ca07cc832e7208ff00ecef4e --- /dev/null +++ b/common/lib/keystore/exceptions.py @@ -0,0 +1,11 @@ +""" +Exceptions thrown by KeyStore objects +""" + + +class ItemNotFoundError(Exception): + pass + + +class InsufficientSpecificationError(Exception): + pass diff --git a/common/lib/keystore/mongo.py b/common/lib/keystore/mongo.py new file mode 100644 index 0000000000000000000000000000000000000000..d9760909c908d5ec3328fc304254007aeb4cebd2 --- /dev/null +++ b/common/lib/keystore/mongo.py @@ -0,0 +1,86 @@ +import pymongo +from . import KeyStore, Location +from .exceptions import ItemNotFoundError, InsufficientSpecificationError +from xmodule.x_module import XModuleDescriptor + + +class MongoKeyStore(KeyStore): + """ + A Mongodb backed KeyStore + """ + def __init__(self, host, db, collection, port=27017): + self.collection = pymongo.connection.Connection( + host=host, + port=port + )[db][collection] + + # Force mongo to report errors, at the expense of performance + self.collection.safe = True + + def get_item(self, location): + """ + Returns an XModuleDescriptor instance for the item at location + + If no object is found at that location, raises keystore.exceptions.ItemNotFoundError + + Searches for all matches of a partially specifed location, but raises an + keystore.exceptions.InsufficientSpecificationError if more + than a single object matches the query. + + location: Something that can be passed to Location + """ + query = dict( + ('location.{key}'.format(key=key), val) + for (key, val) + in Location(location).dict().items() + if val is not None + ) + items = self.collection.find( + query, + sort=[('revision', pymongo.ASCENDING)], + limit=1, + ) + if items.count() > 1: + raise InsufficientSpecificationError(location) + + if items.count() == 0: + raise ItemNotFoundError(location) + + return XModuleDescriptor.load_from_json(items[0], self.get_item) + + def create_item(self, location, editor): + """ + Create an empty item at the specified location with the supplied editor + + location: Something that can be passed to Location + """ + self.collection.insert({ + 'location': Location(location).dict(), + 'editor': editor + }) + + def update_item(self, location, data): + """ + Set the data in the item specified by the location to + data + + location: Something that can be passed to Location + data: A nested dictionary of problem data + """ + self.collection.update( + {'location': Location(location).dict()}, + {'$set': {'data': data}} + ) + + def update_children(self, location, children): + """ + Set the children for the item specified by the location to + data + + location: Something that can be passed to Location + children: A list of child item identifiers + """ + self.collection.update( + {'location': Location(location).dict()}, + {'$set': {'children': children}} + ) diff --git a/lms/lib/mitxmako/README b/common/lib/mitxmako/README similarity index 100% rename from lms/lib/mitxmako/README rename to common/lib/mitxmako/README diff --git a/lms/lib/mitxmako/__init__.py b/common/lib/mitxmako/__init__.py similarity index 100% rename from lms/lib/mitxmako/__init__.py rename to common/lib/mitxmako/__init__.py diff --git a/lms/lib/mitxmako/middleware.py b/common/lib/mitxmako/middleware.py similarity index 88% rename from lms/lib/mitxmako/middleware.py rename to common/lib/mitxmako/middleware.py index 1d175abbf73e3b2d0af760df3edf1a1a39293438..50f2840a05f0cdf9932de3c59984b5749053861c 100644 --- a/lms/lib/mitxmako/middleware.py +++ b/common/lib/mitxmako/middleware.py @@ -20,10 +20,10 @@ from django.conf import settings requestcontext = None lookup = {} + class MakoMiddleware(object): def __init__(self): """Setup mako variables and lookup object""" - from django.conf import settings # Set all mako variables based on django settings template_locations = settings.MAKO_TEMPLATES module_directory = getattr(settings, 'MAKO_MODULE_DIR', None) @@ -32,17 +32,17 @@ class MakoMiddleware(object): module_directory = tempfile.mkdtemp() for location in template_locations: - lookup[location] = TemplateLookup(directories=template_locations[location], + lookup[location] = TemplateLookup(directories=template_locations[location], module_directory=module_directory, - output_encoding='utf-8', - input_encoding='utf-8', + output_encoding='utf-8', + input_encoding='utf-8', encoding_errors='replace', ) import mitxmako mitxmako.lookup = lookup - def process_request (self, request): + def process_request(self, request): global requestcontext requestcontext = RequestContext(request) requestcontext['is_secure'] = request.is_secure() diff --git a/lms/lib/mitxmako/shortcuts.py b/common/lib/mitxmako/shortcuts.py similarity index 84% rename from lms/lib/mitxmako/shortcuts.py rename to common/lib/mitxmako/shortcuts.py index 7286a4e259d4d46738e509d92b47b89f7a9f541a..9f6044b81ea679d546fc5235b667204c55322b65 100644 --- a/lms/lib/mitxmako/shortcuts.py +++ b/common/lib/mitxmako/shortcuts.py @@ -15,10 +15,9 @@ from django.template import Context from django.http import HttpResponse -import mitxmako.middleware as middleware +from . import middleware from django.conf import settings -import mitxmako.middleware def render_to_string(template_name, dictionary, context=None, namespace='main'): context_instance = Context(dictionary) @@ -28,15 +27,12 @@ def render_to_string(template_name, dictionary, context=None, namespace='main'): context_dictionary = {} context_instance['settings'] = settings context_instance['MITX_ROOT_URL'] = settings.MITX_ROOT_URL - for d in mitxmako.middleware.requestcontext: + for d in middleware.requestcontext: context_dictionary.update(d) for d in context_instance: context_dictionary.update(d) - if context: + if context: context_dictionary.update(context) - ## HACK - ## We should remove this, and possible set COURSE_TITLE in the middleware from the session. - if 'COURSE_TITLE' not in context_dictionary: context_dictionary['COURSE_TITLE'] = '' # fetch and render template template = middleware.lookup[namespace].get_template(template_name) return template.render(**context_dictionary) diff --git a/lms/lib/mitxmako/template.py b/common/lib/mitxmako/template.py similarity index 87% rename from lms/lib/mitxmako/template.py rename to common/lib/mitxmako/template.py index 9e5897ef25e52615301bb59adb1ec9b8e9bf357e..911f5a5b285c3761e121b6f91e9c55b6e5c0ce7f 100644 --- a/lms/lib/mitxmako/template.py +++ b/common/lib/mitxmako/template.py @@ -14,10 +14,11 @@ from mako.template import Template as MakoTemplate -import middleware +from . import middleware + +django_variables = ['lookup', 'template_dirs', 'output_encoding', + 'module_directory', 'encoding_errors'] -django_variables = ['lookup', 'template_dirs', 'output_encoding', - 'module_directory', 'encoding_errors',] class Template(MakoTemplate): def __init__(self, *args, **kwargs): @@ -25,4 +26,4 @@ class Template(MakoTemplate): if not kwargs.get('no_django', False): overrides = dict([(k, getattr(middleware, k, None),) for k in django_variables]) kwargs.update(overrides) - super(Template, self).__init__(*args, **kwargs) + super(Template, self).__init__(*args, **kwargs) diff --git a/common/lib/xmodule/seq_module.py b/common/lib/xmodule/seq_module.py index f643eaab4ad44188a597506c5c675d7b8dbc7631..91ff6d26716542ded55a3cd25d08495a08213b09 100644 --- a/common/lib/xmodule/seq_module.py +++ b/common/lib/xmodule/seq_module.py @@ -95,3 +95,24 @@ class Module(XModule): self.position = int(system.get('position')) self.rendered = False + + +class WeekDescriptor(XModuleDescriptor): + + def get_goals(self): + """ + Return a list of Goal XModuleDescriptors that are children + of this Week + """ + return [child for child in self.get_children() if child.type == 'Goal'] + + def get_non_goals(self): + """ + Return a list of non-Goal XModuleDescriptors that are children of + this Week + """ + return [child for child in self.get_children() if child.type != 'Goal'] + + +class SectionDescriptor(XModuleDescriptor): + pass diff --git a/common/lib/xmodule/setup.py b/common/lib/xmodule/setup.py new file mode 100644 index 0000000000000000000000000000000000000000..114003725980a36f1665ad22d58bcffd0ed760dd --- /dev/null +++ b/common/lib/xmodule/setup.py @@ -0,0 +1,21 @@ +from setuptools import setup, find_packages + +setup( + name="XModule", + version="0.1", + packages=find_packages(), + install_requires=['distribute'], + entry_points={ + 'xmodule.v1': [ + "Course = seq_module:SectionDescriptor", + "Week = seq_module:WeekDescriptor", + "Section = seq_module:SectionDescriptor", + "LectureSequence = seq_module:SectionDescriptor", + "Lab = seq_module:SectionDescriptor", + "Homework = seq_module:SectionDescriptor", + "TutorialIndex = seq_module:SectionDescriptor", + "Exam = seq_module:SectionDescriptor", + "VideoSegment = video_module:VideoSegmentDescriptor", + ] + } +) diff --git a/common/lib/xmodule/video_module.py b/common/lib/xmodule/video_module.py index 8f8a2c2ffde022aa88cb51c26dd6eab970fa0984..d7c7f80291bac0dcf8e504b9bb8d0db06642f60c 100644 --- a/common/lib/xmodule/video_module.py +++ b/common/lib/xmodule/video_module.py @@ -57,3 +57,7 @@ class Module(XModule): self.annotations=[(e.get("name"),self.render_function(e)) \ for e in xmltree] + + +class VideoSegmentDescriptor(XModuleDescriptor): + pass diff --git a/common/lib/xmodule/x_module.py b/common/lib/xmodule/x_module.py index d783694feef3e0e3a26b48779746765bf5b9b948..3560eecbdcd1aaec11f0935b72c066539249dcf9 100644 --- a/common/lib/xmodule/x_module.py +++ b/common/lib/xmodule/x_module.py @@ -1,8 +1,34 @@ from lxml import etree +import pkg_resources +import logging +from keystore import Location + +log = logging.getLogger('mitx.' + __name__) def dummy_track(event_type, event): pass + +class ModuleMissingError(Exception): + pass + + +class Plugin(object): + @classmethod + def load_class(cls, identifier): + classes = list(pkg_resources.iter_entry_points(cls.entry_point, name=identifier)) + if len(classes) > 1: + log.warning("Found multiple classes for {entry_point} with identifier {id}: {classes}. Returning the first one.".format( + entry_point=cls.entry_point, + id=identifier, + classes=", ".join([class_.module_name for class_ in classes]))) + + if len(classes) == 0: + raise ModuleMissingError(identifier) + + return classes[0].load() + + class XModule(object): ''' Implements a generic learning module. Initialized on access with __init__, first time with state=None, and @@ -24,8 +50,8 @@ class XModule(object): or a CAPA input type ''' return ['xmodule'] - def get_name(): - name = self.__xmltree.get(name) + def get_name(self): + name = self.__xmltree.get('name') if name: return name else: @@ -98,15 +124,47 @@ class XModule(object): return "" -class XModuleDescriptor(object): - def __init__(self, xml = None, json = None): - if not xml and not json: - raise "XModuleDescriptor must be initalized with XML or JSON" - if not xml: - raise NotImplementedError("Code does not have support for JSON yet") - - self.xml = xml - self.json = json +class XModuleDescriptor(Plugin): + + entry_point = "xmodule.v1" + + @staticmethod + def load_from_json(json_data, load_item): + class_ = XModuleDescriptor.load_class(json_data['location']['category']) + return class_.from_json(json_data, load_item) + + @classmethod + def from_json(cls, json_data, load_item): + """ + Creates an instance of this descriptor from the supplied json_data. + + json_data: Json data specifying the data, children, and metadata for the descriptor + load_item: A function that takes an i4x url and returns a module descriptor + """ + return cls(load_item=load_item, **json_data) + + def __init__(self, + load_item, + data=None, + children=None, + **kwargs): + self.load_item = load_item + self.data = data if data is not None else {} + self.children = children if children is not None else [] + self.name = Location(kwargs.get('location')).name + self.type = Location(kwargs.get('location')).category + self._child_instances = None + + def get_children(self, categories=None): + """Returns a list of XModuleDescriptor instances for the children of this module""" + if self._child_instances is None: + self._child_instances = [self.load_item(child) for child in self.children] + + if categories is None: + return self._child_instances + else: + return [child for child in self._child_instances if child.type in categories] + def get_xml(self): ''' For conversions between JSON and legacy XML representations. diff --git a/lms/envs/common.py b/lms/envs/common.py index 643ee47de56925f46fab2e7b9df3038075222e03..cc462711307a4d1ae70e81b0dbd6726b0012e15e 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -61,6 +61,7 @@ sys.path.append(ASKBOT_ROOT) sys.path.append(ASKBOT_ROOT / "askbot" / "deps") sys.path.append(PROJECT_ROOT / 'djangoapps') sys.path.append(PROJECT_ROOT / 'lib') +sys.path.append(COMMON_ROOT / 'djangoapps') sys.path.append(COMMON_ROOT / 'lib') ################################## MITXWEB ##################################### diff --git a/lms/envs/dev.py b/lms/envs/dev.py index 17e1e96f45539b5b4bd2d1318d61cfe82c0edd5b..decd92d136d370ab92c404c2d5aec3343584d40c 100644 --- a/lms/envs/dev.py +++ b/lms/envs/dev.py @@ -44,7 +44,7 @@ CACHES = { 'BACKEND': 'django.core.cache.backends.dummy.DummyCache', 'KEY_PREFIX': 'general', 'VERSION': 4, - 'KEY_FUNCTION': 'util.cache.memcache_safe_key', + 'KEY_FUNCTION': 'util.memcache.safe_key', } } diff --git a/rakefile b/rakefile index 29446f4287f3748dd12520f8722517939f859e0b..a3d742cef1ce9c91a8c246c2ca06bb60666d5c4a 100644 --- a/rakefile +++ b/rakefile @@ -58,7 +58,7 @@ task :pylint => REPORT_DIR do end end -[:lms].each do |system| +[:lms, :cms].each do |system| task_name = "test_#{system}" report_dir = File.join(REPORT_DIR, task_name) directory report_dir @@ -67,9 +67,18 @@ end task task_name => report_dir do ENV['NOSE_XUNIT_FILE'] = File.join(report_dir, "nosetests.xml") ENV['NOSE_COVER_HTML_DIR'] = File.join(report_dir, "cover") - sh(django_admin(:lms, :test, 'test', *Dir['lms/djangoapps'].each)) + sh(django_admin(system, :test, 'test', *Dir["#{system}/djangoapps/*"].each)) end task :test => task_name + + desc <<-desc + Start the #{system} locally with the specified environment (defaults to dev). + Other useful environments are devplus (for dev testing with a real local database) + desc + task system, [:env, :options] => [] do |t, args| + args.with_defaults(:env => 'dev', :options => '') + sh(django_admin(system, args.env, 'runserver', args.options)) + end end Dir["common/lib/*"].each do |lib| @@ -86,15 +95,6 @@ Dir["common/lib/*"].each do |lib| task :test => task_name end -desc <<-desc - Start the lms locally with the specified environment (defaults to dev). - Other useful environments are devplus (for dev testing with a real local database) - desc -task :lms, [:env] => [] do |t, args| - args.with_defaults(:env => 'dev') - sh(django_admin(:lms, args.env, 'runserver')) -end - task :runserver => :lms desc "Run django-admin <action> against the specified system and environment" diff --git a/requirements.txt b/requirements.txt index a62baad94b9ac3fdb15e47d8b9ae68009f124259..55e4dd665e804eff421f20b599255aa7094b638c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -23,6 +23,8 @@ requests sympy newrelic glob2 +pymongo +-e common/lib/xmodule django_nose nosexcover rednose