Commit 93b8ad3e by ichuang

Merge branch 'master' of github.com:MITx/mitx into stable-edx4edx

parents a2e2b6e4 8ca56ed4
......@@ -20,3 +20,4 @@ log/
reports/
/src/
\#*\#
*.egg-info
###
### One-off script for importing courseware form XML format
###
#import mitxmako.middleware
#from courseware import content_parser
#from django.contrib.auth.models import User
import os.path
from StringIO import StringIO
from mako.template import Template
from mako.lookup import TemplateLookup
from django.core.management.base import BaseCommand
from keystore.django import keystore
from lxml import etree
class Command(BaseCommand):
help = \
''' Run FTP server.'''
def handle(self, *args, **options):
print args
data_dir = args[0]
parser = etree.XMLParser(remove_comments = True)
lookup = TemplateLookup(directories=[data_dir])
template = lookup.get_template("course.xml")
course_string = template.render(groups=[])
course = etree.parse(StringIO(course_string), parser=parser)
elements = list(course.iter())
tag_to_category = {
# Custom tags
'videodev': 'Custom',
'slides': 'Custom',
'book': 'Custom',
'image': 'Custom',
'discuss': 'Custom',
# Simple lists
'chapter': 'Week',
'course': 'Course',
'sequential': 'LectureSequence',
'vertical': 'ProblemSet',
'section': {
'Lab': 'Lab',
'Lecture Sequence': 'LectureSequence',
'Homework': 'Homework',
'Tutorial Index': 'TutorialIndex',
'Video': 'VideoSegment',
'Midterm': 'Exam',
'Final': 'Exam',
None: 'Section',
},
# True types
'video': 'VideoSegment',
'html': 'HTML',
'problem': 'Problem',
}
name_index = 0
for e in elements:
name = e.attrib.get('name', None)
for f in elements:
if f != e and f.attrib.get('name', None) == name:
name = None
if not name:
name = "{tag}_{index}".format(tag=e.tag, index=name_index)
name_index = name_index + 1
if e.tag in tag_to_category:
category = tag_to_category[e.tag]
if isinstance(category, dict):
category = category[e.get('format')]
category = category.replace('/', '-')
name = name.replace('/', '-')
e.set('url', 'i4x://mit.edu/6002xs12/{category}/{name}'.format(
category=category,
name=name))
def handle_skip(e):
print "Skipping ", e
results = {}
def handle_custom(e):
data = {'type':'i4x://mit.edu/6002xs12/tag/{tag}'.format(tag=e.tag),
'attrib':dict(e.attrib)}
results[e.attrib['url']] = {'data':data}
def handle_list(e):
if e.attrib.get("class", None) == "tutorials":
return
children = [le.attrib['url'] for le in e.getchildren()]
results[e.attrib['url']] = {'children':children}
def handle_video(e):
url = e.attrib['url']
clip_url = url.replace('VideoSegment', 'VideoClip')
# Take: 0.75:izygArpw-Qo,1.0:p2Q6BrNhdh8,1.25:1EeWXzPdhSA,1.50:rABDYkeK0x8
# Make: [(0.75, 'izygArpw-Qo'), (1.0, 'p2Q6BrNhdh8'), (1.25, '1EeWXzPdhSA'), (1.5, 'rABDYkeK0x8')]
youtube_str = e.attrib['youtube']
youtube_list = [(float(x), y) for x,y in map(lambda x:x.split(':'), youtube_str.split(','))]
clip_infos = [{ "status": "ready",
"format": "youtube",
"sane": True,
"location": "youtube",
"speed": speed,
"id": youtube_id,
"size": None} \
for (speed, youtube_id) \
in youtube_list]
results[clip_url] = {'data':{'clip_infos':clip_infos}}
results[url] = {'children' : [{'url':clip_url}]}
def handle_html(e):
if 'src' in e.attrib:
text = open(data_dir+'html/'+e.attrib['src']).read()
else:
textlist=[e.text]+[etree.tostring(elem) for elem in e]+[e.tail]
textlist=[i for i in textlist if type(i)==str]
text = "".join(textlist)
results[e.attrib['url']] = {'data':{'text':text}}
def handle_problem(e):
data = open(os.path.join(data_dir, 'problems', e.attrib['filename']+'.xml')).read()
results[e.attrib['url']] = {'data':{'statement':data}}
element_actions = {# Inside HTML ==> Skip these
'a': handle_skip,
'h1': handle_skip,
'h2': handle_skip,
'hr': handle_skip,
'strong': handle_skip,
'ul': handle_skip,
'li': handle_skip,
'p': handle_skip,
# Custom tags
'videodev': handle_custom,
'slides': handle_custom,
'book': handle_custom,
'image': handle_custom,
'discuss': handle_custom,
# Simple lists
'chapter': handle_list,
'course': handle_list,
'sequential': handle_list,
'vertical': handle_list,
'section': handle_list,
# True types
'video': handle_video,
'html': handle_html,
'problem': handle_problem,
}
for e in elements:
element_actions[e.tag](e)
for k in results:
keystore().create_item(k, 'Piotr Mitros')
if 'data' in results[k]:
keystore().update_item(k, results[k]['data'])
if 'children' in results[k]:
keystore().update_children(k, results[k]['children'])
from mitxmako.shortcuts import render_to_response
from keystore.django import keystore
from django.contrib.auth.decorators import login_required
def index(request):
# TODO (cpennington): These need to be read in from the active user
org = 'mit.edu'
course = '6002xs12'
name = '6.002 Spring 2012'
course = keystore().get_item(['i4x', org, course, 'Course', name])
weeks = course.get_children()
return render_to_response('index.html', {'weeks': weeks})
"""
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
############################ FEATURE CONFIGURATION #############################
MITX_FEATURES = {
'USE_DJANGO_PIPELINE': True,
}
############################# 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
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(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',
COMMON_ROOT / 'djangoapps' / 'pipeline_mako' / '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 = (
'staticfiles.finders.FileSystemFinder',
'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'
############################### Pipeline #######################################
STATICFILES_STORAGE = 'pipeline.storage.PipelineCachedStorage'
PIPELINE_CSS = {
'base-style': {
'source_filenames': ['sass/base-style.scss'],
'output_filename': 'css/base-style.css',
},
}
PIPELINE_ALWAYS_RECOMPILE = ['sass/base-style.scss']
PIPELINE_JS = {
}
PIPELINE_COMPILERS = [
'pipeline.compilers.sass.SASSCompiler',
'pipeline.compilers.coffee.CoffeeScriptCompiler',
]
PIPELINE_SASS_ARGUMENTS = '-t compressed -r {proj_dir}/static/sass/bourbon/lib/bourbon.rb'.format(proj_dir=PROJECT_ROOT)
PIPELINE_CSS_COMPRESSOR = None
PIPELINE_JS_COMPRESSOR = 'pipeline.compressors.yui.YUICompressor'
STATICFILES_IGNORE_PATTERNS = (
"sass/*",
"coffee/*",
"*.py",
"*.pyc"
)
PIPELINE_YUI_BINARY = 'yui-compressor'
PIPELINE_SASS_BINARY = 'sass'
PIPELINE_COFFEE_SCRIPT_BINARY = 'coffee'
# Setting that will only affect the MITx version of django-pipeline until our changes are merged upstream
PIPELINE_COMPILE_INPLACE = True
############################ APPS #####################################
INSTALLED_APPS = (
# Standard apps
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
# For CMS
'contentstore',
# For asset pipelining
'pipeline',
'staticfiles',
)
"""
This config file runs the simplest dev environment"""
from .common import *
DEBUG = True
TEMPLATE_DEBUG = DEBUG
KEYSTORE = {
'default': {
'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',
}
}
"""
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',
}
}
#!/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)
/* 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; }
/*
* jQuery inlineEdit
*
* Copyright (c) 2009 Ca-Phun Ung <caphun at yelotofu dot com>
* Licensed under the MIT (MIT-LICENSE.txt) license.
*
* http://github.com/caphun/jquery.inlineedit/
*
* Inline (in-place) editing.
*/
(function($) {
// cached values
var namespace = '.inlineedit',
placeholderClass = 'inlineEdit-placeholder';
// define inlineEdit method
$.fn.inlineEdit = function( options ) {
var self = this;
return this
.each( function() {
$.inlineEdit.getInstance( this, options ).initValue();
})
.live( ['click', 'mouseenter','mouseleave'].join(namespace+' '), function( event ) {
var widget = $.inlineEdit.getInstance( this, options ),
editableElement = widget.element.find( widget.options.control ),
mutated = !!editableElement.length;
widget.element.removeClass( widget.options.hover );
if ( event.target !== editableElement[0] ) {
switch ( event.type ) {
case 'click':
widget[ mutated ? 'mutate' : 'init' ]();
break;
case 'mouseover': // jquery 1.4.x
case 'mouseout': // jquery 1.4.x
case 'mouseenter':
case 'mouseleave':
if ( !mutated ) {
widget.hoverClassChange( event );
}
break;
}
}
});
}
// plugin constructor
$.inlineEdit = function( elem, options ) {
// deep extend
this.options = $.extend( true, {}, $.inlineEdit.defaults, options );
// the original element
this.element = $( elem );
}
// plugin instance
$.inlineEdit.getInstance = function( elem, options ) {
return ( $.inlineEdit.initialised( elem ) )
? $( elem ).data( 'widget' + namespace )
: new $.inlineEdit( elem, options );
}
// check if plugin initialised
$.inlineEdit.initialised = function( elem ) {
var init = $( elem ).data( 'init' + namespace );
return init !== undefined && init !== null ? true : false;
}
// plugin defaults
$.inlineEdit.defaults = {
hover: 'ui-state-hover',
value: '',
save: '',
buttons: '<button class="save">✔</button> <button class="cancel">✘</button>',
placeholder: 'Click to edit',
control: 'input',
cancelOnBlur: false,
saveOnBlur: false
};
// plugin prototypes
$.inlineEdit.prototype = {
// initialisation
init: function() {
// set initialise flag
this.element.data( 'init' + namespace, true );
// initialise value
this.initValue();
// mutate
this.mutate();
// save widget data
this.element.data( 'widget' + namespace, this );
},
initValue: function() {
this.value( $.trim( this.element.text() ) || this.options.value );
if ( !this.value() ) {
this.element.html( $( this.placeholderHtml() ) );
} else if ( this.options.value ) {
this.element.html( this.options.value );
}
},
mutate: function() {
var self = this;
return self
.element
.html( self.mutatedHtml( self.value() ) )
.find( 'button.save' )
.bind( 'click', function( event ) {
self.save( self.element, event );
self.change( self.element, event );
return false;
})
.end()
.find( 'button.cancel' )
.bind( 'click', function( event ) {
self.change( self.element, event );
return false;
})
.end()
.find( self.options.control )
.bind( 'blur', function( event ) {
if (self.options.cancelOnBlur === true)
self.change( self.element, event );
else if (self.options.saveOnBlur == true){
self.save( self.element, event );
self.change( self.element, event );
}
})
.bind( 'keyup', function( event ) {
switch ( event.keyCode ) {
case 13: // save on ENTER
if (self.options.control !== 'textarea') {
self.save( self.element, event );
self.change( self.element, event );
}
break;
case 27: // cancel on ESC
self.change( self.element, event );
break;
}
})
.focus()
.end();
},
value: function( newValue ) {
if ( arguments.length ) {
var value = newValue === this.options.placeholder ? '' : newValue;
this.element.data( 'value' + namespace, $( '.' + placeholderClass, this ).length ? '' : value && this.encodeHtml( value.replace( /\n/g,"<br />" ) ) );
}
return this.element.data( 'value' + namespace );
},
mutatedHtml: function( value ) {
return this.controls[ this.options.control ].call( this, value );
},
placeholderHtml: function() {
return '<span class="'+ placeholderClass +'">'+ this.options.placeholder +'</span>';
},
buttonHtml: function( options ) {
var o = $.extend({}, {
before: ' ',
buttons: this.options.buttons,
after: ''
}, options);
return o.before + o.buttons + o.after;
},
save: function( elem, event ) {
var $control = this.element.find( this.options.control ),
hash = {
value: this.encodeHtml( $control.val() )
};
// save value back to control to avoid XSS
$control.val(hash.value);
if ( ( $.isFunction( this.options.save ) && this.options.save.call( this.element[0], event, hash ) ) !== false || !this.options.save ) {
this.value( hash.value );
}
},
change: function( elem, event ) {
var self = this;
if ( this.timer ) {
window.clearTimeout( this.timer );
}
this.timer = window.setTimeout( function() {
self.element.html( self.value() || self.placeholderHtml() );
self.element.removeClass( self.options.hover );
}, 200 );
},
controls: {
textarea: function( value ) {
return '<textarea>'+ value.replace(/<br\s?\/?>/g,"\n") +'</textarea>' + this.buttonHtml( { before: '<br />' } );
},
input: function( value ) {
return '<input type="text" value="'+ value.replace(/(\u0022)+/g, '') +'">' + this.buttonHtml();
}
},
hoverClassChange: function( event ) {
$( event.target )[ /mouseover|mouseenter/.test( event.type ) ? 'addClass':'removeClass']( this.options.hover );
},
encodeHtml: function( s ) {
var encoding = [
{key: /</g, value: '&lt;'},
{key: />/g, value: '&gt;'},
{key: /"/g, value: '&quot;'}
],
value = s;
$.each(encoding, function(i,n) {
value = value.replace(n.key, n.value);
});
return value;
}
};
})(jQuery);
// leanModal v1.1 by Ray Stone - http://finelysliced.com.au
// Dual licensed under the MIT and GPL
(function($){$.fn.extend({leanModal:function(options){var defaults={top:100,overlay:0.5,closeButton:null};var overlay=$("<div id='lean_overlay'></div>");$("body").append(overlay);options=$.extend(defaults,options);return this.each(function(){var o=options;$(this).click(function(e){var modal_id=$(this).attr("href");$("#lean_overlay").click(function(){close_modal(modal_id)});$(o.closeButton).click(function(){close_modal(modal_id)});var modal_height=$(modal_id).outerHeight();var modal_width=$(modal_id).outerWidth();
$("#lean_overlay").css({"display":"block",opacity:0});$("#lean_overlay").fadeTo(200,o.overlay);$(modal_id).css({"display":"block","position":"fixed","opacity":0,"z-index":11000,"left":50+"%","margin-left":-(modal_width/2)+"px","top":o.top+"px"});$(modal_id).fadeTo(200,1);e.preventDefault()})});function close_modal(modal_id){$("#lean_overlay").fadeOut(200);$(modal_id).css({"display":"none"})}}})})(jQuery);
jQuery.tableDnD = {
/** Keep hold of the current table being dragged */
currentTable : null,
/** Keep hold of the current drag object if any */
dragObject: null,
/** The current mouse offset */
mouseOffset: null,
/** Remember the old value of Y so that we don't do too much processing */
oldY: 0,
/** Actually build the structure */
build: function(options) {
// Make sure options exists
options = options || {};
// Set up the defaults if any
this.each(function() {
// Remember the options
this.tableDnDConfig = {
onDragStyle: options.onDragStyle,
onDropStyle: options.onDropStyle,
// Add in the default class for whileDragging
onDragClass: options.onDragClass ? options.onDragClass : "dragged",
onDrop: options.onDrop,
onDragStart: options.onDragStart,
scrollAmount: options.scrollAmount ? options.scrollAmount : 5
};
// Now make the rows draggable
jQuery.tableDnD.makeDraggable(this);
});
// Now we need to capture the mouse up and mouse move event
// We can use bind so that we don't interfere with other event handlers
jQuery(document)
.bind('mousemove', jQuery.tableDnD.mousemove)
.bind('mouseup', jQuery.tableDnD.mouseup);
// Don't break the chain
return this;
},
/** This function makes all the rows on the table draggable apart from those marked as "NoDrag" */
makeDraggable: function(table) {
// Now initialise the rows
var rows = table.rows; //getElementsByTagName("tr")
var config = table.tableDnDConfig;
for (var i=0; i<rows.length; i++) {
// To make non-draggable rows, add the nodrag class (eg for Category and Header rows)
// inspired by John Tarr and Famic
var nodrag = $(rows[i]).hasClass("nodrag");
if (! nodrag) { //There is no NoDnD attribute on rows I want to drag
jQuery(rows[i]).mousedown(function(ev) {
if (ev.target.tagName == "TD") {
jQuery.tableDnD.dragObject = this;
jQuery.tableDnD.currentTable = table;
jQuery.tableDnD.mouseOffset = jQuery.tableDnD.getMouseOffset(this, ev);
if (config.onDragStart) {
// Call the onDrop method if there is one
config.onDragStart(table, this);
}
return false;
}
}).css("cursor", "move"); // Store the tableDnD object
}
}
},
/** Get the mouse coordinates from the event (allowing for browser differences) */
mouseCoords: function(ev){
if(ev.pageX || ev.pageY){
return {x:ev.pageX, y:ev.pageY};
}
return {
x:ev.clientX + document.body.scrollLeft - document.body.clientLeft,
y:ev.clientY + document.body.scrollTop - document.body.clientTop
};
},
/** Given a target element and a mouse event, get the mouse offset from that element.
To do this we need the element's position and the mouse position */
getMouseOffset: function(target, ev) {
ev = ev || window.event;
var docPos = this.getPosition(target);
var mousePos = this.mouseCoords(ev);
return {x:mousePos.x - docPos.x, y:mousePos.y - docPos.y};
},
/** Get the position of an element by going up the DOM tree and adding up all the offsets */
getPosition: function(e){
var left = 0;
var top = 0;
/** Safari fix -- thanks to Luis Chato for this! */
if (e.offsetHeight == 0) {
/** Safari 2 doesn't correctly grab the offsetTop of a table row
this is detailed here:
http://jacob.peargrove.com/blog/2006/technical/table-row-offsettop-bug-in-safari/
the solution is likewise noted there, grab the offset of a table cell in the row - the firstChild.
note that firefox will return a text node as a first child, so designing a more thorough
solution may need to take that into account, for now this seems to work in firefox, safari, ie */
e = e.firstChild; // a table cell
}
while (e.offsetParent){
left += e.offsetLeft;
top += e.offsetTop;
e = e.offsetParent;
}
left += e.offsetLeft;
top += e.offsetTop;
return {x:left, y:top};
},
mousemove: function(ev) {
if (jQuery.tableDnD.dragObject == null) {
return;
}
var dragObj = jQuery(jQuery.tableDnD.dragObject);
var config = jQuery.tableDnD.currentTable.tableDnDConfig;
var mousePos = jQuery.tableDnD.mouseCoords(ev);
var y = mousePos.y - jQuery.tableDnD.mouseOffset.y;
//auto scroll the window
var yOffset = window.pageYOffset;
if (document.all) {
// Windows version
//yOffset=document.body.scrollTop;
if (typeof document.compatMode != 'undefined' &&
document.compatMode != 'BackCompat') {
yOffset = document.documentElement.scrollTop;
}
else if (typeof document.body != 'undefined') {
yOffset=document.body.scrollTop;
}
}
if (mousePos.y-yOffset < config.scrollAmount) {
window.scrollBy(0, -config.scrollAmount);
} else {
var windowHeight = window.innerHeight ? window.innerHeight
: document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight;
if (windowHeight-(mousePos.y-yOffset) < config.scrollAmount) {
window.scrollBy(0, config.scrollAmount);
}
}
if (y != jQuery.tableDnD.oldY) {
// work out if we're going up or down...
var movingDown = y > jQuery.tableDnD.oldY;
// update the old value
jQuery.tableDnD.oldY = y;
// update the style to show we're dragging
if (config.onDragClass) {
dragObj.addClass(config.onDragClass);
} else {
dragObj.css(config.onDragStyle);
}
// If we're over a row then move the dragged row to there so that the user sees the
// effect dynamically
var currentRow = jQuery.tableDnD.findDropTargetRow(dragObj, y);
if (currentRow) {
// TODO worry about what happens when there are multiple TBODIES
if (movingDown && jQuery.tableDnD.dragObject != currentRow) {
jQuery.tableDnD.dragObject.parentNode.insertBefore(jQuery.tableDnD.dragObject, currentRow.nextSibling);
} else if (! movingDown && jQuery.tableDnD.dragObject != currentRow) {
jQuery.tableDnD.dragObject.parentNode.insertBefore(jQuery.tableDnD.dragObject, currentRow);
}
}
}
return false;
},
/** We're only worried about the y position really, because we can only move rows up and down */
findDropTargetRow: function(draggedRow, y) {
var rows = jQuery.tableDnD.currentTable.rows;
for (var i=0; i<rows.length; i++) {
var row = rows[i];
var rowY = this.getPosition(row).y;
var rowHeight = parseInt(row.offsetHeight)/2;
if (row.offsetHeight == 0) {
rowY = this.getPosition(row.firstChild).y;
rowHeight = parseInt(row.firstChild.offsetHeight)/2;
}
// Because we always have to insert before, we need to offset the height a bit
if ((y > rowY - rowHeight) && (y < (rowY + rowHeight))) {
// that's the row we're over
// If it's the same as the current row, ignore it
if (row == draggedRow) {return null;}
var config = jQuery.tableDnD.currentTable.tableDnDConfig;
if (config.onAllowDrop) {
if (config.onAllowDrop(draggedRow, row)) {
return row;
} else {
return null;
}
} else {
// If a row has nodrop class, then don't allow dropping (inspired by John Tarr and Famic)
var nodrop = $(row).hasClass("nodrop");
if (! nodrop) {
return row;
} else {
return null;
}
}
return row;
}
}
return null;
},
mouseup: function(e) {
if (jQuery.tableDnD.currentTable && jQuery.tableDnD.dragObject) {
var droppedRow = jQuery.tableDnD.dragObject;
var config = jQuery.tableDnD.currentTable.tableDnDConfig;
// If we have a dragObject, then we need to release it,
// The row will already have been moved to the right place so we just reset stuff
if (config.onDragClass) {
jQuery(droppedRow).removeClass(config.onDragClass);
} else {
jQuery(droppedRow).css(config.onDropStyle);
}
jQuery.tableDnD.dragObject = null;
if (config.onDrop) {
// Call the onDrop method if there is one
config.onDrop(jQuery.tableDnD.currentTable, droppedRow);
}
jQuery.tableDnD.currentTable = null; // let go of the table too
}
},
serialize: function() {
if (jQuery.tableDnD.currentTable) {
var result = "";
var tableId = jQuery.tableDnD.currentTable.id;
var rows = jQuery.tableDnD.currentTable.rows;
for (var i=0; i<rows.length; i++) {
if (result.length > 0) result += "&";
result += tableId + '[]=' + rows[i].id;
}
return result;
} else {
return "Error: No Table id set, you need to set an id on your table and every row";
}
}
}
jQuery.fn.extend(
{
tableDnD : jQuery.tableDnD.build
}
);
$(document).ready(function(){
$('section.main-content').children().hide();
$(function(){
$('.editable').inlineEdit();
$('.editable-textarea').inlineEdit({control: 'textarea'});
});
var heighest = 0;
$('.cal ol > li').each(function(){
heighest = ($(this).height() > heighest) ? $(this).height() : heighest;
});
$('.cal ol > li').css('height',heighest + 'px');
$('.add-new-section').click(function() {
return false;
});
$('.new-week .close').click( function(){
$(this).parents('.new-week').hide();
$('p.add-new-week').show();
return false;
});
$('.save-update').click(function(){
$(this).parent().parent().hide();
return false;
});
setHeight = function(){
var windowHeight = $(this).height();
var contentHeight = windowHeight - 29;
$('section.main-content > section').css('min-height', contentHeight);
$('body.content .cal').css('height', contentHeight);
$('.edit-week').click( function() {
$('body').addClass('content');
$('body.content .cal').css('height', contentHeight);
$('section.week-new').show();
return false;
});
$('.cal ol li header h1 a').click( function() {
$('body').addClass('content');
$('body.content .cal').css('height', contentHeight);
$('section.week-edit').show();
return false;
});
$('a.sequence-edit').click(function(){
$('body').addClass('content');
$('body.content .cal').css('height', contentHeight);
$('section.sequence-edit').show();
return false;
});
}
$(document).ready(setHeight);
$(window).bind('resize', setHeight);
$('.video-new a').click(function(){
$('section.video-new').show();
return false;
});
$('a.video-edit').click(function(){
$('section.video-edit').show();
return false;
});
$('.problem-new a').click(function(){
$('section.problem-new').show();
return false;
});
$('a.problem-edit').click(function(){
$('section.problem-edit').show();
return false;
});
});
// ----------------------------------------------------------------------------
// markItUp!
// ----------------------------------------------------------------------------
// Copyright (C) 2008 Jay Salvat
// http://markitup.jaysalvat.com/
// ----------------------------------------------------------------------------
myWikiSettings = {
nameSpace: "wiki", // Useful to prevent multi-instances CSS conflict
previewParserPath: "~/sets/wiki/preview.php",
onShiftEnter: {keepDefault:false, replaceWith:'\n\n'},
markupSet: [
{name:'Heading 1', key:'1', openWith:'== ', closeWith:' ==', placeHolder:'Your title here...' },
{name:'Heading 2', key:'2', openWith:'=== ', closeWith:' ===', placeHolder:'Your title here...' },
{name:'Heading 3', key:'3', openWith:'==== ', closeWith:' ====', placeHolder:'Your title here...' },
{name:'Heading 4', key:'4', openWith:'===== ', closeWith:' =====', placeHolder:'Your title here...' },
{name:'Heading 5', key:'5', openWith:'====== ', closeWith:' ======', placeHolder:'Your title here...' },
{separator:'---------------' },
{name:'Bold', key:'B', openWith:"'''", closeWith:"'''"},
{name:'Italic', key:'I', openWith:"''", closeWith:"''"},
{name:'Stroke through', key:'S', openWith:'<s>', closeWith:'</s>'},
{separator:'---------------' },
{name:'Bulleted list', openWith:'(!(* |!|*)!)'},
{name:'Numeric list', openWith:'(!(# |!|#)!)'},
{separator:'---------------' },
{name:'Picture', key:'P', replaceWith:'[[Image:[![Url:!:http://]!]|[![name]!]]]'},
{name:'Link', key:'L', openWith:'[[![Link]!] ', closeWith:']', placeHolder:'Your text to link here...' },
{name:'Url', openWith:'[[![Url:!:http://]!] ', closeWith:']', placeHolder:'Your text to link here...' },
{separator:'---------------' },
{name:'Quotes', openWith:'(!(> |!|>)!)'},
{name:'Code', openWith:'(!(<source lang="[![Language:!:php]!]">|!|<pre>)!)', closeWith:'(!(</source>|!|</pre>)!)'},
{separator:'---------------' },
{name:'Preview', call:'preview', className:'preview'}
]
}
/* -------------------------------------------------------------------
// 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);
}
/* -------------------------------------------------------------------
// 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;
}
Sass Watch:
sass --watch cms/static/sass:cms/static/css -r ./cms/static/sass/bourbon/lib/bourbon.rb
$fg-column: 70px;
$fg-gutter: 26px;
$fg-max-columns: 12;
$body-font-family: "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Geneva, Verdana, sans-serif;
html {
height: 100%;
}
body {
@include clearfix();
height: 100%;
font: 14px $body-font-family;
> section {
display: table;
width: 100%;
}
> header {
background: #000;
color: #fff;
display: block;
float: none;
padding: 6px 20px;
width: 100%;
@include box-sizing(border-box);
nav {
@include clearfix;
h2 {
font-size: 14px;
text-transform: uppercase;
float: left;
}
ul {
float: left;
&.user-nav {
float: right;
}
li {
@include inline-block();
margin-left: 15px;
}
}
}
}
&.content {
section.main-content {
border-left: 2px solid #000;
@include box-sizing(border-box);
width: flex-grid(9);
float: left;
@include box-shadow( -2px 0 3px #ddd );
}
}
}
a {
text-decoration: none;
color: #888;
}
input {
font-family: $body-font-family;
}
input[type="submit"], .button {
border: 1px solid #ccc;
background: #efefef;
@include border-radius(3px);
padding: 6px;
}
.new-module {
position: relative;
a {
padding: 6px;
display: block;
}
ul.new-dropdown {
list-style: none;
position: absolute;
li {
display: none;
padding: 6px;
}
}
&:hover {
ul.new-dropdown {
display: block;
}
}
}
.draggable {
width: 7px;
min-height: 14px;
background: url('../img/drag-handle.png') no-repeat center;
text-indent: -9999px;
display: block;
float: right;
}
section.cal {
@include box-sizing(border-box);
padding: 25px;
@include clearfix;
> header {
@include clearfix;
margin-bottom: 10px;
background: #efefef;
border: 1px solid #ddd;
h2 {
@include inline-block();
text-transform: uppercase;
letter-spacing: 1px;
font-size: 14px;
padding: 6px;
margin-left: 6px;
font-size: 12px;
}
ul {
@include inline-block;
li {
@include inline-block;
margin-left: 6px;
padding-left: 6px;
border-left: 1px solid #ddd;
padding: 6px;
a {
@include inline-block();
}
ul {
@include inline-block();
li {
@include inline-block();
padding: 0;
border-left: 0;
}
}
}
}
}
ol {
list-style: none;
@include clearfix;
@include box-sizing(border-box);
border-left: 1px solid #333;
border-top: 1px solid #333;
width: 100%;
> li {
border-right: 1px solid #333;
border-bottom: 1px solid;
@include box-sizing(border-box);
float: left;
width: flex-grid(3) + ((flex-gutter() * 3) / 4);
header {
border-bottom: 1px solid #000;
@include box-shadow(0 1px 2px #aaa);
display: block;
margin-bottom: 2px;
h1 {
font-size: 14px;
text-transform: uppercase;
border-bottom: 1px solid #ccc;
padding: 6px;
a {
color: #000;
display: block;
}
}
ul {
li {
background: #fff;
color: #888;
border-bottom: 0;
font-size: 12px;
}
}
}
ul {
list-style: none;
margin-bottom: 1px;
li {
background: #efefef;
border-bottom: 1px solid #666;
padding: 6px;
&.create-module {
position: relative;
> div {
display: none;
@include position(absolute, 30px 0 0 0);
width: 90%;
background: rgba(#000, .9);
padding: 10px;
@include box-sizing(border-box);
@include border-radius(3px);
z-index: 99;
&:before {
content: " ";
display: block;
background: rgba(#000, .8);
width: 10px;
height: 10px;
@include position(absolute, -5px 0 0 50%);
@include transform(rotate(45deg));
}
ul {
li {
border-bottom: 0;
background: none;
input {
width: 100%;
@include box-sizing(border-box);
border-color: #000;
padding: 6px;
}
select {
width: 100%;
@include box-sizing(border-box);
option {
font-size: 14px;
}
}
a {
float: right;
&:first-child {
float: left;
}
}
}
}
}
&:hover {
div {
display: block;
}
}
}
}
}
}
}
section.new-section {
margin-top: 10px;
@include inline-block();
position: relative;
> a {
@extend .button;
display: block;
}
section {
display: none;
@include position(absolute, 30px 0 0 0);
background: rgba(#000, .8);
min-width: 300px;
padding: 10px;
@include box-sizing(border-box);
@include border-radius(3px);
z-index: 99;
&:before {
content: " ";
display: block;
background: rgba(#000, .8);
width: 10px;
height: 10px;
@include position(absolute, -5px 0 0 20%);
@include transform(rotate(45deg));
}
form {
ul {
list-style: none;
li {
border-bottom: 0;
background: none;
margin-bottom: 6px;
input {
width: 100%;
@include box-sizing(border-box);
border-color: #000;
padding: 6px;
}
select {
width: 100%;
@include box-sizing(border-box);
option {
font-size: 14px;
}
}
a {
float: right;
&:first-child {
float: left;
}
}
}
}
}
}
&:hover {
section {
display: block;
}
}
}
}
body.content
section.cal {
width: flex-grid(3) + flex-gutter();
float: left;
overflow: scroll;
@include box-sizing(border-box);
opacity: .4;
@include transition();
> header ul {
display: none;
}
&:hover {
opacity: 1;
}
ol {
li {
@include box-sizing(border-box);
width: 100%;
&.create-module {
display: none;
}
}
}
}
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;
}
}
}
}
section.problem-new, section.problem-edit {
> section {
textarea {
@include box-sizing(border-box);
display: block;
width: 100%;
}
div.preview {
background: #eee;
@include box-sizing(border-box);
height: 40px;
padding: 10px;
width: 100%;
}
a.save {
@extend .button;
@include inline-block();
margin-top: 20px;
}
}
}
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;
}
section.video-new, section.video-edit {
> section {
section.upload {
padding: 6px;
margin-bottom: 10px;
border: 1px solid #ddd;
a.upload-button {
@extend .button;
@include inline-block();
}
}
section.in-use {
h2 {
font-size: 14px;
}
div {
background: #eee;
text-align: center;
padding: 6px;
}
}
a.save-update {
@extend .button;
@include inline-block();
margin-top: 20px;
}
}
}
section.week-edit,
section.week-new,
section.sequence-edit {
> header {
border-bottom: 2px solid #333;
@include clearfix();
div {
@include clearfix();
padding: 6px 20px;
h1 {
font-size: 18px;
text-transform: uppercase;
letter-spacing: 1px;
float: left;
}
p {
float: right;
}
&.week {
background: #eee;
font-size: 12px;
border-bottom: 1px solid #ccc;
h2 {
font-size: 12px;
@include inline-block();
margin-right: 20px;
}
ul {
list-style: none;
@include inline-block();
li {
@include inline-block();
margin-right: 10px;
p {
float: none;
}
}
}
}
}
section.goals {
background: #eee;
padding: 6px 20px;
border-top: 1px solid #ccc;
ul {
list-style: none;
color: #999;
li {
margin-bottom: 6px;
&:last-child {
margin-bottom: 0;
}
}
}
}
}
> section.content {
@include box-sizing(border-box);
padding: 20px;
section.filters {
@include clearfix;
margin-bottom: 10px;
background: #efefef;
border: 1px solid #ddd;
ul {
@include clearfix();
list-style: none;
padding: 6px;
li {
@include inline-block();
&.advanced {
float: right;
}
}
}
}
> div {
display: table;
border: 1px solid;
width: 100%;
section {
header {
background: #eee;
padding: 6px;
border-bottom: 1px solid #ccc;
@include clearfix;
h2 {
text-transform: uppercase;
letter-spacing: 1px;
font-size: 12px;
float: left;
}
}
&.modules {
@include box-sizing(border-box);
display: table-cell;
width: flex-grid(6, 9);
border-right: 1px solid #333;
&.empty {
text-align: center;
vertical-align: middle;
a {
@extend .button;
@include inline-block();
margin-top: 10px;
}
}
ol {
list-style: none;
border-bottom: 1px solid #333;
li {
border-bottom: 1px solid #333;
&:last-child{
border-bottom: 0;
}
a {
color: #000;
}
ol {
list-style: none;
li {
padding: 6px;
&:hover {
a.draggable {
opacity: 1;
}
}
a.draggable {
float: right;
opacity: .5;
}
&.group {
padding: 0;
header {
padding: 6px;
background: none;
h3 {
font-size: 14px;
}
}
ol {
border-left: 4px solid #999;
border-bottom: 0;
li {
&:last-child {
border-bottom: 0;
}
}
}
}
}
}
}
}
}
&.scratch-pad {
@include box-sizing(border-box);
display: table-cell;
width: flex-grid(3, 9) + flex-gutter(9);
vertical-align: top;
ol {
list-style: none;
border-bottom: 1px solid #999;
li {
border-bottom: 1px solid #999;
background: #f9f9f9;
&:last-child {
border-bottom: 0;
}
ul {
list-style: none;
li {
padding: 6px;
&:last-child {
border-bottom: 0;
}
&:hover {
a.draggable {
opacity: 1;
}
}
&.empty {
padding: 12px;
a {
@extend .button;
display: block;
text-align: center;
}
}
a.draggable {
float: right;
opacity: .3;
}
a {
color: #000;
}
}
}
}
}
}
}
}
}
}
@import 'bourbon/bourbon';
@import 'reset';
@import 'base';
@import 'calendar';
@import 'week', 'video', 'problem', 'module-header';
// 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";
// 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/)
$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;
//************************************************************************//
// 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;
// }
@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;
}
}
// 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);
// http://www.w3.org/TR/css3-animations/#the-animation-name-property-
// Each of these mixins support comma separated lists of values, which allows different transitions for individual properties to be described in a single style rule. Each value in the list corresponds to the value at that same position in the other properties.
// Official animation shorthand property.
@mixin animation ($animation-1,
$animation-2: false, $animation-3: false,
$animation-4: false, $animation-5: false,
$animation-6: false, $animation-7: false,
$animation-8: false, $animation-9: false)
{
$full: compact($animation-1, $animation-2, $animation-3, $animation-4,
$animation-5, $animation-6, $animation-7, $animation-8, $animation-9);
-webkit-animation: $full;
-moz-animation: $full;
animation: $full;
}
// Individual Animation Properties
@mixin animation-name ($name-1,
$name-2: false, $name-3: false,
$name-4: false, $name-5: false,
$name-6: false, $name-7: false,
$name-8: false, $name-9: false)
{
$full: compact($name-1, $name-2, $name-3, $name-4,
$name-5, $name-6, $name-7, $name-8, $name-9);
-webkit-animation-name: $full;
-moz-animation-name: $full;
animation-name: $full;
}
@mixin animation-duration ($time-1: 0,
$time-2: false, $time-3: false,
$time-4: false, $time-5: false,
$time-6: false, $time-7: false,
$time-8: false, $time-9: false)
{
$full: compact($time-1, $time-2, $time-3, $time-4,
$time-5, $time-6, $time-7, $time-8, $time-9);
-webkit-animation-duration: $full;
-moz-animation-duration: $full;
animation-duration: $full;
}
@mixin animation-timing-function ($motion-1: ease,
// ease | linear | ease-in | ease-out | ease-in-out
$motion-2: false, $motion-3: false,
$motion-4: false, $motion-5: false,
$motion-6: false, $motion-7: false,
$motion-8: false, $motion-9: false)
{
$full: compact($motion-1, $motion-2, $motion-3, $motion-4,
$motion-5, $motion-6, $motion-7, $motion-8, $motion-9);
-webkit-animation-timing-function: $full;
-moz-animation-timing-function: $full;
animation-timing-function: $full;
}
@mixin animation-iteration-count ($value-1: 1,
// infinite | <number>
$value-2: false, $value-3: false,
$value-4: false, $value-5: false,
$value-6: false, $value-7: false,
$value-8: false, $value-9: false)
{
$full: compact($value-1, $value-2, $value-3, $value-4,
$value-5, $value-6, $value-7, $value-8, $value-9);
-webkit-animation-iteration-count: $full;
-moz-animation-iteration-count: $full;
animation-iteration-count: $full;
}
@mixin animation-direction ($direction-1: normal,
// normal | alternate
$direction-2: false, $direction-3: false,
$direction-4: false, $direction-5: false,
$direction-6: false, $direction-7: false,
$direction-8: false, $direction-9: false)
{
$full: compact($direction-1, $direction-2, $direction-3, $direction-4,
$direction-5, $direction-6, $direction-7, $direction-8, $direction-9);
-webkit-animation-direction: $full;
-moz-animation-direction: $full;
animation-direction: $full;
}
@mixin animation-play-state ($state-1: running,
// running | paused
$state-2: false, $state-3: false,
$state-4: false, $state-5: false,
$state-6: false, $state-7: false,
$state-8: false, $state-9: false)
{
$full: compact($state-1, $state-2, $state-3, $state-4,
$state-5, $state-6, $state-7, $state-8, $state-9);
-webkit-animation-play-state: $full;
-moz-animation-play-state: $full;
animation-play-state: $full;
}
@mixin animation-delay ($time-1: 0,
$time-2: false, $time-3: false,
$time-4: false, $time-5: false,
$time-6: false, $time-7: false,
$time-8: false, $time-9: false)
{
$full: compact($time-1, $time-2, $time-3, $time-4,
$time-5, $time-6, $time-7, $time-8, $time-9);
-webkit-animation-delay: $full;
-moz-animation-delay: $full;
animation-delay: $full;
}
@mixin animation-fill-mode ($mode-1: none,
// http://goo.gl/l6ckm
// none | forwards | backwards | both
$mode-2: false, $mode-3: false,
$mode-4: false, $mode-5: false,
$mode-6: false, $mode-7: false,
$mode-8: false, $mode-9: false)
{
$full: compact($mode-1, $mode-2, $mode-3, $mode-4,
$mode-5, $mode-6, $mode-7, $mode-8, $mode-9);
-webkit-animation-fill-mode: $full;
-moz-animation-fill-mode: $full;
animation-fill-mode: $full;
}
// Deprecated
@mixin animation-basic ($name, $time: 0, $motion: ease) {
$length-of-name: length($name);
$length-of-time: length($time);
$length-of-motion: length($motion);
@if $length-of-name > 1 {
@include animation-name(zip($name));
} @else {
@include animation-name( $name);
}
@if $length-of-time > 1 {
@include animation-duration(zip($time));
} @else {
@include animation-duration( $time);
}
@if $length-of-motion > 1 {
@include animation-timing-function(zip($motion));
} @else {
@include animation-timing-function( $motion);
}
@warn "The animation-basic mixin is deprecated. Use the animation mixin instead.";
}
@mixin appearance ($value) {
-webkit-appearance: $value;
-moz-appearance: $value;
-ms-appearance: $value;
-o-appearance: $value;
appearance: $value;
}
//************************************************************************//
// 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);
@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;
}
@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));
@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);
}
// 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;
}
@mixin box-sizing ($box) {
// content-box | border-box | inherit
-webkit-box-sizing: $box;
-moz-box-sizing: $box;
box-sizing: $box;
}
@mixin columns($arg: auto) {
// <column-count> || <column-width>
-webkit-columns: $arg;
-moz-columns: $arg;
columns: $arg;
}
@mixin column-count($int: auto) {
// auto || integer
-webkit-column-count: $int;
-moz-column-count: $int;
column-count: $int;
}
@mixin column-gap($length: normal) {
// normal || length
-webkit-column-gap: $length;
-moz-column-gap: $length;
column-gap: $length;
}
@mixin column-fill($arg: auto) {
// auto || length
-webkit-columns-fill: $arg;
-moz-columns-fill: $arg;
columns-fill: $arg;
}
@mixin column-rule($arg) {
// <border-width> || <border-style> || <color>
-webkit-column-rule: $arg;
-moz-column-rule: $arg;
column-rule: $arg;
}
@mixin column-rule-color($color) {
-webkit-column-rule-color: $color;
-moz-column-rule-color: $color;
column-rule-color: $color;
}
@mixin column-rule-style($style: none) {
// none | hidden | dashed | dotted | double | groove | inset | inset | outset | ridge | solid
-webkit-column-rule-style: $style;
-moz-column-rule-style: $style;
column-rule-style: $style;
}
@mixin column-rule-width ($width: none) {
-webkit-column-rule-width: $width;
-moz-column-rule-width: $width;
column-rule-width: $width;
}
@mixin column-span($arg: none) {
// none || all
-webkit-column-span: $arg;
-moz-column-span: $arg;
column-span: $arg;
}
@mixin column-width($length: auto) {
// auto || length
-webkit-column-width: $length;
-moz-column-width: $length;
column-width: $length;
}
// 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;
}
// 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;
}
@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%);
// 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);
@mixin transform($property: none) {
// none | <transform-function>
-webkit-transform: $property;
-moz-transform: $property;
-ms-transform: $property;
-o-transform: $property;
transform: $property;
}
@mixin transform-origin($axes: 50%) {
// x-axis - left | center | right | length | %
// y-axis - top | center | bottom | length | %
// z-axis - length
-webkit-transform-origin: $axes;
-moz-transform-origin: $axes;
-ms-transform-origin: $axes;
-o-transform-origin: $axes;
transform-origin: $axes;
}
// 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;
}
@mixin user-select($arg: none) {
-webkit-user-select: $arg;
-moz-user-select: $arg;
-ms-user-select: $arg;
user-select: $arg;
}
// 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;
}
// 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%;
// }
// }
@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;
// }
@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;
}
@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
// 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;
}
// 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;
}
// 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);
}
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")
module Bourbon::SassExtensions
end
require "sass"
require File.join(File.dirname(__FILE__), "/sass_extensions/functions")
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
# 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
<%namespace name='static' file='static_content.html'/>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
% if settings.MITX_FEATURES['USE_DJANGO_PIPELINE']:
<%static:css group='base-style'/>
% else:
<link rel="stylesheet" href="${ STATIC_URL }/css/base-style.css">
% endif
<link rel="stylesheet" type="text/css" href="${ STATIC_URL }/js/markitup/skins/simple/style.css" />
<link rel="stylesheet" type="text/css" href="${ STATIC_URL }/js/markitup/sets/wiki/style.css" />
<title><%block name="title"></%block></title>
<meta name="viewport" content="width=device-width,initial-scale=1">
</head>
<body>
<%include file="widgets/header.html"/>
<%block name="content"></%block>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript" src="${ STATIC_URL }/js/markitup/jquery.markitup.js"></script>
<script type="text/javascript" src="${ STATIC_URL }/js/markitup/sets/wiki/set.js"></script>
<script src="${ STATIC_URL }/js/main.js"></script>
<script src="${ STATIC_URL }/js/jquery.inlineedit.js"></script>
<script src="${ STATIC_URL }/js/jquery.leanModal.min.js"></script>
<script src="${ STATIC_URL }/js/jquery.tablednd.js"></script>
</body>
</html>
<%inherit file="base.html" />
<%block name="title">Course Manager</%block>
<%block name="content">
<section class="main-container">
<%include file="widgets/navigation.html"/>
<section class="main-content">
<%include file="widgets/week-edit.html"/>
<%include file="widgets/week-new.html"/>
<%include file="widgets/sequnce-edit.html"/>
<%include file="widgets/video-edit.html"/>
<%include file="widgets/video-new.html"/>
<%include file="widgets/problem-edit.html"/>
<%include file="widgets/problem-new.html"/>
</section>
</section>
</%block>
<form name="login" action="login", method="post">
<input type="hidden" name="csrfmiddlewaretoken" value="${csrf_token}"/>
% if next is not None:
<input type="hidden" name="next" value="${next}"/>
% endif
Username: <input type="text" name="username" />
Possword: <input type="password" name="password" />
<input type="submit" value="Submit" />
</form>
<header>
<nav>
<h2><a href="/">6.002x circuits and electronics</a></h2>
<ul>
<li>
<a href="#" class="new-module">New Section</a>
</li>
<li>
<a href="#" class="new-module">New Module</a>
</li>
<li>
<a href="#" class="new-module">New Unit</a>
</li>
</ul>
<ul class="user-nav">
<li><a href="#">Tasks</a></li>
<li><a href="#">Settings</a></li>
</ul>
</nav>
</header>
<li class="create-module">
<a href="#" class="new-module">
+ Add new module
</a>
<div>
<form>
<ul>
<li>
<input type="text" name="" id="" placeholder="Moldule title" />
</li>
<li>
<select>
<option>Use template</option>
<option>Lecture Sequence</option>
<option>Use template</option>
</select>
</li>
<li>
<input type="submit" value="Create & Edit Module" />
<div>
<a href="#">Save without edit</a>
<a href="#">Cancel</a>
</div>
</li>
</ul>
</form>
</div>
</li>
<section class="cal">
<header>
<h2>Filter content:</h2>
<ul>
<li>
<a href="#">Sequences</a>
<ul>
<li>Hide all</li>
<li>Lectures</li>
<li>Labs</li>
<li>Homeworks</li>
<li>Exams</li>
</ul>
</li>
<li>
<a href="#">Deadlines</a>
<ul>
<li>Today</li>
<li>Tomorrow</li>
<li>This week</li>
<li>In 2 weeks</li>
<li>This month</li>
</ul>
</li>
<li>
<a href="#">Goals</a>
<ul>
<li>Hide</li>
</ul>
</li>
</ul>
</header>
<ol>
% for week in weeks:
<li>
<header>
<h1><a href="#">${week.name}</a></h1>
<ul>
% if week.goals:
% for goal in week.goals:
<li class="goal editable">${goal}</li>
% endfor
% else:
<li class="goal editable">Please create a learning goal for this week</li>
% endif
</ul>
</header>
<ul>
% for module in week.get_children():
<li class="${module.type}">
<a href="#" class="${module.type}-edit">${module.name}</a>
<a href="#" class="draggable">handle</a>
</li>
% endfor
<%include file="module-dropdown.html"/>
</ul>
</li>
%endfor
<li>
<header>
<h1>Course Scratch Pad</h1>
</header>
<ul>
<li>
<a href="#" class="problem-edit">Problem title 11</a>
<a href="#" class="draggable">handle</a>
</li>
<li>
<a href="#" class="problem-edit">Problem title 13 </a>
<a href="#" class="draggable">handle</a>
</li>
<li>
<a href="#" class="problem-edit"> Problem title 14</a>
<a href="#" class="draggable">handle</a>
</li>
<li>
<a href="" class="video-edit">Video 3</a>
<a href="#" class="draggable">handle</a>
</li>
</ul>
</li>
</ol>
<section class="new-section">
<a href="#" >+ Add New Section</a>
<section>
<form>
<ul>
<li>
<input type="text" name="" id="" placeholder="Section title" />
</li>
<li>
<select>
<option>Blank</option>
<option>6.002x</option>
<option>6.00x</option>
</select>
</li>
<li>
<input type="submit" value="Save and edit week" class="edit-week" />
<div>
<a href="#" class="close">Save without edit</a>
<a href="#" class="close">cancel</a>
</div>
</li>
</ul>
</form>
</section>
</section>
</section>
<a href="" class="default">+ add new</a>
<ul class="new-dropdown">
<li class="import"><a href="#">Import from the edX library</a></li>
<li class="video-new"><a href="#">Create new video segment</a></li>
<li class="problem-new"><a href="#">Create new problem</a></li>
<li class="lab-lab"><a href="#">Create new lab</a></li>
</ul>
<section class="problem-edit">
<header>
<a href="#" class="cancel">Cancel</a>
<a href="#" class="save-update">Save &amp; Update</a>
</header>
<section>
<header>
<h1 class="editable">New Problem</h1>
<section class="author">
<div>
<h2>Last modified:</h2>
<p>mm/dd/yy</p>
</div>
<div>
<h2>By</h2>
<p>Anant Agarwal</p>
</div>
</section>
<section class="status-settings">
<ul>
<li><a href="#" class="current">Scrap</a></li>
<li><a href="#">Draft</a></li>
<li><a href="#">Proofed</a></li>
<li><a href="#">Published</a></li>
</ul>
<a href="#" class="settings">Settings</a>
<select name="" id="">
<option>Global</option>
</select>
</section>
<section class="meta">
<div>
<h2>Tags:</h2>
<p class="editable">Click to edit</p>
</div>
<div>
<h2>Goal</h2>
<p class="editable">Click to edit</p>
</div>
</section>
</header>
<section>
<textarea name="" id= rows="8" cols="40">Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.</textarea>
<div class="preview">
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.
</div>
</section>
<section class="notes">
<h2>Add notes</h2>
<textarea name="" id= rows="8" cols="40"></textarea>
<input type="submit" name="" id="" value="post" />
<ul>
<li>
<p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.</p>
<p class="author">Anant Agarwal</p>
</li>
<li>
<p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.</p>
<p class="author">Anant Agarwal</p>
</li>
</ul> </section>
<a href="" class="save-update">Save &amp; Update</a>
</section>
</section>
This diff is collapsed. Click to expand it.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment