diff --git a/lms/djangoapps/courseware/tests/test_course_info.py b/lms/djangoapps/courseware/tests/test_course_info.py
index 11e0289acb..00b4881808 100644
--- a/lms/djangoapps/courseware/tests/test_course_info.py
+++ b/lms/djangoapps/courseware/tests/test_course_info.py
@@ -388,7 +388,7 @@ class SelfPacedCourseInfoTestCase(LoginEnrollmentTestCase, SharedModuleStoreTest
self.assertEqual(resp.status_code, 200)
def test_num_queries_instructor_paced(self):
- self.fetch_course_info_with_queries(self.instructor_paced_course, 22, 3)
+ self.fetch_course_info_with_queries(self.instructor_paced_course, 25, 3)
def test_num_queries_self_paced(self):
- self.fetch_course_info_with_queries(self.self_paced_course, 22, 3)
+ self.fetch_course_info_with_queries(self.self_paced_course, 25, 3)
diff --git a/lms/static/sass/_build-lms-v1.scss b/lms/static/sass/_build-lms-v1.scss
index 25b1095129..ddca292653 100644
--- a/lms/static/sass/_build-lms-v1.scss
+++ b/lms/static/sass/_build-lms-v1.scss
@@ -18,6 +18,7 @@
@import 'edx-pattern-library-shims/buttons';
// base - elements
+@import 'elements/banners';
@import 'elements/controls';
@import 'elements/creative-commons';
@import 'elements/icons';
diff --git a/lms/static/sass/bootstrap/_components.scss b/lms/static/sass/bootstrap/_components.scss
new file mode 100644
index 0000000000..3957b06a25
--- /dev/null
+++ b/lms/static/sass/bootstrap/_components.scss
@@ -0,0 +1,19 @@
+// Open edX: components
+// ====================
+
+// Page banner
+.page-banner {
+ max-width: $lms-max-width;
+ margin: 0 auto;
+
+ .user-messages {
+ margin-top: $baseline;
+ }
+}
+
+// Alerts
+.alert {
+ .icon-alert {
+ margin-right: $baseline / 4;
+ }
+}
diff --git a/lms/static/sass/bootstrap/lms-main.scss b/lms/static/sass/bootstrap/lms-main.scss
index 8b2059f028..4f89e9c064 100644
--- a/lms/static/sass/bootstrap/lms-main.scss
+++ b/lms/static/sass/bootstrap/lms-main.scss
@@ -13,3 +13,4 @@
@import 'footer';
@import 'navigation';
@import 'layouts';
+@import 'components';
diff --git a/lms/static/sass/elements/_banners.scss b/lms/static/sass/elements/_banners.scss
index 27d76fd8e9..dab763fb8e 100644
--- a/lms/static/sass/elements/_banners.scss
+++ b/lms/static/sass/elements/_banners.scss
@@ -44,3 +44,50 @@ $full-width-banner-margin: 20px;
right: $full-width-banner-margin;
}
}
+
+.page-banner {
+ max-width: $lms-max-width;
+ margin: 0 auto;
+
+ .user-messages {
+ padding-top: $baseline;
+ }
+
+ .alert {
+ margin-bottom: $baseline !important;
+ padding: $baseline;
+ border: 1px solid;
+
+ .icon-alert {
+ margin-right: $baseline / 4;
+ }
+
+ &.alert-info {
+ color: $state-info-text;
+ background-color: $state-info-bg;
+ border-color: $state-info-border;
+ box-shadow: none;
+ }
+
+ &.alert-success {
+ color: $state-success-text;
+ background-color: $state-success-bg;
+ border-color: $state-success-border;
+ box-shadow: none;
+ }
+
+ &.alert-warning {
+ color: $state-warning-text;
+ background-color: $state-warning-bg;
+ border-color: $state-warning-border;
+ box-shadow: none;
+ }
+
+ &.alert-danger {
+ color: $state-danger-text;
+ background-color: $state-danger-bg;
+ border-color: $state-danger-border;
+ box-shadow: none;
+ }
+ }
+}
diff --git a/lms/static/sass/partials/base/_variables.scss b/lms/static/sass/partials/base/_variables.scss
index 00aa6d412f..27bfac453d 100644
--- a/lms/static/sass/partials/base/_variables.scss
+++ b/lms/static/sass/partials/base/_variables.scss
@@ -220,6 +220,26 @@ $alert-color: rgb(212, 64, 64) !default;
$success-color: rgb(0, 155, 0) !default;
$success-color-hover: rgb(0, 129, 0) !default;
+// ----------------------------
+// #COLORS- Bootstrap-style
+// ----------------------------
+
+$state-success-text: $black !default;
+$state-success-bg: #dff0d8 !default;
+$state-success-border: darken($state-success-bg, 5%) !default;
+
+$state-info-text: $black !default;
+$state-info-bg: #d9edf7 !default;
+$state-info-border: darken($state-info-bg, 7%) !default;
+
+$state-warning-text: $black !default;
+$state-warning-bg: #fcf8e3 !default;
+$state-warning-border: darken($state-warning-bg, 5%) !default;
+
+$state-danger-text: $black !default;
+$state-danger-bg: #f2dede !default;
+$state-danger-border: darken($state-danger-bg, 5%) !default;
+
// ----------------------------
// #COLORS- EDX-SPECIFIC
// ----------------------------
diff --git a/lms/static/sass/shared-v2/_components.scss b/lms/static/sass/shared-v2/_components.scss
index 59ec336dd5..cabb4e45cf 100644
--- a/lms/static/sass/shared-v2/_components.scss
+++ b/lms/static/sass/shared-v2/_components.scss
@@ -89,6 +89,48 @@
}
}
+.page-banner {
+ max-width: $lms-max-width;
+ margin: 0 auto;
+
+ .alert {
+ margin-top: $baseline;
+ border: 1px solid;
+
+ .icon-alert {
+ margin-right: $baseline / 4;
+ }
+
+ &.alert-info {
+ color: $state-info-text;
+ background-color: $state-info-bg;
+ border-color: $state-info-border;
+ box-shadow: none;
+ }
+
+ &.alert-success {
+ color: $state-success-text;
+ background-color: $state-success-bg;
+ border-color: $state-success-border;
+ box-shadow: none;
+ }
+
+ &.alert-warning {
+ color: $state-warning-text;
+ background-color: $state-warning-bg;
+ border-color: $state-warning-border;
+ box-shadow: none;
+ }
+
+ &.alert-danger {
+ color: $state-danger-text;
+ background-color: $state-danger-bg;
+ border-color: $state-danger-border;
+ box-shadow: none;
+ }
+ }
+}
+
.wrapper-preview-menu {
@include clearfix();
@include box-sizing(border-box);
diff --git a/lms/static/sass/shared-v2/_variables.scss b/lms/static/sass/shared-v2/_variables.scss
index 5ea9424aae..9603ac1136 100644
--- a/lms/static/sass/shared-v2/_variables.scss
+++ b/lms/static/sass/shared-v2/_variables.scss
@@ -62,3 +62,23 @@ $lms-dark-icon-background-color: palette(grayscale, black) !default;
$site-status-color: rgb(182,37,103) !default;
$shadow-l1: rgba(0,0,0,0.1) !default;
+
+// ----------------------------
+// #ALERTS
+// ----------------------------
+
+$state-success-text: $black !default;
+$state-success-bg: #dff0d8 !default;
+$state-success-border: darken($state-success-bg, 5%) !default;
+
+$state-info-text: $black !default;
+$state-info-bg: #d9edf7 !default;
+$state-info-border: darken($state-info-bg, 7%) !default;
+
+$state-warning-text: $black !default;
+$state-warning-bg: #fcf8e3 !default;
+$state-warning-border: darken($state-warning-bg, 5%) !default;
+
+$state-danger-text: $black !default;
+$state-danger-bg: #f2dede !default;
+$state-danger-border: darken($state-danger-bg, 5%) !default;
diff --git a/lms/templates/main.html b/lms/templates/main.html
index 8cf1562992..dad1767c40 100644
--- a/lms/templates/main.html
+++ b/lms/templates/main.html
@@ -141,6 +141,8 @@ from pipeline_mako import render_require_js_path_overrides
<%include file="/preview_menu.html" />
% endif
+ <%include file="/page_banner.html" />
+
${self.body()}
<%block name="bodyextra"/>
diff --git a/lms/templates/page_banner.html b/lms/templates/page_banner.html
new file mode 100644
index 0000000000..e7f998732e
--- /dev/null
+++ b/lms/templates/page_banner.html
@@ -0,0 +1,24 @@
+## mako
+
+<%page expression_filter="h"/>
+
+<%namespace name='static' file='static_content.html'/>
+<% online_help_token = self.online_help_token() if hasattr(self, 'online_help_token') else None %>
+<%!
+from django.utils.translation import ugettext as _
+from openedx.core.djangolib.markup import HTML
+from openedx.core.djangoapps.util.user_messages import user_messages
+%>
+
+% if user_messages:
+
+
+ % for message in user_messages(request):
+
+
+ ${HTML(message.message_html)}
+
+ % endfor
+
+
+% endif
diff --git a/lms/templates/ux/reference/bootstrap/course-skeleton.html b/lms/templates/ux/reference/bootstrap/course-skeleton.html
index 7eae185815..ff31a6368a 100644
--- a/lms/templates/ux/reference/bootstrap/course-skeleton.html
+++ b/lms/templates/ux/reference/bootstrap/course-skeleton.html
@@ -1,3 +1,5 @@
+## mako
+
## Override the default styles_version to use Bootstrap
<%! main_css = "css/bootstrap/lms-main.css" %>
diff --git a/lms/templates/ux/reference/index.html b/lms/templates/ux/reference/index.html
index bb4db4d303..a9d1b8de3b 100644
--- a/lms/templates/ux/reference/index.html
+++ b/lms/templates/ux/reference/index.html
@@ -1,5 +1,4 @@
-## Override the default styles_version to the Pattern Library version (version 2)
-<%! main_css = "style-main-v2" %>
+## mako
<%page expression_filter="h"/>
<%inherit file="/main.html" />
@@ -18,10 +17,14 @@
UX Style Reference
- Page Types
+ v1-style LMS Pages
+
+ Pattern Library
+
Bootstrap
diff --git a/lms/templates/ux/reference/pattern-library-test.html b/lms/templates/ux/reference/pattern-library-test.html
deleted file mode 100644
index 67f68270c5..0000000000
--- a/lms/templates/ux/reference/pattern-library-test.html
+++ /dev/null
@@ -1,24 +0,0 @@
-## Override the default styles_version to the Pattern Library version (version 2)
-<%! main_css = "style-main-v2" %>
-
-<%page expression_filter="h"/>
-<%inherit file="/main.html" />
-
-<%block name="pagetitle">Pattern Library Test%block>
-<%block name="nav_skip">#content%block>
-
-<%block name="bodyclass">pattern-library%block>
-
-<%block name="content">
-Pattern Library test page
-
-
-
-
-
-
- Interesting pattern library content to come...
-
-
-
-%block>
diff --git a/lms/templates/ux/reference/course-skeleton.html b/lms/templates/ux/reference/pattern-library/course-skeleton.html
similarity index 99%
rename from lms/templates/ux/reference/course-skeleton.html
rename to lms/templates/ux/reference/pattern-library/course-skeleton.html
index f626364591..c5ccc5357a 100644
--- a/lms/templates/ux/reference/course-skeleton.html
+++ b/lms/templates/ux/reference/pattern-library/course-skeleton.html
@@ -1,3 +1,5 @@
+## mako
+
## Override the default styles_version to the Pattern Library version (version 2)
<%! main_css = "style-main-v2" %>
diff --git a/lms/templates/ux/reference/v1/course-skeleton.html b/lms/templates/ux/reference/v1/course-skeleton.html
new file mode 100644
index 0000000000..f19081dbe3
--- /dev/null
+++ b/lms/templates/ux/reference/v1/course-skeleton.html
@@ -0,0 +1,945 @@
+## mako
+
+<%page expression_filter="h"/>
+
+<%namespace name='static' file='/static_content.html'/>
+<%inherit file="/main.html" />
+
+<%block name="pagetitle">Course Skeleton%block>
+
+<%block name="bodyclass">view-in-course view-courseware courseware%block>
+
+<%block name="headextra">
+<%static:css group='style-course-vendor'/>
+<%static:css group='style-course'/>
+%block>
+
+<%block name="content">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Previous
+
+
+
+
+
+
+
+ video Introduction: Video and Sequences
+
+
+
+
+
+ Next
+
+
+
+
+
+
+
+
+
+<div class="wrap-instructor-info studio-view">
+<a class="instructor-info-action" href="//localhost:18010/container/block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_0270f6de40fc">View Unit in Studio</a>
+</div>
+<div class="xblock xblock-student_view xblock-student_view-vertical" data-runtime-class="LmsRuntime" data-init="VerticalStudentView" data-course-id="course-v1:edX+DemoX+Demo_Course" data-request-token="cd3bba7c68a511e7826c08002779ca96" data-runtime-version="1" data-usage-id="block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_0270f6de40fc" data-block-type="vertical">
+
+
+<h2 class="hd hd-2 unit-title">Introduction: Video and Sequences</h2>
+
+
+
+
+
+<div class="bookmark-button-wrapper">
+<button class="btn btn-link bookmark-button "
+aria-pressed="false"
+data-bookmark-id="AndyA,block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_0270f6de40fc"
+data-bookmarks-api-url="/api/bookmarks/v1/bookmarks/">
+<span class="bookmark-text">Bookmark this page</span>
+</button>
+</div>
+
+
+<div class="vert-mod">
+<div class="vert vert-0" data-id="block-v1:edX+DemoX+Demo_Course+type@html+block@030e35c4756a4ddc8d40b95fbbfff4d4">
+
+
+
+<div class="xblock xblock-student_view xblock-student_view-html xmodule_display xmodule_HtmlModule" data-runtime-class="LmsRuntime" data-init="XBlockToXModuleShim" data-block-type="html" data-request-token="cd3bba7c68a511e7826c08002779ca96" data-runtime-version="1" data-usage-id="block-v1:edX+DemoX+Demo_Course+type@html+block@030e35c4756a4ddc8d40b95fbbfff4d4" data-type="HTMLModule" data-course-id="course-v1:edX+DemoX+Demo_Course">
+<script type="json/xblock-args" class="xblock-json-init-args">
+{"xmodule-type": "HTMLModule"}
+</script>
+<p><strong>Welcome to the edX Demo Course Introduction.</strong> This is where you can explore how to take an edX course (like this one). Most courses have an "intro" video that shows you how it all works. </p>
+<p style="margin-right: 0px; font-size: 16px; margin-left: 0px; font-family: 'Open Sans', Verdana, Geneva, sans-serif;">You can watch the introduction video (below) or scroll though the course studies and assignments using the toolbar (above). Just for fun, we'll keep track of your work in this demo course, and show you your progress in the toolbar just like in a real course.</p>
+<p style="margin-right: 0px; font-size: 16px; margin-left: 0px; font-family: 'Open Sans', Verdana, Geneva, sans-serif;">Watch the overview video (below), then click on "Example Week One" in the left hand navigation to get started.</p>
+</div>
+
+<div class="wrap-instructor-info">
+<a class="instructor-info-action" href="#030e35c4756a4ddc8d40b95fbbfff4d4_debug" id="030e35c4756a4ddc8d40b95fbbfff4d4_trig">Staff Debug Info</a>
+
+</div>
+
+<div aria-hidden="true" role="dialog" tabindex="-1" id="030e35c4756a4ddc8d40b95fbbfff4d4_xqa-modal" class="modal xqa-modal">
+<div class="inner-wrapper">
+<header>
+<h2>Your Platform Name Here Content Quality Assessment</h2>
+</header>
+
+<form id="030e35c4756a4ddc8d40b95fbbfff4d4_xqa_form" class="xqa_form">
+<label for="030e35c4756a4ddc8d40b95fbbfff4d4_xqa_entry">Comment</label>
+<input tabindex="0" id="030e35c4756a4ddc8d40b95fbbfff4d4_xqa_entry" type="text" placeholder="comment">
+<label for="030e35c4756a4ddc8d40b95fbbfff4d4_xqa_tag">Tag</label>
+<span style="color:black;vertical-align: -10pt">Optional tag (eg "done" or "broken"): </span>
+<input id="030e35c4756a4ddc8d40b95fbbfff4d4_xqa_tag" type="text" placeholder="tag" style="width:80px;display:inline">
+<div class="submit">
+<button name="submit" type="submit">Add comment</button>
+</div>
+<hr>
+<div id="030e35c4756a4ddc8d40b95fbbfff4d4_xqa_log_data"></div>
+</form>
+
+</div>
+</div>
+
+<div aria-hidden="true" role="dialog" tabindex="-1" class="modal staff-modal" id="030e35c4756a4ddc8d40b95fbbfff4d4_debug" >
+<div class="inner-wrapper">
+<header>
+<h2>Staff Debug</h2>
+</header>
+
+<hr />
+<div class="staff_actions">
+<h3>Actions</h3>
+<div>
+<label for="sd_fu_030e35c4756a4ddc8d40b95fbbfff4d4">Username:</label>
+<input type="text" tabindex="0" id="sd_fu_030e35c4756a4ddc8d40b95fbbfff4d4" placeholder="AndyA"/>
+</div>
+<div data-location="block-v1:edX+DemoX+Demo_Course+type@html+block@030e35c4756a4ddc8d40b95fbbfff4d4" data-location-name="030e35c4756a4ddc8d40b95fbbfff4d4">
+[
+<button type="button" class="btn-link staff-debug-sdelete">Delete Learner's State</button>
+]
+</div>
+<div id="result_030e35c4756a4ddc8d40b95fbbfff4d4"></div>
+</div>
+
+<div class="staff_info" style="display:block">
+is_released = <font color='red'>Yes!</font>
+location = block-v1:edX+DemoX+Demo_Course+type@html+block@030e35c4756a4ddc8d40b95fbbfff4d4
+
+<table summary="Module Fields">
+<tr><th>Module Fields</th></tr>
+<tr><td style="width:25%">visible_to_staff_only</td><td><pre style="display:inline-block; margin: 0;">False</pre></td></tr>
+<tr><td style="width:25%">graded</td><td><pre style="display:inline-block; margin: 0;">False</pre></td></tr>
+<tr><td style="width:25%">annotation_token_secret</td><td><pre style="display:inline-block; margin: 0;">xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx</pre></td></tr>
+<tr><td style="width:25%">giturl</td><td><pre style="display:inline-block; margin: 0;">None</pre></td></tr>
+<tr><td style="width:25%">edxnotes</td><td><pre style="display:inline-block; margin: 0;">False</pre></td></tr>
+<tr><td style="width:25%">source_file</td><td><pre style="display:inline-block; margin: 0;">None</pre></td></tr>
+<tr><td style="width:25%">course_edit_method</td><td><pre style="display:inline-block; margin: 0;">Studio</pre></td></tr>
+<tr><td style="width:25%">default_tab</td><td><pre style="display:inline-block; margin: 0;">None</pre></td></tr>
+<tr><td style="width:25%">in_entrance_exam</td><td><pre style="display:inline-block; margin: 0;">False</pre></td></tr>
+<tr><td style="width:25%">showanswer</td><td><pre style="display:inline-block; margin: 0;">attempted</pre></td></tr>
+<tr><td style="width:25%">display_name</td><td><pre style="display:inline-block; margin: 0;">Blank HTML Page</pre></td></tr>
+<tr><td style="width:25%">video_speed_optimizations</td><td><pre style="display:inline-block; margin: 0;">True</pre></td></tr>
+<tr><td style="width:25%">graceperiod</td><td><pre style="display:inline-block; margin: 0;">5:00:00</pre></td></tr>
+<tr><td style="width:25%">format</td><td><pre style="display:inline-block; margin: 0;">None</pre></td></tr>
+<tr><td style="width:25%">due</td><td><pre style="display:inline-block; margin: 0;">None</pre></td></tr>
+<tr><td style="width:25%">start</td><td><pre style="display:inline-block; margin: 0;">1970-01-01 05:00:00+00:00</pre></td></tr>
+<tr><td style="width:25%">editor</td><td><pre style="display:inline-block; margin: 0;">visual</pre></td></tr>
+<tr><td style="width:25%">video_bumper</td><td><pre style="display:inline-block; margin: 0;">{}</pre></td></tr>
+<tr><td style="width:25%">max_attempts</td><td><pre style="display:inline-block; margin: 0;">None</pre></td></tr>
+<tr><td style="width:25%">parent</td><td><pre style="display:inline-block; margin: 0;">block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_0270f6de40fc</pre></td></tr>
+<tr><td style="width:25%">tags</td><td><pre style="display:inline-block; margin: 0;">[]</pre></td></tr>
+<tr><td style="width:25%">matlab_api_key</td><td><pre style="display:inline-block; margin: 0;">None</pre></td></tr>
+<tr><td style="width:25%">xqa_key</td><td><pre style="display:inline-block; margin: 0;">qaijS3UatK020Wc0sfCtFe0V6jpB4d64</pre></td></tr>
+<tr><td style="width:25%">annotation_storage_url</td><td><pre style="display:inline-block; margin: 0;">http://your_annotation_storage.com</pre></td></tr>
+<tr><td style="width:25%">use_latex_compiler</td><td><pre style="display:inline-block; margin: 0;">False</pre></td></tr>
+<tr><td style="width:25%">days_early_for_beta</td><td><pre style="display:inline-block; margin: 0;">None</pre></td></tr>
+<tr><td style="width:25%">show_correctness</td><td><pre style="display:inline-block; margin: 0;">always</pre></td></tr>
+<tr><td style="width:25%">source_code</td><td><pre style="display:inline-block; margin: 0;">None</pre></td></tr>
+<tr><td style="width:25%">data</td><td><pre style="display:inline-block; margin: 0;"><p><strong>Welcome to the edX Demo Course Introduction.</strong>&nbsp;This is where you can explore how to take an edX course (like this one). Most courses have an "intro" video that shows you how it all works.&nbsp;</p>
+<p style="margin-right: 0px; font-size: 16px; margin-left: 0px; font-family: 'Open Sans', Verdana, Geneva, sans-serif;">You can watch the introduction video (below) or scroll though the course studies and assignments using the toolbar (above). &nbsp;Just for fun, we'll keep track of your work in this demo course, and show you your progress in the toolbar just like in a real course.</p>
+<p style="margin-right: 0px; font-size: 16px; margin-left: 0px; font-family: 'Open Sans', Verdana, Geneva, sans-serif;">Watch the overview video (below), then click on "Example Week One" in the left hand navigation to get started.</p></pre></td></tr>
+<tr><td style="width:25%">static_asset_path</td><td><pre style="display:inline-block; margin: 0;"></pre></td></tr>
+<tr><td style="width:25%">name</td><td><pre style="display:inline-block; margin: 0;">None</pre></td></tr>
+<tr><td style="width:25%">hide_from_toc</td><td><pre style="display:inline-block; margin: 0;">False</pre></td></tr>
+<tr><td style="width:25%">group_access</td><td><pre style="display:inline-block; margin: 0;">{}</pre></td></tr>
+<tr><td style="width:25%">rerandomize</td><td><pre style="display:inline-block; margin: 0;">never</pre></td></tr>
+<tr><td style="width:25%">user_partitions</td><td><pre style="display:inline-block; margin: 0;">[]</pre></td></tr>
+<tr><td style="width:25%">chrome</td><td><pre style="display:inline-block; margin: 0;">None</pre></td></tr>
+<tr><td style="width:25%">edxnotes_visibility</td><td><pre style="display:inline-block; margin: 0;">True</pre></td></tr>
+<tr><td style="width:25%">show_reset_button</td><td><pre style="display:inline-block; margin: 0;">False</pre></td></tr>
+<tr><td style="width:25%">self_paced</td><td><pre style="display:inline-block; margin: 0;">False</pre></td></tr>
+</table>
+<table>
+<tr><th>XML attributes</th></tr>
+</table>
+category = HtmlModuleWithMixins
+</div>
+</div>
+</div>
+
+<div aria-hidden="true" role="dialog" tabindex="-1" class="modal history-modal" id="030e35c4756a4ddc8d40b95fbbfff4d4_history">
+<div class="inner-wrapper">
+<header>
+<h2>Submission History Viewer</h2>
+</header>
+<form id="030e35c4756a4ddc8d40b95fbbfff4d4_history_form">
+<label for="030e35c4756a4ddc8d40b95fbbfff4d4_history_student_username">User:</label>
+<input tabindex="0" id="030e35c4756a4ddc8d40b95fbbfff4d4_history_student_username" type="text" placeholder=""/>
+<input type="hidden" id="030e35c4756a4ddc8d40b95fbbfff4d4_history_location" value="block-v1:edX+DemoX+Demo_Course+type@html+block@030e35c4756a4ddc8d40b95fbbfff4d4"/>
+<div class="submit">
+<button name="submit" type="submit">View History</button>
+</div>
+</form>
+
+<div id="030e35c4756a4ddc8d40b95fbbfff4d4_history_text" class="staff_info" style="display:block">
+</div>
+</div>
+</div>
+
+<div id="030e35c4756a4ddc8d40b95fbbfff4d4_setup"></div>
+
+<script type="text/javascript">
+// assumes courseware.html's loaded this method.
+$(function () {
+setup_debug('030e35c4756a4ddc8d40b95fbbfff4d4',
+null,
+{
+'location': 'block\u002Dv1:edX+DemoX+Demo_Course+type@html+block@030e35c4756a4ddc8d40b95fbbfff4d4',
+'xqa_key': 'qaijS3UatK020Wc0sfCtFe0V6jpB4d64',
+'category': 'HtmlModuleWithMixins',
+'user': 'AndyA'
+}
+);
+});
+</script>
+
+</div>
+<div class="vert vert-1" data-id="block-v1:edX+DemoX+Demo_Course+type@video+block@0b9e39477cf34507a7a48f74be381fdd">
+
+
+
+<div class="xblock xblock-student_view xblock-student_view-video xmodule_display xmodule_VideoModule" data-runtime-class="LmsRuntime" data-init="XBlockToXModuleShim" data-block-type="video" data-request-token="cd3bba7c68a511e7826c08002779ca96" data-runtime-version="1" data-usage-id="block-v1:edX+DemoX+Demo_Course+type@video+block@0b9e39477cf34507a7a48f74be381fdd" data-type="Video" data-course-id="course-v1:edX+DemoX+Demo_Course">
+<script type="json/xblock-args" class="xblock-json-init-args">
+{"xmodule-type": "Video"}
+</script>
+
+
+
+<h3 class="hd hd-2">Welcome!</h3>
+
+<div
+id="video_0b9e39477cf34507a7a48f74be381fdd"
+class="video closed"
+data-metadata='{"savedVideoPosition": 0.0, "ytMetadataUrl": "https://www.googleapis.com/youtube/v3/videos/", "sources": ["https://s3.amazonaws.com/edx-course-videos/edx-edx101/EDXSPCPJSP13-H010000_100.mp4"], "speed": null, "generalSpeed": 1.0, "end": 0.0, "sub": "name_of_file", "ytTestTimeout": 1500, "transcriptLanguages": {"en": "English"}, "start": 0.0, "ytKey": "PUT_YOUR_API_KEY_HERE", "poster": null, "recordedYoutubeIsAvailable": true, "ytApiUrl": "https://www.youtube.com/iframe_api", "saveStateUrl": "/courses/course-v1:edX+DemoX+Demo_Course/xblock/block-v1:edX+DemoX+Demo_Course+type@video+block@0b9e39477cf34507a7a48f74be381fdd/handler/xmodule_handler/save_user_state", "transcriptAvailableTranslationsUrl": "/courses/course-v1:edX+DemoX+Demo_Course/xblock/block-v1:edX+DemoX+Demo_Course+type@video+block@0b9e39477cf34507a7a48f74be381fdd/handler/transcript/available_translations", "transcriptLanguage": "en", "showCaptions": "true", "autohideHtml5": false, "streams": "1.00:b7xgknqkQk8", "transcriptTranslationUrl": "/courses/course-v1:edX+DemoX+Demo_Course/xblock/block-v1:edX+DemoX+Demo_Course+type@video+block@0b9e39477cf34507a7a48f74be381fdd/handler/transcript/translation/__lang__", "captionDataDir": null, "autoplay": false}'
+data-bumper-metadata='null'
+data-poster='null'
+tabindex="-1"
+>
+<div class="focus_grabber first"></div>
+
+<div class="tc-wrapper">
+<div class="video-wrapper">
+<span tabindex="0" class="spinner" aria-hidden="false" aria-label="Loading video player"></span>
+<span tabindex="-1" class="btn-play fa fa-youtube-play fa-2x is-hidden" aria-hidden="true" aria-label="Play video"></span>
+<div class="video-player-pre"></div>
+<div class="video-player">
+<div id="0b9e39477cf34507a7a48f74be381fdd"></div>
+<h4 class="hd hd-4 video-error is-hidden">No playable video sources found.</h4>
+<h4 class="hd hd-4 video-hls-error is-hidden">
+Your browser does not support this video format. Try using a different browser.
+</h4>
+</div>
+<div class="video-player-post"></div>
+<div class="closed-captions"></div>
+<div class="video-controls is-hidden">
+<div>
+<div class="vcr"><div class="vidtime">0:00 / 0:00</div></div>
+<div class="secondary-controls"></div>
+</div>
+</div>
+</div>
+</div>
+
+<div class="focus_grabber last"></div>
+
+<h3 class="hd hd-4 downloads-heading sr" id="video-download-transcripts_0b9e39477cf34507a7a48f74be381fdd">Downloads and transcripts</h3>
+<div class="wrapper-downloads" role="region" aria-labelledby="video-download-transcripts_0b9e39477cf34507a7a48f74be381fdd">
+<div class="wrapper-download-video">
+<h4 class="hd hd-5">Video</h4>
+<a class="btn-link video-sources video-download-button" href="https://s3.amazonaws.com/edx-course-videos/edx-edx101/EDXSPCPJSP13-H010000_100.mp4">
+Download video file
+</a>
+</div>
+<div class="wrapper-download-transcripts">
+<h4 class="hd hd-5">Transcripts</h4>
+<ul class="list-download-transcripts">
+<li class="transcript-option">
+
+<a class="btn btn-link" href="/courses/course-v1:edX+DemoX+Demo_Course/xblock/block-v1:edX+DemoX+Demo_Course+type@video+block@0b9e39477cf34507a7a48f74be381fdd/handler/transcript/download" data-value="srt">Download SubRip (.srt) file</a>
+</li>
+<li class="transcript-option">
+
+<a class="btn btn-link" href="/courses/course-v1:edX+DemoX+Demo_Course/xblock/block-v1:edX+DemoX+Demo_Course+type@video+block@0b9e39477cf34507a7a48f74be381fdd/handler/transcript/download" data-value="txt">Download Text (.txt) file</a>
+</li>
+</ul>
+</div>
+</div>
+</div>
+
+</div>
+
+<div class="wrap-instructor-info">
+<a class="instructor-info-action" href="#0b9e39477cf34507a7a48f74be381fdd_debug" id="0b9e39477cf34507a7a48f74be381fdd_trig">Staff Debug Info</a>
+
+</div>
+
+<div aria-hidden="true" role="dialog" tabindex="-1" id="0b9e39477cf34507a7a48f74be381fdd_xqa-modal" class="modal xqa-modal">
+<div class="inner-wrapper">
+<header>
+<h2>Your Platform Name Here Content Quality Assessment</h2>
+</header>
+
+<form id="0b9e39477cf34507a7a48f74be381fdd_xqa_form" class="xqa_form">
+<label for="0b9e39477cf34507a7a48f74be381fdd_xqa_entry">Comment</label>
+<input tabindex="0" id="0b9e39477cf34507a7a48f74be381fdd_xqa_entry" type="text" placeholder="comment">
+<label for="0b9e39477cf34507a7a48f74be381fdd_xqa_tag">Tag</label>
+<span style="color:black;vertical-align: -10pt">Optional tag (eg "done" or "broken"): </span>
+<input id="0b9e39477cf34507a7a48f74be381fdd_xqa_tag" type="text" placeholder="tag" style="width:80px;display:inline">
+<div class="submit">
+<button name="submit" type="submit">Add comment</button>
+</div>
+<hr>
+<div id="0b9e39477cf34507a7a48f74be381fdd_xqa_log_data"></div>
+</form>
+
+</div>
+</div>
+
+<div aria-hidden="true" role="dialog" tabindex="-1" class="modal staff-modal" id="0b9e39477cf34507a7a48f74be381fdd_debug" >
+<div class="inner-wrapper">
+<header>
+<h2>Staff Debug</h2>
+</header>
+
+<hr />
+<div class="staff_actions">
+<h3>Actions</h3>
+<div>
+<label for="sd_fu_0b9e39477cf34507a7a48f74be381fdd">Username:</label>
+<input type="text" tabindex="0" id="sd_fu_0b9e39477cf34507a7a48f74be381fdd" placeholder="AndyA"/>
+</div>
+<div data-location="block-v1:edX+DemoX+Demo_Course+type@video+block@0b9e39477cf34507a7a48f74be381fdd" data-location-name="0b9e39477cf34507a7a48f74be381fdd">
+[
+<button type="button" class="btn-link staff-debug-sdelete">Delete Learner's State</button>
+]
+</div>
+<div id="result_0b9e39477cf34507a7a48f74be381fdd"></div>
+</div>
+
+<div class="staff_info" style="display:block">
+is_released = <font color='red'>Yes!</font>
+location = block-v1:edX+DemoX+Demo_Course+type@video+block@0b9e39477cf34507a7a48f74be381fdd
+
+<table summary="Module Fields">
+<tr><th>Module Fields</th></tr>
+<tr><td style="width:25%">transcript_language</td><td><pre style="display:inline-block; margin: 0;">en</pre></td></tr>
+<tr><td style="width:25%">group_access</td><td><pre style="display:inline-block; margin: 0;">{}</pre></td></tr>
+<tr><td style="width:25%">graded</td><td><pre style="display:inline-block; margin: 0;">False</pre></td></tr>
+<tr><td style="width:25%">annotation_token_secret</td><td><pre style="display:inline-block; margin: 0;">xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx</pre></td></tr>
+<tr><td style="width:25%">youtube_id_1_25</td><td><pre style="display:inline-block; margin: 0;"></pre></td></tr>
+<tr><td style="width:25%">transcript_download_format</td><td><pre style="display:inline-block; margin: 0;">srt</pre></td></tr>
+<tr><td style="width:25%">giturl</td><td><pre style="display:inline-block; margin: 0;">None</pre></td></tr>
+<tr><td style="width:25%">edxnotes</td><td><pre style="display:inline-block; margin: 0;">False</pre></td></tr>
+<tr><td style="width:25%">show_captions</td><td><pre style="display:inline-block; margin: 0;">True</pre></td></tr>
+<tr><td style="width:25%">source_file</td><td><pre style="display:inline-block; margin: 0;">None</pre></td></tr>
+<tr><td style="width:25%">handout</td><td><pre style="display:inline-block; margin: 0;">None</pre></td></tr>
+<tr><td style="width:25%">course_edit_method</td><td><pre style="display:inline-block; margin: 0;">Studio</pre></td></tr>
+<tr><td style="width:25%">default_tab</td><td><pre style="display:inline-block; margin: 0;">None</pre></td></tr>
+<tr><td style="width:25%">bumper_do_not_show_again</td><td><pre style="display:inline-block; margin: 0;">False</pre></td></tr>
+<tr><td style="width:25%">in_entrance_exam</td><td><pre style="display:inline-block; margin: 0;">False</pre></td></tr>
+<tr><td style="width:25%">showanswer</td><td><pre style="display:inline-block; margin: 0;">attempted</pre></td></tr>
+<tr><td style="width:25%">display_name</td><td><pre style="display:inline-block; margin: 0;">Welcome!</pre></td></tr>
+<tr><td style="width:25%">sub</td><td><pre style="display:inline-block; margin: 0;">name_of_file</pre></td></tr>
+<tr><td style="width:25%">video_speed_optimizations</td><td><pre style="display:inline-block; margin: 0;">True</pre></td></tr>
+<tr><td style="width:25%">graceperiod</td><td><pre style="display:inline-block; margin: 0;">5:00:00</pre></td></tr>
+<tr><td style="width:25%">speed</td><td><pre style="display:inline-block; margin: 0;">None</pre></td></tr>
+<tr><td style="width:25%">format</td><td><pre style="display:inline-block; margin: 0;">None</pre></td></tr>
+<tr><td style="width:25%">due</td><td><pre style="display:inline-block; margin: 0;">None</pre></td></tr>
+<tr><td style="width:25%">edx_video_id</td><td><pre style="display:inline-block; margin: 0;"></pre></td></tr>
+<tr><td style="width:25%">start</td><td><pre style="display:inline-block; margin: 0;">1970-01-01 05:00:00+00:00</pre></td></tr>
+<tr><td style="width:25%">youtube_id_1_0</td><td><pre style="display:inline-block; margin: 0;">b7xgknqkQk8</pre></td></tr>
+<tr><td style="width:25%">only_on_web</td><td><pre style="display:inline-block; margin: 0;">False</pre></td></tr>
+<tr><td style="width:25%">youtube_id_1_5</td><td><pre style="display:inline-block; margin: 0;"></pre></td></tr>
+<tr><td style="width:25%">days_early_for_beta</td><td><pre style="display:inline-block; margin: 0;">None</pre></td></tr>
+<tr><td style="width:25%">start_time</td><td><pre style="display:inline-block; margin: 0;">0:00:00</pre></td></tr>
+<tr><td style="width:25%">visible_to_staff_only</td><td><pre style="display:inline-block; margin: 0;">False</pre></td></tr>
+<tr><td style="width:25%">download_video</td><td><pre style="display:inline-block; margin: 0;">True</pre></td></tr>
+<tr><td style="width:25%">parent</td><td><pre style="display:inline-block; margin: 0;">block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_0270f6de40fc</pre></td></tr>
+<tr><td style="width:25%">tags</td><td><pre style="display:inline-block; margin: 0;">[]</pre></td></tr>
+<tr><td style="width:25%">matlab_api_key</td><td><pre style="display:inline-block; margin: 0;">None</pre></td></tr>
+<tr><td style="width:25%">xqa_key</td><td><pre style="display:inline-block; margin: 0;">qaijS3UatK020Wc0sfCtFe0V6jpB4d64</pre></td></tr>
+<tr><td style="width:25%">youtube_is_available</td><td><pre style="display:inline-block; margin: 0;">True</pre></td></tr>
+<tr><td style="width:25%">html5_sources</td><td><pre style="display:inline-block; margin: 0;">[u'https://s3.amazonaws.com/edx-course-videos/edx-edx101/EDXSPCPJSP13-H010000_100.mp4']</pre></td></tr>
+<tr><td style="width:25%">global_speed</td><td><pre style="display:inline-block; margin: 0;">1.0</pre></td></tr>
+<tr><td style="width:25%">annotation_storage_url</td><td><pre style="display:inline-block; margin: 0;">http://your_annotation_storage.com</pre></td></tr>
+<tr><td style="width:25%">track</td><td><pre style="display:inline-block; margin: 0;"></pre></td></tr>
+<tr><td style="width:25%">use_latex_compiler</td><td><pre style="display:inline-block; margin: 0;">False</pre></td></tr>
+<tr><td style="width:25%">video_bumper</td><td><pre style="display:inline-block; margin: 0;">{}</pre></td></tr>
+<tr><td style="width:25%">show_correctness</td><td><pre style="display:inline-block; margin: 0;">always</pre></td></tr>
+<tr><td style="width:25%">youtube_id_0_75</td><td><pre style="display:inline-block; margin: 0;"></pre></td></tr>
+<tr><td style="width:25%">static_asset_path</td><td><pre style="display:inline-block; margin: 0;"></pre></td></tr>
+<tr><td style="width:25%">hide_from_toc</td><td><pre style="display:inline-block; margin: 0;">False</pre></td></tr>
+<tr><td style="width:25%">bumper_last_view_date</td><td><pre style="display:inline-block; margin: 0;">None</pre></td></tr>
+<tr><td style="width:25%">show_reset_button</td><td><pre style="display:inline-block; margin: 0;">False</pre></td></tr>
+<tr><td style="width:25%">name</td><td><pre style="display:inline-block; margin: 0;">None</pre></td></tr>
+<tr><td style="width:25%">license</td><td><pre style="display:inline-block; margin: 0;">None</pre></td></tr>
+<tr><td style="width:25%">rerandomize</td><td><pre style="display:inline-block; margin: 0;">never</pre></td></tr>
+<tr><td style="width:25%">user_partitions</td><td><pre style="display:inline-block; margin: 0;">[]</pre></td></tr>
+<tr><td style="width:25%">chrome</td><td><pre style="display:inline-block; margin: 0;">None</pre></td></tr>
+<tr><td style="width:25%">download_track</td><td><pre style="display:inline-block; margin: 0;">True</pre></td></tr>
+<tr><td style="width:25%">edxnotes_visibility</td><td><pre style="display:inline-block; margin: 0;">True</pre></td></tr>
+<tr><td style="width:25%">source</td><td><pre style="display:inline-block; margin: 0;"></pre></td></tr>
+<tr><td style="width:25%">transcripts</td><td><pre style="display:inline-block; margin: 0;">{}</pre></td></tr>
+<tr><td style="width:25%">max_attempts</td><td><pre style="display:inline-block; margin: 0;">None</pre></td></tr>
+<tr><td style="width:25%">saved_video_position</td><td><pre style="display:inline-block; margin: 0;">0:00:00</pre></td></tr>
+<tr><td style="width:25%">self_paced</td><td><pre style="display:inline-block; margin: 0;">False</pre></td></tr>
+<tr><td style="width:25%">end_time</td><td><pre style="display:inline-block; margin: 0;">0:00:00</pre></td></tr>
+</table>
+<table>
+<tr><th>XML attributes</th></tr>
+</table>
+category = VideoModuleWithMixins
+</div>
+</div>
+</div>
+
+<div aria-hidden="true" role="dialog" tabindex="-1" class="modal history-modal" id="0b9e39477cf34507a7a48f74be381fdd_history">
+<div class="inner-wrapper">
+<header>
+<h2>Submission History Viewer</h2>
+</header>
+<form id="0b9e39477cf34507a7a48f74be381fdd_history_form">
+<label for="0b9e39477cf34507a7a48f74be381fdd_history_student_username">User:</label>
+<input tabindex="0" id="0b9e39477cf34507a7a48f74be381fdd_history_student_username" type="text" placeholder=""/>
+<input type="hidden" id="0b9e39477cf34507a7a48f74be381fdd_history_location" value="block-v1:edX+DemoX+Demo_Course+type@video+block@0b9e39477cf34507a7a48f74be381fdd"/>
+<div class="submit">
+<button name="submit" type="submit">View History</button>
+</div>
+</form>
+
+<div id="0b9e39477cf34507a7a48f74be381fdd_history_text" class="staff_info" style="display:block">
+</div>
+</div>
+</div>
+
+<div id="0b9e39477cf34507a7a48f74be381fdd_setup"></div>
+
+<script type="text/javascript">
+// assumes courseware.html's loaded this method.
+$(function () {
+setup_debug('0b9e39477cf34507a7a48f74be381fdd',
+null,
+{
+'location': 'block\u002Dv1:edX+DemoX+Demo_Course+type@video+block@0b9e39477cf34507a7a48f74be381fdd',
+'xqa_key': 'qaijS3UatK020Wc0sfCtFe0V6jpB4d64',
+'category': 'VideoModuleWithMixins',
+'user': 'AndyA'
+}
+);
+});
+</script>
+
+</div>
+</div>
+
+</div>
+
+
+
+
+
+
+
+
+
+
Introduction: Video and Sequences
+
+
+
+
+
+
+
+ Bookmark this page
+
+
+
+
+
+
+
+
+
+
+
+
Welcome to the edX Demo Course Introduction. This is where you can explore how to take an edX course (like this one). Most courses have an "intro" video that shows you how it all works.
+
You can watch the introduction video (below) or scroll though the course studies and assignments using the toolbar (above). Just for fun, we'll keep track of your work in this demo course, and show you your progress in the toolbar just like in a real course.
+
Watch the overview video (below), then click on "Example Week One" in the left hand navigation to get started.
+
+
+
+
+
+
+
+ Your Platform Name Here Content Quality Assessment
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Actions
+
+ Username:
+
+
+
+ [
+ Delete Learner's State
+ ]
+
+
+
+
+
+ is_released =
Yes!
+ location = block-v1:edX+DemoX+Demo_Course+type@html+block@030e35c4756a4ddc8d40b95fbbfff4d4
+
+
+ Module Fields
+ visible_to_staff_only False
+ graded False
+ annotation_token_secret xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
+ giturl None
+ edxnotes False
+ source_file None
+ course_edit_method Studio
+ default_tab None
+ in_entrance_exam False
+ showanswer attempted
+ display_name Blank HTML Page
+ video_speed_optimizations True
+ graceperiod 5:00:00
+ format None
+ due None
+ start 1970-01-01 05:00:00+00:00
+ editor visual
+ video_bumper {}
+ max_attempts None
+ parent block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_0270f6de40fc
+ tags []
+ matlab_api_key None
+ xqa_key qaijS3UatK020Wc0sfCtFe0V6jpB4d64
+ annotation_storage_url http://your_annotation_storage.com
+ use_latex_compiler False
+ days_early_for_beta None
+ show_correctness always
+ source_code None
+ data <p><strong>Welcome to the edX Demo Course Introduction.</strong> This is where you can explore how to take an edX course (like this one). Most courses have an "intro" video that shows you how it all works. </p>
+<p style="margin-right: 0px; font-size: 16px; margin-left: 0px; font-family: 'Open Sans', Verdana, Geneva, sans-serif;">You can watch the introduction video (below) or scroll though the course studies and assignments using the toolbar (above). Just for fun, we'll keep track of your work in this demo course, and show you your progress in the toolbar just like in a real course.</p>
+<p style="margin-right: 0px; font-size: 16px; margin-left: 0px; font-family: 'Open Sans', Verdana, Geneva, sans-serif;">Watch the overview video (below), then click on "Example Week One" in the left hand navigation to get started.</p>
+ static_asset_path
+ name None
+ hide_from_toc False
+ group_access {}
+ rerandomize never
+ user_partitions []
+ chrome None
+ edxnotes_visibility True
+ show_reset_button False
+ self_paced False
+
+
+ category = HtmlModuleWithMixins
+
+
+
+
+
+
+
+ Submission History Viewer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Welcome!
+
+
+
+
+
+
+
+
+
+
+ VIDEO
+
No playable video sources found.
+
+ Your browser does not support this video format. Try using a different browser.
+
+
+
+
+
+
+
+
Click on this button to mute or unmute this video or press UP or DOWN buttons to increase or decrease volume level.
Maximum Volume.
HD High Definition off
+
+
+
+
Video transcript
+
+
+
+
Downloads and transcripts
+
+
+
+
+
+
+
+
+
+
+ Your Platform Name Here Content Quality Assessment
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Actions
+
+ Username:
+
+
+
+ [
+ Delete Learner's State
+ ]
+
+
+
+
+
+ is_released =
Yes!
+ location = block-v1:edX+DemoX+Demo_Course+type@video+block@0b9e39477cf34507a7a48f74be381fdd
+
+
+ Module Fields
+ transcript_language en
+ group_access {}
+ graded False
+ annotation_token_secret xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
+ youtube_id_1_25
+ transcript_download_format srt
+ giturl None
+ edxnotes False
+ show_captions True
+ source_file None
+ handout None
+ course_edit_method Studio
+ default_tab None
+ bumper_do_not_show_again False
+ in_entrance_exam False
+ showanswer attempted
+ display_name Welcome!
+ sub name_of_file
+ video_speed_optimizations True
+ graceperiod 5:00:00
+ speed None
+ format None
+ due None
+ edx_video_id
+ start 1970-01-01 05:00:00+00:00
+ youtube_id_1_0 b7xgknqkQk8
+ only_on_web False
+ youtube_id_1_5
+ days_early_for_beta None
+ start_time 0:00:00
+ visible_to_staff_only False
+ download_video True
+ parent block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_0270f6de40fc
+ tags []
+ matlab_api_key None
+ xqa_key qaijS3UatK020Wc0sfCtFe0V6jpB4d64
+ youtube_is_available True
+ html5_sources [u'https://s3.amazonaws.com/edx-course-videos/edx-edx101/EDXSPCPJSP13-H010000_100.mp4']
+ global_speed 1.0
+ annotation_storage_url http://your_annotation_storage.com
+ track
+ use_latex_compiler False
+ video_bumper {}
+ show_correctness always
+ youtube_id_0_75
+ static_asset_path
+ hide_from_toc False
+ bumper_last_view_date None
+ show_reset_button False
+ name None
+ license None
+ rerandomize never
+ user_partitions []
+ chrome None
+ download_track True
+ edxnotes_visibility True
+ source
+ transcripts {}
+ max_attempts None
+ saved_video_position 0:00:00
+ self_paced False
+ end_time 0:00:00
+
+
+ category = VideoModuleWithMixins
+
+
+
+
+
+
+
+ Submission History Viewer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Previous
+
+
+ Next
+
+
+
+
+
+
+
+
+
+
+%block>
diff --git a/lms/urls.py b/lms/urls.py
index 87cda93ceb..2ba2ced7fd 100644
--- a/lms/urls.py
+++ b/lms/urls.py
@@ -998,7 +998,10 @@ if settings.DEBUG:
settings.PROFILE_IMAGE_BACKEND['options']['base_url'],
document_root=settings.PROFILE_IMAGE_BACKEND['options']['location']
)
+ # TODO: re-enable this after removing the URL below
+ # urlpatterns += url(r'^template/(?P.+)$', 'openedx.core.djangoapps.debug.views.show_reference_template')
+# TODO: DO NOT MERGE
urlpatterns += url(r'^template/(?P.+)$', 'openedx.core.djangoapps.debug.views.show_reference_template'),
if 'debug_toolbar' in settings.INSTALLED_APPS:
diff --git a/openedx/core/djangoapps/debug/views.py b/openedx/core/djangoapps/debug/views.py
index 59d8661335..983ecda81a 100644
--- a/openedx/core/djangoapps/debug/views.py
+++ b/openedx/core/djangoapps/debug/views.py
@@ -4,9 +4,15 @@ These views will NOT be shown on production: trying to access them will result
in a 404 error.
"""
from django.http import HttpResponseNotFound
-from mako.exceptions import TopLevelLookupException
-
+from django.utils.translation import ugettext as _
from edxmako.shortcuts import render_to_response
+from mako.exceptions import TopLevelLookupException
+from openedx.core.djangoapps.util.user_messages import (
+ register_error_message,
+ register_info_message,
+ register_success_message,
+ register_warning_message,
+)
def show_reference_template(request, template):
@@ -23,13 +29,22 @@ def show_reference_template(request, template):
"""
try:
uses_bootstrap = u'/bootstrap/' in request.path
- uses_pattern_library = not uses_bootstrap
+ uses_pattern_library = u'/pattern-library/' in request.path
+ is_v1 = u'/v1/' in request.path
context = {
- "disable_courseware_js": True,
+ "disable_courseware_js": not is_v1,
"uses_pattern_library": uses_pattern_library,
"uses_bootstrap": uses_bootstrap,
}
context.update(request.GET.dict())
+
+ # Add some messages to the course skeleton pages
+ if u'course-skeleton.html' in request.path:
+ register_info_message(request, _('This is a test message'))
+ register_success_message(request, _('This is a success message'))
+ register_warning_message(request, _('This is a test warning'))
+ register_error_message(request, _('This is a test error'))
+
return render_to_response(template, context)
except TopLevelLookupException:
return HttpResponseNotFound("Couldn't find template {template}".format(template=template))
diff --git a/openedx/core/djangoapps/util/tests/test_user_messages.py b/openedx/core/djangoapps/util/tests/test_user_messages.py
new file mode 100644
index 0000000000..6be513578c
--- /dev/null
+++ b/openedx/core/djangoapps/util/tests/test_user_messages.py
@@ -0,0 +1,85 @@
+"""
+Unit tests for user messages.
+"""
+
+import ddt
+from unittest import TestCase
+
+from django.contrib.messages.middleware import MessageMiddleware
+from django.test import RequestFactory
+from openedx.core.djangolib.markup import HTML, Text
+from student.tests.factories import UserFactory
+
+from ..user_messages import (
+ register_error_message,
+ register_info_message,
+ register_success_message,
+ register_user_message,
+ register_warning_message,
+ user_messages,
+ UserMessageType,
+)
+
+TEST_MESSAGE = 'Test message'
+
+
+@ddt.ddt
+class UserMessagesTestCase(TestCase):
+ """
+ Unit tests for user messages.
+ """
+ def setUp(self):
+ super(UserMessagesTestCase, self).setUp()
+ self.student = UserFactory.create()
+ self.request = RequestFactory().request()
+ self.request.session = {}
+ self.request.user = self.student
+ MessageMiddleware().process_request(self.request)
+
+ @ddt.data(
+ ('Rock & Roll', 'Rock & Roll'),
+ (Text('Rock & Roll'), 'Rock & Roll'),
+ (HTML('Hello, world!
'), 'Hello, world!
')
+ )
+ @ddt.unpack
+ def test_message_escaping(self, message, expected_message_html):
+ """
+ Verifies that a user message is escaped correctly.
+ """
+ register_user_message(self.request, UserMessageType.INFO, message)
+ messages = list(user_messages(self.request))
+ self.assertEqual(len(messages), 1)
+ self.assertEquals(messages[0].message_html, expected_message_html)
+
+ @ddt.data(
+ (UserMessageType.ERROR, 'alert-danger', 'fa fa-warning'),
+ (UserMessageType.INFO, 'alert-info', 'fa fa-bullhorn'),
+ (UserMessageType.SUCCESS, 'alert-success', 'fa fa-check-circle'),
+ (UserMessageType.WARNING, 'alert-warning', 'fa fa-warning'),
+ )
+ @ddt.unpack
+ def test_message_icon(self, message_type, expected_css_class, expected_icon_class):
+ """
+ Verifies that a user message returns the correct CSS and icon classes.
+ """
+ register_user_message(self.request, message_type, TEST_MESSAGE)
+ messages = list(user_messages(self.request))
+ self.assertEqual(len(messages), 1)
+ self.assertEquals(messages[0].css_class, expected_css_class)
+ self.assertEquals(messages[0].icon_class, expected_icon_class)
+
+ @ddt.data(
+ (register_error_message, UserMessageType.ERROR),
+ (register_info_message, UserMessageType.INFO),
+ (register_success_message, UserMessageType.SUCCESS),
+ (register_warning_message, UserMessageType.WARNING),
+ )
+ @ddt.unpack
+ def test_message_type(self, register_message_function, expected_message_type):
+ """
+ Verifies that each user message function returns the correct type.
+ """
+ register_message_function(self.request, TEST_MESSAGE)
+ messages = list(user_messages(self.request))
+ self.assertEqual(len(messages), 1)
+ self.assertEquals(messages[0].type, expected_message_type)
diff --git a/openedx/core/djangoapps/util/user_messages.py b/openedx/core/djangoapps/util/user_messages.py
new file mode 100644
index 0000000000..251b4e9339
--- /dev/null
+++ b/openedx/core/djangoapps/util/user_messages.py
@@ -0,0 +1,137 @@
+"""
+Support for per-request messages to be shown to the user.
+
+These utilities are based upon the Django message framework, and allow
+code to register messages to be shown to the user on their next page
+view. These messages are shown in a page banner which is supported on
+all pages that utilize the main.html template.
+
+There are two common use cases:
+ - register a message before rendering a view, in which case the message
+ will be shown on the resulting page
+ - register a message before posting or redirecting. In these situations
+ the message will be shown on the subsequent page. This is typically
+ used to show a success message to the use.
+"""
+
+from enum import Enum
+
+from django.contrib import messages
+from openedx.core.djangolib.markup import Text
+
+EDX_USER_MESSAGE_TAG = 'edx-user-message'
+
+
+class UserMessageType(Enum):
+ """
+ An enumeration of the types of user messages.
+ """
+ INFO = messages.constants.INFO
+ SUCCESS = messages.constants.SUCCESS
+ WARNING = messages.constants.WARNING
+ ERROR = messages.constants.ERROR
+
+
+CSS_CLASSES = {
+ UserMessageType.INFO: 'alert-info',
+ UserMessageType.SUCCESS: 'alert-success',
+ UserMessageType.WARNING: 'alert-warning',
+ UserMessageType.ERROR: 'alert-danger',
+}
+
+ICON_CLASSES = {
+ UserMessageType.INFO: 'fa fa-bullhorn',
+ UserMessageType.SUCCESS: 'fa fa-check-circle',
+ UserMessageType.WARNING: 'fa fa-warning',
+ UserMessageType.ERROR: 'fa fa-warning',
+}
+
+
+class UserMessage():
+ """
+ Representation of a message to be shown to a user
+ """
+ def __init__(self, type, message_html):
+ assert isinstance(type, UserMessageType)
+ self.type = type
+ self.message_html = message_html
+
+ @property
+ def css_class(self):
+ """
+ Returns the CSS class to be used on the message element.
+ """
+ return CSS_CLASSES[self.type]
+
+ @property
+ def icon_class(self):
+ """
+ Returns the CSS icon class representing the message type.
+ Returns:
+ """
+ return ICON_CLASSES[self.type]
+
+
+def register_user_message(request, message_type, message, title=None):
+ """
+ Register a message to be shown to the user in the next page.
+ """
+ assert isinstance(message_type, UserMessageType)
+ messages.add_message(request, message_type.value, Text(message), extra_tags=EDX_USER_MESSAGE_TAG)
+
+
+def register_info_message(request, message, **kwargs):
+ """
+ Registers an information message to be shown to the user.
+ """
+ register_user_message(request, UserMessageType.INFO, message, **kwargs)
+
+
+def register_success_message(request, message, **kwargs):
+ """
+ Registers a success message to be shown to the user.
+ """
+ register_user_message(request, UserMessageType.SUCCESS, message, **kwargs)
+
+
+def register_warning_message(request, message, **kwargs):
+ """
+ Registers a warning message to be shown to the user.
+ """
+ register_user_message(request, UserMessageType.WARNING, message, **kwargs)
+
+
+def register_error_message(request, message, **kwargs):
+ """
+ Registers an error message to be shown to the user.
+ """
+ register_user_message(request, UserMessageType.ERROR, message, **kwargs)
+
+
+def user_messages(request):
+ """
+ Returns any outstanding user messages.
+
+ Note: this function also marks these messages as being complete
+ so they won't be returned in the next request.
+ """
+ def _get_message_type_for_level(level):
+ """
+ Returns the user message type associated with a level.
+ """
+ for __, type in UserMessageType.__members__.items():
+ if type.value is level:
+ return type
+ raise 'Unable to find UserMessageType for level {level}'.format(level=level)
+
+ def _create_user_message(message):
+ """
+ Creates a user message from a Django message.
+ """
+ return UserMessage(
+ type=_get_message_type_for_level(message.level),
+ message_html=unicode(message.message),
+ )
+
+ django_messages = messages.get_messages(request)
+ return (_create_user_message(message) for message in django_messages if EDX_USER_MESSAGE_TAG in message.tags)