From 8acc72975e95b80678a0422cdc97fb3510ce4286 Mon Sep 17 00:00:00 2001 From: Marco Morales Date: Wed, 20 May 2015 08:31:33 -0400 Subject: [PATCH 1/2] Iniital refactor of capa styling for basic checkbox and multiple choice problem types, including additional comments to sass styles --- .../lib/capa/capa/templates/choicegroup.html | 37 +- .../lib/capa/capa/templates/choicetext.html | 14 +- .../capa/templates/formulaequationinput.html | 8 +- .../lib/capa/capa/templates/optioninput.html | 13 +- common/lib/capa/capa/templates/textline.html | 22 +- .../capa/capa/tests/test_input_templates.py | 4 +- .../lib/xmodule/xmodule/css/capa/display.scss | 388 ++++++++++++++---- .../xmodule/js/src/capa/display.coffee | 4 +- common/static/sass/_mixins.scss | 9 + .../courseware/features/problems.feature | 8 +- lms/static/sass/base/_variables.scss | 22 + lms/static/sass/course/base/_extends.scss | 2 +- 12 files changed, 391 insertions(+), 140 deletions(-) diff --git a/common/lib/capa/capa/templates/choicegroup.html b/common/lib/capa/capa/templates/choicegroup.html index 814fae6594..6a27a3df4f 100644 --- a/common/lib/capa/capa/templates/choicegroup.html +++ b/common/lib/capa/capa/templates/choicegroup.html @@ -1,24 +1,5 @@
-
- % if input_type == 'checkbox' or not value: - - - %for choice_id, choice_description in choices: - % if choice_id in value: - ${choice_description}, - %endif - %endfor - - - ${status.display_name} - - - % endif -
-
- % for choice_id, choice_description in choices:
- +
+ % if input_type == 'checkbox' or not value: + + + %for choice_id, choice_description in choices: + % if choice_id in value: + ${choice_description}, + %endif + %endfor + - + ${status.display_name} + + + % endif +
% if show_correctness == "never" and (value or status not in ['unsubmitted']):
${submitted_message}
%endif diff --git a/common/lib/capa/capa/templates/choicetext.html b/common/lib/capa/capa/templates/choicetext.html index 91a894dd4f..e370f10594 100644 --- a/common/lib/capa/capa/templates/choicetext.html +++ b/common/lib/capa/capa/templates/choicetext.html @@ -9,12 +9,7 @@
-
- % if input_type == 'checkbox' or not element_checked: - - % endif -
- +
% for choice_id, choice_description in choices: <%choice_id= choice_id %> @@ -62,6 +57,13 @@
+ +
+ % if input_type == 'checkbox' or not element_checked: + + % endif +
+ % if show_correctness == "never" and (value or status not in ['unsubmitted']):
${_(submitted_message)}
%endif diff --git a/common/lib/capa/capa/templates/formulaequationinput.html b/common/lib/capa/capa/templates/formulaequationinput.html index de56fd5098..04b4f8e965 100644 --- a/common/lib/capa/capa/templates/formulaequationinput.html +++ b/common/lib/capa/capa/templates/formulaequationinput.html @@ -10,9 +10,11 @@ % endif /> -

- ${status.display_name} -

+ + + ${status.display_name} + +
\[\] diff --git a/common/lib/capa/capa/templates/optioninput.html b/common/lib/capa/capa/templates/optioninput.html index f804e771cc..65965597b7 100644 --- a/common/lib/capa/capa/templates/optioninput.html +++ b/common/lib/capa/capa/templates/optioninput.html @@ -13,12 +13,13 @@ - - ${value|h} - ${status.display_name} - - +
+ + ${value|h} - ${status.display_name} + +
% if msg: ${msg|n} % endif diff --git a/common/lib/capa/capa/templates/textline.html b/common/lib/capa/capa/templates/textline.html index 8a9826b0a5..ed006240ca 100644 --- a/common/lib/capa/capa/templates/textline.html +++ b/common/lib/capa/capa/templates/textline.html @@ -27,18 +27,20 @@ /> ${trailing_text | h} -

- %if value: - ${value|h} - % else: - ${label} - %endif - - - ${status.display_name} -

+ aria-describedby="input_${id}" data-tooltip="This is ${status.display_name}."> + + %if value: + ${value|h} + % else: + ${label} + %endif + - + ${status.display_name} + +

diff --git a/common/lib/capa/capa/tests/test_input_templates.py b/common/lib/capa/capa/tests/test_input_templates.py index 09ae25476d..4bed5e88c7 100644 --- a/common/lib/capa/capa/tests/test_input_templates.py +++ b/common/lib/capa/capa/tests/test_input_templates.py @@ -388,9 +388,9 @@ class TextlineTemplateTest(TemplateTestCase): xpath = "//div[@class='%s ']" % div_class self.assert_has_xpath(xml, xpath, self.context) - # Expect that we get a

with class="status" + # Expect that we get a with class="status" # (used to by CSS to draw the green check / red x) - self.assert_has_text(xml, "//p[@class='status']", + self.assert_has_text(xml, "//span[@class='status']", status_mark, exact=False) def test_label(self): diff --git a/common/lib/xmodule/xmodule/css/capa/display.scss b/common/lib/xmodule/xmodule/css/capa/display.scss index 727630b79b..c8d5f7787f 100644 --- a/common/lib/xmodule/xmodule/css/capa/display.scss +++ b/common/lib/xmodule/xmodule/css/capa/display.scss @@ -1,8 +1,54 @@ +// capa - styling +// ==================== + +// Table of Contents +// * +Variables - Capa +// * +Extends - Capa +// * +Mixins - Status Icon - Capa +// * +Resets - Deprecate Please +// * +Problem - Base +// * +Problem - Choice Group +// * +Problem - Misc, Unclassified Mess +// * +Problem - Text Input, Numerical Input +// * +Problem - Option Input (Dropdown) +// * +Problem - CodeMirror +// * +Problem - Misc, Unclassified Mess Part 2 +// * +Problem - Rubric +// * +Problem - Annotation +// * +Problem - Choice Text Group + +// +Variables - Capa +// ==================== $annotation-yellow: rgba(255,255,10,0.3); $color-copy-tip: rgb(100,100,100); -$color-success: rgb(0, 136, 1); -$color-fail: rgb(212, 64, 64); +$correct: $green-d1; +$incorrect: $red; +// +Extends - Capa +// ==================== +// Duplicated from _mixins.scss due to xmodule compilation, inheritance issues +%use-font-awesome { + font-family: FontAwesome; + -webkit-font-smoothing: antialiased; + display: inline-block; + speak: none; +} + +// +Mixins - Status Icon - Capa +// ==================== +@mixin status-icon($color: $gray, $fontAwesomeIcon: "\f00d"){ + + &:after { + @extend %use-font-awesome; + @include margin-left(17px); + color: $color; + font-size: 1.2em; + content: $fontAwesomeIcon; + } +} + +// +Resets - Deprecate Please +// ==================== h2 { margin-top: 0; margin-bottom: ($baseline*0.75); @@ -24,12 +70,12 @@ h2 { .feedback-hint-correct { margin-top: ($baseline/2); - color: $color-success; + color: $correct; } .feedback-hint-incorrect { margin-top: ($baseline/2); - color: $color-fail; + color: $incorrect; } .feedback-hint-text { @@ -55,10 +101,9 @@ h2 { display: block; } - iframe[seamless]{ overflow: hidden; - padding: 0px; + padding: 0; border: 0px none transparent; background-color: transparent; } @@ -68,13 +113,15 @@ iframe[seamless]{ } div.problem-progress { + @include padding-left($baseline/4); display: inline-block; - padding-left: ($baseline/4); - color: #666; + color: $gray-d1; font-weight: 100; font-size: em(16); } +// +Problem - Base +// ==================== div.problem { @media print { display: block; @@ -89,7 +136,11 @@ div.problem { .inline { display: inline; } +} +// +Problem - Choice Group +// ==================== +div.problem { .choicegroup { @include clearfix(); min-width: 100px; @@ -97,51 +148,100 @@ div.problem { width: 100px; label { - @include float(left); + @include box-sizing(border-box); + display: inline-block; clear: both; - margin-bottom: ($baseline/4); + width: 100%; + border: 2px solid $gray-l4; + border-radius: 3px; + margin-bottom: ($baseline/2); + padding: ($baseline/2); &.choicegroup_correct { - &:after { - margin-left: ($baseline*0.75); - content: url('../images/correct-icon.png'); + @include status-icon($correct, "\f00c"); + border: 2px solid $correct; + + // keep green for correct answers on hover. + &:hover { + border-color: $correct; } } &.choicegroup_incorrect { - &:after { - margin-left: ($baseline*0.75); - content: url('../images/incorrect-icon.png'); + @include status-icon($incorrect, "\f00d"); + border: 2px solid $incorrect; + + // keep red for incorrect answers on hover. + &:hover { + border-color: $incorrect; } } + + &:hover { + border: 2px solid $blue; + } } .indicator_container { - @include float(left); + display: inline-block; + min-height: 1px; width: 25px; - height: 1px; - @include margin-right(15px); } fieldset { @include box-sizing(border-box); - margin: 0px 0px $baseline; - @include padding-left($baseline); - @include border-left(1px solid #ddd); } input[type="radio"], input[type="checkbox"] { - @include float(left); - @include margin(4px, 8px, 0, 0); + @include margin(($baseline/4) ($baseline/2) ($baseline/4) ($baseline/4)); } text { + @include margin-left(25px); display: inline; - margin-left: 25px; } } +} +// +Problem - Status Indicators +// ==================== +// Summary status indicators shown after the input area +div.problem { + + .indicator_container { + + .status { + width: 20px; + height: 20px; + + // CASE: correct answer + &.correct { + @include status-icon($correct, "\f00c"); + } + + // CASE: incorrect answer + &.incorrect { + @include status-icon($incorrect, "\f00d"); + } + + // CASE: unanswered + &.unanswered { + @include status-icon($gray-l4, "\f128"); + } + + // CASE: processing + &.processing { + // add once spinner is rotated through animations + //@include status-icon($gray-d1, "\f110", 0); + } + } + } +} + +// +Problem - Misc, Unclassified Mess +// ==================== +div.problem { ol.enumerate { li { &:before { @@ -187,17 +287,22 @@ div.problem { } } + // known classes using this div: .indicator_container, moved to section above div { + + // TO-DO: Styling used by advanced capa problem types. Should be synced up to use .status class p { &.answer { margin-top: -2px; } + &.status { - margin: 8px 0 0 $baseline/2; + @include margin(8px, 0, 0, $baseline/2); text-indent: 100%; white-space: nowrap; overflow: hidden; } + span.clarification i { font-style: normal; &:hover { @@ -241,7 +346,21 @@ div.problem { } } - &.incorrect, &.incomplete, &.ui-icon-close { + &.ui-icon-close { + p.status { + display: inline-block; + width: 20px; + height: 20px; + background: url('../images/incorrect-icon.png') center center no-repeat; + } + + input { + border-color: red; + } + } + + &.incorrect, &.incomplete { + p.status { display: inline-block; width: 20px; @@ -260,9 +379,9 @@ div.problem { } p.answer { + @include margin-left($baseline/2); display: inline-block; margin-bottom: 0; - margin-left: $baseline/2; &:before { display: inline; @@ -287,8 +406,8 @@ div.problem { } img.loading { + @include padding-left($baseline/2); display: inline-block; - padding-left: ($baseline/2); } span { @@ -303,7 +422,7 @@ div.problem { background: #f1f1f1; } } - } + } // Hides equation previews in symbolic response problems when printing [id^='display'].equation { @@ -312,8 +431,9 @@ div.problem { } } + //TO-DO: review and deprecate all these styles within span {} span { - &.unanswered, &.ui-icon-bullet { + &.ui-icon-bullet { display: inline-block; position: relative; top: 4px; @@ -331,7 +451,7 @@ div.problem { background: url('../images/spinner.gif') center center no-repeat; } - &.correct, &.ui-icon-check { + &.ui-icon-check { display: inline-block; position: relative; top: 3px; @@ -349,7 +469,7 @@ div.problem { background: url('../images/partially-correct-icon.png') center center no-repeat; } - &.incorrect, &.incomplete, &.ui-icon-close { + &.incomplete, &.ui-icon-close { display: inline-block; position: relative; top: 3px; @@ -360,8 +480,8 @@ div.problem { } .reload { - float:right; - margin: $baseline/2; + @include float(right); + margin: ($baseline/2); } @@ -457,15 +577,6 @@ div.problem { } } - form.option-input { - margin: -$baseline/2 0 $baseline; - padding-bottom: $baseline; - - select { - margin-right: flex-gutter(); - } - } - ul { margin-bottom: lh(); margin-left: .75em; @@ -584,6 +695,93 @@ div.problem { white-space: pre; } } +} + +// +Problem - Text Input, Numerical Input +// ==================== +.problem { + .capa_inputtype.textline, .inputtype.formulaequationinput { + + input { + @include box-sizing(border-box); + border: 2px solid $gray-l4; + border-radius: 3px; + height: 46px; + min-width: 160px; + } + + > .incorrect, .correct, .unanswered { + + .status { + display: inline-block; + background: none; + margin-top: ($baseline/2); + } + } + + // CASE: incorrect answer + > .incorrect { + + input { + border: 2px solid $incorrect; + } + + .status { + @include status-icon($incorrect, "\f00d"); + } + } + + // CASE: correct answer + > .correct { + + input { + border: 2px solid $correct; + } + + .status { + @include status-icon($correct, "\f00c"); + } + } + + // CASE: unanswered + > .unanswered { + + input { + border: 2px solid $gray-l4; + } + + .status { + @include status-icon($gray-l4, "\f128"); + } + } + } +} + + +// +Problem - Option Input (Dropdown) +// ==================== +.problem { + .inputtype.option-input { + margin: (-$baseline/2) 0 $baseline; + padding-bottom: $baseline; + + select { + @include margin-right($baseline/2); + } + + .indicator_container { + display: inline-block; + + .status.correct:after, .status.incorrect:after { + @include margin-left(0); + } + } + } +} + +// +Problem - CodeMirror +// ==================== +div.problem { .CodeMirror { border: 1px solid black; @@ -634,7 +832,52 @@ div.problem { .CodeMirror-scroll { margin-right: 0px; } +} +// +Problem - Actions +// ==================== +div.problem .action { + margin-top: $baseline; + + .save, .check, .show, .reset, .hint-button { + @include margin-right($baseline/2); + margin-bottom: ($baseline/2); + height: ($baseline*2); + vertical-align: middle; + font-weight: 600; + text-transform: uppercase; + } + + .save { + @extend .blue-button !optional; + } + + .show { + + .show-label { + font-weight: 600; + font-size: 1.0em; + } + } + + .submission_feedback { + // background: #F3F3F3; + // border: 1px solid #ddd; + // border-radius: 3px; + // padding: 8px 12px; + // margin-top: ($baseline/2); + display: inline-block; + margin-top: 8px; + @include margin-left($baseline/2); + color: $gray-d1; + font-style: italic; + -webkit-font-smoothing: antialiased; + } +} + +// +Problem - Misc, Unclassified Mess Part 2 +// ==================== +div.problem { hr { float: none; clear: both; @@ -663,47 +906,7 @@ div.problem { padding: lh(); border: 1px solid $gray-l3; } - - div.action { - margin-top: $baseline; - - .save, .check, .show, .reset, .hint-button { - height: ($baseline*2); - vertical-align: middle; - font-weight: 600; - - @media print { - display: none; - } - } - - .save { - @extend .blue-button !optional; - } - - .show { - - .show-label { - font-weight: 600; - font-size: 1.0em; - } - } - - .submission_feedback { - // background: #F3F3F3; - // border: 1px solid #ddd; - // border-radius: 3px; - // padding: 8px 12px; - // margin-top: ($baseline/2); - display: inline-block; - margin-top: 8px; - @include margin-left($baseline/2); - color: #666; - font-style: italic; - -webkit-font-smoothing: antialiased; - } - } - + .detailed-solution { > p:first-child { color: #aaa; @@ -951,7 +1154,12 @@ div.problem { } } } +} + +// +Problem - Rubric +// ==================== +div.problem { .rubric { tr { margin: ($baseline/2) 0; @@ -1004,7 +1212,11 @@ div.problem { display: none; } } +} +// +Problem - Annotation +// ==================== +div.problem { .annotation-input { margin: 0 0 1em 0; border: 1px solid $gray-l3; @@ -1102,8 +1314,12 @@ div.problem { } } } +} - .choicetextgroup{ +// +Problem - Choice Text Group +// ==================== +div.problem { + .choicetextgroup { @extend .choicegroup; input[type="text"]{ diff --git a/common/lib/xmodule/xmodule/js/src/capa/display.coffee b/common/lib/xmodule/xmodule/js/src/capa/display.coffee index 139654e5e5..f5e6c1baa0 100644 --- a/common/lib/xmodule/xmodule/js/src/capa/display.coffee +++ b/common/lib/xmodule/xmodule/js/src/capa/display.coffee @@ -468,7 +468,7 @@ class @Problem # They should set handlers on each to reset the whole. formulaequationinput: (element) -> $(element).find('input').on 'input', -> - $p = $(element).find('p.status') + $p = $(element).find('span.status') `// Translators: the word unanswered here is about answering a problem the student must solve.` $p.parent().removeClass().addClass "unanswered" @@ -496,7 +496,7 @@ class @Problem textline: (element) -> $(element).find('input').on 'input', -> - $p = $(element).find('p.status') + $p = $(element).find('span.status') `// Translators: the word unanswered here is about answering a problem the student must solve.` $p.parent().removeClass("correct incorrect").addClass "unanswered" diff --git a/common/static/sass/_mixins.scss b/common/static/sass/_mixins.scss index b86ac1e2bd..6e702fdff6 100644 --- a/common/static/sass/_mixins.scss +++ b/common/static/sass/_mixins.scss @@ -23,6 +23,7 @@ // * +Content - Screenreader Text - Extend // * +Content - Text Wrap - Extend // * +Content - Text Truncate - Extend +// * +Icon - Font-Awesome - Extend // +Font Sizing - Mixin // ==================== @@ -428,3 +429,11 @@ text-overflow: ellipsis; } +// * +Icon - Font-Awesome - Extend +// ==================== +%use-font-awesome { + font-family: FontAwesome; + -webkit-font-smoothing: antialiased; + display: inline-block; + speak: none; +} diff --git a/lms/djangoapps/courseware/features/problems.feature b/lms/djangoapps/courseware/features/problems.feature index b1e0359f62..58c0e90040 100644 --- a/lms/djangoapps/courseware/features/problems.feature +++ b/lms/djangoapps/courseware/features/problems.feature @@ -176,11 +176,11 @@ Feature: LMS.Answer problems Scenario: I can view and hide the answer if the problem has it: Given I am viewing a "numerical" that shows the answer "always" - When I press the button with the label "Show Answer" - Then the Show/Hide button label is "Hide Answer" + When I press the button with the label "SHOW ANSWER" + Then the Show/Hide button label is "HIDE ANSWER" And I should see "4.14159" somewhere in the page - When I press the button with the label "Hide Answer" - Then the Show/Hide button label is "Show Answer" + When I press the button with the label "HIDE ANSWER" + Then the Show/Hide button label is "SHOW ANSWER" And I should not see "4.14159" anywhere on the page Scenario: I can see my score on a problem when I answer it and after I reset it diff --git a/lms/static/sass/base/_variables.scss b/lms/static/sass/base/_variables.scss index a057789f27..5b1197c3ef 100644 --- a/lms/static/sass/base/_variables.scss +++ b/lms/static/sass/base/_variables.scss @@ -82,6 +82,28 @@ $gray-d2: shade($gray,40%); // #4c4c4c $gray-d3: shade($gray,60%); // #323232 $gray-d4: shade($gray,80%); // #191919 +// TO-DO: once existing lms $blue is removed, change $cms-blue to $blue. +$cms-blue: rgb(0, 159, 230); +$blue-l1: tint($cms-blue,20%); +$blue-l2: tint($cms-blue,40%); +$blue-l3: tint($cms-blue,60%); +$blue-l4: tint($cms-blue,80%); +$blue-l5: tint($cms-blue,90%); +$blue-d1: shade($cms-blue,20%); +$blue-d2: shade($cms-blue,40%); +$blue-d3: shade($cms-blue,60%); +$blue-d4: shade($cms-blue,80%); +$blue-s1: saturate($cms-blue,15%); +$blue-s2: saturate($cms-blue,30%); +$blue-s3: saturate($cms-blue,45%); +$blue-u1: desaturate($cms-blue,15%); +$blue-u2: desaturate($cms-blue,30%); +$blue-u3: desaturate($cms-blue,45%); +$blue-t0: rgba($cms-blue, 0.125); +$blue-t1: rgba($cms-blue, 0.25); +$blue-t2: rgba($cms-blue, 0.50); +$blue-t3: rgba($cms-blue, 0.75); + $pink: rgb(182,37,103); // #b72567; $pink-l1: tint($pink,20%); $pink-l2: tint($pink,40%); diff --git a/lms/static/sass/course/base/_extends.scss b/lms/static/sass/course/base/_extends.scss index cac78034be..19e065f31f 100644 --- a/lms/static/sass/course/base/_extends.scss +++ b/lms/static/sass/course/base/_extends.scss @@ -28,7 +28,7 @@ h1.top-header { .light-button, a.light-button, // only used in askbot as classes .gray-button { - @include button(simple, #eee); + @include button(simple, $gray-l5); @extend .button-reset; font-size: em(13); } From aa5e2f49bd58ba5d5e066f0db2a47bf6ebc5e912 Mon Sep 17 00:00:00 2001 From: Kyle McCormick Date: Thu, 4 Jun 2015 16:44:08 -0400 Subject: [PATCH 2/2] Fixes tests, adds internationalized strings for new state tooltips, corrected tooltip javascript, etc. --- cms/templates/ux/reference/container.html | 2 +- common/lib/capa/capa/inputtypes.py | 13 +++- .../lib/capa/capa/templates/choicegroup.html | 6 +- .../lib/capa/capa/templates/choicetext.html | 2 +- .../capa/templates/formulaequationinput.html | 2 +- .../lib/capa/capa/templates/optioninput.html | 4 +- common/lib/capa/capa/templates/textline.html | 2 +- .../capa/capa/tests/test_input_templates.py | 26 ++++---- .../lib/xmodule/xmodule/css/capa/display.scss | 64 +++++++++---------- .../xmodule/js/spec/capa/display_spec.coffee | 2 +- .../xmodule/js/src/capa/display.coffee | 4 +- common/static/sass/_mixins.scss | 2 +- common/test/acceptance/pages/lms/problem.py | 2 +- .../courseware/features/problems_setup.py | 8 +-- lms/static/sass/base/_variables.scss | 22 ------- test_root/db/test_edx.db-journal | 0 16 files changed, 73 insertions(+), 88 deletions(-) create mode 100644 test_root/db/test_edx.db-journal diff --git a/cms/templates/ux/reference/container.html b/cms/templates/ux/reference/container.html index 81821b503a..19ab1db780 100644 --- a/cms/templates/ux/reference/container.html +++ b/cms/templates/ux/reference/container.html @@ -351,7 +351,7 @@

