[Fixes #10597] Make course modules section more accessible
Issues: * Screen readers cannot detect the indent, edit or delete buttons when navigating by keyboard. * On the Edit Module Settings/Add Module box, none of the fields or dropdowns have labels. Additionally, the "Before students can view this module: No prerequisites defined" and "This module is complete when: You'll need to add items before you can specify how a user will complete this module No requirements defined" text is no detected by a screen reader. * On the Add Item to Module box the text in the combo box is not detected. The screen reader can detect the dropdown lists but none of them are labeled. * When creating a new item, the field to enter a name for the item also has no label. Changes: * Adds labels to all fields on 'add module' and 'add module item' dialog boxes * Enables tab access to hidden hover icons on index for modules and module items by making elements visible but off screen (matching behavior of 'assignments' section) * Adds alt text to icons that didn't used to have it * Adds tabindex to non-label text that was being bypassed by JAWS * Fixes unrelated bug - module icon controls not linked to hover state * A few unrelated JS/CSS refactors * Tweaks selenium tests to use new with_focus_icons_visible helper to show off-screen icons Change-Id: Idb8151ef97c726b1f56d98270b6eb430f4dec5d4 Reviewed-on: https://gerrit.instructure.com/14322 Tested-by: Jenkins <jenkins@instructure.com> Reviewed-by: Zach Pendleton <zachp@instructure.com> Reviewed-by: Clare Hetherington <clare@instructure.com>
This commit is contained in:
parent
be6093f9cd
commit
181d300e2d
|
@ -4,6 +4,14 @@ $context_module_bg_color: #f2f3f4
|
|||
|
||||
#context_modules
|
||||
min-width: 20px
|
||||
|
||||
.hidden_tabbable
|
||||
position: relative
|
||||
left: -10000px
|
||||
|
||||
&:focus, &.focus
|
||||
left: auto !important
|
||||
|
||||
.context_module
|
||||
border:
|
||||
top: 1px dotted $context_module_border_color
|
||||
|
@ -16,8 +24,11 @@ $context_module_bg_color: #f2f3f4
|
|||
+opacity(0.5)
|
||||
&:hover
|
||||
+opacity(1)
|
||||
|
||||
.reorder_module_link, .move_item_link
|
||||
padding-left: 2px
|
||||
.move_item_link
|
||||
cursor: move
|
||||
.links
|
||||
padding-right: 10px
|
||||
text-align: right
|
||||
|
@ -29,17 +40,17 @@ $context_module_bg_color: #f2f3f4
|
|||
color: #323232
|
||||
.links
|
||||
float: right
|
||||
&:hover .hidden_tabbable
|
||||
left: auto !important
|
||||
|
||||
.completion_status .complete_icon,
|
||||
.locked_icon,
|
||||
.progression_details_link,
|
||||
.header .links,
|
||||
.add_module_item_link,
|
||||
.manage_module,
|
||||
.delete_prerequisite_link,
|
||||
.expand_module_link,
|
||||
.collapsed,
|
||||
.context_module_item .links
|
||||
.collapsed
|
||||
display: none
|
||||
&.editable_context_module
|
||||
.progression_details_link,
|
||||
|
@ -239,10 +250,7 @@ $context_module_bg_color: #f2f3f4
|
|||
font-size: 0.9em
|
||||
.locked_title
|
||||
display: none
|
||||
width: 100%
|
||||
.move_item_link
|
||||
visibility: hidden
|
||||
|
||||
width: 100%
|
||||
.locked_module &
|
||||
.title
|
||||
display: none
|
||||
|
@ -261,14 +269,13 @@ $context_module_bg_color: #f2f3f4
|
|||
font-weight: bold
|
||||
color: #888
|
||||
.links
|
||||
visibility: hidden
|
||||
width: 80px
|
||||
vertical-align: top
|
||||
padding-top: 2px
|
||||
&.context_module_item_hover, &:hover
|
||||
background-color: darken($context_module_bg_color, 2.5%)
|
||||
.move_item_link, .links, .links a
|
||||
visibility: visible
|
||||
.hidden_tabbable
|
||||
left: auto !important
|
||||
|
||||
td.points_possible_display, td.due_date_display
|
||||
padding-top: 5px
|
||||
|
@ -315,12 +322,8 @@ $context_module_bg_color: #f2f3f4
|
|||
.context_module .context_module_items
|
||||
border-collapse: collapse
|
||||
.context_module_item
|
||||
.move_item_link
|
||||
display: none
|
||||
.completion_status
|
||||
display: inline
|
||||
.links a
|
||||
display: none
|
||||
&.manageable
|
||||
.context_module_item
|
||||
.move_item_link
|
||||
|
|
|
@ -12,6 +12,7 @@ You can also sequence modules by defining criteria and prerequisites for each mo
|
|||
|
||||
To start organizing your course into modules, click the "%{button}" button to the right.
|
||||
TEXT
|
||||
#'
|
||||
%>
|
||||
<% else %>
|
||||
<p><%= t('help.no_modules', %{No modules have been defined for this course.}) %></p>
|
||||
|
@ -36,7 +37,7 @@ TEXT
|
|||
<tr>
|
||||
<td>
|
||||
<div class="module_name">
|
||||
<%= before_label('module_name', %{Name}) %>
|
||||
<%= f.label :name, before_label('module_name', %{Name}) %>
|
||||
</div>
|
||||
</td><td>
|
||||
<div class="module_name">
|
||||
|
@ -45,21 +46,22 @@ TEXT
|
|||
</td>
|
||||
</tr><tr>
|
||||
<td colspan="2">
|
||||
<input type="checkbox" id="unlock_module_at"/>
|
||||
<label for="unlock_module_at"><%= t('#labels.lock_module_until', %{lock module until a given date}) %></label>
|
||||
<%- label = t("#labels.lock_module_until", %{lock module until a given date}) %>
|
||||
<input type="checkbox" id="unlock_module_at" title="<%= label %>"/>
|
||||
<label for="unlock_module_at"><%= label %></label>
|
||||
</td>
|
||||
</tr><tr class="unlock_module_at_details">
|
||||
<td>
|
||||
<%= before_label('unlock_at', %{Unlock At}) %>
|
||||
<%= f.label :unlock_at, before_label('unlock_at', %{Unlock At}) %>
|
||||
</td><td>
|
||||
<%= f.text_field :unlock_at, :class => "datetime_field", :style => "width: 125px;" %>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td colspan="2">
|
||||
<div class="prerequisites_entry">
|
||||
<b><%= before_label('modules.before_students_view', %{Before students can view this module}) %></b>
|
||||
<b tabindex="0"><%= before_label('modules.before_students_view', %{Before students can view this module}) %></b>
|
||||
<div style="margin: 2px 10px 5px 20px;" class="prerequisites_list">
|
||||
<div class="no_prerequisites_message"><%= t('no_preprequisites', %{No prerequisites defined}) %></div>
|
||||
<div class="no_prerequisites_message" tabindex="0"><%= t('no_preprequisites', %{No prerequisites defined}) %></div>
|
||||
<div class="criteria_list" style="display: none;">
|
||||
</div>
|
||||
<div id="criterion_blank" class="criterion" style="display: none;">
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<div class="context_module <%= 'editable_context_module' if editable %>" id="context_module_<%= context_module ? context_module.id : "blank" %>" style="<%= hidden unless context_module %>">
|
||||
<a name="module_<%= context_module.id if context_module %>"></a>
|
||||
<div class="header">
|
||||
<span class="reorder_module_link" title="<%= t('reorder_modules', %{Drag to reorder modules}) %>" style="cursor: move; <%= 'hidden' unless @modules.length > 1 %>"><%= image_tag "move.png", :alt => t('reorder_modules', 'Drag to reorder modules') %></span>
|
||||
<span class="reorder_module_link" title="<%= t('reorder_modules', %{Drag to reorder modules}) %>" style="cursor: move; <%= 'hidden' unless @modules.length > 1 %>"><%= image_tag "move.png", :alt => t('reorder_modules', 'Drag to reorder modules'), :tabindex => '0', :class => 'hidden_tabbable' %></span>
|
||||
<span class="completion_status" style="<%= "visibility: hidden;" if !context_module || (context_module.completion_requirements || []).empty? %>">
|
||||
<%= image_tag "pass.png", :alt => t('images.alt.complete', "done"), :title => t('images.title.complete', "Module Completed"), :class => "complete_icon" %>
|
||||
<%= image_tag "blank.png", :alt => t('images.alt.incomplete', "incomplete"), :title => t('images.title.incomplete', "Module Incomplete"), :class => "incomplete_icon" %>
|
||||
|
@ -19,8 +19,8 @@
|
|||
<span class="id" style="display: none;"><%= context_module ? context_module.id : nbsp %></span>
|
||||
<span class="unlock_at" style="display: none;"><%= datetime_string(context_module.try_rescue(:unlock_at)) || nbsp %></span>
|
||||
|
||||
<a href="<%= context_url(@context, :context_url) %>/modules/<%= context_module ? context_module.id : "{{ id }}" %>" class="edit_module_link edit_link no-hover" title="<%= t('links.title.edit_module', %{Edit module settings}) %>"><%= image_tag "edit.png" %></a>
|
||||
<a href="<%= context_url(@context, :context_url) %>/modules/<%= context_module ? context_module.id : "{{ id }}" %>" class="delete_module_link delete_link no-hover" title="<%= t('links.title.delete_module', %{Delete this module}) %>"><%= image_tag "delete.png" %></a>
|
||||
<a href="<%= context_url(@context, :context_url) %>/modules/<%= context_module ? context_module.id : "{{ id }}" %>" class="edit_module_link edit_link no-hover hidden_tabbable" title="<%= t('links.title.edit_module', %{Edit module settings}) %>"><%= image_tag "edit.png" %></a>
|
||||
<a href="<%= context_url(@context, :context_url) %>/modules/<%= context_module ? context_module.id : "{{ id }}" %>" class="delete_module_link delete_link no-hover hidden_tabbable" title="<%= t('links.title.delete_module', %{Delete this module}) %>"><%= image_tag "delete.png" %></a>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
<div style="display: none;">
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
'must_view' => image_tag("preview_dim.png", :class => "image not_blank", :alt => t('images.alt.must_view', "must view"), :title => t('images.title.must_view', "Students must view this item before the module is considered complete"), :style => "vertical-align: top; padding-top: 2px;"),
|
||||
'must_contribute' => image_tag("text_entry_dim.png", :class => "image not_blank", :alt => t('images.alt.must_contribute', "must contribute"), :title => t('images.title.must_contribute', "Students must contribute to this item before the module is considered complete"), :style => "vertical-align: top; padding-top: 2px;"),
|
||||
'must_submit' => image_tag("text_entry_dim.png", :class => "image not_blank", :alt => t('images.alt.must_submit', "must submit"), :title => t('images.title.must_submit', "Students must submit this assignment before the module is considered complete"), :style => "vertical-align: top; padding-top: 2px;"),
|
||||
'indent' => image_tag('indent_thin.png'),
|
||||
'outdent' => image_tag('outdent_thin.png'),
|
||||
'edit' => image_tag('edit.png'),
|
||||
'delete' => image_tag('delete_circle.png'),
|
||||
'indent' => image_tag('indent_thin.png', :alt => t('images.alt.indent', 'indent')),
|
||||
'outdent' => image_tag('outdent_thin.png', :alt => t('images.alt.outdent', 'outdent')),
|
||||
'edit' => image_tag('edit.png', :alt => t('images.alt.edit', 'edit')),
|
||||
'delete' => image_tag('delete_circle.png', :alt => t('images.alt.delete', 'delete')),
|
||||
'other' => image_tag("blank.png", :class => "image", :alt => '')
|
||||
}
|
||||
%>
|
||||
|
@ -19,7 +19,10 @@
|
|||
<tr>
|
||||
<td class="module_item_icons">
|
||||
<div class="nobr">
|
||||
<span style="cursor: move;" title="<%= t('drag_to_reorder', %{Drag to reorder or move item to another module}) %>" class="move_item_link"><%= image_tag "move.png" %></span>
|
||||
<%- title = t('drag_to_reorder', %{Drag to reorder or move item to another module}) %>
|
||||
<span title="<%= title %>" class="move_item_link">
|
||||
<%= image_tag "move.png", :class => 'hidden_tabbable', :alt => title, :tabindex => '0' %>
|
||||
</span>
|
||||
<span class="completion_status">
|
||||
<%= image_tag "blank.png", :alt => t('images.alt.complete', "done"), :title => t('images.title.complete', "Module Item Completed"), :class => "complete_item_icon" %>
|
||||
<%= image_tag "blank.png", :alt => t('images.alt.incomplete', "incomplete"), :title => t('images.title.incomplete', "Module Item Incomplete"), :class => "incomplete_item_icon" %>
|
||||
|
@ -71,10 +74,10 @@
|
|||
<td class="points_possible_display"> </td>
|
||||
<td class="links">
|
||||
|
||||
<a href="<%= context_url(@context, :context_url) %>/modules/items/<%= tag ? tag.id : "{{ id }}" %>" class="outdent_item_link" title="<%= t('links.outdent', %{Outdent item}) %>"><%= @module_item_image_tags['outdent'] %></a>
|
||||
<a href="<%= context_url(@context, :context_url) %>/modules/items/<%= tag ? tag.id : "{{ id }}" %>" class="indent_item_link" title="<%= t('links.indent', %{Indent item}) %>"><%= @module_item_image_tags['indent'] %></a>
|
||||
<a href="<%= context_url(@context, :context_url) %>/modules/items/<%= tag ? tag.id : "{{ id }}" %>" class="edit_item_link edit_link" title="<%= t('links.edit_item', %{Edit item details}) %>"><%= @module_item_image_tags['edit'] %></a>
|
||||
<a href="<%= context_url(@context, :context_url) %>/modules/items/<%= tag ? tag.id : "{{ id }}" %>" class="delete_item_link delete_link" title="<%= t('links.remove_item', %{Remove this item from the module}) %>"><%= @module_item_image_tags['delete'] %></a>
|
||||
<a href="<%= context_url(@context, :context_url) %>/modules/items/<%= tag ? tag.id : "{{ id }}" %>" class="outdent_item_link hidden_tabbable" title="<%= t('links.outdent', %{Outdent item}) %>"><%= @module_item_image_tags['outdent'] %></a>
|
||||
<a href="<%= context_url(@context, :context_url) %>/modules/items/<%= tag ? tag.id : "{{ id }}" %>" class="indent_item_link hidden_tabbable" title="<%= t('links.indent', %{Indent item}) %>"><%= @module_item_image_tags['indent'] %></a>
|
||||
<a href="<%= context_url(@context, :context_url) %>/modules/items/<%= tag ? tag.id : "{{ id }}" %>" class="edit_item_link edit_link hidden_tabbable" title="<%= t('links.edit_item', %{Edit item details}) %>"><%= @module_item_image_tags['edit'] %></a>
|
||||
<a href="<%= context_url(@context, :context_url) %>/modules/items/<%= tag ? tag.id : "{{ id }}" %>" class="delete_item_link delete_link hidden_tabbable" title="<%= t('links.remove_item', %{Remove this item from the module}) %>"><%= @module_item_image_tags['delete'] %></a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<div style="<%= hidden if only && only.size == 1 %>">
|
||||
<a href="<%= context_url(@context, :context_external_tool_resource_selection_url, "{{ id }}") %>" id="select_content_resource_selection_url" style="display: none;"> </a>
|
||||
<% ot :add_to_module, "Add %{item} to *module*", :item => capture { %>
|
||||
<select id="add_module_item_select">
|
||||
<select id="add_module_item_select" aria-label="<%= t('titles.add_item_to_module', "Add Item to Module") %>">
|
||||
<% if !only || only.include?(:assignments) %>
|
||||
<option value="assignment"><%= t :assignment_item, "Assignment" %></option>
|
||||
<% end %>
|
||||
|
@ -38,12 +38,14 @@
|
|||
<% if !only || only.include?(:sub_headers) %>
|
||||
<div id="context_module_sub_headers_select" class="module_item_option" style="margin: 5px 20px;">
|
||||
<div style="font-size: 0.8em;">
|
||||
<%= t :sub_header_notice, "Type the text you'd like to add as a *module* sub-header", :wrapper => '<span class="holder_type">\1</span>' %>
|
||||
<span class="holder_type" id="sub_header_notice">
|
||||
<%= t :sub_header_notice, "Type the text you'd like to add as a *module* sub-header" %>
|
||||
</span>
|
||||
</div>
|
||||
<table>
|
||||
<tr>
|
||||
<td><label for="sub_header_title"><%= before_label :header, "Header" %></label></td>
|
||||
<td><input type="text" name="title" id="sub_header_title" style="width: 200px;"/></td>
|
||||
<td><label for="sub_header_title"><%= label_tag :sub_header_title, before_label(:header, "Header") %></label></td>
|
||||
<td><input type="text" name="title" id="sub_header_title" style="width: 200px;" aria-describedby="sub_header_notice" /></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
@ -52,20 +54,22 @@
|
|||
<div id="external_urls_select" class="module_item_option" style="margin: 5px 20px;">
|
||||
<div style="font-size: 0.8em;">
|
||||
<%= image_tag "link.png", :alt => t(:external_url_link_alt, "External URL") %>
|
||||
<%= t :external_url_notice, "Enter a URL and page name to add a link to any website URL to this *module*.", :wrapper => '<span class="holder_type">\1</span>' %>
|
||||
<span class="holder_type" id="external_url_notice">
|
||||
<%= t :external_url_notice, "Enter a URL and page name to add a link to any website URL to this *module*." %>
|
||||
</span>
|
||||
</div>
|
||||
<table>
|
||||
<tr>
|
||||
<td><label for="content_tag_create_url"><%= before_label :url, "URL" %></label></td>
|
||||
<td><%= label_tag :content_tag_create_url, before_label(:url, "URL") %></td>
|
||||
<td>
|
||||
<input type="text" name="url" id="content_tag_create_url" style="width: 200px;"/>
|
||||
<input type="text" name="url" id="content_tag_create_url" style="width: 200px;" aria-describedby="external_url_notice" />
|
||||
<div id="content_tag_services">
|
||||
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class='select_item_name'>
|
||||
<td><label for="content_tag_create_title"><%= before_label :page_name, "Page Name" %></label></td>
|
||||
<td><%= label_tag :content_tag_create_title, before_label(:page_name, "Page Name") %></label></td>
|
||||
<td><input type="text" name="title" id="content_tag_create_title" style="width: 120px;"/></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
@ -114,10 +118,12 @@
|
|||
<div id="wiki_pages_select" class="module_item_option" style="margin: 5px 20px;">
|
||||
<div style="font-size: 0.8em;">
|
||||
<%= image_tag "file.png", :alt => t(:wiki_page_alt, "Wiki page") %>
|
||||
<%= t :wiki_page_notice, 'Select the wiki page you want to associate with this *module*, or add a new page by selecting "New Page".', :wrapper => '<span class="holder_type">\1</span>' %>
|
||||
<span class="holder_type">
|
||||
<%= label_tag :wiki_select, t(:wiki_page_notice, 'Select the wiki page you want to associate with this *module*, or add a new page by selecting "New Page".') %>
|
||||
</span>
|
||||
</div>
|
||||
<div style="margin-top: 5px;">
|
||||
<select class="module_item_select" multiple>
|
||||
<select class="module_item_select" id="wiki_select" multiple>
|
||||
<%# cache on the context.wiki instead of just the context because even though it will require a db query, we will get a much better cache hit rate %>
|
||||
<% cache([@context.wiki, 'active_wiki_pages']) do %>
|
||||
<% @context.wiki.wiki_pages.active.scoped({:select => "id, title"}).each do |page| %>
|
||||
|
@ -130,8 +136,8 @@
|
|||
</select>
|
||||
</div>
|
||||
<div class="new" style="margin-top: 5px;">
|
||||
<%= before_label :page_name, "Page Name" %>
|
||||
<input type="text" name="wiki_page[title]" class="item_title"/>
|
||||
<%= label_tag :wiki_page_title, before_label(:page_name, "Page Name") %>
|
||||
<input type="text" name="wiki_page[title]" class="item_title" id="wiki_page_title"/>
|
||||
<a href="<%= context_url(@context, :context_wiki_pages_url) %>" style="display: none;" class="add_item_url"> </a>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -139,11 +145,15 @@
|
|||
<% if !only || only.include?(:attachments) %>
|
||||
<div id="attachments_select" class="module_item_option" style="margin: 5px 20px;">
|
||||
<div style="font-size: 0.8em;">
|
||||
<%= image_tag "file_download.png" %>
|
||||
<%= t :file_notice, 'Select the file you want to associate with this *module*, or add a file by selecting "New File".', :wrapper => '<span class="holder_type">\1</span>' %>
|
||||
<%= image_tag "file_download.png", :alt => "Upload" %>
|
||||
<label for="module_item_select">
|
||||
<span class="holder_type">
|
||||
<%= label_tag :module_item_select, t(:file_notice, 'Select the file you want to associate with this *module*, or add a file by selecting "New File".') %>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div style="margin-top: 5px;">
|
||||
<select class="module_item_select" multiple>
|
||||
<select class="module_item_select" id="module_item_select" multiple>
|
||||
<% @context.folders.active.scoped({:limit => 200}).sort_by{|f| f.full_name}.each do |folder| %>
|
||||
<optgroup label="<%= folder.full_name %>">
|
||||
<%
|
||||
|
@ -164,12 +174,12 @@
|
|||
<div class="new" style="margin-top: 5px;">
|
||||
<table>
|
||||
<tr>
|
||||
<td><%= before_label :file, "File" %></td>
|
||||
<td><%= label_tag :module_attachment_uploaded_data, before_label(:file, "File") %></td>
|
||||
<td><input id="module_attachment_uploaded_data" type="file" name="attachment[uploaded_data]" class="item_title"/></td>
|
||||
</tr><tr>
|
||||
<td>
|
||||
<a href="<%= context_url(@context, :context_files_url, :format => :text) %>" style="display: none;" class="add_item_url"> </a>
|
||||
<%= before_label :folder, "Folder" %>
|
||||
<%= label_tag :attachment_folder_id, before_label(:folder, "Folder") %>
|
||||
</td><td>
|
||||
<% Folder.root_folders(@context) %>
|
||||
<% folders = @context.active_folders_with_sub_folders.by_position %>
|
||||
|
@ -187,10 +197,12 @@
|
|||
<div id="quizs_select" class="module_item_option" style="margin: 5px 20px;">
|
||||
<div style="font-size: 0.8em;">
|
||||
<%= image_tag "quiz.png", :alt => t(:quiz_alt, "Quiz") %>
|
||||
<%= t :quiz_notice, 'Select the quiz you want to associate with this *module*, or add a new one by selecting "New Quiz".', :wrapper => '<span class="holder_type">\1</span>' %>
|
||||
<span class="holder_type">
|
||||
<%= label_tag :quiz_select, t(:quiz_notice, 'Select the quiz you want to associate with this *module*, or add a new one by selecting "New Quiz".') %>
|
||||
</span>
|
||||
</div>
|
||||
<div style="margin-top: 5px;">
|
||||
<select class="module_item_select" multiple>
|
||||
<select class="module_item_select" id="quiz_select" multiple>
|
||||
<% @context.quizzes.active.scoped({:limit => 400}).each do |quiz| %>
|
||||
<option value="<%= quiz.id %>"><%= quiz.title %></option>
|
||||
<% end %>
|
||||
|
@ -201,12 +213,12 @@
|
|||
<input type="hidden" name="quiz[quiz_type]" value="assignment" />
|
||||
<table>
|
||||
<tr>
|
||||
<td><%= before_label :quiz_name, "Quiz Name" %></td>
|
||||
<td><input type="text" name="quiz[title]" class="item_title"/></td>
|
||||
<td><%= label_tag :quiz_title, before_label(:quiz_name, "Quiz Name") %></td>
|
||||
<td><input type="text" name="quiz[title]" class="item_title" id="quiz_title"/></td>
|
||||
</tr><tr>
|
||||
<td><%= before_label :quiz_group, "Group" %></td>
|
||||
<td><%= label_tag :quiz_assignment_group_id, before_label(:quiz_group, "Group") %></td>
|
||||
<td>
|
||||
<select name="quiz[assignment_group_id]">
|
||||
<select name="quiz[assignment_group_id]" id="quiz_assignment_group_id">
|
||||
<% cnt = 0 %>
|
||||
<% @context.assignment_groups.active.each do |group| %>
|
||||
<% cnt += 1 %>
|
||||
|
@ -227,10 +239,12 @@
|
|||
<div id="assignments_select" class="module_item_option" style="margin: 5px 20px;">
|
||||
<div style="font-size: 0.8em;">
|
||||
<%= image_tag "grading_icon.png", :alt => t(:assignment_alt, "Assignment") %>
|
||||
<%= t :assignment_notice, 'Select the assignment you want to associate with this *module*, or add an assignment by selecting "New Assignment".', :wrapper => '<span class="holder_type">\1</span>' %>
|
||||
<span class="holder_type">
|
||||
<%= label_tag :assignment_select, t(:assignment_notice, 'Select the assignment you want to associate with this *module*, or add an assignment by selecting "New Assignment".') %>
|
||||
</span>
|
||||
</div>
|
||||
<div style="margin-top: 5px;">
|
||||
<select class="module_item_select" multiple>
|
||||
<select class="module_item_select" id="assignment_select" multiple>
|
||||
<% @context.assignment_groups.active.include_active_assignments.each do |group| %>
|
||||
<optgroup label="<%= group.name %>">
|
||||
<% group.active_assignments.no_graded_quizzes_or_topics.scoped({:limit => 200}).each do |assignment| %>
|
||||
|
@ -242,8 +256,8 @@
|
|||
</select>
|
||||
</div>
|
||||
<div class="new" style="margin-top: 5px;">
|
||||
<%= before_label :assignment_name, "Assignment Name" %>
|
||||
<input type="text" name="assignment[title]" class="item_title"/>
|
||||
<%= label_tag :assignment_title, before_label(:assignment_name, "Assignment Name") %>
|
||||
<input type="text" name="assignment[title]" class="item_title" id="assignment_title" />
|
||||
<a href="<%= context_url(@context, :context_assignments_url) %>" style="display: none;" class="add_item_url"> </a>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -252,10 +266,12 @@
|
|||
<div id="discussion_topics_select" class="module_item_option" style="margin: 5px 20px;">
|
||||
<div style="font-size: 0.8em;">
|
||||
<%= image_tag "word_bubble.png", :alt => t(:topic_alt, "Topic") %>
|
||||
<%= t :topic_notice, 'Select the topic you want to associate with this *module*, or add a topic by selecting "New Topic".', :wrapper => '<span class="holder_type">\1</span>' %>
|
||||
<span class="holder_type">
|
||||
<%= label_tag :topic_select, t(:topic_notice, 'Select the topic you want to associate with this *module*, or add a topic by selecting "New Topic".') %>
|
||||
</span>
|
||||
</div>
|
||||
<div style="margin-top: 5px;">
|
||||
<select class="module_item_select" multiple>
|
||||
<select class="module_item_select" id="topic_select" multiple>
|
||||
<% @context.discussion_topics.active.only_discussion_topics.scoped({:limit => 200}).each do |topic| %>
|
||||
<option value="<%= topic.id %>"><%= topic.title %></option>
|
||||
<% end %>
|
||||
|
@ -263,15 +279,15 @@
|
|||
</select>
|
||||
</div>
|
||||
<div class="new" style="margin-top: 5px;">
|
||||
<%= before_label :topic_name, "Topic Name" %>
|
||||
<input type="text" name="title" class="item_title"/>
|
||||
<%= label_tag :topic_name, before_label(:topic_name, "Topic Name") %>
|
||||
<input type="text" name="title" class="item_title" id="topic_name"/>
|
||||
<a href="<%= context_url(@context, :api_v1_context_discussion_topics_url) %>" style="display: none;" class="add_item_url"> </a>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if !only || only.include?(:indentation) %>
|
||||
<div style="margin: 0px 20px 5px;" class="context_module_content">
|
||||
<%= before_label :indentation, "Indentation" %>
|
||||
<%= label_tag :content_tag_indent, before_label(:indentation, "Indentation") %>
|
||||
<select name="content_tag[indent]" id="content_tag_indent">
|
||||
<% (0..3).each do |level| %>
|
||||
<%= t(:indent_level, { :zero => "*Don't Indent*", :one => "*Indent 1 Level*", :other => "*Indent %{count} levels*" }, :count => level, :wrapper => "<option value=\"#{level}\">\\1</option>") %>
|
||||
|
|
|
@ -852,14 +852,15 @@ define([
|
|||
|
||||
$(document).ready(function() {
|
||||
$(".datetime_field").datetime_field();
|
||||
$(".context_module").live('mouseover', function() {
|
||||
$(".context_module_hover").removeClass('context_module_hover');
|
||||
$(this).addClass('context_module_hover');
|
||||
|
||||
$("#context_modules").on('mouseenter mouseleave', '.context_module', function() {
|
||||
$(this).toggleClass('context_module_hover');
|
||||
});
|
||||
$(".context_module_item").live('mouseover', function() {
|
||||
$(".context_module_item_hover").removeClass('context_module_item_hover');
|
||||
$(this).addClass('context_module_item_hover');
|
||||
|
||||
$("#context_modules").on('mouseenter mouseleave', '.context_module_item', function() {
|
||||
$(this).toggleClass('context_module_item_hover');
|
||||
});
|
||||
|
||||
var $currentElem = null;
|
||||
var hover = function($elem) {
|
||||
if($elem.hasClass('context_module')) {
|
||||
|
|
|
@ -149,7 +149,10 @@ describe "context_modules" do
|
|||
a2_img = fj('.context_module_items .context_module_item:last .move_item_link img')
|
||||
|
||||
#performs the change position
|
||||
driver.action.drag_and_drop(a2_img, a1_img).perform
|
||||
with_focus_icons_visible do
|
||||
driver.action.drag_and_drop(a2_img, a1_img).perform
|
||||
end
|
||||
|
||||
wait_for_ajax_requests
|
||||
|
||||
#validates the assignments switched, the number convention doesn't make sense, should be assignment == 2 and assignment2 == 1 but this is working
|
||||
|
@ -172,7 +175,10 @@ describe "context_modules" do
|
|||
a2_img = fj('#context_modules .context_module:last-child .context_module_items .context_module_item:first .move_item_link img')
|
||||
|
||||
#performs the change position
|
||||
driver.action.drag_and_drop(a2_img, a1_img).perform
|
||||
with_focus_icons_visible do
|
||||
driver.action.drag_and_drop(a2_img, a1_img).perform
|
||||
end
|
||||
|
||||
wait_for_ajax_requests
|
||||
|
||||
#validates the module 1 assignments are in the expected places and that module 2 context_module_items isn't present
|
||||
|
@ -235,10 +241,13 @@ describe "context_modules" do
|
|||
|
||||
it "should delete a module" do
|
||||
add_module('Delete Module')
|
||||
driver.execute_script("$('.context_module').addClass('context_module_hover')")
|
||||
f('.delete_module_link').click
|
||||
driver.switch_to.alert.should_not be_nil
|
||||
driver.switch_to.alert.accept
|
||||
|
||||
with_focus_icons_visible do
|
||||
f('.delete_module_link').click
|
||||
driver.switch_to.alert.should_not be_nil
|
||||
driver.switch_to.alert.accept
|
||||
end
|
||||
|
||||
wait_for_ajaximations
|
||||
refresh_page
|
||||
f('#no_context_modules_message').should be_displayed
|
||||
|
@ -249,7 +258,9 @@ describe "context_modules" do
|
|||
add_module('Edit Module')
|
||||
context_module = f('.context_module')
|
||||
driver.action.move_to(context_module).perform
|
||||
f('.edit_module_link').click
|
||||
with_focus_icons_visible do
|
||||
f('.edit_module_link').click
|
||||
end
|
||||
f('.ui-dialog').should be_displayed
|
||||
edit_form = f('#add_context_module_form')
|
||||
edit_form.find_element(:id, 'context_module_name').send_keys(edit_text)
|
||||
|
@ -265,7 +276,9 @@ describe "context_modules" do
|
|||
# add completion criterion
|
||||
context_module = f('.context_module')
|
||||
driver.action.move_to(context_module).perform
|
||||
f('.edit_module_link').click
|
||||
with_focus_icons_visible do
|
||||
f('.edit_module_link').click
|
||||
end
|
||||
f('.ui-dialog').should be_displayed
|
||||
edit_form = f('#add_context_module_form')
|
||||
f('.add_completion_criterion_link', edit_form).click
|
||||
|
@ -285,7 +298,11 @@ describe "context_modules" do
|
|||
|
||||
# delete the criterion, then cancel the form
|
||||
driver.action.move_to(context_module).perform
|
||||
f('.edit_module_link').click
|
||||
|
||||
with_focus_icons_visible do
|
||||
f('.edit_module_link').click
|
||||
end
|
||||
|
||||
f('.ui-dialog').should be_displayed
|
||||
edit_form = f('#add_context_module_form')
|
||||
f('.completion_entry .delete_criterion_link', edit_form).click
|
||||
|
@ -296,7 +313,11 @@ describe "context_modules" do
|
|||
# now delete the criterion frd
|
||||
# (if the previous step did even though it shouldn't have, this will error)
|
||||
driver.action.move_to(context_module).perform
|
||||
f('.edit_module_link').click
|
||||
|
||||
with_focus_icons_visible do
|
||||
f('.edit_module_link').click
|
||||
end
|
||||
|
||||
f('.ui-dialog').should be_displayed
|
||||
edit_form = f('#add_context_module_form')
|
||||
f('.completion_entry .delete_criterion_link', edit_form).click
|
||||
|
@ -310,7 +331,11 @@ describe "context_modules" do
|
|||
|
||||
# and also make sure the form remembers that it's gone (#8329)
|
||||
driver.action.move_to(context_module).perform
|
||||
f('.edit_module_link').click
|
||||
|
||||
with_focus_icons_visible do
|
||||
f('.edit_module_link').click
|
||||
end
|
||||
|
||||
f('.ui-dialog').should be_displayed
|
||||
edit_form = f('#add_context_module_form')
|
||||
ff('.completion_entry .delete_criterion_link', edit_form).should be_empty
|
||||
|
@ -515,7 +540,11 @@ describe "context_modules" do
|
|||
|
||||
m1_img = fj('#context_modules .context_module:first-child .reorder_module_link img')
|
||||
m2_img = fj('#context_modules .context_module:last-child .reorder_module_link img')
|
||||
driver.action.drag_and_drop(m2_img, m1_img).perform
|
||||
|
||||
with_focus_icons_visible do
|
||||
driver.action.drag_and_drop(m2_img, m1_img).perform
|
||||
end
|
||||
|
||||
wait_for_ajax_requests
|
||||
|
||||
m1.reload
|
||||
|
@ -594,7 +623,11 @@ describe "context_modules" do
|
|||
# add completion criterion
|
||||
context_module = f('.context_module')
|
||||
driver.action.move_to(context_module).perform
|
||||
f('.edit_module_link').click
|
||||
|
||||
with_focus_icons_visible do
|
||||
f('.edit_module_link').click
|
||||
end
|
||||
|
||||
edit_form = f('#add_context_module_form')
|
||||
f('.add_completion_criterion_link', edit_form).click
|
||||
wait_for_ajaximations
|
||||
|
@ -619,6 +652,37 @@ describe "context_modules" do
|
|||
f('.criterion', module_item).attribute('class').split.should include 'defined'
|
||||
driver.execute_script("return $('#context_module_item_#{tag.id} .criterion_type').text()").should == "must_contribute"
|
||||
end
|
||||
|
||||
it "should allow editing external tools settings for a tool in a module" do
|
||||
# moved from external_tools_spec
|
||||
|
||||
@module = @course.context_modules.create!(:name => "module")
|
||||
@tag = @module.add_item({
|
||||
:type => 'context_external_tool',
|
||||
:title => 'Example',
|
||||
:url => 'http://www.example.com',
|
||||
:new_tab => '1'
|
||||
})
|
||||
get "/courses/#{@course.id}/modules"
|
||||
keep_trying_until { driver.execute_script("return window.modules.refreshed == true") }
|
||||
|
||||
with_focus_icons_visible do
|
||||
f("#context_module_item_#{@tag.id} .edit_item_link").click
|
||||
end
|
||||
|
||||
f("#edit_item_form").should be_displayed
|
||||
replace_content(f("#edit_item_form #content_tag_title"), "Example 2")
|
||||
f("#edit_item_form #content_tag_new_tab").click
|
||||
submit_form("#edit_item_form")
|
||||
|
||||
wait_for_ajax_requests
|
||||
|
||||
@tag.reload
|
||||
@tag.should_not be_nil
|
||||
@tag.title.should == "Example 2"
|
||||
@tag.new_tab.should == false
|
||||
@tag.url.should == "http://www.example.com"
|
||||
end
|
||||
end
|
||||
|
||||
describe "files" do
|
||||
|
|
|
@ -283,33 +283,6 @@ describe "editing external tools" do
|
|||
f("#external_tool_create_title").should have_value "bob"
|
||||
end
|
||||
|
||||
it "should allow editing the settings for a tool in a module" do
|
||||
@module = @course.context_modules.create!(:name => "module")
|
||||
@tag = @module.add_item({
|
||||
:type => 'context_external_tool',
|
||||
:title => 'Example',
|
||||
:url => 'http://www.example.com',
|
||||
:new_tab => '1'
|
||||
})
|
||||
get "/courses/#{@course.id}/modules"
|
||||
keep_trying_until { driver.execute_script("return window.modules.refreshed == true") }
|
||||
|
||||
f("#context_module_item_#{@tag.id}").click
|
||||
f("#context_module_item_#{@tag.id} .edit_item_link").click
|
||||
|
||||
f("#edit_item_form").should be_displayed
|
||||
replace_content(f("#edit_item_form #content_tag_title"), "Example 2")
|
||||
f("#edit_item_form #content_tag_new_tab").click
|
||||
submit_form("#edit_item_form")
|
||||
|
||||
wait_for_ajax_requests
|
||||
|
||||
@tag.reload
|
||||
@tag.should_not be_nil
|
||||
@tag.title.should == "Example 2"
|
||||
@tag.new_tab.should == false
|
||||
@tag.url.should == "http://www.example.com"
|
||||
end
|
||||
|
||||
it "should launch assignment external tools when viewing assignment" do
|
||||
@tool = @course.context_external_tools.create!(:name => "new tool", :consumer_key => "key", :shared_secret => "secret", :domain => 'example.com', :custom_fields => {'a' => '1', 'b' => '2'})
|
||||
|
|
|
@ -93,4 +93,11 @@ shared_examples_for "context module tests" do
|
|||
submit_form(edit_form)
|
||||
wait_for_ajaximations
|
||||
end
|
||||
|
||||
def with_focus_icons_visible(&block)
|
||||
# reveals 'hidden_tabbable' icons that are only visible on focus or hover for the duration of the block
|
||||
driver.execute_script("$('.hidden_tabbable').addClass('focus');")
|
||||
yield(block)
|
||||
driver.execute_script("$('.hidden_tabbable').removeClass('focus');")
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue