From 2e4f21ee3b505190238c5be2a47c0c42643dc338 Mon Sep 17 00:00:00 2001 From: ichuang Date: Tue, 7 Aug 2012 19:39:57 -0400 Subject: [PATCH 01/21] replace_static_urls should only be run once (currently twice, eg if html is in a veritical) --- common/djangoapps/xmodule_modifiers.py | 4 +++- lms/djangoapps/courseware/module_render.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/common/djangoapps/xmodule_modifiers.py b/common/djangoapps/xmodule_modifiers.py index 380388b545..eac9604a7f 100644 --- a/common/djangoapps/xmodule_modifiers.py +++ b/common/djangoapps/xmodule_modifiers.py @@ -34,7 +34,7 @@ def wrap_xmodule(get_html, module, template): return _get_html -def replace_static_urls(get_html, prefix): +def replace_static_urls(get_html, prefix, module): """ Updates the supplied module with a new get_html function that wraps the old get_html function and substitutes urls of the form /static/... @@ -43,6 +43,8 @@ def replace_static_urls(get_html, prefix): @wraps(get_html) def _get_html(): + if type(module) in [SequenceModule, VerticalModule]: # TODO: make this more general, eg use an XModule attribute instead + return get_html() return replace_urls(get_html(), staticfiles_prefix=prefix) return _get_html diff --git a/lms/djangoapps/courseware/module_render.py b/lms/djangoapps/courseware/module_render.py index d32f3d81ec..1397b881f2 100644 --- a/lms/djangoapps/courseware/module_render.py +++ b/lms/djangoapps/courseware/module_render.py @@ -191,7 +191,7 @@ def get_module(user, request, location, student_module_cache, position=None): module.get_html = replace_static_urls( wrap_xmodule(module.get_html, module, 'xmodule_display.html'), - module.metadata['data_dir'] + module.metadata['data_dir'], module ) if settings.MITX_FEATURES.get('DISPLAY_HISTOGRAMS_TO_STAFF'): From 4240830e68247d0690e1d6716df45e13febbca24 Mon Sep 17 00:00:00 2001 From: ichuang Date: Tue, 7 Aug 2012 19:47:14 -0400 Subject: [PATCH 02/21] cms also needs replace_static_urls call fixed --- cms/djangoapps/contentstore/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cms/djangoapps/contentstore/views.py b/cms/djangoapps/contentstore/views.py index 0305795e52..31be96ad7b 100644 --- a/cms/djangoapps/contentstore/views.py +++ b/cms/djangoapps/contentstore/views.py @@ -249,7 +249,7 @@ def load_preview_module(request, preview_id, descriptor, instance_state, shared_ module = descriptor.xmodule_constructor(system)(instance_state, shared_state) module.get_html = replace_static_urls( wrap_xmodule(module.get_html, module, "xmodule_display.html"), - module.metadata['data_dir'] + module.metadata['data_dir'], module ) save_preview_state(request, preview_id, descriptor.location.url(), module.get_instance_state(), module.get_shared_state()) From 27cd9ef98662b7067046b69f8b3961fbf2556a7f Mon Sep 17 00:00:00 2001 From: ichuang Date: Wed, 8 Aug 2012 22:41:19 -0400 Subject: [PATCH 03/21] minor change to allow github url to be overridden by metadata --- common/djangoapps/xmodule_modifiers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common/djangoapps/xmodule_modifiers.py b/common/djangoapps/xmodule_modifiers.py index eac9604a7f..5dac093a66 100644 --- a/common/djangoapps/xmodule_modifiers.py +++ b/common/djangoapps/xmodule_modifiers.py @@ -99,7 +99,8 @@ def add_histogram(get_html, module): # doesn't like symlinks) filepath = filename data_dir = osfs.root_path.rsplit('/')[-1] - edit_link = "https://github.com/MITx/%s/tree/master/%s" % (data_dir,filepath) + giturl = module.metadata.get('giturl','https://github.com/MITx') + edit_link = "%s/%s/tree/master/%s" % (giturl,data_dir,filepath) else: edit_link = False From d2c1df88d1f6e33c3c0928a499de14707e68ba1a Mon Sep 17 00:00:00 2001 From: ichuang Date: Wed, 8 Aug 2012 23:08:05 -0400 Subject: [PATCH 04/21] update utility script to create course groups --- utility-scripts/create_groups.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/utility-scripts/create_groups.py b/utility-scripts/create_groups.py index 33c563127f..0e3245bb4d 100644 --- a/utility-scripts/create_groups.py +++ b/utility-scripts/create_groups.py @@ -18,6 +18,7 @@ except Exception as err: from django.conf import settings from django.contrib.auth.models import User, Group from path import path +from lxml import etree data_dir = settings.DATA_DIR print "data_dir = %s" % data_dir @@ -26,7 +27,17 @@ for course_dir in os.listdir(data_dir): # print course_dir if not os.path.isdir(path(data_dir) / course_dir): continue - gname = 'staff_%s' % course_dir + + cxfn = path(data_dir) / course_dir / 'course.xml' + coursexml = etree.parse(cxfn) + cxmlroot = coursexml.getroot() + course = cxmlroot.get('course') + if course is None: + print "oops, can't get course id for %s" % course_dir + continue + print "course=%s for course_dir=%s" % (course,course_dir) + + gname = 'staff_%s' % course if Group.objects.filter(name=gname): print "group exists for %s" % gname continue From 411e77e19d2d7a4c31ea1910dfb0e1855f97b1b2 Mon Sep 17 00:00:00 2001 From: ichuang Date: Thu, 9 Aug 2012 19:03:11 -0400 Subject: [PATCH 05/21] ModuleSystem should get its DEBUG set from settings.DEBUG in module_render --- lms/djangoapps/courseware/module_render.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lms/djangoapps/courseware/module_render.py b/lms/djangoapps/courseware/module_render.py index 1397b881f2..4910488af2 100644 --- a/lms/djangoapps/courseware/module_render.py +++ b/lms/djangoapps/courseware/module_render.py @@ -186,6 +186,7 @@ def get_module(user, request, location, student_module_cache, position=None): ) # pass position specified in URL to module through ModuleSystem system.set('position', position) + system.set('DEBUG',settings.DEBUG) module = descriptor.xmodule_constructor(system)(instance_state, shared_state) From c0a4ff3717ff7adeee4b91aa42b31f023353efad Mon Sep 17 00:00:00 2001 From: ichuang Date: Thu, 9 Aug 2012 19:12:53 -0400 Subject: [PATCH 06/21] more useful debugging message for capa problem script errors --- common/lib/capa/capa/capa_problem.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/common/lib/capa/capa/capa_problem.py b/common/lib/capa/capa/capa_problem.py index 92823667e7..70e76913be 100644 --- a/common/lib/capa/capa/capa_problem.py +++ b/common/lib/capa/capa/capa_problem.py @@ -393,9 +393,10 @@ class LoncapaProblem(object): context['script_code'] += code # store code source in context try: exec code in context, context # use "context" for global context; thus defs in code are global within code - except Exception: + except Exception as err: log.exception("Error while execing script code: " + code) - raise responsetypes.LoncapaProblemError("Error while executing script code") + msg = "Error while executing script code: %s" % str(err).replace('<','<') + raise responsetypes.LoncapaProblemError(msg) finally: sys.path = original_path From dade6dd18217fa8af8d16853d7e7e983f0af653e Mon Sep 17 00:00:00 2001 From: ichuang Date: Fri, 10 Aug 2012 09:36:11 -0400 Subject: [PATCH 07/21] askbot template loader is broken - breaks admin view; disable in dev_ike.py --- lms/envs/dev_ike.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lms/envs/dev_ike.py b/lms/envs/dev_ike.py index 288a99bf3b..d8b61572a5 100644 --- a/lms/envs/dev_ike.py +++ b/lms/envs/dev_ike.py @@ -21,3 +21,4 @@ MITX_FEATURES['ACCESS_REQUIRE_STAFF_FOR_COURSE'] = True # require that user be 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') ]) +TEMPLATE_LOADERS = tuple([ app for app in TEMPLATE_LOADERS if not app.startswith('askbot') ]) From 881f07f3c3d0d8ae0dd1f23263de6fe0817cb1f0 Mon Sep 17 00:00:00 2001 From: ichuang Date: Fri, 10 Aug 2012 10:35:08 -0400 Subject: [PATCH 08/21] revert double-mangling patch in xmodule_modifiers; cale fixed in replace_urls --- common/djangoapps/xmodule_modifiers.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/common/djangoapps/xmodule_modifiers.py b/common/djangoapps/xmodule_modifiers.py index 5dac093a66..6cbf334afc 100644 --- a/common/djangoapps/xmodule_modifiers.py +++ b/common/djangoapps/xmodule_modifiers.py @@ -43,8 +43,6 @@ def replace_static_urls(get_html, prefix, module): @wraps(get_html) def _get_html(): - if type(module) in [SequenceModule, VerticalModule]: # TODO: make this more general, eg use an XModule attribute instead - return get_html() return replace_urls(get_html(), staticfiles_prefix=prefix) return _get_html From f99eb930ac973ebfa0c9ab81b830d93f76b63c23 Mon Sep 17 00:00:00 2001 From: ichuang Date: Fri, 10 Aug 2012 15:18:33 -0400 Subject: [PATCH 09/21] new static/admin files for django 1.4 admin --- lms/static/admin/css/base.css | 135 +++++++++++++----- lms/static/admin/css/changelists.css | 14 +- lms/static/admin/css/forms.css | 22 ++- lms/static/admin/css/ie.css | 8 +- lms/static/admin/css/login.css | 3 + lms/static/admin/css/rtl.css | 31 ++-- lms/static/admin/css/widgets.css | 113 ++++++++++----- lms/static/admin/img/changelist-bg.gif | Bin 0 -> 58 bytes lms/static/admin/img/changelist-bg_rtl.gif | Bin 0 -> 75 bytes lms/static/admin/img/chooser-bg.gif | Bin 0 -> 199 bytes lms/static/admin/img/chooser_stacked-bg.gif | Bin 0 -> 212 bytes lms/static/admin/img/default-bg-reverse.gif | Bin 0 -> 843 bytes lms/static/admin/img/default-bg.gif | Bin 0 -> 844 bytes lms/static/admin/img/deleted-overlay.gif | Bin 0 -> 45 bytes lms/static/admin/img/icon-no.gif | Bin 0 -> 176 bytes lms/static/admin/img/icon-unknown.gif | Bin 0 -> 130 bytes lms/static/admin/img/icon-yes.gif | Bin 0 -> 299 bytes lms/static/admin/img/icon_addlink.gif | Bin 0 -> 119 bytes lms/static/admin/img/icon_alert.gif | Bin 0 -> 145 bytes lms/static/admin/img/icon_calendar.gif | Bin 0 -> 192 bytes lms/static/admin/img/icon_changelink.gif | Bin 0 -> 119 bytes lms/static/admin/img/icon_clock.gif | Bin 0 -> 390 bytes lms/static/admin/img/icon_deletelink.gif | Bin 0 -> 181 bytes lms/static/admin/img/icon_error.gif | Bin 0 -> 319 bytes lms/static/admin/img/icon_searchbox.png | Bin 0 -> 667 bytes lms/static/admin/img/icon_success.gif | Bin 0 -> 341 bytes lms/static/admin/img/inline-delete-8bit.png | Bin 0 -> 477 bytes lms/static/admin/img/inline-delete.png | Bin 0 -> 781 bytes lms/static/admin/img/inline-restore-8bit.png | Bin 0 -> 447 bytes lms/static/admin/img/inline-restore.png | Bin 0 -> 623 bytes lms/static/admin/img/inline-splitter-bg.gif | Bin 0 -> 102 bytes lms/static/admin/img/nav-bg-grabber.gif | Bin 0 -> 116 bytes lms/static/admin/img/nav-bg-reverse.gif | Bin 0 -> 186 bytes lms/static/admin/img/nav-bg-selected.gif | Bin 0 -> 265 bytes lms/static/admin/img/nav-bg.gif | Bin 0 -> 273 bytes lms/static/admin/img/selector-icons.gif | Bin 0 -> 2771 bytes lms/static/admin/img/selector-search.gif | Bin 0 -> 552 bytes lms/static/admin/img/sorting-icons.gif | Bin 0 -> 369 bytes lms/static/admin/img/tool-left.gif | Bin 0 -> 197 bytes lms/static/admin/img/tool-left_over.gif | Bin 0 -> 203 bytes lms/static/admin/img/tool-right.gif | Bin 0 -> 198 bytes lms/static/admin/img/tool-right_over.gif | Bin 0 -> 200 bytes lms/static/admin/img/tooltag-add.gif | Bin 0 -> 932 bytes lms/static/admin/img/tooltag-add_over.gif | Bin 0 -> 336 bytes lms/static/admin/img/tooltag-arrowright.gif | Bin 0 -> 351 bytes .../admin/img/tooltag-arrowright_over.gif | Bin 0 -> 354 bytes lms/static/admin/js/SelectFilter2.js | 75 +++++++--- lms/static/admin/js/actions.min.js | 12 +- .../admin/js/admin/DateTimeShortcuts.js | 24 +++- .../admin/js/admin/RelatedObjectLookups.js | 5 +- lms/static/admin/js/admin/ordering.js | 2 +- lms/static/admin/js/collapse.js | 11 +- lms/static/admin/js/collapse.min.js | 4 +- lms/static/admin/js/core.js | 10 -- lms/static/admin/js/inlines.min.js | 10 +- lms/static/admin/js/jquery.init.js | 6 +- lms/static/admin/js/prepopulate.min.js | 2 +- 57 files changed, 322 insertions(+), 165 deletions(-) create mode 100644 lms/static/admin/img/changelist-bg.gif create mode 100644 lms/static/admin/img/changelist-bg_rtl.gif create mode 100644 lms/static/admin/img/chooser-bg.gif create mode 100644 lms/static/admin/img/chooser_stacked-bg.gif create mode 100644 lms/static/admin/img/default-bg-reverse.gif create mode 100644 lms/static/admin/img/default-bg.gif create mode 100644 lms/static/admin/img/deleted-overlay.gif create mode 100644 lms/static/admin/img/icon-no.gif create mode 100644 lms/static/admin/img/icon-unknown.gif create mode 100644 lms/static/admin/img/icon-yes.gif create mode 100644 lms/static/admin/img/icon_addlink.gif create mode 100644 lms/static/admin/img/icon_alert.gif create mode 100644 lms/static/admin/img/icon_calendar.gif create mode 100644 lms/static/admin/img/icon_changelink.gif create mode 100644 lms/static/admin/img/icon_clock.gif create mode 100644 lms/static/admin/img/icon_deletelink.gif create mode 100644 lms/static/admin/img/icon_error.gif create mode 100644 lms/static/admin/img/icon_searchbox.png create mode 100644 lms/static/admin/img/icon_success.gif create mode 100644 lms/static/admin/img/inline-delete-8bit.png create mode 100644 lms/static/admin/img/inline-delete.png create mode 100644 lms/static/admin/img/inline-restore-8bit.png create mode 100644 lms/static/admin/img/inline-restore.png create mode 100644 lms/static/admin/img/inline-splitter-bg.gif create mode 100644 lms/static/admin/img/nav-bg-grabber.gif create mode 100644 lms/static/admin/img/nav-bg-reverse.gif create mode 100644 lms/static/admin/img/nav-bg-selected.gif create mode 100644 lms/static/admin/img/nav-bg.gif create mode 100644 lms/static/admin/img/selector-icons.gif create mode 100644 lms/static/admin/img/selector-search.gif create mode 100644 lms/static/admin/img/sorting-icons.gif create mode 100644 lms/static/admin/img/tool-left.gif create mode 100644 lms/static/admin/img/tool-left_over.gif create mode 100644 lms/static/admin/img/tool-right.gif create mode 100644 lms/static/admin/img/tool-right_over.gif create mode 100644 lms/static/admin/img/tooltag-add.gif create mode 100644 lms/static/admin/img/tooltag-add_over.gif create mode 100644 lms/static/admin/img/tooltag-arrowright.gif create mode 100644 lms/static/admin/img/tooltag-arrowright_over.gif diff --git a/lms/static/admin/css/base.css b/lms/static/admin/css/base.css index c5e385d508..5e5fc58a77 100644 --- a/lms/static/admin/css/base.css +++ b/lms/static/admin/css/base.css @@ -189,6 +189,10 @@ p.mini { color: #999; } +img.help-tooltip { + cursor: help; +} + p img, h1 img, h2 img, h3 img, h4 img, td img { vertical-align: middle; } @@ -259,7 +263,7 @@ tfoot td { color: #666; padding: 2px 5px; font-size: 11px; - background: #e1e1e1 url(../img/admin/nav-bg.gif) top left repeat-x; + background: #e1e1e1 url(../img/nav-bg.gif) top left repeat-x; border-left: 1px solid #ddd; border-bottom: 1px solid #ddd; } @@ -305,25 +309,84 @@ tr.alt { /* SORTABLE TABLES */ +thead th { + padding: 2px 5px; + line-height: normal; +} + thead th a:link, thead th a:visited { color: #666; +} + +thead th.sorted { + background: #c5c5c5 url(../img/nav-bg-selected.gif) top left repeat-x; +} + +table thead th .text span { + padding: 2px 5px; + display:block; +} + +table thead th .text a { display: block; + cursor: pointer; + padding: 2px 5px; } -table thead th.sorted { - background-position: bottom left !important; +table thead th.sortable:hover { + background: white url(../img/nav-bg-reverse.gif) 0 -5px repeat-x; } -table thead th.sorted a { - padding-right: 13px; +thead th.sorted a.sortremove { + visibility: hidden; } -table thead th.ascending a { - background: url(../img/admin/arrow-up.gif) right .4em no-repeat; +table thead th.sorted:hover a.sortremove { + visibility: visible; } -table thead th.descending a { - background: url(../img/admin/arrow-down.gif) right .4em no-repeat; +table thead th.sorted .sortoptions { + display: block; + padding: 4px 5px 0 5px; + float: right; + text-align: right; +} + +table thead th.sorted .sortpriority { + font-size: .8em; + min-width: 12px; + text-align: center; + vertical-align: top; +} + +table thead th.sorted .sortoptions a { + width: 14px; + height: 12px; + display: inline-block; +} + +table thead th.sorted .sortoptions a.sortremove { + background: url(../img/sorting-icons.gif) -4px -5px no-repeat; +} + +table thead th.sorted .sortoptions a.sortremove:hover { + background: url(../img/sorting-icons.gif) -4px -27px no-repeat; +} + +table thead th.sorted .sortoptions a.ascending { + background: url(../img/sorting-icons.gif) -5px -50px no-repeat; +} + +table thead th.sorted .sortoptions a.ascending:hover { + background: url(../img/sorting-icons.gif) -5px -72px no-repeat; +} + +table thead th.sorted .sortoptions a.descending { + background: url(../img/sorting-icons.gif) -5px -94px no-repeat; +} + +table thead th.sorted .sortoptions a.descending:hover { + background: url(../img/sorting-icons.gif) -5px -115px no-repeat; } /* ORDERABLE TABLES */ @@ -334,7 +397,7 @@ table.orderable tbody tr td:hover { table.orderable tbody tr td:first-child { padding-left: 14px; - background-image: url(../img/admin/nav-bg-grabber.gif); + background-image: url(../img/nav-bg-grabber.gif); background-repeat: repeat-y; } @@ -364,7 +427,7 @@ input[type=text], input[type=password], textarea, select, .vTextField { /* FORM BUTTONS */ .button, input[type=submit], input[type=button], .submit-row input { - background: white url(../img/admin/nav-bg.gif) bottom repeat-x; + background: white url(../img/nav-bg.gif) bottom repeat-x; padding: 3px 5px; color: black; border: 1px solid #bbb; @@ -372,31 +435,31 @@ input[type=text], input[type=password], textarea, select, .vTextField { } .button:active, input[type=submit]:active, input[type=button]:active { - background-image: url(../img/admin/nav-bg-reverse.gif); + background-image: url(../img/nav-bg-reverse.gif); background-position: top; } .button[disabled], input[type=submit][disabled], input[type=button][disabled] { - background-image: url(../img/admin/nav-bg.gif); + background-image: url(../img/nav-bg.gif); background-position: bottom; opacity: 0.4; } .button.default, input[type=submit].default, .submit-row input.default { border: 2px solid #5b80b2; - background: #7CA0C7 url(../img/admin/default-bg.gif) bottom repeat-x; + background: #7CA0C7 url(../img/default-bg.gif) bottom repeat-x; font-weight: bold; color: white; float: right; } .button.default:active, input[type=submit].default:active { - background-image: url(../img/admin/default-bg-reverse.gif); + background-image: url(../img/default-bg-reverse.gif); background-position: top; } .button[disabled].default, input[type=submit][disabled].default, input[type=button][disabled].default { - background-image: url(../img/admin/default-bg.gif); + background-image: url(../img/default-bg.gif); background-position: bottom; opacity: 0.4; } @@ -433,7 +496,7 @@ input[type=text], input[type=password], textarea, select, .vTextField { font-size: 11px; text-align: left; font-weight: bold; - background: #7CA0C7 url(../img/admin/default-bg.gif) top left repeat-x; + background: #7CA0C7 url(../img/default-bg.gif) top left repeat-x; color: white; } @@ -455,15 +518,15 @@ ul.messagelist li { margin: 0 0 3px 0; border-bottom: 1px solid #ddd; color: #666; - background: #ffc url(../img/admin/icon_success.gif) 5px .3em no-repeat; + background: #ffc url(../img/icon_success.gif) 5px .3em no-repeat; } ul.messagelist li.warning{ - background-image: url(../img/admin/icon_alert.gif); + background-image: url(../img/icon_alert.gif); } ul.messagelist li.error{ - background-image: url(../img/admin/icon_error.gif); + background-image: url(../img/icon_error.gif); } .errornote { @@ -473,7 +536,7 @@ ul.messagelist li.error{ margin: 0 0 3px 0; border: 1px solid red; color: red; - background: #ffc url(../img/admin/icon_error.gif) 5px .3em no-repeat; + background: #ffc url(../img/icon_error.gif) 5px .3em no-repeat; } ul.errorlist { @@ -488,7 +551,7 @@ ul.errorlist { margin: 0 0 3px 0; border: 1px solid red; color: white; - background: red url(../img/admin/icon_alert.gif) 5px .3em no-repeat; + background: red url(../img/icon_alert.gif) 5px .3em no-repeat; } .errorlist li a { @@ -524,7 +587,7 @@ div.system-message p.system-message-title { padding: 4px 5px 4px 25px; margin: 0; color: red; - background: #ffc url(../img/admin/icon_error.gif) 5px .3em no-repeat; + background: #ffc url(../img/icon_error.gif) 5px .3em no-repeat; } .description { @@ -535,7 +598,7 @@ div.system-message p.system-message-title { /* BREADCRUMBS */ div.breadcrumbs { - background: white url(../img/admin/nav-bg-reverse.gif) 0 -10px repeat-x; + background: white url(../img/nav-bg-reverse.gif) 0 -10px repeat-x; padding: 2px 8px 3px 8px; font-size: 11px; color: #999; @@ -548,17 +611,17 @@ div.breadcrumbs { .addlink { padding-left: 12px; - background: url(../img/admin/icon_addlink.gif) 0 .2em no-repeat; + background: url(../img/icon_addlink.gif) 0 .2em no-repeat; } .changelink { padding-left: 12px; - background: url(../img/admin/icon_changelink.gif) 0 .2em no-repeat; + background: url(../img/icon_changelink.gif) 0 .2em no-repeat; } .deletelink { padding-left: 12px; - background: url(../img/admin/icon_deletelink.gif) 0 .25em no-repeat; + background: url(../img/icon_deletelink.gif) 0 .25em no-repeat; } a.deletelink:link, a.deletelink:visited { @@ -593,14 +656,14 @@ a.deletelink:hover { .object-tools li { display: block; float: left; - background: url(../img/admin/tool-left.gif) 0 0 no-repeat; + background: url(../img/tool-left.gif) 0 0 no-repeat; padding: 0 0 0 8px; margin-left: 2px; height: 16px; } .object-tools li:hover { - background: url(../img/admin/tool-left_over.gif) 0 0 no-repeat; + background: url(../img/tool-left_over.gif) 0 0 no-repeat; } .object-tools a:link, .object-tools a:visited { @@ -609,29 +672,29 @@ a.deletelink:hover { color: white; padding: .1em 14px .1em 8px; height: 14px; - background: #999 url(../img/admin/tool-right.gif) 100% 0 no-repeat; + background: #999 url(../img/tool-right.gif) 100% 0 no-repeat; } .object-tools a:hover, .object-tools li:hover a { - background: #5b80b2 url(../img/admin/tool-right_over.gif) 100% 0 no-repeat; + background: #5b80b2 url(../img/tool-right_over.gif) 100% 0 no-repeat; } .object-tools a.viewsitelink, .object-tools a.golink { - background: #999 url(../img/admin/tooltag-arrowright.gif) top right no-repeat; + background: #999 url(../img/tooltag-arrowright.gif) top right no-repeat; padding-right: 28px; } .object-tools a.viewsitelink:hover, .object-tools a.golink:hover { - background: #5b80b2 url(../img/admin/tooltag-arrowright_over.gif) top right no-repeat; + background: #5b80b2 url(../img/tooltag-arrowright_over.gif) top right no-repeat; } .object-tools a.addlink { - background: #999 url(../img/admin/tooltag-add.gif) top right no-repeat; + background: #999 url(../img/tooltag-add.gif) top right no-repeat; padding-right: 28px; } .object-tools a.addlink:hover { - background: #5b80b2 url(../img/admin/tooltag-add_over.gif) top right no-repeat; + background: #5b80b2 url(../img/tooltag-add_over.gif) top right no-repeat; } /* OBJECT HISTORY */ @@ -766,7 +829,7 @@ table#change-history tbody th { } #content-related .module h2 { - background: #eee url(../img/admin/nav-bg.gif) bottom left repeat-x; + background: #eee url(../img/nav-bg.gif) bottom left repeat-x; color: #666; } diff --git a/lms/static/admin/css/changelists.css b/lms/static/admin/css/changelists.css index 315b8c7a38..3c1a8c16a9 100644 --- a/lms/static/admin/css/changelists.css +++ b/lms/static/admin/css/changelists.css @@ -20,7 +20,7 @@ } .change-list .filtered { - background: white url(../img/admin/changelist-bg.gif) top right repeat-y !important; + background: white url(../img/changelist-bg.gif) top right repeat-y !important; } .change-list .filtered .results, .change-list .filtered .paginator, .filtered #toolbar, .filtered div.xfull { @@ -40,7 +40,7 @@ color: #666; border-top: 1px solid #eee; border-bottom: 1px solid #eee; - background: white url(../img/admin/nav-bg.gif) 0 180% repeat-x; + background: white url(../img/nav-bg.gif) 0 180% repeat-x; overflow: hidden; } @@ -51,6 +51,7 @@ /* CHANGELIST TABLES */ #changelist table thead th { + padding: 0; white-space: nowrap; vertical-align: middle; } @@ -82,7 +83,7 @@ #changelist #toolbar { padding: 3px; border-bottom: 1px solid #ddd; - background: #e1e1e1 url(../img/admin/nav-bg.gif) top left repeat-x; + background: #e1e1e1 url(../img/nav-bg.gif) top left repeat-x; color: #666; } @@ -156,7 +157,7 @@ .change-list ul.toplinks { display: block; - background: white url(../img/admin/nav-bg-reverse.gif) 0 -10px repeat-x; + background: white url(../img/nav-bg-reverse.gif) 0 -10px repeat-x; border-top: 1px solid white; float: left; padding: 0 !important; @@ -165,11 +166,10 @@ } .change-list ul.toplinks li { - float: left; - width: 9em; padding: 3px 6px; font-weight: bold; list-style-type: none; + display: inline-block; } .change-list ul.toplinks .date-back a { @@ -246,7 +246,7 @@ padding: 3px; border-top: 1px solid #fff; border-bottom: 1px solid #ddd; - background: white url(../img/admin/nav-bg-reverse.gif) 0 -10px repeat-x; + background: white url(../img/nav-bg-reverse.gif) 0 -10px repeat-x; } #changelist .actions.selected { diff --git a/lms/static/admin/css/forms.css b/lms/static/admin/css/forms.css index 1cedf24b5b..0ecfca784c 100644 --- a/lms/static/admin/css/forms.css +++ b/lms/static/admin/css/forms.css @@ -140,7 +140,7 @@ fieldset.collapsed h2, fieldset.collapsed { } fieldset.collapsed h2 { - background-image: url(../img/admin/nav-bg.gif); + background-image: url(../img/nav-bg.gif); background-position: bottom left; color: #999; } @@ -161,12 +161,16 @@ fieldset.monospace textarea { .submit-row { padding: 5px 7px; text-align: right; - background: white url(../img/admin/nav-bg.gif) 0 100% repeat-x; + background: white url(../img/nav-bg.gif) 0 100% repeat-x; border: 1px solid #ccc; margin: 5px 0; overflow: hidden; } +body.popup .submit-row { + overflow: auto; +} + .submit-row input { margin: 0 0 0 5px; } @@ -180,7 +184,7 @@ fieldset.monospace textarea { } .submit-row .deletelink { - background: url(../img/admin/icon_deletelink.gif) 0 50% no-repeat; + background: url(../img/icon_deletelink.gif) 0 50% no-repeat; padding-left: 14px; } @@ -247,7 +251,7 @@ fieldset.monospace textarea { color: #666; padding: 3px 5px; font-size: 11px; - background: #e1e1e1 url(../img/admin/nav-bg.gif) top left repeat-x; + background: #e1e1e1 url(../img/nav-bg.gif) top left repeat-x; border-bottom: 1px solid #ddd; } @@ -332,7 +336,7 @@ fieldset.monospace textarea { color: #666; padding: 3px 5px; border-bottom: 1px solid #ddd; - background: #e1e1e1 url(../img/admin/nav-bg.gif) top left repeat-x; + background: #e1e1e1 url(../img/nav-bg.gif) top left repeat-x; } .inline-group .tabular tr.add-row td { @@ -343,7 +347,7 @@ fieldset.monospace textarea { .inline-group ul.tools a.add, .inline-group div.add-row a, .inline-group .tabular tr.add-row td a { - background: url(../img/admin/icon_addlink.gif) 0 50% no-repeat; + background: url(../img/icon_addlink.gif) 0 50% no-repeat; padding-left: 14px; font-size: 11px; outline: 0; /* Remove dotted border around link */ @@ -352,9 +356,3 @@ fieldset.monospace textarea { .empty-form { display: none; } - -/* IE7 specific bug fixes */ - -.submit-row input { - float: right; -} \ No newline at end of file diff --git a/lms/static/admin/css/ie.css b/lms/static/admin/css/ie.css index 5fd1ce364b..fd00f7f204 100644 --- a/lms/static/admin/css/ie.css +++ b/lms/static/admin/css/ie.css @@ -53,5 +53,11 @@ /* IE doesn't know alpha transparency in PNGs */ .inline-deletelink { - background: transparent url(../img/admin/inline-delete-8bit.png) no-repeat; + background: transparent url(../img/inline-delete-8bit.png) no-repeat; +} + +/* IE7 doesn't support inline-block */ +.change-list ul.toplinks li { + zoom: 1; + *display: inline; } \ No newline at end of file diff --git a/lms/static/admin/css/login.css b/lms/static/admin/css/login.css index 8d90d12901..8872ade70b 100644 --- a/lms/static/admin/css/login.css +++ b/lms/static/admin/css/login.css @@ -52,3 +52,6 @@ body.login { padding: 1em 0 0 9.4em; } +.login .password-reset-link { + text-align: center; +} diff --git a/lms/static/admin/css/rtl.css b/lms/static/admin/css/rtl.css index c02241d13d..82d16024e6 100644 --- a/lms/static/admin/css/rtl.css +++ b/lms/static/admin/css/rtl.css @@ -80,15 +80,8 @@ div.breadcrumbs { /* SORTABLE TABLES */ - -table thead th.sorted a { - padding-left: 13px; - padding-right: 0px; -} - -table thead th.ascending a, -table thead th.descending a { - background-position: left; +table thead th.sorted .sortoptions { + float: left; } /* dashboard styles */ @@ -100,12 +93,8 @@ table thead th.descending a { /* changelists styles */ -.change-list ul.toplinks li { - float: right; -} - .change-list .filtered { - background: white url(../img/admin/changelist-bg_rtl.gif) top left repeat-y !important; + background: white url(../img/changelist-bg_rtl.gif) top left repeat-y !important; } .change-list .filtered table { @@ -162,7 +151,7 @@ table thead th.descending a { } .submit-row .deletelink { - background: url(../img/admin/icon_deletelink.gif) 0 50% no-repeat; + background: url(../img/icon_deletelink.gif) 0 50% no-repeat; padding-right: 14px; } @@ -183,6 +172,7 @@ input[type=submit].default, .submit-row input.default { fieldset .field-box { float: right; margin-left: 20px; + margin-right: 0; } .errorlist li { @@ -236,9 +226,20 @@ fieldset .field-box { padding-left: inherit; left: 10px; right: inherit; + float:left; } .inline-related h3 span.delete label { margin-left: inherit; margin-right: 2px; } + +/* IE7 specific bug fixes */ + +div.colM { + position: relative; +} + +.submit-row input { + float: left; +} \ No newline at end of file diff --git a/lms/static/admin/css/widgets.css b/lms/static/admin/css/widgets.css index 26400fac50..0a7012c7b2 100644 --- a/lms/static/admin/css/widgets.css +++ b/lms/static/admin/css/widgets.css @@ -17,12 +17,16 @@ margin-bottom: 5px; } +.selector-chosen select { + border-top: none; +} + .selector-available h2, .selector-chosen h2 { border: 1px solid #ccc; } .selector .selector-available h2 { - background: white url(../img/admin/nav-bg.gif) bottom left repeat-x; + background: white url(../img/nav-bg.gif) bottom left repeat-x; color: #666; } @@ -37,8 +41,10 @@ text-align: left; } -.selector .selector-chosen .selector-filter { - padding: 4px 5px; +.selector .selector-filter label, +.inline-group .aligned .selector .selector-filter label { + width: 16px; + padding: 2px; } .selector .selector-available input { @@ -49,8 +55,8 @@ float: left; width: 22px; height: 50px; - background: url(../img/admin/chooser-bg.gif) top center no-repeat; - margin: 8em 3px 0 3px; + background: url(../img/chooser-bg.gif) top center no-repeat; + margin: 10em 5px 0 5px; padding: 0; } @@ -61,7 +67,7 @@ } .selector select { - margin-bottom: 5px; + margin-bottom: 10px; margin-top: 0; } @@ -74,38 +80,66 @@ } .selector-add { - background: url(../img/admin/selector-add.gif) top center no-repeat; + background: url(../img/selector-icons.gif) 0 -161px no-repeat; + cursor: default; margin-bottom: 2px; } +.active.selector-add { + background: url(../img/selector-icons.gif) 0 -187px no-repeat; + cursor: pointer; +} + .selector-remove { - background: url(../img/admin/selector-remove.gif) top center no-repeat; + background: url(../img/selector-icons.gif) 0 -109px no-repeat; + cursor: default; +} + +.active.selector-remove { + background: url(../img/selector-icons.gif) 0 -135px no-repeat; + cursor: pointer; } a.selector-chooseall, a.selector-clearall { - display: block; - width: 6em; + display: inline-block; text-align: left; margin-left: auto; margin-right: auto; font-weight: bold; color: #666; +} + +a.selector-chooseall { + padding: 3px 18px 3px 0; +} + +a.selector-clearall { padding: 3px 0 3px 18px; } -a.selector-chooseall:hover, a.selector-clearall:hover { +a.active.selector-chooseall:hover, a.active.selector-clearall:hover { color: #036; } a.selector-chooseall { - width: 7em; - background: url(../img/admin/selector-addall.gif) left center no-repeat; + background: url(../img/selector-icons.gif) right -263px no-repeat; + cursor: default; +} + +a.active.selector-chooseall { + background: url(../img/selector-icons.gif) right -289px no-repeat; + cursor: pointer; } a.selector-clearall { - background: url(../img/admin/selector-removeall.gif) left center no-repeat; + background: url(../img/selector-icons.gif) left -211px no-repeat; + cursor: default; } +a.active.selector-clearall { + background: url(../img/selector-icons.gif) left -237px no-repeat; + cursor: pointer; +} /* STACKED SELECTORS */ @@ -135,7 +169,7 @@ a.selector-clearall { height: 22px; width: 50px; margin: 0 0 3px 40%; - background: url(../img/admin/chooser_stacked-bg.gif) top center no-repeat; + background: url(../img/chooser_stacked-bg.gif) top center no-repeat; } .stacked .selector-chooser li { @@ -148,13 +182,24 @@ a.selector-clearall { } .stacked .selector-add { - background-image: url(../img/admin/selector_stacked-add.gif); + background: url(../img/selector-icons.gif) 0 -57px no-repeat; + cursor: default; +} + +.stacked .active.selector-add { + background: url(../img/selector-icons.gif) 0 -83px no-repeat; + cursor: pointer; } .stacked .selector-remove { - background-image: url(../img/admin/selector_stacked-remove.gif); + background: url(../img/selector-icons.gif) 0 -5px no-repeat; + cursor: default; } +.stacked .active.selector-remove { + background: url(../img/selector-icons.gif) 0 -31px no-repeat; + cursor: pointer; +} /* DATE AND TIME */ @@ -231,7 +276,7 @@ span.clearable-file-input label { padding: 0; border-collapse: collapse; background: white; - width: 99%; + width: 100%; } .calendar caption, .calendarbox h2 { @@ -246,7 +291,7 @@ span.clearable-file-input label { color: #666; padding: 2px 3px; text-align: center; - background: #e1e1e1 url(../img/admin/nav-bg.gif) 0 50% repeat-x; + background: #e1e1e1 url(../img/nav-bg.gif) 0 50% repeat-x; border-bottom: 1px solid #ddd; } @@ -314,7 +359,7 @@ span.clearable-file-input label { position: absolute; font-weight: bold; font-size: 12px; - background: #C9DBED url(../img/admin/default-bg.gif) bottom left repeat-x; + background: #C9DBED url(../img/default-bg.gif) bottom left repeat-x; padding: 1px 4px 2px 4px; color: white; } @@ -335,15 +380,19 @@ span.clearable-file-input label { .calendar-cancel { margin: 0 !important; - padding: 0; + padding: 0 !important; font-size: 10px; - background: #e1e1e1 url(../img/admin/nav-bg.gif) 0 50% repeat-x; + background: #e1e1e1 url(../img/nav-bg.gif) 0 50% repeat-x; border-top: 1px solid #ddd; } +.calendar-cancel:hover { + background: #e1e1e1 url(../img/nav-bg-reverse.gif) 0 50% repeat-x; +} + .calendar-cancel a { - padding: 2px; - color: #999; + color: black; + display: block; } ul.timelist, .timelist li { @@ -374,7 +423,7 @@ ul.orderer li { border-width: 0 1px 1px 0; white-space: nowrap; overflow: hidden; - background: #e2e2e2 url(../img/admin/nav-bg-grabber.gif) repeat-y; + background: #e2e2e2 url(../img/nav-bg-grabber.gif) repeat-y; } ul.orderer li:hover { @@ -406,7 +455,7 @@ ul.orderer li.selected { } ul.orderer li.deleted { - background: #bbb url(../img/admin/deleted-overlay.gif); + background: #bbb url(../img/deleted-overlay.gif); } ul.orderer li.deleted a:link, ul.orderer li.deleted a:visited { @@ -414,7 +463,7 @@ ul.orderer li.deleted a:link, ul.orderer li.deleted a:visited { } ul.orderer li.deleted .inline-deletelink { - background-image: url(../img/admin/inline-restore.png); + background-image: url(../img/inline-restore.png); } ul.orderer li.deleted:hover, ul.orderer li.deleted a.selector:hover { @@ -426,7 +475,7 @@ ul.orderer li.deleted:hover, ul.orderer li.deleted a.selector:hover { .inline-deletelink { float: right; text-indent: -9999px; - background: transparent url(../img/admin/inline-delete.png) no-repeat; + background: transparent url(../img/inline-delete.png) no-repeat; width: 15px; height: 15px; border: 0px none; @@ -465,11 +514,11 @@ ul.orderer li.deleted:hover, ul.orderer li.deleted a.selector:hover { } .editinline tr.deleted { - background: #ddd url(../img/admin/deleted-overlay.gif); + background: #ddd url(../img/deleted-overlay.gif); } .editinline tr.deleted .inline-deletelink { - background-image: url(../img/admin/inline-restore.png); + background-image: url(../img/inline-restore.png); } .editinline tr.deleted td:hover { @@ -500,13 +549,13 @@ ul.orderer li.deleted:hover, ul.orderer li.deleted a.selector:hover { .editinline-stacked .inline-splitter { float: left; width: 9px; - background: #f8f8f8 url(../img/admin/inline-splitter-bg.gif) 50% 50% no-repeat; + background: #f8f8f8 url(../img/inline-splitter-bg.gif) 50% 50% no-repeat; border-right: 1px solid #ccc; } .editinline-stacked .controls { clear: both; - background: #e1e1e1 url(../img/admin/nav-bg.gif) top left repeat-x; + background: #e1e1e1 url(../img/nav-bg.gif) top left repeat-x; padding: 3px 4px; font-size: 11px; border-top: 1px solid #ddd; diff --git a/lms/static/admin/img/changelist-bg.gif b/lms/static/admin/img/changelist-bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..7f4699470adc8c021740023dcd4f0a1bd5f50b84 GIT binary patch literal 58 zcmZ?wbhEHbT*$!0(7?d({{8#Acke3xWMKdS9S{MMVPF#E>05dFE&t*vt?bv=6id7ONcO70{{r%8=U|E literal 0 HcmV?d00001 diff --git a/lms/static/admin/img/chooser-bg.gif b/lms/static/admin/img/chooser-bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..30e83c2518b0e5ee5f4bda6ce790b47f6dbdbfbb GIT binary patch literal 199 zcmZ?wbhEHb6l2h5*v!E2@87@o@85s?`0?-Gzu&)q|NQy$j~_oiefsp_!-t2MMY9TZUv9~%Sp!>_)cW&ci3#* zUhC5m*S~nZz=*>R=VoO!-wlwA$Z`-01 q@~q#j3=%veq*@rvq^WHhU}-`1SSm{{H^+^Yi-p`uF$u@bK{c{r&s< z`||Sg^z`)c@$vTd_5c6?A^8LV00000EC2ui05AX-000DmFvuy15jgA3yCGB Oo}Zwd4gw#T5db^5xM#Bf literal 0 HcmV?d00001 diff --git a/lms/static/admin/img/default-bg-reverse.gif b/lms/static/admin/img/default-bg-reverse.gif new file mode 100644 index 0000000000000000000000000000000000000000..0873281e51bdcfd1e7eb5bbfbde3a09c4cbc943e GIT binary patch literal 843 zcmV-R1GM}{Nk%w1VG#fy0OkMyywd5g$>Wc((SfDPyV2;h%;kux&VHiEgQv@Yq{*Sa z+l{W!qQ2X>&*yuf#)zuThN#S(y4aey*L$GHimcC{yxF9{+^)ysgs01&yxO+S=DE=5 zq`=*$!rrpW%Ia#o)Ef<&3V-tHt57%Hx^1)~CYVyVB@=p~tMo;ew{h zv&!VG#o?8+)Qqmrnz+`6sm*|+$&#|ts>I*7&E~4Z;GetNkg(B_veJR3%8#$nw9VzU z&E=W6*PXi9oVwYCsLX|_%&NoRhN#WD(ddt_(zwp%xX$ON!QH9E;Dn~jv&-bS&gP%H z*|yE)hN;YZp~kn*=6s;Xx6kLIz1xql(y__nrNG^btIvL;$&0MdA^8LV00000EC2ui z01*Hm000O7fOifPgAR3s6N!Zm4lp*4BuykFJTOf*l}$X9EG!3~2cDpzoqh=-BB!UR zRtX8Ms!u=zUbD1M1G%=j2p9;zy>Gw17{$G1Xb@%)%w}{DRc2LX%n%O-*9O`T+}qs- z6yY>9I~3y-JAD*?=sPhn3-R$WM@RDTQ%3>JcA0syKJpvRw!9yxMc>2a`&3xzov zx=8UshKv*xrBwWoF@=l|HCC*s;bR3396o&D2#Io}gqKQ&P@xj@r5G_1lt>sdX2ggH z5q<(4L&hf=pb;u$$grh?Ql=T4R*EFeIr5KLGLmcd%i6bbUe36dy_8@~t=1<8vdNG`N! zQKH3#5}!MR)_mbYfB-X2r#`*swCdC*JV5b~Bz9~MxJ{UV0|gEkBL#wo0UoA+5ir4% zYY4HNd5A1o;>^)NJp}VL4YJ!gaiT$Y@80pSX|Q3#jTWc((SfDPyV2;h%;kux&VHiEgQv@Yq{*Sa z+l{W!qQ2X>&*yuf#)zuThN#S(y4aey*L$GHimcC{yxF9{+^)ysgs01&yxO+S=DE=5 zq`=*$!rrpW%Ia#o)Ef<&3V-tHt57%Hx^1)~CYVyVB@=p~tMo;ew{h zv&!VG#o?8+)Qqmrnz+`6sm*|+$&#|ts>I*7&E~4Z;GetNkg(B_veJR3%8#$nw9VzU z&E=W6*PXi9oVwYCsLX|_%&NoRhN#WD(ddt_(zwp%xX$ON!QH9E;Dn~jv&-bS&gP%H z*|yE)hN;YZp~kn*=6s;Xx6kLIz1xql(y__nrNG^btIvL;$&0MdA^8LV00000EC2ui z01*Hm000O7fB=GngoT0x1WZIsh=@c4X^)Hq8yhz_C@7YhmN%6fC~FO)b|)tdr>LlS zYz-PAudpFmS#fh3xFN7$Mg_iMy zEiEN27bWH6=HM3>ML{o4NKx(YFF{dAFGWZyZdf27DgX-9f+e7qGeUGM>CmP_hlM&i z=nx`A;t~!VesHj0A)^I895r&}pnw5`k|<3oSa~uJg9;fkY^eZKW(JxS@T~!jKv(R@CsZ0tXHsK5$_Dsx`$288T9sm2&pO z+7vRWKDg+SBgd5`H-TFR%!C^)o_GDj!gPtK1gc27Dv@$SQ0{~`FJvsmY literal 0 HcmV?d00001 diff --git a/lms/static/admin/img/icon-unknown.gif b/lms/static/admin/img/icon-unknown.gif new file mode 100644 index 0000000000000000000000000000000000000000..cfd2b02ad91b3677dbe59111faaf4f437c362cb8 GIT binary patch literal 130 zcmV-|0Db>QNk%w1VF~~W0J9GO^z`(anwr7E!O_vts;a8Fxw+ur;K|9!=;-Lh#l`#k z`?0aH)z#IOmX?c)i~s-sA^8LW000jFEC2ui015yK000Cp@IAI#TTH&>x=&LlD2fp{ kltU;-pbSpsb&B9v9)J|xHP4tFtdrsVKoW`tBZ&Y2J8`5w82|tP literal 0 HcmV?d00001 diff --git a/lms/static/admin/img/icon-yes.gif b/lms/static/admin/img/icon-yes.gif new file mode 100644 index 0000000000000000000000000000000000000000..73992827403791d6c1a75a079880e41dce7e0214 GIT binary patch literal 299 zcmZ?wbhEHbb?NhTQ$x_deWPc4O)NkN2|oXRf%p{M+wuUw(Z# z`TWGXJ8Mf07p=Or^7yl3mtJ2C+~V)C-fh~&DX}}E_C4PF@Y93ee}B)tGUw-?pC_Il zZ#vO%{oS?y|Nqw=uUUR`+4?){5_iQh&Q{xM6OkFieY2o T4)tf0@^WEj=4)bdWUvMRbX#E6 literal 0 HcmV?d00001 diff --git a/lms/static/admin/img/icon_addlink.gif b/lms/static/admin/img/icon_addlink.gif new file mode 100644 index 0000000000000000000000000000000000000000..ee70e1adba52480cc6aedbee650000c5d55b0088 GIT binary patch literal 119 zcmZ?wbhEHb(s)E@aY^3 F)&O8RB1ZrK literal 0 HcmV?d00001 diff --git a/lms/static/admin/img/icon_alert.gif b/lms/static/admin/img/icon_alert.gif new file mode 100644 index 0000000000000000000000000000000000000000..a1dde2625445b76d041ae02ccfcb83481ca63c5e GIT binary patch literal 145 zcmV;C0B-+BNk%w1VGsZi0J9GO|G@+Q!3O`;RR7pu|IkAJ%Ps%YPXF0v|INcdJ{u&=}=IXLDhr+J%S1nrq(gCL;wIgri4F* literal 0 HcmV?d00001 diff --git a/lms/static/admin/img/icon_calendar.gif b/lms/static/admin/img/icon_calendar.gif new file mode 100644 index 0000000000000000000000000000000000000000..7587b305a4ee702cbed3bee1ae17c78feb85d00b GIT binary patch literal 192 zcmV;x06+gnNk%w1VGsZi0J8u9nVFf2iHY^~_4)bv@bK{4+uQ&D|FN{U?d|Qf&F0D5 z?Wd=w{QUgs>FMX^=l}ozA^8LW000jFEC2ui01yBW000DS@X1N*1UPGamH(iU1QH+` z43ii};vPZqm~L$+una7G@AI)4YnU1cj)Wk=I*&Aa=g_Vl48 zmH)wj0Spv>vM@3*@G|Itcpx(vSX4HgyeYC&>*nrB_bxSQsBGn6*)YRRaLr}Q6>6LJ P$Rx*~-FRR+2ZJ>L#Kbnb literal 0 HcmV?d00001 diff --git a/lms/static/admin/img/icon_clock.gif b/lms/static/admin/img/icon_clock.gif new file mode 100644 index 0000000000000000000000000000000000000000..ff2d57e0a3b6373b7bd9540e688b1b4c71081cb7 GIT binary patch literal 390 zcmV;10eSvMNk%w1VGsZi0M$DH{QUg>{{H#-`S$kq$lLA4+3fD_?(*{T{{H>?`uXqg z@BaV(?CkCH^Yi-p`u6wt#Mtch_4dHk>iGEh^7Hca^z*{j>crRU`1twz{QT_e?DqEc z$J*@b>gvMQ>+|&V$lC14+wAM>>;3)w@9*%!*X#51^1;{Z`}_OH+U@-O`^ehu#MkWU z>FEFe{^{xI#n|ld@$l~N@5kBgv9!0z+wHW?=G)ubr>Cd?|NohpnY8A@0000000000 z00000A^8LW0027xEC2ui01yBW000J~z@2cXD;jmfB(YW_ga{xGQmJF&uGa!=Dy-IU zx$q)@gRrJva4tXt05Uks30VcZ5F=VbfDzy%IyZGW2r3RV4+8@cI5vSg1UL%-4ihvL z4F?pBk1IFOZ1vml&CJGE4FE})gH$(*xI2#8t kA}zwiLpm2FSXaY=R2~vG+}zkoL`Ox%;6gX&=t@BVI|kg>kN^Mx literal 0 HcmV?d00001 diff --git a/lms/static/admin/img/icon_deletelink.gif b/lms/static/admin/img/icon_deletelink.gif new file mode 100644 index 0000000000000000000000000000000000000000..72523e3a3ba1446c8f768c157cea642119a02741 GIT binary patch literal 181 zcmZ?wbhEHbc&kkH2hg{xUB9fxq8%JG(R5 zT3?Eao`!{eDJnj1U~tLY{9|s;X>G0VWo1vp!yowhEs~V{|NlP&4xspxg^__loIwX9 z53-Yi)#yQKi;S#{{sX6 zi;Dh#`0#&e>3>Vh|D2rv=gC*q|>i-WM_<#QV|C1;G zS5*8rF!=rZ_kUyK|3JV%TcG%pg^__lo4aiRnY%vG=3p{kB40{i-Of=+@`~3X;@bK{O@9+Kn{rLF!_xJbl@$pSfP5S!!_4W1n`T6YZ?B3qqPft(K z(9rAa>(gwwA^YilZ@=HrgUS3{FNlEth_IP-BSy@@<=jZ6? z=$e|EaBy(V&CR>JyVcdz;o;$EXlUQx-&9moTU%RKS68&OwCU;T!NJ+t*-}zc&)b92AH zzpJaOZfvlTPVlRhn*D zzYj!ubf8e2}%QyRfsr*SWe%Rb`=>R1ae%6%2~5|TAxeL zzADQysO81>*ZZYCyl6@$BdV$biI?uic&0bzMrFb%Aq1#ZUv-+v+w0VD#)3jAg-{rn zQK{SBuPmhC5$}W{D84q?yXp06=7SUzUxd5@c^_-Jtgg3OcgI0-bjam_F)Z9$Uf=5< z*hz6@lo{ZZu*P|f^TenPFmQjgIBP%6a@>yq0{~})9l-cU)g%A_002ovPDHLkV1oH8 BY;phq literal 0 HcmV?d00001 diff --git a/lms/static/admin/img/icon_success.gif b/lms/static/admin/img/icon_success.gif new file mode 100644 index 0000000000000000000000000000000000000000..5cf90a15aa6731798b025a238fa47a1658510fff GIT binary patch literal 341 zcmZ?wbhEHb6krfwxXJ(m|NsC0@cYBBf4?q$zBut-@A?;OHoRQB_4TGbZ+4yjc=Gy} zYu7$sefa&slkbn8{dih+uDI?}MdP*V#;eu+_qwJ$=-=~p=Y>z_u719puq!NScSPpF zg#4pv1xM2>&lOf*D6TwP`0>{VkG0l*8=OKmdxUNAj@;&(aUeGLNb=vme}Ptmoj^XJ z_>+Z^fkBHw2V?}uPYi5D4pR#}bfiS5bS&9qz$LFSv4l%VM0VNAuq7M$%x`OYevyni z6y)sQCFr(n`AWsDVxcXCnHqNfPZgaKf;1I5H8q8UQ?&$wdD=UoSe-bM`a7e(;ev*DhVUbne`_Q>RWHJ$m%u z!GnAE?%ld|>&A^6SFT*SV8MbJGiFSgGG)Sq2|YbM4Gj%I(@xu~L;ww!E(!7r26Ax# z26Yo|Q=l@=0*}aI1_rJVAk65r#$*OiP`<=9q9iy!t)x7$D3!rCF}Wx|H#H?QQNb;< zD78GlD7#p}Vr#~w3ZT-9o-U3d5>s0PZ;Q1kaJcNw6<2ol{`H?fR&lq@+fNPd=`slo zkNq2-l{wAX{kw31#NjUjI#s<#Uj@rXCa>o{s1qmoLR|UF+{q6*%d3Ul-XEy+RoY#| zkfg@p<7MzuzoD2R^0?fz%GC`Vt9o~eIX#}ba7TVWzqWIsT+0Qozj6zvZ?O^|iOvau45i`%PE+DBAs)9(WdP);)FE4qk(op#PgM^?h(mhZn$bMx7!ED!$ll-yWMuFR9Y9iY1q7x+Tho7W2RcIw$bnR z2Z2D~y5@l64y0TzH$=tFKLOu2^C00_)Ch$_LD)3MqdNl)v!b&k++3HA!8QF=ku#b%{yJ#wK~|XDwD}%Ih)Ns*K9MH z%(HYly{5CB)Ym{qon_8#Hk*fGCw9C2rdkss8}e+bO6J_@bS`v6TrSr|wI)OwBZmQm zHE@-oO(YTz5V;=1&QvJr=y6WMe@$|)b-+D_HXIJ8d%fN;>`aB04(d23;lD2}`^z_f zWD`6<7Ey3_>h*ewj@6o=j&q`$*PTb){4yf-uu`dfren1xsNE;uf~-qQ~+a-GFR@J$@b>Hh94o@B%i?F()B=ob5MjVEX~Af^TCZ zpt}o>$R?)bE~vB3v9|mNm(eM3QreV7{t3JXuf|(;ev*DhVUbne`_qeqV(Ja};L z-o0D5Zr!+XNxJHx&=ckpFCl;kL_$DS7<>#iRWF{)OWfrBD=NDxcD_CsJ zxKsgDy5G~qF+^f&>qJMfW(6J><{J?Kf>R&;&5u&^T)oP_O3;r=6p7) zlfNAI+AzN1yld9iPbOE?zDn^FWNWTzVg8q;tMyQH#xB2CjJMamULv=ffzPT{LG9m{ z3!RZZYz+J_R$O4Tn}6ZyW@b)?Zsy_zb<*cm_zc-z$!)fZ;AeP{VB3kMP1FLBYMl`sP8M=cy-s(-<#^LNPFbS VZ>oP-s}J-FgQu&X%Q~loCIHeD(U1TD literal 0 HcmV?d00001 diff --git a/lms/static/admin/img/inline-restore.png b/lms/static/admin/img/inline-restore.png new file mode 100644 index 0000000000000000000000000000000000000000..efdd92ac39d12c2f84fbd22d05d7b495e2206bf4 GIT binary patch literal 623 zcmV-#0+9WQP)V!KQp&Gv#VQ{rTw<)x~~1Dk?(c~!+vyQpqu`J3b+L~ zR`ZDG!5ruVF7OO4z$y5w^TqAKF*#fWUI*hZ;0T(M%?=EJb>Mf<-hn;vz<0pKoOhsG zlFpOKWZcFGeU*W=oyt4~z9F4M8?n(2flbiMCtYkj4Ls7hVHi$Z+y!QpxfL)doj1_- zgSEON5MRGa0deQ)bh_3T3I#0~42F6BfCG^m^!3}IjXPJgF{Y(F*a1(q;}n-rM^R@F=3jf=JWZqL?XfSLgqn_(8ii* zd0u$rK$hW~oS-1&G0<4f=kxiv+wJDZ_bU1_)5hd6(3oi>ingRCVUgFUx)angnT)37 zKv9fM@WF#BmfOQv#2a57-S&KT*C(G{DQl+NNW9y=`fHnu-v==- Ot=>b+CQo8uum%9*_Ae;_ literal 0 HcmV?d00001 diff --git a/lms/static/admin/img/nav-bg-reverse.gif b/lms/static/admin/img/nav-bg-reverse.gif new file mode 100644 index 0000000000000000000000000000000000000000..f11029f90fc965141b8815a78ac2651759099475 GIT binary patch literal 186 zcmV;r07d^tNk%w1VG#fy0J8u9|NsB^`1t<*{`U6v@$vEd`}^(f?dRv`;^N}{{r&3d z>hA9DU$B!R9e*F0P^XD&Kym`~Lm=e{4X9 z0SG{LF|hV2sP&~}&dXS}F6Z^GaGmodx!1$iy|0P;dtku_cTK7O6OU3(=2%Uiw4%hT z*KOU6HQ%^iR_%ZAF4;$K_VK literal 0 HcmV?d00001 diff --git a/lms/static/admin/img/nav-bg.gif b/lms/static/admin/img/nav-bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..f8402b809dc1efec80db6e466d789f88429a79a8 GIT binary patch literal 273 zcmZ?wbhEHb6l9QRIKsg2{rmT~Z{I$D{`}ReSAYNh{q^hDhYue(@t*9{u_A=gpfpKY#xG_U+rVXV3oq`}hC||i=Q&8(m$()z5YF*CjUEw001<4;4tjrTwH+&%FA_x~E6rskH`CdQ7= zuI>)uzWxal`(>Zw+Pr1!Chi?O LckSMx$Y2cs9wnNk literal 0 HcmV?d00001 diff --git a/lms/static/admin/img/selector-icons.gif b/lms/static/admin/img/selector-icons.gif new file mode 100644 index 0000000000000000000000000000000000000000..8809c4fb9acea53623b8e3b8251b72a245aa17e8 GIT binary patch literal 2771 zcmV;^3M}+$#R@9*pI_UiEW z?CP?Ck95?C|R9>g4S7hI*~?c(b5<>~I>>hs{~^5^I0=I80; z=IGz%@8ag`<>lq%*5<_4=+e^C z#nk1*)a1g{=h4y8!qVf<&(F@z&b-j%ywK&%&CR~h<;={?xXN z&E(0+$+peq$jHdI%ip)m;Iz!+w9MqT%HPMw$F$4hwaenO%j2}k;Izu%vdZJM$=|Zc z;j_rz#Kgq1$KA2V-NVDftj6HN!otD9!KlRGz`(%2zrU)&+P=QNr@`C2yu78s+@-+W zroh{!z}uj}25$81 znTg4wKV*_V0SZ({QZjm6}T8>Lu zxjGjJ)+xulI<9B;qVJnt{R*M#&-Y#bxc995vnxO+na5sZdb#&&u1=qRmR%x-M3#sxVCMpF zM)_t4c82h#EK=5a=bwS9!2+Lmh7dxTW=hHBop%bsr7UTxAq1q7a#@O-V_v!d4{KVP zr4Xc&%0j7s=B=|F-c zK>^HRP9tb=A*~?X*zo{Cb_@eY8{Br=#w+&yb=oDHs5S!M>yn1Bo=p=wh%g8vwPz!3OK2&oU50>;X_7L=3TT*kpXd2@U|| zzzH-UgA6wKNQ2JFZsccxDd4oMPaN%ZBl8p-G`Jj% z!Xz!s6@Vx$Otk~qAx-e$zfEprRTWH%Oow9jPh8 z1m3CnV1VVRVZK`2id^Qo0RTv#I_8(frida+Fa-cpn7{6N>9W&KhwXC5Mh8%;t8RO2 zn#AV20U#K!i1CV{^7`vwfbjhDlL20OW~*Vg8RCjeKKb&83v@RsqKA%(YX!mGJ1TX% z?f(1lGgQMQ!renoAu;r|(vAV(bxFp%-Y;(rJ{gEC?ykUGS|MQ1SAGh$SO z`xWAXPPo7YH&}@5bO=LEFu({nbfIUQ;T~1f0#h!)!a`83KmM4(K z$ic%{Fl7Wlj0F$>$zh=(l4BAgG~y8JPy_OqXA&}4j}D{5KL*8uLCO%IK*sY7t65Ep z1+1dglyQ#%8f1R;yI=m|$Hq3s4+&9X3zc|akPuuV6QpWE3nZ0^OE6#{A&>>DT9v9* z5fW8>+y@dep(X~jU`&~4K`GRv1_m%7Q)=j=Ah~48PF`|LnE(`9w&cl93PFyt7-c0( z$$(6TGL>ynR0ulh%21X~)kfJQsE zvX+74Wih*%%u-+go5?I^I~!WhWFR!36>T3!bDA(#;WVfTL~35F8rHP753YF)Y+@r@ zLCl6WdUP|JNKL9z3lf7sKm!_qhyg+fpax)wp$J6~12EJ;0E4K35;e)e5h$UCg3KTp zUP$W^Brt=tCSwK!Q3NQc0)(;XfGVI+1VOAZ3r4Jf0Du(&D+X(gy*A?y82~H+l#qxkpsX!!5Wy=>p*6(4T*qa3J3^-M79A}f~Wx&T&hA4PFvQ3P}LZ8=m{N+ z!BvF+%s>&;poSt!yVTzL_P4#U0Vc#D4ouhpAqkM0FZQqpUx>pF2{4Eqd=ZA~Vxb9P z@P)bvVgqq7cMn*ozz&!zj^hpl6TZL%CYq3d1nfY)=_QCb(rbhECZGwv$geo$I}J>5 zz`jkGhJg2bUU`UP8arq&7KkekOmJ5o0-i<~?kiw^xt(K0HGWe3p!hdNxXX?bKL8&QBj8J?XD3l~Ic!Z5=ll-6NG+o2uB Zpam_8(T+!#coX3W$0kPo=cNV&06TG~#AN^g literal 0 HcmV?d00001 diff --git a/lms/static/admin/img/selector-search.gif b/lms/static/admin/img/selector-search.gif new file mode 100644 index 0000000000000000000000000000000000000000..6d5f4c74923af2daba13baa484364380fb1614b9 GIT binary patch literal 552 zcmZ?wbhEHb6krfwc*ekR;r}fg8=Jp>|9X0Qe){yu!NI}X+uO&-$I8koH8s`3!otqZ z?(W^YSy@?TW@e{PpT2zg^6J&ABO)T)-Q5!s60Tjl=Ire3>gqaW%9PsL+PQP*Ha9mX zCnrZoN9W|^#K*^f{rYv@ym@clym|8E$=&V_@LPJBVtE(?uxDXW;RaaLxbLLEYd;7Mww%N01*VNRUKY#wgg9n+J znUg0^j*E-y=;*j{51X2rQc_ZG-@bkS{(VPBM~0yT6o0ZXf?TTuB0zD%z~0)x z(A3=0+M*~cF2*k1)@;Hotjo#FYS$;lCc@9cB5K1e*(T4%&$OJ0N1L&YotI^~f{vr% zn$~qnssdI5qW0Tb4Ak_r)E!)0jSnm~~hECZvY5o%BVqvfb0K*)eZU6uP literal 0 HcmV?d00001 diff --git a/lms/static/admin/img/sorting-icons.gif b/lms/static/admin/img/sorting-icons.gif new file mode 100644 index 0000000000000000000000000000000000000000..451aae59874c795763cee9b044bf2c487f15a853 GIT binary patch literal 369 zcmZ?wbhEHb6k}*%IKsg2;>C++&z_w!(hg+Pin}?%lgLZrnIy)1g(XR`svm zGk^a4IdkUBoH=vGj2X$3R|a-2{Qv(y1JOY7CkrDxgCK(rNC(JH2G(~8Dt#%L^DAd!+Lo{0I{PlaWBPvS zl4w&vYiXCFU#`t13Om+FTO9ns`tXZiGLm(GX1Uw7}z rTlY@?-zz3A8IKJL+X^m4Dfq0|aN9iZ(F((o&leUP?N)YTV6X-NKX0r` literal 0 HcmV?d00001 diff --git a/lms/static/admin/img/tool-left.gif b/lms/static/admin/img/tool-left.gif new file mode 100644 index 0000000000000000000000000000000000000000..011490ff3a0100bea63eca7d8a3f821edecf6d3f GIT binary patch literal 197 zcmV;$06PCiNk%w1VF>^d0K@+9+1 z>Fn(6>gwvFqods1+`_`bsi~>N#Kh<4=efDLot>Sks;aTEvEJU^(b3W4lL@fC0syEMTS%hy>Zm!0PcpEpJwG;hh<#5^Y_P4;QTzJF~^?;ZNVo;-~tj z3GxIURaQ?9NK-h~-O_%Ehr|6W>p_W03|&Y3moVBW-4OX{v_eKqd6L;=PDTc60DL-S AivR!s literal 0 HcmV?d00001 diff --git a/lms/static/admin/img/tool-right.gif b/lms/static/admin/img/tool-right.gif new file mode 100644 index 0000000000000000000000000000000000000000..cdc140cc590a56bf45ceef6eaeebf47e4a699ac3 GIT binary patch literal 198 zcmV;%06G6hNk%w1VF>^d0K@+9+1 z>Fn(6>gwvFqods1+`_`bsi~>N#Kh<4=efDLot>Sks;aTEvEJU^(b3W4R literal 0 HcmV?d00001 diff --git a/lms/static/admin/img/tool-right_over.gif b/lms/static/admin/img/tool-right_over.gif new file mode 100644 index 0000000000000000000000000000000000000000..4db977e838dd97ae4f59524a764cf8298f19ccc5 GIT binary patch literal 200 zcmZ?wbhEHblL@fC0syEMTS%hy>Zm!0M`SJhE@w+}Rz8zHMDu50@FVv!<=}o0a$2j_;|E wNJ^Lce8rW`28j}!f$kDtvUrX>)$-C{u;f$x#4um1{ZvBtsg!MMAsh_W0PS95AOHXW literal 0 HcmV?d00001 diff --git a/lms/static/admin/img/tooltag-add.gif b/lms/static/admin/img/tooltag-add.gif new file mode 100644 index 0000000000000000000000000000000000000000..8b53d49ae58dbc324ca7fb318198b187fc124c09 GIT binary patch literal 932 zcmZ?wbhEHb6lM@)_|Cxa`}glZfBv+zw0!^m{n4XG%aU|5d-nPB=MNq{xOeZ~wr$(``}?0g zdp3Xm{Fg6Zwzjt3y?giHzkgr9e*ORde?vn9!zdUHfx#C7ia%Mvj?w{lD0p`BHNuZH8`gv5jGtilW#8Ul-s@(Rm3u`n_%YH1afFWM53xbWyi0reSoZU`=F zW>B;|HRonfOG771<|UO1;}pj!{KgMbG6N3=Of=;-YN#}Nd4NeFEUKo%!I@!YFuRjN h0z*m|qaatng9}?1vhrtKUbNTY0V7A3A`=sXH2_xRgyR4J literal 0 HcmV?d00001 diff --git a/lms/static/admin/img/tooltag-add_over.gif b/lms/static/admin/img/tooltag-add_over.gif new file mode 100644 index 0000000000000000000000000000000000000000..bfc52f10de75998687154585752513a27a02e5c4 GIT binary patch literal 336 zcmZ?wbhEHb6lM@)xXQp_AKmol&!20zAN~IQ+b5;fJ+bBa>km(!zx7XVkIL_<>s=I* z-Fg4<%i9m06*kQ}fA#LqpFhjm=B8Ioc1vhpx_)m~&D4mz?loHv1!s0R#56sA{$|&q zv$L0NTfOzr<~=7olUmZNro(_t( z{<*|8FIl(u()IiQ|Npm*YGNP-DE?#tE7t*$AU`p%OuD z64&(xJYQ3LjTSFY75~+{EbMWTq?Tj+^`lM+ch;D9HZb0eJO28D|1uloD@pFe*-apJ^Hn>L+2d-m?#yFEQU|Ni~^ z`t|Go|Nk2r8W_k0ia%MvT6I7q$WIJxH4gmQ9x7=Hf&p1aV>r7mD6wA%agA(z(Y9-o zn{Z!7=F3()sh$@ap>8_^S=AZ45`|}1urBhDn)0zi%$1R$zCpXHxz#1VpeR78J1{*n zKx$GzLbz~Ucw``(R#|u;i#+q?x}l#o5$^*7-1rs_)vpOO{(vYlW{PgEasf C+m{mn literal 0 HcmV?d00001 diff --git a/lms/static/admin/img/tooltag-arrowright_over.gif b/lms/static/admin/img/tooltag-arrowright_over.gif new file mode 100644 index 0000000000000000000000000000000000000000..7163189604a638ee170f093cd042075a7da48c7a GIT binary patch literal 354 zcmZ?wbhEHb6lM@)xXQp_AKmol&!20zAN~IQ+b5;fJ+bBa>km(!zx7XVkIL_<>s=I* z-Fg4<%i9m06*kQ}fA#LqpFhjm=B8Ioc1vhpx_)m~&D4mz?loHv1!s0R#56sA{$|&q zv$L0NTfOzr<~=7olUmZNro(_t( z{<*|8FIl(u()IiQ|Npm*YGNP-DE?#tE7t*$AU`p%)jRO!c&Mb=iC%tqw1%_mf>OuD z64%5AjkaH#++@37WWH>5lj_LG3QgM?$)(Pyl_<=6_Sxb99hOrSl|Hhr49pEp`qi!N zF8KvT0m8k3>6rnFQvwpgW$MEt13C4|!UI|47?&<{5fc~Cj$Ol`%&8*1!G}pzckjNv NA{t6st9%_9tO2syk|zKF literal 0 HcmV?d00001 diff --git a/lms/static/admin/js/SelectFilter2.js b/lms/static/admin/js/SelectFilter2.js index 92eff2ecfa..0accd080b7 100644 --- a/lms/static/admin/js/SelectFilter2.js +++ b/lms/static/admin/js/SelectFilter2.js @@ -1,11 +1,9 @@ /* SelectFilter2 - Turns a multiple-select box into a filter interface. -Different than SelectFilter because this is coupled to the admin framework. - Requires core.js, SelectBox.js and addevent.js. */ - +(function($) { function findForm(node) { // returns the node of the form containing the given node if (node.tagName.toLowerCase() != 'form') { @@ -14,7 +12,7 @@ function findForm(node) { return node; } -var SelectFilter = { +window.SelectFilter = { init: function(field_id, field_name, is_stacked, admin_media_prefix) { if (field_id.match(/__prefix__/)){ // Don't intialize on empty forms. @@ -44,41 +42,42 @@ var SelectFilter = { //
var selector_available = quickElement('div', selector_div, ''); selector_available.className = 'selector-available'; - quickElement('h2', selector_available, interpolate(gettext('Available %s'), [field_name])); - var filter_p = quickElement('p', selector_available, ''); + var title_available = quickElement('h2', selector_available, interpolate(gettext('Available %s') + ' ', [field_name])); + quickElement('img', title_available, '', 'src', admin_media_prefix + 'img/icon-unknown.gif', 'width', '10', 'height', '10', 'class', 'help help-tooltip', 'title', interpolate(gettext('This is the list of available %s. You may choose some by selecting them in the box below and then clicking the "Choose" arrow between the two boxes.'), [field_name])); + + var filter_p = quickElement('p', selector_available, '', 'id', field_id + '_filter'); filter_p.className = 'selector-filter'; - var search_filter_label = quickElement('label', filter_p, '', 'for', field_id + "_input", 'style', 'width:16px;padding:2px'); + var search_filter_label = quickElement('label', filter_p, '', 'for', field_id + "_input"); - var search_selector_img = quickElement('img', search_filter_label, '', 'src', admin_media_prefix + 'img/admin/selector-search.gif'); - search_selector_img.alt = gettext("Filter"); + var search_selector_img = quickElement('img', search_filter_label, '', 'src', admin_media_prefix + 'img/selector-search.gif', 'class', 'help-tooltip', 'alt', '', 'title', interpolate(gettext("Type into this box to filter down the list of available %s."), [field_name])); filter_p.appendChild(document.createTextNode(' ')); - var filter_input = quickElement('input', filter_p, '', 'type', 'text'); + var filter_input = quickElement('input', filter_p, '', 'type', 'text', 'placeholder', gettext("Filter")); filter_input.id = field_id + '_input'; + selector_available.appendChild(from_box); - var choose_all = quickElement('a', selector_available, gettext('Choose all'), 'href', 'javascript: (function(){ SelectBox.move_all("' + field_id + '_from", "' + field_id + '_to"); })()'); + var choose_all = quickElement('a', selector_available, gettext('Choose all'), 'title', interpolate(gettext('Click to choose all %s at once.'), [field_name]), 'href', 'javascript: (function(){ SelectBox.move_all("' + field_id + '_from", "' + field_id + '_to"); SelectFilter.refresh_icons("' + field_id + '");})()', 'id', field_id + '_add_all_link'); choose_all.className = 'selector-chooseall'; //
    var selector_chooser = quickElement('ul', selector_div, ''); selector_chooser.className = 'selector-chooser'; - var add_link = quickElement('a', quickElement('li', selector_chooser, ''), gettext('Add'), 'href', 'javascript: (function(){ SelectBox.move("' + field_id + '_from","' + field_id + '_to");})()'); + var add_link = quickElement('a', quickElement('li', selector_chooser, ''), gettext('Choose'), 'title', gettext('Choose'), 'href', 'javascript: (function(){ SelectBox.move("' + field_id + '_from","' + field_id + '_to"); SelectFilter.refresh_icons("' + field_id + '");})()', 'id', field_id + '_add_link'); add_link.className = 'selector-add'; - var remove_link = quickElement('a', quickElement('li', selector_chooser, ''), gettext('Remove'), 'href', 'javascript: (function(){ SelectBox.move("' + field_id + '_to","' + field_id + '_from");})()'); + var remove_link = quickElement('a', quickElement('li', selector_chooser, ''), gettext('Remove'), 'title', gettext('Remove'), 'href', 'javascript: (function(){ SelectBox.move("' + field_id + '_to","' + field_id + '_from"); SelectFilter.refresh_icons("' + field_id + '");})()', 'id', field_id + '_remove_link'); remove_link.className = 'selector-remove'; //
    var selector_chosen = quickElement('div', selector_div, ''); selector_chosen.className = 'selector-chosen'; - quickElement('h2', selector_chosen, interpolate(gettext('Chosen %s'), [field_name])); - var selector_filter = quickElement('p', selector_chosen, gettext('Select your choice(s) and click ')); - selector_filter.className = 'selector-filter'; - quickElement('img', selector_filter, '', 'src', admin_media_prefix + (is_stacked ? 'img/admin/selector_stacked-add.gif':'img/admin/selector-add.gif'), 'alt', 'Add'); + var title_chosen = quickElement('h2', selector_chosen, interpolate(gettext('Chosen %s') + ' ', [field_name])); + quickElement('img', title_chosen, '', 'src', admin_media_prefix + 'img/icon-unknown.gif', 'width', '10', 'height', '10', 'class', 'help help-tooltip', 'title', interpolate(gettext('This is the list of chosen %s. You may remove some by selecting them in the box below and then clicking the "Remove" arrow between the two boxes.'), [field_name])); + var to_box = quickElement('select', selector_chosen, '', 'id', field_id + '_to', 'multiple', 'multiple', 'size', from_box.size, 'name', from_box.getAttribute('name')); to_box.className = 'filtered'; - var clear_all = quickElement('a', selector_chosen, gettext('Clear all'), 'href', 'javascript: (function() { SelectBox.move_all("' + field_id + '_to", "' + field_id + '_from");})()'); + var clear_all = quickElement('a', selector_chosen, gettext('Remove all'), 'title', interpolate(gettext('Click to remove all chosen %s at once.'), [field_name]), 'href', 'javascript: (function() { SelectBox.move_all("' + field_id + '_to", "' + field_id + '_from"); SelectFilter.refresh_icons("' + field_id + '");})()', 'id', field_id + '_remove_all_link'); clear_all.className = 'selector-clearall'; from_box.setAttribute('name', from_box.getAttribute('name') + '_old'); @@ -86,16 +85,46 @@ var SelectFilter = { // Set up the JavaScript event handlers for the select box filter interface addEvent(filter_input, 'keyup', function(e) { SelectFilter.filter_key_up(e, field_id); }); addEvent(filter_input, 'keydown', function(e) { SelectFilter.filter_key_down(e, field_id); }); - addEvent(from_box, 'dblclick', function() { SelectBox.move(field_id + '_from', field_id + '_to'); }); - addEvent(to_box, 'dblclick', function() { SelectBox.move(field_id + '_to', field_id + '_from'); }); + addEvent(from_box, 'change', function(e) { SelectFilter.refresh_icons(field_id) }); + addEvent(to_box, 'change', function(e) { SelectFilter.refresh_icons(field_id) }); + addEvent(from_box, 'dblclick', function() { SelectBox.move(field_id + '_from', field_id + '_to'); SelectFilter.refresh_icons(field_id); }); + addEvent(to_box, 'dblclick', function() { SelectBox.move(field_id + '_to', field_id + '_from'); SelectFilter.refresh_icons(field_id); }); addEvent(findForm(from_box), 'submit', function() { SelectBox.select_all(field_id + '_to'); }); SelectBox.init(field_id + '_from'); SelectBox.init(field_id + '_to'); // Move selected from_box options to to_box SelectBox.move(field_id + '_from', field_id + '_to'); + + if (!is_stacked) { + // In horizontal mode, give the same height to the two boxes. + var j_from_box = $(from_box); + var j_to_box = $(to_box); + var resize_filters = function() { j_to_box.height($(filter_p).outerHeight() + j_from_box.outerHeight()); } + if (j_from_box.outerHeight() > 0) { + resize_filters(); // This fieldset is already open. Resize now. + } else { + // This fieldset is probably collapsed. Wait for its 'show' event. + j_to_box.closest('fieldset').one('show.fieldset', resize_filters); + } + } + + // Initial icon refresh + SelectFilter.refresh_icons(field_id); + }, + refresh_icons: function(field_id) { + var from = $('#' + field_id + '_from'); + var to = $('#' + field_id + '_to'); + var is_from_selected = from.find('option:selected').length > 0; + var is_to_selected = to.find('option:selected').length > 0; + // Active if at least one item is selected + $('#' + field_id + '_add_link').toggleClass('active', is_from_selected); + $('#' + field_id + '_remove_link').toggleClass('active', is_to_selected); + // Active if the corresponding box isn't empty + $('#' + field_id + '_add_all_link').toggleClass('active', from.find('option').length > 0); + $('#' + field_id + '_remove_all_link').toggleClass('active', to.find('option').length > 0); }, filter_key_up: function(event, field_id) { - from = document.getElementById(field_id + '_from'); + var from = document.getElementById(field_id + '_from'); // don't submit form if user pressed Enter if ((event.which && event.which == 13) || (event.keyCode && event.keyCode == 13)) { from.selectedIndex = 0; @@ -109,7 +138,7 @@ var SelectFilter = { return true; }, filter_key_down: function(event, field_id) { - from = document.getElementById(field_id + '_from'); + var from = document.getElementById(field_id + '_from'); // right arrow -- move across if ((event.which && event.which == 39) || (event.keyCode && event.keyCode == 39)) { var old_index = from.selectedIndex; @@ -128,3 +157,5 @@ var SelectFilter = { return true; } } + +})(django.jQuery); diff --git a/lms/static/admin/js/actions.min.js b/lms/static/admin/js/actions.min.js index 21f00cdab9..c4a01e4f6e 100644 --- a/lms/static/admin/js/actions.min.js +++ b/lms/static/admin/js/actions.min.js @@ -1,7 +1,7 @@ -(function(a){a.fn.actions=function(h){var b=a.extend({},a.fn.actions.defaults,h),e=a(this),f=false;checker=function(c){c?showQuestion():reset();a(e).attr("checked",c).parent().parent().toggleClass(b.selectedClass,c)};updateCounter=function(){var c=a(e).filter(":checked").length;a(b.counterContainer).html(interpolate(ngettext("%(sel)s of %(cnt)s selected","%(sel)s of %(cnt)s selected",c),{sel:c,cnt:_actions_icnt},true));a(b.allToggle).attr("checked",function(){if(c==e.length){value=true;showQuestion()}else{value= -false;clearAcross()}return value})};showQuestion=function(){a(b.acrossClears).hide();a(b.acrossQuestions).show();a(b.allContainer).hide()};showClear=function(){a(b.acrossClears).show();a(b.acrossQuestions).hide();a(b.actionContainer).toggleClass(b.selectedClass);a(b.allContainer).show();a(b.counterContainer).hide()};reset=function(){a(b.acrossClears).hide();a(b.acrossQuestions).hide();a(b.allContainer).hide();a(b.counterContainer).show()};clearAcross=function(){reset();a(b.acrossInput).val(0);a(b.actionContainer).removeClass(b.selectedClass)}; -a(b.counterContainer).show();a(this).filter(":checked").each(function(){a(this).parent().parent().toggleClass(b.selectedClass);updateCounter();a(b.acrossInput).val()==1&&showClear()});a(b.allToggle).show().click(function(){checker(a(this).attr("checked"));updateCounter()});a("div.actions span.question a").click(function(c){c.preventDefault();a(b.acrossInput).val(1);showClear()});a("div.actions span.clear a").click(function(c){c.preventDefault();a(b.allToggle).attr("checked",false);clearAcross();checker(0); -updateCounter()});lastChecked=null;a(e).click(function(c){if(!c)c=window.event;var d=c.target?c.target:c.srcElement;if(lastChecked&&a.data(lastChecked)!=a.data(d)&&c.shiftKey==true){var g=false;a(lastChecked).attr("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked);a(e).each(function(){if(a.data(this)==a.data(lastChecked)||a.data(this)==a.data(d))g=g?false:true;g&&a(this).attr("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked)})}a(d).parent().parent().toggleClass(b.selectedClass, -d.checked);lastChecked=d;updateCounter()});a("form#changelist-form table#result_list tr").find("td:gt(0) :input").change(function(){f=true});a('form#changelist-form button[name="index"]').click(function(){if(f)return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."))});a('form#changelist-form input[name="_save"]').click(function(){var c=false;a("div.actions select option:selected").each(function(){if(a(this).val())c= -true});if(c)return f?confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action.")):confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button."))})};a.fn.actions.defaults={actionContainer:"div.actions",counterContainer:"span.action-counter",allContainer:"div.actions span.all",acrossInput:"div.actions input.select-across", +(function(a){a.fn.actions=function(g){var b=a.extend({},a.fn.actions.defaults,g),f=a(this),e=!1;checker=function(c){c?showQuestion():reset();a(f).attr("checked",c).parent().parent().toggleClass(b.selectedClass,c)};updateCounter=function(){var c=a(f).filter(":checked").length;a(b.counterContainer).html(interpolate(ngettext("%(sel)s of %(cnt)s selected","%(sel)s of %(cnt)s selected",c),{sel:c,cnt:_actions_icnt},!0));a(b.allToggle).attr("checked",function(){c==f.length?(value=!0,showQuestion()):(value= +!1,clearAcross());return value})};showQuestion=function(){a(b.acrossClears).hide();a(b.acrossQuestions).show();a(b.allContainer).hide()};showClear=function(){a(b.acrossClears).show();a(b.acrossQuestions).hide();a(b.actionContainer).toggleClass(b.selectedClass);a(b.allContainer).show();a(b.counterContainer).hide()};reset=function(){a(b.acrossClears).hide();a(b.acrossQuestions).hide();a(b.allContainer).hide();a(b.counterContainer).show()};clearAcross=function(){reset();a(b.acrossInput).val(0);a(b.actionContainer).removeClass(b.selectedClass)}; +a(b.counterContainer).show();a(this).filter(":checked").each(function(){a(this).parent().parent().toggleClass(b.selectedClass);updateCounter();1==a(b.acrossInput).val()&&showClear()});a(b.allToggle).show().click(function(){checker(a(this).attr("checked"));updateCounter()});a("div.actions span.question a").click(function(c){c.preventDefault();a(b.acrossInput).val(1);showClear()});a("div.actions span.clear a").click(function(c){c.preventDefault();a(b.allToggle).attr("checked",!1);clearAcross();checker(0); +updateCounter()});lastChecked=null;a(f).click(function(c){if(!c)c=window.event;var d=c.target?c.target:c.srcElement;if(lastChecked&&a.data(lastChecked)!=a.data(d)&&!0==c.shiftKey){var e=!1;a(lastChecked).attr("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked);a(f).each(function(){if(a.data(this)==a.data(lastChecked)||a.data(this)==a.data(d))e=e?!1:!0;e&&a(this).attr("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked)})}a(d).parent().parent().toggleClass(b.selectedClass, +d.checked);lastChecked=d;updateCounter()});a("form#changelist-form table#result_list tr").find("td:gt(0) :input").change(function(){e=!0});a('form#changelist-form button[name="index"]').click(function(){if(e)return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."))});a('form#changelist-form input[name="_save"]').click(function(){var b=!1;a("div.actions select option:selected").each(function(){a(this).val()&&(b=!0)}); +if(b)return e?confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action.")):confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button."))})};a.fn.actions.defaults={actionContainer:"div.actions",counterContainer:"span.action-counter",allContainer:"div.actions span.all",acrossInput:"div.actions input.select-across", acrossQuestions:"div.actions span.question",acrossClears:"div.actions span.clear",allToggle:"#action-toggle",selectedClass:"selected"}})(django.jQuery); diff --git a/lms/static/admin/js/admin/DateTimeShortcuts.js b/lms/static/admin/js/admin/DateTimeShortcuts.js index a4293b305b..3ecc06f098 100644 --- a/lms/static/admin/js/admin/DateTimeShortcuts.js +++ b/lms/static/admin/js/admin/DateTimeShortcuts.js @@ -50,7 +50,7 @@ var DateTimeShortcuts = { var clock_link = document.createElement('a'); clock_link.setAttribute('href', 'javascript:DateTimeShortcuts.openClock(' + num + ');'); clock_link.id = DateTimeShortcuts.clockLinkName + num; - quickElement('img', clock_link, '', 'src', DateTimeShortcuts.admin_media_prefix + 'img/admin/icon_clock.gif', 'alt', gettext('Clock')); + quickElement('img', clock_link, '', 'src', DateTimeShortcuts.admin_media_prefix + 'img/icon_clock.gif', 'alt', gettext('Clock')); shortcuts_span.appendChild(document.createTextNode('\240')); shortcuts_span.appendChild(now_link); shortcuts_span.appendChild(document.createTextNode('\240|\240')); @@ -79,17 +79,24 @@ var DateTimeShortcuts = { addEvent(clock_box, 'click', DateTimeShortcuts.cancelEventPropagation); quickElement('h2', clock_box, gettext('Choose a time')); - time_list = quickElement('ul', clock_box, ''); + var time_list = quickElement('ul', clock_box, ''); time_list.className = 'timelist'; - time_format = get_format('TIME_INPUT_FORMATS')[0]; + var time_format = get_format('TIME_INPUT_FORMATS')[0]; quickElement("a", quickElement("li", time_list, ""), gettext("Now"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date().strftime('" + time_format + "'));"); quickElement("a", quickElement("li", time_list, ""), gettext("Midnight"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date(1970,1,1,0,0,0,0).strftime('" + time_format + "'));"); quickElement("a", quickElement("li", time_list, ""), gettext("6 a.m."), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date(1970,1,1,6,0,0,0).strftime('" + time_format + "'));"); quickElement("a", quickElement("li", time_list, ""), gettext("Noon"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date(1970,1,1,12,0,0,0).strftime('" + time_format + "'));"); - cancel_p = quickElement('p', clock_box, ''); + var cancel_p = quickElement('p', clock_box, ''); cancel_p.className = 'calendar-cancel'; quickElement('a', cancel_p, gettext('Cancel'), 'href', 'javascript:DateTimeShortcuts.dismissClock(' + num + ');'); + django.jQuery(document).bind('keyup', function(event) { + if (event.which == 27) { + // ESC key closes popup + DateTimeShortcuts.dismissClock(num); + event.preventDefault(); + } + }); }, openClock: function(num) { var clock_box = document.getElementById(DateTimeShortcuts.clockDivName+num) @@ -138,7 +145,7 @@ var DateTimeShortcuts = { var cal_link = document.createElement('a'); cal_link.setAttribute('href', 'javascript:DateTimeShortcuts.openCalendar(' + num + ');'); cal_link.id = DateTimeShortcuts.calendarLinkName + num; - quickElement('img', cal_link, '', 'src', DateTimeShortcuts.admin_media_prefix + 'img/admin/icon_calendar.gif', 'alt', gettext('Calendar')); + quickElement('img', cal_link, '', 'src', DateTimeShortcuts.admin_media_prefix + 'img/icon_calendar.gif', 'alt', gettext('Calendar')); shortcuts_span.appendChild(document.createTextNode('\240')); shortcuts_span.appendChild(today_link); shortcuts_span.appendChild(document.createTextNode('\240|\240')); @@ -195,6 +202,13 @@ var DateTimeShortcuts = { var cancel_p = quickElement('p', cal_box, ''); cancel_p.className = 'calendar-cancel'; quickElement('a', cancel_p, gettext('Cancel'), 'href', 'javascript:DateTimeShortcuts.dismissCalendar(' + num + ');'); + django.jQuery(document).bind('keyup', function(event) { + if (event.which == 27) { + // ESC key closes popup + DateTimeShortcuts.dismissCalendar(num); + event.preventDefault(); + } + }); }, openCalendar: function(num) { var cal_box = document.getElementById(DateTimeShortcuts.calendarDivName1+num) diff --git a/lms/static/admin/js/admin/RelatedObjectLookups.js b/lms/static/admin/js/admin/RelatedObjectLookups.js index 1bc78f89b1..ce54fa5083 100644 --- a/lms/static/admin/js/admin/RelatedObjectLookups.js +++ b/lms/static/admin/js/admin/RelatedObjectLookups.js @@ -74,11 +74,12 @@ function dismissAddAnotherPopup(win, newId, newRepr) { var name = windowname_to_id(win.name); var elem = document.getElementById(name); if (elem) { - if (elem.nodeName == 'SELECT') { + var elemName = elem.nodeName.toUpperCase(); + if (elemName == 'SELECT') { var o = new Option(newRepr, newId); elem.options[elem.options.length] = o; o.selected = true; - } else if (elem.nodeName == 'INPUT') { + } else if (elemName == 'INPUT') { if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) { elem.value += ',' + newId; } else { diff --git a/lms/static/admin/js/admin/ordering.js b/lms/static/admin/js/admin/ordering.js index 53c42f3609..595be4d62b 100644 --- a/lms/static/admin/js/admin/ordering.js +++ b/lms/static/admin/js/admin/ordering.js @@ -11,7 +11,7 @@ function reorder_init() { setOrder(input.value.split(',')); input.disabled = true; draw(); - // Now initialise the dragging behaviour + // Now initialize the dragging behavior var limit = (lis.length - 1) * height; for (var i = 0; i < lis.length; i++) { var li = lis[i]; diff --git a/lms/static/admin/js/collapse.js b/lms/static/admin/js/collapse.js index 0a1e2d8893..889e1a5dfc 100644 --- a/lms/static/admin/js/collapse.js +++ b/lms/static/admin/js/collapse.js @@ -3,9 +3,8 @@ // Add anchor tag for Show/Hide link $("fieldset.collapse").each(function(i, elem) { // Don't hide if fields in this fieldset have errors - if ( $(elem).find("div.errors").length == 0 ) { - $(elem).addClass("collapsed"); - $(elem).find("h2").first().append(' (' + gettext("Show") + ')'); } @@ -13,13 +12,11 @@ // Add toggle to anchor tag $("fieldset.collapse a.collapse-toggle").toggle( function() { // Show - $(this).text(gettext("Hide")); - $(this).closest("fieldset").removeClass("collapsed"); + $(this).text(gettext("Hide")).closest("fieldset").removeClass("collapsed").trigger("show.fieldset", [$(this).attr("id")]); return false; }, function() { // Hide - $(this).text(gettext("Show")); - $(this).closest("fieldset").addClass("collapsed"); + $(this).text(gettext("Show")).closest("fieldset").addClass("collapsed").trigger("hide.fieldset", [$(this).attr("id")]); return false; } ); diff --git a/lms/static/admin/js/collapse.min.js b/lms/static/admin/js/collapse.min.js index 428984ee01..5e41b3c86c 100644 --- a/lms/static/admin/js/collapse.min.js +++ b/lms/static/admin/js/collapse.min.js @@ -1,2 +1,2 @@ -(function(a){a(document).ready(function(){a("fieldset.collapse").each(function(c,b){if(a(b).find("div.errors").length==0){a(b).addClass("collapsed");a(b).find("h2").first().append(' ('+gettext("Show")+")")}});a("fieldset.collapse a.collapse-toggle").toggle(function(){a(this).text(gettext("Hide"));a(this).closest("fieldset").removeClass("collapsed");return false},function(){a(this).text(gettext("Show"));a(this).closest("fieldset").addClass("collapsed"); -return false})})})(django.jQuery); +(function(a){a(document).ready(function(){a("fieldset.collapse").each(function(c,b){0==a(b).find("div.errors").length&&a(b).addClass("collapsed").find("h2").first().append(' ('+gettext("Show")+")")});a("fieldset.collapse a.collapse-toggle").toggle(function(){a(this).text(gettext("Hide")).closest("fieldset").removeClass("collapsed").trigger("show.fieldset",[a(this).attr("id")]);return!1},function(){a(this).text(gettext("Show")).closest("fieldset").addClass("collapsed").trigger("hide.fieldset", +[a(this).attr("id")]);return!1})})})(django.jQuery); diff --git a/lms/static/admin/js/core.js b/lms/static/admin/js/core.js index 3ca8ad0f9a..ab776509ba 100644 --- a/lms/static/admin/js/core.js +++ b/lms/static/admin/js/core.js @@ -108,12 +108,6 @@ function findPosY(obj) { //----------------------------------------------------------------------------- // Date object extensions // ---------------------------------------------------------------------------- -Date.prototype.getCorrectYear = function() { - // Date.getYear() is unreliable -- - // see http://www.quirksmode.org/js/introdate.html#year - var y = this.getYear() % 100; - return (y < 38) ? y + 2000 : y + 1900; -} Date.prototype.getTwelveHours = function() { hours = this.getHours(); @@ -149,10 +143,6 @@ Date.prototype.getTwoDigitSecond = function() { return (this.getSeconds() < 10) ? '0' + this.getSeconds() : this.getSeconds(); } -Date.prototype.getISODate = function() { - return this.getCorrectYear() + '-' + this.getTwoDigitMonth() + '-' + this.getTwoDigitDate(); -} - Date.prototype.getHourMinute = function() { return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute(); } diff --git a/lms/static/admin/js/inlines.min.js b/lms/static/admin/js/inlines.min.js index e8152ea357..5631cd5cf2 100644 --- a/lms/static/admin/js/inlines.min.js +++ b/lms/static/admin/js/inlines.min.js @@ -1,5 +1,5 @@ -(function(b){b.fn.formset=function(g){var a=b.extend({},b.fn.formset.defaults,g),k=function(c,f,d){var e=new RegExp("("+f+"-(\\d+|__prefix__))");f=f+"-"+d;b(c).attr("for")&&b(c).attr("for",b(c).attr("for").replace(e,f));if(c.id)c.id=c.id.replace(e,f);if(c.name)c.name=c.name.replace(e,f)};g=b("#id_"+a.prefix+"-TOTAL_FORMS").attr("autocomplete","off");var l=parseInt(g.val()),h=b("#id_"+a.prefix+"-MAX_NUM_FORMS").attr("autocomplete","off");g=h.val()==""||h.val()-g.val()>0;b(this).each(function(){b(this).not("."+ -a.emptyCssClass).addClass(a.formCssClass)});if(b(this).length&&g){var j;if(b(this).attr("tagName")=="TR"){g=this.eq(0).children().length;b(this).parent().append(''+a.addText+"");j=b(this).parent().find("tr:last a")}else{b(this).filter(":last").after('");j=b(this).filter(":last").next().find("a")}j.click(function(){var c=b("#id_"+ -a.prefix+"-TOTAL_FORMS"),f=b("#"+a.prefix+"-empty"),d=f.clone(true);d.removeClass(a.emptyCssClass).addClass(a.formCssClass).attr("id",a.prefix+"-"+l);if(d.is("tr"))d.children(":last").append('");else d.is("ul")||d.is("ol")?d.append('
  • '+a.deleteText+"
  • "):d.children(":first").append(''+ -a.deleteText+"");d.find("*").each(function(){k(this,a.prefix,c.val())});d.insertBefore(b(f));b(c).val(parseInt(c.val())+1);l+=1;h.val()!=""&&h.val()-c.val()<=0&&j.parent().hide();d.find("a."+a.deleteCssClass).click(function(){var e=b(this).parents("."+a.formCssClass);e.remove();l-=1;a.removed&&a.removed(e);e=b("."+a.formCssClass);b("#id_"+a.prefix+"-TOTAL_FORMS").val(e.length);if(h.val()==""||h.val()-e.length>0)j.parent().show();for(var i=0,m=e.length;i'+a.addText+""),h=b(this).parent().find("tr:last a")):(b(this).filter(":last").after('"),h=b(this).filter(":last").next().find("a"));h.click(function(){var c=b("#id_"+a.prefix+ +"-TOTAL_FORMS"),e=b("#"+a.prefix+"-empty"),d=e.clone(!0);d.removeClass(a.emptyCssClass).addClass(a.formCssClass).attr("id",a.prefix+"-"+g);d.is("tr")?d.children(":last").append('"):d.is("ul")||d.is("ol")?d.append('
  • '+a.deleteText+"
  • "):d.children(":first").append(''+a.deleteText+ +"");d.find("*").each(function(){j(this,a.prefix,c.val())});d.insertBefore(b(e));b(c).val(parseInt(c.val())+1);g+=1;""!=f.val()&&0>=f.val()-c.val()&&h.parent().hide();d.find("a."+a.deleteCssClass).click(function(){var c=b(this).parents("."+a.formCssClass);c.remove();g-=1;a.removed&&a.removed(c);c=b("."+a.formCssClass);b("#id_"+a.prefix+"-TOTAL_FORMS").val(c.length);(""==f.val()||00&&e.push(a(f).val())});b.val(URLify(e.join(" "),g))}};a(d.join(",")).keyup(c).change(c).focus(c)})}})(django.jQuery); +(function(a){a.fn.prepopulate=function(d,e){return this.each(function(){var b=a(this);b.data("_changed",!1);b.change(function(){b.data("_changed",!0)});var c=function(){if(!0!=b.data("_changed")){var c=[];a.each(d,function(b,d){0 Date: Tue, 7 Aug 2012 19:39:57 -0400 Subject: [PATCH 10/21] replace_static_urls should only be run once (currently twice, eg if html is in a veritical) --- common/djangoapps/xmodule_modifiers.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/common/djangoapps/xmodule_modifiers.py b/common/djangoapps/xmodule_modifiers.py index 6cbf334afc..5dac093a66 100644 --- a/common/djangoapps/xmodule_modifiers.py +++ b/common/djangoapps/xmodule_modifiers.py @@ -43,6 +43,8 @@ def replace_static_urls(get_html, prefix, module): @wraps(get_html) def _get_html(): + if type(module) in [SequenceModule, VerticalModule]: # TODO: make this more general, eg use an XModule attribute instead + return get_html() return replace_urls(get_html(), staticfiles_prefix=prefix) return _get_html From f556e3f7d96dc61972ef3c35344f4a257462749d Mon Sep 17 00:00:00 2001 From: ichuang Date: Fri, 10 Aug 2012 10:35:08 -0400 Subject: [PATCH 11/21] revert double-mangling patch in xmodule_modifiers; cale fixed in replace_urls --- common/djangoapps/xmodule_modifiers.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/common/djangoapps/xmodule_modifiers.py b/common/djangoapps/xmodule_modifiers.py index 5dac093a66..6cbf334afc 100644 --- a/common/djangoapps/xmodule_modifiers.py +++ b/common/djangoapps/xmodule_modifiers.py @@ -43,8 +43,6 @@ def replace_static_urls(get_html, prefix, module): @wraps(get_html) def _get_html(): - if type(module) in [SequenceModule, VerticalModule]: # TODO: make this more general, eg use an XModule attribute instead - return get_html() return replace_urls(get_html(), staticfiles_prefix=prefix) return _get_html From b159eb48256df269cb3629fca92f87aed094886e Mon Sep 17 00:00:00 2001 From: ichuang Date: Fri, 10 Aug 2012 15:57:41 -0400 Subject: [PATCH 12/21] add feature flag to disable login button (for systems which autologin) --- lms/envs/common.py | 2 ++ lms/envs/dev_ike.py | 5 +++++ lms/templates/navigation.html | 4 ++++ 3 files changed, 11 insertions(+) diff --git a/lms/envs/common.py b/lms/envs/common.py index 487e2efe48..9289517be7 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -55,6 +55,8 @@ MITX_FEATURES = { 'ENABLE_SQL_TRACKING_LOGS': False, 'ENABLE_LMS_MIGRATION': False, + 'DISABLE_LOGIN_BUTTON': False, # used in systems where login is automatic, eg MIT SSL + # extrernal access methods 'ACCESS_REQUIRE_STAFF_FOR_COURSE': False, 'AUTH_USE_OPENID': False, diff --git a/lms/envs/dev_ike.py b/lms/envs/dev_ike.py index d8b61572a5..91adfbf605 100644 --- a/lms/envs/dev_ike.py +++ b/lms/envs/dev_ike.py @@ -10,12 +10,17 @@ sessions. Assumes structure: from .common import * from .logsettings import get_logger_config from .dev import * +import socket WIKI_ENABLED = False 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 +myhost = socket.gethostname() +if ('edxvm' in myhost) or ('ocw' in myhost): + MITX_FEATURES['DISABLE_LOGIN_BUTTON'] = True # auto-login with MIT certificate + #----------------------------------------------------------------------------- # disable django debug toolbars diff --git a/lms/templates/navigation.html b/lms/templates/navigation.html index 7ba5cca8d0..6c4cfc853b 100644 --- a/lms/templates/navigation.html +++ b/lms/templates/navigation.html @@ -42,11 +42,15 @@ About Blog Jobs +% if not settings.MITX_FEATURES['DISABLE_LOGIN_BUTTON']: Log In +% endif +% if not settings.MITX_FEATURES['DISABLE_LOGIN_BUTTON']:
  • Sign Up
  • +% endif %endif From f6e84e84da5ead6be5701fd3860bf3468ce6d346 Mon Sep 17 00:00:00 2001 From: ichuang Date: Fri, 10 Aug 2012 16:24:32 -0400 Subject: [PATCH 13/21] SECURE_PROXY_SSL_HEADER for django-1.4 in envs/dev_ike for nginx ssl proxy --- lms/envs/dev_ike.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lms/envs/dev_ike.py b/lms/envs/dev_ike.py index 91adfbf605..c58a35f082 100644 --- a/lms/envs/dev_ike.py +++ b/lms/envs/dev_ike.py @@ -21,6 +21,8 @@ myhost = socket.gethostname() if ('edxvm' in myhost) or ('ocw' in myhost): MITX_FEATURES['DISABLE_LOGIN_BUTTON'] = True # auto-login with MIT certificate +SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTOCOL', 'https') # django 1.4 for nginx ssl proxy + #----------------------------------------------------------------------------- # disable django debug toolbars From 241d445f302322c67f0697368e0df99784f55804 Mon Sep 17 00:00:00 2001 From: ichuang Date: Fri, 10 Aug 2012 19:00:50 -0400 Subject: [PATCH 14/21] changes to xml_module to allow problem metadata to be added via --- common/lib/xmodule/xmodule/xml_module.py | 29 +++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/common/lib/xmodule/xmodule/xml_module.py b/common/lib/xmodule/xmodule/xml_module.py index 69c770e279..968c42adcb 100644 --- a/common/lib/xmodule/xmodule/xml_module.py +++ b/common/lib/xmodule/xmodule/xml_module.py @@ -1,6 +1,7 @@ from xmodule.x_module import XModuleDescriptor from xmodule.modulestore import Location from lxml import etree +import json import copy import logging import traceback @@ -32,7 +33,15 @@ def is_pointer_tag(xml_obj): actual_attr = set(xml_obj.attrib.keys()) return len(xml_obj) == 0 and actual_attr == expected_attr - +def get_metadata_from_xml(xml_object, remove=True): + meta = xml_object.find('meta') + if meta is None: + return '' + dmdata = meta.text + log.debug('meta for %s loaded: %s' % (xml_object,dmdata)) + if remove: + xml_object.remove(meta) + return dmdata _AttrMapBase = namedtuple('_AttrMap', 'from_xml to_xml') @@ -180,8 +189,11 @@ class XmlDescriptor(XModuleDescriptor): definition_xml = cls.load_file(filepath, system.resources_fs, location) + definition_metadata = get_metadata_from_xml(definition_xml) cls.clean_metadata_from_xml(definition_xml) definition = cls.definition_from_xml(definition_xml, system) + if definition_metadata: + definition['definition_metadata'] = definition_metadata # TODO (ichuang): remove this after migration # for Fall 2012 LMS migration: keep filename (and unmangled filename) @@ -236,9 +248,9 @@ class XmlDescriptor(XModuleDescriptor): filepath = cls._format_filepath(xml_object.tag, url_name) definition_xml = cls.load_file(filepath, system.resources_fs, location) else: - definition_xml = xml_object + definition_xml = xml_object # this is just a pointer, not the real definition content - definition = cls.load_definition(definition_xml, system, location) + definition = cls.load_definition(definition_xml, system, location) # note this removes metadata # VS[compat] -- make Ike's github preview links work in both old and # new file layouts if is_pointer_tag(xml_object): @@ -246,6 +258,17 @@ class XmlDescriptor(XModuleDescriptor): definition['filename'] = [filepath, filepath] metadata = cls.load_metadata(definition_xml) + + # move definition metadata into dict + dmdata = definition.get('definition_metadata','') + if dmdata: + metadata['definition_metadata_raw'] = dmdata + try: + metadata.update(json.loads(dmdata)) + except Exception as err: + log.debug('Error %s in loading metadata %s' % (err,dmdata)) + metadata['definition_metadata_err'] = str(err) + return cls( system, definition, From da64c8f0a1f6473d603e014fffe8af20d1ce0f57 Mon Sep 17 00:00:00 2001 From: ichuang Date: Sat, 11 Aug 2012 20:12:37 -0400 Subject: [PATCH 15/21] add xqa interface to staff_problem_info, make staff_debug a modal window, add xqa modal window, add xqa_key to course metadata --- common/djangoapps/xmodule_modifiers.py | 10 +- common/lib/xmodule/xmodule/x_module.py | 3 +- common/lib/xmodule/xmodule/xml_module.py | 1 + lms/djangoapps/courseware/module_render.py | 2 +- lms/templates/staff_problem_info.html | 124 +++++++++++++++++++-- 5 files changed, 126 insertions(+), 14 deletions(-) diff --git a/common/djangoapps/xmodule_modifiers.py b/common/djangoapps/xmodule_modifiers.py index 6cbf334afc..982d47efaa 100644 --- a/common/djangoapps/xmodule_modifiers.py +++ b/common/djangoapps/xmodule_modifiers.py @@ -69,14 +69,14 @@ def grade_histogram(module_id): return grades -def add_histogram(get_html, module): +def add_histogram(get_html, module, user): """ Updates the supplied module with a new get_html function that wraps the output of the old get_html function with additional information for admin users only, including a histogram of student answers and the definition of the xmodule - Does nothing if module is a SequenceModule + Does nothing if module is a SequenceModule or a VerticalModule. """ @wraps(get_html) def _get_html(): @@ -104,8 +104,12 @@ def add_histogram(get_html, module): staff_context = {'definition': module.definition.get('data'), 'metadata': json.dumps(module.metadata, indent=4), - 'element_id': module.location.html_id(), + 'location': module.location, + 'xqa_key': module.metadata.get('xqa_key',''), + 'category': str(module.__class__.__name__), + 'element_id': module.location.html_id().replace('-','_'), 'edit_link': edit_link, + 'user': user, 'histogram': json.dumps(histogram), 'render_histogram': render_histogram, 'module_content': get_html()} diff --git a/common/lib/xmodule/xmodule/x_module.py b/common/lib/xmodule/xmodule/x_module.py index 2cd51b9e6e..1c183e03c7 100644 --- a/common/lib/xmodule/xmodule/x_module.py +++ b/common/lib/xmodule/xmodule/x_module.py @@ -319,7 +319,8 @@ class XModuleDescriptor(Plugin, HTMLSnippet): # A list of metadata that this module can inherit from its parent module inheritable_metadata = ( 'graded', 'start', 'due', 'graceperiod', 'showanswer', 'rerandomize', - + # TODO (ichuang): used for Fall 2012 xqa server access + 'xqa_key', # TODO: This is used by the XMLModuleStore to provide for locations for # static files, and will need to be removed when that code is removed 'data_dir' diff --git a/common/lib/xmodule/xmodule/xml_module.py b/common/lib/xmodule/xmodule/xml_module.py index 968c42adcb..399d5d3f91 100644 --- a/common/lib/xmodule/xmodule/xml_module.py +++ b/common/lib/xmodule/xmodule/xml_module.py @@ -80,6 +80,7 @@ class XmlDescriptor(XModuleDescriptor): metadata_attributes = ('format', 'graceperiod', 'showanswer', 'rerandomize', 'start', 'due', 'graded', 'display_name', 'url_name', 'hide_from_toc', 'ispublic', # if True, then course is listed for all users; see + 'xqa_key', # for xqaa server access # VS[compat] Remove once unused. 'name', 'slug') diff --git a/lms/djangoapps/courseware/module_render.py b/lms/djangoapps/courseware/module_render.py index 4910488af2..3ea1abe068 100644 --- a/lms/djangoapps/courseware/module_render.py +++ b/lms/djangoapps/courseware/module_render.py @@ -197,7 +197,7 @@ def get_module(user, request, location, student_module_cache, position=None): if settings.MITX_FEATURES.get('DISPLAY_HISTOGRAMS_TO_STAFF'): if has_staff_access_to_course(user, module.location.course): - module.get_html = add_histogram(module.get_html, module) + module.get_html = add_histogram(module.get_html, module, user) return module diff --git a/lms/templates/staff_problem_info.html b/lms/templates/staff_problem_info.html index a8aaae0cb9..436af6842f 100644 --- a/lms/templates/staff_problem_info.html +++ b/lms/templates/staff_problem_info.html @@ -1,15 +1,121 @@ ${module_content} %if edit_link: - + % endif - + -