Merge branch 'master' of github.com:MITx/mitx into merge
Conflicts: lms/urls.py
This commit is contained in:
@@ -52,7 +52,7 @@ def certificate_request(request):
|
||||
return return_error(survey_response['error'])
|
||||
|
||||
grade = None
|
||||
student_gradesheet = grades.grade_sheet(request.user)
|
||||
student_gradesheet = grades.grade(request.user, request, course)
|
||||
grade = student_gradesheet['grade']
|
||||
|
||||
if not grade:
|
||||
@@ -65,7 +65,7 @@ def certificate_request(request):
|
||||
else:
|
||||
#This is not a POST, we should render the page with the form
|
||||
|
||||
grade_sheet = grades.grade_sheet(request.user)
|
||||
student_gradesheet = grades.grade(request.user, request, course)
|
||||
certificate_state = certificate_state_for_student(request.user, grade_sheet['grade'])
|
||||
|
||||
if certificate_state['state'] != "requestable":
|
||||
|
||||
@@ -46,12 +46,15 @@ def check_course(course_id, course_must_be_open=True, course_required=True):
|
||||
|
||||
|
||||
def course_image_url(course):
|
||||
return staticfiles_storage.url(course.metadata['data_dir'] + "/images/course_image.jpg")
|
||||
return staticfiles_storage.url(course.metadata['data_dir'] +
|
||||
"/images/course_image.jpg")
|
||||
|
||||
|
||||
def get_course_about_section(course, section_key):
|
||||
"""
|
||||
This returns the snippet of html to be rendered on the course about page, given the key for the section.
|
||||
This returns the snippet of html to be rendered on the course about page,
|
||||
given the key for the section.
|
||||
|
||||
Valid keys:
|
||||
- overview
|
||||
- title
|
||||
@@ -70,18 +73,23 @@ def get_course_about_section(course, section_key):
|
||||
- more_info
|
||||
"""
|
||||
|
||||
# Many of these are stored as html files instead of some semantic markup. This can change without effecting
|
||||
# this interface when we find a good format for defining so many snippets of text/html.
|
||||
# Many of these are stored as html files instead of some semantic
|
||||
# markup. This can change without effecting this interface when we find a
|
||||
# good format for defining so many snippets of text/html.
|
||||
|
||||
# TODO: Remove number, instructors from this list
|
||||
if section_key in ['short_description', 'description', 'key_dates', 'video', 'course_staff_short', 'course_staff_extended',
|
||||
'requirements', 'syllabus', 'textbook', 'faq', 'more_info', 'number', 'instructors', 'overview',
|
||||
'effort', 'end_date', 'prerequisites']:
|
||||
if section_key in ['short_description', 'description', 'key_dates', 'video',
|
||||
'course_staff_short', 'course_staff_extended',
|
||||
'requirements', 'syllabus', 'textbook', 'faq', 'more_info',
|
||||
'number', 'instructors', 'overview',
|
||||
'effort', 'end_date', 'prerequisites']:
|
||||
try:
|
||||
with course.system.resources_fs.open(path("about") / section_key + ".html") as htmlFile:
|
||||
return replace_urls(htmlFile.read().decode('utf-8'), course.metadata['data_dir'])
|
||||
return replace_urls(htmlFile.read().decode('utf-8'),
|
||||
course.metadata['data_dir'])
|
||||
except ResourceNotFoundError:
|
||||
log.warning("Missing about section {key} in course {url}".format(key=section_key, url=course.location.url()))
|
||||
log.warning("Missing about section {key} in course {url}".format(
|
||||
key=section_key, url=course.location.url()))
|
||||
return None
|
||||
elif section_key == "title":
|
||||
return course.metadata.get('display_name', course.url_name)
|
||||
@@ -95,7 +103,9 @@ def get_course_about_section(course, section_key):
|
||||
|
||||
def get_course_info_section(course, section_key):
|
||||
"""
|
||||
This returns the snippet of html to be rendered on the course info page, given the key for the section.
|
||||
This returns the snippet of html to be rendered on the course info page,
|
||||
given the key for the section.
|
||||
|
||||
Valid keys:
|
||||
- handouts
|
||||
- guest_handouts
|
||||
@@ -103,43 +113,51 @@ def get_course_info_section(course, section_key):
|
||||
- guest_updates
|
||||
"""
|
||||
|
||||
# Many of these are stored as html files instead of some semantic markup. This can change without effecting
|
||||
# this interface when we find a good format for defining so many snippets of text/html.
|
||||
# Many of these are stored as html files instead of some semantic
|
||||
# markup. This can change without effecting this interface when we find a
|
||||
# good format for defining so many snippets of text/html.
|
||||
|
||||
if section_key in ['handouts', 'guest_handouts', 'updates', 'guest_updates']:
|
||||
try:
|
||||
with course.system.resources_fs.open(path("info") / section_key + ".html") as htmlFile:
|
||||
return replace_urls(htmlFile.read().decode('utf-8'), course.metadata['data_dir'])
|
||||
return replace_urls(htmlFile.read().decode('utf-8'),
|
||||
course.metadata['data_dir'])
|
||||
except ResourceNotFoundError:
|
||||
log.exception("Missing info section {key} in course {url}".format(key=section_key, url=course.location.url()))
|
||||
log.exception("Missing info section {key} in course {url}".format(
|
||||
key=section_key, url=course.location.url()))
|
||||
return "! Info section missing !"
|
||||
|
||||
raise KeyError("Invalid about key " + str(section_key))
|
||||
|
||||
def course_staff_group_name(course):
|
||||
'''
|
||||
course should be either a CourseDescriptor instance, or a string (the .course entry of a Location)
|
||||
course should be either a CourseDescriptor instance, or a string (the
|
||||
.course entry of a Location)
|
||||
'''
|
||||
if isinstance(course,str):
|
||||
if isinstance(course, str) or isinstance(course, unicode):
|
||||
coursename = course
|
||||
else:
|
||||
coursename = course.metadata.get('data_dir','UnknownCourseName')
|
||||
if not coursename: # Fall 2012: not all course.xml have metadata correct yet
|
||||
coursename = course.metadata.get('course','')
|
||||
# should be a CourseDescriptor, so grab its location.course:
|
||||
coursename = course.location.course
|
||||
return 'staff_%s' % coursename
|
||||
|
||||
def has_staff_access_to_course(user,course):
|
||||
def has_staff_access_to_course(user, course):
|
||||
'''
|
||||
Returns True if the given user has staff access to the course.
|
||||
This means that user is in the staff_* group, or is an overall admin.
|
||||
|
||||
course is the course field of the location being accessed.
|
||||
'''
|
||||
if user is None or (not user.is_authenticated()) or course is None:
|
||||
return False
|
||||
if user.is_staff:
|
||||
return True
|
||||
user_groups = [x[1] for x in user.groups.values_list()] # note this is the Auth group, not UserTestGroup
|
||||
|
||||
# note this is the Auth group, not UserTestGroup
|
||||
user_groups = [x[1] for x in user.groups.values_list()]
|
||||
staff_group = course_staff_group_name(course)
|
||||
log.debug('course %s user %s groups %s' % (staff_group, user, user_groups))
|
||||
log.debug('course %s, staff_group %s, user %s, groups %s' % (
|
||||
course, staff_group, user, user_groups))
|
||||
if staff_group in user_groups:
|
||||
return True
|
||||
return False
|
||||
@@ -154,7 +172,8 @@ def get_courses_by_university(user):
|
||||
Returns dict of lists of courses available, keyed by course.org (ie university).
|
||||
Courses are sorted by course.number.
|
||||
|
||||
if ACCESS_REQUIRE_STAFF_FOR_COURSE then list only includes those accessible to user.
|
||||
if ACCESS_REQUIRE_STAFF_FOR_COURSE then list only includes those accessible
|
||||
to user.
|
||||
'''
|
||||
# TODO: Clean up how 'error' is done.
|
||||
# filter out any courses that errored.
|
||||
@@ -163,9 +182,9 @@ def get_courses_by_university(user):
|
||||
courses = sorted(courses, key=lambda course: course.number)
|
||||
universities = defaultdict(list)
|
||||
for course in courses:
|
||||
if settings.MITX_FEATURES.get('ENABLE_LMS_MIGRATION'):
|
||||
if settings.MITX_FEATURES.get('ACCESS_REQUIRE_STAFF_FOR_COURSE'):
|
||||
if not has_access_to_course(user,course):
|
||||
continue
|
||||
universities[course.org].append(course)
|
||||
return universities
|
||||
|
||||
|
||||
|
||||
@@ -3,26 +3,135 @@ import logging
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
from models import StudentModuleCache
|
||||
from module_render import get_module, get_instance_module
|
||||
from xmodule import graders
|
||||
from xmodule.graders import Score
|
||||
from models import StudentModule
|
||||
|
||||
_log = logging.getLogger("mitx.courseware")
|
||||
log = logging.getLogger("mitx.courseware")
|
||||
|
||||
|
||||
def grade_sheet(student, course, grader, student_module_cache):
|
||||
def yield_module_descendents(module):
|
||||
for child in module.get_display_items():
|
||||
yield child
|
||||
for module in yield_module_descendents(child):
|
||||
yield module
|
||||
|
||||
def grade(student, request, course, student_module_cache=None):
|
||||
"""
|
||||
This pulls a summary of all problems in the course. It returns a dictionary
|
||||
with two datastructures:
|
||||
This grades a student as quickly as possible. It retuns the
|
||||
output from the course grader, augmented with the final letter
|
||||
grade. The keys in the output are:
|
||||
|
||||
- grade : A final letter grade.
|
||||
- percent : The final percent for the class (rounded up).
|
||||
- section_breakdown : A breakdown of each section that makes
|
||||
up the grade. (For display)
|
||||
- grade_breakdown : A breakdown of the major components that
|
||||
make up the final grade. (For display)
|
||||
|
||||
More information on the format is in the docstring for CourseGrader.
|
||||
"""
|
||||
|
||||
grading_context = course.grading_context
|
||||
|
||||
if student_module_cache == None:
|
||||
student_module_cache = StudentModuleCache(student, grading_context['all_descriptors'])
|
||||
|
||||
totaled_scores = {}
|
||||
# This next complicated loop is just to collect the totaled_scores, which is
|
||||
# passed to the grader
|
||||
for section_format, sections in grading_context['graded_sections'].iteritems():
|
||||
format_scores = []
|
||||
for section in sections:
|
||||
section_descriptor = section['section_descriptor']
|
||||
section_name = section_descriptor.metadata.get('display_name')
|
||||
|
||||
should_grade_section = False
|
||||
# If we haven't seen a single problem in the section, we don't have to grade it at all! We can assume 0%
|
||||
for moduledescriptor in section['xmoduledescriptors']:
|
||||
if student_module_cache.lookup(moduledescriptor.category, moduledescriptor.location.url() ):
|
||||
should_grade_section = True
|
||||
break
|
||||
|
||||
if should_grade_section:
|
||||
scores = []
|
||||
# TODO: We need the request to pass into here. If we could forgo that, our arguments
|
||||
# would be simpler
|
||||
section_module = get_module(student, request, section_descriptor.location, student_module_cache)
|
||||
|
||||
# TODO: We may be able to speed this up by only getting a list of children IDs from section_module
|
||||
# Then, we may not need to instatiate any problems if they are already in the database
|
||||
for module in yield_module_descendents(section_module):
|
||||
(correct, total) = get_score(student, module, student_module_cache)
|
||||
if correct is None and total is None:
|
||||
continue
|
||||
|
||||
if settings.GENERATE_PROFILE_SCORES:
|
||||
if total > 1:
|
||||
correct = random.randrange(max(total - 2, 1), total + 1)
|
||||
else:
|
||||
correct = total
|
||||
|
||||
graded = module.metadata.get("graded", False)
|
||||
if not total > 0:
|
||||
#We simply cannot grade a problem that is 12/0, because we might need it as a percentage
|
||||
graded = False
|
||||
|
||||
scores.append(Score(correct, total, graded, module.metadata.get('display_name')))
|
||||
|
||||
section_total, graded_total = graders.aggregate_scores(scores, section_name)
|
||||
else:
|
||||
section_total = Score(0.0, 1.0, False, section_name)
|
||||
graded_total = Score(0.0, 1.0, True, section_name)
|
||||
|
||||
#Add the graded total to totaled_scores
|
||||
if graded_total.possible > 0:
|
||||
format_scores.append(graded_total)
|
||||
else:
|
||||
log.exception("Unable to grade a section with a total possible score of zero. " + str(section_descriptor.id))
|
||||
|
||||
totaled_scores[section_format] = format_scores
|
||||
|
||||
grade_summary = course.grader.grade(totaled_scores)
|
||||
|
||||
# We round the grade here, to make sure that the grade is an whole percentage and
|
||||
# doesn't get displayed differently than it gets grades
|
||||
grade_summary['percent'] = round(grade_summary['percent'] * 100 + 0.05) / 100
|
||||
|
||||
letter_grade = grade_for_percentage(course.grade_cutoffs, grade_summary['percent'])
|
||||
grade_summary['grade'] = letter_grade
|
||||
|
||||
return grade_summary
|
||||
|
||||
- courseware_summary is a summary of all sections with problems in the
|
||||
course. It is organized as an array of chapters, each containing an array of
|
||||
sections, each containing an array of scores. This contains information for
|
||||
graded and ungraded problems, and is good for displaying a course summary
|
||||
with due dates, etc.
|
||||
def grade_for_percentage(grade_cutoffs, percentage):
|
||||
"""
|
||||
Returns a letter grade 'A' 'B' 'C' or None.
|
||||
|
||||
Arguments
|
||||
- grade_cutoffs is a dictionary mapping a grade to the lowest
|
||||
possible percentage to earn that grade.
|
||||
- percentage is the final percent across all problems in a course
|
||||
"""
|
||||
|
||||
letter_grade = None
|
||||
for possible_grade in ['A', 'B', 'C']:
|
||||
if percentage >= grade_cutoffs[possible_grade]:
|
||||
letter_grade = possible_grade
|
||||
break
|
||||
|
||||
return letter_grade
|
||||
|
||||
- grade_summary is the output from the course grader. More information on
|
||||
the format is in the docstring for CourseGrader.
|
||||
def progress_summary(student, course, grader, student_module_cache):
|
||||
"""
|
||||
This pulls a summary of all problems in the course.
|
||||
|
||||
Returns
|
||||
- courseware_summary is a summary of all sections with problems in the course.
|
||||
It is organized as an array of chapters, each containing an array of sections,
|
||||
each containing an array of scores. This contains information for graded and
|
||||
ungraded problems, and is good for displaying a course summary with due dates,
|
||||
etc.
|
||||
|
||||
Arguments:
|
||||
student: A User object for the student to grade
|
||||
@@ -30,49 +139,24 @@ def grade_sheet(student, course, grader, student_module_cache):
|
||||
student_module_cache: A StudentModuleCache initialized with all
|
||||
instance_modules for the student
|
||||
"""
|
||||
totaled_scores = {}
|
||||
chapters = []
|
||||
for c in course.get_children():
|
||||
sections = []
|
||||
for s in c.get_children():
|
||||
def yield_descendents(module):
|
||||
yield module
|
||||
for child in module.get_display_items():
|
||||
for module in yield_descendents(child):
|
||||
yield module
|
||||
|
||||
graded = s.metadata.get('graded', False)
|
||||
scores = []
|
||||
for module in yield_descendents(s):
|
||||
for module in yield_module_descendents(s):
|
||||
(correct, total) = get_score(student, module, student_module_cache)
|
||||
|
||||
if correct is None and total is None:
|
||||
continue
|
||||
|
||||
if settings.GENERATE_PROFILE_SCORES:
|
||||
if total > 1:
|
||||
correct = random.randrange(max(total - 2, 1), total + 1)
|
||||
else:
|
||||
correct = total
|
||||
|
||||
if not total > 0:
|
||||
#We simply cannot grade a problem that is 12/0, because we
|
||||
#might need it as a percentage
|
||||
graded = False
|
||||
|
||||
scores.append(Score(correct, total, graded,
|
||||
module.metadata.get('display_name')))
|
||||
scores.append(Score(correct, total, graded,
|
||||
module.metadata.get('display_name')))
|
||||
|
||||
section_total, graded_total = graders.aggregate_scores(
|
||||
scores, s.metadata.get('display_name'))
|
||||
|
||||
#Add the graded total to totaled_scores
|
||||
format = s.metadata.get('format', "")
|
||||
if format and graded_total.possible > 0:
|
||||
format_scores = totaled_scores.get(format, [])
|
||||
format_scores.append(graded_total)
|
||||
totaled_scores[format] = format_scores
|
||||
|
||||
sections.append({
|
||||
'display_name': s.display_name,
|
||||
'url_name': s.url_name,
|
||||
@@ -88,13 +172,10 @@ def grade_sheet(student, course, grader, student_module_cache):
|
||||
'url_name': c.url_name,
|
||||
'sections': sections})
|
||||
|
||||
grade_summary = grader.grade(totaled_scores)
|
||||
|
||||
return {'courseware_summary': chapters,
|
||||
'grade_summary': grade_summary}
|
||||
return chapters
|
||||
|
||||
|
||||
def get_score(user, problem, cache):
|
||||
def get_score(user, problem, student_module_cache):
|
||||
"""
|
||||
Return the score for a user on a problem
|
||||
|
||||
@@ -105,17 +186,18 @@ def get_score(user, problem, cache):
|
||||
correct = 0.0
|
||||
|
||||
# If the ID is not in the cache, add the item
|
||||
instance_module = cache.lookup(problem.category, problem.id)
|
||||
if instance_module is None:
|
||||
instance_module = StudentModule(module_type=problem.category,
|
||||
module_state_key=problem.id,
|
||||
student=user,
|
||||
state=None,
|
||||
grade=0,
|
||||
max_grade=problem.max_score(),
|
||||
done='i')
|
||||
cache.append(instance_module)
|
||||
instance_module.save()
|
||||
instance_module = get_instance_module(user, problem, student_module_cache)
|
||||
# instance_module = student_module_cache.lookup(problem.category, problem.id)
|
||||
# if instance_module is None:
|
||||
# instance_module = StudentModule(module_type=problem.category,
|
||||
# module_state_key=problem.id,
|
||||
# student=user,
|
||||
# state=None,
|
||||
# grade=0,
|
||||
# max_grade=problem.max_score(),
|
||||
# done='i')
|
||||
# cache.append(instance_module)
|
||||
# instance_module.save()
|
||||
|
||||
# If this problem is ungraded/ungradable, bail
|
||||
if instance_module.max_grade is None:
|
||||
@@ -126,8 +208,11 @@ def get_score(user, problem, cache):
|
||||
|
||||
if correct is not None and total is not None:
|
||||
#Now we re-weight the problem, if specified
|
||||
weight = getattr(problem, 'weight', 1)
|
||||
if weight != 1:
|
||||
weight = getattr(problem, 'weight', None)
|
||||
if weight is not None:
|
||||
if total == 0:
|
||||
log.exception("Cannot reweight a problem with zero weight. Problem: " + str(instance_module))
|
||||
return (correct, total)
|
||||
correct = correct * weight / total
|
||||
total = weight
|
||||
|
||||
|
||||
@@ -78,8 +78,8 @@ class Command(BaseCommand):
|
||||
|
||||
# TODO (cpennington): Get coursename in a legitimate way
|
||||
course_location = 'i4x://edx/6002xs12/course/6.002_Spring_2012'
|
||||
student_module_cache = StudentModuleCache(sample_user, modulestore().get_item(course_location))
|
||||
(course, _, _, _) = get_module(sample_user, None, course_location, student_module_cache)
|
||||
student_module_cache = StudentModuleCache.cache_for_descriptor_descendents(sample_user, modulestore().get_item(course_location))
|
||||
course = get_module(sample_user, None, course_location, student_module_cache)
|
||||
|
||||
to_run = [
|
||||
#TODO (vshnayder) : make check_rendering work (use module_render.py),
|
||||
|
||||
@@ -67,17 +67,19 @@ class StudentModuleCache(object):
|
||||
"""
|
||||
A cache of StudentModules for a specific student
|
||||
"""
|
||||
def __init__(self, user, descriptor, depth=None):
|
||||
def __init__(self, user, descriptors):
|
||||
'''
|
||||
Find any StudentModule objects that are needed by any child modules of the
|
||||
supplied descriptor. Avoids making multiple queries to the database
|
||||
|
||||
descriptor: An XModuleDescriptor
|
||||
depth is the number of levels of descendent modules to load StudentModules for, in addition to
|
||||
the supplied descriptor. If depth is None, load all descendent StudentModules
|
||||
supplied descriptor, or caches only the StudentModule objects specifically
|
||||
for every descriptor in descriptors. Avoids making multiple queries to the
|
||||
database.
|
||||
|
||||
Arguments
|
||||
user: The user for which to fetch maching StudentModules
|
||||
descriptors: An array of XModuleDescriptors.
|
||||
'''
|
||||
if user.is_authenticated():
|
||||
module_ids = self._get_module_state_keys(descriptor, depth)
|
||||
module_ids = self._get_module_state_keys(descriptors)
|
||||
|
||||
# This works around a limitation in sqlite3 on the number of parameters
|
||||
# that can be put into a single query
|
||||
@@ -91,27 +93,52 @@ class StudentModuleCache(object):
|
||||
|
||||
else:
|
||||
self.cache = []
|
||||
|
||||
def _get_module_state_keys(self, descriptor, depth):
|
||||
'''
|
||||
Get a list of the state_keys needed for StudentModules
|
||||
required for this module descriptor
|
||||
|
||||
|
||||
|
||||
@classmethod
|
||||
def cache_for_descriptor_descendents(cls, user, descriptor, depth=None, descriptor_filter=lambda descriptor: True):
|
||||
"""
|
||||
descriptor: An XModuleDescriptor
|
||||
depth is the number of levels of descendent modules to load StudentModules for, in addition to
|
||||
the supplied descriptor. If depth is None, load all descendent StudentModules
|
||||
descriptor_filter is a function that accepts a descriptor and return wether the StudentModule
|
||||
should be cached
|
||||
"""
|
||||
|
||||
def get_child_descriptors(descriptor, depth, descriptor_filter):
|
||||
if descriptor_filter(descriptor):
|
||||
descriptors = [descriptor]
|
||||
else:
|
||||
descriptors = []
|
||||
|
||||
if depth is None or depth > 0:
|
||||
new_depth = depth - 1 if depth is not None else depth
|
||||
|
||||
for child in descriptor.get_children():
|
||||
descriptors.extend(get_child_descriptors(child, new_depth, descriptor_filter))
|
||||
|
||||
return descriptors
|
||||
|
||||
|
||||
descriptors = get_child_descriptors(descriptor, depth, descriptor_filter)
|
||||
|
||||
return StudentModuleCache(user, descriptors)
|
||||
|
||||
def _get_module_state_keys(self, descriptors):
|
||||
'''
|
||||
keys = [descriptor.location.url()]
|
||||
|
||||
shared_state_key = getattr(descriptor, 'shared_state_key', None)
|
||||
if shared_state_key is not None:
|
||||
keys.append(shared_state_key)
|
||||
|
||||
if depth is None or depth > 0:
|
||||
new_depth = depth - 1 if depth is not None else depth
|
||||
|
||||
for child in descriptor.get_children():
|
||||
keys.extend(self._get_module_state_keys(child, new_depth))
|
||||
Get a list of the state_keys needed for StudentModules
|
||||
required for this module descriptor
|
||||
|
||||
descriptor_filter is a function that accepts a descriptor and return wether the StudentModule
|
||||
should be cached
|
||||
'''
|
||||
keys = []
|
||||
for descriptor in descriptors:
|
||||
keys.append(descriptor.location.url())
|
||||
|
||||
shared_state_key = getattr(descriptor, 'shared_state_key', None)
|
||||
if shared_state_key is not None:
|
||||
keys.append(shared_state_key)
|
||||
|
||||
return keys
|
||||
|
||||
|
||||
@@ -50,9 +50,9 @@ def toc_for_course(user, request, course, active_chapter, active_section):
|
||||
|
||||
chapters with name 'hidden' are skipped.
|
||||
'''
|
||||
|
||||
student_module_cache = StudentModuleCache(user, course, depth=2)
|
||||
(course, _, _, _) = get_module(user, request, course.location, student_module_cache)
|
||||
|
||||
student_module_cache = StudentModuleCache.cache_for_descriptor_descendents(user, course, depth=2)
|
||||
course = get_module(user, request, course.location, student_module_cache)
|
||||
|
||||
chapters = list()
|
||||
for chapter in course.get_display_items():
|
||||
@@ -121,25 +121,26 @@ def get_module(user, request, location, student_module_cache, position=None):
|
||||
- position : extra information from URL for user-specified
|
||||
position within module
|
||||
|
||||
Returns:
|
||||
- a tuple (xmodule instance, instance_module, shared_module, module category).
|
||||
instance_module is a StudentModule specific to this module for this student,
|
||||
or None if this is an anonymous user
|
||||
shared_module is a StudentModule specific to all modules with the same
|
||||
'shared_state_key' attribute, or None if the module does not elect to
|
||||
share state
|
||||
Returns: xmodule instance
|
||||
|
||||
'''
|
||||
descriptor = modulestore().get_item(location)
|
||||
|
||||
instance_module = student_module_cache.lookup(descriptor.category,
|
||||
descriptor.location.url())
|
||||
|
||||
shared_state_key = getattr(descriptor, 'shared_state_key', None)
|
||||
if shared_state_key is not None:
|
||||
shared_module = student_module_cache.lookup(descriptor.category,
|
||||
shared_state_key)
|
||||
|
||||
#TODO Only check the cache if this module can possibly have state
|
||||
if user.is_authenticated():
|
||||
instance_module = student_module_cache.lookup(descriptor.category,
|
||||
descriptor.location.url())
|
||||
|
||||
shared_state_key = getattr(descriptor, 'shared_state_key', None)
|
||||
if shared_state_key is not None:
|
||||
shared_module = student_module_cache.lookup(descriptor.category,
|
||||
shared_state_key)
|
||||
else:
|
||||
shared_module = None
|
||||
else:
|
||||
instance_module = None
|
||||
shared_module = None
|
||||
|
||||
|
||||
instance_state = instance_module.state if instance_module is not None else {}
|
||||
shared_state = shared_module.state if shared_module is not None else None
|
||||
@@ -163,9 +164,8 @@ def get_module(user, request, location, student_module_cache, position=None):
|
||||
'default_queuename': xqueue_default_queuename.replace(' ','_') }
|
||||
|
||||
def _get_module(location):
|
||||
(module, _, _, _) = get_module(user, request, location,
|
||||
return get_module(user, request, location,
|
||||
student_module_cache, position)
|
||||
return module
|
||||
|
||||
# TODO (cpennington): When modules are shared between courses, the static
|
||||
# prefix is going to have to be specific to the module, not the directory
|
||||
@@ -198,31 +198,59 @@ def get_module(user, request, location, student_module_cache, position=None):
|
||||
if has_staff_access_to_course(user, module.location.course):
|
||||
module.get_html = add_histogram(module.get_html, module)
|
||||
|
||||
# If StudentModule for this instance wasn't already in the database,
|
||||
# and this isn't a guest user, create it.
|
||||
return module
|
||||
|
||||
def get_instance_module(user, module, student_module_cache):
|
||||
"""
|
||||
Returns instance_module is a StudentModule specific to this module for this student,
|
||||
or None if this is an anonymous user
|
||||
"""
|
||||
if user.is_authenticated():
|
||||
instance_module = student_module_cache.lookup(module.category,
|
||||
module.location.url())
|
||||
|
||||
if not instance_module:
|
||||
instance_module = StudentModule(
|
||||
student=user,
|
||||
module_type=descriptor.category,
|
||||
module_type=module.category,
|
||||
module_state_key=module.id,
|
||||
state=module.get_instance_state(),
|
||||
max_grade=module.max_score())
|
||||
instance_module.save()
|
||||
# Add to cache. The caller and the system context have references
|
||||
# to it, so the change persists past the return
|
||||
student_module_cache.append(instance_module)
|
||||
if not shared_module and shared_state_key is not None:
|
||||
shared_module = StudentModule(
|
||||
student=user,
|
||||
module_type=descriptor.category,
|
||||
module_state_key=shared_state_key,
|
||||
state=module.get_shared_state())
|
||||
shared_module.save()
|
||||
student_module_cache.append(shared_module)
|
||||
|
||||
return (module, instance_module, shared_module, descriptor.category)
|
||||
|
||||
|
||||
return instance_module
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_shared_instance_module(user, module, student_module_cache):
|
||||
"""
|
||||
Return shared_module is a StudentModule specific to all modules with the same
|
||||
'shared_state_key' attribute, or None if the module does not elect to
|
||||
share state
|
||||
"""
|
||||
if user.is_authenticated():
|
||||
# To get the shared_state_key, we need to descriptor
|
||||
descriptor = modulestore().get_item(module.location)
|
||||
|
||||
shared_state_key = getattr(module, 'shared_state_key', None)
|
||||
if shared_state_key is not None:
|
||||
shared_module = student_module_cache.lookup(module.category,
|
||||
shared_state_key)
|
||||
if not shared_module:
|
||||
shared_module = StudentModule(
|
||||
student=user,
|
||||
module_type=descriptor.category,
|
||||
module_state_key=shared_state_key,
|
||||
state=module.get_shared_state())
|
||||
shared_module.save()
|
||||
student_module_cache.append(shared_module)
|
||||
else:
|
||||
shared_module = None
|
||||
|
||||
return shared_module
|
||||
else:
|
||||
return None
|
||||
|
||||
@csrf_exempt
|
||||
def xqueue_callback(request, userid, id, dispatch):
|
||||
@@ -240,12 +268,13 @@ def xqueue_callback(request, userid, id, dispatch):
|
||||
# Retrieve target StudentModule
|
||||
user = User.objects.get(id=userid)
|
||||
|
||||
student_module_cache = StudentModuleCache(user, modulestore().get_item(id))
|
||||
instance, instance_module, shared_module, module_type = get_module(request.user, request, id, student_module_cache)
|
||||
student_module_cache = StudentModuleCache.cache_for_descriptor_descendents(user, modulestore().get_item(id))
|
||||
instance = get_module(user, request, id, student_module_cache)
|
||||
instance_module = get_instance_module(user, instance, student_module_cache)
|
||||
|
||||
if instance_module is None:
|
||||
log.debug("Couldn't find module '%s' for user '%s'",
|
||||
id, request.user)
|
||||
id, user)
|
||||
raise Http404
|
||||
|
||||
oldgrade = instance_module.grade
|
||||
@@ -285,16 +314,18 @@ def modx_dispatch(request, dispatch=None, id=None):
|
||||
- id -- the module id. Used to look up the XModule instance
|
||||
'''
|
||||
# ''' (fix emacs broken parsing)
|
||||
|
||||
# Check for submitted files
|
||||
p = request.POST.copy()
|
||||
if request.FILES:
|
||||
for inputfile_id in request.FILES.keys():
|
||||
p[inputfile_id] = request.FILES[inputfile_id]
|
||||
|
||||
student_module_cache = StudentModuleCache(request.user, modulestore().get_item(id))
|
||||
instance, instance_module, shared_module, module_type = get_module(request.user, request, id, student_module_cache)
|
||||
student_module_cache = StudentModuleCache.cache_for_descriptor_descendents(request.user, modulestore().get_item(id))
|
||||
instance = get_module(request.user, request, id, student_module_cache)
|
||||
|
||||
instance_module = get_instance_module(request.user, instance, student_module_cache)
|
||||
shared_module = get_shared_instance_module(request.user, instance, student_module_cache)
|
||||
|
||||
# Don't track state for anonymous users (who don't have student modules)
|
||||
if instance_module is not None:
|
||||
oldgrade = instance_module.grade
|
||||
|
||||
@@ -135,10 +135,25 @@ class ActivateLoginTestCase(TestCase):
|
||||
class PageLoader(ActivateLoginTestCase):
|
||||
''' Base class that adds a function to load all pages in a modulestore '''
|
||||
|
||||
|
||||
def enroll(self, course):
|
||||
resp = self.client.post('/change_enrollment', {
|
||||
'enrollment_action': 'enroll',
|
||||
'course_id': course.id,
|
||||
})
|
||||
data = parse_json(resp)
|
||||
self.assertTrue(data['success'])
|
||||
|
||||
def check_pages_load(self, course_name, data_dir, modstore):
|
||||
print "Checking course {0} in {1}".format(course_name, data_dir)
|
||||
import_from_xml(modstore, data_dir, [course_name])
|
||||
|
||||
# enroll in the course before trying to access pages
|
||||
courses = modstore.get_courses()
|
||||
self.assertEqual(len(courses), 1)
|
||||
course = courses[0]
|
||||
self.enroll(course)
|
||||
|
||||
n = 0
|
||||
num_bad = 0
|
||||
all_ok = True
|
||||
|
||||
@@ -48,7 +48,6 @@ log = logging.getLogger("mitx.courseware")
|
||||
|
||||
template_imports = {'urllib': urllib}
|
||||
|
||||
|
||||
def user_groups(user):
|
||||
if not user.is_authenticated():
|
||||
return []
|
||||
@@ -59,6 +58,8 @@ def user_groups(user):
|
||||
|
||||
# Kill caching on dev machines -- we switch groups a lot
|
||||
group_names = cache.get(key)
|
||||
if settings.DEBUG:
|
||||
group_names = None
|
||||
|
||||
if group_names is None:
|
||||
group_names = [u.name for u in UserTestGroup.objects.filter(users=user)]
|
||||
@@ -82,18 +83,17 @@ def gradebook(request, course_id):
|
||||
if 'course_admin' not in user_groups(request.user):
|
||||
raise Http404
|
||||
course = check_course(course_id)
|
||||
|
||||
|
||||
student_objects = User.objects.all()[:100]
|
||||
student_info = []
|
||||
|
||||
for student in student_objects:
|
||||
student_module_cache = StudentModuleCache(student, course)
|
||||
course, _, _, _ = get_module(request.user, request, course.location, student_module_cache)
|
||||
|
||||
#TODO: Only select students who are in the course
|
||||
for student in student_objects:
|
||||
student_info.append({
|
||||
'username': student.username,
|
||||
'id': student.id,
|
||||
'email': student.email,
|
||||
'grade_info': grades.grade_sheet(student, course, student_module_cache),
|
||||
'grade_summary': grades.grade(student, request, course),
|
||||
'realname': UserProfile.objects.get(user=student).name
|
||||
})
|
||||
|
||||
@@ -116,18 +116,23 @@ def profile(request, course_id, student_id=None):
|
||||
|
||||
user_info = UserProfile.objects.get(user=student)
|
||||
|
||||
student_module_cache = StudentModuleCache(request.user, course)
|
||||
course_module, _, _, _ = get_module(request.user, request, course.location, student_module_cache)
|
||||
|
||||
student_module_cache = StudentModuleCache.cache_for_descriptor_descendents(request.user, course)
|
||||
course_module = get_module(request.user, request, course.location, student_module_cache)
|
||||
|
||||
courseware_summary = grades.progress_summary(student, course_module, course.grader, student_module_cache)
|
||||
grade_summary = grades.grade(request.user, request, course, student_module_cache)
|
||||
|
||||
context = {'name': user_info.name,
|
||||
'username': student.username,
|
||||
'location': user_info.location,
|
||||
'language': user_info.language,
|
||||
'email': student.email,
|
||||
'course': course,
|
||||
'csrf': csrf(request)['csrf_token']
|
||||
'csrf': csrf(request)['csrf_token'],
|
||||
'courseware_summary' : courseware_summary,
|
||||
'grade_summary' : grade_summary
|
||||
}
|
||||
context.update(grades.grade_sheet(student, course_module, course.grader, student_module_cache))
|
||||
context.update()
|
||||
|
||||
return render_to_response('profile.html', context)
|
||||
|
||||
@@ -198,11 +203,12 @@ def index(request, course_id, chapter=None, section=None,
|
||||
if look_for_module:
|
||||
section_descriptor = get_section(course, chapter, section)
|
||||
if section_descriptor is not None:
|
||||
student_module_cache = StudentModuleCache(request.user,
|
||||
student_module_cache = StudentModuleCache.cache_for_descriptor_descendents(
|
||||
request.user,
|
||||
section_descriptor)
|
||||
module, _, _, _ = get_module(request.user, request,
|
||||
section_descriptor.location,
|
||||
student_module_cache)
|
||||
module = get_module(request.user, request,
|
||||
section_descriptor.location,
|
||||
student_module_cache)
|
||||
context['content'] = module.get_html()
|
||||
else:
|
||||
log.warning("Couldn't find a section descriptor for course_id '{0}',"
|
||||
|
||||
@@ -158,6 +158,9 @@ COURSE_SETTINGS = {'6.002x_Fall_2012': {'number' : '6.002x',
|
||||
}
|
||||
}
|
||||
|
||||
# IP addresses that are allowed to reload the course, etc.
|
||||
# TODO (vshnayder): Will probably need to change as we get real access control in.
|
||||
LMS_MIGRATION_ALLOWED_IPS = []
|
||||
|
||||
############################### XModule Store ##################################
|
||||
MODULESTORE = {
|
||||
|
||||
@@ -16,3 +16,8 @@ MITX_FEATURES['ENABLE_TEXTBOOK'] = False
|
||||
MITX_FEATURES['ENABLE_DISCUSSION'] = False
|
||||
MITX_FEATURES['ACCESS_REQUIRE_STAFF_FOR_COURSE'] = True # require that user be in the staff_* group to be able to enroll
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# disable django debug toolbars
|
||||
|
||||
INSTALLED_APPS = tuple([ app for app in INSTALLED_APPS if not app.startswith('debug_toolbar') ])
|
||||
MIDDLEWARE_CLASSES = tuple([ mcl for mcl in MIDDLEWARE_CLASSES if not mcl.startswith('debug_toolbar') ])
|
||||
|
||||
BIN
lms/static/images/textbook/textbook-left.png
Normal file
BIN
lms/static/images/textbook/textbook-left.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 783 B |
BIN
lms/static/images/textbook/textbook-right.png
Normal file
BIN
lms/static/images/textbook/textbook-right.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 822 B |
@@ -20,7 +20,7 @@ div.info-wrapper {
|
||||
|
||||
> li {
|
||||
@extend .clearfix;
|
||||
border-bottom: 1px solid #e3e3e3;
|
||||
border-bottom: 1px solid lighten($border-color, 10%);
|
||||
margin-bottom: lh();
|
||||
padding-bottom: lh(.5);
|
||||
list-style-type: disk;
|
||||
@@ -76,42 +76,29 @@ div.info-wrapper {
|
||||
h1 {
|
||||
@extend .bottom-border;
|
||||
padding: lh(.5) lh(.5);
|
||||
}
|
||||
|
||||
header {
|
||||
|
||||
// h1 {
|
||||
// font-weight: 100;
|
||||
// font-style: italic;
|
||||
// }
|
||||
|
||||
p {
|
||||
color: #666;
|
||||
font-size: 12px;
|
||||
margin-bottom: 0;
|
||||
margin-top: 4px;
|
||||
}
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
ol {
|
||||
background: none;
|
||||
list-style: none;
|
||||
padding-left: 0;
|
||||
margin: 0;
|
||||
|
||||
li {
|
||||
@extend .clearfix;
|
||||
background: none;
|
||||
border-bottom: 1px solid #d3d3d3;
|
||||
@include box-shadow(0 1px 0 #eee);
|
||||
border-bottom: 1px solid $border-color;
|
||||
@include box-sizing(border-box);
|
||||
padding: em(7) lh(.75);
|
||||
position: relative;
|
||||
font-size: 1em;
|
||||
|
||||
&.expandable,
|
||||
&.collapsable {
|
||||
h4 {
|
||||
font-style: $body-font-size;
|
||||
font-weight: normal;
|
||||
font-size: 1em;
|
||||
padding-left: 18px;
|
||||
}
|
||||
}
|
||||
@@ -122,16 +109,12 @@ div.info-wrapper {
|
||||
|
||||
li {
|
||||
border-bottom: 0;
|
||||
border-top: 1px solid #d3d3d3;
|
||||
border-top: 1px solid $border-color;
|
||||
@include box-shadow(inset 0 1px 0 #eee);
|
||||
padding-left: lh(1.5);
|
||||
font-size: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: #e9e9e9;
|
||||
}
|
||||
|
||||
div.hitarea {
|
||||
background-image: url('../images/treeview-default.gif');
|
||||
display: block;
|
||||
@@ -159,14 +142,12 @@ div.info-wrapper {
|
||||
h3 {
|
||||
border-bottom: 0;
|
||||
@include box-shadow(none);
|
||||
color: #999;
|
||||
font-size: $body-font-size;
|
||||
font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
color: #aaa;
|
||||
font-size: 1em;
|
||||
margin-bottom: em(6);
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: $body-font-size;
|
||||
letter-spacing: 0;
|
||||
margin: 0;
|
||||
text-transform: none;
|
||||
@@ -191,14 +172,8 @@ div.info-wrapper {
|
||||
}
|
||||
|
||||
a {
|
||||
color: lighten($text-color, 10%);
|
||||
@include inline-block();
|
||||
text-decoration: none;
|
||||
@include transition();
|
||||
|
||||
&:hover {
|
||||
color: $mit-red;
|
||||
}
|
||||
line-height: lh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,38 +10,26 @@ div.profile-wrapper {
|
||||
|
||||
header {
|
||||
@extend .bottom-border;
|
||||
margin: 0 ;
|
||||
padding: lh(.5) lh();
|
||||
margin: 0;
|
||||
padding: lh(.5);
|
||||
|
||||
h1 {
|
||||
font-size: 18px;
|
||||
margin: 0;
|
||||
padding-right: 30px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
position: absolute;
|
||||
right: lh(.5);
|
||||
text-transform: uppercase;
|
||||
top: 13px;
|
||||
|
||||
&:hover {
|
||||
color: #555;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
||||
li {
|
||||
border-bottom: 1px solid #d3d3d3;
|
||||
@include box-shadow(0 1px 0 #eee);
|
||||
color: lighten($text-color, 10%);
|
||||
display: block;
|
||||
padding: 7px lh();
|
||||
padding: lh(.5) 0 lh(.5) lh(.5);
|
||||
position: relative;
|
||||
text-decoration: none;
|
||||
@include transition();
|
||||
@@ -144,11 +132,14 @@ div.profile-wrapper {
|
||||
@extend .content;
|
||||
|
||||
header {
|
||||
@extend h1.top-header;
|
||||
@extend .clearfix;
|
||||
@extend h1.top-header;
|
||||
margin-bottom: lh();
|
||||
|
||||
h1 {
|
||||
float: left;
|
||||
font-size: 1em;
|
||||
font-weight: 100;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
@@ -162,6 +153,7 @@ div.profile-wrapper {
|
||||
border-top: 1px solid #e3e3e3;
|
||||
list-style: none;
|
||||
margin-top: lh();
|
||||
padding-left: 0;
|
||||
|
||||
> li {
|
||||
@extend .clearfix;
|
||||
@@ -178,9 +170,11 @@ div.profile-wrapper {
|
||||
border-right: 1px dashed #ddd;
|
||||
@include box-sizing(border-box);
|
||||
display: table-cell;
|
||||
letter-spacing: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
padding-right: flex-gutter(9);
|
||||
text-transform: none;
|
||||
width: flex-grid(2, 9);
|
||||
}
|
||||
|
||||
@@ -203,14 +197,39 @@ div.profile-wrapper {
|
||||
|
||||
h3 {
|
||||
color: #666;
|
||||
|
||||
span {
|
||||
color: #999;
|
||||
font-size: em(14);
|
||||
font-weight: 100;
|
||||
}
|
||||
}
|
||||
|
||||
ol {
|
||||
list-style: none;
|
||||
p {
|
||||
color: #999;
|
||||
font-size: em(14);
|
||||
}
|
||||
|
||||
li {
|
||||
display: inline-block;
|
||||
padding-right: 1em;
|
||||
section.scores {
|
||||
margin: lh(.5) 0;
|
||||
|
||||
h3 {
|
||||
font-size: em(14);
|
||||
@include inline-block;
|
||||
}
|
||||
|
||||
ol {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
@include inline-block;
|
||||
|
||||
li {
|
||||
@include inline-block;
|
||||
font-size: em(14);
|
||||
font-weight: normal;
|
||||
padding-right: 1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ div.book-wrapper {
|
||||
@include box-sizing(border-box);
|
||||
|
||||
ul#booknav {
|
||||
font-size: 12px;
|
||||
font-size: $body-font-size;
|
||||
|
||||
a {
|
||||
color: #000;
|
||||
@@ -39,8 +39,7 @@ div.book-wrapper {
|
||||
}
|
||||
|
||||
> li {
|
||||
border-bottom: 1px solid #d3d3d3;
|
||||
@include box-shadow(0 1px 0 #eee);
|
||||
border-bottom: 1px solid $border-color;
|
||||
padding: 7px 7px 7px 30px;
|
||||
}
|
||||
}
|
||||
@@ -48,9 +47,11 @@ div.book-wrapper {
|
||||
|
||||
section.book {
|
||||
@extend .content;
|
||||
padding-right: 0;
|
||||
padding-bottom: 0;
|
||||
padding-top: 0;
|
||||
|
||||
nav {
|
||||
@extend .topbar;
|
||||
@extend .clearfix;
|
||||
|
||||
a {
|
||||
@@ -62,32 +63,57 @@ div.book-wrapper {
|
||||
@extend .clearfix;
|
||||
|
||||
li {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: flex-grid(2, 8);
|
||||
|
||||
a {
|
||||
display: table;
|
||||
@include box-sizing(border-box);
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
vertical-align: middle;
|
||||
@include transition;
|
||||
background-color: rgba(#000, .7);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
opacity: 0;
|
||||
filter: alpha(opacity=0);
|
||||
text-indent: -9999px;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
filter: alpha(opacity=100);
|
||||
|
||||
&.last {
|
||||
}
|
||||
|
||||
&.next {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.last {
|
||||
display: block;
|
||||
float: left;
|
||||
left: 0;
|
||||
|
||||
a {
|
||||
border-left: 0;
|
||||
border-right: 1px solid darken(#f6efd4, 20%);
|
||||
@include box-shadow(inset -1px 0 0 lighten(#f6efd4, 5%));
|
||||
background-image: url('../images/textbook/textbook-left.png');
|
||||
}
|
||||
}
|
||||
|
||||
&.next {
|
||||
display: block;
|
||||
float: right;
|
||||
right: 0;
|
||||
|
||||
a {
|
||||
background-image: url('../images/textbook/textbook-right.png');
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.bottom-nav {
|
||||
border-bottom: 0;
|
||||
border-top: 1px solid #EDDFAA;
|
||||
margin-bottom: -(lh());
|
||||
margin-top: lh();
|
||||
}
|
||||
@@ -95,9 +121,10 @@ div.book-wrapper {
|
||||
|
||||
section.page {
|
||||
text-align: center;
|
||||
position: relative;
|
||||
border: 1px solid $border-color;
|
||||
|
||||
img {
|
||||
border: 1px solid $border-color;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
body {
|
||||
font-family: $sans-serif;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
body, h1, h2, h3, h4, h5, h6, p, p a:link, p a:visited, a {
|
||||
font-family: $sans-serif;
|
||||
}
|
||||
|
||||
@@ -19,3 +15,9 @@ table {
|
||||
table-layout: fixed;
|
||||
}
|
||||
}
|
||||
|
||||
form {
|
||||
label {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
h1.top-header {
|
||||
border-bottom: 1px solid #e3e3e3;
|
||||
text-align: left;
|
||||
font-size: 24px;
|
||||
font-size: em(24);
|
||||
font-weight: 100;
|
||||
padding-bottom: lh();
|
||||
}
|
||||
@@ -51,7 +51,6 @@ h1.top-header {
|
||||
|
||||
.sidebar {
|
||||
border-right: 1px solid #C8C8C8;
|
||||
@include box-shadow(inset -1px 0 0 #e6e6e6);
|
||||
@include box-sizing(border-box);
|
||||
display: table-cell;
|
||||
font-family: $sans-serif;
|
||||
@@ -75,7 +74,7 @@ h1.top-header {
|
||||
}
|
||||
|
||||
.bottom-border {
|
||||
border-bottom: 1px solid #d3d3d3;
|
||||
border-bottom: 1px solid $border-color;
|
||||
}
|
||||
|
||||
@media print {
|
||||
|
||||
@@ -4,78 +4,70 @@ div#wiki_panel {
|
||||
|
||||
h2 {
|
||||
@extend .bottom-border;
|
||||
font-size: 18px;
|
||||
margin: 0 ;
|
||||
padding: lh(.5) lh();
|
||||
}
|
||||
|
||||
input[type="button"] {
|
||||
background: transparent;
|
||||
border: none;
|
||||
@include box-shadow(none);
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
margin: 0px;
|
||||
padding: 7px lh();
|
||||
text-align: left;
|
||||
@include transition();
|
||||
width: 100%;
|
||||
padding: lh(.5) lh() lh(.5) 0;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding-left: 0;
|
||||
margin: 0;
|
||||
|
||||
li {
|
||||
@include box-shadow(inset 0 1px 0 0 #eee);
|
||||
border-top: 1px solid #d3d3d3;
|
||||
|
||||
&:hover {
|
||||
background: #efefef;
|
||||
@include background-image(linear-gradient(-90deg, rgb(245,245,245), rgb(225,225,225)));
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
border: none;
|
||||
}
|
||||
@extend .bottom-border;
|
||||
|
||||
&.search {
|
||||
padding: 10px lh();
|
||||
padding: 10px lh() 10px 0;
|
||||
|
||||
label {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.create-article {
|
||||
h3 {
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
padding: 7px lh();
|
||||
padding: 7px lh() 7px 0;
|
||||
|
||||
&:hover {
|
||||
background: #efefef;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
form {
|
||||
input[type="submit"]{
|
||||
@extend .light-button;
|
||||
text-transform: none;
|
||||
text-shadow: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
div#wiki_create_form {
|
||||
@extend .clearfix;
|
||||
background: #dadada;
|
||||
border-bottom: 1px solid #d3d3d3;
|
||||
padding: 15px;
|
||||
padding: lh(.5) lh() lh(.5) 0;
|
||||
|
||||
label {
|
||||
font-family: $sans-serif;
|
||||
margin-bottom: lh(.5);
|
||||
}
|
||||
|
||||
input[type="text"] {
|
||||
@include box-sizing(border-box);
|
||||
display: block;
|
||||
margin-bottom: 6px;
|
||||
width: 100%;
|
||||
margin-bottom: lh(.5);
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
|
||||
li {
|
||||
float: left;
|
||||
border-bottom: 0;
|
||||
|
||||
&#cancel {
|
||||
float: right;
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0; }
|
||||
|
||||
.wrapper, .subpage, section.copyright, section.tos, section.privacy-policy, section.honor-code, header.announcement div, section.index-content, footer {
|
||||
margin: 0;
|
||||
overflow: hidden; }
|
||||
|
||||
div#enroll form {
|
||||
display: none; }
|
||||
@@ -1,1017 +0,0 @@
|
||||
/*
|
||||
html5doctor.com Reset Stylesheet
|
||||
v1.6.1
|
||||
Last Updated: 2010-09-17
|
||||
Author: Richard Clark - http://richclarkdesign.com
|
||||
Twitter: @rich_clark
|
||||
*/
|
||||
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, 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;
|
||||
font-size: 100%;
|
||||
vertical-align: baseline;
|
||||
background: transparent; }
|
||||
|
||||
body {
|
||||
line-height: 1; }
|
||||
|
||||
article, aside, details, figcaption, figure,
|
||||
footer, header, hgroup, menu, nav, section {
|
||||
display: block; }
|
||||
|
||||
nav ul {
|
||||
list-style: none; }
|
||||
|
||||
blockquote, q {
|
||||
quotes: none; }
|
||||
|
||||
blockquote:before, blockquote:after,
|
||||
q:before, q:after {
|
||||
content: '';
|
||||
content: none; }
|
||||
|
||||
a {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 100%;
|
||||
vertical-align: baseline;
|
||||
background: transparent; }
|
||||
|
||||
/* change colours to suit your needs */
|
||||
ins {
|
||||
background-color: #ff9;
|
||||
color: #000;
|
||||
text-decoration: none; }
|
||||
|
||||
/* change colours to suit your needs */
|
||||
mark {
|
||||
background-color: #ff9;
|
||||
color: #000;
|
||||
font-style: italic;
|
||||
font-weight: bold; }
|
||||
|
||||
del {
|
||||
text-decoration: line-through; }
|
||||
|
||||
abbr[title], dfn[title] {
|
||||
border-bottom: 1px dotted;
|
||||
cursor: help; }
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0; }
|
||||
|
||||
/* change border colour to suit your needs */
|
||||
hr {
|
||||
display: block;
|
||||
height: 1px;
|
||||
border: 0;
|
||||
border-top: 1px solid #cccccc;
|
||||
margin: 1em 0;
|
||||
padding: 0; }
|
||||
|
||||
input, select {
|
||||
vertical-align: middle; }
|
||||
|
||||
/* Generated by Font Squirrel (http://www.fontsquirrel.com) on January 25, 2012 05:06:34 PM America/New_York */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
src: url("../fonts/OpenSans-Regular-webfont.eot");
|
||||
src: url("../fonts/OpenSans-Regular-webfont.eot?#iefix") format("embedded-opentype"), url("../fonts/OpenSans-Regular-webfont.woff") format("woff"), url("../fonts/OpenSans-Regular-webfont.ttf") format("truetype"), url("../fonts/OpenSans-Regular-webfont.svg#OpenSansRegular") format("svg");
|
||||
font-weight: 600;
|
||||
font-style: normal; }
|
||||
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
src: url("../fonts/OpenSans-Italic-webfont.eot");
|
||||
src: url("../fonts/OpenSans-Italic-webfont.eot?#iefix") format("embedded-opentype"), url("../fonts/OpenSans-Italic-webfont.woff") format("woff"), url("../fonts/OpenSans-Italic-webfont.ttf") format("truetype"), url("../fonts/OpenSans-Italic-webfont.svg#OpenSansItalic") format("svg");
|
||||
font-weight: 400;
|
||||
font-style: italic; }
|
||||
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
src: url("../fonts/OpenSans-Bold-webfont.eot");
|
||||
src: url("../fonts/OpenSans-Bold-webfont.eot?#iefix") format("embedded-opentype"), url("../fonts/OpenSans-Bold-webfont.woff") format("woff"), url("../fonts/OpenSans-Bold-webfont.ttf") format("truetype"), url("../fonts/OpenSans-Bold-webfont.svg#OpenSansBold") format("svg");
|
||||
font-weight: 700;
|
||||
font-style: normal; }
|
||||
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
src: url("../fonts/OpenSans-BoldItalic-webfont.eot");
|
||||
src: url("../fonts/OpenSans-BoldItalic-webfont.eot?#iefix") format("embedded-opentype"), url("../fonts/OpenSans-BoldItalic-webfont.woff") format("woff"), url("../fonts/OpenSans-BoldItalic-webfont.ttf") format("truetype"), url("../fonts/OpenSans-BoldItalic-webfont.svg#OpenSansBoldItalic") format("svg");
|
||||
font-weight: 700;
|
||||
font-style: italic; }
|
||||
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
src: url("../fonts/OpenSans-ExtraBold-webfont.eot");
|
||||
src: url("../fonts/OpenSans-ExtraBold-webfont.eot?#iefix") format("embedded-opentype"), url("../fonts/OpenSans-ExtraBold-webfont.woff") format("woff"), url("../fonts/OpenSans-ExtraBold-webfont.ttf") format("truetype"), url("../fonts/OpenSans-ExtraBold-webfont.svg#OpenSansExtrabold") format("svg");
|
||||
font-weight: 800;
|
||||
font-style: normal; }
|
||||
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
src: url("../fonts/OpenSans-ExtraBoldItalic-webfont.eot");
|
||||
src: url("../fonts/OpenSans-ExtraBoldItalic-webfont.eot?#iefix") format("embedded-opentype"), url("../fonts/OpenSans-ExtraBoldItalic-webfont.woff") format("woff"), url("../fonts/OpenSans-ExtraBoldItalic-webfont.ttf") format("truetype"), url("../fonts/OpenSans-ExtraBoldItalic-webfont.svg#OpenSansExtraboldItalic") format("svg");
|
||||
font-weight: 800;
|
||||
font-style: italic; }
|
||||
|
||||
.wrapper, .subpage, section.copyright, section.tos, section.privacy-policy, section.honor-code, header.announcement div, footer, section.index-content {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
margin: 0 auto;
|
||||
max-width: 1400px;
|
||||
padding: 25.888px;
|
||||
width: 100%; }
|
||||
|
||||
.subpage > div, section.copyright > div, section.tos > div, section.privacy-policy > div, section.honor-code > div {
|
||||
padding-left: 34.171%; }
|
||||
@media screen and (max-width: 940px) {
|
||||
.subpage > div, section.copyright > div, section.tos > div, section.privacy-policy > div, section.honor-code > div {
|
||||
padding-left: 0; } }
|
||||
.subpage > div p, section.copyright > div p, section.tos > div p, section.privacy-policy > div p, section.honor-code > div p {
|
||||
margin-bottom: 25.888px;
|
||||
line-height: 25.888px; }
|
||||
.subpage > div h1, section.copyright > div h1, section.tos > div h1, section.privacy-policy > div h1, section.honor-code > div h1 {
|
||||
margin-bottom: 12.944px; }
|
||||
.subpage > div h2, section.copyright > div h2, section.tos > div h2, section.privacy-policy > div h2, section.honor-code > div h2 {
|
||||
font: 18px "Open Sans", Helvetica, Arial, sans-serif;
|
||||
color: #000;
|
||||
margin-bottom: 12.944px; }
|
||||
.subpage > div ul, section.copyright > div ul, section.tos > div ul, section.privacy-policy > div ul, section.honor-code > div ul {
|
||||
list-style: disc outside none; }
|
||||
.subpage > div ul li, section.copyright > div ul li, section.tos > div ul li, section.privacy-policy > div ul li, section.honor-code > div ul li {
|
||||
list-style: disc outside none;
|
||||
line-height: 25.888px; }
|
||||
.subpage > div dl, section.copyright > div dl, section.tos > div dl, section.privacy-policy > div dl, section.honor-code > div dl {
|
||||
margin-bottom: 25.888px; }
|
||||
.subpage > div dl dd, section.copyright > div dl dd, section.tos > div dl dd, section.privacy-policy > div dl dd, section.honor-code > div dl dd {
|
||||
margin-bottom: 12.944px; }
|
||||
|
||||
.clearfix:after, .subpage:after, section.copyright:after, section.tos:after, section.privacy-policy:after, section.honor-code:after, header.announcement div section:after, footer:after, section.index-content:after, section.index-content section:after, section.index-content section.about section:after, div.leanModal_box#enroll ol:after {
|
||||
content: ".";
|
||||
display: block;
|
||||
height: 0;
|
||||
clear: both;
|
||||
visibility: hidden; }
|
||||
|
||||
.button, header.announcement div section.course section a, section.index-content section.course a, section.index-content section.staff a, section.index-content section.about-course section.cta a.enroll {
|
||||
-webkit-border-radius: 3px;
|
||||
-moz-border-radius: 3px;
|
||||
-ms-border-radius: 3px;
|
||||
-o-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
display: -moz-inline-box;
|
||||
-moz-box-orient: vertical;
|
||||
display: inline-block;
|
||||
vertical-align: baseline;
|
||||
zoom: 1;
|
||||
*display: inline;
|
||||
*vertical-align: auto;
|
||||
-webkit-transition-property: all;
|
||||
-moz-transition-property: all;
|
||||
-ms-transition-property: all;
|
||||
-o-transition-property: all;
|
||||
transition-property: all;
|
||||
-webkit-transition-duration: 0.15s;
|
||||
-moz-transition-duration: 0.15s;
|
||||
-ms-transition-duration: 0.15s;
|
||||
-o-transition-duration: 0.15s;
|
||||
transition-duration: 0.15s;
|
||||
-webkit-transition-timing-function: ease-out;
|
||||
-moz-transition-timing-function: ease-out;
|
||||
-ms-transition-timing-function: ease-out;
|
||||
-o-transition-timing-function: ease-out;
|
||||
transition-timing-function: ease-out;
|
||||
-webkit-transition-delay: 0;
|
||||
-moz-transition-delay: 0;
|
||||
-ms-transition-delay: 0;
|
||||
-o-transition-delay: 0;
|
||||
transition-delay: 0;
|
||||
background-color: #993333;
|
||||
border: 1px solid #732626;
|
||||
color: #fff;
|
||||
margin: 25.888px 0 12.944px;
|
||||
padding: 6.472px 12.944px;
|
||||
text-decoration: none;
|
||||
font-style: normal;
|
||||
-webkit-box-shadow: inset 0 1px 0 #b83d3d;
|
||||
-moz-box-shadow: inset 0 1px 0 #b83d3d;
|
||||
box-shadow: inset 0 1px 0 #b83d3d;
|
||||
-webkit-font-smoothing: antialiased; }
|
||||
.button:hover, header.announcement div section.course section a:hover, section.index-content section.course a:hover, section.index-content section.staff a:hover, section.index-content section.about-course section.cta a.enroll:hover {
|
||||
background-color: #732626;
|
||||
border-color: #4d1919; }
|
||||
.button span, header.announcement div section.course section a span, section.index-content section.course a span, section.index-content section.staff a span, section.index-content section.about-course section.cta a.enroll span {
|
||||
font-family: Garamond, Baskerville, "Baskerville Old Face", "Hoefler Text", "Times New Roman", serif;
|
||||
font-style: italic; }
|
||||
|
||||
p.ie-warning {
|
||||
display: block !important;
|
||||
line-height: 1.3em;
|
||||
background: yellow;
|
||||
margin-bottom: 25.888px;
|
||||
padding: 25.888px; }
|
||||
|
||||
body {
|
||||
background-color: #fff;
|
||||
color: #444;
|
||||
font: 16px Georgia, serif; }
|
||||
body :focus {
|
||||
outline-color: #ccc; }
|
||||
body h1 {
|
||||
font: 800 24px "Open Sans", Helvetica, Arial, sans-serif; }
|
||||
body li {
|
||||
margin-bottom: 25.888px; }
|
||||
body em {
|
||||
font-style: italic; }
|
||||
body a {
|
||||
color: #993333;
|
||||
font-style: italic;
|
||||
text-decoration: none; }
|
||||
body a:hover, body a:focus {
|
||||
color: #732626; }
|
||||
body input[type="email"], body input[type="number"], body input[type="password"], body input[type="search"], body input[type="tel"], body input[type="text"], body input[type="url"], body input[type="color"], body input[type="date"], body input[type="datetime"], body input[type="datetime-local"], body input[type="month"], body input[type="time"], body input[type="week"], body textarea {
|
||||
-webkit-box-shadow: 0 -1px 0 white;
|
||||
-moz-box-shadow: 0 -1px 0 white;
|
||||
box-shadow: 0 -1px 0 white;
|
||||
background-color: #eeeeee;
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #eeeeee), color-stop(100%, white));
|
||||
background-image: -webkit-linear-gradient(top, #eeeeee, white);
|
||||
background-image: -moz-linear-gradient(top, #eeeeee, white);
|
||||
background-image: -ms-linear-gradient(top, #eeeeee, white);
|
||||
background-image: -o-linear-gradient(top, #eeeeee, white);
|
||||
background-image: linear-gradient(top, #eeeeee, white);
|
||||
border: 1px solid #999;
|
||||
font: 16px Georgia, serif;
|
||||
padding: 4px;
|
||||
width: 100%; }
|
||||
body input[type="email"]:focus, body input[type="number"]:focus, body input[type="password"]:focus, body input[type="search"]:focus, body input[type="tel"]:focus, body input[type="text"]:focus, body input[type="url"]:focus, body input[type="color"]:focus, body input[type="date"]:focus, body input[type="datetime"]:focus, body input[type="datetime-local"]:focus, body input[type="month"]:focus, body input[type="time"]:focus, body input[type="week"]:focus, body textarea:focus {
|
||||
border-color: #993333; }
|
||||
|
||||
header.announcement {
|
||||
-webkit-background-size: cover;
|
||||
-moz-background-size: cover;
|
||||
-ms-background-size: cover;
|
||||
-o-background-size: cover;
|
||||
background-size: cover;
|
||||
background: #333;
|
||||
border-bottom: 1px solid #000;
|
||||
color: #fff;
|
||||
-webkit-font-smoothing: antialiased; }
|
||||
header.announcement.home {
|
||||
background: #e3e3e3 url("../images/marketing/shot-5-medium.jpg"); }
|
||||
@media screen and (min-width: 1200px) {
|
||||
header.announcement.home {
|
||||
background: #e3e3e3 url("../images/marketing/shot-5-large.jpg"); } }
|
||||
header.announcement.home div {
|
||||
padding: 258.88px 25.888px 77.664px; }
|
||||
@media screen and (max-width:780px) {
|
||||
header.announcement.home div {
|
||||
padding: 64.72px 25.888px 51.776px; } }
|
||||
header.announcement.home div nav h1 {
|
||||
margin-right: 0; }
|
||||
header.announcement.home div nav a.login {
|
||||
display: none; }
|
||||
header.announcement.course {
|
||||
background: #e3e3e3 url("../images/marketing/course-bg-small.jpg"); }
|
||||
@media screen and (min-width: 1200px) {
|
||||
header.announcement.course {
|
||||
background: #e3e3e3 url("../images/marketing/course-bg-large.jpg"); } }
|
||||
@media screen and (max-width: 1199px) and (min-width: 700px) {
|
||||
header.announcement.course {
|
||||
background: #e3e3e3 url("../images/marketing/course-bg-medium.jpg"); } }
|
||||
header.announcement.course div {
|
||||
padding: 103.552px 25.888px 51.776px; }
|
||||
@media screen and (max-width:780px) {
|
||||
header.announcement.course div {
|
||||
padding: 64.72px 25.888px 51.776px; } }
|
||||
header.announcement div {
|
||||
position: relative; }
|
||||
header.announcement div nav {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 25.888px;
|
||||
-webkit-border-radius: 0 0 3px 3px;
|
||||
-moz-border-radius: 0 0 3px 3px;
|
||||
-ms-border-radius: 0 0 3px 3px;
|
||||
-o-border-radius: 0 0 3px 3px;
|
||||
border-radius: 0 0 3px 3px;
|
||||
background: #333;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
padding: 12.944px 25.888px; }
|
||||
header.announcement div nav h1 {
|
||||
display: -moz-inline-box;
|
||||
-moz-box-orient: vertical;
|
||||
display: inline-block;
|
||||
vertical-align: baseline;
|
||||
zoom: 1;
|
||||
*display: inline;
|
||||
*vertical-align: auto;
|
||||
margin-right: 12.944px; }
|
||||
header.announcement div nav h1 a {
|
||||
font: italic 800 18px "Open Sans", Helvetica, Arial, sans-serif;
|
||||
color: #fff;
|
||||
text-decoration: none; }
|
||||
header.announcement div nav h1 a:hover, header.announcement div nav h1 a:focus {
|
||||
color: #999; }
|
||||
header.announcement div nav a.login {
|
||||
text-decoration: none;
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
font-style: normal;
|
||||
font-family: "Open Sans", Helvetica, Arial, sans-serif; }
|
||||
header.announcement div nav a.login:hover, header.announcement div nav a.login:focus {
|
||||
color: #999; }
|
||||
header.announcement div section {
|
||||
background: #993333;
|
||||
display: -moz-inline-box;
|
||||
-moz-box-orient: vertical;
|
||||
display: inline-block;
|
||||
vertical-align: baseline;
|
||||
zoom: 1;
|
||||
*display: inline;
|
||||
*vertical-align: auto;
|
||||
margin-left: 34.171%;
|
||||
padding: 25.888px 38.832px; }
|
||||
@media screen and (max-width: 780px) {
|
||||
header.announcement div section {
|
||||
margin-left: 0; } }
|
||||
header.announcement div section h1 {
|
||||
font-family: "Open Sans";
|
||||
font-size: 30px;
|
||||
font-weight: 800;
|
||||
display: -moz-inline-box;
|
||||
-moz-box-orient: vertical;
|
||||
display: inline-block;
|
||||
vertical-align: baseline;
|
||||
zoom: 1;
|
||||
*display: inline;
|
||||
*vertical-align: auto;
|
||||
line-height: 1.2em;
|
||||
margin: 0 25.888px 0 0; }
|
||||
header.announcement div section h2 {
|
||||
font-family: "Open Sans";
|
||||
font-size: 24px;
|
||||
font-weight: 400;
|
||||
display: -moz-inline-box;
|
||||
-moz-box-orient: vertical;
|
||||
display: inline-block;
|
||||
vertical-align: baseline;
|
||||
zoom: 1;
|
||||
*display: inline;
|
||||
*vertical-align: auto;
|
||||
line-height: 1.2em; }
|
||||
header.announcement div section.course section {
|
||||
float: left;
|
||||
margin-left: 0;
|
||||
margin-right: 3.817%;
|
||||
padding: 0;
|
||||
width: 48.092%; }
|
||||
@media screen and (max-width: 780px) {
|
||||
header.announcement div section.course section {
|
||||
float: none;
|
||||
width: 100%;
|
||||
margin-right: 0; } }
|
||||
header.announcement div section.course section a {
|
||||
background-color: #4d1919;
|
||||
border-color: #260d0d;
|
||||
-webkit-box-shadow: inset 0 1px 0 #732626, 0 1px 0 #ac3939;
|
||||
-moz-box-shadow: inset 0 1px 0 #732626, 0 1px 0 #ac3939;
|
||||
box-shadow: inset 0 1px 0 #732626, 0 1px 0 #ac3939;
|
||||
display: block;
|
||||
padding: 12.944px 25.888px;
|
||||
text-align: center; }
|
||||
header.announcement div section.course section a:hover {
|
||||
background-color: #732626;
|
||||
border-color: #4d1919; }
|
||||
header.announcement div section.course p {
|
||||
width: 48.092%;
|
||||
line-height: 25.888px;
|
||||
float: left; }
|
||||
@media screen and (max-width: 780px) {
|
||||
header.announcement div section.course p {
|
||||
float: none;
|
||||
width: 100%; } }
|
||||
|
||||
footer {
|
||||
padding-top: 0; }
|
||||
footer div.footer-wrapper {
|
||||
border-top: 1px solid #e5e5e5;
|
||||
padding: 25.888px 0;
|
||||
background: url("../images/marketing/mit-logo.png") right center no-repeat; }
|
||||
@media screen and (max-width: 780px) {
|
||||
footer div.footer-wrapper {
|
||||
background-position: left bottom;
|
||||
padding-bottom: 77.664px; } }
|
||||
footer div.footer-wrapper a {
|
||||
color: #888;
|
||||
text-decoration: none;
|
||||
-webkit-transition-property: all;
|
||||
-moz-transition-property: all;
|
||||
-ms-transition-property: all;
|
||||
-o-transition-property: all;
|
||||
transition-property: all;
|
||||
-webkit-transition-duration: 0.15s;
|
||||
-moz-transition-duration: 0.15s;
|
||||
-ms-transition-duration: 0.15s;
|
||||
-o-transition-duration: 0.15s;
|
||||
transition-duration: 0.15s;
|
||||
-webkit-transition-timing-function: ease-out;
|
||||
-moz-transition-timing-function: ease-out;
|
||||
-ms-transition-timing-function: ease-out;
|
||||
-o-transition-timing-function: ease-out;
|
||||
transition-timing-function: ease-out;
|
||||
-webkit-transition-delay: 0;
|
||||
-moz-transition-delay: 0;
|
||||
-ms-transition-delay: 0;
|
||||
-o-transition-delay: 0;
|
||||
transition-delay: 0; }
|
||||
footer div.footer-wrapper a:hover, footer div.footer-wrapper a:focus {
|
||||
color: #666; }
|
||||
footer div.footer-wrapper p {
|
||||
display: -moz-inline-box;
|
||||
-moz-box-orient: vertical;
|
||||
display: inline-block;
|
||||
vertical-align: baseline;
|
||||
zoom: 1;
|
||||
*display: inline;
|
||||
*vertical-align: auto;
|
||||
margin-right: 25.888px; }
|
||||
footer div.footer-wrapper ul {
|
||||
display: -moz-inline-box;
|
||||
-moz-box-orient: vertical;
|
||||
display: inline-block;
|
||||
vertical-align: baseline;
|
||||
zoom: 1;
|
||||
*display: inline;
|
||||
*vertical-align: auto; }
|
||||
@media screen and (max-width: 780px) {
|
||||
footer div.footer-wrapper ul {
|
||||
margin-top: 25.888px; } }
|
||||
footer div.footer-wrapper ul li {
|
||||
display: -moz-inline-box;
|
||||
-moz-box-orient: vertical;
|
||||
display: inline-block;
|
||||
vertical-align: baseline;
|
||||
zoom: 1;
|
||||
*display: inline;
|
||||
*vertical-align: auto;
|
||||
margin-bottom: 0; }
|
||||
footer div.footer-wrapper ul li:after {
|
||||
content: ' |';
|
||||
display: inline;
|
||||
color: #ccc; }
|
||||
footer div.footer-wrapper ul li:last-child:after {
|
||||
content: none; }
|
||||
footer div.footer-wrapper ul.social {
|
||||
float: right;
|
||||
margin-right: 60px;
|
||||
position: relative;
|
||||
top: -5px; }
|
||||
@media screen and (max-width: 780px) {
|
||||
footer div.footer-wrapper ul.social {
|
||||
float: none; } }
|
||||
footer div.footer-wrapper ul.social li {
|
||||
float: left;
|
||||
margin-right: 12.944px; }
|
||||
footer div.footer-wrapper ul.social li:after {
|
||||
content: none;
|
||||
display: none; }
|
||||
footer div.footer-wrapper ul.social li a {
|
||||
display: block;
|
||||
height: 29px;
|
||||
width: 28px;
|
||||
text-indent: -9999px; }
|
||||
footer div.footer-wrapper ul.social li a:hover {
|
||||
opacity: .8; }
|
||||
footer div.footer-wrapper ul.social li.twitter a {
|
||||
background: url("../images/marketing/twitter.png") 0 0 no-repeat; }
|
||||
footer div.footer-wrapper ul.social li.facebook a {
|
||||
background: url("../images/marketing/facebook.png") 0 0 no-repeat; }
|
||||
footer div.footer-wrapper ul.social li.linkedin a {
|
||||
background: url("../images/marketing/linkedin.png") 0 0 no-repeat; }
|
||||
|
||||
section.index-content section {
|
||||
float: left; }
|
||||
@media screen and (max-width: 780px) {
|
||||
section.index-content section {
|
||||
float: none;
|
||||
width: auto;
|
||||
margin-right: 0; } }
|
||||
section.index-content section h1 {
|
||||
font-size: 800 24px "Open Sans";
|
||||
margin-bottom: 25.888px; }
|
||||
section.index-content section p {
|
||||
line-height: 25.888px;
|
||||
margin-bottom: 25.888px; }
|
||||
section.index-content section ul {
|
||||
margin: 0; }
|
||||
section.index-content section.about {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
border-right: 1px solid #e5e5e5;
|
||||
margin-right: 2.513%;
|
||||
padding-right: 1.256%;
|
||||
width: 65.829%; }
|
||||
@media screen and (max-width: 780px) {
|
||||
section.index-content section.about {
|
||||
width: 100%;
|
||||
border-right: 0;
|
||||
margin-right: 0;
|
||||
padding-right: 0; } }
|
||||
section.index-content section.about section {
|
||||
margin-bottom: 25.888px; }
|
||||
section.index-content section.about section p {
|
||||
width: 48.092%;
|
||||
float: left; }
|
||||
@media screen and (max-width: 780px) {
|
||||
section.index-content section.about section p {
|
||||
float: none;
|
||||
width: auto; } }
|
||||
section.index-content section.about section p:nth-child(odd) {
|
||||
margin-right: 3.817%; }
|
||||
@media screen and (max-width: 780px) {
|
||||
section.index-content section.about section p:nth-child(odd) {
|
||||
margin-right: 0; } }
|
||||
section.index-content section.about section.intro section {
|
||||
margin-bottom: 0; }
|
||||
section.index-content section.about section.intro section.intro-text {
|
||||
margin-right: 3.817%;
|
||||
width: 48.092%; }
|
||||
@media screen and (max-width: 780px) {
|
||||
section.index-content section.about section.intro section.intro-text {
|
||||
margin-right: 0;
|
||||
width: auto; } }
|
||||
section.index-content section.about section.intro section.intro-text p {
|
||||
margin-right: 0;
|
||||
width: auto;
|
||||
float: none; }
|
||||
section.index-content section.about section.intro section.intro-video {
|
||||
width: 48.092%; }
|
||||
@media screen and (max-width: 780px) {
|
||||
section.index-content section.about section.intro section.intro-video {
|
||||
width: auto; } }
|
||||
section.index-content section.about section.intro section.intro-video a {
|
||||
display: block;
|
||||
width: 100%; }
|
||||
section.index-content section.about section.intro section.intro-video a img {
|
||||
width: 100%; }
|
||||
section.index-content section.about section.intro section.intro-video a span {
|
||||
display: none; }
|
||||
section.index-content section.about section.features {
|
||||
border-top: 1px solid #E5E5E5;
|
||||
padding-top: 25.888px;
|
||||
margin-bottom: 0; }
|
||||
section.index-content section.about section.features h2 {
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
color: #888;
|
||||
margin-bottom: 25.888px;
|
||||
font-weight: normal;
|
||||
font-size: 14px; }
|
||||
section.index-content section.about section.features h2 span {
|
||||
text-transform: none; }
|
||||
section.index-content section.about section.features p {
|
||||
width: auto;
|
||||
clear: both; }
|
||||
section.index-content section.about section.features p strong {
|
||||
font-family: "Open sans";
|
||||
font-weight: 800; }
|
||||
section.index-content section.about section.features p a {
|
||||
color: #993333;
|
||||
text-decoration: none;
|
||||
-webkit-transition-property: all;
|
||||
-moz-transition-property: all;
|
||||
-ms-transition-property: all;
|
||||
-o-transition-property: all;
|
||||
transition-property: all;
|
||||
-webkit-transition-duration: 0.15s;
|
||||
-moz-transition-duration: 0.15s;
|
||||
-ms-transition-duration: 0.15s;
|
||||
-o-transition-duration: 0.15s;
|
||||
transition-duration: 0.15s;
|
||||
-webkit-transition-timing-function: ease-out;
|
||||
-moz-transition-timing-function: ease-out;
|
||||
-ms-transition-timing-function: ease-out;
|
||||
-o-transition-timing-function: ease-out;
|
||||
transition-timing-function: ease-out;
|
||||
-webkit-transition-delay: 0;
|
||||
-moz-transition-delay: 0;
|
||||
-ms-transition-delay: 0;
|
||||
-o-transition-delay: 0;
|
||||
transition-delay: 0; }
|
||||
section.index-content section.about section.features p a:hover, section.index-content section.about section.features p a:focus {
|
||||
color: #602020; }
|
||||
section.index-content section.about section.features ul {
|
||||
margin-bottom: 0; }
|
||||
section.index-content section.about section.features ul li {
|
||||
line-height: 25.888px;
|
||||
width: 48.092%;
|
||||
float: left;
|
||||
margin-bottom: 12.944px; }
|
||||
@media screen and (max-width: 780px) {
|
||||
section.index-content section.about section.features ul li {
|
||||
width: auto;
|
||||
float: none; } }
|
||||
section.index-content section.about section.features ul li:nth-child(odd) {
|
||||
margin-right: 3.817%; }
|
||||
@media screen and (max-width: 780px) {
|
||||
section.index-content section.about section.features ul li:nth-child(odd) {
|
||||
margin-right: 0; } }
|
||||
section.index-content section.course, section.index-content section.staff {
|
||||
width: 31.658%; }
|
||||
@media screen and (max-width: 780px) {
|
||||
section.index-content section.course, section.index-content section.staff {
|
||||
width: auto; } }
|
||||
section.index-content section.course h1, section.index-content section.staff h1 {
|
||||
color: #888;
|
||||
font: normal 16px Georgia, serif;
|
||||
font-size: 14px;
|
||||
letter-spacing: 1px;
|
||||
margin-bottom: 25.888px;
|
||||
text-transform: uppercase; }
|
||||
section.index-content section.course h2, section.index-content section.staff h2 {
|
||||
font: 800 24px "Open Sans", Helvetica, Arial, sans-serif; }
|
||||
section.index-content section.course h3, section.index-content section.staff h3 {
|
||||
font: 400 18px "Open Sans", Helvetica, Arial, sans-serif; }
|
||||
section.index-content section.course a span.arrow, section.index-content section.staff a span.arrow {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
font-style: normal;
|
||||
display: -moz-inline-box;
|
||||
-moz-box-orient: vertical;
|
||||
display: inline-block;
|
||||
vertical-align: baseline;
|
||||
zoom: 1;
|
||||
*display: inline;
|
||||
*vertical-align: auto;
|
||||
padding-left: 10px; }
|
||||
section.index-content section.course ul, section.index-content section.staff ul {
|
||||
list-style: none; }
|
||||
section.index-content section.course ul li img, section.index-content section.staff ul li img {
|
||||
float: left;
|
||||
margin-right: 12.944px; }
|
||||
section.index-content section.course h2 {
|
||||
padding-top: 129.44px;
|
||||
background: url("../images/marketing/circuits-bg.jpg") 0 0 no-repeat;
|
||||
-webkit-background-size: contain;
|
||||
-moz-background-size: contain;
|
||||
-ms-background-size: contain;
|
||||
-o-background-size: contain;
|
||||
background-size: contain; }
|
||||
@media screen and (max-width: 998px) and (min-width: 781px) {
|
||||
section.index-content section.course h2 {
|
||||
background: url("../images/marketing/circuits-medium-bg.jpg") 0 0 no-repeat; } }
|
||||
@media screen and (max-width: 780px) {
|
||||
section.index-content section.course h2 {
|
||||
padding-top: 129.44px;
|
||||
background: url("../images/marketing/circuits-bg.jpg") 0 0 no-repeat; } }
|
||||
@media screen and (min-width: 500px) and (max-width: 781px) {
|
||||
section.index-content section.course h2 {
|
||||
padding-top: 207.104px; } }
|
||||
section.index-content section.course div.announcement p.announcement-button a {
|
||||
margin-top: 0; }
|
||||
section.index-content section.course div.announcement img {
|
||||
max-width: 100%;
|
||||
margin-bottom: 25.888px; }
|
||||
section.index-content section.about-course {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
border-right: 1px solid #e5e5e5;
|
||||
margin-right: 2.513%;
|
||||
padding-right: 1.256%;
|
||||
width: 65.829%; }
|
||||
@media screen and (max-width: 780px) {
|
||||
section.index-content section.about-course {
|
||||
width: auto;
|
||||
border-right: 0;
|
||||
margin-right: 0;
|
||||
padding-right: 0; } }
|
||||
section.index-content section.about-course section {
|
||||
width: 48.092%; }
|
||||
@media screen and (max-width: 780px) {
|
||||
section.index-content section.about-course section {
|
||||
width: auto; } }
|
||||
section.index-content section.about-course section.about-info {
|
||||
margin-right: 3.817%; }
|
||||
@media screen and (max-width: 780px) {
|
||||
section.index-content section.about-course section.about-info {
|
||||
margin-right: 0; } }
|
||||
section.index-content section.about-course section.requirements {
|
||||
clear: both;
|
||||
width: 100%;
|
||||
border-top: 1px solid #E5E5E5;
|
||||
padding-top: 25.888px;
|
||||
margin-bottom: 0; }
|
||||
section.index-content section.about-course section.requirements p {
|
||||
float: left;
|
||||
width: 48.092%;
|
||||
margin-right: 3.817%; }
|
||||
@media screen and (max-width: 780px) {
|
||||
section.index-content section.about-course section.requirements p {
|
||||
margin-right: 0;
|
||||
float: none;
|
||||
width: auto; } }
|
||||
section.index-content section.about-course section.requirements p:nth-child(odd) {
|
||||
margin-right: 0; }
|
||||
section.index-content section.about-course section.cta {
|
||||
width: 100%;
|
||||
text-align: center; }
|
||||
section.index-content section.about-course section.cta a.enroll {
|
||||
padding: 12.944px 51.776px;
|
||||
display: -moz-inline-box;
|
||||
-moz-box-orient: vertical;
|
||||
display: inline-block;
|
||||
vertical-align: baseline;
|
||||
zoom: 1;
|
||||
*display: inline;
|
||||
*vertical-align: auto;
|
||||
text-align: center;
|
||||
font: 800 18px "Open Sans", Helvetica, Arial, sans-serif; }
|
||||
section.index-content section.staff h1 {
|
||||
margin-top: 25.888px; }
|
||||
|
||||
#lean_overlay {
|
||||
background: #000;
|
||||
display: none;
|
||||
height: 100%;
|
||||
left: 0px;
|
||||
position: fixed;
|
||||
top: 0px;
|
||||
width: 100%;
|
||||
z-index: 100; }
|
||||
|
||||
div.leanModal_box {
|
||||
background: #fff;
|
||||
border: none;
|
||||
-webkit-border-radius: 3px;
|
||||
-moz-border-radius: 3px;
|
||||
-ms-border-radius: 3px;
|
||||
-o-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
-webkit-box-shadow: 0 0 6px black;
|
||||
-moz-box-shadow: 0 0 6px black;
|
||||
box-shadow: 0 0 6px black;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
display: none;
|
||||
padding: 51.776px;
|
||||
text-align: left; }
|
||||
div.leanModal_box a.modal_close {
|
||||
color: #aaa;
|
||||
display: block;
|
||||
font-style: normal;
|
||||
height: 14px;
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
top: 12px;
|
||||
width: 14px;
|
||||
z-index: 2; }
|
||||
div.leanModal_box a.modal_close:hover {
|
||||
color: #993333;
|
||||
text-decoration: none; }
|
||||
div.leanModal_box h1 {
|
||||
border-bottom: 1px solid #eee;
|
||||
font-size: 24px;
|
||||
margin-bottom: 25.888px;
|
||||
margin-top: 0;
|
||||
padding-bottom: 25.888px;
|
||||
text-align: left; }
|
||||
div.leanModal_box#enroll {
|
||||
max-width: 600px; }
|
||||
div.leanModal_box#enroll ol {
|
||||
padding-top: 25.888px; }
|
||||
div.leanModal_box#enroll ol li.terms, div.leanModal_box#enroll ol li.honor-code {
|
||||
float: none;
|
||||
width: auto; }
|
||||
div.leanModal_box#enroll ol li div.tip {
|
||||
display: none; }
|
||||
div.leanModal_box#enroll ol li:hover div.tip {
|
||||
background: #333;
|
||||
color: #fff;
|
||||
display: block;
|
||||
font-size: 16px;
|
||||
line-height: 25.888px;
|
||||
margin: 0 0 0 -10px;
|
||||
padding: 10px;
|
||||
position: absolute;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
width: 500px; }
|
||||
div.leanModal_box form {
|
||||
text-align: left; }
|
||||
div.leanModal_box form div#enroll_error, div.leanModal_box form div#login_error, div.leanModal_box form div#pwd_error {
|
||||
background-color: #333333;
|
||||
border: black;
|
||||
color: #fff;
|
||||
font-family: "Open sans";
|
||||
font-weight: bold;
|
||||
letter-spacing: 1px;
|
||||
margin: -25.888px -25.888px 25.888px;
|
||||
padding: 12.944px;
|
||||
text-shadow: 0 1px 0 #1a1a1a;
|
||||
-webkit-font-smoothing: antialiased; }
|
||||
div.leanModal_box form div#enroll_error:empty, div.leanModal_box form div#login_error:empty, div.leanModal_box form div#pwd_error:empty {
|
||||
padding: 0; }
|
||||
div.leanModal_box form ol {
|
||||
list-style: none;
|
||||
margin-bottom: 25.888px; }
|
||||
div.leanModal_box form ol li {
|
||||
margin-bottom: 12.944px; }
|
||||
div.leanModal_box form ol li.terms, div.leanModal_box form ol li.remember {
|
||||
border-top: 1px solid #eee;
|
||||
clear: both;
|
||||
float: none;
|
||||
padding-top: 25.888px;
|
||||
width: auto; }
|
||||
div.leanModal_box form ol li.honor-code {
|
||||
float: none;
|
||||
width: auto; }
|
||||
div.leanModal_box form ol li label {
|
||||
display: block;
|
||||
font-weight: bold; }
|
||||
div.leanModal_box form ol li input[type="email"], div.leanModal_box form ol li input[type="number"], div.leanModal_box form ol li input[type="password"], div.leanModal_box form ol li input[type="search"], div.leanModal_box form ol li input[type="tel"], div.leanModal_box form ol li input[type="text"], div.leanModal_box form ol li input[type="url"], div.leanModal_box form ol li input[type="color"], div.leanModal_box form ol li input[type="date"], div.leanModal_box form ol li input[type="datetime"], div.leanModal_box form ol li input[type="datetime-local"], div.leanModal_box form ol li input[type="month"], div.leanModal_box form ol li input[type="time"], div.leanModal_box form ol li input[type="week"], div.leanModal_box form ol li textarea {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
width: 100%; }
|
||||
div.leanModal_box form ol li input[type="checkbox"] {
|
||||
margin-right: 10px; }
|
||||
div.leanModal_box form ol li ul {
|
||||
list-style: disc outside none;
|
||||
margin: 12.944px 0 25.888px 25.888px; }
|
||||
div.leanModal_box form ol li ul li {
|
||||
color: #666;
|
||||
float: none;
|
||||
font-size: 14px;
|
||||
list-style: disc outside none;
|
||||
margin-bottom: 12.944px; }
|
||||
div.leanModal_box form input[type="button"], div.leanModal_box form input[type="submit"] {
|
||||
border: 1px solid #691b1b;
|
||||
-webkit-border-radius: 3px;
|
||||
-moz-border-radius: 3px;
|
||||
-ms-border-radius: 3px;
|
||||
-o-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
-webkit-box-shadow: inset 0 1px 0 0 #bc5c5c;
|
||||
-moz-box-shadow: inset 0 1px 0 0 #bc5c5c;
|
||||
box-shadow: inset 0 1px 0 0 #bc5c5c;
|
||||
color: white;
|
||||
display: inline;
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
background-color: #993333;
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #993333), color-stop(100%, #761e1e));
|
||||
background-image: -webkit-linear-gradient(top, #993333, #761e1e);
|
||||
background-image: -moz-linear-gradient(top, #993333, #761e1e);
|
||||
background-image: -ms-linear-gradient(top, #993333, #761e1e);
|
||||
background-image: -o-linear-gradient(top, #993333, #761e1e);
|
||||
background-image: linear-gradient(top, #993333, #761e1e);
|
||||
padding: 6px 18px 7px;
|
||||
text-shadow: 0 1px 0 #5d1414;
|
||||
-webkit-background-clip: padding-box;
|
||||
font-size: 18px;
|
||||
padding: 12.944px; }
|
||||
div.leanModal_box form input[type="button"]:hover, div.leanModal_box form input[type="submit"]:hover {
|
||||
-webkit-box-shadow: inset 0 1px 0 0 #a44141;
|
||||
-moz-box-shadow: inset 0 1px 0 0 #a44141;
|
||||
box-shadow: inset 0 1px 0 0 #a44141;
|
||||
cursor: pointer;
|
||||
background-color: #823030;
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #823030), color-stop(100%, #691c1c));
|
||||
background-image: -webkit-linear-gradient(top, #823030, #691c1c);
|
||||
background-image: -moz-linear-gradient(top, #823030, #691c1c);
|
||||
background-image: -ms-linear-gradient(top, #823030, #691c1c);
|
||||
background-image: -o-linear-gradient(top, #823030, #691c1c);
|
||||
background-image: linear-gradient(top, #823030, #691c1c); }
|
||||
div.leanModal_box form input[type="button"]:active, div.leanModal_box form input[type="submit"]:active {
|
||||
border: 1px solid #691b1b;
|
||||
-webkit-box-shadow: inset 0 0 8px 4px #5c1919, inset 0 0 8px 4px #5c1919, 0 1px 1px 0 #eeeeee;
|
||||
-moz-box-shadow: inset 0 0 8px 4px #5c1919, inset 0 0 8px 4px #5c1919, 0 1px 1px 0 #eeeeee;
|
||||
box-shadow: inset 0 0 8px 4px #5c1919, inset 0 0 8px 4px #5c1919, 0 1px 1px 0 #eeeeee; }
|
||||
|
||||
div#login {
|
||||
min-width: 400px; }
|
||||
div#login header {
|
||||
border-bottom: 1px solid #ddd;
|
||||
margin-bottom: 25.888px;
|
||||
padding-bottom: 25.888px; }
|
||||
div#login header h1 {
|
||||
border-bottom: 0;
|
||||
padding-bottom: 0;
|
||||
margin-bottom: 6.472px; }
|
||||
div#login ol li {
|
||||
float: none;
|
||||
width: auto; }
|
||||
|
||||
div.lost-password {
|
||||
margin-top: 25.888px;
|
||||
text-align: left; }
|
||||
div.lost-password a {
|
||||
color: #999; }
|
||||
div.lost-password a:hover {
|
||||
color: #444; }
|
||||
|
||||
div#pwd_reset p {
|
||||
margin-bottom: 25.888px; }
|
||||
div#pwd_reset input[type="email"] {
|
||||
margin-bottom: 25.888px; }
|
||||
|
||||
div#apply_name_change,
|
||||
div#change_email,
|
||||
div#unenroll,
|
||||
div#deactivate-account {
|
||||
max-width: 700px; }
|
||||
div#apply_name_change ul,
|
||||
div#change_email ul,
|
||||
div#unenroll ul,
|
||||
div#deactivate-account ul {
|
||||
list-style: none; }
|
||||
div#apply_name_change ul li,
|
||||
div#change_email ul li,
|
||||
div#unenroll ul li,
|
||||
div#deactivate-account ul li {
|
||||
margin-bottom: 12.944px; }
|
||||
div#apply_name_change ul li textarea, div#apply_name_change ul li input[type="email"], div#apply_name_change ul li input[type="number"], div#apply_name_change ul li input[type="password"], div#apply_name_change ul li input[type="search"], div#apply_name_change ul li input[type="tel"], div#apply_name_change ul li input[type="text"], div#apply_name_change ul li input[type="url"], div#apply_name_change ul li input[type="color"], div#apply_name_change ul li input[type="date"], div#apply_name_change ul li input[type="datetime"], div#apply_name_change ul li input[type="datetime-local"], div#apply_name_change ul li input[type="month"], div#apply_name_change ul li input[type="time"], div#apply_name_change ul li input[type="week"],
|
||||
div#change_email ul li textarea,
|
||||
div#change_email ul li input[type="email"],
|
||||
div#change_email ul li input[type="number"],
|
||||
div#change_email ul li input[type="password"],
|
||||
div#change_email ul li input[type="search"],
|
||||
div#change_email ul li input[type="tel"],
|
||||
div#change_email ul li input[type="text"],
|
||||
div#change_email ul li input[type="url"],
|
||||
div#change_email ul li input[type="color"],
|
||||
div#change_email ul li input[type="date"],
|
||||
div#change_email ul li input[type="datetime"],
|
||||
div#change_email ul li input[type="datetime-local"],
|
||||
div#change_email ul li input[type="month"],
|
||||
div#change_email ul li input[type="time"],
|
||||
div#change_email ul li input[type="week"],
|
||||
div#unenroll ul li textarea,
|
||||
div#unenroll ul li input[type="email"],
|
||||
div#unenroll ul li input[type="number"],
|
||||
div#unenroll ul li input[type="password"],
|
||||
div#unenroll ul li input[type="search"],
|
||||
div#unenroll ul li input[type="tel"],
|
||||
div#unenroll ul li input[type="text"],
|
||||
div#unenroll ul li input[type="url"],
|
||||
div#unenroll ul li input[type="color"],
|
||||
div#unenroll ul li input[type="date"],
|
||||
div#unenroll ul li input[type="datetime"],
|
||||
div#unenroll ul li input[type="datetime-local"],
|
||||
div#unenroll ul li input[type="month"],
|
||||
div#unenroll ul li input[type="time"],
|
||||
div#unenroll ul li input[type="week"],
|
||||
div#deactivate-account ul li textarea,
|
||||
div#deactivate-account ul li input[type="email"],
|
||||
div#deactivate-account ul li input[type="number"],
|
||||
div#deactivate-account ul li input[type="password"],
|
||||
div#deactivate-account ul li input[type="search"],
|
||||
div#deactivate-account ul li input[type="tel"],
|
||||
div#deactivate-account ul li input[type="text"],
|
||||
div#deactivate-account ul li input[type="url"],
|
||||
div#deactivate-account ul li input[type="color"],
|
||||
div#deactivate-account ul li input[type="date"],
|
||||
div#deactivate-account ul li input[type="datetime"],
|
||||
div#deactivate-account ul li input[type="datetime-local"],
|
||||
div#deactivate-account ul li input[type="month"],
|
||||
div#deactivate-account ul li input[type="time"],
|
||||
div#deactivate-account ul li input[type="week"] {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
width: 100%; }
|
||||
div#apply_name_change ul li textarea,
|
||||
div#change_email ul li textarea,
|
||||
div#unenroll ul li textarea,
|
||||
div#deactivate-account ul li textarea {
|
||||
height: 60px; }
|
||||
div#apply_name_change ul li input[type="submit"],
|
||||
div#change_email ul li input[type="submit"],
|
||||
div#unenroll ul li input[type="submit"],
|
||||
div#deactivate-account ul li input[type="submit"] {
|
||||
white-space: normal; }
|
||||
|
||||
div#feedback_div form ol li {
|
||||
float: none;
|
||||
width: 100%; }
|
||||
div#feedback_div form ol li textarea#feedback_message {
|
||||
height: 100px; }
|
||||
@@ -299,3 +299,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.leanModal_box {
|
||||
@extend .modal;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
</%block>
|
||||
|
||||
<%block name="headextra">
|
||||
<%static:css group='course'/>
|
||||
|
||||
<style type="text/css">
|
||||
.grade_a {color:green;}
|
||||
@@ -19,7 +20,8 @@
|
||||
|
||||
</%block>
|
||||
|
||||
<%include file="navigation.html" args="active_page=''" />
|
||||
<%include file="course_navigation.html" args="active_page=''" />
|
||||
|
||||
<section class="container">
|
||||
<div class="gradebook-wrapper">
|
||||
<section class="gradebook-content">
|
||||
@@ -28,7 +30,7 @@
|
||||
%if len(students) > 0:
|
||||
<table>
|
||||
<%
|
||||
templateSummary = students[0]['grade_info']['grade_summary']
|
||||
templateSummary = students[0]['grade_summary']
|
||||
%>
|
||||
|
||||
|
||||
@@ -42,15 +44,15 @@
|
||||
|
||||
<%def name="percent_data(percentage)">
|
||||
<%
|
||||
data_class = "grade_none"
|
||||
if percentage > .87:
|
||||
data_class = "grade_a"
|
||||
elif percentage > .70:
|
||||
data_class = "grade_b"
|
||||
elif percentage > .6:
|
||||
data_class = "grade_c"
|
||||
elif percentage > 0:
|
||||
data_class = "grade_f"
|
||||
letter_grade = 'None'
|
||||
if percentage > 0:
|
||||
letter_grade = 'F'
|
||||
for grade in ['A', 'B', 'C']:
|
||||
if percentage >= course.grade_cutoffs[grade]:
|
||||
letter_grade = grade
|
||||
break
|
||||
|
||||
data_class = "grade_" + letter_grade
|
||||
%>
|
||||
<td class="${data_class}">${ "{0:.0%}".format( percentage ) }</td>
|
||||
</%def>
|
||||
@@ -58,10 +60,10 @@
|
||||
%for student in students:
|
||||
<tr>
|
||||
<td><a href="/profile/${student['id']}/">${student['username']}</a></td>
|
||||
%for section in student['grade_info']['grade_summary']['section_breakdown']:
|
||||
%for section in student['grade_summary']['section_breakdown']:
|
||||
${percent_data( section['percent'] )}
|
||||
%endfor
|
||||
<th>${percent_data( student['grade_info']['grade_summary']['percent'])}</th>
|
||||
<th>${percent_data( student['grade_summary']['percent'])}</th>
|
||||
</tr>
|
||||
%endfor
|
||||
</table>
|
||||
|
||||
@@ -26,9 +26,9 @@
|
||||
<%include file="navigation.html" />
|
||||
<section class="content-wrapper">
|
||||
${self.body()}
|
||||
<%block name="bodyextra"/>
|
||||
</section>
|
||||
|
||||
<%block name="bodyextra"/>
|
||||
<%include file="footer.html" />
|
||||
|
||||
<%static:js group='application'/>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
if(json.success) {
|
||||
location.href="${reverse('dashboard')}";
|
||||
}else{
|
||||
$('#register_message).html("<p><font color='red'>" + json.error + "</font></p>")
|
||||
$('#register_message').html("<p><font color='red'>" + json.error + "</font></p>");
|
||||
}
|
||||
});
|
||||
})(this)
|
||||
|
||||
@@ -18,99 +18,98 @@
|
||||
<script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.stack.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.symbol.js')}"></script>
|
||||
<script>
|
||||
${profile_graphs.body(grade_summary, "grade-detail-graph")}
|
||||
${profile_graphs.body(grade_summary, course.grade_cutoffs, "grade-detail-graph")}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
var loc=true; // Activate on clicks? Not if already clicked.
|
||||
var lang=true;
|
||||
$(function() {
|
||||
$("#change_location").click(function() {
|
||||
$(this).hide();
|
||||
$("#change_location").click(function() {
|
||||
$(this).hide();
|
||||
|
||||
log_event("profile", {"type":"location_show", "old":$("#location_sub").text()});
|
||||
log_event("profile", {"type":"location_show", "old":$("#location_sub").text()});
|
||||
|
||||
if(loc) {
|
||||
$("#description").html('<div>'+
|
||||
"Preferred format is city, state, country (so for us, "+
|
||||
""Cambridge, Massachusetts, USA"), but give "+
|
||||
"as much or as little detail as you want. </div>");
|
||||
if(loc) {
|
||||
$("#description").html('<div>'+
|
||||
"Preferred format is city, state, country (so for us, "+
|
||||
""Cambridge, Massachusetts, USA"), but give "+
|
||||
"as much or as little detail as you want. </div>");
|
||||
|
||||
loc=false;
|
||||
loc=false;
|
||||
|
||||
$("#location_sub").html('<form>'+'<input id="id_loc_text" type="text" name="loc_text" />'+
|
||||
'<input type="submit" id="change_loc_button" value="Save" />'+'</form>');
|
||||
$("#location_sub").html('<form>'+'<input id="id_loc_text" type="text" name="loc_text" />'+
|
||||
'<input type="submit" id="change_loc_button" value="Save" />'+'</form>');
|
||||
|
||||
$("#change_loc_button").click(function() {
|
||||
$("#change_location").show();
|
||||
$("#change_loc_button").click(function() {
|
||||
$("#change_location").show();
|
||||
|
||||
postJSON('/change_setting', {'location':$("#id_loc_text").attr("value")}, function(json) {
|
||||
$("#location_sub").text(json.location);
|
||||
loc=true;
|
||||
$("#description").html("");
|
||||
log_event("profile", {"type":"location_change", "new":json.location});
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$('#change_password').click(function(){
|
||||
$('.modal').trigger('click');
|
||||
log_event("profile", {"type":"password_show"});
|
||||
});
|
||||
|
||||
$('#pwd_reset_button').click(function() {
|
||||
$.postWithPrefix('/password_reset/',{ "csrfmiddlewaretoken" : "${ csrf }",
|
||||
"email" : $('#id_email').val()}, function(data){
|
||||
$("#password_reset_complete_link").click();
|
||||
log_event("profile", {"type":"password_send"});
|
||||
});
|
||||
postJSON('/change_setting', {'location':$("#id_loc_text").attr("value")}, function(json) {
|
||||
$("#location_sub").text(json.location);
|
||||
loc=true;
|
||||
$("#description").html("");
|
||||
log_event("profile", {"type":"location_change", "new":json.location});
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
$("#change_email_form").submit(function(){
|
||||
var new_email = $('#new_email_field').val();
|
||||
var new_password = $('#new_email_password').val();
|
||||
|
||||
postJSON('/change_email',{"new_email":new_email,
|
||||
"password":new_password},
|
||||
function(data){
|
||||
if(data.success){
|
||||
$("#change_email").html("<h1>Please verify your new email</h1><p>You'll receive a confirmation in your in-box. Please click the link in the email to confirm the email change.</p>");
|
||||
} else {
|
||||
$("#change_email_error").html(data.error);
|
||||
}
|
||||
});
|
||||
log_event("profile", {"type":"email_change_request",
|
||||
"old_email":"${email}",
|
||||
"new_email":new_email});
|
||||
return false;
|
||||
$('#change_password').click(function(){
|
||||
$('.modal').trigger('click');
|
||||
log_event("profile", {"type":"password_show"});
|
||||
});
|
||||
|
||||
$("#change_name_form").submit(function(){
|
||||
var new_name = $('#new_name_field').val();
|
||||
var rationale = $('#name_rationale_field').val();
|
||||
|
||||
postJSON('/change_name',{"new_name":new_name,
|
||||
"rationale":rationale},
|
||||
function(data){
|
||||
if(data.success){
|
||||
$("#apply_name_change").html("<h1>Your request has been submitted.</h1><p>We'll send you an e-mail when approve the change or need further information. Please allow for up to a week for us to process your request.</p>");
|
||||
} else {
|
||||
$("#change_name_error").html(data.error);
|
||||
}
|
||||
});
|
||||
log_event("profile", {"type":"name_change_request",
|
||||
"new_name":new_name,
|
||||
"rationale":rationale});
|
||||
return false;
|
||||
$('#pwd_reset_button').click(function() {
|
||||
$.postWithPrefix('/password_reset/',{ "csrfmiddlewaretoken" : "${ csrf }",
|
||||
"email" : $('#id_email').val()}, function(data){
|
||||
$("#password_reset_complete_link").click();
|
||||
log_event("profile", {"type":"password_send"});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
$("#change_email_form").submit(function(){
|
||||
var new_email = $('#new_email_field').val();
|
||||
var new_password = $('#new_email_password').val();
|
||||
|
||||
postJSON('/change_email',{"new_email":new_email,
|
||||
"password":new_password},
|
||||
function(data){
|
||||
if(data.success){
|
||||
$("#change_email").html("<h1>Please verify your new email</h1><p>You'll receive a confirmation in your in-box. Please click the link in the email to confirm the email change.</p>");
|
||||
} else {
|
||||
$("#change_email_error").html(data.error);
|
||||
}
|
||||
});
|
||||
log_event("profile", {"type":"email_change_request",
|
||||
"old_email":"${email}",
|
||||
"new_email":new_email});
|
||||
return false;
|
||||
});
|
||||
|
||||
$("#change_name_form").submit(function(){
|
||||
var new_name = $('#new_name_field').val();
|
||||
var rationale = $('#name_rationale_field').val();
|
||||
|
||||
postJSON('/change_name',{"new_name":new_name,
|
||||
"rationale":rationale},
|
||||
function(data){
|
||||
if(data.success){
|
||||
$("#apply_name_change").html("<h1>Your request has been submitted.</h1><p>We'll send you an e-mail when approve the change or need further information. Please allow for up to a week for us to process your request.</p>");
|
||||
} else {
|
||||
$("#change_name_error").html(data.error);
|
||||
}
|
||||
});
|
||||
log_event("profile", {"type":"name_change_request",
|
||||
"new_name":new_name,
|
||||
"rationale":rationale});
|
||||
return false;
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
</%block>
|
||||
|
||||
|
||||
<%include file="course_navigation.html" args="active_page='profile'" />
|
||||
|
||||
<section class="container">
|
||||
@@ -139,19 +138,26 @@ $(function() {
|
||||
%>
|
||||
|
||||
<h3><a href="${reverse('courseware_section', kwargs={'course_id' : course.id, 'chapter' : chapter['url_name'], 'section' : section['url_name']})}">
|
||||
${ section['display_name'] }</a> ${"({0:.3n}/{1:.3n}) {2}".format( float(earned), float(total), percentageString )}</h3>
|
||||
${section['format']}
|
||||
%if 'due' in section and section['due']!="":
|
||||
due ${section['due']}
|
||||
%endif
|
||||
${ section['display_name'] }</a><span> ${"({0:.3n}/{1:.3n}) {2}".format( float(earned), float(total), percentageString )}</span></h3>
|
||||
<p>
|
||||
${section['format']}
|
||||
|
||||
%if 'due' in section and section['due']!="":
|
||||
<em>
|
||||
due ${section['due']}
|
||||
</em>
|
||||
%endif
|
||||
</p>
|
||||
|
||||
%if len(section['scores']) > 0:
|
||||
<ol class="scores">
|
||||
${ "Problem Scores: " if section['graded'] else "Practice Scores: "}
|
||||
%for score in section['scores']:
|
||||
<li class="score">${"{0:.3n}/{1:.3n}".format(float(score.earned),float(score.possible))}</li>
|
||||
%endfor
|
||||
</ol>
|
||||
<section class="scores">
|
||||
<h3> ${ "Problem Scores: " if section['graded'] else "Practice Scores: "} </h3>
|
||||
<ol>
|
||||
%for score in section['scores']:
|
||||
<li>${"{0:.3n}/{1:.3n}".format(float(score.earned),float(score.possible))}</li>
|
||||
%endfor
|
||||
</ol>
|
||||
</section>
|
||||
%endif
|
||||
|
||||
</li> <!--End section-->
|
||||
@@ -202,7 +208,7 @@ $(function() {
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div id="password_reset_complete" class="leanModal_box">
|
||||
<div id="password_reset_complete" class="modal">
|
||||
<a href="#password_reset_complete" rel="leanModal" id="password_reset_complete_link"></a>
|
||||
<h1>Password Reset Email Sent</h1>
|
||||
<p>
|
||||
@@ -210,83 +216,78 @@ $(function() {
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div id="apply_name_change" class="leanModal_box">
|
||||
<h1>Apply to change your name</h1>
|
||||
<form id="change_name_form">
|
||||
<div id="change_name_error"> </div>
|
||||
<fieldset>
|
||||
<p>To uphold the credibility of <span class="edx">edX</span> certificates, name changes must go through an approval process. A member of the course staff will review your request, and if approved, update your information. Please allow up to a week for your request to be processed. Thank you.</p>
|
||||
<ul>
|
||||
<li>
|
||||
<label>Enter your desired full name, as it will appear on the <span class="edx">edX</span> Certificate: </label>
|
||||
<input id="new_name_field" value="" type="text" />
|
||||
</li>
|
||||
<li>
|
||||
<label>Reason for name change:</label>
|
||||
<textarea id="name_rationale_field" value=""></textarea>
|
||||
</li>
|
||||
<li>
|
||||
<input type="submit" id="submit">
|
||||
</li>
|
||||
</ul>
|
||||
</fieldset>
|
||||
</form>
|
||||
<div id="apply_name_change" class="modal">
|
||||
<div class="inner-wrapper">
|
||||
<header>
|
||||
<h2>Apply to change your name</h2>
|
||||
<hr />
|
||||
</header>
|
||||
<form id="change_name_form">
|
||||
<div id="change_name_error"> </div>
|
||||
<fieldset>
|
||||
<p>To uphold the credibility of <span class="edx">edX</span> certificates, name changes must go through an approval process. A member of the course staff will review your request, and if approved, update your information. Please allow up to a week for your request to be processed. Thank you.</p>
|
||||
<label>Enter your desired full name, as it will appear on the <span class="edx">edX</span> Certificate: </label>
|
||||
<input id="new_name_field" value="" type="text" />
|
||||
<label>Reason for name change:</label>
|
||||
<textarea id="name_rationale_field" value=""></textarea>
|
||||
<input type="submit" id="submit">
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="change_email" class="leanModal_box">
|
||||
<h1>Change e-mail</h1>
|
||||
<div id="change_email" class="modal">
|
||||
<div class="inner-wrapper">
|
||||
<header>
|
||||
<h2>Change e-mail</h2>
|
||||
<hr />
|
||||
</header>
|
||||
<div id="apply_name_change_error"></div>
|
||||
<form id="change_email_form">
|
||||
<div id="change_email_error"> </div>
|
||||
<fieldset>
|
||||
<ul>
|
||||
<li>
|
||||
<label> Please enter your new email address: </label>
|
||||
<input id="new_email_field" type="email" value="" />
|
||||
</li>
|
||||
<label> Please enter your new email address: </label>
|
||||
<input id="new_email_field" type="email" value="" />
|
||||
<label> Please confirm your password: </label>
|
||||
<input id="new_email_password" value="" type="password" />
|
||||
<p>We will send a confirmation to both ${email} and your new e-mail as part of the process.</p>
|
||||
<input type="submit" id="submit_email_change" />
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<li>
|
||||
<label> Please confirm your password: </label>
|
||||
<input id="new_email_password" value="" type="password" />
|
||||
</li>
|
||||
<li>
|
||||
<p>We will send a confirmation to both ${email} and your new e-mail as part of the process.</p>
|
||||
<input type="submit" id="submit_email_change" />
|
||||
</li>
|
||||
</ul>
|
||||
<div id="deactivate-account" class="modal">
|
||||
<div class="inner-wrapper">
|
||||
<header>
|
||||
<h2>Deactivate <span class="edx">edX</span> Account</h2>
|
||||
<hr />
|
||||
</header>
|
||||
<p>Once you deactivate you’re MIT<em>x</em> account you will no longer recieve updates and new class announcements from MIT<em>x</em>.</p>
|
||||
<p>If you’d like to still get updates and new class announcements you can just <a href="#unenroll" rel="leanModal">unenroll</a> and keep your account active.</p>
|
||||
|
||||
<form id="unenroll_form">
|
||||
<div id="unenroll_error"> </div>
|
||||
<fieldset>
|
||||
<input type="submit" id="" value="Yes, I don't want an edX account or hear about any new classes or updates to edX" />
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="deactivate-account" class="leanModal_box">
|
||||
<h1>Deactivate <span class="edx">edX</span> Account</h1>
|
||||
<p>Once you deactivate you’re MIT<em>x</em> account you will no longer recieve updates and new class announcements from MIT<em>x</em>.</p>
|
||||
<p>If you’d like to still get updates and new class announcements you can just <a href="#unenroll" rel="leanModal">unenroll</a> and keep your account active.</p>
|
||||
<div id="unenroll" class="modal">
|
||||
<div class="inner-wrapper">
|
||||
<header>
|
||||
<h2>Unenroll from 6.002x</h2>
|
||||
<hr />
|
||||
</header>
|
||||
<p>Please note: you will still receive updates and new class announcements from ed<em>X</em>. If you don’t wish to receive any more updates or announcements <a href="#deactivate-account" rel="leanModal">deactivate your account</a>.</p>
|
||||
|
||||
<form id="unenroll_form">
|
||||
<div id="unenroll_error"> </div>
|
||||
<fieldset>
|
||||
<ul>
|
||||
<li>
|
||||
<input type="submit" id="" value="Yes, I don't want an edX account or hear about any new classes or updates to edX" />
|
||||
</li>
|
||||
</ul>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="unenroll" class="leanModal_box">
|
||||
<h1>Unenroll from 6.002x</h1>
|
||||
<p>Please note: you will still receive updates and new class announcements from ed<em>X</em>. If you don’t wish to receive any more updates or announcements <a href="#deactivate-account" rel="leanModal">deactivate your account</a>.</p>
|
||||
|
||||
<form id="unenroll_form">
|
||||
<div id="unenroll_error"> </div>
|
||||
<fieldset>
|
||||
<ul>
|
||||
<li>
|
||||
<input type="submit" id="" value="Yes, I want to unenroll from 6.002x but still hear about any new classes or updates to edX" />
|
||||
</li>
|
||||
</ul>
|
||||
</fieldset>
|
||||
</form>
|
||||
<form id="unenroll_form">
|
||||
<div id="unenroll_error"> </div>
|
||||
<fieldset>
|
||||
<input type="submit" id="" value="Yes, I want to unenroll from 6.002x but still hear about any new classes or updates to edX" />
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<%page args="grade_summary, graph_div_id, **kwargs"/>
|
||||
<%page args="grade_summary, grade_cutoffs, graph_div_id, **kwargs"/>
|
||||
<%!
|
||||
import json
|
||||
import math
|
||||
%>
|
||||
|
||||
$(function () {
|
||||
@@ -89,8 +90,16 @@ $(function () {
|
||||
ticks += [ [overviewBarX, "Total"] ]
|
||||
tickIndex += 1 + sectionSpacer
|
||||
|
||||
totalScore = grade_summary['percent']
|
||||
totalScore = math.floor(grade_summary['percent'] * 100) / 100 #We floor it to the nearest percent, 80.9 won't show up like a 90 (an A)
|
||||
detail_tooltips['Dropped Scores'] = dropped_score_tooltips
|
||||
|
||||
|
||||
## ----------------------------- Grade cutoffs ------------------------- ##
|
||||
|
||||
grade_cutoff_ticks = [ [1, "100%"], [0, "0%"] ]
|
||||
for grade in ['A', 'B', 'C']:
|
||||
percent = grade_cutoffs[grade]
|
||||
grade_cutoff_ticks.append( [ percent, "{0} {1:.0%}".format(grade, percent) ] )
|
||||
%>
|
||||
|
||||
var series = ${ json.dumps( series ) };
|
||||
@@ -98,6 +107,7 @@ $(function () {
|
||||
var bottomTicks = ${ json.dumps(bottomTicks) };
|
||||
var detail_tooltips = ${ json.dumps(detail_tooltips) };
|
||||
var droppedScores = ${ json.dumps(droppedScores) };
|
||||
var grade_cutoff_ticks = ${ json.dumps(grade_cutoff_ticks) }
|
||||
|
||||
//Alwasy be sure that one series has the xaxis set to 2, or the second xaxis labels won't show up
|
||||
series.push( {label: 'Dropped Scores', data: droppedScores, points: {symbol: "cross", show: true, radius: 3}, bars: {show: false}, color: "#333"} );
|
||||
@@ -107,10 +117,10 @@ $(function () {
|
||||
lines: {show: false, steps: false },
|
||||
bars: {show: true, barWidth: 0.8, align: 'center', lineWidth: 0, fill: .8 },},
|
||||
xaxis: {tickLength: 0, min: 0.0, max: ${tickIndex - sectionSpacer}, ticks: ticks, labelAngle: 90},
|
||||
yaxis: {ticks: [[1, "100%"], [0.87, "A 87%"], [0.7, "B 70%"], [0.6, "C 60%"], [0, "0%"]], min: 0.0, max: 1.0, labelWidth: 50},
|
||||
yaxis: {ticks: grade_cutoff_ticks, min: 0.0, max: 1.0, labelWidth: 50},
|
||||
grid: { hoverable: true, clickable: true, borderWidth: 1,
|
||||
markings: [ {yaxis: {from: 0.87, to: 1 }, color: "#ddd"}, {yaxis: {from: 0.7, to: 0.87 }, color: "#e9e9e9"},
|
||||
{yaxis: {from: 0.6, to: 0.7 }, color: "#f3f3f3"}, ] },
|
||||
markings: [ {yaxis: {from: ${grade_cutoffs['A']}, to: 1 }, color: "#ddd"}, {yaxis: {from: ${grade_cutoffs['B']}, to: ${grade_cutoffs['A']} }, color: "#e9e9e9"},
|
||||
{yaxis: {from: ${grade_cutoffs['C']}, to: ${grade_cutoffs['B']} }, color: "#f3f3f3"}, ] },
|
||||
legend: {show: false},
|
||||
};
|
||||
|
||||
|
||||
@@ -71,9 +71,9 @@
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<%block name="wiki_head"/>
|
||||
|
||||
|
||||
</%block>
|
||||
|
||||
<%block name="bodyextra">
|
||||
@@ -86,7 +86,7 @@
|
||||
<div class="wiki-wrapper">
|
||||
<%block name="wiki_panel">
|
||||
<div aria-label="Wiki Navigation" id="wiki_panel">
|
||||
<h2>Course Wiki</h2>
|
||||
<h2>Course Wiki</h2>
|
||||
<ul class="action">
|
||||
<li>
|
||||
<h3>
|
||||
@@ -101,12 +101,12 @@
|
||||
|
||||
<div id="wiki_create_form">
|
||||
<%
|
||||
baseURL = wiki_reverse("wiki_create", course=course, kwargs={"article_path" : namespace + "/" })
|
||||
baseURL = wiki_reverse("wiki_create", course=course, kwargs={"article_path" : namespace + "/" })
|
||||
%>
|
||||
<form method="GET" onsubmit="this.action='${baseURL}' + this.wiki_article_name.value.replace(/([^a-zA-Z0-9\-])/g, '');">
|
||||
<div>
|
||||
<label for="id_wiki_article_name">Title of article</label>
|
||||
<input type="text" name="wiki_article_name" id="id_wiki_article_name" /><br/>
|
||||
<input type="text" name="wiki_article_name" id="id_wiki_article_name" />
|
||||
</div>
|
||||
<ul>
|
||||
<li>
|
||||
@@ -130,31 +130,31 @@
|
||||
</%block>
|
||||
|
||||
<section class="wiki-body">
|
||||
%if wiki_article is not UNDEFINED:
|
||||
<header>
|
||||
%if wiki_article.locked:
|
||||
<p><strong>This article has been locked</strong></p>
|
||||
%endif
|
||||
<p>Last modified: ${wiki_article.modified_on.strftime("%b %d, %Y, %I:%M %p")}</p>
|
||||
%endif
|
||||
|
||||
%if wiki_article is not UNDEFINED:
|
||||
<ul>
|
||||
|
||||
<li>
|
||||
<a href="${ wiki_reverse('wiki_view', wiki_article, course)}" class="view">View</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="${ wiki_reverse('wiki_edit', wiki_article, course)}" class="edit">Edit</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="${ wiki_reverse('wiki_history', wiki_article, course)}" class="history">History</a>
|
||||
</li>
|
||||
</ul>
|
||||
</header>
|
||||
%if wiki_article is not UNDEFINED:
|
||||
<header>
|
||||
%if wiki_article.locked:
|
||||
<p><strong>This article has been locked</strong></p>
|
||||
%endif
|
||||
<p>Last modified: ${wiki_article.modified_on.strftime("%b %d, %Y, %I:%M %p")}</p>
|
||||
%endif
|
||||
|
||||
%if wiki_article is not UNDEFINED:
|
||||
<ul>
|
||||
|
||||
<li>
|
||||
<a href="${ wiki_reverse('wiki_view', wiki_article, course)}" class="view">View</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="${ wiki_reverse('wiki_edit', wiki_article, course)}" class="edit">Edit</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="${ wiki_reverse('wiki_history', wiki_article, course)}" class="history">History</a>
|
||||
</li>
|
||||
</ul>
|
||||
</header>
|
||||
%endif
|
||||
|
||||
<%block name="wiki_page_title"/>
|
||||
<%block name="wiki_body"/>
|
||||
|
||||
@@ -65,12 +65,10 @@ ${"Edit " + wiki_title + " - " if wiki_title is not UNDEFINED else ""}MITx 6.002
|
||||
</div>
|
||||
${wiki_form}
|
||||
%if create_article:
|
||||
<input type="submit" id="submit_edit" value="Create article" /></td>
|
||||
<input type="submit" id="submit_edit" value="Create article" />
|
||||
%else:
|
||||
<input type="submit" id="submit_edit" name="edit" value="Save Changes" />
|
||||
<input type="submit" id="submit_delete" name="delete" value="Delete article" />
|
||||
%endif
|
||||
</form>
|
||||
|
||||
<%include file="simplewiki_instructions.html"/>
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ Displaying all articles
|
||||
<li><h3><a href="${wiki_reverse("wiki_view", article, course)}">${article.title} ${'(Deleted)' if article_deleted else ''}</a></h3></li>
|
||||
%endfor
|
||||
|
||||
%if not wiki_search_results:
|
||||
%if not wiki_search_results:
|
||||
No articles matching <b>${wiki_search_query if wiki_search_query is not UNDEFINED else ""} </b>!
|
||||
%endif
|
||||
</ul>
|
||||
|
||||
@@ -2,9 +2,13 @@ ${module_content}
|
||||
%if edit_link:
|
||||
<div><a href="${edit_link}">Edit</a></div>
|
||||
% endif
|
||||
|
||||
<div class="staff_info">
|
||||
<a href="javascript:void(0)" onclick="javascript:$('#${element_id}_debug').toggle()">Staff Debug Info</a>
|
||||
<span style="display:none" id="${element_id}_debug">
|
||||
definition = <pre>${definition | h}</pre>
|
||||
metadata = ${metadata | h}
|
||||
</span>
|
||||
</div>
|
||||
%if render_histogram:
|
||||
<div id="histogram_${element_id}" class="histogram" data-histogram="${histogram}"></div>
|
||||
|
||||
@@ -89,17 +89,6 @@ $("#open_close_accordion a").click(function(){
|
||||
</nav>
|
||||
|
||||
<img id="bookpage" src="${ settings.BOOK_URL }p${ "%03i"%(page) }.png">
|
||||
|
||||
<nav class="bottom-nav">
|
||||
<ul>
|
||||
<li class="last">
|
||||
<a href="javascript:prev_page()">Previous page</a>
|
||||
</li>
|
||||
<li class="next">
|
||||
<a href="javascript:next_page()">Next page</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
@@ -107,7 +107,6 @@ if settings.COURSEWARE_ENABLED:
|
||||
|
||||
# TODO: These views need to be updated before they work
|
||||
# url(r'^calculate$', 'util.views.calculate'),
|
||||
# url(r'^gradebook$', 'courseware.views.gradebook'),
|
||||
# TODO: We should probably remove the circuit package. I believe it was only used in the old way of saving wiki circuits for the wiki
|
||||
# url(r'^edit_circuit/(?P<circuit>[^/]*)$', 'circuit.views.edit_circuit'),
|
||||
# url(r'^save_circuit/(?P<circuit>[^/]*)$', 'circuit.views.save_circuit'),
|
||||
@@ -119,7 +118,7 @@ if settings.COURSEWARE_ENABLED:
|
||||
#About the course
|
||||
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/about$',
|
||||
'courseware.views.course_about', name="about_course"),
|
||||
|
||||
|
||||
#Inside the course
|
||||
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/info$',
|
||||
'courseware.views.course_info', name="info"),
|
||||
@@ -143,6 +142,10 @@ if settings.COURSEWARE_ENABLED:
|
||||
# discussion
|
||||
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/discussion/',
|
||||
include('django_comment_client.urls')),
|
||||
|
||||
# For the instructor
|
||||
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/gradebook$',
|
||||
'courseware.views.gradebook'),
|
||||
)
|
||||
|
||||
# Multicourse wiki
|
||||
|
||||
Reference in New Issue
Block a user