What Apple device competed with the portable CD player?

-
+
diff --git a/common/lib/capa/capa/inputtypes.py b/common/lib/capa/capa/inputtypes.py index f4ea46932d..c487efed69 100644 --- a/common/lib/capa/capa/inputtypes.py +++ b/common/lib/capa/capa/inputtypes.py @@ -69,7 +69,7 @@ registry = TagRegistry() # pylint: disable=invalid-name class Status(object): """ Problem status - attributes: classname, display_name + attributes: classname, display_name, display_tooltip """ css_classes = { # status: css class @@ -77,7 +77,7 @@ class Status(object): 'incomplete': 'incorrect', 'queued': 'processing', } - __slots__ = ('classname', '_status', 'display_name') + __slots__ = ('classname', '_status', 'display_name', 'display_tooltip') def __init__(self, status, gettext_func=unicode): self.classname = self.css_classes.get(status, status) @@ -90,7 +90,16 @@ class Status(object): 'unsubmitted': _('unanswered'), 'queued': _('processing'), } + tooltips = { + # Translators: these are tooltips that indicate the state of an assessment question + 'correct': _('This is correct.'), + 'incorrect': _('This is incorrect.'), + 'unanswered': _('This is unanswered.'), + 'unsubmitted': _('This is unanswered.'), + 'queued': _('This is being processed.'), + } self.display_name = names.get(status, unicode(status)) + self.display_tooltip = tooltips.get(status, u'') self._status = status or '' def __str__(self): diff --git a/common/lib/capa/capa/templates/choicegroup.html b/common/lib/capa/capa/templates/choicegroup.html index 6a27a3df4f..da5d372401 100644 --- a/common/lib/capa/capa/templates/choicegroup.html +++ b/common/lib/capa/capa/templates/choicegroup.html @@ -39,11 +39,9 @@ % endfor -
+
% if input_type == 'checkbox' or not value: - + %for choice_id, choice_description in choices: % if choice_id in value: diff --git a/common/lib/capa/capa/templates/choicetext.html b/common/lib/capa/capa/templates/choicetext.html index e370f10594..448205c2aa 100644 --- a/common/lib/capa/capa/templates/choicetext.html +++ b/common/lib/capa/capa/templates/choicetext.html @@ -58,7 +58,7 @@ -
+
% if input_type == 'checkbox' or not element_checked: % endif diff --git a/common/lib/capa/capa/templates/formulaequationinput.html b/common/lib/capa/capa/templates/formulaequationinput.html index 04b4f8e965..206a8bc21c 100644 --- a/common/lib/capa/capa/templates/formulaequationinput.html +++ b/common/lib/capa/capa/templates/formulaequationinput.html @@ -10,7 +10,7 @@ % endif /> - + ${status.display_name} diff --git a/common/lib/capa/capa/templates/optioninput.html b/common/lib/capa/capa/templates/optioninput.html index 65965597b7..a4f25d801b 100644 --- a/common/lib/capa/capa/templates/optioninput.html +++ b/common/lib/capa/capa/templates/optioninput.html @@ -13,10 +13,10 @@ -
+
+ aria-describedby="input_${id}" data-tooltip="${status.display_tooltip}"> ${value|h} - ${status.display_name}
diff --git a/common/lib/capa/capa/templates/textline.html b/common/lib/capa/capa/templates/textline.html index ed006240ca..b37fb0d67e 100644 --- a/common/lib/capa/capa/templates/textline.html +++ b/common/lib/capa/capa/templates/textline.html @@ -30,7 +30,7 @@ + aria-describedby="input_${id}" data-tooltip="${status.display_tooltip}"> %if value: ${value|h} diff --git a/common/lib/capa/capa/tests/test_input_templates.py b/common/lib/capa/capa/tests/test_input_templates.py index 4bed5e88c7..5af21fd5e2 100644 --- a/common/lib/capa/capa/tests/test_input_templates.py +++ b/common/lib/capa/capa/tests/test_input_templates.py @@ -144,7 +144,7 @@ class ChoiceGroupTemplateTest(TemplateTestCase): # Should mark the entire problem correct xml = self.render_to_xml(self.context) - xpath = "//div[@class='indicator_container']/span[@class='status correct']" + xpath = "//div[@class='indicator-container']/span[@class='status correct']" self.assert_has_xpath(xml, xpath, self.context) # Should NOT mark individual options @@ -172,7 +172,7 @@ class ChoiceGroupTemplateTest(TemplateTestCase): for test_conditions in conditions: self.context.update(test_conditions) xml = self.render_to_xml(self.context) - xpath = "//div[@class='indicator_container']/span[@class='status incorrect']" + xpath = "//div[@class='indicator-container']/span[@class='status incorrect']" self.assert_has_xpath(xml, xpath, self.context) # Should NOT mark individual options @@ -204,7 +204,7 @@ class ChoiceGroupTemplateTest(TemplateTestCase): for test_conditions in conditions: self.context.update(test_conditions) xml = self.render_to_xml(self.context) - xpath = "//div[@class='indicator_container']/span[@class='status unanswered']" + xpath = "//div[@class='indicator-container']/span[@class='status unanswered']" self.assert_has_xpath(xml, xpath, self.context) # Should NOT mark individual options @@ -234,7 +234,7 @@ class ChoiceGroupTemplateTest(TemplateTestCase): self.assert_has_xpath(xml, xpath, self.context) # Should NOT mark the whole problem - xpath = "//div[@class='indicator_container']/span" + xpath = "//div[@class='indicator-container']/span" self.assert_no_xpath(xml, xpath, self.context) def test_option_marked_incorrect(self): @@ -255,7 +255,7 @@ class ChoiceGroupTemplateTest(TemplateTestCase): self.assert_has_xpath(xml, xpath, self.context) # Should NOT mark the whole problem - xpath = "//div[@class='indicator_container']/span" + xpath = "//div[@class='indicator-container']/span" self.assert_no_xpath(xml, xpath, self.context) def test_never_show_correctness(self): @@ -289,10 +289,10 @@ class ChoiceGroupTemplateTest(TemplateTestCase): xml = self.render_to_xml(self.context) # Should NOT mark the entire problem correct/incorrect - xpath = "//div[@class='indicator_container']/span[@class='status correct']" + xpath = "//div[@class='indicator-container']/span[@class='status correct']" self.assert_no_xpath(xml, xpath, self.context) - xpath = "//div[@class='indicator_container']/span[@class='status incorrect']" + xpath = "//div[@class='indicator-container']/span[@class='status incorrect']" self.assert_no_xpath(xml, xpath, self.context) # Should NOT mark individual options @@ -390,7 +390,7 @@ class TextlineTemplateTest(TemplateTestCase): # Expect that we get a with class="status" # (used to by CSS to draw the green check / red x) - self.assert_has_text(xml, "//span[@class='status']", + self.assert_has_text(xml, "//span[@class='status']/span[@class='sr']", status_mark, exact=False) def test_label(self): @@ -848,7 +848,7 @@ class ChoiceTextGroupTemplateTest(TemplateTestCase): # Should mark the entire problem correct xml = self.render_to_xml(self.context) - xpath = "//div[@class='indicator_container']/span[@class='status correct']" + xpath = "//div[@class='indicator-container']/span[@class='status correct']" self.assert_has_xpath(xml, xpath, self.context) # Should NOT mark individual options @@ -875,7 +875,7 @@ class ChoiceTextGroupTemplateTest(TemplateTestCase): for test_conditions in conditions: self.context.update(test_conditions) xml = self.render_to_xml(self.context) - xpath = "//div[@class='indicator_container']/span[@class='status incorrect']" + xpath = "//div[@class='indicator-container']/span[@class='status incorrect']" self.assert_has_xpath(xml, xpath, self.context) # Should NOT mark individual options @@ -907,7 +907,7 @@ class ChoiceTextGroupTemplateTest(TemplateTestCase): for test_conditions in conditions: self.context.update(test_conditions) xml = self.render_to_xml(self.context) - xpath = "//div[@class='indicator_container']/span[@class='status unanswered']" + xpath = "//div[@class='indicator-container']/span[@class='status unanswered']" self.assert_has_xpath(xml, xpath, self.context) # Should NOT mark individual options @@ -937,7 +937,7 @@ class ChoiceTextGroupTemplateTest(TemplateTestCase): self.assert_has_xpath(xml, xpath, self.context) # Should NOT mark the whole problem - xpath = "//div[@class='indicator_container']/span" + xpath = "//div[@class='indicator-container']/span" self.assert_no_xpath(xml, xpath, self.context) def test_option_marked_incorrect(self): @@ -957,7 +957,7 @@ class ChoiceTextGroupTemplateTest(TemplateTestCase): self.assert_has_xpath(xml, xpath, self.context) # Should NOT mark the whole problem - xpath = "//div[@class='indicator_container']/span" + xpath = "//div[@class='indicator-container']/span" self.assert_no_xpath(xml, xpath, self.context) def test_label(self): diff --git a/common/lib/xmodule/xmodule/css/capa/display.scss b/common/lib/xmodule/xmodule/css/capa/display.scss index c8d5f7787f..02e4b45ebf 100644 --- a/common/lib/xmodule/xmodule/css/capa/display.scss +++ b/common/lib/xmodule/xmodule/css/capa/display.scss @@ -114,6 +114,7 @@ iframe[seamless]{ div.problem-progress { @include padding-left($baseline/4); + @extend %t-ultralight; display: inline-block; color: $gray-d1; font-weight: 100; @@ -151,11 +152,11 @@ div.problem { @include box-sizing(border-box); display: inline-block; clear: both; - width: 100%; + margin-bottom: ($baseline/2); border: 2px solid $gray-l4; border-radius: 3px; - margin-bottom: ($baseline/2); padding: ($baseline/2); + width: 100%; &.choicegroup_correct { @include status-icon($correct, "\f00c"); @@ -182,7 +183,7 @@ div.problem { } } - .indicator_container { + .indicator-container { display: inline-block; min-height: 1px; width: 25px; @@ -209,11 +210,11 @@ div.problem { // Summary status indicators shown after the input area div.problem { - .indicator_container { + .indicator-container { .status { - width: 20px; - height: 20px; + width: $baseline; + height: $baseline; // CASE: correct answer &.correct { @@ -232,8 +233,6 @@ div.problem { // CASE: processing &.processing { - // add once spinner is rotated through animations - //@include status-icon($gray-d1, "\f110", 0); } } } @@ -287,7 +286,7 @@ div.problem { } } - // known classes using this div: .indicator_container, moved to section above + // known classes using this div: .indicator-container, moved to section above div { // TO-DO: Styling used by advanced capa problem types. Should be synced up to use .status class @@ -297,7 +296,7 @@ div.problem { } &.status { - @include margin(8px, 0, 0, $baseline/2); + @include margin(8px, 0, 0, ($baseline/2)); text-indent: 100%; white-space: nowrap; overflow: hidden; @@ -329,7 +328,7 @@ div.problem { } input { - border-color: green; + border-color: $correct; } } @@ -355,7 +354,7 @@ div.problem { } input { - border-color: red; + border-color: $incorrect; } } @@ -369,7 +368,7 @@ div.problem { } input { - border-color: red; + border-color: $incorrect; } } @@ -384,9 +383,9 @@ div.problem { margin-bottom: 0; &:before { + @extend %t-strong; display: inline; content: "Answer: "; - font-weight: bold; } &:empty { @@ -596,7 +595,8 @@ div.problem { } dl dt { - font-weight: bold; + @extend %t-strong; + } dl dd { @@ -642,8 +642,8 @@ div.problem { } th { + @extend %t-strong; text-align: left; - font-weight: bold; } td { @@ -706,16 +706,16 @@ div.problem { @include box-sizing(border-box); border: 2px solid $gray-l4; border-radius: 3px; - height: 46px; min-width: 160px; + height: 46px; } > .incorrect, .correct, .unanswered { .status { display: inline-block; - background: none; margin-top: ($baseline/2); + background: none; } } @@ -769,7 +769,7 @@ div.problem { @include margin-right($baseline/2); } - .indicator_container { + .indicator-container { display: inline-block; .status.correct:after, .status.incorrect:after { @@ -844,8 +844,8 @@ div.problem .action { margin-bottom: ($baseline/2); height: ($baseline*2); vertical-align: middle; - font-weight: 600; text-transform: uppercase; + font-weight: 600; } .save { @@ -866,9 +866,9 @@ div.problem .action { // border-radius: 3px; // padding: 8px 12px; // margin-top: ($baseline/2); + @include margin-left($baseline/2); display: inline-block; margin-top: 8px; - @include margin-left($baseline/2); color: $gray-d1; font-style: italic; -webkit-font-smoothing: antialiased; @@ -909,9 +909,9 @@ div.problem { .detailed-solution { > p:first-child { + @extend %t-strong; color: #aaa; text-transform: uppercase; - font-weight: bold; font-style: normal; font-size: 0.9em; } @@ -923,9 +923,9 @@ div.problem { .detailed-targeted-feedback { > p:first-child { - color: red; + @extend %t-strong; + color: $incorrect; text-transform: uppercase; - font-weight: bold; font-style: normal; font-size: 0.9em; } @@ -937,9 +937,9 @@ div.problem { .detailed-targeted-feedback-correct { > p:first-child { - color: green; + @extend %t-strong; + color: $correct; text-transform: uppercase; - font-weight: bold; font-style: normal; font-size: 0.9em; } @@ -980,11 +980,11 @@ div.problem { border: 1px solid $gray-l3; h3 { + @extend %t-strong; padding: 9px; border-bottom: 1px solid #e3e3e3; background: #eee; text-shadow: 0 1px 0 $white; - font-weight: bold; font-size: em(16); } @@ -1021,9 +1021,9 @@ div.problem { margin-bottom: 12px; h3 { + @extend %t-strong; color: #aaa; text-transform: uppercase; - font-weight: bold; font-style: normal; font-size: 0.9em; } @@ -1080,7 +1080,7 @@ div.problem { } .shortform { - font-weight: bold; + @extend %t-strong; } .longform { @@ -1223,9 +1223,9 @@ div.problem { border-radius: 1em; .annotation-header { + @extend %t-strong; padding: .5em 1em; border-bottom: 1px solid $gray-l3; - font-weight: bold; } .annotation-body { padding: .5em 1em; } @@ -1306,10 +1306,10 @@ div.problem { pre { background-color: $gray-l3; color: $black; } &:before { + @extend %t-strong; display: block; content: "debug input value"; text-transform: uppercase; - font-weight: bold; font-size: 1.5em; } } @@ -1330,7 +1330,7 @@ div.problem { @extend label.choicegroup_correct; input[type="text"] { - border-color: green; + border-color: $correct; } } diff --git a/common/lib/xmodule/xmodule/js/spec/capa/display_spec.coffee b/common/lib/xmodule/xmodule/js/spec/capa/display_spec.coffee index 892864f631..a8d881c6e6 100644 --- a/common/lib/xmodule/xmodule/js/spec/capa/display_spec.coffee +++ b/common/lib/xmodule/xmodule/js/spec/capa/display_spec.coffee @@ -323,7 +323,7 @@ describe 'Problem', ->

-
+
diff --git a/common/lib/xmodule/xmodule/js/src/capa/display.coffee b/common/lib/xmodule/xmodule/js/src/capa/display.coffee index f5e6c1baa0..da817c1254 100644 --- a/common/lib/xmodule/xmodule/js/src/capa/display.coffee +++ b/common/lib/xmodule/xmodule/js/src/capa/display.coffee @@ -470,7 +470,7 @@ class @Problem $(element).find('input').on 'input', -> $p = $(element).find('span.status') `// Translators: the word unanswered here is about answering a problem the student must solve.` - $p.parent().removeClass().addClass "unanswered" + $p.parent().removeClass().addClass "unsubmitted" choicegroup: (element) -> $element = $(element) @@ -498,7 +498,7 @@ class @Problem $(element).find('input').on 'input', -> $p = $(element).find('span.status') `// Translators: the word unanswered here is about answering a problem the student must solve.` - $p.parent().removeClass("correct incorrect").addClass "unanswered" + $p.parent().removeClass("correct incorrect").addClass "unsubmitted" inputtypeSetupMethods: diff --git a/common/static/sass/_mixins.scss b/common/static/sass/_mixins.scss index 6e702fdff6..9b78525951 100644 --- a/common/static/sass/_mixins.scss +++ b/common/static/sass/_mixins.scss @@ -432,8 +432,8 @@ // * +Icon - Font-Awesome - Extend // ==================== %use-font-awesome { + display: inline-block; font-family: FontAwesome; -webkit-font-smoothing: antialiased; - display: inline-block; speak: none; } diff --git a/common/test/acceptance/pages/lms/problem.py b/common/test/acceptance/pages/lms/problem.py index fa49ea824e..0183d5c3cd 100644 --- a/common/test/acceptance/pages/lms/problem.py +++ b/common/test/acceptance/pages/lms/problem.py @@ -66,7 +66,7 @@ class ProblemPage(PageObject): """ Is there a "correct" status showing? """ - return self.q(css="div.problem div.capa_inputtype.textline div.correct p.status").is_present() + return self.q(css="div.problem div.capa_inputtype.textline div.correct span.status").is_present() def click_clarification(self, index=0): """ diff --git a/lms/djangoapps/courseware/features/problems_setup.py b/lms/djangoapps/courseware/features/problems_setup.py index e7ac96a535..b4a0aa135d 100644 --- a/lms/djangoapps/courseware/features/problems_setup.py +++ b/lms/djangoapps/courseware/features/problems_setup.py @@ -84,7 +84,7 @@ PROBLEM_DICT = { 'answer': 'correct string'}, 'correct': ['div.correct'], 'incorrect': ['div.incorrect'], - 'unanswered': ['div.unanswered']}, + 'unanswered': ['div.unanswered', 'div.unsubmitted']}, 'numerical': { 'factory': NumericalResponseXMLFactory(), @@ -95,7 +95,7 @@ PROBLEM_DICT = { 'math_display': True}, 'correct': ['div.correct'], 'incorrect': ['div.incorrect'], - 'unanswered': ['div.unanswered']}, + 'unanswered': ['div.unanswered', 'div.unsubmitted']}, 'formula': { 'factory': FormulaResponseXMLFactory(), @@ -108,7 +108,7 @@ PROBLEM_DICT = { 'answer': 'x^2+2*x+y'}, 'correct': ['div.correct'], 'incorrect': ['div.incorrect'], - 'unanswered': ['div.unanswered']}, + 'unanswered': ['div.unanswered', 'div.unsubmitted']}, 'script': { 'factory': CustomResponseXMLFactory(), @@ -129,7 +129,7 @@ PROBLEM_DICT = { """)}, 'correct': ['div.correct'], 'incorrect': ['div.incorrect'], - 'unanswered': ['div.unanswered']}, + 'unanswered': ['div.unanswered', 'div.unsubmitted']}, 'code': { 'factory': CodeResponseXMLFactory(), diff --git a/lms/static/sass/base/_variables.scss b/lms/static/sass/base/_variables.scss index 5b1197c3ef..a057789f27 100644 --- a/lms/static/sass/base/_variables.scss +++ b/lms/static/sass/base/_variables.scss @@ -82,28 +82,6 @@ $gray-d2: shade($gray,40%); // #4c4c4c $gray-d3: shade($gray,60%); // #323232 $gray-d4: shade($gray,80%); // #191919 -// TO-DO: once existing lms $blue is removed, change $cms-blue to $blue. -$cms-blue: rgb(0, 159, 230); -$blue-l1: tint($cms-blue,20%); -$blue-l2: tint($cms-blue,40%); -$blue-l3: tint($cms-blue,60%); -$blue-l4: tint($cms-blue,80%); -$blue-l5: tint($cms-blue,90%); -$blue-d1: shade($cms-blue,20%); -$blue-d2: shade($cms-blue,40%); -$blue-d3: shade($cms-blue,60%); -$blue-d4: shade($cms-blue,80%); -$blue-s1: saturate($cms-blue,15%); -$blue-s2: saturate($cms-blue,30%); -$blue-s3: saturate($cms-blue,45%); -$blue-u1: desaturate($cms-blue,15%); -$blue-u2: desaturate($cms-blue,30%); -$blue-u3: desaturate($cms-blue,45%); -$blue-t0: rgba($cms-blue, 0.125); -$blue-t1: rgba($cms-blue, 0.25); -$blue-t2: rgba($cms-blue, 0.50); -$blue-t3: rgba($cms-blue, 0.75); - $pink: rgb(182,37,103); // #b72567; $pink-l1: tint($pink,20%); $pink-l2: tint($pink,40%); diff --git a/test_root/db/test_edx.db-journal b/test_root/db/test_edx.db-journal new file mode 100644 index 0000000000..e69de29bb2