From 05436e591b71c34676d4bb5a143955cb7c1cf747 Mon Sep 17 00:00:00 2001 From: Calen Pennington Date: Fri, 8 Jun 2012 11:27:22 -0400 Subject: [PATCH 01/21] Make mitxmako available to both the lms and the cms --- {lms => common}/lib/mitxmako/README | 0 {lms => common}/lib/mitxmako/__init__.py | 0 {lms => common}/lib/mitxmako/middleware.py | 10 +++++----- {lms => common}/lib/mitxmako/shortcuts.py | 10 +++------- {lms => common}/lib/mitxmako/template.py | 9 +++++---- 5 files changed, 13 insertions(+), 16 deletions(-) rename {lms => common}/lib/mitxmako/README (100%) rename {lms => common}/lib/mitxmako/__init__.py (100%) rename {lms => common}/lib/mitxmako/middleware.py (88%) rename {lms => common}/lib/mitxmako/shortcuts.py (84%) rename {lms => common}/lib/mitxmako/template.py (87%) 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 1d175abbf7..50f2840a05 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 7286a4e259..9f6044b81e 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 9e5897ef25..911f5a5b28 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) From 8134bcbc3df80595b9fcdfa11991772148ca1922 Mon Sep 17 00:00:00 2001 From: Calen Pennington Date: Fri, 8 Jun 2012 14:01:41 -0400 Subject: [PATCH 02/21] Get the cms up to the point of rendering a template --- {lms/djangoapps/track => cms}/__init__.py | 0 .../templatetags => cms/envs}/__init__.py | 0 cms/envs/common.py | 151 ++++++++++++++++++ cms/envs/dev.py | 37 +++++ cms/manage.py | 14 ++ lms/lib/util/__init__.py => cms/models.py | 0 cms/templates/calendar.html | 3 + cms/urls.py | 9 ++ cms/views.py | 5 + common/djangoapps/track/__init__.py | 0 .../djangoapps/track/middleware.py | 0 {lms => common}/djangoapps/track/models.py | 0 {lms => common}/djangoapps/track/tests.py | 0 {lms => common}/djangoapps/track/views.py | 0 {lms => common}/lib/cache_toolbox/COPYING | 0 {lms => common}/lib/cache_toolbox/README.rst | 0 {lms => common}/lib/cache_toolbox/__init__.py | 0 .../lib/cache_toolbox/app_settings.py | 0 {lms => common}/lib/cache_toolbox/core.py | 0 .../lib/cache_toolbox/middleware.py | 0 {lms => common}/lib/cache_toolbox/model.py | 0 {lms => common}/lib/cache_toolbox/relation.py | 0 .../cache_toolbox/templatetags/__init__.py | 0 .../templatetags/cache_toolbox.py | 0 common/lib/monitoring/__init__.py | 0 common/lib/monitoring/exceptions.py | 10 ++ common/lib/util/__init__.py | 0 {lms => common}/lib/util/cache.py | 0 {lms => common}/lib/util/memcache.py | 0 {lms => common}/lib/util/middleware.py | 0 {lms => common}/lib/util/models.py | 0 {lms => common}/lib/util/tests.py | 0 {lms => common}/lib/util/views.py | 0 lms/envs/common.py | 1 + rakefile | 20 +-- 35 files changed, 240 insertions(+), 10 deletions(-) rename {lms/djangoapps/track => cms}/__init__.py (100%) rename {lms/lib/cache_toolbox/templatetags => cms/envs}/__init__.py (100%) create mode 100644 cms/envs/common.py create mode 100644 cms/envs/dev.py create mode 100644 cms/manage.py rename lms/lib/util/__init__.py => cms/models.py (100%) create mode 100644 cms/templates/calendar.html create mode 100644 cms/urls.py create mode 100644 cms/views.py create mode 100644 common/djangoapps/track/__init__.py rename {lms => common}/djangoapps/track/middleware.py (100%) rename {lms => common}/djangoapps/track/models.py (100%) rename {lms => common}/djangoapps/track/tests.py (100%) rename {lms => common}/djangoapps/track/views.py (100%) rename {lms => common}/lib/cache_toolbox/COPYING (100%) rename {lms => common}/lib/cache_toolbox/README.rst (100%) rename {lms => common}/lib/cache_toolbox/__init__.py (100%) rename {lms => common}/lib/cache_toolbox/app_settings.py (100%) rename {lms => common}/lib/cache_toolbox/core.py (100%) rename {lms => common}/lib/cache_toolbox/middleware.py (100%) rename {lms => common}/lib/cache_toolbox/model.py (100%) rename {lms => common}/lib/cache_toolbox/relation.py (100%) create mode 100644 common/lib/cache_toolbox/templatetags/__init__.py rename {lms => common}/lib/cache_toolbox/templatetags/cache_toolbox.py (100%) create mode 100644 common/lib/monitoring/__init__.py create mode 100644 common/lib/monitoring/exceptions.py create mode 100644 common/lib/util/__init__.py rename {lms => common}/lib/util/cache.py (100%) rename {lms => common}/lib/util/memcache.py (100%) rename {lms => common}/lib/util/middleware.py (100%) rename {lms => common}/lib/util/models.py (100%) rename {lms => common}/lib/util/tests.py (100%) rename {lms => common}/lib/util/views.py (100%) 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/envs/__init__.py similarity index 100% rename from lms/lib/cache_toolbox/templatetags/__init__.py rename to cms/envs/__init__.py diff --git a/cms/envs/common.py b/cms/envs/common.py new file mode 100644 index 0000000000..9b349a06d0 --- /dev/null +++ b/cms/envs/common.py @@ -0,0 +1,151 @@ +""" +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', + # Uncomment the next line to enable the admin: + # 'django.contrib.admin', + # Uncomment the next line to enable admin documentation: + # 'django.contrib.admindocs', +) diff --git a/cms/envs/dev.py b/cms/envs/dev.py new file mode 100644 index 0000000000..72a5e512c4 --- /dev/null +++ b/cms/envs/dev.py @@ -0,0 +1,37 @@ +""" +This config file runs the simplest dev environment""" + +from .common import * + +DEBUG = True +TEMPLATE_DEBUG = DEBUG + +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.cache.memcache_safe_key', + } +} diff --git a/cms/manage.py b/cms/manage.py new file mode 100644 index 0000000000..3e4eedc9ff --- /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/lms/lib/util/__init__.py b/cms/models.py similarity index 100% rename from lms/lib/util/__init__.py rename to cms/models.py diff --git a/cms/templates/calendar.html b/cms/templates/calendar.html new file mode 100644 index 0000000000..05b2f88806 --- /dev/null +++ b/cms/templates/calendar.html @@ -0,0 +1,3 @@ +% for week in weeks: +${week} +% endfor diff --git a/cms/urls.py b/cms/urls.py new file mode 100644 index 0000000000..80e2b19e9d --- /dev/null +++ b/cms/urls.py @@ -0,0 +1,9 @@ +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('cms.views', + url(r'^(?P[^/]+)/calendar/', 'calendar', name='calendar'), +) diff --git a/cms/views.py b/cms/views.py new file mode 100644 index 0000000000..d0d4f4871c --- /dev/null +++ b/cms/views.py @@ -0,0 +1,5 @@ +from mitxmako.shortcuts import render_to_response + + +def calendar(request, course): + return render_to_response('calendar.html', {}) diff --git a/common/djangoapps/track/__init__.py b/common/djangoapps/track/__init__.py new file mode 100644 index 0000000000..e69de29bb2 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/djangoapps/track/tests.py b/common/djangoapps/track/tests.py similarity index 100% rename from lms/djangoapps/track/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/lms/lib/cache_toolbox/COPYING b/common/lib/cache_toolbox/COPYING similarity index 100% rename from lms/lib/cache_toolbox/COPYING rename to common/lib/cache_toolbox/COPYING diff --git a/lms/lib/cache_toolbox/README.rst b/common/lib/cache_toolbox/README.rst similarity index 100% rename from lms/lib/cache_toolbox/README.rst rename to common/lib/cache_toolbox/README.rst diff --git a/lms/lib/cache_toolbox/__init__.py b/common/lib/cache_toolbox/__init__.py similarity index 100% rename from lms/lib/cache_toolbox/__init__.py rename to common/lib/cache_toolbox/__init__.py diff --git a/lms/lib/cache_toolbox/app_settings.py b/common/lib/cache_toolbox/app_settings.py similarity index 100% rename from lms/lib/cache_toolbox/app_settings.py rename to common/lib/cache_toolbox/app_settings.py diff --git a/lms/lib/cache_toolbox/core.py b/common/lib/cache_toolbox/core.py similarity index 100% rename from lms/lib/cache_toolbox/core.py rename to common/lib/cache_toolbox/core.py diff --git a/lms/lib/cache_toolbox/middleware.py b/common/lib/cache_toolbox/middleware.py similarity index 100% rename from lms/lib/cache_toolbox/middleware.py rename to common/lib/cache_toolbox/middleware.py diff --git a/lms/lib/cache_toolbox/model.py b/common/lib/cache_toolbox/model.py similarity index 100% rename from lms/lib/cache_toolbox/model.py rename to common/lib/cache_toolbox/model.py diff --git a/lms/lib/cache_toolbox/relation.py b/common/lib/cache_toolbox/relation.py similarity index 100% rename from lms/lib/cache_toolbox/relation.py rename to common/lib/cache_toolbox/relation.py diff --git a/common/lib/cache_toolbox/templatetags/__init__.py b/common/lib/cache_toolbox/templatetags/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/lms/lib/cache_toolbox/templatetags/cache_toolbox.py b/common/lib/cache_toolbox/templatetags/cache_toolbox.py similarity index 100% rename from lms/lib/cache_toolbox/templatetags/cache_toolbox.py rename to common/lib/cache_toolbox/templatetags/cache_toolbox.py diff --git a/common/lib/monitoring/__init__.py b/common/lib/monitoring/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/common/lib/monitoring/exceptions.py b/common/lib/monitoring/exceptions.py new file mode 100644 index 0000000000..6a34d9a38f --- /dev/null +++ b/common/lib/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/lib/util/__init__.py b/common/lib/util/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/lms/lib/util/cache.py b/common/lib/util/cache.py similarity index 100% rename from lms/lib/util/cache.py rename to common/lib/util/cache.py diff --git a/lms/lib/util/memcache.py b/common/lib/util/memcache.py similarity index 100% rename from lms/lib/util/memcache.py rename to common/lib/util/memcache.py diff --git a/lms/lib/util/middleware.py b/common/lib/util/middleware.py similarity index 100% rename from lms/lib/util/middleware.py rename to common/lib/util/middleware.py diff --git a/lms/lib/util/models.py b/common/lib/util/models.py similarity index 100% rename from lms/lib/util/models.py rename to common/lib/util/models.py diff --git a/lms/lib/util/tests.py b/common/lib/util/tests.py similarity index 100% rename from lms/lib/util/tests.py rename to common/lib/util/tests.py diff --git a/lms/lib/util/views.py b/common/lib/util/views.py similarity index 100% rename from lms/lib/util/views.py rename to common/lib/util/views.py diff --git a/lms/envs/common.py b/lms/envs/common.py index 806c379747..3ac026fd81 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -60,6 +60,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/rakefile b/rakefile index 8f49668506..6bd582783e 100644 --- a/rakefile +++ b/rakefile @@ -58,7 +58,7 @@ task :pylint => LMS_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 @@ -69,6 +69,15 @@ end sh(django_admin(:lms, :test, 'test', *Dir['lms/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| @@ -85,15 +94,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 against the specified system and environment" From dc85e46315dfb30ed9a3ead1df2c4e38411b7e6f Mon Sep 17 00:00:00 2001 From: Calen Pennington Date: Fri, 8 Jun 2012 16:55:38 -0400 Subject: [PATCH 03/21] Allow login in the cms, and read a particular course from mongo --- .../djangoapps/instructor}/__init__.py | 0 cms/djangoapps/instructor/models.py | 61 ++++++++++++++ cms/djangoapps/instructor/tests.py | 16 ++++ cms/djangoapps/instructor/views.py | 49 ++++++++++++ cms/envs/dev.py | 6 ++ cms/lib/keystore/__init__.py | 80 +++++++++++++++++++ cms/lib/keystore/django.py | 12 +++ cms/lib/keystore/exceptions.py | 7 ++ cms/lib/keystore/mongo.py | 26 ++++++ cms/templates/login.html | 11 +++ cms/urls.py | 5 +- cms/views.py | 11 ++- common/lib/django_future/__init__.py | 0 {lms => common}/lib/django_future/csrf.py | 0 requirements.txt | 1 + 15 files changed, 281 insertions(+), 4 deletions(-) rename {lms/lib/django_future => cms/djangoapps/instructor}/__init__.py (100%) create mode 100644 cms/djangoapps/instructor/models.py create mode 100644 cms/djangoapps/instructor/tests.py create mode 100644 cms/djangoapps/instructor/views.py create mode 100644 cms/lib/keystore/__init__.py create mode 100644 cms/lib/keystore/django.py create mode 100644 cms/lib/keystore/exceptions.py create mode 100644 cms/lib/keystore/mongo.py create mode 100644 cms/templates/login.html create mode 100644 common/lib/django_future/__init__.py rename {lms => common}/lib/django_future/csrf.py (100%) diff --git a/lms/lib/django_future/__init__.py b/cms/djangoapps/instructor/__init__.py similarity index 100% rename from lms/lib/django_future/__init__.py rename to cms/djangoapps/instructor/__init__.py diff --git a/cms/djangoapps/instructor/models.py b/cms/djangoapps/instructor/models.py new file mode 100644 index 0000000000..906aeee2f1 --- /dev/null +++ b/cms/djangoapps/instructor/models.py @@ -0,0 +1,61 @@ +""" +WE'RE USING MIGRATIONS! + +If you make changes to this model, be sure to create an appropriate migration +file and check it in at the same time as your model changes. To do that, + +1. Go to the mitx dir +2. ./manage.py schemamigration user --auto description_of_your_change +3. Add the migration file created in mitx/courseware/migrations/ +""" +import uuid + +from django.db import models +from django.contrib.auth.models import User + + +class UserProfile(models.Model): + class Meta: + db_table = "auth_userprofile" + + ## CRITICAL TODO/SECURITY + # Sanitize all fields. + # This is not visible to other users, but could introduce holes later + user = models.OneToOneField(User, unique=True, db_index=True, related_name='profile') + name = models.CharField(blank=True, max_length=255, db_index=True) + org = models.CharField(blank=True, max_length=255, db_index=True) + + +class Registration(models.Model): + ''' Allows us to wait for e-mail before user is registered. A + registration profile is created when the user creates an + account, but that account is inactive. Once the user clicks + on the activation key, it becomes active. ''' + class Meta: + db_table = "auth_registration" + + user = models.ForeignKey(User, unique=True) + activation_key = models.CharField(('activation key'), max_length=32, unique=True, db_index=True) + + def register(self, user): + # MINOR TODO: Switch to crypto-secure key + self.activation_key = uuid.uuid4().hex + self.user = user + self.save() + + def activate(self): + self.user.is_active = True + self.user.save() + #self.delete() + + +class PendingNameChange(models.Model): + user = models.OneToOneField(User, unique=True, db_index=True) + new_name = models.CharField(blank=True, max_length=255) + rationale = models.CharField(blank=True, max_length=1024) + + +class PendingEmailChange(models.Model): + user = models.OneToOneField(User, unique=True, db_index=True) + new_email = models.CharField(blank=True, max_length=255, db_index=True) + activation_key = models.CharField(('activation key'), max_length=32, unique=True, db_index=True) diff --git a/cms/djangoapps/instructor/tests.py b/cms/djangoapps/instructor/tests.py new file mode 100644 index 0000000000..501deb776c --- /dev/null +++ b/cms/djangoapps/instructor/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/cms/djangoapps/instructor/views.py b/cms/djangoapps/instructor/views.py new file mode 100644 index 0000000000..fbb341b468 --- /dev/null +++ b/cms/djangoapps/instructor/views.py @@ -0,0 +1,49 @@ +import logging + +from django.views.decorators.http import require_http_methods, require_POST, require_GET +from django.contrib.auth import logout, authenticate, login +from django.shortcuts import redirect +from mitxmako.shortcuts import render_to_response + +from django_future.csrf import ensure_csrf_cookie + +log = logging.getLogger("mitx.student") + + +@require_http_methods(['GET', 'POST']) +def do_login(request): + if request.method == 'POST': + return post_login(request) + elif request.method == 'GET': + return get_login(request) + + +@require_POST +@ensure_csrf_cookie +def post_login(request): + username = request.POST['username'] + password = request.POST['password'] + user = authenticate(username=username, password=password) + if user is not None: + if user.is_active: + login(request, user) + return redirect(request.POST.get('next', '/')) + else: + raise Exception("Can't log in, account disabled") + else: + raise Exception("Can't log in, invalid authentication") + + +@require_GET +@ensure_csrf_cookie +def get_login(request): + return render_to_response('login.html', { + 'next': request.GET.get('next') + }) + + +@ensure_csrf_cookie +def logout_user(request): + ''' HTTP request to log in the user. Redirects to marketing page''' + logout(request) + return redirect('/') diff --git a/cms/envs/dev.py b/cms/envs/dev.py index 72a5e512c4..f7277b3d3f 100644 --- a/cms/envs/dev.py +++ b/cms/envs/dev.py @@ -6,6 +6,12 @@ from .common import * DEBUG = True TEMPLATE_DEBUG = DEBUG +KEYSTORE = { + 'host': 'localhost', + 'db': 'mongo_base', + 'collection': 'key_store', +} + DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', diff --git a/cms/lib/keystore/__init__.py b/cms/lib/keystore/__init__.py new file mode 100644 index 0000000000..5e6374cf4a --- /dev/null +++ b/cms/lib/keystore/__init__.py @@ -0,0 +1,80 @@ +""" +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 "i4x://{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_children_for_item(self, location): + """ + Returns the children for the most recent revision of the object + with the specified location. + + If no object is found at that location, raises keystore.exceptions.ItemNotFoundError + """ + 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/cms/lib/keystore/django.py b/cms/lib/keystore/django.py new file mode 100644 index 0000000000..b6ffb83b5c --- /dev/null +++ b/cms/lib/keystore/django.py @@ -0,0 +1,12 @@ +""" +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 = MongoKeyStore(**settings.KEYSTORE) diff --git a/cms/lib/keystore/exceptions.py b/cms/lib/keystore/exceptions.py new file mode 100644 index 0000000000..b66470859f --- /dev/null +++ b/cms/lib/keystore/exceptions.py @@ -0,0 +1,7 @@ +""" +Exceptions thrown by KeyStore objects +""" + + +class ItemNotFoundError(Exception): + pass diff --git a/cms/lib/keystore/mongo.py b/cms/lib/keystore/mongo.py new file mode 100644 index 0000000000..fc190ee098 --- /dev/null +++ b/cms/lib/keystore/mongo.py @@ -0,0 +1,26 @@ +import pymongo +from . import KeyStore +from .exceptions import ItemNotFoundError + + +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] + + def get_children_for_item(self, location): + item = self.collection.find_one( + {'location': location.dict()}, + fields={'children': True}, + sort=[('revision', pymongo.ASCENDING)], + ) + + if item is None: + raise ItemNotFoundError() + + return item['children'] diff --git a/cms/templates/login.html b/cms/templates/login.html new file mode 100644 index 0000000000..03ea5f967c --- /dev/null +++ b/cms/templates/login.html @@ -0,0 +1,11 @@ +
+ + + % if next is not None: + + % endif + + Username: + Possword: + +
diff --git a/cms/urls.py b/cms/urls.py index 80e2b19e9d..55d7a1086e 100644 --- a/cms/urls.py +++ b/cms/urls.py @@ -4,6 +4,7 @@ from django.conf.urls.defaults import patterns, url # from django.contrib import admin # admin.autodiscover() -urlpatterns = patterns('cms.views', - url(r'^(?P[^/]+)/calendar/', 'calendar', name='calendar'), +urlpatterns = patterns('', + url(r'^(?P[^/]+)/(?P[^/]+)/calendar/', 'cms.views.calendar', name='calendar'), + url(r'^accounts/login/', 'instructor.views.do_login', name='login'), ) diff --git a/cms/views.py b/cms/views.py index d0d4f4871c..c6786b03c4 100644 --- a/cms/views.py +++ b/cms/views.py @@ -1,5 +1,12 @@ from mitxmako.shortcuts import render_to_response +from keystore import Location +from keystore.django import keystore +from django.contrib.auth.decorators import login_required -def calendar(request, course): - return render_to_response('calendar.html', {}) +@login_required +def calendar(request, org, course): + weeks = keystore.get_children_for_item( + Location(['i4x', org, course, 'Course', 'course']) + ) + return render_to_response('calendar.html', {'weeks': weeks}) diff --git a/common/lib/django_future/__init__.py b/common/lib/django_future/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/lms/lib/django_future/csrf.py b/common/lib/django_future/csrf.py similarity index 100% rename from lms/lib/django_future/csrf.py rename to common/lib/django_future/csrf.py diff --git a/requirements.txt b/requirements.txt index 82b28b09cf..5e95e1bf9e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -23,3 +23,4 @@ requests sympy newrelic glob2 +pymongo From b9befbafcd562a037c09140aa2b48cf1f1f18e71 Mon Sep 17 00:00:00 2001 From: Calen Pennington Date: Wed, 13 Jun 2012 11:42:50 -0400 Subject: [PATCH 04/21] Add contentstore from cms proto as a baseline for importing and views for the cms --- cms/djangoapps/contentstore/__init__.py | 0 .../contentstore/management/__init__.py | 0 .../management/commands/__init__.py | 0 .../management/commands/ftpserve.py | 61 +++++++ .../management/commands/import.py | 158 ++++++++++++++++++ cms/djangoapps/contentstore/tests.py | 16 ++ cms/{ => djangoapps/contentstore}/views.py | 0 cms/envs/common.py | 6 +- cms/urls.py | 2 +- 9 files changed, 238 insertions(+), 5 deletions(-) create mode 100644 cms/djangoapps/contentstore/__init__.py create mode 100644 cms/djangoapps/contentstore/management/__init__.py create mode 100644 cms/djangoapps/contentstore/management/commands/__init__.py create mode 100644 cms/djangoapps/contentstore/management/commands/ftpserve.py create mode 100644 cms/djangoapps/contentstore/management/commands/import.py create mode 100644 cms/djangoapps/contentstore/tests.py rename cms/{ => djangoapps/contentstore}/views.py (100%) diff --git a/cms/djangoapps/contentstore/__init__.py b/cms/djangoapps/contentstore/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cms/djangoapps/contentstore/management/__init__.py b/cms/djangoapps/contentstore/management/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cms/djangoapps/contentstore/management/commands/__init__.py b/cms/djangoapps/contentstore/management/commands/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cms/djangoapps/contentstore/management/commands/ftpserve.py b/cms/djangoapps/contentstore/management/commands/ftpserve.py new file mode 100644 index 0000000000..f0a1c19dbf --- /dev/null +++ b/cms/djangoapps/contentstore/management/commands/ftpserve.py @@ -0,0 +1,61 @@ +from django.core.management.base import BaseCommand +from django.contrib.auth.models import User +import contentstore.tasks + +from pyftpdlib import ftpserver +import os + +class DjangoAuthorizer(object): + def validate_authentication(self, username, password): + try: + u=User.objects.get(username=username) + except User.DoesNotExist: + return False + # TODO: Check security groups + return u.check_password(password) + def has_user(self, username): + print "????",username + return True + def has_perm(self, username, perm, path=None): + print "!!!!!",username, perm, path + return True + def get_home_dir(self, username): + d = "/tmp/ftp/"+username + try: + os.mkdir(d) + except OSError: + pass + return "/tmp/ftp/"+username + def get_perms(self, username): + return 'elradfmw' + def get_msg_login(self, username): + return 'Hello' + def get_msg_quit(self, username): + return 'Goodbye' + def __init__(self): + pass + def impersonate_user(self, username, password): + pass + def terminate_impersonation(self, username): + pass + +def on_upload(ftp_handler, filename): + source = ftp_handler.remote_ip + author = ftp_handler.username + print filename, author, source + # We pass on this for now: + # contentstore.tasks.on_upload + # It is a changing API, and it makes testing the FTP server slow. + +class Command(BaseCommand): + help = \ +''' Run FTP server.''' + def handle(self, *args, **options): + authorizer = DjangoAuthorizer() #ftpserver.DummyAuthorizer() + handler = ftpserver.FTPHandler + handler.on_file_received = on_upload + + handler.authorizer = authorizer + address = ("127.0.0.1", 2121) + ftpd = ftpserver.FTPServer(address, handler) + ftpd.serve_forever() diff --git a/cms/djangoapps/contentstore/management/commands/import.py b/cms/djangoapps/contentstore/management/commands/import.py new file mode 100644 index 0000000000..78984f4119 --- /dev/null +++ b/cms/djangoapps/contentstore/management/commands/import.py @@ -0,0 +1,158 @@ +### +### One-off script for importing courseware form XML format +### + + +#import mitxmako.middleware +#from courseware import content_parser +#from django.contrib.auth.models import User +from mako.template import Template +from mako.lookup import TemplateLookup + +from django.core.management.base import BaseCommand +from contentstore.models import create_item, update_item, update_children + +from lxml import etree + +class Command(BaseCommand): + help = \ +''' Run FTP server.''' + def handle(self, *args, **options): + print args + data_dir = args[0] + course_file = 'course.xml' + + parser = etree.XMLParser(remove_comments = True) + + lookup = TemplateLookup(directories=[data_dir]) + template = lookup.get_template("course.xml") + course_string = template.render(groups=[]) + course = etree.XML(course_string, parser=parser) + + elements = course.xpath("//*") + + tag_to_category = {# Inside HTML ==> Skip these + # Custom tags + 'videodev': 'Custom', + 'slides': 'Custom', + 'book': 'Custom', + 'image': 'Custom', + 'discuss': 'Custom', + # Simple lists + 'chapter': 'Sequence', + 'course': 'Sequence', + 'sequential': 'Sequence', + 'vertical': 'Sequence', + 'section': 'Sequence', + # 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] + 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 = [{'url':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(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: + print k + create_item(k, 'Piotr Mitros') + if 'data' in results[k]: + update_item(k, results[k]['data']) + if 'children' in results[k]: + update_children(k, results[k]['children']) + + diff --git a/cms/djangoapps/contentstore/tests.py b/cms/djangoapps/contentstore/tests.py new file mode 100644 index 0000000000..501deb776c --- /dev/null +++ b/cms/djangoapps/contentstore/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/cms/views.py b/cms/djangoapps/contentstore/views.py similarity index 100% rename from cms/views.py rename to cms/djangoapps/contentstore/views.py diff --git a/cms/envs/common.py b/cms/envs/common.py index 9b349a06d0..8d402b6fa9 100644 --- a/cms/envs/common.py +++ b/cms/envs/common.py @@ -144,8 +144,6 @@ INSTALLED_APPS = ( 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.staticfiles', - # Uncomment the next line to enable the admin: - # 'django.contrib.admin', - # Uncomment the next line to enable admin documentation: - # 'django.contrib.admindocs', + 'contentstore', + 'instructor', ) diff --git a/cms/urls.py b/cms/urls.py index 55d7a1086e..a7266066cc 100644 --- a/cms/urls.py +++ b/cms/urls.py @@ -5,6 +5,6 @@ from django.conf.urls.defaults import patterns, url # admin.autodiscover() urlpatterns = patterns('', - url(r'^(?P[^/]+)/(?P[^/]+)/calendar/', 'cms.views.calendar', name='calendar'), + url(r'^(?P[^/]+)/(?P[^/]+)/calendar/', 'contentstore.views.calendar', name='calendar'), url(r'^accounts/login/', 'instructor.views.do_login', name='login'), ) From a333612cce7b9e285dfdc1fc38abf552bb320781 Mon Sep 17 00:00:00 2001 From: Calen Pennington Date: Wed, 13 Jun 2012 11:54:17 -0400 Subject: [PATCH 05/21] Add templates directly from cms_proto/ui_prototype --- cms/djangoapps/contentstore/views.py | 4 + cms/static/css/base-style.css | 589 +++++++++++++++++ cms/static/css/ie.css | 196 ++++++ cms/static/css/style.css | 0 cms/static/img/indicator.gif | Bin 0 -> 1553 bytes cms/static/img/video.jpg | Bin 0 -> 7217 bytes cms/static/js/jquery.inlineedit.js | 251 ++++++++ cms/static/js/jquery.leanModal.min.js | 5 + cms/static/js/jquery.tablednd.js | 257 ++++++++ cms/static/js/main.js | 159 +++++ cms/static/js/markitup/jquery.markitup.js | 593 ++++++++++++++++++ .../js/markitup/sets/wiki/images/bold.png | Bin 0 -> 304 bytes .../js/markitup/sets/wiki/images/clean.png | Bin 0 -> 667 bytes .../js/markitup/sets/wiki/images/code.png | Bin 0 -> 859 bytes .../js/markitup/sets/wiki/images/h1.png | Bin 0 -> 276 bytes .../js/markitup/sets/wiki/images/h2.png | Bin 0 -> 304 bytes .../js/markitup/sets/wiki/images/h3.png | Bin 0 -> 306 bytes .../js/markitup/sets/wiki/images/h4.png | Bin 0 -> 293 bytes .../js/markitup/sets/wiki/images/h5.png | Bin 0 -> 304 bytes .../js/markitup/sets/wiki/images/image.png | Bin 0 -> 516 bytes .../js/markitup/sets/wiki/images/italic.png | Bin 0 -> 223 bytes .../js/markitup/sets/wiki/images/link.png | Bin 0 -> 343 bytes .../markitup/sets/wiki/images/list-bullet.png | Bin 0 -> 344 bytes .../sets/wiki/images/list-numeric.png | Bin 0 -> 357 bytes .../js/markitup/sets/wiki/images/picture.png | Bin 0 -> 606 bytes .../js/markitup/sets/wiki/images/preview.png | Bin 0 -> 537 bytes .../js/markitup/sets/wiki/images/quotes.png | Bin 0 -> 743 bytes .../js/markitup/sets/wiki/images/stroke.png | Bin 0 -> 269 bytes .../js/markitup/sets/wiki/images/url.png | Bin 0 -> 957 bytes cms/static/js/markitup/sets/wiki/set.js | 34 + cms/static/js/markitup/sets/wiki/style.css | 57 ++ .../markitup/skins/simple/images/handle.png | Bin 0 -> 258 bytes .../js/markitup/skins/simple/images/menu.png | Bin 0 -> 27151 bytes .../markitup/skins/simple/images/submenu.png | Bin 0 -> 240 bytes cms/static/js/markitup/skins/simple/style.css | 118 ++++ cms/static/sass/_base.scss | 51 ++ cms/static/sass/_calendar.scss | 206 ++++++ cms/static/sass/_problem.scss | 41 ++ cms/static/sass/_reset.scss | 229 +++++++ cms/static/sass/_video.scss | 40 ++ cms/static/sass/_week.scss | 152 +++++ cms/static/sass/base-style.scss | 18 + cms/static/sass/bourbon/_bourbon.scss | 35 ++ cms/static/sass/bourbon/addons/_button.scss | 267 ++++++++ cms/static/sass/bourbon/addons/_clearfix.scss | 29 + .../sass/bourbon/addons/_font-family.scss | 5 + .../bourbon/addons/_html5-input-types.scss | 36 ++ cms/static/sass/bourbon/addons/_position.scss | 30 + .../bourbon/addons/_timing-functions.scss | 32 + cms/static/sass/bourbon/css3/_animation.scss | 171 +++++ cms/static/sass/bourbon/css3/_appearance.scss | 7 + .../sass/bourbon/css3/_background-image.scss | 57 ++ .../sass/bourbon/css3/_background-size.scss | 15 + .../sass/bourbon/css3/_border-image.scss | 56 ++ .../sass/bourbon/css3/_border-radius.scss | 63 ++ cms/static/sass/bourbon/css3/_box-shadow.scss | 14 + cms/static/sass/bourbon/css3/_box-sizing.scss | 6 + cms/static/sass/bourbon/css3/_columns.scss | 67 ++ cms/static/sass/bourbon/css3/_flex-box.scss | 67 ++ .../sass/bourbon/css3/_inline-block.scss | 10 + .../sass/bourbon/css3/_linear-gradient.scss | 41 ++ .../sass/bourbon/css3/_radial-gradient.scss | 31 + cms/static/sass/bourbon/css3/_transform.scss | 19 + cms/static/sass/bourbon/css3/_transition.scss | 104 +++ .../sass/bourbon/css3/_user-select.scss | 6 + .../_deprecated-webkit-gradient.scss | 36 ++ .../sass/bourbon/functions/_flex-grid.scss | 35 ++ .../sass/bourbon/functions/_grid-width.scss | 13 + .../bourbon/functions/_linear-gradient.scss | 23 + .../bourbon/functions/_modular-scale.scss | 40 ++ .../bourbon/functions/_radial-gradient.scss | 15 + .../bourbon/functions/_render-gradients.scss | 14 + .../sass/bourbon/functions/_tint-shade.scss | 9 + cms/static/sass/bourbon/lib/bourbon.rb | 19 + .../bourbon/lib/bourbon/sass_extensions.rb | 6 + .../lib/bourbon/sass_extensions/functions.rb | 13 + .../sass_extensions/functions/compact.rb | 13 + cms/templates/base.html | 30 + cms/templates/index.html | 19 + cms/templates/widgets/captions.html | 242 +++++++ cms/templates/widgets/header.html | 5 + cms/templates/widgets/navigation.html | 120 ++++ cms/templates/widgets/new-module.html | 9 + cms/templates/widgets/problem-edit.html | 73 +++ cms/templates/widgets/problem-new.html | 52 ++ cms/templates/widgets/raw-videos.html | 3 + cms/templates/widgets/save-captions.html | 4 + cms/templates/widgets/speed-tooltip.html | 7 + cms/templates/widgets/video-box-unused.html | 38 ++ cms/templates/widgets/video-box.html | 35 ++ cms/templates/widgets/video-edit.html | 151 +++++ cms/templates/widgets/video-new.html | 48 ++ cms/templates/widgets/week-edit.html | 83 +++ cms/templates/widgets/week-new.html | 62 ++ cms/urls.py | 1 + 95 files changed, 5386 insertions(+) create mode 100644 cms/static/css/base-style.css create mode 100644 cms/static/css/ie.css create mode 100644 cms/static/css/style.css create mode 100755 cms/static/img/indicator.gif create mode 100644 cms/static/img/video.jpg create mode 100755 cms/static/js/jquery.inlineedit.js create mode 100644 cms/static/js/jquery.leanModal.min.js create mode 100644 cms/static/js/jquery.tablednd.js create mode 100644 cms/static/js/main.js create mode 100644 cms/static/js/markitup/jquery.markitup.js create mode 100644 cms/static/js/markitup/sets/wiki/images/bold.png create mode 100644 cms/static/js/markitup/sets/wiki/images/clean.png create mode 100644 cms/static/js/markitup/sets/wiki/images/code.png create mode 100644 cms/static/js/markitup/sets/wiki/images/h1.png create mode 100644 cms/static/js/markitup/sets/wiki/images/h2.png create mode 100644 cms/static/js/markitup/sets/wiki/images/h3.png create mode 100644 cms/static/js/markitup/sets/wiki/images/h4.png create mode 100644 cms/static/js/markitup/sets/wiki/images/h5.png create mode 100644 cms/static/js/markitup/sets/wiki/images/image.png create mode 100644 cms/static/js/markitup/sets/wiki/images/italic.png create mode 100644 cms/static/js/markitup/sets/wiki/images/link.png create mode 100644 cms/static/js/markitup/sets/wiki/images/list-bullet.png create mode 100644 cms/static/js/markitup/sets/wiki/images/list-numeric.png create mode 100644 cms/static/js/markitup/sets/wiki/images/picture.png create mode 100644 cms/static/js/markitup/sets/wiki/images/preview.png create mode 100644 cms/static/js/markitup/sets/wiki/images/quotes.png create mode 100644 cms/static/js/markitup/sets/wiki/images/stroke.png create mode 100644 cms/static/js/markitup/sets/wiki/images/url.png create mode 100644 cms/static/js/markitup/sets/wiki/set.js create mode 100644 cms/static/js/markitup/sets/wiki/style.css create mode 100644 cms/static/js/markitup/skins/simple/images/handle.png create mode 100644 cms/static/js/markitup/skins/simple/images/menu.png create mode 100644 cms/static/js/markitup/skins/simple/images/submenu.png create mode 100644 cms/static/js/markitup/skins/simple/style.css create mode 100644 cms/static/sass/_base.scss create mode 100644 cms/static/sass/_calendar.scss create mode 100644 cms/static/sass/_problem.scss create mode 100644 cms/static/sass/_reset.scss create mode 100644 cms/static/sass/_video.scss create mode 100644 cms/static/sass/_week.scss create mode 100644 cms/static/sass/base-style.scss create mode 100644 cms/static/sass/bourbon/_bourbon.scss create mode 100644 cms/static/sass/bourbon/addons/_button.scss create mode 100644 cms/static/sass/bourbon/addons/_clearfix.scss create mode 100644 cms/static/sass/bourbon/addons/_font-family.scss create mode 100644 cms/static/sass/bourbon/addons/_html5-input-types.scss create mode 100644 cms/static/sass/bourbon/addons/_position.scss create mode 100644 cms/static/sass/bourbon/addons/_timing-functions.scss create mode 100644 cms/static/sass/bourbon/css3/_animation.scss create mode 100644 cms/static/sass/bourbon/css3/_appearance.scss create mode 100644 cms/static/sass/bourbon/css3/_background-image.scss create mode 100644 cms/static/sass/bourbon/css3/_background-size.scss create mode 100644 cms/static/sass/bourbon/css3/_border-image.scss create mode 100644 cms/static/sass/bourbon/css3/_border-radius.scss create mode 100644 cms/static/sass/bourbon/css3/_box-shadow.scss create mode 100644 cms/static/sass/bourbon/css3/_box-sizing.scss create mode 100644 cms/static/sass/bourbon/css3/_columns.scss create mode 100644 cms/static/sass/bourbon/css3/_flex-box.scss create mode 100644 cms/static/sass/bourbon/css3/_inline-block.scss create mode 100644 cms/static/sass/bourbon/css3/_linear-gradient.scss create mode 100644 cms/static/sass/bourbon/css3/_radial-gradient.scss create mode 100644 cms/static/sass/bourbon/css3/_transform.scss create mode 100644 cms/static/sass/bourbon/css3/_transition.scss create mode 100644 cms/static/sass/bourbon/css3/_user-select.scss create mode 100644 cms/static/sass/bourbon/functions/_deprecated-webkit-gradient.scss create mode 100644 cms/static/sass/bourbon/functions/_flex-grid.scss create mode 100644 cms/static/sass/bourbon/functions/_grid-width.scss create mode 100644 cms/static/sass/bourbon/functions/_linear-gradient.scss create mode 100644 cms/static/sass/bourbon/functions/_modular-scale.scss create mode 100644 cms/static/sass/bourbon/functions/_radial-gradient.scss create mode 100644 cms/static/sass/bourbon/functions/_render-gradients.scss create mode 100644 cms/static/sass/bourbon/functions/_tint-shade.scss create mode 100644 cms/static/sass/bourbon/lib/bourbon.rb create mode 100644 cms/static/sass/bourbon/lib/bourbon/sass_extensions.rb create mode 100644 cms/static/sass/bourbon/lib/bourbon/sass_extensions/functions.rb create mode 100644 cms/static/sass/bourbon/lib/bourbon/sass_extensions/functions/compact.rb create mode 100644 cms/templates/base.html create mode 100644 cms/templates/index.html create mode 100644 cms/templates/widgets/captions.html create mode 100644 cms/templates/widgets/header.html create mode 100644 cms/templates/widgets/navigation.html create mode 100644 cms/templates/widgets/new-module.html create mode 100644 cms/templates/widgets/problem-edit.html create mode 100644 cms/templates/widgets/problem-new.html create mode 100644 cms/templates/widgets/raw-videos.html create mode 100644 cms/templates/widgets/save-captions.html create mode 100644 cms/templates/widgets/speed-tooltip.html create mode 100644 cms/templates/widgets/video-box-unused.html create mode 100644 cms/templates/widgets/video-box.html create mode 100644 cms/templates/widgets/video-edit.html create mode 100644 cms/templates/widgets/video-new.html create mode 100644 cms/templates/widgets/week-edit.html create mode 100644 cms/templates/widgets/week-new.html diff --git a/cms/djangoapps/contentstore/views.py b/cms/djangoapps/contentstore/views.py index c6786b03c4..38e9e8ad35 100644 --- a/cms/djangoapps/contentstore/views.py +++ b/cms/djangoapps/contentstore/views.py @@ -10,3 +10,7 @@ def calendar(request, org, course): Location(['i4x', org, course, 'Course', 'course']) ) return render_to_response('calendar.html', {'weeks': weeks}) + + +def index(request): + return render_to_response('index.html', {}) diff --git a/cms/static/css/base-style.css b/cms/static/css/base-style.css new file mode 100644 index 0000000000..2cdeafe9e5 --- /dev/null +++ b/cms/static/css/base-style.css @@ -0,0 +1,589 @@ +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; } + +a { + text-decoration: none; + color: #888; } + +input[type="submit"], .button, section.week-edit > header a, section.week-new > header a { + 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; } + +section.cal { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 25px; + zoom: 1; + overflow: scroll; } + section.cal:before, section.cal:after { + content: ""; + display: table; } + section.cal:after { + clear: both; } + section.cal > header { + zoom: 1; + margin-bottom: 10px; } + section.cal > header:before, section.cal > header:after { + content: ""; + display: table; } + section.cal > header:after { + clear: both; } + section.cal > header h1 { + float: left; + font-size: 18px; } + section.cal > header ul { + float: right; } + 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; } + section.cal > header ul li a { + padding: 6px; + border: 1px solid #ddd; + display: block; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + -ms-border-radius: 3px; + -o-border-radius: 3px; + border-radius: 3px; + background: #efefef; } + section.cal > header ul li.dropdown { + position: relative; } + section.cal > header ul li.dropdown ul { + display: none; + position: absolute; + background: #fff; + border: 1px solid #ddd; } + section.cal > header ul li.dropdown ul li { + padding: 6px; + display: block; + border-top: 1px solid transparent; + border-bottom: 1px solid transparent; } + section.cal > header ul li.dropdown ul li:hover { + background-color: #efefef; + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; } + section.cal > header ul li.dropdown:hover ul { + display: block; } + section.cal > header ul li.dropdown:hover a { + -webkit-border-radius: 3px 3px 0 0; + -moz-border-radius: 3px 3px 0 0; + -ms-border-radius: 3px 3px 0 0; + -o-border-radius: 3px 3px 0 0; + border-radius: 3px 3px 0 0; + border-bottom: 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:last-child { + text-align: center; + background: #eee; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; } + section.cal ol > li:last-child p { + width: 100%; + height: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; } + section.cal ol > li:last-child p a { + display: block; + width: 100%; + height: 100%; } + section.cal ol > li:last-child section.new-week header { + background: #fff; + text-align: left; } + section.cal ol > li:last-child section.new-week form { + background: #fff; + width: 50%; + padding: 6px; + border: 1px solid #000; + margin: 0 auto; + -webkit-box-shadow: 0 0 2px #333333; + -moz-box-shadow: 0 0 2px #333333; + box-shadow: 0 0 2px #333333; + position: relative; } + section.cal ol > li:last-child section.new-week form:before { + background: #fff; + border-left: 1px solid #000; + border-top: 1px solid #000; + content: " "; + display: block; + height: 10px; + left: 50%; + position: absolute; + top: -6px; + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -ms-transform: rotate(45deg); + -o-transform: rotate(45deg); + transform: rotate(45deg); + width: 10px; + z-index: 0; } + section.cal ol > li:last-child section.new-week form select { + margin-bottom: 6px; + width: 100%; } + section.cal ol > li:last-child section.new-week form select option { + padding: 10px 0 !important; } + section.cal ol > li:last-child section.new-week form input[type="submit"] { + display: block; + margin-bottom: 6px; + width: 100%; } + section.cal ol > li:last-child section.new-week form a:first-child { + float: left; } + section.cal ol > li:last-child section.new-week form a:last-child { + float: right; } + section.cal ol > li header { + border-bottom: 1px solid #000; + -webkit-box-shadow: 0 1px 2px #cccccc; + -moz-box-shadow: 0 1px 2px #cccccc; + box-shadow: 0 1px 2px #cccccc; + display: block; + margin-bottom: 2px; + padding: 6px; } + section.cal ol > li header h1 { + font-size: 14px; } + 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.goal { + background: #fff; } + +body.content +section.cal { + width: 25.577%; + float: left; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; } + body.content + section.cal > header ul { + display: none; } + body.content + section.cal ol li { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + width: 100%; } + +section.week-edit > header, section.week-new > header { + border-bottom: 1px solid #ccc; + zoom: 1; + padding: 6px; } + section.week-edit > header:before, section.week-edit > header:after, section.week-new > header:before, section.week-new > header:after { + content: ""; + display: table; } + section.week-edit > header:after, section.week-new > header:after { + clear: both; } + section.week-edit > header h1, section.week-new > header h1 { + font-size: 18px; + float: left; + margin-top: 8px 6px; } + section.week-edit > header a, section.week-new > header a { + float: right; + display: block; } +section.week-edit section header, section.week-new section header { + background: #666; + color: #fff; + padding: 6px; + border-bottom: 1px solid #333; + -webkit-font-smoothing: antialiased; } + section.week-edit section header h2, section.week-new section header h2 { + font-size: 14px; } +section.week-edit section.sidebar, section.week-new section.sidebar { + width: 34.368%; + float: left; + background: #ccc; + border-right: 1px solid #333; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; } + section.week-edit section.sidebar section, section.week-new section.sidebar section { + height: 50%; } + section.week-edit section.sidebar section > ul, section.week-new section.sidebar section > ul { + list-style: none; } + section.week-edit section.sidebar section > ul > li, section.week-new section.sidebar section > ul > li { + padding: 6px; + border-bottom: 1px solid #666; + background: #eee; } + section.week-edit section.sidebar section > ul > li.new-module, section.week-new section.sidebar section > ul > li.new-module { + position: relative; } + section.week-edit section.sidebar section > ul > li.new-module ul.new-dropdown, section.week-new section.sidebar section > ul > li.new-module ul.new-dropdown { + list-style: none; } + section.week-edit section.sidebar section > ul > li.new-module ul.new-dropdown li, section.week-new section.sidebar section > ul > li.new-module ul.new-dropdown li { + display: none; } + section.week-edit section.sidebar section > ul > li.new-module ul.new-dropdown li:first-child, section.week-new section.sidebar section > ul > li.new-module ul.new-dropdown li:first-child { + display: block; } + section.week-edit section.sidebar section > ul > li.new-module ul.new-dropdown:hover li, section.week-new section.sidebar section > ul > li.new-module ul.new-dropdown:hover li { + display: block; + padding: 6px 0; } + section.week-edit section.sidebar section > ul > li.new-module ul.new-dropdown:hover li:first-child, section.week-new section.sidebar section > ul > li.new-module ul.new-dropdown:hover li:first-child { + padding-top: 0; } + section.week-edit section.sidebar section p, section.week-new section.sidebar section p { + padding: 6px; + border-bottom: 1px solid #666; } +section.week-edit section.weeks-content, section.week-new section.weeks-content { + width: 65.632%; + float: left; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; } + section.week-edit section.weeks-content header, section.week-new section.weeks-content header { + zoom: 1; } + section.week-edit section.weeks-content header:before, section.week-edit section.weeks-content header:after, section.week-new section.weeks-content header:before, section.week-new section.weeks-content header:after { + content: ""; + display: table; } + section.week-edit section.weeks-content header:after, section.week-new section.weeks-content header:after { + clear: both; } + section.week-edit section.weeks-content header h2, section.week-new section.weeks-content header h2 { + float: left; } + section.week-edit section.weeks-content header form, section.week-new section.weeks-content header form { + float: right; + margin: -2px 0; } + section.week-edit section.weeks-content header form input, section.week-new section.weeks-content header form input { + border: 1px solid #000; + background: #ddd; + padding: 2px 4px; + -webkit-border-radius: 2px; + -moz-border-radius: 2px; + -ms-border-radius: 2px; + -o-border-radius: 2px; + border-radius: 2px; } + section.week-edit section.weeks-content section.filters, section.week-new section.weeks-content section.filters { + border-bottom: 1px solid #999; } + section.week-edit section.weeks-content section.filters ul, section.week-new section.weeks-content section.filters ul { + zoom: 1; + list-style: none; + padding: 6px; } + section.week-edit section.weeks-content section.filters ul:before, section.week-edit section.weeks-content section.filters ul:after, section.week-new section.weeks-content section.filters ul:before, section.week-new section.weeks-content section.filters ul:after { + content: ""; + display: table; } + section.week-edit section.weeks-content section.filters ul:after, section.week-new section.weeks-content section.filters ul:after { + clear: both; } + section.week-edit section.weeks-content section.filters ul li, section.week-new section.weeks-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.weeks-content section.filters ul li.advanced, section.week-new section.weeks-content section.filters ul li.advanced { + float: right; } + section.week-edit section.weeks-content section.modules ul, section.week-new section.weeks-content section.modules ul { + list-style: none; } + section.week-edit section.weeks-content section.modules ul li, section.week-new section.weeks-content section.modules ul li { + padding: 6px; + font-weight: bold; + font-size: 16px; + border-bottom: 1px solid #333; } + section.week-edit section.weeks-content section.modules ul li a, section.week-new section.weeks-content section.modules ul li a { + color: #000; } + +section.video-new, section.video-edit { + position: absolute; + top: 80px; + right: 0; + background: #fff; + width: 40.32%; + -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 { + 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 { + content: ""; + display: table; } + section.video-new > header:after, section.video-edit > header:after { + clear: both; } + section.video-new > header h2, section.video-edit > header h2 { + float: left; + font-size: 14px; } + section.video-new > header a, section.video-edit > header a { + float: right; } + section.video-new section ul, section.video-edit section ul { + list-style: none; } + section.video-new section ul li, section.video-edit section ul li { + border-bottom: 1px solid #333; + padding: 10px 25px; } + +section.problem-new, section.problem-edit { + position: absolute; + top: 80px; + right: 0; + background: #fff; + width: 40.32%; + -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.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.problem-new > header:before, section.problem-new > header:after, section.problem-edit > header:before, section.problem-edit > header:after { + content: ""; + display: table; } + section.problem-new > header:after, section.problem-edit > header:after { + clear: both; } + section.problem-new > header h2, section.problem-edit > header h2 { + float: left; + font-size: 14px; } + section.problem-new > header a, section.problem-edit > header a { + float: right; } + section.problem-new section ul, section.problem-edit section ul { + list-style: none; } + section.problem-new section ul li, section.problem-edit section ul li { + border-bottom: 1px solid #333; + padding: 10px 25px; } + +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; } diff --git a/cms/static/css/ie.css b/cms/static/css/ie.css new file mode 100644 index 0000000000..f497a329cf --- /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 0000000000..e69de29bb2 diff --git a/cms/static/img/indicator.gif b/cms/static/img/indicator.gif new file mode 100755 index 0000000000000000000000000000000000000000..085ccaecaf5fa5c34bc14cd2c2ed5cbbd8e25dcb GIT binary patch literal 1553 zcma)+TTl~c6vwlh>nb99Af5rT)t{mCEg5urg=A(g z{C|6SPb~9Xage|wB`SrZk2FOMYM!buln2sX?5Y+T78iB(Zu9cS7|LZyZ++}u$^oi1 z_j@S}bW9OzU2R+RMy&~OT>X-oZ98$jq#ogNfJ!BM-42wHGZk*6s2KD}U*IA%epmxb zm}|6BK9YoIF;*xSL!+z@<64lB7->LTW2Vi4ostCA(z&2XniwNIv}fFo-`MbG;)u4G z^p@F!)|9HhZprHd_vXjDoxs6WkK-6P0@lfxnGT>*p(QHoUV=u1FAqb@b%*W=a3{`LsH5k^AvQNL>6fPpy#oU(&MuH(*aEX4b35*} zn4n7)`I2U%=+Z=?BVZQ?vjQFW4gD@~XSOO6b{qu81`4&LFuU2(ilxW+1|ZkNMnWe79C$gs zWT?Ele|HR{JGPe)5BTW>0Ey?-Ls6S#GoV0tbt6ku7B&*0 z;i9QM$W1Rj*rRIdceL)rAOSl+sDe3LkB87<%){;ZdHp6|SNlopDXRx< zxBDF9-lTo&v`8$humFygUij@qgT=Qzhj8{ym2-{Xciwqq_Xwk%=O3B-MNAL_6e`3U zyxwmXex4`g0^1RYw~Dth3av3Dl^AAlpO3mG!nLr#&ZZ7c_wUboI+deC+&%TFjK2Lm z!Y&f1h|T_On%RCV&=4bx`!>(YezqGVhl&QpED?N6GV)HmzJ9&rh$x*i?*@o9#6QI< z5ZI_MRX;0+pY8$`j)eF#TlUyG(eE%E7S!rj;mj^M5vhUicPm zVWQ2z+imFyg}SRABmOBY_@osR!>7Ov!ioK`NB6_Rv}7Ud?35ed5Sb@?yND?kv~RCa wqs^a3Sh>&&L4)!LKI?D2&k@))k(LESaga|C278ChSzn3NWVkcuNoY&{0f?~U_5c6? literal 0 HcmV?d00001 diff --git a/cms/static/img/video.jpg b/cms/static/img/video.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e92271c3ad5e23185f1fac4bbf5954df735d5949 GIT binary patch literal 7217 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 + * 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: ' ', + 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,"
" ) ) ); + } + return this.element.data( 'value' + namespace ); + }, + + mutatedHtml: function( value ) { + return this.controls[ this.options.control ].call( this, value ); + }, + + placeholderHtml: function() { + return ''+ this.options.placeholder +''; + }, + + 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 '' + this.buttonHtml( { before: '
' } ); + }, + input: function( value ) { + return '' + 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: '"'} + ], + 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 0000000000..a5772dd8e2 --- /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=$("
");$("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 0000000000..56413ccb08 --- /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 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 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 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 0000000000..45f94849f8 --- /dev/null +++ b/cms/static/js/main.js @@ -0,0 +1,159 @@ +$(document).ready(function(){ + $('section.main-content').children().hide(); + + $(function(){ + $('.editable').inlineEdit(); + $('.editable-textarea').inlineEdit({control: 'textarea'}); + }); + + // $("a[rel*=leanModal]").leanModal(); + + // $(".remove").click(function(){ + // $(this).parents('li').hide(); + // }); + + // $("#show-sidebar").click(function(){ + // $("#video-selector").toggleClass('hidden'); + // return false; + // }); + + // $('.use-video').click(function() { + // var used = $('#used'); + // if (used.is(':visible')) { + // used.hide().show('slow'); + // } + // used.show(); + // $('.no-video').hide(); + // }); + + // $('.remove-video').click(function() { + // $('#used').hide(); + // $('.no-video').show(); + // }); + + // $('#new-upload').click(function() { + // $('.selected-files').toggle(); + // return false; + // }); + + // /* $('.block').append('✕<\/a>'); */ + + // $('a.delete').click(function() { + // $(this).parents('.block').hide(); + // }); + + // $('.speed-list > li').hover(function(){ + // $(this).children('.tooltip').toggle(); + // }); + + // $('.delete-speed').click(function(){ + // $(this).parents('li.speed').hide(); + // return false; + // }); + + // $('.edit-captions').click(function(){ + // var parentVid = $(this).parents('div'); + // parentVid.siblings('div.caption-box').toggle(); + // return false; + // }); + + // $('.close-box').click(function(){ + // $(this).parents('.caption-box').hide(); + // return false; + // }); + + // $('ul.dropdown').hide(); + // $('li.questions').click(function() { + // $('ul.dropdown').toggle(); + // return false; + // }); + + // $('#mchoice').click(function(){ + // $('div.used').append($('
').load("/widgets/multi-choice.html")); + // return false; + // }); + + // $('#text').click(function(){ + // $('div.used').append($('
').load("/widgets/text.html")); + // return false; + // }); + + // $('#numerical').click(function(){ + // $('div.used').append($('
').load("/widgets/text-question.html")); + // return false; + // }); + + // $('#equation').click(function(){ + // $('div.used').append($('
').load("/widgets/latex-equation.html")); + // return false; + // }); + + // $('#script').click(function(){ + // $('div.used').append($('
').load("/widgets/script-widget.html")); + // return false; + // }); + + // $("#mark").markItUp(myWikiSettings); + + + var heighest = 0; + $('.cal ol > li').each(function(){ + heighest = ($(this).height() > heighest) ? $(this).height() : heighest; + + }); + + $('.cal ol > li').css('height',heighest + 'px'); + + $('.new-week').hide(); + $('.add-new-week').click(function() { + $(this).hide(); + $('.new-week').show(); + return false; + }); + + $('.new-week .close').click( function(){ + $(this).parents('.new-week').hide(); + $('p.add-new-week').show(); + return false; + }); + + var windowHeight = $(window).resize().height(); + + $('.sidebar').css('height', windowHeight); + + $('.edit-week').click( function() { + $('body').addClass('content'); + $('body.content .cal').css('height', windowHeight); + $('section.week-new').show(); + return false; + }); + + $('.cal ol li header h1 a').click( function() { + $('body').addClass('content'); + $('body.content .cal').css('height', windowHeight); + $('section.week-edit').show(); + return false; + }); + + + $('.video-new a').click(function(){ + $('section.video-new').show(); + return false; + }); + + $('.video-edit a').click(function(){ + $('section.video-edit').show(); + return false; + }); + + $('.problem-new a').click(function(){ + $('section.problem-new').show(); + return false; + }); + + $('.problem-edit a').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 0000000000..10add9d27c --- /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('
'); + $$.wrap('
'); + $$.wrap('
'); + $$.addClass("markItUpEditor"); + + // add the header before the textarea + header = $('
').insertBefore($$); + $(dropMenus(options.markupSet)).appendTo(header); + + // add the footer after the textarea + footer = $('
').insertAfter($$); + + // add the resize handle after textarea + if (options.resizeHandle === true && $.browser.safari !== true) { + resizeHandle = $('
') + .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 = $('
    '), 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 = $('
  • '+(button.separator||'')+'
  • ').appendTo(ul); + } else { + i++; + for (j = levels.length -1; j >= 0; j--) { + t += levels[j]+"-"; + } + li = $('
  • '+(button.name||'')+'
  • ') + .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 = $(''); + 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(//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 GIT binary patch literal 304 zcmV-00nh%4P)b^}|6b=Y6y(;Y{!a!g z@UQp#@Aw}>L3(}s|7f5BUjeuKZvQRjV<2U7yvu*H{aAbvQ6K!@3oKzW z-{Qa8d3gae1^)HE{~f^!v<1}u>;4xnKvUpW540I-w9J3a{{r=B3T*2g{_BH1CtaZO zpZ`6V0*V5g1e5i;`_=Z#_e=H*@8|93RG@lX;D!K7TKswwko8{x0000LlS^n5Q5c2KWM*m}YV3eAws|yDY&wl?DsIf8f*>k% z<*Hc~7ec_5rHi-`yO3f)SBkFeMi8|t(GpA*#H3ciSWBp+c{r^&PVFO&3C&}i$+#MA zZCZ-`mgm3cyWAfxp=la+gJD~$f3lF*v;Jqx`Q8T$Z@WYD zo5ULg-eG}Z89L0f4Zd=*mecc6xt8;=w2x)zu;*%)sVnHZF8Gfgv50&V?aO?Vg=C`G zqt8;QwVsqD3w#sp>uk4(?#r`&eMV@ShR&fc4IOUt64yxY7gl5?KAAs}zQf1Y-^2&g z$Gu&9-`V$(R7R2uQ}2HsoE!1T1^`G5aq_1Rg+NBCRv6kqwQ}ZBXMdtuFS`d*&78wH z%FqTXD^)8WCsqSp-l}5wzGHH~3TMv4``ZJRQO3=(w6oCI`;E z`gMDg;9p*xrm`moLYyi48W1M{s};+X6Y)q)IQvrJsBPN-$Qt1?9(Dn}gMTvW8Vj;U zv~1YHR;Z*VmZrvRmZz6cE&o6XK(RnVCGj2D!Cx>lhwjfzzEPx#2?dhIYK}l!BvcK! z3)ER+Jz{5>jf6w4x#gTU%_MMNlkNp$oSbvBp&uHw9M;u0-4@=t5BI zP6Hx#-C_{5RMJ z0_P+Xkumexn8%)S+Y)#l(gR;YJP<6#1-=jjK0LONWPdJQIR8uK1HpvVIxBIQ2ztt+ zqoEx_X9S%QGMe=~(k#sebCL-an)%CR%a7YtUOQUgv+G>~?N~XSWhx=? z@$fx}0MB;$`JWcQ-Re{XV~5|{DvU(#*+NF*g)j^qk#b~G9_O!i*y&mZVZ=a3;Go(K z`DkskYn56Nhu+k@1Ke*uY|x zI&k6j$JfNe_a{GH%=n2rZOz$Z8R9V?Pe36hIk}jo+A-`;dt9vyvBu#Xm@veu&@v`| zzt%mwc_$nd0-sMVx2d)b0!MqGxmfCumx7yB#nIUWvA{!HOMfslMyW1iV&nY>zxwyj z8^JfLN|kT z4m^Q1mhO(_r4w@`V?H=YNkOf(i&bHT3Auc3bryK1_{hDSetLoLN{VLB^78ULiNFy^ zkUqqG$fjVkJj5tfWkOn|P5`HVEp5@-mGnc0wvJGHC=+39MC2TWT#i?t*~fNch*he_ zgtS^8dH$(KlW)EF1b4Fzv~?&0IQaNdg;W5&{t&Bmg9&N1-rBBr_;Rg8ekw^mn;@T# zlS{|Rq+-Nlg18i%UY;i|q1NnSwf>I@85#4U4002ovPDHLkV1mEDi4_0< literal 0 HcmV?d00001 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 GIT binary patch literal 276 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-$x=IP=XqH%ujg^j!|20W|*-XbO@ zAtBSd^khRzd{=pNv@vN)9uZDqGTXuVPf6#I=?;x2B`Y;1YQMI>>GxvE??vtn{c>{A z7MYxUVrui2JTF|YR&ldntL8M3{q7no52$4`vIX;r@S8@YTFOM5*~nV4Gk-UYI5L$} zDw(h9UDksmVjphbEsSQ?UdGUxU4Htk{EZoY&3@-Y5*_;Wwk`ZAkg@!FaC~ii{N>;; VD%(>GD}XL$@O1TaS?83{1OVXtVO9VD literal 0 HcmV?d00001 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 GIT binary patch literal 304 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-$ROXGNhtQ`{C(%$wdeB3 zGTnLdz~IMJtNg?T>Z(s;oVU0)KW5x*9xvq)rPF;` zY|Fc4&#rLa>Txf#@y+aKf+ac0%`STzAI(*qdYo^XFH557y+_x*JpKO5^1S9?c^6}{ zP=+&OVHtDUrGNmdKI;Vst0KHFj AM*si- literal 0 HcmV?d00001 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 GIT binary patch literal 306 zcmV-20nPr2P)wEzGB literal 0 HcmV?d00001 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 GIT binary patch literal 293 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-&H?&;zfqH%ujg^j$;1_G=B-XbO( zon2btF4r#xDw?mmvtwaL3R_~+Yz66*rrQmiHySwec#9a-mn?F*9`VcnzTNDrbNY9( zxOA;CUb9S|sk-b7=Pc<<>lMA8+|AaBj(NoLhh2`-;+F zenR#-z6;(Syt?;Ub#DVE_OC literal 0 HcmV?d00001 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 GIT binary patch literal 304 zcmV-00nh%4P)ZVg9Hj*!Zw zxkAM~zCH&l><=6QeDdgV4l9hop+%GWq_IPV?Z641X8iiHrWJUN^2}hSiGjhsfbOLp z?d`9_MC0P3jVAVsE0oSgT$J*kO*Aq9I~CW*s{G*(t$KS{OS+#aO%?udUme<*TTEO`Fr@r_QT zk=#}u-n~>Vm!+9S1PE{@3<)G~CPb<$Za;W?3+O}|+q)?*Pn355=}S(XIZmEANjZci zf5 zj<%@MX^bD1^BwlS^+AD|$dm-1wial0hwPI;CDM?Y9SXW#@w-UF0SQ8OgplRTleOB2 zUjkDS|0U9pI|lSN*EvXUa~*UIclJdZ#)Npbwh9>YT?Z;=B8|l&^t~P~om?<5Lre$+ z;%`P>SL7`djY#8Y9$wv9dv|3p)C#5QQ<|d}62BjvZR2H60wE-$B^mK6y(Kw&{<9vg>Q9!g~ne(gm zmj4swoA@7?D86%i^8WzK9JM17E&sp&Z#dpHfz$E-U9ks&4?Z9Gyg!%0k2Q{M-Tz#> z2OnD>vrPZ*#{EHKLq)>Jcx{H|Ovdb&|4aQZWSipI{El%e^Cxx{^9vSw28s;a3IDB= TS1%U=TF&6<>gTe~DWM4fm>N^1 literal 0 HcmV?d00001 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 GIT binary patch literal 343 zcmV-d0jU0oP)$`dXYaZs9=SbAto%g@>T~?_bH&lTUn@`uo|1bXE{eSR(AO)ESb=V4`uk}mK|39Px&03WLbv~pzk+s7D@lK^ zn+aB+sp)&Y_x-B3>;6ywU--WQNUr<8>TU0P-|L#1U&;A)67w(+> pDf@fM7q9#F25QXo3rUI;002ro52U44e~JJA002ovPDHLkV1l;_q@Mr) literal 0 HcmV?d00001 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 GIT binary patch literal 344 zcmV-e0jK_nP)PbXFR5;6H z`2YVu10|S&DhA}te_Swi*Xsu$nk)lAnzx?+_#Z@r_~qs0*+Bfiq@?73K|#U)?Ck9S zsi~>|6A}{sM@B~e4-O9gPhA%bd?2RGd{of6>E(lvp1b6Ep>6&12TPB<{a?EDDL4@0 z;^ML+A|n0=1_u83^78uc?CkvC#>VEqiHXU7U0vP(YHDhzff&$ntDt1@;|H#l*M@2! z+U8#>h@W=vfpy*`^1J}j+`sMRe-I7g8yOj8Yin!&S5Z;VicFNp}SURRVGD{CSNFe~ni^^#wyl5uzj4je z|23%2?k#{x(*%mqe9M%mih+W%ElRQ}7!$^91> z7ymCLB=nz$hvz>#JNtiTW@gkt1Zf0eyP_){bPq%T_kY#2Z7&xs00000NkvXXu0mjf DNYA0= literal 0 HcmV?d00001 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 GIT binary patch literal 606 zcmV-k0-^nhP)Q2rnAt>LM%-F zK|rtwgcU)}7x~z1Hrcs5bH*ZO$!>xO8K#?==bZPQ_ecnV>#P`H`QzGaRhd62G_&rC zTLU$c7_x*nFP_dW#Q+*);mMHE?j)HexK784D4x9l_tfpz2$@1y}9rkF+ zI+J5NMWeZyObc!d+rUc=>D+uOdAOg#%+Ej6h+wn5^xPmVVH*Eu446Y0A_@ zo$rlds-+sL10DbHs{AQG2a)rMyf zFQK~pm1x3+7!nu%-M`k}``c>^00{o_1pjWJUTfl8mg=3qGEl8H@}^@w`VUx0_$uy4 z2FhRqKX}xI*?Tv1DJd8z#F#0c%*~rM30HE1@2o5m~}ZyoWhqv>ql{V z1ZGE0lgcoK^lx+eqc*rAX1Ky;Xx3U%u#zG!m-;eD1Qsn@kf3|F9qz~|95=&g3(7!X zB}JAT>RU;a%vaNOGnJ%e1=K6eAh43c(QN8RQ6~GP%O}Jju$~Ld*%`mO1p?P)vCi#|P&Xm-dkucwL z3)87{8iWe96huvPHfK`KOdC2Z({T6vJ9pwDx$D4>d(Pqff6w7Lmj{5i6;ZyPPpPN; zroaW=6d#@oL2Fa53F~$Su10(RG%K0p3VTuP3?Z=nBA8z$uq+XLUL^QrC74`bU|!e| zr>hK{)%Q!vdmIO5Z3JIvaOyjOX`X@c8-ua03`Q&)f&%p*{(A$q`ZTTjk%q_T7>v^J zu!R-a9fFLScYlKkNBP_Cob=9m9JLVoC-?c{)eOtMnh7qNN{ejy2sM{pS^mgFHJm@(buuM4>=<5Vr$&Kzw{B?uPr; z(1Yf=#g)zADkWnx=MR%ykl| z3Ui42k+O2{bCn)01-s5Sxp|z{G2di&KT(_M6;$EI zDL57JFf}cw4bP1P$pgTRKH$0@h|~aA>j`qZ2*kU5t2EVD5#~@VNhqx{vz8ethDD-=+1vnemftUBA zF;N!Q%PBB5B=KLB#QO(CHe?;R+-C8M?ppDW>R$5`cCPq@YpusFRTaH1i9Kv;l<>I( Ze*oTy+;kdDB`N>_002ovPDHLkV1l3CM+g7_ literal 0 HcmV?d00001 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 GIT binary patch literal 269 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-%c@9E+gqH#X?$N2_%qkv$?&V++! z-fX$@sb%KG-5a$|R8J4(Tcmu7`G0cYgxS-++3#dN^zA^J(=P8r|6lx9G_LLaZ+v5S z!d9iC@)!RP{FnQmdw#}3Ee(C$|NPA#|L6YmR@fBO9w|C7oMMQ$vc`Tu(RETvC<`(>OPJ!ieM-fH~m>7>j(^b;|pVbz=yzjpaJj$ zhrpuriKefui_0DvN;1Ymq&%nwWg*IrK!Xz^eJWuq3u2H~0ra?EC@ge%+`A>6mV z9{TYo{=G6 zt@5m|4G+Q2zKv;Ch@O;`PfWArmB5n3gvMsxV&Iu>97{a!2kL74wd@!f_AP^O%_&ND zm}1c*+F;TcH^{p$P_|akvD5o7vmT>HCkP;z;;&+8tDBI;koi9eX`W!oH4`pYaHlFZwV;$>vvfQTw zM-`m&R_SPIBa^FUasC0GCCh%{h`$~db`z&-lFX#%(f>H6JD6Z(sIW`RKE+xOL+?+uQ%q z){?+F%=6pqEH{6=NzusC-*<`PZYiLCGyKD}Z8^V8ul-K=AV@SE1t4~D2*b1(9UUc= zN-;Dv#Ngl{rd7e$ZUPXC##BFmV>$26ZQi?6Po#@{4gllsPbku3Vq${Y+FAf~T}OJb zGWEz9{(zcvI&CUaN&p7GcqMG4&7ULx##68M4k(F4l7Q+Xm&>uSv4N&(w6?a=)YOC{ zoYLN-J?7@-9xGBx007$C+kK7w_2Z$(k&l}jo2#`dO;J#Ipsbc$pS#^Dy3Q&nSeE5x fGMT)t>sS8=`naU3reLNz00000NkvXXu0mjf)bGN+ literal 0 HcmV?d00001 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 0000000000..895625621d --- /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:'', closeWith:''}, + {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:'(!(|!|
    )!)', closeWith:'(!(|!|
    )!)'}, + {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 0000000000..0a26c698f5 --- /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 GIT binary patch literal 258 zcmeAS@N?(olHy`uVBq!ia0vp^qCm{X#0(?@t!)i}6mzkYX9x!e$L)vy4}e^r0G|-o z4LkP#|NsB{_wSo_?oZ!X{TC?CQWE4B{GZ|f|H~VSrU3bz1s;*b3=G^tAk28_ZrvZC zpje4(M2T}zYGO%dex5=|W^O8jfw{hsp}v86ds2l5P=!25MR0yvNqJ&XDuZuga#4P6 zYD#9Jf?H-$YI%N9cCmuR){ILPK&1wrE{-7_Gm{H=1WS1m6Eb=Pa(faIBBVrjnVf1= soMNglKFuA6ghUcX`bbD&-ZPgg&ebxsLQ0Hz~TmH+?% literal 0 HcmV?d00001 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 GIT binary patch literal 27151 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

    +35?Hj$O) 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 literal 0 HcmV?d00001 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 0000000000..af8dc9cdb5 --- /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/_base.scss b/cms/static/sass/_base.scss new file mode 100644 index 0000000000..d9f3971d9e --- /dev/null +++ b/cms/static/sass/_base.scss @@ -0,0 +1,51 @@ + +$fg-column: 70px; +$fg-gutter: 26px; +$fg-max-columns: 12; + +html { + height: 100%; +} + +body { + @include clearfix(); + height: 100%; + font: 14px "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Geneva, Verdana, sans-serif; + + > 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; + } + } + } +} + +a { + text-decoration: none; + color: #888; +} + +input[type="submit"], .button { + border: 1px solid #ccc; + background: #efefef; + @include border-radius(3px); + padding: 6px; +} + diff --git a/cms/static/sass/_calendar.scss b/cms/static/sass/_calendar.scss new file mode 100644 index 0000000000..b149346ad6 --- /dev/null +++ b/cms/static/sass/_calendar.scss @@ -0,0 +1,206 @@ +section.cal { + @include box-sizing(border-box); + padding: 25px; + @include clearfix; + overflow: scroll; + + > header { + @include clearfix; + margin-bottom: 10px; + + h1 { + float: left; + font-size: 18px; + } + + ul { + float: right; + + li { + @include inline-block; + + a { + padding: 6px; + border: 1px solid #ddd; + display: block; + @include border-radius(3px); + background: #efefef; + } + + &.dropdown { + position: relative; + + ul { + display: none; + position: absolute; + background: #fff; + border: 1px solid #ddd; + + li { + padding: 6px; + display: block; + border-top: 1px solid transparent; + border-bottom: 1px solid transparent; + + &:hover { + background-color: #efefef; + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + } + } + } + + &:hover { + + ul { + display: block; + } + + a { + @include border-radius(3px 3px 0 0); + border-bottom: 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); + + &:last-child { + text-align: center; + background: #eee; + @include box-sizing(border-box); + + p { + width: 100%; + height: 100%; + @include box-sizing(border-box); + + a { + display: block; + width: 100%; + height: 100%; + } + } + + section.new-week { + header { + background: #fff; + text-align: left; + } + + form { + background: #fff; + width: 50%; + padding: 6px; + border: 1px solid #000; + margin: 0 auto; + @include box-shadow(0 0 2px #333); + position: relative; + + &:before { + background: #fff; + border-left: 1px solid #000; + border-top: 1px solid #000; + content: " "; + display: block; + height: 10px; + left: 50%; + position: absolute; + top: -6px; + @include transform(rotate(45deg)); + width: 10px; + z-index: 0; + } + + select { + margin-bottom: 6px; + width: 100%; + + option { + padding: 10px 0 !important; + } + } + + input[type="submit"] { + display: block; + margin-bottom: 6px; + width: 100%; + } + + a { + + &:first-child { + float: left; + } + + &:last-child { + float: right; + } + } + } + } + } + + header { + border-bottom: 1px solid #000; + @include box-shadow(0 1px 2px #ccc); + display: block; + margin-bottom: 2px; + padding: 6px; + + h1 { + font-size: 14px; + } + } + + ul { + list-style: none; + margin-bottom: 1px; + + li { + background: #efefef; + border-bottom: 1px solid #666; + padding: 6px; + + &.goal { + background: #fff; + } + } + } + } + } +} + +body.content + section.cal { + width: flex-grid(3) + flex-gutter(); + float: left; + @include box-sizing(border-box); + + > header ul { + display: none; + } + + ol { + li { + @include box-sizing(border-box); + width: 100%; + } + } + } diff --git a/cms/static/sass/_problem.scss b/cms/static/sass/_problem.scss new file mode 100644 index 0000000000..c513ce38d9 --- /dev/null +++ b/cms/static/sass/_problem.scss @@ -0,0 +1,41 @@ +section.problem-new, section.problem-edit { + position: absolute; + top: 80px; + right: 0; + background: #fff; + width: flex-grid(5); + @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 { + float: right; + } + } + + section { + ul { + list-style: none; + + li { + border-bottom: 1px solid #333; + padding: 10px 25px; + } + } + } +} + diff --git a/cms/static/sass/_reset.scss b/cms/static/sass/_reset.scss new file mode 100644 index 0000000000..bfe619c1b0 --- /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 0000000000..cb234108f4 --- /dev/null +++ b/cms/static/sass/_video.scss @@ -0,0 +1,40 @@ +section.video-new, section.video-edit { + position: absolute; + top: 80px; + right: 0; + background: #fff; + width: flex-grid(5); + @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 { + float: right; + } + } + + section { + ul { + list-style: none; + + li { + border-bottom: 1px solid #333; + padding: 10px 25px; + } + } + } +} diff --git a/cms/static/sass/_week.scss b/cms/static/sass/_week.scss new file mode 100644 index 0000000000..a628b0f164 --- /dev/null +++ b/cms/static/sass/_week.scss @@ -0,0 +1,152 @@ +section.week-edit, section.week-new { + + > header { + border-bottom: 1px solid #ccc; + @include clearfix(); + padding: 6px; + + h1 { + font-size: 18px; + float: left; + margin-top: 8px 6px; + } + + a { + float: right; + @extend .button; + display: block; + } + } + + section { + header { + background: #666; + color: #fff; + padding: 6px; + border-bottom: 1px solid #333; + -webkit-font-smoothing: antialiased; + + h2 { + font-size: 14px; + } + } + + &.sidebar { + width: flex-grid(3, 9) + flex-gutter(9); + float: left; + background: #ccc; + border-right: 1px solid #333; + @include box-sizing(border-box); + + section { + height: 50%; + + > ul { + list-style: none; + + > li { + padding: 6px; + border-bottom: 1px solid #666; + background: #eee; + + &.new-module { + position: relative; + + ul.new-dropdown { + list-style: none; + + li { + display: none; + + &:first-child { + display: block; + } + } + + &:hover { + li { + display: block; + padding: 6px 0; + + &:first-child { + padding-top: 0; + } + } + } + } + } + } + } + + p { + padding: 6px; + border-bottom: 1px solid #666; + } + } + } + + &.weeks-content { + width: flex-grid(6, 9); + float: left; + @include box-sizing(border-box); + + header { + @include clearfix; + + h2 { + float: left; + } + + form { + float: right; + margin: -2px 0; + + input { + border: 1px solid #000; + background: #ddd; + padding: 2px 4px; + @include border-radius(2px); + } + } + } + + + section { + &.filters { + border-bottom: 1px solid #999; + + ul { + @include clearfix(); + list-style: none; + padding: 6px; + + li { + @include inline-block(); + + &.advanced { + float: right; + } + } + } + } + + &.modules { + ul { + list-style: none; + + li { + padding: 6px; + font-weight: bold; + font-size: 16px; + border-bottom: 1px solid #333; + + a { + color: #000; + } + } + } + } + } + } + } +} diff --git a/cms/static/sass/base-style.scss b/cms/static/sass/base-style.scss new file mode 100644 index 0000000000..6a2dfbd0d2 --- /dev/null +++ b/cms/static/sass/base-style.scss @@ -0,0 +1,18 @@ +@import 'bourbon/bourbon'; +@import 'reset'; + +@import 'base'; +@import 'calendar'; +@import 'week', 'video', 'problem'; + +body { + &.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 ); + } + } +} diff --git a/cms/static/sass/bourbon/_bourbon.scss b/cms/static/sass/bourbon/_bourbon.scss new file mode 100644 index 0000000000..27b056e303 --- /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 0000000000..1d32125140 --- /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 0000000000..a9f6a795c5 --- /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 0000000000..df8a80ddfc --- /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 0000000000..9d86fbb4d4 --- /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 0000000000..6ad330f1df --- /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 0000000000..51b2410914 --- /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 0000000000..f99e06eb6f --- /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 | + $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 0000000000..548767e166 --- /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 0000000000..c23cef7c31 --- /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 0000000000..4bba11027d --- /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 0000000000..da4f20ba49 --- /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 0000000000..f24389ebbe --- /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 0000000000..327b66d251 --- /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 0000000000..3f3f7cca9a --- /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 0000000000..2896c91d7f --- /dev/null +++ b/cms/static/sass/bourbon/css3/_columns.scss @@ -0,0 +1,67 @@ +@mixin columns($arg: auto) { +// || + -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) { +// || || + -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 0000000000..44c1dfd789 --- /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 0000000000..d79a13c851 --- /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 0000000000..e366a299a9 --- /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 0000000000..e83cab5234 --- /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 0000000000..8d19e8b88d --- /dev/null +++ b/cms/static/sass/bourbon/css3/_transform.scss @@ -0,0 +1,19 @@ +@mixin transform($property: none) { +// none | + -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 0000000000..058dbe0e33 --- /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 0000000000..d5f5749431 --- /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 0000000000..1322f6f60e --- /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 0000000000..707f994e15 --- /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 0000000000..8e63d83d60 --- /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 0000000000..3b10ca82a6 --- /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 0000000000..dddccb5224 --- /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 0000000000..3d5461ad6e --- /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 0000000000..fe7c799ebe --- /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 0000000000..f7172004ac --- /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 0000000000..1635be836d --- /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 0000000000..ad567200e3 --- /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 0000000000..daa877650e --- /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 0000000000..5192e921e7 --- /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 0000000000..497296ee66 --- /dev/null +++ b/cms/templates/base.html @@ -0,0 +1,30 @@ + + + + + + + + + + {% block title %}{% endblock %} + + + + + + {% include "widgets/header.html"%} + + {% block content %}{% endblock %} + + + + + + + + + + + + diff --git a/cms/templates/index.html b/cms/templates/index.html new file mode 100644 index 0000000000..82c3133a37 --- /dev/null +++ b/cms/templates/index.html @@ -0,0 +1,19 @@ +{% extends "base.html" %} +{% block title %}Course Manager{% endblock %} + +{% block content %} +

    + + {% include "widgets/navigation.html"%} + +
    + {% include "widgets/week-edit.html"%} + {% include "widgets/week-new.html"%} + {% include "widgets/video-edit.html"%} + {% include "widgets/video-new.html"%} + {% include "widgets/problem-edit.html"%} + {% include "widgets/problem-new.html"%} +
    + +
    +{% endblock %} diff --git a/cms/templates/widgets/captions.html b/cms/templates/widgets/captions.html new file mode 100644 index 0000000000..088beb7a33 --- /dev/null +++ b/cms/templates/widgets/captions.html @@ -0,0 +1,242 @@ +
      +
    • English (main)
    • +
    • French
    • +
    • English v2
    • +
    • +
    • +
    + + diff --git a/cms/templates/widgets/header.html b/cms/templates/widgets/header.html new file mode 100644 index 0000000000..86a2afb0f9 --- /dev/null +++ b/cms/templates/widgets/header.html @@ -0,0 +1,5 @@ +
    + +
    diff --git a/cms/templates/widgets/navigation.html b/cms/templates/widgets/navigation.html new file mode 100644 index 0000000000..049e5da537 --- /dev/null +++ b/cms/templates/widgets/navigation.html @@ -0,0 +1,120 @@ +
    +
    +

    Circuts & Electronics

    + + +
    + +
      +
    1. +
      +

      Week 1

      +
      + +
        +
      • Goal 1
      • +
      • Goal 2
      • +
      • Lecture Sequence
      • +
      • Lecture Sequence
      • +
      • Lab
      • +
      • Homework
      • +
      • + Add new sequence
      • +
      +
    2. +
    3. +
      +

      Week 2

      +
      + +
        +
      • Goal 1
      • +
      • Lecture Sequence
      • +
      • Lecture Sequence
      • +
      • Lab
      • +
      • Homework
      • +
      • + Add new sequence
      • +
      +
    4. +
    5. +
      +

      Week 3

      +
      + +
        +
      • Goal 1
      • +
      • Lab
      • +
      • Lab
      • +
      • Homework
      • +
      • + Add new sequence
      • +
      +
    6. +
    7. +
      +

      Week 4

      +
      + +
        +
      • Goal 1
      • +
      • Lecture Sequence
      • +
      • Lab
      • +
      • Homework
      • +
      • Homework
      • +
      • + Add new sequence
      • +
      +
    8. + +
    9. +
      +

      Week 5

      +
      + +
        +
      • + Add new sequence
      • +
      +
    10. +
    11. +

      + + Add New +

      + +
      +
      +

      Week 6

      +
      + +
      + + +
      +
      +
    12. +
    +
    + diff --git a/cms/templates/widgets/new-module.html b/cms/templates/widgets/new-module.html new file mode 100644 index 0000000000..070b6462bb --- /dev/null +++ b/cms/templates/widgets/new-module.html @@ -0,0 +1,9 @@ +
  • + +
  • diff --git a/cms/templates/widgets/problem-edit.html b/cms/templates/widgets/problem-edit.html new file mode 100644 index 0000000000..b1d5796a9f --- /dev/null +++ b/cms/templates/widgets/problem-edit.html @@ -0,0 +1,73 @@ +
    +
    + cancel + Save & Update +
    + +
    +
    +

    Old Problem

    +
    + + +
    + Settings +
    + + +
    +
    +
    +

    Tags:

    +

    Click to edit

    +
    + +
    +

    Last modified:

    +

    mm/dd/yy

    +
    + +
    +

    By

    +

    Anant Agarwal

    +
    +
    +
    + +
    + +
    + 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. +
    +
    + +
    +
      +
    • +

      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.

      +

      Anant Agarwal

      +
    • +
    • +

      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.

      +

      Anant Agarwal

      +
    • +
    + +
    +

    Add notes

    + + +
    +
    + + Save & Update +
    +
    + diff --git a/cms/templates/widgets/problem-new.html b/cms/templates/widgets/problem-new.html new file mode 100644 index 0000000000..9f91dd1177 --- /dev/null +++ b/cms/templates/widgets/problem-new.html @@ -0,0 +1,52 @@ +
    +
    + cancel + Save & Update +
    + +
    +
    +

    New Problem

    +
    + + Settings + +
    +
    +
    +

    Tags:

    +

    Click to edit

    +
    + + + + + + + + + + +
    +
    + +
    + +
    +
    +
    + +
    +

    Add notes

    +
    + + Save & Update +
    +
    diff --git a/cms/templates/widgets/raw-videos.html b/cms/templates/widgets/raw-videos.html new file mode 100644 index 0000000000..f466fd59bc --- /dev/null +++ b/cms/templates/widgets/raw-videos.html @@ -0,0 +1,3 @@ +
  • +
    Video-file-name
    +
  • diff --git a/cms/templates/widgets/save-captions.html b/cms/templates/widgets/save-captions.html new file mode 100644 index 0000000000..87342f0cd0 --- /dev/null +++ b/cms/templates/widgets/save-captions.html @@ -0,0 +1,4 @@ +
    + Cancel + +
    diff --git a/cms/templates/widgets/speed-tooltip.html b/cms/templates/widgets/speed-tooltip.html new file mode 100644 index 0000000000..2a82e237e7 --- /dev/null +++ b/cms/templates/widgets/speed-tooltip.html @@ -0,0 +1,7 @@ +
    + +
    diff --git a/cms/templates/widgets/video-box-unused.html b/cms/templates/widgets/video-box-unused.html new file mode 100644 index 0000000000..8cde10f151 --- /dev/null +++ b/cms/templates/widgets/video-box-unused.html @@ -0,0 +1,38 @@ +
  • + +
    + +
    + video-name 236mb Uploaded 6 hours ago by Anant Agrawal +

    +

      + Speed +
    • + 0.75x + {% include "widgets/speed-tooltip.html" %} +
    • +
    • Normal + {% include "widgets/speed-tooltip.html" %} +
    • +
    • 1.25x + {% include "widgets/speed-tooltip.html" %} +
    • +
    • 1.5x + {% include "widgets/speed-tooltip.html" %} +
    • +
    • +
    • +
    +

    +

    + Download All — + Delete All — + Edit Captions — + Use clip ⬆ +

    +
    +
    + {% include "widgets/captions.html" %} + {% include "widgets/save-captions.html" %} +
    +
  • + diff --git a/cms/templates/widgets/video-box.html b/cms/templates/widgets/video-box.html new file mode 100644 index 0000000000..9ab17030bd --- /dev/null +++ b/cms/templates/widgets/video-box.html @@ -0,0 +1,35 @@ +
  • +
    + +
    + video-name 236mb +

    Uploaded 6 hours ago by Anant Agrawal

    +

    +

      + Speed +
    • + 0.75x + {% include "widgets/speed-tooltip.html" %} +
    • +
    • Normal + {% include "widgets/speed-tooltip.html" %} +
    • +
    • 1.25x + {% include "widgets/speed-tooltip.html" %} +
    • +
    • 1.5x + {% include "widgets/speed-tooltip.html" %} +
    • +
    • +
    • +
    +

    +

    + Download all — +Remove ⬇ + +

    +
    +
    + {% include "widgets/captions.html" %} +
    +
  • diff --git a/cms/templates/widgets/video-edit.html b/cms/templates/widgets/video-edit.html new file mode 100644 index 0000000000..6b49dc27d7 --- /dev/null +++ b/cms/templates/widgets/video-edit.html @@ -0,0 +1,151 @@ +
    + +
    +
    + +
    +
    + Created 22/03/12 + by Piotr Mitros +
    + +
    + Last edited 22/03/12 + by David Ormsbee +
    +
    +
    +
    +

    Video title

    + +
    + Tag mitx, s4v1, circuits, anant +
    + +
    +
    + Keyword + S4V1 + + + Due Date + 21/03/12 + + Status + + + +
    + +
    + +
    +
    +
    + or + use an already uploaded one +
    +
    + +
    +
    +
      +
    • video-name-@0-75x.extension
    • +
    • video-name-@1x.extension
    • +
    • video-name-@1-25x.extension
    • +
    • video-name-@1-5x.extension
    • +
    +
    + + + Cancel +
    + +
    + +
    +
    +
      +

      Video clip in use

      + {% include "widgets/video-box.html" %} +
    +

    No video clip used. Select one from the list below, upload a new one or import an already uploaded video.

    +
    +
    + +
    +
    + + +
    +
    +
      + {% include "widgets/video-box-unused.html" %} +
    +
    +
    + +
    + +
    +

    Annotations

    + + +
    + +
    + +
    + +
    +

    Notes

    + + + +
    + +
    +
    +
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. +

    By Piotr Mitros 10 hours ago

    +
    +
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.

    By Piotr Mitros 10 hours ago

    +
    +
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.

    By Piotr Mitros 10 hours ago

    +
    +
    +
    + + + +
    + +
    + Select the source video or directly enter its ID +
    + +
    + +
    + +
    + + + Cancel +
    +
    diff --git a/cms/templates/widgets/video-new.html b/cms/templates/widgets/video-new.html new file mode 100644 index 0000000000..2555169c05 --- /dev/null +++ b/cms/templates/widgets/video-new.html @@ -0,0 +1,48 @@ +
    +
    + cancel + Save & Update +
    + +
    +
    +

    Untitled Video

    +
    + + Settings + +
    + +
    +
    +

    Tags:

    +

    Click to edit

    +
    + + + + + + + + + + +
    +
    + +
    + +
    +
    + Save & Update +
    +
    +
    diff --git a/cms/templates/widgets/week-edit.html b/cms/templates/widgets/week-edit.html new file mode 100644 index 0000000000..5e6ac199e9 --- /dev/null +++ b/cms/templates/widgets/week-edit.html @@ -0,0 +1,83 @@ +{% block content %} +
    +
    +

    Week 3

    + Done +
    + + + +
    +
    +

    Weeks Content

    +
    + +
    +
    + +
    +
      +
    • + + +
    • + +
    • + + +
    • +
    • + +
    • + +
    • + Advanced filters +
    • +
    +
    + +
    + +
    +
    +
    +{% endblock %} diff --git a/cms/templates/widgets/week-new.html b/cms/templates/widgets/week-new.html new file mode 100644 index 0000000000..42f4f78e1e --- /dev/null +++ b/cms/templates/widgets/week-new.html @@ -0,0 +1,62 @@ +{% block content %} +
    +
    +

    Week 6

    + Done +
    + + + +
    +
    +

    Weeks Content

    +
    + +
    +
    + +
    +
      +
    • + + +
    • + +
    • + + +
    • +
    • + +
    • + +
    • + Advanced filters +
    • +
    +
    +
    +
    +{% endblock %} diff --git a/cms/urls.py b/cms/urls.py index a7266066cc..781c2c261f 100644 --- a/cms/urls.py +++ b/cms/urls.py @@ -7,4 +7,5 @@ from django.conf.urls.defaults import patterns, url urlpatterns = patterns('', url(r'^(?P[^/]+)/(?P[^/]+)/calendar/', 'contentstore.views.calendar', name='calendar'), url(r'^accounts/login/', 'instructor.views.do_login', name='login'), + url(r'^$', 'contentstore.views.index', name='index'), ) From 8338031f3e90c76ea740d1c000456231511b3822 Mon Sep 17 00:00:00 2001 From: Calen Pennington Date: Wed, 13 Jun 2012 13:22:38 -0400 Subject: [PATCH 06/21] Switch to mako templates --- cms/templates/base.html | 24 ++++++++++----------- cms/templates/index.html | 22 +++++++++---------- cms/templates/widgets/video-box-unused.html | 12 +++++------ cms/templates/widgets/video-box.html | 10 ++++----- cms/templates/widgets/video-edit.html | 8 +++---- cms/templates/widgets/week-edit.html | 6 +++--- cms/templates/widgets/week-new.html | 6 +++--- 7 files changed, 44 insertions(+), 44 deletions(-) diff --git a/cms/templates/base.html b/cms/templates/base.html index 497296ee66..a23a31d9a5 100644 --- a/cms/templates/base.html +++ b/cms/templates/base.html @@ -4,26 +4,26 @@ - - - - {% block title %}{% endblock %} + + + + <%block name="title"></%block> - {% include "widgets/header.html"%} + <%include file="widgets/header.html"/> - {% block content %}{% endblock %} + <%block name="content"> - - - - - - + + + + + + diff --git a/cms/templates/index.html b/cms/templates/index.html index 82c3133a37..efd9f9a242 100644 --- a/cms/templates/index.html +++ b/cms/templates/index.html @@ -1,19 +1,19 @@ -{% extends "base.html" %} -{% block title %}Course Manager{% endblock %} +<%inherit file="base.html" /> +<%block name="title">Course Manager -{% block content %} +<%block name="content">
    - {% include "widgets/navigation.html"%} + <%include file="widgets/navigation.html"/>
    - {% include "widgets/week-edit.html"%} - {% include "widgets/week-new.html"%} - {% include "widgets/video-edit.html"%} - {% include "widgets/video-new.html"%} - {% include "widgets/problem-edit.html"%} - {% include "widgets/problem-new.html"%} + <%include file="widgets/week-edit.html"/> + <%include file="widgets/week-new.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"/>
    -{% endblock %} + diff --git a/cms/templates/widgets/video-box-unused.html b/cms/templates/widgets/video-box-unused.html index 8cde10f151..3d643ff3c9 100644 --- a/cms/templates/widgets/video-box-unused.html +++ b/cms/templates/widgets/video-box-unused.html @@ -9,16 +9,16 @@ Speed
  • 0.75x - {% include "widgets/speed-tooltip.html" %} + <%include file="speed-tooltip.html"/>
  • Normal - {% include "widgets/speed-tooltip.html" %} + <%include file="speed-tooltip.html"/>
  • 1.25x - {% include "widgets/speed-tooltip.html" %} + <%include file="speed-tooltip.html"/>
  • 1.5x - {% include "widgets/speed-tooltip.html" %} + <%include file="speed-tooltip.html"/>
  • +
  • @@ -31,8 +31,8 @@

    - {% include "widgets/captions.html" %} - {% include "widgets/save-captions.html" %} + <%include file="captions.html"/> + <%include file="save-captions.html"/>
    diff --git a/cms/templates/widgets/video-box.html b/cms/templates/widgets/video-box.html index 9ab17030bd..1f17e33511 100644 --- a/cms/templates/widgets/video-box.html +++ b/cms/templates/widgets/video-box.html @@ -9,16 +9,16 @@ Speed
  • 0.75x - {% include "widgets/speed-tooltip.html" %} + <%include file="speed-tooltip.html"/>
  • Normal - {% include "widgets/speed-tooltip.html" %} + <%include file="speed-tooltip.html"/>
  • 1.25x - {% include "widgets/speed-tooltip.html" %} + <%include file="speed-tooltip.html"/>
  • 1.5x - {% include "widgets/speed-tooltip.html" %} + <%include file="speed-tooltip.html"/>
  • +
  • @@ -30,6 +30,6 @@

    - {% include "widgets/captions.html" %} + <%include file="captions.html"/>
    diff --git a/cms/templates/widgets/video-edit.html b/cms/templates/widgets/video-edit.html index 6b49dc27d7..ac4c921918 100644 --- a/cms/templates/widgets/video-edit.html +++ b/cms/templates/widgets/video-edit.html @@ -71,7 +71,7 @@

      Video clip in use

      - {% include "widgets/video-box.html" %} + <%include file="video-box.html"/>

    No video clip used. Select one from the list below, upload a new one or import an already uploaded video.

    @@ -84,7 +84,7 @@
      - {% include "widgets/video-box-unused.html" %} + <%include file="video-box-unused.html"/>
    @@ -129,7 +129,7 @@ @@ -140,7 +140,7 @@
    - +
    diff --git a/cms/templates/widgets/week-edit.html b/cms/templates/widgets/week-edit.html index 5e6ac199e9..ea6d29ef3b 100644 --- a/cms/templates/widgets/week-edit.html +++ b/cms/templates/widgets/week-edit.html @@ -1,4 +1,4 @@ -{% block content %} +<%block name="content">

    Week 3

    @@ -27,7 +27,7 @@
  • Problem title 13
  • Problem title 14
  • Video 3
  • - {% include "widgets/new-module.html"%} + <%include file="new-module.html"/>
    @@ -80,4 +80,4 @@ -{% endblock %} + diff --git a/cms/templates/widgets/week-new.html b/cms/templates/widgets/week-new.html index 42f4f78e1e..986dc6e05e 100644 --- a/cms/templates/widgets/week-new.html +++ b/cms/templates/widgets/week-new.html @@ -1,4 +1,4 @@ -{% block content %} +<%block name="content">

    Week 6

    @@ -18,7 +18,7 @@

    Scratchpad

      - {% include "widgets/new-module.html"%} + <%include file="new-module.html"/>
    @@ -59,4 +59,4 @@ -{% endblock %} + From f2080fde62335645a4d9ea787e8097e716d55f7a Mon Sep 17 00:00:00 2001 From: Calen Pennington Date: Wed, 13 Jun 2012 14:43:01 -0400 Subject: [PATCH 07/21] Porting latest changes from ui_prototype --- cms/static/css/base-style.css | 684 ++++++++++++++------- cms/static/js/main.js | 165 ++--- cms/static/sass/_base.scss | 16 +- cms/static/sass/_calendar.scss | 286 +++++---- cms/static/sass/_module-header.scss | 128 ++++ cms/static/sass/_problem.scss | 47 +- cms/static/sass/_video.scss | 59 +- cms/static/sass/_week.scss | 4 +- cms/static/sass/base-style.scss | 14 +- cms/templates/index.html | 1 + cms/templates/widgets/header.html | 3 +- cms/templates/widgets/module-dropdown.html | 28 + cms/templates/widgets/navigation.html | 118 ++-- cms/templates/widgets/new-module.html | 16 +- cms/templates/widgets/problem-edit.html | 72 +-- cms/templates/widgets/problem-new.html | 33 +- cms/templates/widgets/sequnce-edit.html | 85 +++ cms/templates/widgets/video-edit.html | 184 ++---- cms/templates/widgets/video-new.html | 81 ++- cms/templates/widgets/week-edit.html | 94 +-- cms/templates/widgets/week-new.html | 114 ++-- 21 files changed, 1356 insertions(+), 876 deletions(-) create mode 100644 cms/static/sass/_module-header.scss create mode 100644 cms/templates/widgets/module-dropdown.html create mode 100644 cms/templates/widgets/sequnce-edit.html diff --git a/cms/static/css/base-style.css b/cms/static/css/base-style.css index 2cdeafe9e5..518443a41c 100644 --- a/cms/static/css/base-style.css +++ b/cms/static/css/base-style.css @@ -191,13 +191,28 @@ body { clear: both; } body > header nav h2 { font-size: 14px; - text-transform: uppercase; } + text-transform: uppercase; + float: left; } + body > header nav a.new-module { + float: right; } + 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[type="submit"], .button, section.week-edit > header a, section.week-new > header a { +input[type="submit"], .button, section.cal section.new-section > a, section.week-edit > header a, +section.week-new > header a, +section.sequence-edit > header 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; @@ -221,17 +236,36 @@ section.cal { clear: both; } section.cal > header { zoom: 1; - margin-bottom: 10px; } + 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 h1 { - float: left; - font-size: 18px; } + 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 { - float: right; } + 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; @@ -239,42 +273,37 @@ section.cal { vertical-align: baseline; zoom: 1; *display: inline; - *vertical-align: auto; } + *vertical-align: auto; + margin-left: 6px; + padding-left: 6px; + border-left: 1px solid #ddd; + padding: 6px; } section.cal > header ul li a { - padding: 6px; - border: 1px solid #ddd; - display: block; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - -ms-border-radius: 3px; - -o-border-radius: 3px; - border-radius: 3px; - background: #efefef; } - section.cal > header ul li.dropdown { - position: relative; } - section.cal > header ul li.dropdown ul { - display: none; - position: absolute; - background: #fff; - border: 1px solid #ddd; } - section.cal > header ul li.dropdown ul li { - padding: 6px; - display: block; - border-top: 1px solid transparent; - border-bottom: 1px solid transparent; } - section.cal > header ul li.dropdown ul li:hover { - background-color: #efefef; - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; } - section.cal > header ul li.dropdown:hover ul { - display: block; } - section.cal > header ul li.dropdown:hover a { - -webkit-border-radius: 3px 3px 0 0; - -moz-border-radius: 3px 3px 0 0; - -ms-border-radius: 3px 3px 0 0; - -o-border-radius: 3px 3px 0 0; - border-radius: 3px 3px 0 0; - border-bottom: 0; } + 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; @@ -297,75 +326,26 @@ section.cal { box-sizing: border-box; float: left; width: 25.0%; } - section.cal ol > li:last-child { - text-align: center; - background: #eee; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; } - section.cal ol > li:last-child p { - width: 100%; - height: 100%; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; } - section.cal ol > li:last-child p a { - display: block; - width: 100%; - height: 100%; } - section.cal ol > li:last-child section.new-week header { - background: #fff; - text-align: left; } - section.cal ol > li:last-child section.new-week form { - background: #fff; - width: 50%; - padding: 6px; - border: 1px solid #000; - margin: 0 auto; - -webkit-box-shadow: 0 0 2px #333333; - -moz-box-shadow: 0 0 2px #333333; - box-shadow: 0 0 2px #333333; - position: relative; } - section.cal ol > li:last-child section.new-week form:before { - background: #fff; - border-left: 1px solid #000; - border-top: 1px solid #000; - content: " "; - display: block; - height: 10px; - left: 50%; - position: absolute; - top: -6px; - -webkit-transform: rotate(45deg); - -moz-transform: rotate(45deg); - -ms-transform: rotate(45deg); - -o-transform: rotate(45deg); - transform: rotate(45deg); - width: 10px; - z-index: 0; } - section.cal ol > li:last-child section.new-week form select { - margin-bottom: 6px; - width: 100%; } - section.cal ol > li:last-child section.new-week form select option { - padding: 10px 0 !important; } - section.cal ol > li:last-child section.new-week form input[type="submit"] { - display: block; - margin-bottom: 6px; - width: 100%; } - section.cal ol > li:last-child section.new-week form a:first-child { - float: left; } - section.cal ol > li:last-child section.new-week form a:last-child { - float: right; } section.cal ol > li header { border-bottom: 1px solid #000; - -webkit-box-shadow: 0 1px 2px #cccccc; - -moz-box-shadow: 0 1px 2px #cccccc; - box-shadow: 0 1px 2px #cccccc; + -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; - padding: 6px; } + margin-bottom: 2px; } section.cal ol > li header h1 { - font-size: 14px; } + 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; } @@ -373,8 +353,104 @@ section.cal { background: #efefef; border-bottom: 1px solid #666; padding: 6px; } - section.cal ol > li ul li.goal { - background: #fff; } + 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.8); + 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 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; } + section.cal section.new-section > a { + display: -moz-inline-box; + -moz-box-orient: vertical; + display: inline-block; + vertical-align: baseline; + zoom: 1; + *display: inline; + *vertical-align: auto; } + section.cal section.new-section section { + display: none; } + section.cal section.new-section section header { + background: #fff; + text-align: left; } + section.cal section.new-section section form { + background: #fff; + width: 50%; + padding: 6px; + border: 1px solid #000; + margin: 0 auto; + -webkit-box-shadow: 0 0 2px #333333; + -moz-box-shadow: 0 0 2px #333333; + box-shadow: 0 0 2px #333333; + position: relative; } + section.cal section.new-section section form:before { + background: #fff; + border-left: 1px solid #000; + border-top: 1px solid #000; + content: " "; + display: block; + height: 10px; + left: 50%; + position: absolute; + top: -6px; + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -ms-transform: rotate(45deg); + -o-transform: rotate(45deg); + transform: rotate(45deg); + width: 10px; + z-index: 0; } + section.cal section.new-section section form select { + margin-bottom: 6px; + width: 100%; } + section.cal section.new-section section form select option { + padding: 10px 0 !important; } + section.cal section.new-section section form input[type="submit"] { + display: block; + margin-bottom: 6px; + width: 100%; } + section.cal section.new-section section form a:first-child { + float: left; } + section.cal section.new-section section form a:last-child { + float: right; } + section.cal section.new-section:hover section { + display: block; } body.content section.cal { @@ -393,31 +469,49 @@ section.cal { box-sizing: border-box; width: 100%; } -section.week-edit > header, section.week-new > header { +section.week-edit > header, +section.week-new > header, +section.sequence-edit > header { border-bottom: 1px solid #ccc; zoom: 1; padding: 6px; } - section.week-edit > header:before, section.week-edit > header:after, section.week-new > header:before, section.week-new > header:after { + 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.week-edit > header:after, + section.week-new > header:after, + section.sequence-edit > header:after { clear: both; } - section.week-edit > header h1, section.week-new > header h1 { + section.week-edit > header h1, + section.week-new > header h1, + section.sequence-edit > header h1 { font-size: 18px; float: left; margin-top: 8px 6px; } - section.week-edit > header a, section.week-new > header a { + section.week-edit > header a, + section.week-new > header a, + section.sequence-edit > header a { float: right; display: block; } -section.week-edit section header, section.week-new section header { +section.week-edit section header, +section.week-new section header, +section.sequence-edit section header { background: #666; color: #fff; padding: 6px; border-bottom: 1px solid #333; -webkit-font-smoothing: antialiased; } - section.week-edit section header h2, section.week-new section header h2 { + section.week-edit section header h2, + section.week-new section header h2, + section.sequence-edit section header h2 { font-size: 14px; } -section.week-edit section.sidebar, section.week-new section.sidebar { +section.week-edit section.sidebar, +section.week-new section.sidebar, +section.sequence-edit section.sidebar { width: 34.368%; float: left; background: #ccc; @@ -425,49 +519,85 @@ section.week-edit section.sidebar, section.week-new section.sidebar { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } - section.week-edit section.sidebar section, section.week-new section.sidebar section { + section.week-edit section.sidebar section, + section.week-new section.sidebar section, + section.sequence-edit section.sidebar section { height: 50%; } - section.week-edit section.sidebar section > ul, section.week-new section.sidebar section > ul { + section.week-edit section.sidebar section > ul, + section.week-new section.sidebar section > ul, + section.sequence-edit section.sidebar section > ul { list-style: none; } - section.week-edit section.sidebar section > ul > li, section.week-new section.sidebar section > ul > li { + section.week-edit section.sidebar section > ul > li, + section.week-new section.sidebar section > ul > li, + section.sequence-edit section.sidebar section > ul > li { padding: 6px; border-bottom: 1px solid #666; background: #eee; } - section.week-edit section.sidebar section > ul > li.new-module, section.week-new section.sidebar section > ul > li.new-module { + section.week-edit section.sidebar section > ul > li.new-module, + section.week-new section.sidebar section > ul > li.new-module, + section.sequence-edit section.sidebar section > ul > li.new-module { position: relative; } - section.week-edit section.sidebar section > ul > li.new-module ul.new-dropdown, section.week-new section.sidebar section > ul > li.new-module ul.new-dropdown { + section.week-edit section.sidebar section > ul > li.new-module ul.new-dropdown, + section.week-new section.sidebar section > ul > li.new-module ul.new-dropdown, + section.sequence-edit section.sidebar section > ul > li.new-module ul.new-dropdown { list-style: none; } - section.week-edit section.sidebar section > ul > li.new-module ul.new-dropdown li, section.week-new section.sidebar section > ul > li.new-module ul.new-dropdown li { + section.week-edit section.sidebar section > ul > li.new-module ul.new-dropdown li, + section.week-new section.sidebar section > ul > li.new-module ul.new-dropdown li, + section.sequence-edit section.sidebar section > ul > li.new-module ul.new-dropdown li { display: none; } - section.week-edit section.sidebar section > ul > li.new-module ul.new-dropdown li:first-child, section.week-new section.sidebar section > ul > li.new-module ul.new-dropdown li:first-child { + section.week-edit section.sidebar section > ul > li.new-module ul.new-dropdown li:first-child, + section.week-new section.sidebar section > ul > li.new-module ul.new-dropdown li:first-child, + section.sequence-edit section.sidebar section > ul > li.new-module ul.new-dropdown li:first-child { display: block; } - section.week-edit section.sidebar section > ul > li.new-module ul.new-dropdown:hover li, section.week-new section.sidebar section > ul > li.new-module ul.new-dropdown:hover li { + section.week-edit section.sidebar section > ul > li.new-module ul.new-dropdown:hover li, + section.week-new section.sidebar section > ul > li.new-module ul.new-dropdown:hover li, + section.sequence-edit section.sidebar section > ul > li.new-module ul.new-dropdown:hover li { display: block; padding: 6px 0; } - section.week-edit section.sidebar section > ul > li.new-module ul.new-dropdown:hover li:first-child, section.week-new section.sidebar section > ul > li.new-module ul.new-dropdown:hover li:first-child { + section.week-edit section.sidebar section > ul > li.new-module ul.new-dropdown:hover li:first-child, + section.week-new section.sidebar section > ul > li.new-module ul.new-dropdown:hover li:first-child, + section.sequence-edit section.sidebar section > ul > li.new-module ul.new-dropdown:hover li:first-child { padding-top: 0; } - section.week-edit section.sidebar section p, section.week-new section.sidebar section p { + section.week-edit section.sidebar section p, + section.week-new section.sidebar section p, + section.sequence-edit section.sidebar section p { padding: 6px; border-bottom: 1px solid #666; } -section.week-edit section.weeks-content, section.week-new section.weeks-content { +section.week-edit section.weeks-content, +section.week-new section.weeks-content, +section.sequence-edit section.weeks-content { width: 65.632%; float: left; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } - section.week-edit section.weeks-content header, section.week-new section.weeks-content header { + section.week-edit section.weeks-content header, + section.week-new section.weeks-content header, + section.sequence-edit section.weeks-content header { zoom: 1; } - section.week-edit section.weeks-content header:before, section.week-edit section.weeks-content header:after, section.week-new section.weeks-content header:before, section.week-new section.weeks-content header:after { + section.week-edit section.weeks-content header:before, section.week-edit section.weeks-content header:after, + section.week-new section.weeks-content header:before, + section.week-new section.weeks-content header:after, + section.sequence-edit section.weeks-content header:before, + section.sequence-edit section.weeks-content header:after { content: ""; display: table; } - section.week-edit section.weeks-content header:after, section.week-new section.weeks-content header:after { + section.week-edit section.weeks-content header:after, + section.week-new section.weeks-content header:after, + section.sequence-edit section.weeks-content header:after { clear: both; } - section.week-edit section.weeks-content header h2, section.week-new section.weeks-content header h2 { + section.week-edit section.weeks-content header h2, + section.week-new section.weeks-content header h2, + section.sequence-edit section.weeks-content header h2 { float: left; } - section.week-edit section.weeks-content header form, section.week-new section.weeks-content header form { + section.week-edit section.weeks-content header form, + section.week-new section.weeks-content header form, + section.sequence-edit section.weeks-content header form { float: right; margin: -2px 0; } - section.week-edit section.weeks-content header form input, section.week-new section.weeks-content header form input { + section.week-edit section.weeks-content header form input, + section.week-new section.weeks-content header form input, + section.sequence-edit section.weeks-content header form input { border: 1px solid #000; background: #ddd; padding: 2px 4px; @@ -476,18 +606,30 @@ section.week-edit section.weeks-content, section.week-new section.weeks-content -ms-border-radius: 2px; -o-border-radius: 2px; border-radius: 2px; } - section.week-edit section.weeks-content section.filters, section.week-new section.weeks-content section.filters { + section.week-edit section.weeks-content section.filters, + section.week-new section.weeks-content section.filters, + section.sequence-edit section.weeks-content section.filters { border-bottom: 1px solid #999; } - section.week-edit section.weeks-content section.filters ul, section.week-new section.weeks-content section.filters ul { + section.week-edit section.weeks-content section.filters ul, + section.week-new section.weeks-content section.filters ul, + section.sequence-edit section.weeks-content section.filters ul { zoom: 1; list-style: none; padding: 6px; } - section.week-edit section.weeks-content section.filters ul:before, section.week-edit section.weeks-content section.filters ul:after, section.week-new section.weeks-content section.filters ul:before, section.week-new section.weeks-content section.filters ul:after { + section.week-edit section.weeks-content section.filters ul:before, section.week-edit section.weeks-content section.filters ul:after, + section.week-new section.weeks-content section.filters ul:before, + section.week-new section.weeks-content section.filters ul:after, + section.sequence-edit section.weeks-content section.filters ul:before, + section.sequence-edit section.weeks-content section.filters ul:after { content: ""; display: table; } - section.week-edit section.weeks-content section.filters ul:after, section.week-new section.weeks-content section.filters ul:after { + section.week-edit section.weeks-content section.filters ul:after, + section.week-new section.weeks-content section.filters ul:after, + section.sequence-edit section.weeks-content section.filters ul:after { clear: both; } - section.week-edit section.weeks-content section.filters ul li, section.week-new section.weeks-content section.filters ul li { + section.week-edit section.weeks-content section.filters ul li, + section.week-new section.weeks-content section.filters ul li, + section.sequence-edit section.weeks-content section.filters ul li { display: -moz-inline-box; -moz-box-orient: vertical; display: inline-block; @@ -495,95 +637,201 @@ section.week-edit section.weeks-content, section.week-new section.weeks-content zoom: 1; *display: inline; *vertical-align: auto; } - section.week-edit section.weeks-content section.filters ul li.advanced, section.week-new section.weeks-content section.filters ul li.advanced { + section.week-edit section.weeks-content section.filters ul li.advanced, + section.week-new section.weeks-content section.filters ul li.advanced, + section.sequence-edit section.weeks-content section.filters ul li.advanced { float: right; } - section.week-edit section.weeks-content section.modules ul, section.week-new section.weeks-content section.modules ul { + section.week-edit section.weeks-content section.modules ul, + section.week-new section.weeks-content section.modules ul, + section.sequence-edit section.weeks-content section.modules ul { list-style: none; } - section.week-edit section.weeks-content section.modules ul li, section.week-new section.weeks-content section.modules ul li { + section.week-edit section.weeks-content section.modules ul li, + section.week-new section.weeks-content section.modules ul li, + section.sequence-edit section.weeks-content section.modules ul li { padding: 6px; font-weight: bold; font-size: 16px; border-bottom: 1px solid #333; } - section.week-edit section.weeks-content section.modules ul li a, section.week-new section.weeks-content section.modules ul li a { + section.week-edit section.weeks-content section.modules ul li a, + section.week-new section.weeks-content section.modules ul li a, + section.sequence-edit section.weeks-content section.modules ul li a { color: #000; } -section.video-new, section.video-edit { - position: absolute; - top: 80px; - right: 0; - background: #fff; - width: 40.32%; - -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 { - background: #666; +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; - 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 { - content: ""; - display: table; } - section.video-new > header:after, section.video-edit > header:after { - clear: both; } - section.video-new > header h2, section.video-edit > header h2 { - float: left; - font-size: 14px; } - section.video-new > header a, section.video-edit > header a { - float: right; } - section.video-new section ul, section.video-edit section ul { - list-style: none; } - section.video-new section ul li, section.video-edit section ul li { - border-bottom: 1px solid #333; - padding: 10px 25px; } + *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.problem-edit { - position: absolute; - top: 80px; - right: 0; - background: #fff; - width: 40.32%; - -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.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.problem-new > header:before, section.problem-new > header:after, section.problem-edit > header:before, section.problem-edit > header:after { - content: ""; - display: table; } - section.problem-new > header:after, section.problem-edit > header:after { - clear: both; } - section.problem-new > header h2, section.problem-edit > header h2 { - float: left; - font-size: 14px; } - section.problem-new > header a, section.problem-edit > header a { - float: right; } - section.problem-new section ul, section.problem-edit section ul { - list-style: none; } - section.problem-new section ul li, section.problem-edit section ul li { - border-bottom: 1px solid #333; - padding: 10px 25px; } - -body.content section.main-content { - border-left: 2px solid #000; +section.problem-new > section textarea, section.problem-edit > section textarea { -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; } + 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/js/main.js b/cms/static/js/main.js index 45f94849f8..e7bdff0f14 100644 --- a/cms/static/js/main.js +++ b/cms/static/js/main.js @@ -6,96 +6,6 @@ $(document).ready(function(){ $('.editable-textarea').inlineEdit({control: 'textarea'}); }); - // $("a[rel*=leanModal]").leanModal(); - - // $(".remove").click(function(){ - // $(this).parents('li').hide(); - // }); - - // $("#show-sidebar").click(function(){ - // $("#video-selector").toggleClass('hidden'); - // return false; - // }); - - // $('.use-video').click(function() { - // var used = $('#used'); - // if (used.is(':visible')) { - // used.hide().show('slow'); - // } - // used.show(); - // $('.no-video').hide(); - // }); - - // $('.remove-video').click(function() { - // $('#used').hide(); - // $('.no-video').show(); - // }); - - // $('#new-upload').click(function() { - // $('.selected-files').toggle(); - // return false; - // }); - - // /* $('.block').append('✕<\/a>'); */ - - // $('a.delete').click(function() { - // $(this).parents('.block').hide(); - // }); - - // $('.speed-list > li').hover(function(){ - // $(this).children('.tooltip').toggle(); - // }); - - // $('.delete-speed').click(function(){ - // $(this).parents('li.speed').hide(); - // return false; - // }); - - // $('.edit-captions').click(function(){ - // var parentVid = $(this).parents('div'); - // parentVid.siblings('div.caption-box').toggle(); - // return false; - // }); - - // $('.close-box').click(function(){ - // $(this).parents('.caption-box').hide(); - // return false; - // }); - - // $('ul.dropdown').hide(); - // $('li.questions').click(function() { - // $('ul.dropdown').toggle(); - // return false; - // }); - - // $('#mchoice').click(function(){ - // $('div.used').append($('
    ').load("/widgets/multi-choice.html")); - // return false; - // }); - - // $('#text').click(function(){ - // $('div.used').append($('
    ').load("/widgets/text.html")); - // return false; - // }); - - // $('#numerical').click(function(){ - // $('div.used').append($('
    ').load("/widgets/text-question.html")); - // return false; - // }); - - // $('#equation').click(function(){ - // $('div.used').append($('
    ').load("/widgets/latex-equation.html")); - // return false; - // }); - - // $('#script').click(function(){ - // $('div.used').append($('
    ').load("/widgets/script-widget.html")); - // return false; - // }); - - // $("#mark").markItUp(myWikiSettings); - - var heighest = 0; $('.cal ol > li').each(function(){ heighest = ($(this).height() > heighest) ? $(this).height() : heighest; @@ -104,10 +14,7 @@ $(document).ready(function(){ $('.cal ol > li').css('height',heighest + 'px'); - $('.new-week').hide(); - $('.add-new-week').click(function() { - $(this).hide(); - $('.new-week').show(); + $('.add-new-section').click(function() { return false; }); @@ -117,43 +24,63 @@ $(document).ready(function(){ return false; }); - var windowHeight = $(window).resize().height(); - - $('.sidebar').css('height', windowHeight); - - $('.edit-week').click( function() { - $('body').addClass('content'); - $('body.content .cal').css('height', windowHeight); - $('section.week-new').show(); - return false; + $('.save-update').click(function(){ + $(this).parent().parent().hide(); + return false; }); - $('.cal ol li header h1 a').click( function() { - $('body').addClass('content'); - $('body.content .cal').css('height', windowHeight); - $('section.week-edit').show(); - return false; - }); + setHeight = function(){ + var windowHeight = $(this).height(); + var calHeight = windowHeight - 29; + var sidebarHeight = windowHeight - 73; + $('.sidebar').css('height', sidebarHeight); + $('body.content .cal').css('height', calHeight); + + $('.edit-week').click( function() { + $('body').addClass('content'); + $('body.content .cal').css('height', calHeight); + $('section.week-new').show(); + return false; + }); + + $('.cal ol li header h1 a').click( function() { + $('body').addClass('content'); + $('body.content .cal').css('height', calHeight); + $('section.week-edit').show(); + return false; + }); + + $('a.sequence-edit').click(function(){ + $('body').addClass('content'); + $('body.content .cal').css('height', calHeight); + $('section.sequence-edit').show(); + return false; + }); + } + + $(document).ready(setHeight); + $(window).bind('resize', setHeight); $('.video-new a').click(function(){ - $('section.video-new').show(); - return false; + $('section.video-new').show(); + return false; }); - $('.video-edit a').click(function(){ - $('section.video-edit').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; + $('section.problem-new').show(); + return false; }); - $('.problem-edit a').click(function(){ - $('section.problem-edit').show(); - return false; + $('a.problem-edit').click(function(){ + $('section.problem-edit').show(); + return false; }); + }); diff --git a/cms/static/sass/_base.scss b/cms/static/sass/_base.scss index d9f3971d9e..d06998c38a 100644 --- a/cms/static/sass/_base.scss +++ b/cms/static/sass/_base.scss @@ -32,7 +32,22 @@ body { h2 { font-size: 14px; text-transform: uppercase; + float: left; } + + a.new-module { + float: right; + } + } + } + + &.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 ); } } } @@ -48,4 +63,3 @@ input[type="submit"], .button { @include border-radius(3px); padding: 6px; } - diff --git a/cms/static/sass/_calendar.scss b/cms/static/sass/_calendar.scss index b149346ad6..06ac62f549 100644 --- a/cms/static/sass/_calendar.scss +++ b/cms/static/sass/_calendar.scss @@ -7,59 +7,40 @@ section.cal { > header { @include clearfix; margin-bottom: 10px; + background: #efefef; + border: 1px solid #ddd; - h1 { - float: left; - font-size: 18px; + h2 { + @include inline-block(); + text-transform: uppercase; + letter-spacing: 1px; + font-size: 14px; + padding: 6px; + margin-left: 6px; + font-size: 12px; } ul { - float: right; + @include inline-block; li { @include inline-block; + margin-left: 6px; + padding-left: 6px; + border-left: 1px solid #ddd; + padding: 6px; a { - padding: 6px; - border: 1px solid #ddd; - display: block; - @include border-radius(3px); - background: #efefef; + @include inline-block(); } - &.dropdown { - position: relative; + ul { + @include inline-block(); - ul { - display: none; - position: absolute; - background: #fff; - border: 1px solid #ddd; - - li { - padding: 6px; - display: block; - border-top: 1px solid transparent; - border-bottom: 1px solid transparent; - - &:hover { - background-color: #efefef; - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - } - } - } - - &:hover { - - ul { - display: block; - } - - a { - @include border-radius(3px 3px 0 0); - border-bottom: 0; - } + li { + @include inline-block(); + padding: 0; + border-left: 0; } } } @@ -81,91 +62,31 @@ section.cal { float: left; width: flex-grid(3) + ((flex-gutter() * 3) / 4); - &:last-child { - text-align: center; - background: #eee; - @include box-sizing(border-box); - - p { - width: 100%; - height: 100%; - @include box-sizing(border-box); - - a { - display: block; - width: 100%; - height: 100%; - } - } - - section.new-week { - header { - background: #fff; - text-align: left; - } - - form { - background: #fff; - width: 50%; - padding: 6px; - border: 1px solid #000; - margin: 0 auto; - @include box-shadow(0 0 2px #333); - position: relative; - - &:before { - background: #fff; - border-left: 1px solid #000; - border-top: 1px solid #000; - content: " "; - display: block; - height: 10px; - left: 50%; - position: absolute; - top: -6px; - @include transform(rotate(45deg)); - width: 10px; - z-index: 0; - } - - select { - margin-bottom: 6px; - width: 100%; - - option { - padding: 10px 0 !important; - } - } - - input[type="submit"] { - display: block; - margin-bottom: 6px; - width: 100%; - } - - a { - - &:first-child { - float: left; - } - - &:last-child { - float: right; - } - } - } - } - } - header { border-bottom: 1px solid #000; - @include box-shadow(0 1px 2px #ccc); + @include box-shadow(0 1px 2px #aaa); display: block; margin-bottom: 2px; - padding: 6px; 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; + } } } @@ -178,13 +99,136 @@ section.cal { border-bottom: 1px solid #666; padding: 6px; - &.goal { - background: #fff; + &.create-module { + position: relative; + + > div { + display: none; + @include position(absolute, 30px 0 0 0); + width: 90%; + background: rgba(#000, .8); + padding: 10px; + @include box-sizing(border-box); + @include border-radius(3px); + z-index: 99; + + 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; + + > a { + @extend .button; + @include inline-block(); + } + + section { + display: none; + + header { + background: #fff; + text-align: left; + } + + form { + background: #fff; + width: 50%; + padding: 6px; + border: 1px solid #000; + margin: 0 auto; + @include box-shadow(0 0 2px #333); + position: relative; + + &:before { + background: #fff; + border-left: 1px solid #000; + border-top: 1px solid #000; + content: " "; + display: block; + height: 10px; + left: 50%; + position: absolute; + top: -6px; + @include transform(rotate(45deg)); + width: 10px; + z-index: 0; + } + + select { + margin-bottom: 6px; + width: 100%; + + option { + padding: 10px 0 !important; + } + } + + input[type="submit"] { + display: block; + margin-bottom: 6px; + width: 100%; + } + + a { + + &:first-child { + float: left; + } + + &:last-child { + float: right; + } + } + } + } + + &:hover { + section { + display: block; + } + } + } } body.content diff --git a/cms/static/sass/_module-header.scss b/cms/static/sass/_module-header.scss new file mode 100644 index 0000000000..e2af263618 --- /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 index c513ce38d9..66acacf65c 100644 --- a/cms/static/sass/_problem.scss +++ b/cms/static/sass/_problem.scss @@ -1,40 +1,23 @@ section.problem-new, section.problem-edit { - position: absolute; - top: 80px; - right: 0; - background: #fff; - width: flex-grid(5); - @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; + > section { + textarea { + @include box-sizing(border-box); + display: block; + width: 100%; } - a { - float: right; + div.preview { + background: #eee; + @include box-sizing(border-box); + height: 40px; + padding: 10px; + width: 100%; } - } - section { - ul { - list-style: none; - - li { - border-bottom: 1px solid #333; - padding: 10px 25px; - } + a.save { + @extend .button; + @include inline-block(); + margin-top: 20px; } } } diff --git a/cms/static/sass/_video.scss b/cms/static/sass/_video.scss index cb234108f4..b68176e2db 100644 --- a/cms/static/sass/_video.scss +++ b/cms/static/sass/_video.scss @@ -1,40 +1,33 @@ section.video-new, section.video-edit { - position: absolute; - top: 80px; - right: 0; - background: #fff; - width: flex-grid(5); - @include box-shadow(0 0 6px #666); - border: 1px solid #333; - border-right: 0; - z-index: 4; + > section { - > header { - background: #666; - @include clearfix; - color: #fff; - padding: 6px; - border-bottom: 1px solid #333; - -webkit-font-smoothing: antialiased; + section.upload { + padding: 6px; + margin-bottom: 10px; + border: 1px solid #ddd; - h2 { - float: left; - font-size: 14px; - } - - a { - float: right; - } - } - - section { - ul { - list-style: none; - - li { - border-bottom: 1px solid #333; - padding: 10px 25px; + 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 index a628b0f164..1a32557db5 100644 --- a/cms/static/sass/_week.scss +++ b/cms/static/sass/_week.scss @@ -1,4 +1,6 @@ -section.week-edit, section.week-new { +section.week-edit, +section.week-new, +section.sequence-edit { > header { border-bottom: 1px solid #ccc; diff --git a/cms/static/sass/base-style.scss b/cms/static/sass/base-style.scss index 6a2dfbd0d2..133e1bda1b 100644 --- a/cms/static/sass/base-style.scss +++ b/cms/static/sass/base-style.scss @@ -3,16 +3,4 @@ @import 'base'; @import 'calendar'; -@import 'week', 'video', 'problem'; - -body { - &.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 ); - } - } -} +@import 'week', 'video', 'problem', 'module-header'; diff --git a/cms/templates/index.html b/cms/templates/index.html index efd9f9a242..11c226ae3d 100644 --- a/cms/templates/index.html +++ b/cms/templates/index.html @@ -9,6 +9,7 @@
    <%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"/> diff --git a/cms/templates/widgets/header.html b/cms/templates/widgets/header.html index 86a2afb0f9..ec550fec37 100644 --- a/cms/templates/widgets/header.html +++ b/cms/templates/widgets/header.html @@ -1,5 +1,6 @@
    diff --git a/cms/templates/widgets/module-dropdown.html b/cms/templates/widgets/module-dropdown.html new file mode 100644 index 0000000000..7c6e1e068c --- /dev/null +++ b/cms/templates/widgets/module-dropdown.html @@ -0,0 +1,28 @@ +
  • + + + Add new module + +
    +
    + +
    +
    +
  • diff --git a/cms/templates/widgets/navigation.html b/cms/templates/widgets/navigation.html index 049e5da537..2edef08a12 100644 --- a/cms/templates/widgets/navigation.html +++ b/cms/templates/widgets/navigation.html @@ -1,9 +1,8 @@
    -

    Circuts & Electronics

    - +

    Filter content:

      -
    • Sequences
        @@ -17,9 +16,20 @@
      • Deadlines + +
          +
        • Today
        • +
        • Tomorrow
        • +
        • This week
        • +
        • In 2 weeks
        • +
        • This month
        • +
      • Goals +
          +
        • Hide
        • +
    @@ -28,93 +38,131 @@
  • Week 1

    +
      +
    • Goal title: This is a goal that will be in the header of the week
    • +
    • Goal title two: This is another fgoal for this week so that students have two things to learn
    • +
      -
    • Goal 1
    • -
    • Goal 2
    • -
    • Lecture Sequence
    • -
    • Lecture Sequence
    • -
    • Lab
    • +
    • Lecture Sequence
    • +
    • Lecture Sequence
    • +
    • Lab
    • Homework
    • -
    • + Add new sequence
    • + <%include file="module-dropdown.html"/>
  • Week 2

    +
      +
    • Another title This is the goal for the week
    • +
      -
    • Goal 1
    • Lecture Sequence
    • Lecture Sequence
    • Lab
    • Homework
    • -
    • + Add new sequence
    • + <%include file="module-dropdown.html"/>
  • Week 3

    +
      +
    • Another title This is the goal for the week
    • +
      -
    • Goal 1
    • Lab
    • Lab
    • Homework
    • -
    • + Add new sequence
    • + <%include file="module-dropdown.html"/>
  • Week 4

    +
      +
    • Another title This is the goal for the week
    • +
    • Goal title two: This is another fgoal for this week so that students have two things to learn
    • +
      -
    • Goal 1
    • Lecture Sequence
    • Lab
    • Homework
    • Homework
    • -
    • + Add new sequence
    • + <%include file="module-dropdown.html"/>
  • Week 5

    +
      +
    • Please create a learning goal for this week
    • +
      -
    • + Add new sequence
    • + <%include file="module-dropdown.html"/>
  • -

    - + Add New -

    +
    +

    Week 6

    +
      +
    • Please create a learning goal for this week
    • +
    +
    -
    -
    -

    Week 6

    -
    +
      + <%include file="module-dropdown.html"/> +
    +
  • +
  • +
    +

    Week 7

    +
      +
    • Please create a learning goal for this week
    • +
    +
    -
    - -
    +
      + <%include file="module-dropdown.html"/> +
    +
  • + + +
    + + Add New Section + +
    + +
    - - - - + + + + + diff --git a/cms/templates/widgets/new-module.html b/cms/templates/widgets/new-module.html index 070b6462bb..6b7794944a 100644 --- a/cms/templates/widgets/new-module.html +++ b/cms/templates/widgets/new-module.html @@ -1,9 +1,7 @@ -
  • - -
  • + diff --git a/cms/templates/widgets/problem-edit.html b/cms/templates/widgets/problem-edit.html index b1d5796a9f..49f67e3e26 100644 --- a/cms/templates/widgets/problem-edit.html +++ b/cms/templates/widgets/problem-edit.html @@ -1,34 +1,13 @@ -
    +
    - cancel - Save & Update + Cancel + Save & Update
    -

    Old Problem

    -
    - - -
    - Settings -
    - - -
    -
    -
    -

    Tags:

    -

    Click to edit

    -
    - +

    New Problem

    +

    Last modified:

    mm/dd/yy

    @@ -39,6 +18,31 @@

    Anant Agarwal

    + +
    + + Settings + + +
    +
    +
    +

    Tags:

    +

    Click to edit

    +
    + +
    +

    Goal

    +

    Click to edit

    +
    +
    @@ -49,6 +53,10 @@
    +

    Add notes

    + + +
    • 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.

      @@ -58,16 +66,8 @@

      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.

      Anant Agarwal

    • -
    +
    -
    -

    Add notes

    - - -
    -
    - - Save & Update + Save & Update
    - diff --git a/cms/templates/widgets/problem-new.html b/cms/templates/widgets/problem-new.html index 9f91dd1177..d986f5a9ef 100644 --- a/cms/templates/widgets/problem-new.html +++ b/cms/templates/widgets/problem-new.html @@ -1,39 +1,36 @@
    - cancel - Save & Update + Cancel + Save & Update
    -

    New Problem

    -
    +

    New Problem

    + +
    - Settings + Settings +
    -
    +

    Tags:

    Click to edit

    - - - - - - - - - +
    +

    Goal

    +

    Click to edit

    +
    @@ -45,8 +42,10 @@

    Add notes

    + +
    - Save & Update + Save & Update
    diff --git a/cms/templates/widgets/sequnce-edit.html b/cms/templates/widgets/sequnce-edit.html new file mode 100644 index 0000000000..75d4504b68 --- /dev/null +++ b/cms/templates/widgets/sequnce-edit.html @@ -0,0 +1,85 @@ +<%block name="content"> +
    +
    + Done +

    Lecture Sequence name

    + Settings +
    + + + +
    +
    +

    Sequence Content

    +
    + +
    +
    + +
    +
      +
    • + + +
    • + +
    • + + +
    • +
    • + +
    • + +
    • + Advanced filters +
    • +
    +
    + +
    + +
    +
    +
    + + diff --git a/cms/templates/widgets/video-edit.html b/cms/templates/widgets/video-edit.html index ac4c921918..0c82e743fe 100644 --- a/cms/templates/widgets/video-edit.html +++ b/cms/templates/widgets/video-edit.html @@ -1,151 +1,59 @@ -
    +
    +
    + Cancel + Save & Update +
    -
    -
    +
    +
    +

    Untitled Video

    -
    -
    - Created 22/03/12 - by Piotr Mitros -
    +
    +
    -
    -
    -

    Video title

    + Settings -
    - Tag mitx, s4v1, circuits, anant -
    + +
    -
    -
    - Keyword - S4V1 - +
    +
    +

    Tags:

    +

    Click to edit

    +
    +
    +

    Goal

    +

    mitx, s4v1, circuits, anant

    +
    +
    + - Due Date - 21/03/12 - - Status - - - -
    - -
    - -
    -
    -
    - or - use an already uploaded one -
    -
    - -
    -
    -
      -
    • video-name-@0-75x.extension
    • -
    • video-name-@1x.extension
    • -
    • video-name-@1-25x.extension
    • -
    • video-name-@1-5x.extension
    • -
    -
    - - - Cancel -
    - -
    - -
    -
    -
      -

      Video clip in use

      - <%include file="video-box.html"/> -
    -

    No video clip used. Select one from the list below, upload a new one or import an already uploaded video.

    -
    -
    - -
    -
    - - -
    -
    -
      - <%include file="video-box-unused.html"/> -
    -
    -
    - -
    - -
    -

    Annotations

    - - -
    - +
    + Upload new video clip + Or + use an already uploaded one
    - -
    -
    -

    Notes

    - - - -
    - -
    -
    -
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. -

    By Piotr Mitros 10 hours ago

    -
    -
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.

    By Piotr Mitros 10 hours ago

    -
    -
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.

    By Piotr Mitros 10 hours ago

    +
    +

    Video in use

    +
    +

    No video clip used. Select one from the list below, upload a new one or import already existing video

    -
    - +
    +

    Add notes

    + + +
    -
    - -
    - Select the source video or directly enter its ID -
    - -
    - -
    - -
    - - - Cancel -
    + Save & Update
    +
    diff --git a/cms/templates/widgets/video-new.html b/cms/templates/widgets/video-new.html index 2555169c05..fecbaa423c 100644 --- a/cms/templates/widgets/video-new.html +++ b/cms/templates/widgets/video-new.html @@ -1,48 +1,85 @@
    - cancel - Save & Update + Cancel + Save & Update

    Untitled Video

    -
    -
    -
    - -
    -
    - Save & Update +
    + Upload new video clip + Or + use an already uploaded one + +
    +
    +
      +
    • video-name-@0-75x.extension
    • +
    • video-name-@1x.extension
    • +
    • video-name-@1-25x.extension
    • +
    • video-name-@1-5x.extension
    • +
    +
    + + + Cancel +
    + +
    +

    Video in use

    +
    +

    No video clip used. Select one from the list below, upload a new one or import already existing video

    +
    +
    + +
    +

    Add notes

    + + +
    + + Save & Update
    diff --git a/cms/templates/widgets/week-edit.html b/cms/templates/widgets/week-edit.html index ea6d29ef3b..348185be80 100644 --- a/cms/templates/widgets/week-edit.html +++ b/cms/templates/widgets/week-edit.html @@ -1,37 +1,20 @@ -<%block name="content">

    Week 3

    - Done +

    + new goal

    + +
    +

    Weeks goals:

    +
      +
    • +

      Goal title

      +

      This is the goal body

      +
    • +
    +
    -
    @@ -70,14 +53,55 @@
    + +
    +
    +

    Scratchpad

    +
    + +
      +
    • Problem title 11
    • +
    • Problem title 13
    • +
    • Problem title 14
    • +
    • Video 3
    • + <%include file="new-module.html"/> +
    +
    - diff --git a/cms/templates/widgets/week-new.html b/cms/templates/widgets/week-new.html index 986dc6e05e..fe286a74b3 100644 --- a/cms/templates/widgets/week-new.html +++ b/cms/templates/widgets/week-new.html @@ -1,62 +1,86 @@ -<%block name="content">

    Week 6

    - Done -
    +

    + new goal

    -
    diff --git a/cms/templates/widgets/week-new.html b/cms/templates/widgets/week-new.html index fe286a74b3..46aba9b778 100644 --- a/cms/templates/widgets/week-new.html +++ b/cms/templates/widgets/week-new.html @@ -1,10 +1,13 @@

    Week 6

    -

    + new goal

    -

    Weeks goals:

    +
    +

    Weeks goals:

    +

    +

    +
    +
    • Create new goal

      @@ -40,32 +43,32 @@
    • -
      - -
      +
      + +
    -
    -
    -
    -

    Scratch pad

    -
    +
    -
      -
    • - <%include file="new-module.html"/> -
    • -
    -
    +
    +
    +

    Weeks Content

    +
    +
    -
    -
    -

    Weeks Content

    -
    +
    +
    +

    Scratch pad

    +
    -
    +
      +
    • + <%include file="new-module.html"/> +
    • +
    +
    @@ -83,4 +86,5 @@ New Lab +
    From 6fee7928fc9961c08fbcbc7f7f35631a71ffbacf Mon Sep 17 00:00:00 2001 From: Calen Pennington Date: Thu, 14 Jun 2012 16:15:50 -0400 Subject: [PATCH 10/21] Successfully read course children out of mongodb --- .../management/commands/import.py | 29 +++++---- cms/djangoapps/contentstore/views.py | 5 +- cms/lib/keystore/__init__.py | 34 ++++++++++ cms/lib/keystore/exceptions.py | 4 ++ cms/lib/keystore/mongo.py | 63 ++++++++++++++++--- 5 files changed, 109 insertions(+), 26 deletions(-) diff --git a/cms/djangoapps/contentstore/management/commands/import.py b/cms/djangoapps/contentstore/management/commands/import.py index 78984f4119..690e3dbea0 100644 --- a/cms/djangoapps/contentstore/management/commands/import.py +++ b/cms/djangoapps/contentstore/management/commands/import.py @@ -6,11 +6,13 @@ #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 contentstore.models import create_item, update_item, update_children +from keystore.django import keystore from lxml import etree @@ -20,16 +22,15 @@ class Command(BaseCommand): def handle(self, *args, **options): print args data_dir = args[0] - course_file = 'course.xml' parser = etree.XMLParser(remove_comments = True) lookup = TemplateLookup(directories=[data_dir]) template = lookup.get_template("course.xml") course_string = template.render(groups=[]) - course = etree.XML(course_string, parser=parser) + course = etree.parse(StringIO(course_string), parser=parser) - elements = course.xpath("//*") + elements = list(course.iter()) tag_to_category = {# Inside HTML ==> Skip these # Custom tags @@ -39,11 +40,11 @@ class Command(BaseCommand): 'image': 'Custom', 'discuss': 'Custom', # Simple lists - 'chapter': 'Sequence', - 'course': 'Sequence', - 'sequential': 'Sequence', - 'vertical': 'Sequence', - 'section': 'Sequence', + 'chapter': 'Chapter', + 'course': 'Course', + 'sequential': 'LectureSequence', + 'vertical': 'ProblemSet', + 'section': 'Section', # True types 'video': 'VideoSegment', 'html': 'HTML', @@ -114,7 +115,7 @@ class Command(BaseCommand): results[e.attrib['url']] = {'data':{'text':text}} def handle_problem(e): - data = open(data_dir+'problems/'+e.attrib['filename']+'.xml').read() + 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 @@ -149,10 +150,8 @@ class Command(BaseCommand): for k in results: print k - create_item(k, 'Piotr Mitros') + keystore.create_item(k, 'Piotr Mitros') if 'data' in results[k]: - update_item(k, results[k]['data']) + keystore.update_item(k, results[k]['data']) if 'children' in results[k]: - update_children(k, results[k]['children']) - - + keystore.update_children(k, results[k]['children']) diff --git a/cms/djangoapps/contentstore/views.py b/cms/djangoapps/contentstore/views.py index 38e9e8ad35..429fb6c26b 100644 --- a/cms/djangoapps/contentstore/views.py +++ b/cms/djangoapps/contentstore/views.py @@ -1,14 +1,11 @@ from mitxmako.shortcuts import render_to_response -from keystore import Location from keystore.django import keystore from django.contrib.auth.decorators import login_required @login_required def calendar(request, org, course): - weeks = keystore.get_children_for_item( - Location(['i4x', org, course, 'Course', 'course']) - ) + weeks = keystore.get_children_for_item(['i4x', org, course, 'Course', None]) return render_to_response('calendar.html', {'weeks': weeks}) diff --git a/cms/lib/keystore/__init__.py b/cms/lib/keystore/__init__.py index 5e6374cf4a..d0a24be797 100644 --- a/cms/lib/keystore/__init__.py +++ b/cms/lib/keystore/__init__.py @@ -60,6 +60,40 @@ class KeyStore(object): with the specified 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 diff --git a/cms/lib/keystore/exceptions.py b/cms/lib/keystore/exceptions.py index b66470859f..08fd9b11d0 100644 --- a/cms/lib/keystore/exceptions.py +++ b/cms/lib/keystore/exceptions.py @@ -5,3 +5,7 @@ Exceptions thrown by KeyStore objects class ItemNotFoundError(Exception): pass + + +class InsufficientSpecificationError(Exception): + pass diff --git a/cms/lib/keystore/mongo.py b/cms/lib/keystore/mongo.py index fc190ee098..d29afb4bd2 100644 --- a/cms/lib/keystore/mongo.py +++ b/cms/lib/keystore/mongo.py @@ -1,6 +1,6 @@ import pymongo -from . import KeyStore -from .exceptions import ItemNotFoundError +from . import KeyStore, Location +from .exceptions import ItemNotFoundError, InsufficientSpecificationError class MongoKeyStore(KeyStore): @@ -12,15 +12,64 @@ class MongoKeyStore(KeyStore): host=host, port=port )[db][collection] + + # Force mongo to report errors, at the expense of performance + self.collection.safe = True def get_children_for_item(self, location): - item = self.collection.find_one( - {'location': location.dict()}, + 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, fields={'children': True}, sort=[('revision', pymongo.ASCENDING)], + limit=1, + ) + if items.count() > 1: + raise InsufficientSpecificationError(location) + + if items.count() == 0: + raise ItemNotFoundError(location) + + return items[0]['children'] + + 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}} ) - if item is None: - raise ItemNotFoundError() + def update_children(self, location, children): + """ + Set the children for the item specified by the location to + data - return item['children'] + 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}} + ) From 57b605dbd3a791c3c73392f185df5e1e86b89ed1 Mon Sep 17 00:00:00 2001 From: Kyle Fiedler Date: Thu, 14 Jun 2012 17:15:23 -0400 Subject: [PATCH 11/21] Added more styels to the section view and default section view --- cms/static/css/base-style.css | 170 +++++++++++++++++++------- cms/static/img/drag-handle.png | Bin 0 -> 98 bytes cms/static/sass/_base.scss | 47 ++++++- cms/static/sass/_calendar.scss | 6 + cms/static/sass/_week.scss | 99 +++++++++------ cms/templates/widgets/header.html | 19 ++- cms/templates/widgets/new-module.html | 2 +- cms/templates/widgets/week-edit.html | 42 +++++-- cms/templates/widgets/week-new.html | 93 +++++++------- 9 files changed, 336 insertions(+), 142 deletions(-) create mode 100644 cms/static/img/drag-handle.png diff --git a/cms/static/css/base-style.css b/cms/static/css/base-style.css index c84ab046ff..c4bfc6c415 100644 --- a/cms/static/css/base-style.css +++ b/cms/static/css/base-style.css @@ -193,8 +193,19 @@ body { font-size: 14px; text-transform: uppercase; float: left; } - body > header nav a.new-module { - float: right; } + 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; @@ -213,7 +224,11 @@ a { 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.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 { +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; @@ -223,6 +238,26 @@ input[type="submit"], .button, section.cal section.new-section > a, section.vide 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; } + section.cal { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; @@ -484,11 +519,35 @@ section.cal { overflow: scroll; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; - 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; @@ -637,6 +696,22 @@ section.sequence-edit > section.content { 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 { @@ -661,17 +736,27 @@ section.sequence-edit > section.content { 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 0 6px 6px; } - section.week-edit > section.content > div section.modules ol li ol li h3, - section.week-new > section.content > div section.modules ol li ol li h3, - section.sequence-edit > section.content > div section.modules ol li ol li h3 { - text-transform: uppercase; - letter-spacing: 1px; - font-size: 12px; } - section.week-edit > section.content > div section.modules ol li ol li ol, - section.week-new > section.content > div section.modules ol li ol li ol, - section.sequence-edit > section.content > div section.modules ol li ol li ol { - border-left: 1px solid; } + padding: 6px; } + 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; + border-left: 4px solid #999; } + 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: 3px 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 { + text-transform: uppercase; + letter-spacing: 1px; + font-size: 12px; } + 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 { @@ -679,7 +764,8 @@ section.sequence-edit > section.content { -moz-box-sizing: border-box; box-sizing: border-box; display: table-cell; - width: 34.368%; } + 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 { @@ -702,40 +788,32 @@ section.sequence-edit > section.content { 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.week-edit > section.content > div section.scratch-pad ol li.new-module, - section.week-new > section.content > div section.scratch-pad ol li.new-module, - section.sequence-edit > section.content > div section.scratch-pad ol li.new-module { - position: relative; } - section.week-edit > section.content > div section.scratch-pad ol li.new-module ul.new-dropdown, - section.week-new > section.content > div section.scratch-pad ol li.new-module ul.new-dropdown, - section.sequence-edit > section.content > div section.scratch-pad ol li.new-module ul.new-dropdown { - list-style: none; } - section.week-edit > section.content > div section.scratch-pad ol li.new-module ul.new-dropdown li, - section.week-new > section.content > div section.scratch-pad ol li.new-module ul.new-dropdown li, - section.sequence-edit > section.content > div section.scratch-pad ol li.new-module ul.new-dropdown li { - display: none; } - section.week-edit > section.content > div section.scratch-pad ol li.new-module ul.new-dropdown li:first-child, - section.week-new > section.content > div section.scratch-pad ol li.new-module ul.new-dropdown li:first-child, - section.sequence-edit > section.content > div section.scratch-pad ol li.new-module ul.new-dropdown li:first-child { - display: block; } - section.week-edit > section.content > div section.scratch-pad ol li.new-module ul.new-dropdown:hover li, - section.week-new > section.content > div section.scratch-pad ol li.new-module ul.new-dropdown:hover li, - section.sequence-edit > section.content > div section.scratch-pad ol li.new-module ul.new-dropdown:hover li { - display: block; - padding: 6px 0; } - section.week-edit > section.content > div section.scratch-pad ol li.new-module ul.new-dropdown:hover li:first-child, - section.week-new > section.content > div section.scratch-pad ol li.new-module ul.new-dropdown:hover li:first-child, - section.sequence-edit > section.content > div section.scratch-pad ol li.new-module ul.new-dropdown:hover li:first-child { - padding-top: 0; } - section.week-edit > section.content > div section.scratch-pad p, - section.week-new > section.content > div section.scratch-pad p, - section.sequence-edit > section.content > div section.scratch-pad p { - padding: 6px; - border-bottom: 1px solid #666; } section.video-new > section section.upload, section.video-edit > section section.upload { padding: 6px; diff --git a/cms/static/img/drag-handle.png b/cms/static/img/drag-handle.png new file mode 100644 index 0000000000000000000000000000000000000000..3c9c3c1ebcee37ec1fcfd82aa204228ecd629598 GIT binary patch literal 98 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)N!3HEB$FfNSDNRoo$B>F!Z+i`a$~c&!Yh(WZ v_v73tWm2xNh|g`ZvcZL`KR=$S&zsN6c8$yMo{i8-pe6=SS3j3^P6 header ul { display: none; } + &:hover { + opacity: 1; + } + ol { li { @include box-sizing(border-box); diff --git a/cms/static/sass/_week.scss b/cms/static/sass/_week.scss index 1c03ff7962..de7b1e6f9e 100644 --- a/cms/static/sass/_week.scss +++ b/cms/static/sass/_week.scss @@ -86,6 +86,17 @@ section.sequence-edit { 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; @@ -105,16 +116,30 @@ section.sequence-edit { list-style: none; li { - padding: 6px 0 6px 6px; + padding: 6px; - h3 { - text-transform: uppercase; - letter-spacing: 1px; - font-size: 12px; - } + &.group { + padding: 0; + border-left: 4px solid #999; - ol { - border-left: 1px solid; + header { + padding: 3px 6px; + background: none; + + h3 { + text-transform: uppercase; + letter-spacing: 1px; + font-size: 12px; + } + } + + ol { + li { + &:last-child { + border-bottom: 0; + } + } + } } } } @@ -126,6 +151,7 @@ section.sequence-edit { @include box-sizing(border-box); display: table-cell; width: flex-grid(3, 9) + flex-gutter(9); + vertical-align: top; ol { list-style: none; @@ -145,48 +171,41 @@ section.sequence-edit { 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; } } } - &.new-module { - position: relative; - - ul.new-dropdown { - list-style: none; - - li { - display: none; - - &:first-child { - display: block; - } - } - - &:hover { - li { - display: block; - padding: 6px 0; - - &:first-child { - padding-top: 0; - } - } - } - } - } } } - - p { - padding: 6px; - border-bottom: 1px solid #666; - } } } } } } - diff --git a/cms/templates/widgets/header.html b/cms/templates/widgets/header.html index ec550fec37..49965e4026 100644 --- a/cms/templates/widgets/header.html +++ b/cms/templates/widgets/header.html @@ -1,6 +1,21 @@
    diff --git a/cms/templates/widgets/new-module.html b/cms/templates/widgets/new-module.html index 6b7794944a..8b12e5763a 100644 --- a/cms/templates/widgets/new-module.html +++ b/cms/templates/widgets/new-module.html @@ -1,5 +1,5 @@ ++ add new
      -
    1. Problem title 11
    2. -
    3. Problem title 13
    4. -
    5. Problem title 14
    6. -
    7. Video 3
    8. +
    9. + Problem title 11 + handle +
    10. +
    11. + Problem Group + handle +
    12. +
    13. + Problem title 14 + handle +
    14. +
    15. + Video 3 + handle +
  • @@ -68,7 +80,7 @@
      -
    1. +
    2. Problem group @@ -97,10 +109,22 @@

        -
      1. Problem title 11
      2. -
      3. Problem title 13
      4. -
      5. Problem title 14
      6. -
      7. Video 3
      8. +
      9. + Problem title 11 + handle +
      10. +
      11. + Problem Group + handle +
      12. +
      13. + Problem title 14 + handle +
      14. +
      15. + Video 3 + handle +
    3. diff --git a/cms/templates/widgets/week-new.html b/cms/templates/widgets/week-new.html index 46aba9b778..be08587755 100644 --- a/cms/templates/widgets/week-new.html +++ b/cms/templates/widgets/week-new.html @@ -1,23 +1,23 @@
      -

      Week 6

      +

      Week 3

      Weeks goals:

      -

      +

      +

      + new goal

      • -

        Create new goal

        -

        Goals are overarching themes for the week

        +

        Please add a goal for this section

      -
      +
      +
      • @@ -43,48 +43,59 @@
      • -
        - -
        +
      - -
      - -
      -
      -

      Weeks Content

      -
      +
      +
      +

      This are no groups or units in this section yet

      + Add a Group + Add a Unit
      -
      -
      -

      Scratch pad

      -
      +
      +
        +
      1. +
        +

        Section Scratch

        +
        + +
      2. +
      3. +
        +

        Course Scratch

        +
        + +
      4. -
          -
        • - <%include file="new-module.html"/> -
        • -
        -
      +
    4. + <%include file="new-module.html"/> +
    5. +
  • - -
    - +
    + From 93478d53dfa65008a09be1a62d79744b1bc2bc45 Mon Sep 17 00:00:00 2001 From: Kyle Fiedler Date: Fri, 15 Jun 2012 10:11:04 -0400 Subject: [PATCH 12/21] Added scratch on the calendar view and added handles on the calendar view --- cms/static/css/base-style.css | 52 +++-- cms/static/sass/_base.scss | 2 + cms/static/sass/_week.scss | 33 ++- cms/templates/widgets/navigation.html | 100 ++++++-- cms/templates/widgets/week-edit.html | 317 +++++++++++++++----------- 5 files changed, 329 insertions(+), 175 deletions(-) diff --git a/cms/static/css/base-style.css b/cms/static/css/base-style.css index c4bfc6c415..abed82cc05 100644 --- a/cms/static/css/base-style.css +++ b/cms/static/css/base-style.css @@ -256,7 +256,9 @@ section.sequence-edit > section.content > div section.scratch-pad ol li ul li.em width: 7px; min-height: 14px; background: url("../img/drag-handle.png") no-repeat center; - text-indent: -9999px; } + text-indent: -9999px; + display: block; + float: right; } section.cal { -webkit-box-sizing: border-box; @@ -679,14 +681,27 @@ section.sequence-edit > section.content { section.week-new > section.content > div section header, section.sequence-edit > section.content > div section header { background: #eee; - padding: 10px; - border-bottom: 1px solid #ccc; } + 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; } + 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 { @@ -737,26 +752,37 @@ section.sequence-edit > section.content { 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; - border-left: 4px solid #999; } + 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: 3px 6px; + 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 { - text-transform: uppercase; - letter-spacing: 1px; - font-size: 12px; } - 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 { + 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 { diff --git a/cms/static/sass/_base.scss b/cms/static/sass/_base.scss index 4bc24e662f..3a2ef86363 100644 --- a/cms/static/sass/_base.scss +++ b/cms/static/sass/_base.scss @@ -108,4 +108,6 @@ input[type="submit"], .button { 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/_week.scss b/cms/static/sass/_week.scss index de7b1e6f9e..e5283cbc55 100644 --- a/cms/static/sass/_week.scss +++ b/cms/static/sass/_week.scss @@ -67,16 +67,19 @@ section.sequence-edit { display: table; border: 1px solid; width: 100%; + section { header { background: #eee; - padding: 10px; + padding: 6px; border-bottom: 1px solid #ccc; + @include clearfix; h2 { text-transform: uppercase; letter-spacing: 1px; font-size: 12px; + float: left; } } @@ -118,22 +121,34 @@ section.sequence-edit { li { padding: 6px; + &:hover { + a.draggable { + opacity: 1; + } + } + + a.draggable { + float: right; + opacity: .5; + } + &.group { padding: 0; - border-left: 4px solid #999; header { - padding: 3px 6px; + padding: 6px; background: none; h3 { - text-transform: uppercase; - letter-spacing: 1px; - font-size: 12px; + font-size: 14px; } } + ol { + border-left: 4px solid #999; + border-bottom: 0; + li { &:last-child { border-bottom: 0; @@ -185,9 +200,9 @@ section.sequence-edit { padding: 12px; a { - @extend .button; - display: block; - text-align: center; + @extend .button; + display: block; + text-align: center; } } diff --git a/cms/templates/widgets/navigation.html b/cms/templates/widgets/navigation.html index 808c569e74..28b92979d9 100644 --- a/cms/templates/widgets/navigation.html +++ b/cms/templates/widgets/navigation.html @@ -45,10 +45,22 @@ @@ -61,10 +73,22 @@ @@ -77,9 +101,19 @@ @@ -93,10 +127,22 @@ @@ -137,6 +183,30 @@ <%include file="module-dropdown.html"/> +
  • +
    +

    Course Scratch Pad

    +
    + + +
  • diff --git a/cms/templates/widgets/week-edit.html b/cms/templates/widgets/week-edit.html index 6e59c44468..2e37520fde 100644 --- a/cms/templates/widgets/week-edit.html +++ b/cms/templates/widgets/week-edit.html @@ -10,160 +10,201 @@
    • -

      Goal title: This is the goal body and is wehre the goal will be further explained

      +

      Goal title: This is the goal body and is where the goal will be further explained

    -
    -
      -
    • - - -
    • - -
    • - - -
    • -
    • - -
    • - -
    • - Advanced filters -
    • - -
    • - -
    • -
    -
    -
    -
    -
      +
      +
    +
    -
    -
      -
    1. -
      -

      Section Scratch

      -
      -
        -
      • Problem title 11
      • -
      • Problem title 13
      • -
      • Problem title 14
      • -
      • Video 3
      • -
      -
    2. -
    3. -
      -

      Course Scratch

      -
      -
        -
      • Problem title 11
      • -
      • Problem title 13
      • -
      • Problem title 14
      • -
      • Video 3
      • -
      -
    4. +
      +
      +
        +
      1. +
        +

        Lecture Sequence

        + handle +
        -
      2. - <%include file="new-module.html"/> -
      3. -
      -
      +
        +
      1. + Problem title 11 + handle +
      2. +
      3. + Problem Group + handle +
      4. +
      5. + Problem title 14 + handle +
      6. +
      7. + Video 3 + handle +
      8. +
      + +
    5. +
      +

      Lecture Sequence

      + handle +
      + +
        +
      1. +
        +

        + Problem group + handle +

        +
        +
          +
        1. + Problem title 11 + handle +
        2. +
        3. + Problem title 11 + handle +
        4. +
        5. + Problem title 11 + handle +
        6. +
        +
      2. +
      3. + Problem title 13 + handle +
      4. +
      5. + Problem title 14 + handle +
      6. +
      7. + Video 3 + handle +
      8. +
      +
    6. +
    7. +
      +

      Homework 1a

      +
      + +
        +
      1. + Problem title 11 + handle +
      2. +
      3. + Problem Group + handle +
      4. +
      5. + Problem title 14 + handle +
      6. +
      7. + Video 3 + handle +
      8. +
      +
    8. + + + + +
    +
    + +
    +
      +
    1. +
      +

      Section Scratch

      +
      + +
    2. +
    3. +
      +

      Course Scratch

      +
      + + +
    4. + + + + +
    +
    From cb1f6838ba3dc6dd00d0f4baad98b9fe5bc76a47 Mon Sep 17 00:00:00 2001 From: Kyle Fiedler Date: Fri, 15 Jun 2012 13:27:24 -0400 Subject: [PATCH 13/21] Added more styles and markup for sequence --- cms/static/css/base-style.css | 112 +++++++++---- cms/static/sass/_calendar.scss | 2 +- cms/static/sass/_week.scss | 68 +++++--- cms/templates/widgets/sequnce-edit.html | 204 ++++++++++++++++++------ cms/templates/widgets/week-edit.html | 129 +++++++++++++-- cms/templates/widgets/week-new.html | 10 +- 6 files changed, 407 insertions(+), 118 deletions(-) diff --git a/cms/static/css/base-style.css b/cms/static/css/base-style.css index abed82cc05..9ebc6bd839 100644 --- a/cms/static/css/base-style.css +++ b/cms/static/css/base-style.css @@ -460,7 +460,7 @@ section.cal { section.cal section.new-section section { display: none; position: absolute; - top: 32px; + top: 30px; background: rgba(0, 0, 0, 0.8); min-width: 300px; padding: 10px; @@ -575,46 +575,96 @@ section.sequence-edit > header { section.week-new > header:after, section.sequence-edit > header:after { clear: both; } - section.week-edit > header h1, - section.week-new > header h1, - section.sequence-edit > header h1 { - font-size: 18px; - margin: 8px 6px; - text-transform: uppercase; - letter-spacing: 1px; } + 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; + padding: 6px 20px; border-top: 1px solid #ccc; } - section.week-edit > header section.goals header h2, - section.week-new > header section.goals header h2, - section.sequence-edit > header section.goals header 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.week-edit > header section.goals header p, - section.week-new > header section.goals header p, - section.sequence-edit > header section.goals header p { - 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 section.goals ul, section.week-new > header section.goals ul, section.sequence-edit > header section.goals ul { list-style: none; - margin-top: 6px; 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 { diff --git a/cms/static/sass/_calendar.scss b/cms/static/sass/_calendar.scss index ca91337366..fa10c65950 100644 --- a/cms/static/sass/_calendar.scss +++ b/cms/static/sass/_calendar.scss @@ -176,7 +176,7 @@ section.cal { section { display: none; - @include position(absolute, 32px 0 0 0); + @include position(absolute, 30px 0 0 0); background: rgba(#000, .8); min-width: 300px; padding: 10px; diff --git a/cms/static/sass/_week.scss b/cms/static/sass/_week.scss index e5283cbc55..b638a36f5c 100644 --- a/cms/static/sass/_week.scss +++ b/cms/static/sass/_week.scss @@ -6,34 +6,64 @@ section.sequence-edit { border-bottom: 2px solid #333; @include clearfix(); - h1 { - font-size: 18px; - margin: 8px 6px; - text-transform: uppercase; - letter-spacing: 1px; + 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; + padding: 6px 20px; border-top: 1px solid #ccc; - header { - h2 { - font-size: 14px; - @include inline-block(); - } - - p { - @include inline-block(); - } - - } - ul { list-style: none; - margin-top: 6px; color: #999; + + li { + margin-bottom: 6px; + + &:last-child { + margin-bottom: 0; + } + } } } } diff --git a/cms/templates/widgets/sequnce-edit.html b/cms/templates/widgets/sequnce-edit.html index 75d4504b68..b69b523bc4 100644 --- a/cms/templates/widgets/sequnce-edit.html +++ b/cms/templates/widgets/sequnce-edit.html @@ -1,47 +1,20 @@ -<%block name="content">
    - Done -

    Lecture Sequence name

    - Settings +
    +

    Week 1

    +
      +
    • +

      Goal title: This is the goal body and is where the goal will be further explained

      +
    • +
    +
    +
    +

    Lecture sequence

    +

    Group type: Ordered Sequence

    +
    - - -
    -
    -

    Sequence Content

    -
    - -
    -
    - +
    -
    - -
    +
    +
    +
      +
    1. +
        +
      1. + Problem title 11 + handle +
      2. +
      3. + Problem Group + handle +
      4. +
      5. + Problem title 14 + handle +
      6. +
      7. + Video 3 + handle +
      8. +
      9. +
        +

        + Problem group + handle +

        +
        +
          +
        1. + Problem title 11 + handle +
        2. +
        3. + Problem title 11 + handle +
        4. +
        5. + Problem title 11 + handle +
        6. +
        +
      10. +
      11. + Problem title 13 + handle +
      12. +
      13. + Problem title 14 + handle +
      14. +
      15. + Video 3 + handle +
      16. +
      17. + Problem title 11 + handle +
      18. +
      19. + Problem Group + handle +
      20. +
      21. + Problem title 14 + handle +
      22. +
      23. + Video 3 + handle +
      24. +
      +
    2. + + + + +
    +
    + +
    +
      +
    1. +
      +

      Section Scratch

      +
      + +
    2. +
    3. +
      +

      Course Scratch

      +
      + + +
    4. + + + + +
    +
    +
    - diff --git a/cms/templates/widgets/week-edit.html b/cms/templates/widgets/week-edit.html index 2e37520fde..95ca631be0 100644 --- a/cms/templates/widgets/week-edit.html +++ b/cms/templates/widgets/week-edit.html @@ -1,16 +1,14 @@
    -

    Week 3

    +
    +

    Week 3

    +

    + new goal

    +
    -
    -

    Weeks goals:

    -

    + new goal

    -
    -
    • -

      Goal title: This is the goal body and is where the goal will be further explained

      +

      Goal title: This is the goal body and is where the goal will be further explained

    @@ -62,7 +60,40 @@ Problem title 11 handle -
  • +
  • +
    +

    + Problem group + handle +

    +
    +
      +
    1. + Problem title 11 + handle +
    2. +
    3. + Problem title 11 + handle +
    4. +
    5. + Problem title 11 + handle +
    6. +
    7. + Problem title 13 + handle +
    8. +
    9. + Problem title 14 + handle +
    10. +
    11. + Video 3 + handle +
    12. +
    +
  • Problem Group handle
  • @@ -70,11 +101,77 @@ Problem title 14 handle -
  • +
  • +
    +

    + Problem group + handle +

    +
    +
      +
    1. + Problem title 11 + handle +
    2. +
    3. + Problem title 11 + handle +
    4. +
    5. + Problem title 11 + handle +
    6. +
    7. + Problem title 13 + handle +
    8. +
    9. + Problem title 14 + handle +
    10. +
    11. + Video 3 + handle +
    12. +
    +
  • Video 3 handle
  • - +
  • +
    +

    + Problem group + handle +

    +
    +
      +
    1. + Problem title 11 + handle +
    2. +
    3. + Problem title 11 + handle +
    4. +
    5. + Problem title 11 + handle +
    6. +
    7. + Problem title 13 + handle +
    8. +
    9. + Problem title 14 + handle +
    10. +
    11. + Video 3 + handle +
    12. +
    +
  • @@ -103,6 +200,18 @@ Problem title 11 handle
  • +
  • + Problem title 13 + handle +
  • +
  • + Problem title 14 + handle +
  • +
  • + Video 3 + handle +
  • diff --git a/cms/templates/widgets/week-new.html b/cms/templates/widgets/week-new.html index be08587755..c62730c1bc 100644 --- a/cms/templates/widgets/week-new.html +++ b/cms/templates/widgets/week-new.html @@ -1,13 +1,11 @@
    -

    Week 3

    +
    +

    Week 3

    +

    + new goal

    +
    -
    -

    Weeks goals:

    -

    + new goal

    -
    -
    • Please add a goal for this section

      From fe45de3833ebc0ab06d9ed6fff696ee0387177f0 Mon Sep 17 00:00:00 2001 From: Calen Pennington Date: Mon, 18 Jun 2012 10:08:31 -0400 Subject: [PATCH 14/21] Read week headings from mongodb --- .../management/commands/import.py | 2 +- cms/djangoapps/contentstore/views.py | 13 +- cms/lib/keystore/__init__.py | 7 +- cms/lib/keystore/mongo.py | 19 ++- cms/templates/widgets/navigation.html | 123 +----------------- common/lib/xmodule/seq_module.py | 8 ++ common/lib/xmodule/setup.py | 14 ++ common/lib/xmodule/x_module.py | 75 +++++++++-- requirements.txt | 1 + 9 files changed, 115 insertions(+), 147 deletions(-) create mode 100644 common/lib/xmodule/setup.py diff --git a/cms/djangoapps/contentstore/management/commands/import.py b/cms/djangoapps/contentstore/management/commands/import.py index 690e3dbea0..3e0ccdd5e8 100644 --- a/cms/djangoapps/contentstore/management/commands/import.py +++ b/cms/djangoapps/contentstore/management/commands/import.py @@ -82,7 +82,7 @@ class Command(BaseCommand): def handle_list(e): if e.attrib.get("class", None) == "tutorials": return - children = [{'url':le.attrib['url']} for le in e.getchildren()] + children = [le.attrib['url'] for le in e.getchildren()] results[e.attrib['url']] = {'children':children} def handle_video(e): diff --git a/cms/djangoapps/contentstore/views.py b/cms/djangoapps/contentstore/views.py index 429fb6c26b..64bde14869 100644 --- a/cms/djangoapps/contentstore/views.py +++ b/cms/djangoapps/contentstore/views.py @@ -3,11 +3,10 @@ from keystore.django import keystore from django.contrib.auth.decorators import login_required -@login_required -def calendar(request, org, course): - weeks = keystore.get_children_for_item(['i4x', org, course, 'Course', None]) - return render_to_response('calendar.html', {'weeks': weeks}) - - def index(request): - return render_to_response('index.html', {}) + # 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/lib/keystore/__init__.py b/cms/lib/keystore/__init__.py index d0a24be797..61c797241d 100644 --- a/cms/lib/keystore/__init__.py +++ b/cms/lib/keystore/__init__.py @@ -37,7 +37,7 @@ class Location(object): self.update(location.list()) def url(self): - return "i4x://{org}/{course}/{category}/{name}".format(**self.dict()) + return "{tag}://{org}/{course}/{category}/{name}".format(**self.dict()) def list(self): return [self.tag, self.org, self.course, self.category, self.name] @@ -54,10 +54,9 @@ class Location(object): class KeyStore(object): - def get_children_for_item(self, location): + def get_item(self, location): """ - Returns the children for the most recent revision of the object - with the specified location. + Returns an XModuleDescriptor instance for the item at location If no object is found at that location, raises keystore.exceptions.ItemNotFoundError diff --git a/cms/lib/keystore/mongo.py b/cms/lib/keystore/mongo.py index d29afb4bd2..d9760909c9 100644 --- a/cms/lib/keystore/mongo.py +++ b/cms/lib/keystore/mongo.py @@ -1,6 +1,7 @@ import pymongo from . import KeyStore, Location from .exceptions import ItemNotFoundError, InsufficientSpecificationError +from xmodule.x_module import XModuleDescriptor class MongoKeyStore(KeyStore): @@ -12,11 +13,22 @@ class MongoKeyStore(KeyStore): host=host, port=port )[db][collection] - + # Force mongo to report errors, at the expense of performance self.collection.safe = True - def get_children_for_item(self, location): + 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) @@ -25,7 +37,6 @@ class MongoKeyStore(KeyStore): ) items = self.collection.find( query, - fields={'children': True}, sort=[('revision', pymongo.ASCENDING)], limit=1, ) @@ -35,7 +46,7 @@ class MongoKeyStore(KeyStore): if items.count() == 0: raise ItemNotFoundError(location) - return items[0]['children'] + return XModuleDescriptor.load_from_json(items[0], self.get_item) def create_item(self, location, editor): """ diff --git a/cms/templates/widgets/navigation.html b/cms/templates/widgets/navigation.html index 28b92979d9..75d581dd73 100644 --- a/cms/templates/widgets/navigation.html +++ b/cms/templates/widgets/navigation.html @@ -35,9 +35,10 @@
      + % for week in weeks:
    1. -

      Week 1

      +

      ${week.name}

      • Goal title: This is a goal that will be in the header of the week
      • Goal title two: This is another goal for this week so that students have two things to learn
      • @@ -64,125 +65,7 @@ <%include file="module-dropdown.html"/>
    2. -
    3. -
      -

      Week 2

      -
        -
      • Another title This is the goal for the week
      • -
      -
      - - -
    4. -
    5. -
      -

      Week 3

      -
        -
      • Another title This is the goal for the week
      • -
      -
      - - -
    6. -
    7. -
      -

      Week 4

      -
        -
      • Another title This is the goal for the week
      • -
      • Goal title two: This is another fgoal for this week so that students have two things to learn
      • -
      -
      - - -
    8. - -
    9. -
      -

      Week 5

      -
        -
      • Please create a learning goal for this week
      • -
      -
      - -
        - <%include file="module-dropdown.html"/> -
      -
    10. -
    11. -
      -

      Week 6

      -
        -
      • Please create a learning goal for this week
      • -
      -
      - -
        - <%include file="module-dropdown.html"/> -
      -
    12. -
    13. -
      -

      Week 7

      -
        -
      • Please create a learning goal for this week
      • -
      -
      - -
        - <%include file="module-dropdown.html"/> -
      -
    14. + %endfor
    15. Course Scratch Pad

      diff --git a/common/lib/xmodule/seq_module.py b/common/lib/xmodule/seq_module.py index f643eaab4a..4ae4fb3813 100644 --- a/common/lib/xmodule/seq_module.py +++ b/common/lib/xmodule/seq_module.py @@ -95,3 +95,11 @@ class Module(XModule): self.position = int(system.get('position')) self.rendered = False + + +class CourseModuleDescriptor(XModuleDescriptor): + pass + + +class ChapterModuleDescriptor(XModuleDescriptor): + pass diff --git a/common/lib/xmodule/setup.py b/common/lib/xmodule/setup.py new file mode 100644 index 0000000000..6a659b6852 --- /dev/null +++ b/common/lib/xmodule/setup.py @@ -0,0 +1,14 @@ +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:CourseModuleDescriptor", + "Chapter = seq_module:ChapterModuleDescriptor", + ] + } +) diff --git a/common/lib/xmodule/x_module.py b/common/lib/xmodule/x_module.py index d783694fee..23025df50b 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,42 @@ 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._child_instances = None + + def get_children(self): + """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] + return self._child_instances + def get_xml(self): ''' For conversions between JSON and legacy XML representations. diff --git a/requirements.txt b/requirements.txt index 5e95e1bf9e..85cc16b828 100644 --- a/requirements.txt +++ b/requirements.txt @@ -24,3 +24,4 @@ sympy newrelic glob2 pymongo +-e common/lib/xmodule From e67dfb70e4d54da8e078dee94c37fd34a5d9d39c Mon Sep 17 00:00:00 2001 From: Calen Pennington Date: Mon, 18 Jun 2012 11:09:11 -0400 Subject: [PATCH 15/21] Add categories and XModuleDescriptors for all module types that are used at the top level of a course --- .../management/commands/import.py | 27 +++++++++++++------ cms/templates/widgets/navigation.html | 25 ++++++----------- common/lib/xmodule/seq_module.py | 19 ++++++++++--- common/lib/xmodule/setup.py | 11 ++++++-- common/lib/xmodule/video_module.py | 4 +++ common/lib/xmodule/x_module.py | 9 +++++-- 6 files changed, 63 insertions(+), 32 deletions(-) diff --git a/cms/djangoapps/contentstore/management/commands/import.py b/cms/djangoapps/contentstore/management/commands/import.py index 3e0ccdd5e8..8b33f32b94 100644 --- a/cms/djangoapps/contentstore/management/commands/import.py +++ b/cms/djangoapps/contentstore/management/commands/import.py @@ -32,7 +32,7 @@ class Command(BaseCommand): elements = list(course.iter()) - tag_to_category = {# Inside HTML ==> Skip these + tag_to_category = { # Custom tags 'videodev': 'Custom', 'slides': 'Custom', @@ -40,33 +40,44 @@ class Command(BaseCommand): 'image': 'Custom', 'discuss': 'Custom', # Simple lists - 'chapter': 'Chapter', + 'chapter': 'Week', 'course': 'Course', 'sequential': 'LectureSequence', 'vertical': 'ProblemSet', - 'section': 'Section', + '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 + 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 = "{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)) + e.set('url', 'i4x://mit.edu/6002xs12/{category}/{name}'.format( + category=category, + name=name)) def handle_skip(e): diff --git a/cms/templates/widgets/navigation.html b/cms/templates/widgets/navigation.html index 75d581dd73..1f75dab470 100644 --- a/cms/templates/widgets/navigation.html +++ b/cms/templates/widgets/navigation.html @@ -40,28 +40,19 @@

      ${week.name}

        -
      • Goal title: This is a goal that will be in the header of the week
      • -
      • Goal title two: This is another goal for this week so that students have two things to learn
      • + % for goal in week.get_goals(): +
      • ${goal.name}:${goal.data}
      • + % endfor
    16. diff --git a/common/lib/xmodule/seq_module.py b/common/lib/xmodule/seq_module.py index 4ae4fb3813..91ff6d2671 100644 --- a/common/lib/xmodule/seq_module.py +++ b/common/lib/xmodule/seq_module.py @@ -97,9 +97,22 @@ class Module(XModule): self.rendered = False -class CourseModuleDescriptor(XModuleDescriptor): - pass +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 ChapterModuleDescriptor(XModuleDescriptor): +class SectionDescriptor(XModuleDescriptor): pass diff --git a/common/lib/xmodule/setup.py b/common/lib/xmodule/setup.py index 6a659b6852..1140037259 100644 --- a/common/lib/xmodule/setup.py +++ b/common/lib/xmodule/setup.py @@ -7,8 +7,15 @@ setup( install_requires=['distribute'], entry_points={ 'xmodule.v1': [ - "Course = seq_module:CourseModuleDescriptor", - "Chapter = seq_module:ChapterModuleDescriptor", + "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 8f8a2c2ffd..d7c7f80291 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 23025df50b..3560eecbdc 100644 --- a/common/lib/xmodule/x_module.py +++ b/common/lib/xmodule/x_module.py @@ -152,13 +152,18 @@ class XModuleDescriptor(Plugin): 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): + 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] - return self._child_instances + + 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): From 328b2df7c5571f5e38e53e96a413c6964f0fa8ce Mon Sep 17 00:00:00 2001 From: Calen Pennington Date: Mon, 18 Jun 2012 12:21:12 -0400 Subject: [PATCH 16/21] Ignore .egg-info directories --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index ebf06998b1..ef28575da5 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ log/ reports/ /src/ \#*\# +*.egg-info From 5404345b1ff38d7ecd21432835dd739a63ee3a79 Mon Sep 17 00:00:00 2001 From: Calen Pennington Date: Mon, 18 Jun 2012 13:21:06 -0400 Subject: [PATCH 17/21] Make tests pass when running on cms --- .../management/commands/ftpserve.py | 61 ------------------- cms/envs/dev.py | 2 +- cms/envs/test.py | 54 ++++++++++++++++ .../{lib => djangoapps}/cache_toolbox/COPYING | 0 .../cache_toolbox/README.rst | 0 .../cache_toolbox/__init__.py | 0 .../cache_toolbox/app_settings.py | 0 .../{lib => djangoapps}/cache_toolbox/core.py | 0 .../cache_toolbox/middleware.py | 0 .../cache_toolbox/model.py | 0 .../cache_toolbox/relation.py | 0 .../cache_toolbox/templatetags/__init__.py | 0 .../templatetags/cache_toolbox.py | 0 common/{lib => djangoapps}/util/__init__.py | 0 common/{lib => djangoapps}/util/cache.py | 0 common/{lib => djangoapps}/util/memcache.py | 0 common/{lib => djangoapps}/util/middleware.py | 0 common/{lib => djangoapps}/util/models.py | 0 common/{lib => djangoapps}/util/tests.py | 0 common/{lib => djangoapps}/util/views.py | 0 {cms => common}/lib/keystore/__init__.py | 0 {cms => common}/lib/keystore/django.py | 0 {cms => common}/lib/keystore/exceptions.py | 0 {cms => common}/lib/keystore/mongo.py | 0 lms/envs/dev.py | 2 +- rakefile | 2 +- 26 files changed, 57 insertions(+), 64 deletions(-) delete mode 100644 cms/djangoapps/contentstore/management/commands/ftpserve.py create mode 100644 cms/envs/test.py rename common/{lib => djangoapps}/cache_toolbox/COPYING (100%) rename common/{lib => djangoapps}/cache_toolbox/README.rst (100%) rename common/{lib => djangoapps}/cache_toolbox/__init__.py (100%) rename common/{lib => djangoapps}/cache_toolbox/app_settings.py (100%) rename common/{lib => djangoapps}/cache_toolbox/core.py (100%) rename common/{lib => djangoapps}/cache_toolbox/middleware.py (100%) rename common/{lib => djangoapps}/cache_toolbox/model.py (100%) rename common/{lib => djangoapps}/cache_toolbox/relation.py (100%) rename common/{lib => djangoapps}/cache_toolbox/templatetags/__init__.py (100%) rename common/{lib => djangoapps}/cache_toolbox/templatetags/cache_toolbox.py (100%) rename common/{lib => djangoapps}/util/__init__.py (100%) rename common/{lib => djangoapps}/util/cache.py (100%) rename common/{lib => djangoapps}/util/memcache.py (100%) rename common/{lib => djangoapps}/util/middleware.py (100%) rename common/{lib => djangoapps}/util/models.py (100%) rename common/{lib => djangoapps}/util/tests.py (100%) rename common/{lib => djangoapps}/util/views.py (100%) rename {cms => common}/lib/keystore/__init__.py (100%) rename {cms => common}/lib/keystore/django.py (100%) rename {cms => common}/lib/keystore/exceptions.py (100%) rename {cms => common}/lib/keystore/mongo.py (100%) diff --git a/cms/djangoapps/contentstore/management/commands/ftpserve.py b/cms/djangoapps/contentstore/management/commands/ftpserve.py deleted file mode 100644 index f0a1c19dbf..0000000000 --- a/cms/djangoapps/contentstore/management/commands/ftpserve.py +++ /dev/null @@ -1,61 +0,0 @@ -from django.core.management.base import BaseCommand -from django.contrib.auth.models import User -import contentstore.tasks - -from pyftpdlib import ftpserver -import os - -class DjangoAuthorizer(object): - def validate_authentication(self, username, password): - try: - u=User.objects.get(username=username) - except User.DoesNotExist: - return False - # TODO: Check security groups - return u.check_password(password) - def has_user(self, username): - print "????",username - return True - def has_perm(self, username, perm, path=None): - print "!!!!!",username, perm, path - return True - def get_home_dir(self, username): - d = "/tmp/ftp/"+username - try: - os.mkdir(d) - except OSError: - pass - return "/tmp/ftp/"+username - def get_perms(self, username): - return 'elradfmw' - def get_msg_login(self, username): - return 'Hello' - def get_msg_quit(self, username): - return 'Goodbye' - def __init__(self): - pass - def impersonate_user(self, username, password): - pass - def terminate_impersonation(self, username): - pass - -def on_upload(ftp_handler, filename): - source = ftp_handler.remote_ip - author = ftp_handler.username - print filename, author, source - # We pass on this for now: - # contentstore.tasks.on_upload - # It is a changing API, and it makes testing the FTP server slow. - -class Command(BaseCommand): - help = \ -''' Run FTP server.''' - def handle(self, *args, **options): - authorizer = DjangoAuthorizer() #ftpserver.DummyAuthorizer() - handler = ftpserver.FTPHandler - handler.on_file_received = on_upload - - handler.authorizer = authorizer - address = ("127.0.0.1", 2121) - ftpd = ftpserver.FTPServer(address, handler) - ftpd.serve_forever() diff --git a/cms/envs/dev.py b/cms/envs/dev.py index f7277b3d3f..332f52f145 100644 --- a/cms/envs/dev.py +++ b/cms/envs/dev.py @@ -38,6 +38,6 @@ 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/cms/envs/test.py b/cms/envs/test.py new file mode 100644 index 0000000000..1a20d9e6f8 --- /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/common/lib/cache_toolbox/COPYING b/common/djangoapps/cache_toolbox/COPYING similarity index 100% rename from common/lib/cache_toolbox/COPYING rename to common/djangoapps/cache_toolbox/COPYING diff --git a/common/lib/cache_toolbox/README.rst b/common/djangoapps/cache_toolbox/README.rst similarity index 100% rename from common/lib/cache_toolbox/README.rst rename to common/djangoapps/cache_toolbox/README.rst diff --git a/common/lib/cache_toolbox/__init__.py b/common/djangoapps/cache_toolbox/__init__.py similarity index 100% rename from common/lib/cache_toolbox/__init__.py rename to common/djangoapps/cache_toolbox/__init__.py diff --git a/common/lib/cache_toolbox/app_settings.py b/common/djangoapps/cache_toolbox/app_settings.py similarity index 100% rename from common/lib/cache_toolbox/app_settings.py rename to common/djangoapps/cache_toolbox/app_settings.py diff --git a/common/lib/cache_toolbox/core.py b/common/djangoapps/cache_toolbox/core.py similarity index 100% rename from common/lib/cache_toolbox/core.py rename to common/djangoapps/cache_toolbox/core.py diff --git a/common/lib/cache_toolbox/middleware.py b/common/djangoapps/cache_toolbox/middleware.py similarity index 100% rename from common/lib/cache_toolbox/middleware.py rename to common/djangoapps/cache_toolbox/middleware.py diff --git a/common/lib/cache_toolbox/model.py b/common/djangoapps/cache_toolbox/model.py similarity index 100% rename from common/lib/cache_toolbox/model.py rename to common/djangoapps/cache_toolbox/model.py diff --git a/common/lib/cache_toolbox/relation.py b/common/djangoapps/cache_toolbox/relation.py similarity index 100% rename from common/lib/cache_toolbox/relation.py rename to common/djangoapps/cache_toolbox/relation.py diff --git a/common/lib/cache_toolbox/templatetags/__init__.py b/common/djangoapps/cache_toolbox/templatetags/__init__.py similarity index 100% rename from common/lib/cache_toolbox/templatetags/__init__.py rename to common/djangoapps/cache_toolbox/templatetags/__init__.py diff --git a/common/lib/cache_toolbox/templatetags/cache_toolbox.py b/common/djangoapps/cache_toolbox/templatetags/cache_toolbox.py similarity index 100% rename from common/lib/cache_toolbox/templatetags/cache_toolbox.py rename to common/djangoapps/cache_toolbox/templatetags/cache_toolbox.py diff --git a/common/lib/util/__init__.py b/common/djangoapps/util/__init__.py similarity index 100% rename from common/lib/util/__init__.py rename to common/djangoapps/util/__init__.py diff --git a/common/lib/util/cache.py b/common/djangoapps/util/cache.py similarity index 100% rename from common/lib/util/cache.py rename to common/djangoapps/util/cache.py diff --git a/common/lib/util/memcache.py b/common/djangoapps/util/memcache.py similarity index 100% rename from common/lib/util/memcache.py rename to common/djangoapps/util/memcache.py diff --git a/common/lib/util/middleware.py b/common/djangoapps/util/middleware.py similarity index 100% rename from common/lib/util/middleware.py rename to common/djangoapps/util/middleware.py diff --git a/common/lib/util/models.py b/common/djangoapps/util/models.py similarity index 100% rename from common/lib/util/models.py rename to common/djangoapps/util/models.py diff --git a/common/lib/util/tests.py b/common/djangoapps/util/tests.py similarity index 100% rename from common/lib/util/tests.py rename to common/djangoapps/util/tests.py diff --git a/common/lib/util/views.py b/common/djangoapps/util/views.py similarity index 100% rename from common/lib/util/views.py rename to common/djangoapps/util/views.py diff --git a/cms/lib/keystore/__init__.py b/common/lib/keystore/__init__.py similarity index 100% rename from cms/lib/keystore/__init__.py rename to common/lib/keystore/__init__.py diff --git a/cms/lib/keystore/django.py b/common/lib/keystore/django.py similarity index 100% rename from cms/lib/keystore/django.py rename to common/lib/keystore/django.py diff --git a/cms/lib/keystore/exceptions.py b/common/lib/keystore/exceptions.py similarity index 100% rename from cms/lib/keystore/exceptions.py rename to common/lib/keystore/exceptions.py diff --git a/cms/lib/keystore/mongo.py b/common/lib/keystore/mongo.py similarity index 100% rename from cms/lib/keystore/mongo.py rename to common/lib/keystore/mongo.py diff --git a/lms/envs/dev.py b/lms/envs/dev.py index 17e1e96f45..decd92d136 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 6bd582783e..43f5697bb8 100644 --- a/rakefile +++ b/rakefile @@ -66,7 +66,7 @@ end desc "Run all django tests on our djangoapps for the #{system}" task task_name => report_dir do ENV['NOSE_XUNIT_FILE'] = File.join(report_dir, "nosetests.xml") - 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 From 79e81d69b4be8c6d082aa25626f6f442df830ddb Mon Sep 17 00:00:00 2001 From: Calen Pennington Date: Mon, 18 Jun 2012 13:41:53 -0400 Subject: [PATCH 18/21] Delay initializition of the MongoKeyStore until required --- .../contentstore/management/commands/import.py | 7 +++---- cms/djangoapps/contentstore/views.py | 2 +- common/lib/keystore/django.py | 11 ++++++++++- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/cms/djangoapps/contentstore/management/commands/import.py b/cms/djangoapps/contentstore/management/commands/import.py index 8b33f32b94..d6064e1e3d 100644 --- a/cms/djangoapps/contentstore/management/commands/import.py +++ b/cms/djangoapps/contentstore/management/commands/import.py @@ -160,9 +160,8 @@ class Command(BaseCommand): element_actions[e.tag](e) for k in results: - print k - keystore.create_item(k, 'Piotr Mitros') + keystore().create_item(k, 'Piotr Mitros') if 'data' in results[k]: - keystore.update_item(k, results[k]['data']) + keystore().update_item(k, results[k]['data']) if 'children' in results[k]: - keystore.update_children(k, results[k]['children']) + keystore().update_children(k, results[k]['children']) diff --git a/cms/djangoapps/contentstore/views.py b/cms/djangoapps/contentstore/views.py index 64bde14869..e29c41ea59 100644 --- a/cms/djangoapps/contentstore/views.py +++ b/cms/djangoapps/contentstore/views.py @@ -7,6 +7,6 @@ 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]) + course = keystore().get_item(['i4x', org, course, 'Course', None]) weeks = course.get_children() return render_to_response('index.html', {'weeks': weeks}) diff --git a/common/lib/keystore/django.py b/common/lib/keystore/django.py index b6ffb83b5c..b88c74b8a3 100644 --- a/common/lib/keystore/django.py +++ b/common/lib/keystore/django.py @@ -9,4 +9,13 @@ from __future__ import absolute_import from django.conf import settings from .mongo import MongoKeyStore -keystore = MongoKeyStore(**settings.KEYSTORE) +_KEYSTORE = None + + +def keystore(): + global _KEYSTORE + + if _KEYSTORE is None: + _KEYSTORE = MongoKeyStore(**settings.KEYSTORE) + + return _KEYSTORE From f8434b3a6d7d29372aaddab8c62cadf3ca1fb027 Mon Sep 17 00:00:00 2001 From: Calen Pennington Date: Mon, 18 Jun 2012 13:48:26 -0400 Subject: [PATCH 19/21] Move libraries that can only be imported in the context of django into common/djangoapps --- common/{lib => djangoapps}/django_future/__init__.py | 0 common/{lib => djangoapps}/django_future/csrf.py | 0 common/{lib => djangoapps}/monitoring/__init__.py | 0 common/{lib => djangoapps}/monitoring/exceptions.py | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename common/{lib => djangoapps}/django_future/__init__.py (100%) rename common/{lib => djangoapps}/django_future/csrf.py (100%) rename common/{lib => djangoapps}/monitoring/__init__.py (100%) rename common/{lib => djangoapps}/monitoring/exceptions.py (100%) diff --git a/common/lib/django_future/__init__.py b/common/djangoapps/django_future/__init__.py similarity index 100% rename from common/lib/django_future/__init__.py rename to common/djangoapps/django_future/__init__.py diff --git a/common/lib/django_future/csrf.py b/common/djangoapps/django_future/csrf.py similarity index 100% rename from common/lib/django_future/csrf.py rename to common/djangoapps/django_future/csrf.py diff --git a/common/lib/monitoring/__init__.py b/common/djangoapps/monitoring/__init__.py similarity index 100% rename from common/lib/monitoring/__init__.py rename to common/djangoapps/monitoring/__init__.py diff --git a/common/lib/monitoring/exceptions.py b/common/djangoapps/monitoring/exceptions.py similarity index 100% rename from common/lib/monitoring/exceptions.py rename to common/djangoapps/monitoring/exceptions.py From 9ff0effd718664b0ccd29d92cb389825776470e9 Mon Sep 17 00:00:00 2001 From: Calen Pennington Date: Mon, 18 Jun 2012 14:08:15 -0400 Subject: [PATCH 20/21] Remove copy/paste instructor module. It was a bad idea anyway. =) --- cms/djangoapps/instructor/__init__.py | 0 cms/djangoapps/instructor/models.py | 61 --------------------------- cms/djangoapps/instructor/tests.py | 16 ------- cms/djangoapps/instructor/views.py | 49 --------------------- 4 files changed, 126 deletions(-) delete mode 100644 cms/djangoapps/instructor/__init__.py delete mode 100644 cms/djangoapps/instructor/models.py delete mode 100644 cms/djangoapps/instructor/tests.py delete mode 100644 cms/djangoapps/instructor/views.py diff --git a/cms/djangoapps/instructor/__init__.py b/cms/djangoapps/instructor/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/cms/djangoapps/instructor/models.py b/cms/djangoapps/instructor/models.py deleted file mode 100644 index 906aeee2f1..0000000000 --- a/cms/djangoapps/instructor/models.py +++ /dev/null @@ -1,61 +0,0 @@ -""" -WE'RE USING MIGRATIONS! - -If you make changes to this model, be sure to create an appropriate migration -file and check it in at the same time as your model changes. To do that, - -1. Go to the mitx dir -2. ./manage.py schemamigration user --auto description_of_your_change -3. Add the migration file created in mitx/courseware/migrations/ -""" -import uuid - -from django.db import models -from django.contrib.auth.models import User - - -class UserProfile(models.Model): - class Meta: - db_table = "auth_userprofile" - - ## CRITICAL TODO/SECURITY - # Sanitize all fields. - # This is not visible to other users, but could introduce holes later - user = models.OneToOneField(User, unique=True, db_index=True, related_name='profile') - name = models.CharField(blank=True, max_length=255, db_index=True) - org = models.CharField(blank=True, max_length=255, db_index=True) - - -class Registration(models.Model): - ''' Allows us to wait for e-mail before user is registered. A - registration profile is created when the user creates an - account, but that account is inactive. Once the user clicks - on the activation key, it becomes active. ''' - class Meta: - db_table = "auth_registration" - - user = models.ForeignKey(User, unique=True) - activation_key = models.CharField(('activation key'), max_length=32, unique=True, db_index=True) - - def register(self, user): - # MINOR TODO: Switch to crypto-secure key - self.activation_key = uuid.uuid4().hex - self.user = user - self.save() - - def activate(self): - self.user.is_active = True - self.user.save() - #self.delete() - - -class PendingNameChange(models.Model): - user = models.OneToOneField(User, unique=True, db_index=True) - new_name = models.CharField(blank=True, max_length=255) - rationale = models.CharField(blank=True, max_length=1024) - - -class PendingEmailChange(models.Model): - user = models.OneToOneField(User, unique=True, db_index=True) - new_email = models.CharField(blank=True, max_length=255, db_index=True) - activation_key = models.CharField(('activation key'), max_length=32, unique=True, db_index=True) diff --git a/cms/djangoapps/instructor/tests.py b/cms/djangoapps/instructor/tests.py deleted file mode 100644 index 501deb776c..0000000000 --- a/cms/djangoapps/instructor/tests.py +++ /dev/null @@ -1,16 +0,0 @@ -""" -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/cms/djangoapps/instructor/views.py b/cms/djangoapps/instructor/views.py deleted file mode 100644 index fbb341b468..0000000000 --- a/cms/djangoapps/instructor/views.py +++ /dev/null @@ -1,49 +0,0 @@ -import logging - -from django.views.decorators.http import require_http_methods, require_POST, require_GET -from django.contrib.auth import logout, authenticate, login -from django.shortcuts import redirect -from mitxmako.shortcuts import render_to_response - -from django_future.csrf import ensure_csrf_cookie - -log = logging.getLogger("mitx.student") - - -@require_http_methods(['GET', 'POST']) -def do_login(request): - if request.method == 'POST': - return post_login(request) - elif request.method == 'GET': - return get_login(request) - - -@require_POST -@ensure_csrf_cookie -def post_login(request): - username = request.POST['username'] - password = request.POST['password'] - user = authenticate(username=username, password=password) - if user is not None: - if user.is_active: - login(request, user) - return redirect(request.POST.get('next', '/')) - else: - raise Exception("Can't log in, account disabled") - else: - raise Exception("Can't log in, invalid authentication") - - -@require_GET -@ensure_csrf_cookie -def get_login(request): - return render_to_response('login.html', { - 'next': request.GET.get('next') - }) - - -@ensure_csrf_cookie -def logout_user(request): - ''' HTTP request to log in the user. Redirects to marketing page''' - logout(request) - return redirect('/') From 605b1ae0fd16bc3fec0fd4becb321f79f7644dab Mon Sep 17 00:00:00 2001 From: Calen Pennington Date: Mon, 18 Jun 2012 14:24:45 -0400 Subject: [PATCH 21/21] Remove old template that is no longer relevant --- cms/templates/calendar.html | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 cms/templates/calendar.html diff --git a/cms/templates/calendar.html b/cms/templates/calendar.html deleted file mode 100644 index 05b2f88806..0000000000 --- a/cms/templates/calendar.html +++ /dev/null @@ -1,3 +0,0 @@ -% for week in weeks: -${week} -% endfor