Merge branch 'MDL-40975-master' of git://github.com/andrewnicols/moodle
Conflicts: theme/bootstrapbase/style/moodle.css
@@ -21,14 +21,18 @@ Feature: Duplicate activities
|
||||
And I add a "Database" to section "1" and I fill the form with:
|
||||
| Name | Test database name |
|
||||
| Description | Test database description |
|
||||
And I click on "Actions" "link" in the "Test database name" activity
|
||||
And I open "Test database name" actions menu
|
||||
When I click on "Duplicate" "link" in the "Test database name" activity
|
||||
And I press "Continue"
|
||||
And I press "Edit the new copy"
|
||||
And I click on "Edit settings" "link" in the "Test database name" activity
|
||||
And I fill the moodle form with:
|
||||
| Name | Original database name |
|
||||
And I press "Save and return to course"
|
||||
And I open "Test database name" actions menu
|
||||
And I click on "Edit settings" "link" in the "Test database name" activity
|
||||
And I fill the moodle form with:
|
||||
| Name | Duplicated database name |
|
||||
| Description | Duplicated database description |
|
||||
And I press "Save and return to course"
|
||||
Then I should see "Test database name" in the "#section-1" "css_element"
|
||||
Then I should see "Original database name" in the "#section-1" "css_element"
|
||||
And I should see "Duplicated database name" in the "#section-1" "css_element"
|
||||
And "Test database name" "link" should appear before "Duplicated database name" "link"
|
||||
And "Original database name" "link" should appear before "Duplicated database name" "link"
|
||||
|
||||
@@ -40,7 +40,7 @@ Feature: Restore Moodle 2 course backups
|
||||
Then I should see "Course 1 restored in a new course"
|
||||
And I should see "Community finder" in the "Community finder" "block"
|
||||
And I should see "Test forum name"
|
||||
And I follow "Edit settings"
|
||||
And I click on "Edit settings" "link" in the "Administration" "block"
|
||||
And I expand all fieldsets
|
||||
And the "id_format" field should match "Topics format" value
|
||||
And the "Number of sections" field should match "15" value
|
||||
@@ -85,7 +85,7 @@ Feature: Restore Moodle 2 course backups
|
||||
When I restore "test_backup.mbz" backup into a new course using this options:
|
||||
Then I should see "Topic 1"
|
||||
And I should see "Test forum name"
|
||||
And I follow "Edit settings"
|
||||
And I click on "Edit settings" "link" in the "Administration" "block"
|
||||
And I expand all fieldsets
|
||||
And the "id_format" field should match "Topics format" value
|
||||
And I fill the moodle form with:
|
||||
@@ -96,14 +96,14 @@ Feature: Restore Moodle 2 course backups
|
||||
And I press "Save changes"
|
||||
And I should see "1 January - 7 January"
|
||||
And I should see "Test forum name"
|
||||
And I follow "Edit settings"
|
||||
And I click on "Edit settings" "link" in the "Administration" "block"
|
||||
And I expand all fieldsets
|
||||
And the "id_format" field should match "Weekly format" value
|
||||
And I fill the moodle form with:
|
||||
| id_format | Social format |
|
||||
And I press "Save changes"
|
||||
And I should see "An open forum for chatting about anything you want to"
|
||||
And I follow "Edit settings"
|
||||
And I click on "Edit settings" "link" in the "Administration" "block"
|
||||
And I expand all fieldsets
|
||||
And the "id_format" field should match "Social format" value
|
||||
And I press "Cancel"
|
||||
@@ -120,7 +120,7 @@ Feature: Restore Moodle 2 course backups
|
||||
| Filename | test_backup.mbz |
|
||||
And I restore "test_backup.mbz" backup into "Course 2" course using this options:
|
||||
| Overwrite course configuration | Yes |
|
||||
And I follow "Edit settings"
|
||||
And I click on "Edit settings" "link" in the "Administration" "block"
|
||||
And I expand all fieldsets
|
||||
Then the "id_format" field should match "Topics format" value
|
||||
And the "Number of sections" field should match "15" value
|
||||
|
||||
@@ -18,6 +18,7 @@ Feature: Add and configure blocks throughout the site
|
||||
And I log in as "manager1"
|
||||
And I follow "Turn editing on"
|
||||
And I add the "Comments" block
|
||||
And I click on "Actions" "link" in the "Comments" "block"
|
||||
And I follow "Configure Comments block"
|
||||
And I fill the moodle form with:
|
||||
| Page contexts | Display throughout the entire site |
|
||||
@@ -26,6 +27,7 @@ Feature: Add and configure blocks throughout the site
|
||||
Then I should see "Comments" in the "Comments" "block"
|
||||
And I should see "Save comment" in the "Comments" "block"
|
||||
And I am on homepage
|
||||
And I click on "Actions" "link" in the "Comments" "block"
|
||||
And I follow "Configure Comments block"
|
||||
And I fill the moodle form with:
|
||||
| Default weight | -10 (first) |
|
||||
|
||||
@@ -15,6 +15,7 @@ Feature: The context of a block can always be returned to it's original state.
|
||||
And I add the "Tags" block
|
||||
Then I should see "Tags" in the "Tags" "block"
|
||||
And I click on "Participants" "link" in the "//li[p/span[contains(normalize-space(string(.)), 'Current course')]]" "xpath_element"
|
||||
And I click on "Actions" "link" in the "Tags" "block"
|
||||
And I follow "Configure Tags block"
|
||||
And I fill the moodle form with:
|
||||
| Display on page types | Any page |
|
||||
@@ -24,6 +25,7 @@ Feature: The context of a block can always be returned to it's original state.
|
||||
| Assignment name | Assignment1 |
|
||||
| Description | Description |
|
||||
And I follow "Assignment1"
|
||||
And I click on "Actions" "link" in the "Tags" "block"
|
||||
And I follow "Configure Tags block"
|
||||
And I fill the moodle form with:
|
||||
| Display on page types | Any assignment module page |
|
||||
@@ -39,6 +41,7 @@ Feature: The context of a block can always be returned to it's original state.
|
||||
| Description | Description |
|
||||
And I follow "Assignment2"
|
||||
And I should see "Tags" in the "Tags" "block"
|
||||
And I click on "Actions" "link" in the "Tags" "block"
|
||||
And I follow "Configure Tags block"
|
||||
And I fill the moodle form with:
|
||||
| Display on page types | Any page |
|
||||
|
||||
@@ -25,7 +25,7 @@ Feature: Allow students to manually mark an activity as complete
|
||||
And I log in as "teacher1"
|
||||
And I follow "Course 1"
|
||||
And I turn editing mode on
|
||||
And I follow "Edit settings"
|
||||
And I click on "Edit settings" "link" in the "Administration" "block"
|
||||
And I fill the moodle form with:
|
||||
| Enable completion tracking | Yes |
|
||||
And I press "Save changes"
|
||||
|
||||
@@ -27,7 +27,7 @@ Feature: Restrict sections availability through completion or grade conditions
|
||||
Given I log in as "teacher1"
|
||||
And I follow "Course 1"
|
||||
And I turn editing mode on
|
||||
And I follow "Edit settings"
|
||||
And I click on "Edit settings" "link" in the "Administration" "block"
|
||||
And I fill the moodle form with:
|
||||
| Enable completion tracking | Yes |
|
||||
And I press "Save changes"
|
||||
@@ -93,4 +93,4 @@ Feature: Restrict sections availability through completion or grade conditions
|
||||
And I log in as "student1"
|
||||
And I follow "Course 1"
|
||||
And "Test page name" activity should be visible
|
||||
And I should not see "Not available until you achieve a required score in Grade assignment"
|
||||
And I should not see "Not available until you achieve a required score in Grade assignment"
|
||||
|
||||
@@ -611,8 +611,7 @@ class core_course_management_renderer extends plugin_renderer_base {
|
||||
new action_menu_link_secondary($shortnameurl, null, get_string('resortbyshortname')),
|
||||
new action_menu_link_secondary($idnumberurl, null, get_string('resortbyidnumber'))
|
||||
));
|
||||
$menu->actiontext = get_string('resortcourses');
|
||||
$menu->actionicon = new pix_icon('t/contextmenu', ' ', 'moodle', array('class' => 'iconsmall', 'title' => ''));
|
||||
$menu->set_menu_trigger(get_string('resortcourses'));
|
||||
$actions[] = $this->render($menu);
|
||||
}
|
||||
$strall = get_string('all');
|
||||
@@ -628,7 +627,7 @@ class core_course_management_renderer extends plugin_renderer_base {
|
||||
$perpage = $strall;
|
||||
}
|
||||
$menu->attributes['class'] .= ' courses-per-page';
|
||||
$menu->actiontext = get_string('perpagea', 'moodle', $perpage);
|
||||
$menu->set_menu_trigger(get_string('perpagea', 'moodle', $perpage));
|
||||
$actions[] = $this->render($menu);
|
||||
return html_writer::div(join(' | ', $actions), 'listing-actions course-listing-actions');
|
||||
}
|
||||
@@ -922,7 +921,7 @@ class core_course_management_renderer extends plugin_renderer_base {
|
||||
$menu->add(new action_menu_link_secondary($modeurl, null, $modestr, $attributes));
|
||||
}
|
||||
|
||||
$menu->actiontext = get_string('viewing', 'moodle', $selected);
|
||||
$menu->set_menu_trigger(get_string('viewing', 'moodle', $selected));
|
||||
|
||||
$html = html_writer::start_div('view-mode-selector vms');
|
||||
$html .= $this->render($menu);
|
||||
|
||||
@@ -1949,14 +1949,11 @@ function course_get_cm_edit_actions(cm_info $mod, $indent = -1, $sr = null) {
|
||||
|
||||
if (!isset($str)) {
|
||||
$str = get_strings(array('delete', 'move', 'moveright', 'moveleft',
|
||||
'update', 'duplicate', 'hide', 'show', 'edittitle'), 'moodle');
|
||||
'editsettings', 'duplicate', 'hide', 'show'), 'moodle');
|
||||
$str->assign = get_string('assignroles', 'role');
|
||||
$str->groupsnone = get_string('clicktochangeinbrackets', 'moodle', get_string("groupsnone"));
|
||||
$str->groupsseparate = get_string('clicktochangeinbrackets', 'moodle', get_string("groupsseparate"));
|
||||
$str->groupsvisible = get_string('clicktochangeinbrackets', 'moodle', get_string("groupsvisible"));
|
||||
$str->forcedgroupsnone = get_string('forcedmodeinbrackets', 'moodle', get_string("groupsnone"));
|
||||
$str->forcedgroupsseparate = get_string('forcedmodeinbrackets', 'moodle', get_string("groupsseparate"));
|
||||
$str->forcedgroupsvisible = get_string('forcedmodeinbrackets', 'moodle', get_string("groupsvisible"));
|
||||
}
|
||||
|
||||
$baseurl = new moodle_url('/course/mod.php', array('sesskey' => sesskey()));
|
||||
@@ -1966,21 +1963,21 @@ function course_get_cm_edit_actions(cm_info $mod, $indent = -1, $sr = null) {
|
||||
}
|
||||
$actions = array();
|
||||
|
||||
// AJAX edit title.
|
||||
if ($mod->has_view() && $hasmanageactivities &&
|
||||
(($mod->course == $COURSE->id && course_ajax_enabled($COURSE)) ||
|
||||
($mod->course == SITEID && course_ajax_enabled($SITE)))) {
|
||||
// we will not display link if we are on some other-course page (where we should not see this module anyway)
|
||||
$actions['title'] = new action_menu_link_secondary(
|
||||
// Update.
|
||||
if ($hasmanageactivities) {
|
||||
$actions['update'] = new action_menu_link_secondary(
|
||||
new moodle_url($baseurl, array('update' => $mod->id)),
|
||||
new pix_icon('t/editstring', $str->edittitle, 'moodle', array('class' => 'iconsmall visibleifjs', 'title' => '')),
|
||||
$str->edittitle,
|
||||
array('class' => 'editing_title', 'data-action' => 'edittitle')
|
||||
new pix_icon('t/edit', $str->editsettings, 'moodle', array('class' => 'iconsmall', 'title' => '')),
|
||||
$str->editsettings,
|
||||
array('class' => 'editing_update', 'data-action' => 'update')
|
||||
);
|
||||
}
|
||||
|
||||
// Indent.
|
||||
if ($hasmanageactivities) {
|
||||
$indentlimits = new stdClass();
|
||||
$indentlimits->min = 0;
|
||||
$indentlimits->max = 16;
|
||||
if (right_to_left()) { // Exchange arrows on RTL
|
||||
$rightarrow = 't/left';
|
||||
$leftarrow = 't/right';
|
||||
@@ -1989,46 +1986,49 @@ function course_get_cm_edit_actions(cm_info $mod, $indent = -1, $sr = null) {
|
||||
$leftarrow = 't/left';
|
||||
}
|
||||
|
||||
$hiddenclass = 'hidden';
|
||||
if ($indent > 0) {
|
||||
$hiddenclass = '';
|
||||
}
|
||||
$actions['moveleft'] = new action_menu_link_secondary(
|
||||
new moodle_url($baseurl, array('id' => $mod->id, 'indent' => '-1')),
|
||||
new pix_icon($leftarrow, $str->moveleft, 'moodle', array('class' => 'iconsmall', 'title' => '')),
|
||||
$str->moveleft,
|
||||
array('class' => 'editing_moveleft ' . $hiddenclass, 'data-action' => 'moveleft')
|
||||
);
|
||||
$hiddenclass = 'hidden';
|
||||
if ($indent >= 0) {
|
||||
$hiddenclass = '';
|
||||
if ($indent >= $indentlimits->max) {
|
||||
$enabledclass = 'hidden';
|
||||
} else {
|
||||
$enabledclass = '';
|
||||
}
|
||||
$actions['moveright'] = new action_menu_link_secondary(
|
||||
new moodle_url($baseurl, array('id' => $mod->id, 'indent' => '1')),
|
||||
new pix_icon($rightarrow, $str->moveright, 'moodle', array('class' => 'iconsmall', 'title' => '')),
|
||||
$str->moveright,
|
||||
array('class' => 'editing_moveright ' . $hiddenclass, 'data-action' => 'moveright')
|
||||
array('class' => 'editing_moveright ' . $enabledclass, 'data-action' => 'moveright')
|
||||
);
|
||||
|
||||
if ($indent <= $indentlimits->min) {
|
||||
$enabledclass = 'hidden';
|
||||
} else {
|
||||
$enabledclass = '';
|
||||
}
|
||||
$actions['moveleft'] = new action_menu_link_secondary(
|
||||
new moodle_url($baseurl, array('id' => $mod->id, 'indent' => '-1')),
|
||||
new pix_icon($leftarrow, $str->moveleft, 'moodle', array('class' => 'iconsmall', 'title' => '')),
|
||||
$str->moveleft,
|
||||
array('class' => 'editing_moveleft ' . $enabledclass, 'data-action' => 'moveleft')
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
// Move.
|
||||
if ($hasmanageactivities) {
|
||||
$actions['move'] = new action_menu_link_primary(
|
||||
new moodle_url($baseurl, array('copy' => $mod->id)),
|
||||
new pix_icon('t/move', $str->move, 'moodle', array('class' => 'iconsmall', 'title' => '')),
|
||||
$str->move,
|
||||
array('class' => 'editing_move status', 'data-action' => 'move')
|
||||
);
|
||||
}
|
||||
|
||||
// Update.
|
||||
if ($hasmanageactivities) {
|
||||
$actions['update'] = new action_menu_link_secondary(
|
||||
new moodle_url($baseurl, array('update' => $mod->id)),
|
||||
new pix_icon('t/edit', $str->update, 'moodle', array('class' => 'iconsmall', 'title' => '')),
|
||||
$str->update,
|
||||
array('class' => 'editing_update', 'data-action' => 'update')
|
||||
);
|
||||
// Hide/Show.
|
||||
if (has_capability('moodle/course:activityvisibility', $modcontext)) {
|
||||
if ($mod->visible) {
|
||||
$actions['hide'] = new action_menu_link_secondary(
|
||||
new moodle_url($baseurl, array('hide' => $mod->id)),
|
||||
new pix_icon('t/hide', $str->hide, 'moodle', array('class' => 'iconsmall', 'title' => '')),
|
||||
$str->hide,
|
||||
array('class' => 'editing_hide', 'data-action' => 'hide')
|
||||
);
|
||||
} else {
|
||||
$actions['show'] = new action_menu_link_secondary(
|
||||
new moodle_url($baseurl, array('show' => $mod->id)),
|
||||
new pix_icon('t/show', $str->show, 'moodle', array('class' => 'iconsmall', 'title' => '')),
|
||||
$str->show,
|
||||
array('class' => 'editing_show', 'data-action' => 'show')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Duplicate (require both target import caps to be able to duplicate and backup2 support, see modduplicate.php)
|
||||
@@ -2039,61 +2039,30 @@ function course_get_cm_edit_actions(cm_info $mod, $indent = -1, $sr = null) {
|
||||
new moodle_url($baseurl, array('duplicate' => $mod->id)),
|
||||
new pix_icon('t/copy', $str->duplicate, 'moodle', array('class' => 'iconsmall', 'title' => '')),
|
||||
$str->duplicate,
|
||||
array('class' => 'editing_duplicate', 'data-action' => 'duplicate')
|
||||
array('class' => 'editing_duplicate', 'data-action' => 'duplicate', 'data-sr' => $sr)
|
||||
);
|
||||
}
|
||||
|
||||
// Delete.
|
||||
if ($hasmanageactivities) {
|
||||
$actions['delete'] = new action_menu_link_secondary(
|
||||
new moodle_url($baseurl, array('delete' => $mod->id)),
|
||||
new pix_icon('t/delete', $str->delete, 'moodle', array('class' => 'iconsmall', 'title' => '')),
|
||||
$str->delete,
|
||||
array('class' => 'editing_delete', 'data-action' => 'delete')
|
||||
);
|
||||
}
|
||||
|
||||
// Hide/Show.
|
||||
if (has_capability('moodle/course:activityvisibility', $modcontext)) {
|
||||
if ($mod->visible) {
|
||||
$actions['hide'] = new action_menu_link_primary(
|
||||
new moodle_url($baseurl, array('hide' => $mod->id)),
|
||||
new pix_icon('t/hide', $str->hide, 'moodle', array('class' => 'iconsmall', 'title' => '')),
|
||||
$str->hide,
|
||||
array('class' => 'editing_hide', 'data-action' => 'hide')
|
||||
);
|
||||
} else {
|
||||
$actions['show'] = new action_menu_link_primary(
|
||||
new moodle_url($baseurl, array('show' => $mod->id)),
|
||||
new pix_icon('t/show', $str->show, 'moodle', array('class' => 'iconsmall', 'title' => '')),
|
||||
$str->show,
|
||||
array('class' => 'editing_show', 'data-action' => 'show')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Groupmode.
|
||||
if ($hasmanageactivities and plugin_supports('mod', $mod->modname, FEATURE_GROUPS, 0)) {
|
||||
if ($mod->effectivegroupmode == SEPARATEGROUPS) {
|
||||
$nextgroupmode = VISIBLEGROUPS;
|
||||
$grouptitle = $str->groupsseparate;
|
||||
$forcedgrouptitle = $str->forcedgroupsseparate;
|
||||
$actionname = 'groupsseparate';
|
||||
$groupimage = 't/groups';
|
||||
} else if ($mod->effectivegroupmode == VISIBLEGROUPS) {
|
||||
$nextgroupmode = NOGROUPS;
|
||||
$grouptitle = $str->groupsvisible;
|
||||
$forcedgrouptitle = $str->forcedgroupsvisible;
|
||||
$actionname = 'groupsvisible';
|
||||
$groupimage = 't/groupv';
|
||||
} else {
|
||||
$nextgroupmode = SEPARATEGROUPS;
|
||||
$grouptitle = $str->groupsnone;
|
||||
$forcedgrouptitle = $str->forcedgroupsnone;
|
||||
$actionname = 'groupsnone';
|
||||
$groupimage = 't/groupn';
|
||||
}
|
||||
if (!$mod->coursegroupmodeforce) {
|
||||
if ($hasmanageactivities && !$mod->coursegroupmodeforce) {
|
||||
if (plugin_supports('mod', $mod->modname, FEATURE_GROUPS, 0)) {
|
||||
if ($mod->effectivegroupmode == SEPARATEGROUPS) {
|
||||
$nextgroupmode = VISIBLEGROUPS;
|
||||
$grouptitle = $str->groupsseparate;
|
||||
$actionname = 'groupsseparate';
|
||||
$groupimage = 'i/groups';
|
||||
} else if ($mod->effectivegroupmode == VISIBLEGROUPS) {
|
||||
$nextgroupmode = NOGROUPS;
|
||||
$grouptitle = $str->groupsvisible;
|
||||
$actionname = 'groupsvisible';
|
||||
$groupimage = 'i/groupv';
|
||||
} else {
|
||||
$nextgroupmode = SEPARATEGROUPS;
|
||||
$grouptitle = $str->groupsnone;
|
||||
$actionname = 'groupsnone';
|
||||
$groupimage = 'i/groupn';
|
||||
}
|
||||
|
||||
$actions[$actionname] = new action_menu_link_primary(
|
||||
new moodle_url($baseurl, array('id' => $mod->id, 'groupmode' => $nextgroupmode)),
|
||||
new pix_icon($groupimage, $grouptitle, 'moodle', array('class' => 'iconsmall', 'title' => '')),
|
||||
@@ -2101,7 +2070,7 @@ function course_get_cm_edit_actions(cm_info $mod, $indent = -1, $sr = null) {
|
||||
array('class' => 'editing_'. $actionname, 'data-action' => $actionname, 'data-nextgroupmode' => $nextgroupmode)
|
||||
);
|
||||
} else {
|
||||
$actions[$actionname] = new pix_icon($groupimage, $forcedgrouptitle, 'moodle', array('class' => 'iconsmall'));
|
||||
$actions['nogroupsupport'] = new action_menu_filler();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2115,9 +2084,111 @@ function course_get_cm_edit_actions(cm_info $mod, $indent = -1, $sr = null) {
|
||||
);
|
||||
}
|
||||
|
||||
// Delete.
|
||||
if ($hasmanageactivities) {
|
||||
$actions['delete'] = new action_menu_link_secondary(
|
||||
new moodle_url($baseurl, array('delete' => $mod->id)),
|
||||
new pix_icon('t/delete', $str->delete, 'moodle', array('class' => 'iconsmall', 'title' => '')),
|
||||
$str->delete,
|
||||
array('class' => 'editing_delete', 'data-action' => 'delete')
|
||||
);
|
||||
}
|
||||
|
||||
return $actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the rename action.
|
||||
*
|
||||
* @param cm_info $mod The module to produce editing buttons for
|
||||
* @param int $sr The section to link back to (used for creating the links)
|
||||
* @return The markup for the rename action, or an empty string if not available.
|
||||
*/
|
||||
function course_get_cm_rename_action(cm_info $mod, $sr = null) {
|
||||
global $COURSE, $OUTPUT;
|
||||
|
||||
static $str;
|
||||
static $baseurl;
|
||||
|
||||
$modcontext = context_module::instance($mod->id);
|
||||
$hasmanageactivities = has_capability('moodle/course:manageactivities', $modcontext);
|
||||
|
||||
if (!isset($str)) {
|
||||
$str = get_strings(array('edittitle'));
|
||||
}
|
||||
|
||||
if (!isset($baseurl)) {
|
||||
$baseurl = new moodle_url('/course/mod.php', array('sesskey' => sesskey()));
|
||||
}
|
||||
|
||||
if ($sr !== null) {
|
||||
$baseurl->param('sr', $sr);
|
||||
}
|
||||
|
||||
// AJAX edit title.
|
||||
if ($mod->has_view() && $hasmanageactivities && course_ajax_enabled($COURSE) &&
|
||||
(($mod->course == $COURSE->id) || ($mod->course == SITEID))) {
|
||||
// we will not display link if we are on some other-course page (where we should not see this module anyway)
|
||||
return html_writer::span(
|
||||
html_writer::link(
|
||||
new moodle_url($baseurl, array('update' => $mod->id)),
|
||||
$OUTPUT->pix_icon('t/editstring', '', 'moodle', array('class' => 'iconsmall visibleifjs', 'title' => '')),
|
||||
array(
|
||||
'class' => 'editing_title',
|
||||
'data-action' => 'edittitle',
|
||||
'title' => $str->edittitle,
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the move action.
|
||||
*
|
||||
* @param cm_info $mod The module to produce a move button for
|
||||
* @param int $sr The section to link back to (used for creating the links)
|
||||
* @return The markup for the move action, or an empty string if not available.
|
||||
*/
|
||||
function course_get_cm_move(cm_info $mod, $sr = null) {
|
||||
global $OUTPUT;
|
||||
|
||||
static $str;
|
||||
static $baseurl;
|
||||
|
||||
$modcontext = context_module::instance($mod->id);
|
||||
$hasmanageactivities = has_capability('moodle/course:manageactivities', $modcontext);
|
||||
|
||||
if (!isset($str)) {
|
||||
$str = get_strings(array('move'));
|
||||
}
|
||||
|
||||
if (!isset($baseurl)) {
|
||||
$baseurl = new moodle_url('/course/mod.php', array('sesskey' => sesskey()));
|
||||
|
||||
if ($sr !== null) {
|
||||
$baseurl->param('sr', $sr);
|
||||
}
|
||||
}
|
||||
|
||||
if ($hasmanageactivities) {
|
||||
$pixicon = 'i/dragdrop';
|
||||
|
||||
if ($mod->course == SITEID) {
|
||||
// Override for course frontpage until we get drag/drop working there.
|
||||
$pixicon = 't/move';
|
||||
}
|
||||
|
||||
return html_writer::link(
|
||||
new moodle_url($baseurl, array('copy' => $mod->id)),
|
||||
$OUTPUT->pix_icon($pixicon, $str->move, 'moodle', array('class' => 'iconsmall', 'title' => '')),
|
||||
array('class' => 'editing_move', 'data-action' => 'move')
|
||||
);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* given a course object with shortname & fullname, this function will
|
||||
* truncate the the number of chars allowed and add ... if it was too long
|
||||
@@ -3309,6 +3380,111 @@ function update_module($moduleinfo) {
|
||||
return $moduleinfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate a module on the course.
|
||||
*
|
||||
* @param object $course The course
|
||||
* @param object $cm The course module to duplicate
|
||||
* @throws moodle_exception if the plugin doesn't support duplication
|
||||
* @return Object containing:
|
||||
* - fullcontent: The HTML markup for the created CM
|
||||
* - cmid: The CMID of the newly created CM
|
||||
* - redirect: Whether to trigger a redirect following this change
|
||||
*/
|
||||
function mod_duplicate_activity($course, $cm, $sr = null) {
|
||||
global $CFG, $USER, $PAGE, $DB;
|
||||
|
||||
require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');
|
||||
require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php');
|
||||
require_once($CFG->libdir . '/filelib.php');
|
||||
|
||||
$a = new stdClass();
|
||||
$a->modtype = get_string('modulename', $cm->modname);
|
||||
$a->modname = format_string($cm->name);
|
||||
|
||||
if (!plugin_supports('mod', $cm->modname, FEATURE_BACKUP_MOODLE2)) {
|
||||
throw new moodle_exception('duplicatenosupport', 'error');
|
||||
}
|
||||
|
||||
// backup the activity
|
||||
|
||||
$bc = new backup_controller(backup::TYPE_1ACTIVITY, $cm->id, backup::FORMAT_MOODLE,
|
||||
backup::INTERACTIVE_NO, backup::MODE_IMPORT, $USER->id);
|
||||
|
||||
$backupid = $bc->get_backupid();
|
||||
$backupbasepath = $bc->get_plan()->get_basepath();
|
||||
|
||||
$bc->execute_plan();
|
||||
|
||||
$bc->destroy();
|
||||
|
||||
// restore the backup immediately
|
||||
|
||||
$rc = new restore_controller($backupid, $course->id,
|
||||
backup::INTERACTIVE_NO, backup::MODE_IMPORT, $USER->id, backup::TARGET_CURRENT_ADDING);
|
||||
|
||||
$cmcontext = context_module::instance($cm->id);
|
||||
if (!$rc->execute_precheck()) {
|
||||
$precheckresults = $rc->get_precheck_results();
|
||||
if (is_array($precheckresults) && !empty($precheckresults['errors'])) {
|
||||
if (empty($CFG->keeptempdirectoriesonbackup)) {
|
||||
fulldelete($backupbasepath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$rc->execute_plan();
|
||||
|
||||
// now a bit hacky part follows - we try to get the cmid of the newly
|
||||
// restored copy of the module
|
||||
$newcmid = null;
|
||||
$tasks = $rc->get_plan()->get_tasks();
|
||||
foreach ($tasks as $task) {
|
||||
error_log("Looking at a task");
|
||||
if (is_subclass_of($task, 'restore_activity_task')) {
|
||||
error_log("Looking at a restore_activity_task task");
|
||||
if ($task->get_old_contextid() == $cmcontext->id) {
|
||||
error_log("Contexts match");
|
||||
$newcmid = $task->get_moduleid();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if we know the cmid of the new course module, let us move it
|
||||
// right below the original one. otherwise it will stay at the
|
||||
// end of the section
|
||||
if ($newcmid) {
|
||||
$info = get_fast_modinfo($course);
|
||||
$newcm = $info->get_cm($newcmid);
|
||||
$section = $DB->get_record('course_sections', array('id' => $cm->section, 'course' => $cm->course));
|
||||
moveto_module($newcm, $section, $cm);
|
||||
moveto_module($cm, $section, $newcm);
|
||||
}
|
||||
rebuild_course_cache($cm->course);
|
||||
|
||||
$rc->destroy();
|
||||
|
||||
if (empty($CFG->keeptempdirectoriesonbackup)) {
|
||||
fulldelete($backupbasepath);
|
||||
}
|
||||
|
||||
$resp = new stdClass();
|
||||
if ($newcm) {
|
||||
$courserenderer = $PAGE->get_renderer('core', 'course');
|
||||
$completioninfo = new completion_info($course);
|
||||
$modulehtml = $courserenderer->course_section_cm($course, $completioninfo,
|
||||
$newcm, null, array());
|
||||
|
||||
$resp->fullcontent = $courserenderer->course_section_cm_list_item($course, $completioninfo, $newcm, $sr);
|
||||
$resp->cmid = $newcm->id;
|
||||
} else {
|
||||
// Trigger a redirect
|
||||
$resp->redirect = true;
|
||||
}
|
||||
return $resp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two objects to find out their correct order based on timestamp (to be used by usort).
|
||||
* Sorts by descending order of time.
|
||||
|
||||
@@ -364,9 +364,37 @@ class core_course_renderer extends plugin_renderer_base {
|
||||
$menu = new action_menu();
|
||||
$menu->set_owner_selector($ownerselector);
|
||||
$menu->set_constraint($constraint);
|
||||
$menu->set_alignment(action_menu::TL, action_menu::TR);
|
||||
$menu->set_alignment(action_menu::TR, action_menu::BR);
|
||||
$menu->set_menu_trigger(get_string('edit'));
|
||||
if (isset($CFG->modeditingmenu) && !$CFG->modeditingmenu || !empty($displayoptions['donotenhance'])) {
|
||||
$menu->do_not_enhance();
|
||||
|
||||
// Swap the left/right icons.
|
||||
// Normally we have have right, then left but this does not
|
||||
// make sense when modactionmenu is disabled.
|
||||
$moveright = null;
|
||||
$_actions = array();
|
||||
foreach ($actions as $key => $value) {
|
||||
if ($key === 'moveright') {
|
||||
|
||||
// Save moveright for later.
|
||||
$moveright = $value;
|
||||
} else if ($moveright) {
|
||||
|
||||
// This assumes that the order was moveright, moveleft.
|
||||
// If we have a moveright, then we should place it immediately after the current value.
|
||||
$_actions[$key] = $value;
|
||||
$_actions['moveright'] = $moveright;
|
||||
|
||||
// Clear the value to prevent it being used multiple times.
|
||||
$moveright = null;
|
||||
} else {
|
||||
|
||||
$_actions[$key] = $value;
|
||||
}
|
||||
}
|
||||
$actions = $_actions;
|
||||
unset($_actions);
|
||||
}
|
||||
foreach ($actions as $action) {
|
||||
if ($action instanceof action_menu_link) {
|
||||
@@ -375,6 +403,10 @@ class core_course_renderer extends plugin_renderer_base {
|
||||
$menu->add($action);
|
||||
}
|
||||
$menu->attributes['class'] .= ' section-cm-edit-actions commands';
|
||||
|
||||
// Prioritise the menu ahead of all other actions.
|
||||
$menu->prioritise = true;
|
||||
|
||||
return $this->render($menu);
|
||||
}
|
||||
|
||||
@@ -577,6 +609,9 @@ class core_course_renderer extends plugin_renderer_base {
|
||||
}
|
||||
$completion = $completioninfo->is_enabled($mod);
|
||||
if ($completion == COMPLETION_TRACKING_NONE) {
|
||||
if ($this->page->user_is_editing()) {
|
||||
$output .= html_writer::span(' ', 'filler');
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
@@ -612,7 +647,14 @@ class core_course_renderer extends plugin_renderer_base {
|
||||
if ($completionicon) {
|
||||
$formattedname = $mod->get_formatted_name();
|
||||
$imgalt = get_string('completion-alt-' . $completionicon, 'completion', $formattedname);
|
||||
if ($completion == COMPLETION_TRACKING_MANUAL && !$this->page->user_is_editing()) {
|
||||
|
||||
if ($this->page->user_is_editing()) {
|
||||
// When editing, the icon is just an image.
|
||||
$completionpixicon = new pix_icon('i/completion-'.$completionicon, $imgalt, '',
|
||||
array('title' => $imgalt, 'class' => 'iconsmall'));
|
||||
$output .= html_writer::tag('span', $this->output->render($completionpixicon),
|
||||
array('class' => 'autocompletion'));
|
||||
} else if ($completion == COMPLETION_TRACKING_MANUAL) {
|
||||
$imgtitle = get_string('completion-title-' . $completionicon, 'completion', $formattedname);
|
||||
$newstate =
|
||||
$completiondata->completionstate == COMPLETION_COMPLETE
|
||||
@@ -648,7 +690,7 @@ class core_course_renderer extends plugin_renderer_base {
|
||||
$output .= html_writer::end_tag('div');
|
||||
$output .= html_writer::end_tag('form');
|
||||
} else {
|
||||
// In auto mode, or when editing, the icon is just an image
|
||||
// In auto mode, the icon is just an image.
|
||||
$completionpixicon = new pix_icon('i/completion-'.$completionicon, $imgalt, '',
|
||||
array('title' => $imgalt));
|
||||
$output .= html_writer::tag('span', $this->output->render($completionpixicon),
|
||||
@@ -933,6 +975,13 @@ class core_course_renderer extends plugin_renderer_base {
|
||||
$indentclasses .= ' mod-indent-huge';
|
||||
}
|
||||
}
|
||||
|
||||
$output .= html_writer::start_tag('div');
|
||||
|
||||
if ($this->page->user_is_editing()) {
|
||||
$output .= course_get_cm_move($mod, $sectionreturn);
|
||||
}
|
||||
|
||||
$output .= html_writer::start_tag('div', array('class' => $indentclasses));
|
||||
|
||||
// Start the div for the activity title, excluding the edit icons.
|
||||
@@ -940,6 +989,9 @@ class core_course_renderer extends plugin_renderer_base {
|
||||
|
||||
// Display the link to the module (or do nothing if module has no url)
|
||||
$output .= $this->course_section_cm_name($mod, $displayoptions);
|
||||
if ($this->page->user_is_editing()) {
|
||||
$output .= ' ' . course_get_cm_rename_action($mod, $sectionreturn);
|
||||
}
|
||||
|
||||
// Module can put text after the link (e.g. forum unread)
|
||||
$output .= $mod->get_after_link();
|
||||
@@ -959,13 +1011,18 @@ class core_course_renderer extends plugin_renderer_base {
|
||||
$output .= $contentpart;
|
||||
}
|
||||
|
||||
$modicons = '';
|
||||
if ($this->page->user_is_editing()) {
|
||||
$editactions = course_get_cm_edit_actions($mod, $mod->indent, $sectionreturn);
|
||||
$output .= ' '. $this->course_section_cm_edit_actions($editactions, $mod, $displayoptions);
|
||||
$output .= $mod->get_after_edit_icons();
|
||||
$modicons .= ' '. $this->course_section_cm_edit_actions($editactions, $mod, $displayoptions);
|
||||
$modicons .= $mod->get_after_edit_icons();
|
||||
}
|
||||
|
||||
$output .= $this->course_section_cm_completion($course, $completioninfo, $mod, $displayoptions);
|
||||
$modicons .= $this->course_section_cm_completion($course, $completioninfo, $mod, $displayoptions);
|
||||
|
||||
if (!empty($modicons)) {
|
||||
$output .= html_writer::span($modicons, 'actions');
|
||||
}
|
||||
|
||||
// If there is content AND a link, then display the content here
|
||||
// (AFTER any icons). Otherwise it was displayed before
|
||||
@@ -976,7 +1033,9 @@ class core_course_renderer extends plugin_renderer_base {
|
||||
// show availability info (if module is not available)
|
||||
$output .= $this->course_section_cm_availability($mod, $displayoptions);
|
||||
|
||||
$output .= html_writer::end_tag('div'); // $indentclasses
|
||||
$output .= html_writer::end_tag('span'); // $indentclasses
|
||||
|
||||
$output .= html_writer::end_tag('div');
|
||||
return $output;
|
||||
}
|
||||
|
||||
|
||||
@@ -106,6 +106,18 @@ switch($requestmethod) {
|
||||
set_coursemodule_visible($cm->id, $value);
|
||||
break;
|
||||
|
||||
case 'duplicate':
|
||||
require_capability('moodle/course:manageactivities', $modcontext);
|
||||
require_capability('moodle/backup:backuptargetimport', $modcontext);
|
||||
require_capability('moodle/restore:restoretargetimport', $modcontext);
|
||||
if (!course_allowed_module($course, $cm->modname)) {
|
||||
throw new moodle_exception('No permission to create that activity');
|
||||
}
|
||||
$sr = optional_param('sr', null, PARAM_INT);
|
||||
$result = mod_duplicate_activity($course, $cm, $sr);
|
||||
echo json_encode($result);
|
||||
break;
|
||||
|
||||
case 'groupmode':
|
||||
require_capability('moodle/course:manageactivities', $modcontext);
|
||||
set_coursemodule_groupmode($cm->id, $value);
|
||||
|
||||
@@ -21,7 +21,7 @@ Feature: Toggle activities groups mode from the course page
|
||||
And I add a "Forum" to section "1" and I fill the form with:
|
||||
| Forum name | Test forum name |
|
||||
| Description | Test forum description |
|
||||
And I follow "Edit settings"
|
||||
And I click on "Edit settings" "link" in the "Administration" "block"
|
||||
And I fill the moodle form with:
|
||||
| Group mode | No groups |
|
||||
| Force group mode | No |
|
||||
|
||||
@@ -24,7 +24,8 @@ Feature: Toggle activities visibility from the course page
|
||||
| Forum name | Test forum name |
|
||||
| Description | Test forum description |
|
||||
| Visible | Show |
|
||||
When I click on "Hide" "link" in the "Test forum name" activity
|
||||
When I open "Test forum name" actions menu
|
||||
And I click on "Hide" "link" in the "Test forum name" activity
|
||||
Then "Test forum name" activity should be hidden
|
||||
And I click on "Show" "link" in the "Test forum name" activity
|
||||
And "Test forum name" activity should be visible
|
||||
|
||||
@@ -30,7 +30,7 @@ Feature: Add activities to courses
|
||||
And I turn editing mode off
|
||||
Then I should not see "Adding a new"
|
||||
And I follow "Test name"
|
||||
And I follow "Edit settings"
|
||||
And I click on "Edit settings" "link" in the "Administration" "block"
|
||||
And I expand all fieldsets
|
||||
And the "Name" field should match "Test name" value
|
||||
And the "Entries required for completion" field should match "9" value
|
||||
|
||||
@@ -327,6 +327,11 @@ class behat_course extends behat_base {
|
||||
|
||||
// Non-JS browsers can not click on img elements.
|
||||
if ($this->running_javascript()) {
|
||||
|
||||
// Expanding the actions menu.
|
||||
$actionsmenu = $this->find('css', "a[role='menuitem']", false, $activity);
|
||||
$actionsmenu->click();
|
||||
|
||||
// To check that the visibility is not clickable we check the funcionality rather than the applied style.
|
||||
$visibilityiconnode = $this->find('css', 'a.editing_show img', false, $activity);
|
||||
$visibilityiconnode->click();
|
||||
@@ -527,7 +532,6 @@ class behat_course extends behat_base {
|
||||
// Adding chr(10) to save changes.
|
||||
$activity = $this->escape($activityname);
|
||||
return array(
|
||||
new Given('I open "' . $activity . '" actions menu'),
|
||||
new Given('I click on "' . get_string('edittitle') . '" "link" in the "' . $activity .'" activity'),
|
||||
new Given('I fill in "title" with "' . $this->escape($newactivityname) . chr(10) . '"'),
|
||||
new Given('I wait "2" seconds')
|
||||
@@ -555,7 +559,7 @@ class behat_course extends behat_base {
|
||||
return;
|
||||
}
|
||||
|
||||
return new Given('I click on "' . get_string('actions', 'moodle') . '" "link" in the "' . $this->escape($activityname) . '" activity');
|
||||
return new Given('I click on "a[role=\'menuitem\']" "css_element" in the "' . $this->escape($activityname) . '" activity');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -654,8 +658,13 @@ class behat_course extends behat_base {
|
||||
$steps[] = new Given('I open "' . $activity . '" actions menu');
|
||||
}
|
||||
$steps[] = new Given('I click on "' . get_string('duplicate') . '" "link" in the "' . $activity . '" activity');
|
||||
$steps[] = new Given('I press "' . get_string('continue') .'"');
|
||||
$steps[] = new Given('I press "' . get_string('duplicatecontcourse') .'"');
|
||||
if ($this->running_javascript()) {
|
||||
// Temporary wait until MDL-41030 lands.
|
||||
$steps[] = new Given('I wait "4" seconds');
|
||||
} else {
|
||||
$steps[] = new Given('I press "' . get_string('continue') .'"');
|
||||
$steps[] = new Given('I press "' . get_string('duplicatecontcourse') .'"');
|
||||
}
|
||||
return $steps;
|
||||
}
|
||||
|
||||
@@ -668,14 +677,31 @@ class behat_course extends behat_base {
|
||||
* @return Given[]
|
||||
*/
|
||||
public function i_duplicate_activity_editing_the_new_copy_with($activityname, TableNode $data) {
|
||||
|
||||
$steps = array();
|
||||
|
||||
$activity = $this->escape($activityname);
|
||||
|
||||
if ($this->running_javascript()) {
|
||||
$steps[] = new Given('I open "' . $activity . '" actions menu');
|
||||
$steps[] = new Given('I duplicate "' . $activity . '" activity');
|
||||
|
||||
// Determine the future new activity xpath from the former one.
|
||||
$activityliteral = $this->getSession()->getSelectorsHandler()->xpathLiteral($activityname);
|
||||
$duplicatedxpath = "//li[contains(concat(' ', normalize-space(@class), ' '), ' activity ')][contains(., $activityliteral)]" .
|
||||
"/following-sibling::li";
|
||||
$duplicatedactionsmenuxpath = $duplicatedxpath . "/descendant::a[@role='menuitem']";
|
||||
|
||||
// The next sibling of the former activity will be the duplicated one, so we click on it from it's xpath as, at
|
||||
// this point, it don't even exists in the DOM (the steps are executed when we return them).
|
||||
$steps[] = new Given('I click on "' . $this->escape($duplicatedactionsmenuxpath) . '" "xpath_element"');
|
||||
|
||||
// We force the xpath as otherwise mink tries to interact with the former one.
|
||||
$steps[] = new Given('I click on "' . get_string('editsettings') . '" "link" in the "' . $this->escape($duplicatedxpath) . '" "xpath_element"');
|
||||
} else {
|
||||
$steps[] = new Given('I click on "' . get_string('duplicate') . '" "link" in the "' . $activity . '" activity');
|
||||
$steps[] = new Given('I press "' . get_string('continue') .'"');
|
||||
$steps[] = new Given('I press "' . get_string('duplicatecontedit') . '"');
|
||||
}
|
||||
$steps[] = new Given('I click on "' . get_string('duplicate') . '" "link" in the "' . $activity . '" activity');
|
||||
$steps[] = new Given('I press "' . get_string('continue') .'"');
|
||||
$steps[] = new Given('I press "' . get_string('duplicatecontedit') . '"');
|
||||
$steps[] = new Given('I fill the moodle form with:', $data);
|
||||
$steps[] = new Given('I press "' . get_string('savechangesandreturntocourse') . '"');
|
||||
return $steps;
|
||||
|
||||
@@ -56,7 +56,7 @@ Feature: Course activity controls works as expected
|
||||
And I indent left "Test forum name 1" activity
|
||||
And "#section-2" "css_element" <should_see_other_sections> exists
|
||||
And I open "Test forum name 1" actions menu
|
||||
And I click on "Update" "link" in the "Test forum name 1" activity
|
||||
And I click on "Edit settings" "link" in the "Test forum name 1" activity
|
||||
And I should see "Updating Forum"
|
||||
And I should see "Display description on course page"
|
||||
And I press "Save and return to course"
|
||||
@@ -128,7 +128,7 @@ Feature: Course activity controls works as expected
|
||||
And "#section-2" "css_element" <should_see_other_sections> exists
|
||||
And I indent left "Test forum name 1" activity
|
||||
And "#section-2" "css_element" <should_see_other_sections> exists
|
||||
And I click on "Update" "link" in the "Test forum name 1" activity
|
||||
And I click on "Edit settings" "link" in the "Test forum name 1" activity
|
||||
And I should see "Updating Forum"
|
||||
And I should see "Display description on course page"
|
||||
And I press "Save and return to course"
|
||||
|
||||
@@ -17,7 +17,7 @@ Feature: Edit course settings
|
||||
| teacher1 | C1 | editingteacher |
|
||||
And I log in as "teacher1"
|
||||
And I follow "Course 1"
|
||||
When I follow "Edit settings"
|
||||
When I click on "Edit settings" "link" in the "Administration" "block"
|
||||
And I fill the moodle form with:
|
||||
| Course full name | Edited course fullname |
|
||||
| Course short name | Edited course shortname |
|
||||
@@ -28,7 +28,7 @@ Feature: Edit course settings
|
||||
And I should not see "C1"
|
||||
And I should see "Edited course fullname"
|
||||
And I should see "Edited course shortname"
|
||||
And I follow "Edit settings"
|
||||
And I click on "Edit settings" "link" in the "Administration" "block"
|
||||
And the "Course full name" field should match "Edited course fullname" value
|
||||
And the "Course short name" field should match "Edited course shortname" value
|
||||
And the "Course summary" field should match "Edited course summary" value
|
||||
|
||||
@@ -20,7 +20,7 @@ Feature: Force group mode in a course
|
||||
And I add a "Chat" to section "1" and I fill the form with:
|
||||
| Name of this chat room | Chat room |
|
||||
| Description | Chat description |
|
||||
And I follow "Edit settings"
|
||||
And I click on "Edit settings" "link" in the "Administration" "block"
|
||||
|
||||
@javascript
|
||||
Scenario: Forced group mode using separate groups
|
||||
@@ -29,10 +29,7 @@ Feature: Force group mode in a course
|
||||
| Force group mode | Yes |
|
||||
When I press "Save changes"
|
||||
Then "//a/child::img[contains(@alt, 'Separate groups (forced mode)')]" "xpath_element" should not exists
|
||||
And "//img[contains(@alt, 'Separate groups (forced mode)')]" "xpath_element" should exists
|
||||
And I click on "//img[contains(@alt, 'Separate groups (forced mode)')]" "xpath_element" in the "li.activity.chat" "css_element"
|
||||
And "//a/child::img[contains(@alt, 'Separate groups (forced mode)')]" "xpath_element" should not exists
|
||||
And "//img[contains(@alt, 'Separate groups (forced mode)')]" "xpath_element" should exists
|
||||
And "//img[contains(@alt, 'Separate groups (forced mode)')]" "xpath_element" should not exists
|
||||
|
||||
@javascript
|
||||
Scenario: Forced group mode using visible groups
|
||||
@@ -41,10 +38,7 @@ Feature: Force group mode in a course
|
||||
| Force group mode | Yes |
|
||||
And I press "Save changes"
|
||||
Then "//a/child::img[contains(@alt, 'Visible groups (forced mode)')]" "xpath_element" should not exists
|
||||
And "//img[contains(@alt, 'Visible groups (forced mode)')]" "xpath_element" should exists
|
||||
And I click on "//img[contains(@alt, 'Visible groups (forced mode)')]" "xpath_element" in the "li.activity.chat" "css_element"
|
||||
And "//a/child::img[contains(@alt, 'Visible groups (forced mode)')]" "xpath_element" should not exists
|
||||
And "//img[contains(@alt, 'Visible groups (forced mode)')]" "xpath_element" should exists
|
||||
And "//img[contains(@alt, 'Visible groups (forced mode)')]" "xpath_element" should not exists
|
||||
|
||||
@javascript
|
||||
Scenario: Forced group mode without groups
|
||||
@@ -53,8 +47,5 @@ Feature: Force group mode in a course
|
||||
| Force group mode | Yes |
|
||||
And I press "Save changes"
|
||||
Then "//a/child::img[contains(@alt, 'No groups (forced mode)')]" "xpath_element" should not exists
|
||||
And "//img[contains(@alt, 'No groups (forced mode)')]" "xpath_element" should exists
|
||||
And I click on "//img[contains(@alt, 'No groups (forced mode)')]" "xpath_element" in the "li.activity.chat" "css_element"
|
||||
And "//a/child::img[contains(@alt, 'No groups (forced mode)')]" "xpath_element" should not exists
|
||||
And "//img[contains(@alt, 'No groups (forced mode)')]" "xpath_element" should exists
|
||||
And "//img[contains(@alt, 'No groups (forced mode)')]" "xpath_element" should not exists
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ Feature: Activities can be moved between sections
|
||||
And I should not see "Test forum name" in the "#section-1" "css_element"
|
||||
|
||||
Scenario: Move activities in the course home with Javascript disabled using paged mode
|
||||
Given I follow "Edit settings"
|
||||
Given I click on "Edit settings" "link" in the "Administration" "block"
|
||||
And I fill the moodle form with:
|
||||
| Course layout | Show one section per page |
|
||||
And I press "Save changes"
|
||||
@@ -42,7 +42,7 @@ Feature: Activities can be moved between sections
|
||||
And I should not see "Test forum name" in the "#section-1" "css_element"
|
||||
|
||||
Scenario: Move activities in a course section with Javascript disabled using paged mode
|
||||
Given I follow "Edit settings"
|
||||
Given I click on "Edit settings" "link" in the "Administration" "block"
|
||||
And I fill the moodle form with:
|
||||
| Course layout | Show one section per page |
|
||||
And I press "Save changes"
|
||||
|
||||
@@ -28,7 +28,7 @@ Feature: Sections can be moved
|
||||
And I should see "Test forum name" in the "#section-1" "css_element"
|
||||
|
||||
Scenario: Move up and down a section with Javascript disabled in the course home of a course using paged mode
|
||||
Given I follow "Edit settings"
|
||||
Given I click on "Edit settings" "link" in the "Administration" "block"
|
||||
And I fill the moodle form with:
|
||||
| Course layout | Show one section per page |
|
||||
And I press "Save changes"
|
||||
@@ -41,7 +41,7 @@ Feature: Sections can be moved
|
||||
And I should see "Test forum name" in the "#section-1" "css_element"
|
||||
|
||||
Scenario: Sections can not be moved with Javascript disabled in a section page of a course using paged mode
|
||||
Given I follow "Edit settings"
|
||||
Given I click on "Edit settings" "link" in the "Administration" "block"
|
||||
And I fill the moodle form with:
|
||||
| Course layout | Show one section per page |
|
||||
And I press "Save changes"
|
||||
|
||||
@@ -21,7 +21,7 @@ Feature: Rename roles within a course
|
||||
| student1 | C1 | student |
|
||||
And I log in as "teacher1"
|
||||
And I follow "Course 1"
|
||||
When I follow "Edit settings"
|
||||
When I click on "Edit settings" "link" in the "Administration" "block"
|
||||
And I fill the moodle form with:
|
||||
| Your word for 'Non-editing teacher' | Tutor |
|
||||
| Your word for 'Student' | Learner |
|
||||
@@ -33,7 +33,7 @@ Feature: Rename roles within a course
|
||||
And the "roleid" select box should contain "Tutor"
|
||||
And the "roleid" select box should contain "Learner"
|
||||
And the "roleid" select box should not contain "Student"
|
||||
And I follow "Edit settings"
|
||||
And I click on "Edit settings" "link" in the "Administration" "block"
|
||||
And I fill the moodle form with:
|
||||
| Your word for 'Non-editing teacher' | |
|
||||
| Your word for 'Student' | |
|
||||
|
||||
@@ -2,6 +2,7 @@ YUI.add('moodle-course-dragdrop', function(Y) {
|
||||
|
||||
var CSS = {
|
||||
ACTIVITY : 'activity',
|
||||
ACTIVITYINSTANCE : 'activityinstance',
|
||||
COMMANDSPAN : '.commands',
|
||||
CONTENT : 'content',
|
||||
COURSECONTENT : 'course-content',
|
||||
@@ -277,7 +278,7 @@ YUI.add('moodle-course-dragdrop', function(Y) {
|
||||
this.groups = ['resource'];
|
||||
this.samenodeclass = CSS.ACTIVITY;
|
||||
this.parentnodeclass = CSS.SECTION;
|
||||
this.resourcedraghandle = this.get_drag_handle(M.str.moodle.move, CSS.EDITINGMOVE, CSS.ICONCLASS);
|
||||
this.resourcedraghandle = this.get_drag_handle(M.str.moodle.move, CSS.EDITINGMOVE, CSS.ICONCLASS, true);
|
||||
|
||||
// Go through all sections
|
||||
var sectionlistselector = M.course.format.get_section_selector(Y);
|
||||
@@ -374,12 +375,14 @@ YUI.add('moodle-course-dragdrop', function(Y) {
|
||||
var dropnode = e.drop.get('node');
|
||||
|
||||
// Add spinner if it not there
|
||||
var spinner = M.util.add_spinner(Y, dragnode.one(CSS.COMMANDSPAN));
|
||||
var activityinstance = dragnode.one('.' + CSS.ACTIVITYINSTANCE);
|
||||
var spinner = M.util.add_spinner(Y, activityinstance);
|
||||
|
||||
var params = {};
|
||||
|
||||
// Handle any variables which we must pass back through to
|
||||
var pageparams = this.get('config').pageparams;
|
||||
var varname;
|
||||
for (varname in pageparams) {
|
||||
params[varname] = pageparams[varname];
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ YUI.add('moodle-course-toolboxes', function(Y) {
|
||||
DIMCLASS : 'dimmed',
|
||||
DIMMEDTEXT : 'dimmed_text',
|
||||
EDITINSTRUCTIONS : 'editinstructions',
|
||||
EDITINGTITLE: 'editor_displayed',
|
||||
HIDE : 'hide',
|
||||
MODINDENTCOUNT : 'mod-indent-',
|
||||
MODINDENTHUGE : 'mod-indent-huge',
|
||||
@@ -25,22 +26,29 @@ YUI.add('moodle-course-toolboxes', function(Y) {
|
||||
// The CSS selectors we use.
|
||||
SELECTOR = {
|
||||
ACTIONLINKTEXT : '.actionlinktext',
|
||||
ACTIVITYACTION : 'a.cm-edit-action[data-action]',
|
||||
ACTIVITYFORM : 'form.'+CSS.ACTIVITYINSTANCE,
|
||||
ACTIVITYACTION : 'a.cm-edit-action[data-action], a.editing_title',
|
||||
ACTIVITYFORM : '.' + CSS.ACTIVITYINSTANCE + ' form',
|
||||
ACTIVITYICON : 'img.activityicon',
|
||||
ACTIVITYINSTANCE : '.' + CSS.ACTIVITYINSTANCE,
|
||||
ACTIVITYLINK: '.' + CSS.ACTIVITYINSTANCE + ' > a',
|
||||
ACTIVITYLI : 'li.activity',
|
||||
ACTIVITYTITLE : 'input[name=title]',
|
||||
COMMANDSPAN : '.commands',
|
||||
CONTENTAFTERLINK : 'div.contentafterlink',
|
||||
EDITTITLE: 'a.editing_title',
|
||||
HIDE : 'a.editing_hide',
|
||||
HIGHLIGHT : 'a.editing_highlight',
|
||||
INSTANCENAME : 'span.instancename',
|
||||
MODINDENTDIV : 'div.mod-indent',
|
||||
MODINDENTDIV : '.mod-indent',
|
||||
PAGECONTENT : 'div#page-content',
|
||||
SECTIONLI : 'li.section',
|
||||
SHOW : 'a.'+CSS.SHOW,
|
||||
SHOWHIDE : 'a.editing_showhide'
|
||||
},
|
||||
INDENTLIMITS = {
|
||||
MIN: 0,
|
||||
MAX: 16
|
||||
},
|
||||
BODY = Y.one(document.body);
|
||||
|
||||
/**
|
||||
@@ -52,24 +60,27 @@ YUI.add('moodle-course-toolboxes', function(Y) {
|
||||
*/
|
||||
var TOOLBOX = function() {
|
||||
TOOLBOX.superclass.constructor.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
|
||||
Y.extend(TOOLBOX, Y.Base, {
|
||||
/**
|
||||
* Send a request using the REST API
|
||||
*
|
||||
* @method send_request
|
||||
* @param data The data to submit
|
||||
* @param statusspinner (optional) A statusspinner which may contain a section loader
|
||||
* @param {Function} success_callback The callback to use on success
|
||||
* @param optionalconfig (optional) Any additional configuration to submit
|
||||
* @return response responseText field from responce
|
||||
* @return response responseText field from response - please use success_callback instead
|
||||
*/
|
||||
send_request : function(data, statusspinner, optionalconfig) {
|
||||
send_request : function(data, statusspinner, success_callback, optionalconfig) {
|
||||
// Default data structure
|
||||
if (!data) {
|
||||
data = {};
|
||||
}
|
||||
// Handle any variables which we must pass back through to
|
||||
var pageparams = this.get('config').pageparams;
|
||||
var pageparams = this.get('config').pageparams,
|
||||
varname;
|
||||
for (varname in pageparams) {
|
||||
data[varname] = pageparams[varname];
|
||||
}
|
||||
@@ -92,8 +103,14 @@ YUI.add('moodle-course-toolboxes', function(Y) {
|
||||
new M.core.ajaxException(responsetext);
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
// Run the callback if we have one.
|
||||
if (success_callback) {
|
||||
Y.bind(success_callback, this, responsetext)();
|
||||
}
|
||||
|
||||
if (statusspinner) {
|
||||
window.setTimeout(function(e) {
|
||||
window.setTimeout(function() {
|
||||
statusspinner.hide();
|
||||
}, 400);
|
||||
}
|
||||
@@ -105,9 +122,8 @@ YUI.add('moodle-course-toolboxes', function(Y) {
|
||||
new M.core.ajaxException(response);
|
||||
}
|
||||
},
|
||||
context: this,
|
||||
sync: true
|
||||
}
|
||||
context: this
|
||||
};
|
||||
|
||||
// Apply optional config
|
||||
if (optionalconfig) {
|
||||
@@ -249,6 +265,10 @@ YUI.add('moodle-course-toolboxes', function(Y) {
|
||||
// The user is deleting the activity.
|
||||
this.delete_with_confirmation(ev, node, activity, action);
|
||||
break;
|
||||
case 'duplicate' :
|
||||
// The user is duplicating the activity.
|
||||
this.duplicate(ev, node, activity, action);
|
||||
break;
|
||||
case 'hide' :
|
||||
case 'show' :
|
||||
// The user is changing the visibility of the activity.
|
||||
@@ -270,6 +290,15 @@ YUI.add('moodle-course-toolboxes', function(Y) {
|
||||
break;
|
||||
}
|
||||
},
|
||||
add_spinner: function(activity) {
|
||||
var instance = activity.one(SELECTOR.ACTIVITYINSTANCE);
|
||||
|
||||
if (instance) {
|
||||
return M.util.add_spinner(Y, instance);
|
||||
} else {
|
||||
return M.util.add_spinner(Y, activity);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Change the indent of the activity or resource.
|
||||
@@ -288,16 +317,22 @@ YUI.add('moodle-course-toolboxes', function(Y) {
|
||||
var direction = (action === 'moveleft') ? -1 : 1;
|
||||
|
||||
// And we need to determine the current and new indent level
|
||||
var indentdiv = activity.one(SELECTOR.MODINDENTDIV);
|
||||
var indent = indentdiv.getAttribute('class').match(/mod-indent-(\d{1,})/);
|
||||
var indentdiv = activity.one(SELECTOR.MODINDENTDIV),
|
||||
indent = indentdiv.getAttribute('class').match(/mod-indent-(\d{1,})/),
|
||||
oldindent = 0,
|
||||
newindent;
|
||||
|
||||
if (indent) {
|
||||
oldindent = parseInt(indent[1], 10);
|
||||
}
|
||||
newindent = oldindent + parseInt(direction, 10);
|
||||
|
||||
if (newindent < INDENTLIMITS.MIN || newindent > INDENTLIMITS.MAX) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (indent) {
|
||||
var oldindent = parseInt(indent[1]);
|
||||
var newindent = Math.max(0, (oldindent + parseInt(direction)));
|
||||
indentdiv.removeClass(indent[0]);
|
||||
} else {
|
||||
var oldindent = 0;
|
||||
var newindent = 1;
|
||||
}
|
||||
|
||||
// Perform the move
|
||||
@@ -308,11 +343,7 @@ YUI.add('moodle-course-toolboxes', function(Y) {
|
||||
'value' : newindent,
|
||||
'id' : Y.Moodle.core_course.util.cm.getId(activity)
|
||||
};
|
||||
var commands = activity.one(SELECTOR.COMMANDSPAN);
|
||||
var spinner = M.util.add_spinner(Y, commands).setStyles({
|
||||
position: 'absolute',
|
||||
top: 0
|
||||
});
|
||||
var spinner = this.add_spinner(activity);
|
||||
if (BODY.hasClass('dir-ltr')) {
|
||||
spinner.setStyle('left', '100%');
|
||||
} else {
|
||||
@@ -321,12 +352,18 @@ YUI.add('moodle-course-toolboxes', function(Y) {
|
||||
this.send_request(data, spinner);
|
||||
|
||||
// Handle removal/addition of the moveleft button.
|
||||
if (newindent == 0) {
|
||||
if (newindent === INDENTLIMITS.MIN) {
|
||||
button.addClass('hidden');
|
||||
} else if (newindent == 1 && oldindent == 0) {
|
||||
} else if (newindent > INDENTLIMITS.MIN && oldindent === INDENTLIMITS.MIN) {
|
||||
button.ancestor('.menu').one('[data-action=moveleft]').removeClass('hidden');
|
||||
}
|
||||
|
||||
if (newindent === INDENTLIMITS.MAX) {
|
||||
button.addClass('hidden');
|
||||
} else if (newindent < INDENTLIMITS.MAX && oldindent === INDENTLIMITS.MAX) {
|
||||
button.ancestor('.menu').one('[data-action=moveright]').removeClass('hidden');
|
||||
}
|
||||
|
||||
// Handle massive indentation to match non-ajax display
|
||||
var hashugeclass = indentdiv.hasClass(CSS.MODINDENTHUGE);
|
||||
if (newindent > 15 && !hashugeclass) {
|
||||
@@ -383,6 +420,48 @@ YUI.add('moodle-course-toolboxes', function(Y) {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Duplicates the activity
|
||||
*
|
||||
* @protected
|
||||
* @method duplicate
|
||||
* @param {EventFacade} ev The event that was fired.
|
||||
* @param {Node} button The button that triggered this action.
|
||||
* @param {Node} activity The activity node that this action will be performed on.
|
||||
* @return Boolean
|
||||
*/
|
||||
duplicate : function(ev, button, activity) {
|
||||
// Prevent the default button action
|
||||
ev.preventDefault();
|
||||
|
||||
// Get the element we're working on
|
||||
var element = activity;
|
||||
|
||||
// Add the lightbox.
|
||||
var section = activity.ancestor(M.course.format.get_section_selector(Y)),
|
||||
lightbox = M.util.add_lightbox(Y, section).show();
|
||||
|
||||
// Build and send the request.
|
||||
var data = {
|
||||
'class' : 'resource',
|
||||
'field' : 'duplicate',
|
||||
'id' : Y.Moodle.core_course.util.cm.getId(element),
|
||||
'sr' : button.getData('sr')
|
||||
};
|
||||
this.send_request(data, lightbox, function(response) {
|
||||
var newcm = Y.Node.create(response.fullcontent);
|
||||
|
||||
// Append to the section?
|
||||
activity.insert(newcm, 'after');
|
||||
Y.use('moodle-course-coursebase', function() {
|
||||
M.course.coursebase.invoke_function('setup_for_resource', newcm);
|
||||
});
|
||||
if (M.core.actionmenu && M.core.actionmenu.newDOMNode) {
|
||||
M.core.actionmenu.newDOMNode(newcm);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the visibility of this activity or resource.
|
||||
*
|
||||
@@ -415,7 +494,7 @@ YUI.add('moodle-course-toolboxes', function(Y) {
|
||||
'value' : value,
|
||||
'id' : Y.Moodle.core_course.util.cm.getId(element)
|
||||
};
|
||||
var spinner = M.util.add_spinner(Y, element.one(SELECTOR.COMMANDSPAN));
|
||||
var spinner = this.add_spinner(element);
|
||||
this.send_request(data, spinner);
|
||||
return false; // Need to return false to stop the delegate for the new state firing
|
||||
},
|
||||
@@ -434,7 +513,8 @@ YUI.add('moodle-course-toolboxes', function(Y) {
|
||||
var toggleclass = CSS.DIMCLASS,
|
||||
dimarea = activity.one('a'),
|
||||
availabilityinfo = activity.one(CSS.AVAILABILITYINFODIV),
|
||||
nextaction = (action === 'hide') ? 'show' : 'hide';
|
||||
nextaction = (action === 'hide') ? 'show' : 'hide',
|
||||
buttontext = button.one('span'),
|
||||
newstring = M.util.get_string(nextaction, 'moodle');
|
||||
|
||||
// Update button info.
|
||||
@@ -445,9 +525,12 @@ YUI.add('moodle-course-toolboxes', function(Y) {
|
||||
button.set('title', newstring);
|
||||
button.replaceClass('editing_'+action, 'editing_'+nextaction);
|
||||
button.setData('action', nextaction);
|
||||
if (buttontext) {
|
||||
buttontext.set('text', newstring);
|
||||
}
|
||||
|
||||
// If activity is conditionally hidden, then don't toggle.
|
||||
if (Y.Moodle.core_course.util.cm.getName(activity) == null) {
|
||||
if (Y.Moodle.core_course.util.cm.getName(activity) === null) {
|
||||
toggleclass = CSS.DIMMEDTEXT;
|
||||
dimarea = activity.all(SELECTOR.MODINDENTDIV + ' > div').item(1);
|
||||
}
|
||||
@@ -494,13 +577,13 @@ YUI.add('moodle-course-toolboxes', function(Y) {
|
||||
|
||||
if (groupmode === this.GROUPS_NONE) {
|
||||
newtitle = 'groupsnone';
|
||||
iconsrc = M.util.image_url('t/groupn', 'moodle');
|
||||
iconsrc = M.util.image_url('i/groupn', 'moodle');
|
||||
} else if (groupmode === this.GROUPS_SEPARATE) {
|
||||
newtitle = 'groupsseparate';
|
||||
iconsrc = M.util.image_url('t/groups', 'moodle');
|
||||
iconsrc = M.util.image_url('i/groups', 'moodle');
|
||||
} else if (groupmode === this.GROUPS_VISIBLE) {
|
||||
newtitle = 'groupsvisible';
|
||||
iconsrc = M.util.image_url('t/groupv', 'moodle');
|
||||
iconsrc = M.util.image_url('i/groupv', 'moodle');
|
||||
}
|
||||
newtitlestr = M.util.get_string(newtitle, 'moodle'),
|
||||
newtitlestr = M.util.get_string('clicktochangeinbrackets', 'moodle', newtitlestr);
|
||||
@@ -520,7 +603,7 @@ YUI.add('moodle-course-toolboxes', function(Y) {
|
||||
'id' : Y.Moodle.core_course.util.cm.getId(activity)
|
||||
};
|
||||
|
||||
spinner = M.util.add_spinner(Y, activity.one(SELECTOR.COMMANDSPAN));
|
||||
spinner = this.add_spinner(activity);
|
||||
this.send_request(data, spinner);
|
||||
return false; // Need to return false to stop the delegate for the new state firing
|
||||
},
|
||||
@@ -549,49 +632,55 @@ YUI.add('moodle-course-toolboxes', function(Y) {
|
||||
'class' : 'resource',
|
||||
'field' : 'gettitle',
|
||||
'id' : activityid
|
||||
},
|
||||
response = this.send_request(data);
|
||||
};
|
||||
|
||||
if (M.core.actionmenu && M.core.actionmenu.instance) {
|
||||
M.core.actionmenu.instance.hideMenu();
|
||||
}
|
||||
|
||||
// Try to retrieve the existing string from the server
|
||||
if (response.instancename) {
|
||||
titletext = response.instancename;
|
||||
}
|
||||
|
||||
// Create the editor and submit button
|
||||
var editform = Y.Node.create('<form class="'+CSS.ACTIVITYINSTANCE+'" action="#" />');
|
||||
var editinstructions = Y.Node.create('<span class="'+CSS.EDITINSTRUCTIONS+'" id="id_editinstructions" />')
|
||||
.set('innerHTML', M.util.get_string('edittitleinstructions', 'moodle'));
|
||||
var editor = Y.Node.create('<input name="title" type="text" class="'+CSS.TITLEEDITOR+'" />').setAttrs({
|
||||
'value' : titletext,
|
||||
'autocomplete' : 'off',
|
||||
'aria-describedby' : 'id_editinstructions',
|
||||
'maxLength' : '255'
|
||||
})
|
||||
|
||||
// Clear the existing content and put the editor in
|
||||
editform.appendChild(activity.one(SELECTOR.ACTIVITYICON).cloneNode());
|
||||
editform.appendChild(editor);
|
||||
editform.setData('anchor', anchor);
|
||||
anchor.replace(editform);
|
||||
activity.one('div').appendChild(editinstructions);
|
||||
// Prevent the default actions.
|
||||
ev.preventDefault();
|
||||
|
||||
// Focus and select the editor text
|
||||
editor.focus().select();
|
||||
this.send_request(data, null, function(response) {
|
||||
if (M.core.actionmenu && M.core.actionmenu.instance) {
|
||||
M.core.actionmenu.instance.hideMenu();
|
||||
}
|
||||
|
||||
// Cancel the edit if we lose focus or the escape key is pressed.
|
||||
thisevent = editor.on('blur', this.edit_title_cancel, this, activity, false);
|
||||
this.edittitleevents.push(thisevent);
|
||||
thisevent = editor.on('key', this.edit_title_cancel, 'esc', this, activity, true);
|
||||
this.edittitleevents.push(thisevent);
|
||||
// Try to retrieve the existing string from the server
|
||||
if (response.instancename) {
|
||||
titletext = response.instancename;
|
||||
}
|
||||
|
||||
// Handle form submission.
|
||||
thisevent = editform.on('submit', this.edit_title_submit, this, activity, oldtitle);
|
||||
this.edittitleevents.push(thisevent);
|
||||
// Create the editor and submit button
|
||||
var editform = Y.Node.create('<form action="#" />');
|
||||
var editinstructions = Y.Node.create('<span class="'+CSS.EDITINSTRUCTIONS+'" id="id_editinstructions" />')
|
||||
.set('innerHTML', M.util.get_string('edittitleinstructions', 'moodle'));
|
||||
var editor = Y.Node.create('<input name="title" type="text" class="'+CSS.TITLEEDITOR+'" />').setAttrs({
|
||||
'value' : titletext,
|
||||
'autocomplete' : 'off',
|
||||
'aria-describedby' : 'id_editinstructions',
|
||||
'maxLength' : '255'
|
||||
});
|
||||
|
||||
// Clear the existing content and put the editor in
|
||||
editform.appendChild(activity.one(SELECTOR.ACTIVITYICON).cloneNode());
|
||||
editform.appendChild(editor);
|
||||
editform.setData('anchor', anchor);
|
||||
anchor.replace(editform);
|
||||
activity.one('div').appendChild(editinstructions);
|
||||
|
||||
// We hide various components whilst editing:
|
||||
activity.addClass(CSS.EDITINGTITLE);
|
||||
|
||||
// Focus and select the editor text
|
||||
editor.focus().select();
|
||||
|
||||
// Cancel the edit if we lose focus or the escape key is pressed.
|
||||
thisevent = editor.on('blur', this.edit_title_cancel, this, activity, false);
|
||||
this.edittitleevents.push(thisevent);
|
||||
thisevent = editor.on('key', this.edit_title_cancel, 'esc', this, activity, true);
|
||||
this.edittitleevents.push(thisevent);
|
||||
|
||||
// Handle form submission.
|
||||
thisevent = editform.on('submit', this.edit_title_submit, this, activity, oldtitle);
|
||||
this.edittitleevents.push(thisevent);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -609,7 +698,7 @@ YUI.add('moodle-course-toolboxes', function(Y) {
|
||||
|
||||
var newtitle = Y.Lang.trim(activity.one(SELECTOR.ACTIVITYFORM + ' ' + SELECTOR.ACTIVITYTITLE).get('value'));
|
||||
this.edit_title_clear(activity);
|
||||
var spinner = M.util.add_spinner(Y, activity.one(SELECTOR.INSTANCENAME));
|
||||
var spinner = this.add_spinner(activity);
|
||||
if (newtitle != null && newtitle != "" && newtitle != originaltitle) {
|
||||
var data = {
|
||||
'class' : 'resource',
|
||||
@@ -617,10 +706,11 @@ YUI.add('moodle-course-toolboxes', function(Y) {
|
||||
'title' : newtitle,
|
||||
'id' : Y.Moodle.core_course.util.cm.getId(activity)
|
||||
};
|
||||
var response = this.send_request(data, spinner);
|
||||
if (response.instancename) {
|
||||
activity.one(SELECTOR.INSTANCENAME).setContent(response.instancename);
|
||||
}
|
||||
this.send_request(data, spinner, function(response) {
|
||||
if (response.instancename) {
|
||||
activity.one(SELECTOR.INSTANCENAME).setContent(response.instancename);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
@@ -661,6 +751,14 @@ YUI.add('moodle-course-toolboxes', function(Y) {
|
||||
if (instructions) {
|
||||
instructions.remove();
|
||||
}
|
||||
|
||||
// Remove the editing class again to revert the display.
|
||||
activity.removeClass(CSS.EDITINGTITLE);
|
||||
|
||||
// Refocus the link which was clicked originally so the user can continue using keyboard nav.
|
||||
Y.later(100, this, function() {
|
||||
activity.one(SELECTOR.EDITTITLE).focus();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -781,23 +879,24 @@ YUI.add('moodle-course-toolboxes', function(Y) {
|
||||
var lightbox = M.util.add_lightbox(Y, section);
|
||||
lightbox.show();
|
||||
|
||||
var response = this.send_request(data, lightbox);
|
||||
this.send_request(data, lightbox, function(response) {
|
||||
var activities = section.all(SELECTOR.ACTIVITYLI);
|
||||
activities.each(function(node) {
|
||||
var button;
|
||||
if (node.one(SELECTOR.SHOW)) {
|
||||
button = node.one(SELECTOR.SHOW);
|
||||
} else {
|
||||
button = node.one(SELECTOR.HIDE);
|
||||
}
|
||||
var activityid = Y.Moodle.core_course.util.cm.getId(node);
|
||||
|
||||
var activities = section.all(SELECTOR.ACTIVITYLI);
|
||||
activities.each(function(node) {
|
||||
if (node.one(SELECTOR.SHOW)) {
|
||||
var button = node.one(SELECTOR.SHOW);
|
||||
} else {
|
||||
var button = node.one(SELECTOR.HIDE);
|
||||
}
|
||||
var activityid = Y.Moodle.core_course.util.cm.getId(node);
|
||||
|
||||
// NOTE: resourcestotoggle is returned as a string instead
|
||||
// of a Number so we must cast our activityid to a String.
|
||||
if (Y.Array.indexOf(response.resourcestotoggle, "" + activityid) != -1) {
|
||||
M.course.resource_toolbox.handle_resource_dim(button, node, action);
|
||||
}
|
||||
}, this);
|
||||
// NOTE: resourcestotoggle is returned as a string instead
|
||||
// of a Number so we must cast our activityid to a String.
|
||||
if (Y.Array.indexOf(response.resourcestotoggle, "" + activityid) !== -1) {
|
||||
M.course.resource_toolbox.handle_resource_dim(button, node, action);
|
||||
}
|
||||
}, this);
|
||||
});
|
||||
},
|
||||
toggle_highlight : function(e) {
|
||||
// Prevent the default button action
|
||||
|
||||
@@ -21,7 +21,7 @@ Feature: Guest users can auto-enrol themself in courses where guest access is al
|
||||
And I add a "Forum" to section "1" and I fill the form with:
|
||||
| Forum name | Test forum name |
|
||||
| Description | Test forum description |
|
||||
And I follow "Edit settings"
|
||||
And I click on "Edit settings" "link" in the "Administration" "block"
|
||||
|
||||
@javascript
|
||||
Scenario: Allow guest access without password
|
||||
|
||||
@@ -529,6 +529,7 @@ $string['edita'] = 'Edit {$a}';
|
||||
$string['editcategorysettings'] = 'Edit category settings';
|
||||
$string['editcategorythis'] = 'Edit this category';
|
||||
$string['editcoursesettings'] = 'Edit course settings';
|
||||
$string['editsettings'] = 'Edit settings';
|
||||
$string['editfiles'] = 'Edit files';
|
||||
$string['editgroupprofile'] = 'Edit group profile';
|
||||
$string['editinga'] = 'Editing {$a}';
|
||||
@@ -763,7 +764,6 @@ $string['followingoptional'] = 'The following items are optional';
|
||||
$string['followingrequired'] = 'The following items are required';
|
||||
$string['for'] = 'For';
|
||||
$string['force'] = 'Force';
|
||||
$string['forcedmodeinbrackets'] = '{$a} (forced mode)';
|
||||
$string['forcelanguage'] = 'Force language';
|
||||
$string['forceno'] = 'Do not force';
|
||||
$string['forcepasswordchange'] = 'Force password change';
|
||||
|
||||
@@ -1050,7 +1050,7 @@ class block_manager {
|
||||
if ($this->page->user_can_edit_blocks() || $block->user_can_edit()) {
|
||||
// Edit config icon - always show - needed for positioning UI.
|
||||
$str = new lang_string('configureblock', 'block', $blocktitle);
|
||||
$controls[] = new action_menu_link_primary(
|
||||
$controls[] = new action_menu_link_secondary(
|
||||
new moodle_url($actionurl, array('bui_editid' => $block->instance->id)),
|
||||
new pix_icon('t/edit', $str, 'moodle', array('class' => 'iconsmall', 'title' => '')),
|
||||
$str,
|
||||
@@ -1059,17 +1059,6 @@ class block_manager {
|
||||
|
||||
}
|
||||
|
||||
if ($this->user_can_delete_block($block)) {
|
||||
// Delete icon.
|
||||
$str = new lang_string('deleteblock', 'block', $blocktitle);
|
||||
$controls[] = new action_menu_link_secondary(
|
||||
new moodle_url($actionurl, array('bui_deleteid' => $block->instance->id)),
|
||||
new pix_icon('t/delete', $str, 'moodle', array('class' => 'iconsmall', 'title' => '')),
|
||||
$str,
|
||||
array('class' => 'editing_delete')
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->page->user_can_edit_blocks() && $block->instance_can_be_hidden()) {
|
||||
// Show/hide icon.
|
||||
if ($block->instance->visible) {
|
||||
@@ -1083,7 +1072,7 @@ class block_manager {
|
||||
$icon = new pix_icon('t/show', $str, 'moodle', array('class' => 'iconsmall', 'title' => ''));
|
||||
$attributes = array('class' => 'editing_show');
|
||||
}
|
||||
$controls[] = new action_menu_link_primary($url, $icon, $str, $attributes);
|
||||
$controls[] = new action_menu_link_secondary($url, $icon, $str, $attributes);
|
||||
}
|
||||
|
||||
// Assign roles icon.
|
||||
@@ -1105,6 +1094,18 @@ class block_manager {
|
||||
array('class' => 'editing_roles')
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->user_can_delete_block($block)) {
|
||||
// Delete icon.
|
||||
$str = new lang_string('deleteblock', 'block', $blocktitle);
|
||||
$controls[] = new action_menu_link_secondary(
|
||||
new moodle_url($actionurl, array('bui_deleteid' => $block->instance->id)),
|
||||
new pix_icon('t/delete', $str, 'moodle', array('class' => 'iconsmall', 'title' => '')),
|
||||
$str,
|
||||
array('class' => 'editing_delete')
|
||||
);
|
||||
}
|
||||
|
||||
return $controls;
|
||||
}
|
||||
|
||||
|
||||
@@ -3109,10 +3109,22 @@ class action_menu implements renderable {
|
||||
|
||||
/**
|
||||
* An icon to use for the toggling the secondary menu (dropdown).
|
||||
* @var pix_icon
|
||||
* @var actionicon
|
||||
*/
|
||||
public $actionicon;
|
||||
|
||||
/**
|
||||
* Any text to use for the toggling the secondary menu (dropdown).
|
||||
* @var menutrigger
|
||||
*/
|
||||
public $menutrigger = '';
|
||||
|
||||
/**
|
||||
* Place the action menu before all other actions.
|
||||
* @var prioritise
|
||||
*/
|
||||
public $prioritise = false;
|
||||
|
||||
/**
|
||||
* Constructs the action menu with the given items.
|
||||
*
|
||||
@@ -3140,18 +3152,16 @@ class action_menu implements renderable {
|
||||
'aria-labelledby' => 'action-menu-toggle-'.$this->instance,
|
||||
'role' => 'menu'
|
||||
);
|
||||
$this->actionicon = new pix_icon(
|
||||
't/contextmenu',
|
||||
new lang_string('actions', 'moodle'),
|
||||
'moodle',
|
||||
array('class' => 'iconsmall', 'title' => '')
|
||||
);
|
||||
$this->set_alignment(self::TR, self::BR);
|
||||
foreach ($actions as $action) {
|
||||
$this->add($action);
|
||||
}
|
||||
}
|
||||
|
||||
public function set_menu_trigger($trigger) {
|
||||
$this->menutrigger = $trigger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialises JS required fore the action menu.
|
||||
* The JS is only required once as it manages all action menu's on the page.
|
||||
@@ -3172,7 +3182,7 @@ class action_menu implements renderable {
|
||||
* @param action_menu_link|pix_icon|string $action
|
||||
*/
|
||||
public function add($action) {
|
||||
if ($action instanceof action_menu_link) {
|
||||
if ($action instanceof action_link) {
|
||||
if ($action->primary) {
|
||||
$this->add_primary_action($action);
|
||||
} else {
|
||||
@@ -3227,7 +3237,22 @@ class action_menu implements renderable {
|
||||
$output = $OUTPUT;
|
||||
}
|
||||
$pixicon = $this->actionicon;
|
||||
$title = new lang_string('actions', 'moodle');
|
||||
$linkclasses = array('toggle-display');
|
||||
|
||||
$title = '';
|
||||
if (!empty($this->menutrigger)) {
|
||||
$pixicon = '<b class="caret"></b>';
|
||||
$linkclasses[] = 'textmenu';
|
||||
} else {
|
||||
$title = new lang_string('actions', 'moodle');
|
||||
$this->actionicon = new pix_icon(
|
||||
't/edit_menu',
|
||||
'',
|
||||
'moodle',
|
||||
array('class' => 'iconsmall actionmenu', 'title' => '')
|
||||
);
|
||||
$pixicon = $this->actionicon;
|
||||
}
|
||||
if ($pixicon instanceof renderable) {
|
||||
$pixicon = $output->render($pixicon);
|
||||
if ($pixicon instanceof pix_icon && isset($pixicon->attributes['alt'])) {
|
||||
@@ -3240,12 +3265,17 @@ class action_menu implements renderable {
|
||||
}
|
||||
$actions = $this->primaryactions;
|
||||
$attributes = array(
|
||||
'class' => 'toggle-display',
|
||||
'class' => implode(' ', $linkclasses),
|
||||
'title' => $title,
|
||||
'id' => 'action-menu-toggle-'.$this->instance,
|
||||
'role' => 'menuitem'
|
||||
);
|
||||
$actions[] = html_writer::link('#', $string.$pixicon, $attributes);
|
||||
$link = html_writer::link('#', $string . $this->menutrigger . $pixicon, $attributes);
|
||||
if ($this->prioritise) {
|
||||
array_unshift($actions, $link);
|
||||
} else {
|
||||
$actions[] = $link;
|
||||
}
|
||||
return $actions;
|
||||
}
|
||||
|
||||
@@ -3335,6 +3365,29 @@ class action_menu implements renderable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An action menu filler
|
||||
*
|
||||
* @package core
|
||||
* @category output
|
||||
* @copyright 2013 Andrew Nicols
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class action_menu_filler extends action_link implements renderable {
|
||||
|
||||
/**
|
||||
* True if this is a primary action. False if not.
|
||||
* @var bool
|
||||
*/
|
||||
public $primary = true;
|
||||
|
||||
/**
|
||||
* Constructs the object.
|
||||
*/
|
||||
public function __construct() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An action menu action
|
||||
*
|
||||
|
||||
@@ -1161,6 +1161,16 @@ class core_renderer extends renderer_base {
|
||||
return html_writer::tag('a', $icon.$text, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a primary action_menu_filler item.
|
||||
*
|
||||
* @param action_menu_link_filler $action
|
||||
* @return string HTML fragment
|
||||
*/
|
||||
protected function render_action_menu_filler(action_menu_filler $action) {
|
||||
return html_writer::span(' ', 'filler');
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a primary action_menu_link item.
|
||||
*
|
||||
@@ -2064,7 +2074,7 @@ class core_renderer extends renderer_base {
|
||||
public function heading_with_help($text, $helpidentifier, $component = 'moodle', $icon = '', $iconalt = '', $level = 2, $classnames = null) {
|
||||
$image = '';
|
||||
if ($icon) {
|
||||
$image = $this->pix_icon($icon, $iconalt, $component, array('class'=>'icon'));
|
||||
$image = $this->pix_icon($icon, $iconalt, $component, array('class'=>'icon iconlarge'));
|
||||
}
|
||||
|
||||
$help = '';
|
||||
|
||||
@@ -11,8 +11,11 @@ var BODY = Y.one(Y.config.doc.body),
|
||||
MENUSHOWN : 'action-menu-shown'
|
||||
},
|
||||
SELECTOR = {
|
||||
CAN_RECEIVE_FOCUS_SELECTOR: 'input:not([type="hidden"]), a[href], button, textarea, select, [tabindex]',
|
||||
MENU : '.moodle-actionmenu[data-enhance=moodle-core-actionmenu]',
|
||||
MENUCONTENT : '.menu[data-rel=menu-content]',
|
||||
MENUCONTENTCHILD: 'li a',
|
||||
MENUCHILD: '.menu li a',
|
||||
TOGGLE : '.toggle-display'
|
||||
},
|
||||
ACTIONMENU,
|
||||
@@ -59,6 +62,15 @@ ACTIONMENU.prototype = {
|
||||
*/
|
||||
owner : null,
|
||||
|
||||
/**
|
||||
* The menu button that toggles this open.
|
||||
*
|
||||
* @property menulink
|
||||
* @type Node
|
||||
* @protected
|
||||
*/
|
||||
menulink: null,
|
||||
|
||||
/**
|
||||
* Called during the initialisation process of the object.
|
||||
* @method initializer
|
||||
@@ -104,16 +116,21 @@ ACTIONMENU.prototype = {
|
||||
this.dialogue.one(SELECTOR.MENUCONTENT).set('aria-hidden', true);
|
||||
this.dialogue = null;
|
||||
}
|
||||
if (this.owner) {
|
||||
this.owner.removeClass(CSS.MENUSHOWN);
|
||||
this.owner = null;
|
||||
}
|
||||
for (var i in this.events) {
|
||||
if (this.events[i].detach) {
|
||||
this.events[i].detach();
|
||||
}
|
||||
}
|
||||
this.events = [];
|
||||
if (this.owner) {
|
||||
this.owner.removeClass(CSS.MENUSHOWN);
|
||||
this.owner = null;
|
||||
}
|
||||
|
||||
if (this.menulink) {
|
||||
this.menulink.focus();
|
||||
this.menulink = null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -132,13 +149,49 @@ ACTIONMENU.prototype = {
|
||||
// The menu was visible and the user has clicked to toggle it again.
|
||||
return;
|
||||
}
|
||||
this.showMenu(menu);
|
||||
this.showMenu(e, menu);
|
||||
// Close the menu if the user presses escape.
|
||||
this.events.push(BODY.on('key', this.hideMenu, 'esc', this));
|
||||
// Close the menu if the user clicks outside the menu.
|
||||
this.events.push(BODY.on('click', this.hideIfOutside, this));
|
||||
// Close the menu if the user focuses outside the menu.
|
||||
this.events.push(BODY.delegate('focus', this.hideIfOutside, '*', this));
|
||||
|
||||
// Check tabbing.
|
||||
this.events.push(menu.delegate('key', this.checkFocus, 'down:9', SELECTOR.MENUCHILD, this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Check current focus when moving around with the tab key.
|
||||
* This will ensure that when the etreme menu items are reached, the
|
||||
* menu is closed and the next DOM element is focused.
|
||||
*
|
||||
* @method checkFocus
|
||||
* @param {EventFacade} e The key event
|
||||
*/
|
||||
checkFocus: function(e) {
|
||||
var nodelist = this.dialogue.all(SELECTOR.MENUCHILD),
|
||||
firstNode,
|
||||
lastNode;
|
||||
|
||||
if (nodelist) {
|
||||
firstNode = nodelist.item(0);
|
||||
lastNode = nodelist.pop();
|
||||
}
|
||||
|
||||
var menulink = this.menulink;
|
||||
if (e.target === firstNode && e.shiftKey) {
|
||||
this.hideMenu();
|
||||
e.preventDefault();
|
||||
} else if (e.target === lastNode && !e.shiftKey) {
|
||||
var next;
|
||||
if (this.hideMenu()) {
|
||||
next = menulink.next(SELECTOR.CAN_RECEIVE_FOCUS_SELECTOR);
|
||||
if (next) {
|
||||
next.focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -156,21 +209,31 @@ ACTIONMENU.prototype = {
|
||||
|
||||
/**
|
||||
* Displays the menu with the given content and alignment.
|
||||
* @param {EventFacade} e
|
||||
* @param {Node} menu
|
||||
* @param Array align
|
||||
* @returns {M.core.dialogue|dialogue}
|
||||
*/
|
||||
showMenu : function(menu) {
|
||||
showMenu : function(e, menu) {
|
||||
Y.log('Displaying an action menu', 'debug', ACTIONMENU.NAME);
|
||||
var ownerselector = menu.getData('owner'),
|
||||
menucontent = menu.one(SELECTOR.MENUCONTENT);
|
||||
menucontent = menu.one(SELECTOR.MENUCONTENT),
|
||||
menuchild;
|
||||
this.owner = (ownerselector) ? menu.ancestor(ownerselector) : null;
|
||||
this.dialogue = menu;
|
||||
menu.addClass('show');
|
||||
if (this.owner) {
|
||||
this.owner.addClass(CSS.MENUSHOWN);
|
||||
this.menulink = this.owner.one(SELECTOR.TOGGLE);
|
||||
}
|
||||
this.constrain(menucontent.set('aria-hidden', false));
|
||||
|
||||
if (e.type && e.type === 'key') {
|
||||
menuchild = menucontent.one(SELECTOR.MENUCONTENTCHILD);
|
||||
if (menuchild) {
|
||||
menuchild.focus();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
YUI.add("moodle-core-actionmenu",function(e,t){var n=e.one(e.config.doc.body),r={MENUSHOWN:"action-menu-shown"},i={MENU:".moodle-actionmenu[data-enhance=moodle-core-actionmenu]",MENUCONTENT:".menu[data-rel=menu-content]",TOGGLE:".toggle-display"},s,o={TL:"tl",TR:"tr",BL:"bl",BR:"br"};s=function(){s.superclass.constructor.apply(this,arguments)},s.prototype={dialogue:null,events:[],owner:null,initializer:function(){e.all(i.MENU).each(this.enhance,this),n.delegate("click",this.toggleMenu,i.MENU+" "+i.TOGGLE,this),n.delegate("key",this.toggleMenu,"enter,space",i.MENU+" "+i.TOGGLE,this)},enhance:function(e){var t=e.one(i.MENUCONTENT),n;if(!t)return!1;n=t.getData("align")||this.get("align").join("-"),e.one(i.TOGGLE).set("aria-haspopup",!0),t.set("aria-hidden",!0),t.hasClass("align-"+n)||t.addClass("align-"+n),t.hasChildNodes()&&e.setAttribute("data-enhanced","1")},hideMenu:function(){this.dialogue&&(this.dialogue.removeClass("show"),this.dialogue.one(i.MENUCONTENT).set("aria-hidden",!0),this.dialogue=null),this.owner&&(this.owner.removeClass(r.MENUSHOWN),this.owner=null);for(var e in this.events)this.events[e].detach&&this.events[e].detach();this.events=[]},toggleMenu:function(e){var t=e.target.ancestor(i.MENU),r=t.hasClass("show");e.halt(!0),this.hideMenu();if(r)return;this.showMenu(t),this.events.push(n.on("key",this.hideMenu,"esc",this)),this.events.push(n.on("click",this.hideIfOutside,this)),this.events.push(n.delegate("focus",this.hideIfOutside,"*",this))},hideIfOutside:function(e){!e.target.test(i.MENU)&&!e.target.ancestor(i.MENU)&&this.hideMenu()},showMenu:function(e){var t=e.getData("owner"),n=e.one(i.MENUCONTENT);return this.owner=t?e.ancestor(t):null,this.dialogue=e,e.addClass("show"),this.owner&&this.owner.addClass(r.MENUSHOWN),this.constrain(n.set("aria-hidden",!1)),!0},constrain:function(e){var t=e.getData("constraint"),n=e.getX(),r=e.getY(),i=e.get("offsetWidth"),s=e.get("offsetHeight"),o=0,u=0,a,f,l="auto",c=null,h=null,p=null,d=null,v=null;t&&(t=e.ancestor(t)),t?(a=t.get("offsetWidth"),f=t.get("offsetHeight"),o=t.getX(),u=t.getY(),l=t.getStyle("overflow")||"auto"):(a=e.get("docWidth"),f=e.get("docHeight")),i>a?(c=i=a,p=n=o):n<o?p=n=o:n+i>=o+a&&(p=o+a-i),s>f&&l.toLowerCase()==="hidden"&&(h=s=f,e.setStyle("overflow","auto"));if(r>=u&&r+s>u+f){d=u+f-s;try{v=e.getStyle("boxShadow").replace(/.*? (\d+)px \d+px$/,"$1"),(new RegExp(/^\d+$/)).test(v)&&d-u>v&&(d-=v)}catch(m){}}p!==null&&e.setX(p),d!==null&&e.setY(d),c!==null&&e.setStyle("width",c.toString()+"px"),h!==null&&e.setStyle("height",h.toString()+"px")}},e.extend(s,e.Base,s.prototype,{NAME:"moodle-core-actionmenu",ATTRS:{align:{value:[o.TR,o.BR]}}}),M.core=M.core||{},M.core.actionmenu=M.core.actionmenu||{},M.core.actionmenu.instance=null,M.core.actionmenu.init=M.core.actionmenu.init||function(e){M.core.actionmenu.instance=M.core.actionmenu.instance||new s(e)},M.core.actionmenu.newDOMNode=function(e){if(M.core.actionmenu.instance===null)return!0;e.all(i.MENU).each(M.core.actionmenu.instance.enhance,M.core.actionmenu.instance)}},"@VERSION@",{requires:["base","event"]});
|
||||
YUI.add("moodle-core-actionmenu",function(e,t){var n=e.one(e.config.doc.body),r={MENUSHOWN:"action-menu-shown"},i={CAN_RECEIVE_FOCUS_SELECTOR:'input:not([type="hidden"]), a[href], button, textarea, select, [tabindex]',MENU:".moodle-actionmenu[data-enhance=moodle-core-actionmenu]",MENUCONTENT:".menu[data-rel=menu-content]",MENUCONTENTCHILD:"li a",MENUCHILD:".menu li a",TOGGLE:".toggle-display"},s,o={TL:"tl",TR:"tr",BL:"bl",BR:"br"};s=function(){s.superclass.constructor.apply(this,arguments)},s.prototype={dialogue:null,events:[],owner:null,menulink:null,initializer:function(){e.all(i.MENU).each(this.enhance,this),n.delegate("click",this.toggleMenu,i.MENU+" "+i.TOGGLE,this),n.delegate("key",this.toggleMenu,"enter,space",i.MENU+" "+i.TOGGLE,this)},enhance:function(e){var t=e.one(i.MENUCONTENT),n;if(!t)return!1;n=t.getData("align")||this.get("align").join("-"),e.one(i.TOGGLE).set("aria-haspopup",!0),t.set("aria-hidden",!0),t.hasClass("align-"+n)||t.addClass("align-"+n),t.hasChildNodes()&&e.setAttribute("data-enhanced","1")},hideMenu:function(){this.dialogue&&(this.dialogue.removeClass("show"),this.dialogue.one(i.MENUCONTENT).set("aria-hidden",!0),this.dialogue=null);for(var e in this.events)this.events[e].detach&&this.events[e].detach();this.events=[],this.owner&&(this.owner.removeClass(r.MENUSHOWN),this.owner=null),this.menulink&&(this.menulink.focus(),this.menulink=null)},toggleMenu:function(e){var t=e.target.ancestor(i.MENU),r=t.hasClass("show");e.halt(!0),this.hideMenu();if(r)return;this.showMenu(e,t),this.events.push(n.on("key",this.hideMenu,"esc",this)),this.events.push(n.on("click",this.hideIfOutside,this)),this.events.push(n.delegate("focus",this.hideIfOutside,"*",this)),this.events.push(t.delegate("key",this.checkFocus,"down:9",i.MENUCHILD,this))},checkFocus:function(e){var t=this.dialogue.all(i.MENUCHILD),n,r;t&&(n=t.item(0),r=t.pop());var s=this.menulink;if(e.target===n&&e.shiftKey)this.hideMenu(),e.preventDefault();else if(e.target===r&&!e.shiftKey){var o;this.hideMenu()&&(o=s.next(i.CAN_RECEIVE_FOCUS_SELECTOR),o&&o.focus())}},hideIfOutside:function(e){!e.target.test(i.MENU)&&!e.target.ancestor(i.MENU)&&this.hideMenu()},showMenu:function(e,t){var n=t.getData("owner"),s=t.one(i.MENUCONTENT),o;return this.owner=n?t.ancestor(n):null,this.dialogue=t,t.addClass("show"),this.owner&&(this.owner.addClass(r.MENUSHOWN),this.menulink=this.owner.one(i.TOGGLE)),this.constrain(s.set("aria-hidden",!1)),e.type&&e.type==="key"&&(o=s.one(i.MENUCONTENTCHILD),o&&o.focus()),!0},constrain:function(e){var t=e.getData("constraint"),n=e.getX(),r=e.getY(),i=e.get("offsetWidth"),s=e.get("offsetHeight"),o=0,u=0,a,f,l="auto",c=null,h=null,p=null,d=null,v=null;t&&(t=e.ancestor(t)),t?(a=t.get("offsetWidth"),f=t.get("offsetHeight"),o=t.getX(),u=t.getY(),l=t.getStyle("overflow")||"auto"):(a=e.get("docWidth"),f=e.get("docHeight")),i>a?(c=i=a,p=n=o):n<o?p=n=o:n+i>=o+a&&(p=o+a-i),s>f&&l.toLowerCase()==="hidden"&&(h=s=f,e.setStyle("overflow","auto"));if(r>=u&&r+s>u+f){d=u+f-s;try{v=e.getStyle("boxShadow").replace(/.*? (\d+)px \d+px$/,"$1"),(new RegExp(/^\d+$/)).test(v)&&d-u>v&&(d-=v)}catch(m){}}p!==null&&e.setX(p),d!==null&&e.setY(d),c!==null&&e.setStyle("width",c.toString()+"px"),h!==null&&e.setStyle("height",h.toString()+"px")}},e.extend(s,e.Base,s.prototype,{NAME:"moodle-core-actionmenu",ATTRS:{align:{value:[o.TR,o.BR]}}}),M.core=M.core||{},M.core.actionmenu=M.core.actionmenu||{},M.core.actionmenu.instance=null,M.core.actionmenu.init=M.core.actionmenu.init||function(e){M.core.actionmenu.instance=M.core.actionmenu.instance||new s(e)},M.core.actionmenu.newDOMNode=function(e){if(M.core.actionmenu.instance===null)return!0;e.all(i.MENU).each(M.core.actionmenu.instance.enhance,M.core.actionmenu.instance)}},"@VERSION@",{requires:["base","event"]});
|
||||
|
||||
@@ -11,8 +11,11 @@ var BODY = Y.one(Y.config.doc.body),
|
||||
MENUSHOWN : 'action-menu-shown'
|
||||
},
|
||||
SELECTOR = {
|
||||
CAN_RECEIVE_FOCUS_SELECTOR: 'input:not([type="hidden"]), a[href], button, textarea, select, [tabindex]',
|
||||
MENU : '.moodle-actionmenu[data-enhance=moodle-core-actionmenu]',
|
||||
MENUCONTENT : '.menu[data-rel=menu-content]',
|
||||
MENUCONTENTCHILD: 'li a',
|
||||
MENUCHILD: '.menu li a',
|
||||
TOGGLE : '.toggle-display'
|
||||
},
|
||||
ACTIONMENU,
|
||||
@@ -59,6 +62,15 @@ ACTIONMENU.prototype = {
|
||||
*/
|
||||
owner : null,
|
||||
|
||||
/**
|
||||
* The menu button that toggles this open.
|
||||
*
|
||||
* @property menulink
|
||||
* @type Node
|
||||
* @protected
|
||||
*/
|
||||
menulink: null,
|
||||
|
||||
/**
|
||||
* Called during the initialisation process of the object.
|
||||
* @method initializer
|
||||
@@ -102,16 +114,21 @@ ACTIONMENU.prototype = {
|
||||
this.dialogue.one(SELECTOR.MENUCONTENT).set('aria-hidden', true);
|
||||
this.dialogue = null;
|
||||
}
|
||||
if (this.owner) {
|
||||
this.owner.removeClass(CSS.MENUSHOWN);
|
||||
this.owner = null;
|
||||
}
|
||||
for (var i in this.events) {
|
||||
if (this.events[i].detach) {
|
||||
this.events[i].detach();
|
||||
}
|
||||
}
|
||||
this.events = [];
|
||||
if (this.owner) {
|
||||
this.owner.removeClass(CSS.MENUSHOWN);
|
||||
this.owner = null;
|
||||
}
|
||||
|
||||
if (this.menulink) {
|
||||
this.menulink.focus();
|
||||
this.menulink = null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -130,13 +147,49 @@ ACTIONMENU.prototype = {
|
||||
// The menu was visible and the user has clicked to toggle it again.
|
||||
return;
|
||||
}
|
||||
this.showMenu(menu);
|
||||
this.showMenu(e, menu);
|
||||
// Close the menu if the user presses escape.
|
||||
this.events.push(BODY.on('key', this.hideMenu, 'esc', this));
|
||||
// Close the menu if the user clicks outside the menu.
|
||||
this.events.push(BODY.on('click', this.hideIfOutside, this));
|
||||
// Close the menu if the user focuses outside the menu.
|
||||
this.events.push(BODY.delegate('focus', this.hideIfOutside, '*', this));
|
||||
|
||||
// Check tabbing.
|
||||
this.events.push(menu.delegate('key', this.checkFocus, 'down:9', SELECTOR.MENUCHILD, this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Check current focus when moving around with the tab key.
|
||||
* This will ensure that when the etreme menu items are reached, the
|
||||
* menu is closed and the next DOM element is focused.
|
||||
*
|
||||
* @method checkFocus
|
||||
* @param {EventFacade} e The key event
|
||||
*/
|
||||
checkFocus: function(e) {
|
||||
var nodelist = this.dialogue.all(SELECTOR.MENUCHILD),
|
||||
firstNode,
|
||||
lastNode;
|
||||
|
||||
if (nodelist) {
|
||||
firstNode = nodelist.item(0);
|
||||
lastNode = nodelist.pop();
|
||||
}
|
||||
|
||||
var menulink = this.menulink;
|
||||
if (e.target === firstNode && e.shiftKey) {
|
||||
this.hideMenu();
|
||||
e.preventDefault();
|
||||
} else if (e.target === lastNode && !e.shiftKey) {
|
||||
var next;
|
||||
if (this.hideMenu()) {
|
||||
next = menulink.next(SELECTOR.CAN_RECEIVE_FOCUS_SELECTOR);
|
||||
if (next) {
|
||||
next.focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -154,20 +207,30 @@ ACTIONMENU.prototype = {
|
||||
|
||||
/**
|
||||
* Displays the menu with the given content and alignment.
|
||||
* @param {EventFacade} e
|
||||
* @param {Node} menu
|
||||
* @param Array align
|
||||
* @returns {M.core.dialogue|dialogue}
|
||||
*/
|
||||
showMenu : function(menu) {
|
||||
showMenu : function(e, menu) {
|
||||
var ownerselector = menu.getData('owner'),
|
||||
menucontent = menu.one(SELECTOR.MENUCONTENT);
|
||||
menucontent = menu.one(SELECTOR.MENUCONTENT),
|
||||
menuchild;
|
||||
this.owner = (ownerselector) ? menu.ancestor(ownerselector) : null;
|
||||
this.dialogue = menu;
|
||||
menu.addClass('show');
|
||||
if (this.owner) {
|
||||
this.owner.addClass(CSS.MENUSHOWN);
|
||||
this.menulink = this.owner.one(SELECTOR.TOGGLE);
|
||||
}
|
||||
this.constrain(menucontent.set('aria-hidden', false));
|
||||
|
||||
if (e.type && e.type === 'key') {
|
||||
menuchild = menucontent.one(SELECTOR.MENUCONTENTCHILD);
|
||||
if (menuchild) {
|
||||
menuchild.focus();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ YUI.add('moodle-core-dragdrop', function(Y) {
|
||||
parentnodeclass : null,
|
||||
groups : [],
|
||||
lastdroptarget : null,
|
||||
initializer : function(params) {
|
||||
initializer : function() {
|
||||
// Listen for all drag:start events
|
||||
Y.DD.DDM.on('drag:start', this.global_drag_start, this);
|
||||
// Listen for all drag:end events
|
||||
@@ -35,7 +35,8 @@ YUI.add('moodle-core-dragdrop', function(Y) {
|
||||
// Listen for all drop:miss events
|
||||
Y.DD.DDM.on('drag:dropmiss', this.global_drag_dropmiss, this);
|
||||
|
||||
Y.on('key', this.global_keydown, window, 'down:32,enter,esc', this);
|
||||
Y.one(Y.config.doc.body).delegate('key', this.global_keydown, 'down:32, enter, esc', '.' + MOVEICON.cssclass, this);
|
||||
Y.one(Y.config.doc.body).delegate('click', this.global_keydown, '.' + MOVEICON.cssclass , this);
|
||||
},
|
||||
|
||||
get_drag_handle: function(title, classname, iconclass, large) {
|
||||
@@ -57,7 +58,8 @@ YUI.add('moodle-core-dragdrop', function(Y) {
|
||||
.addClass(classname)
|
||||
.setAttribute('title', title)
|
||||
.setAttribute('tabIndex', 0)
|
||||
.setAttribute('data-draggroups', this.groups);
|
||||
.setAttribute('data-draggroups', this.groups)
|
||||
.setAttribute('aria-grabbed', 'false');
|
||||
dragelement.appendChild(dragicon);
|
||||
dragelement.addClass(MOVEICON.cssclass);
|
||||
|
||||
@@ -437,11 +439,16 @@ YUI.add('moodle-core-dragdrop', function(Y) {
|
||||
* @param {Event} e The keydown / click event on the drag handle.
|
||||
*/
|
||||
global_keydown : function(e) {
|
||||
var draghandle = e.target,
|
||||
var draghandle = e.target.ancestor('.' + MOVEICON.cssclass, true),
|
||||
dragcontainer,
|
||||
draggroups;
|
||||
|
||||
if (e.keyCode == 27 ) {
|
||||
if (draghandle === null) {
|
||||
// The element clicked did not have a a draghandle in it's lineage.
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.keyCode === 27 ) {
|
||||
// Escape to cancel from anywhere.
|
||||
this.global_cancel_keyboard_drag();
|
||||
e.preventDefault();
|
||||
@@ -452,17 +459,19 @@ YUI.add('moodle-core-dragdrop', function(Y) {
|
||||
if (!draghandle.hasClass(MOVEICON.cssclass)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Do nothing if not space or enter.
|
||||
if (e.keyCode != 13 && e.keyCode != 32) {
|
||||
if (e.keyCode !== 13 && e.keyCode !== 32 && e.type !== 'click') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check the drag groups to see if we are the handler for this node.
|
||||
draggroups = e.target.getAttribute('data-draggroups').split(' ');
|
||||
draggroups = draghandle.getAttribute('data-draggroups').split(' ');
|
||||
var i, j, validgroup = false;
|
||||
|
||||
for (i = 0; i < draggroups.length; i++) {
|
||||
for (j = 0; j < this.groups.length; j++) {
|
||||
if (draggroups[i] == this.groups[j]) {
|
||||
if (draggroups[i] === this.groups[j]) {
|
||||
validgroup = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -9,8 +9,11 @@ var BODY = Y.one(Y.config.doc.body),
|
||||
MENUSHOWN : 'action-menu-shown'
|
||||
},
|
||||
SELECTOR = {
|
||||
CAN_RECEIVE_FOCUS_SELECTOR: 'input:not([type="hidden"]), a[href], button, textarea, select, [tabindex]',
|
||||
MENU : '.moodle-actionmenu[data-enhance=moodle-core-actionmenu]',
|
||||
MENUCONTENT : '.menu[data-rel=menu-content]',
|
||||
MENUCONTENTCHILD: 'li a',
|
||||
MENUCHILD: '.menu li a',
|
||||
TOGGLE : '.toggle-display'
|
||||
},
|
||||
ACTIONMENU,
|
||||
@@ -57,6 +60,15 @@ ACTIONMENU.prototype = {
|
||||
*/
|
||||
owner : null,
|
||||
|
||||
/**
|
||||
* The menu button that toggles this open.
|
||||
*
|
||||
* @property menulink
|
||||
* @type Node
|
||||
* @protected
|
||||
*/
|
||||
menulink: null,
|
||||
|
||||
/**
|
||||
* Called during the initialisation process of the object.
|
||||
* @method initializer
|
||||
@@ -102,16 +114,21 @@ ACTIONMENU.prototype = {
|
||||
this.dialogue.one(SELECTOR.MENUCONTENT).set('aria-hidden', true);
|
||||
this.dialogue = null;
|
||||
}
|
||||
if (this.owner) {
|
||||
this.owner.removeClass(CSS.MENUSHOWN);
|
||||
this.owner = null;
|
||||
}
|
||||
for (var i in this.events) {
|
||||
if (this.events[i].detach) {
|
||||
this.events[i].detach();
|
||||
}
|
||||
}
|
||||
this.events = [];
|
||||
if (this.owner) {
|
||||
this.owner.removeClass(CSS.MENUSHOWN);
|
||||
this.owner = null;
|
||||
}
|
||||
|
||||
if (this.menulink) {
|
||||
this.menulink.focus();
|
||||
this.menulink = null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -130,13 +147,49 @@ ACTIONMENU.prototype = {
|
||||
// The menu was visible and the user has clicked to toggle it again.
|
||||
return;
|
||||
}
|
||||
this.showMenu(menu);
|
||||
this.showMenu(e, menu);
|
||||
// Close the menu if the user presses escape.
|
||||
this.events.push(BODY.on('key', this.hideMenu, 'esc', this));
|
||||
// Close the menu if the user clicks outside the menu.
|
||||
this.events.push(BODY.on('click', this.hideIfOutside, this));
|
||||
// Close the menu if the user focuses outside the menu.
|
||||
this.events.push(BODY.delegate('focus', this.hideIfOutside, '*', this));
|
||||
|
||||
// Check tabbing.
|
||||
this.events.push(menu.delegate('key', this.checkFocus, 'down:9', SELECTOR.MENUCHILD, this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Check current focus when moving around with the tab key.
|
||||
* This will ensure that when the etreme menu items are reached, the
|
||||
* menu is closed and the next DOM element is focused.
|
||||
*
|
||||
* @method checkFocus
|
||||
* @param {EventFacade} e The key event
|
||||
*/
|
||||
checkFocus: function(e) {
|
||||
var nodelist = this.dialogue.all(SELECTOR.MENUCHILD),
|
||||
firstNode,
|
||||
lastNode;
|
||||
|
||||
if (nodelist) {
|
||||
firstNode = nodelist.item(0);
|
||||
lastNode = nodelist.pop();
|
||||
}
|
||||
|
||||
var menulink = this.menulink;
|
||||
if (e.target === firstNode && e.shiftKey) {
|
||||
this.hideMenu();
|
||||
e.preventDefault();
|
||||
} else if (e.target === lastNode && !e.shiftKey) {
|
||||
var next;
|
||||
if (this.hideMenu()) {
|
||||
next = menulink.next(SELECTOR.CAN_RECEIVE_FOCUS_SELECTOR);
|
||||
if (next) {
|
||||
next.focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -154,21 +207,31 @@ ACTIONMENU.prototype = {
|
||||
|
||||
/**
|
||||
* Displays the menu with the given content and alignment.
|
||||
* @param {EventFacade} e
|
||||
* @param {Node} menu
|
||||
* @param Array align
|
||||
* @returns {M.core.dialogue|dialogue}
|
||||
*/
|
||||
showMenu : function(menu) {
|
||||
showMenu : function(e, menu) {
|
||||
Y.log('Displaying an action menu', 'debug', ACTIONMENU.NAME);
|
||||
var ownerselector = menu.getData('owner'),
|
||||
menucontent = menu.one(SELECTOR.MENUCONTENT);
|
||||
menucontent = menu.one(SELECTOR.MENUCONTENT),
|
||||
menuchild;
|
||||
this.owner = (ownerselector) ? menu.ancestor(ownerselector) : null;
|
||||
this.dialogue = menu;
|
||||
menu.addClass('show');
|
||||
if (this.owner) {
|
||||
this.owner.addClass(CSS.MENUSHOWN);
|
||||
this.menulink = this.owner.one(SELECTOR.TOGGLE);
|
||||
}
|
||||
this.constrain(menucontent.set('aria-hidden', false));
|
||||
|
||||
if (e.type && e.type === 'key') {
|
||||
menuchild = menucontent.one(SELECTOR.MENUCONTENTCHILD);
|
||||
if (menuchild) {
|
||||
menuchild.focus();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ Feature: Group assignment submissions
|
||||
And I fill the moodle form with:
|
||||
| Group mode | Separate groups |
|
||||
And I press "Save and return to course"
|
||||
And I follow "Edit settings"
|
||||
And I click on "Edit settings" "link" in the "Administration" "block"
|
||||
And I fill the moodle form with:
|
||||
| Group mode | Separate groups |
|
||||
And I press "Save changes"
|
||||
|
||||
@@ -25,7 +25,7 @@ Feature: Set a certain number of discussions as a completion condition for a for
|
||||
And I log in as "teacher1"
|
||||
And I follow "Course 1"
|
||||
And I turn editing mode on
|
||||
And I follow "Edit settings"
|
||||
And I click on "Edit settings" "link" in the "Administration" "block"
|
||||
And I fill the moodle form with:
|
||||
| Enable completion tracking | Yes |
|
||||
And I press "Save changes"
|
||||
|
||||
|
After Width: | Height: | Size: 230 B |
|
After Width: | Height: | Size: 264 B |
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
|
||||
<!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
|
||||
]>
|
||||
<svg version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
|
||||
x="0px" y="0px" width="16px" height="16px" viewBox="0 0 16 16" style="overflow:visible;enable-background:new 0 0 16 16;"
|
||||
xml:space="preserve" preserveAspectRatio="xMinYMid meet">
|
||||
<defs>
|
||||
</defs>
|
||||
<path style="fill:#999999;" d="M5.2,10.3L0,13.1V16h16v-3l-5.2-2.7C10.3,10,10.2,9.4,10.6,9c0,0,1.4-1.8,1.4-3.8C12,2.3,10.2,0,8,0
|
||||
S4,2.3,4,5.2C4,7.2,5.4,9,5.4,9C5.8,9.5,5.7,10,5.2,10.3z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 827 B |
|
After Width: | Height: | Size: 345 B |
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
|
||||
<!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
|
||||
]>
|
||||
<svg version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
|
||||
x="0px" y="0px" width="16px" height="16px" viewBox="0 0 16 16" style="overflow:visible;enable-background:new 0 0 16 16;"
|
||||
xml:space="preserve">
|
||||
<defs>
|
||||
</defs>
|
||||
<path style="fill:#999999;" d="M4.4,13H0V9.9l2.2-1.3C2.6,8.4,2.6,8,2.3,7.6c0,0-1.3-1.5-1.3-3.2C1,2,2.5,0,4.4,0s3.4,2,3.4,4.4
|
||||
c0,1.7-1.2,3.2-1.2,3.2c-0.3,0.4-0.2,0.8,0.2,1l1.1,0.6c0.3,0.6,0.6,1.1,0.8,1.4L4.4,13L4.4,13z M16,12.2l-1.9-1
|
||||
c-0.4-0.2-0.5-0.7-0.2-1c0,0,1.2-1.5,1.2-3.2c0-2.4-1.5-4.4-3.4-4.4S8.3,4.6,8.3,7c0,1.7,1.3,3.2,1.3,3.2c0.3,0.4,0.3,0.8-0.1,1.1
|
||||
l-4.1,2.3V16H16V12.2z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 993 B |
|
After Width: | Height: | Size: 327 B |
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
|
||||
<!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
|
||||
]>
|
||||
<svg version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
|
||||
x="0px" y="0px" width="16px" height="16px" viewBox="0 0 16 16" style="overflow:visible;enable-background:new 0 0 16 16;"
|
||||
xml:space="preserve" preserveAspectRatio="xMinYMid meet">
|
||||
<defs>
|
||||
</defs>
|
||||
<path style="fill:#999999;" d="M3,16H0v-4l3.2-1.7C3.6,10,3.8,9.5,3.4,9C3.4,9,2,7.2,2,5.2C2,2.3,3.8,0,6,0c0.4,0,0.7,0.1,1.1,0.2
|
||||
c-1.2,1.1-2,3-2,5c0,1.7,0.6,2.7,1,3.5c0.6,0.9,0.1,1-0.3,1.3C5.6,10.1,3,11.4,3,11.4V16z M16,11.9l-3.1-1.6
|
||||
C12.4,10,12.3,9.4,12.6,9c0,0,1.4-1.8,1.4-3.8C14,2.3,12.2,0,10,0S6,2.3,6,5.2C6,7.2,7.5,9,7.5,9c0.3,0.4,0.2,1-0.3,1.3L4,12v4h12
|
||||
V11.9z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1012 B |
|
After Width: | Height: | Size: 181 B |
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
|
||||
<!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
|
||||
]>
|
||||
<svg version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
|
||||
x="0px" y="0px" width="16px" height="16px" viewBox="-2.1 -5 16 16"
|
||||
style="overflow:visible;enable-background:new -2.1 -5 16 16;" xml:space="preserve" preserveAspectRatio="xMinYMid meet">
|
||||
<defs>
|
||||
</defs>
|
||||
<path style="fill:#999999;" d="M0.5,0C0,0-0.2,0.3,0.2,0.7l5,5c0.4,0.4,1,0.4,1.4,0l5-5C12,0.3,11.9,0,11.3,0H0.5z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 761 B |
|
After Width: | Height: | Size: 320 B |
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
|
||||
<!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
|
||||
]>
|
||||
<svg version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
|
||||
x="0px" y="0px" width="22px" height="12px" viewBox="0 0 22 12" style="overflow:visible;enable-background:new 0 0 22 12;"
|
||||
xml:space="preserve">
|
||||
<defs>
|
||||
</defs>
|
||||
<path style="fill:#999999;" d="M11.9,7C12,6.7,12,6.3,12,6s0-0.7-0.1-1l-1.6-0.3c-0.1-0.3-0.2-0.6-0.4-0.9l0.9-1.3
|
||||
C10.5,2,10,1.5,9.5,1.1L8.1,2C7.9,1.9,7.6,1.8,7.3,1.7L7,0.1C6.7,0,6.3,0,6,0C5.7,0,5.3,0,5,0.1L4.7,1.7C4.4,1.8,4.1,1.9,3.9,2
|
||||
L2.5,1.1C2,1.5,1.5,2,1.1,2.5L2,3.9C1.9,4.1,1.8,4.4,1.7,4.7L0.1,5C0,5.3,0,5.7,0,6c0,0.3,0,0.7,0.1,1l1.6,0.3
|
||||
C1.8,7.6,1.9,7.9,2,8.1L1.1,9.5c0.4,0.5,0.9,1,1.4,1.4L3.9,10c0.3,0.1,0.6,0.3,0.9,0.4L5,11.9C5.3,12,5.7,12,6,12c0.3,0,0.7,0,1-0.1
|
||||
l0.3-1.6c0.3-0.1,0.6-0.2,0.9-0.4l1.3,0.9c0.5-0.4,1-0.9,1.4-1.4L10,8.1c0.2-0.3,0.3-0.6,0.4-0.9L11.9,7z M6,7.5
|
||||
C5.2,7.5,4.5,6.8,4.5,6S5.2,4.5,6,4.5S7.5,5.2,7.5,6S6.8,7.5,6,7.5z M15,4H22l-3.5,3.5L15,4L15,4z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -169,6 +169,9 @@ img.iconsmall,
|
||||
-moz-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.block.block_with_controls div.header div.commands img.iconsmall.actionmenu {
|
||||
width: auto;
|
||||
}
|
||||
.course-content ul.topics li.section .right img.spacer,
|
||||
.course-content ul.topics li.section .left img.spacer {
|
||||
height: 1px;
|
||||
@@ -179,13 +182,6 @@ img.iconsmall,
|
||||
padding: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
.block .header .commands {
|
||||
text-align: center;
|
||||
}
|
||||
.block-control-actions span.moodle-core-dragdrop-draghandle {
|
||||
position: relative;
|
||||
top: 5px;
|
||||
}
|
||||
.moodle-actionmenu.show[data-enhanced] .menu a {
|
||||
color: #333333;
|
||||
display: block;
|
||||
@@ -193,4 +189,4 @@ img.iconsmall,
|
||||
}
|
||||
.moodle-actionmenu.show[data-enhanced] .menu {
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -486,3 +486,9 @@ body#page-course-view-topics.path-course div.moodle-dialogue-base div.yui3-widge
|
||||
color: #cc3300;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* Actionmenu
|
||||
-------------*/
|
||||
.jsenabled .moodle-actionmenu[data-enhance] .toggle-display.textmenu .iconsmall {
|
||||
margin: 4px 4px 4px 2px;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
.block .header .commands { text-align: right; clear: both;}
|
||||
.block .header .commands > a { margin:0 3px; }
|
||||
.block .header .commands .icon img {width:12px;height:12px;}
|
||||
.block .header .commands img.actionmenu {width:auto;}
|
||||
.block .content {padding:4px;}
|
||||
.block.hidden .content {display: none;}
|
||||
.block .content .userpicture {width:16px;height:16px;margin-right:6px;}
|
||||
|
||||
@@ -102,7 +102,7 @@ img.resize {height: 1em;width: 1em;}
|
||||
/* Icon styles */
|
||||
img.icon {height:16px;vertical-align:text-bottom;width:16px;padding-right: 6px;}
|
||||
.dir-rtl img.icon {padding-left: 6px; padding-right: 0; }
|
||||
img.iconsmall {height:12px;margin-right:3px;vertical-align:middle;width:12px;}
|
||||
img.iconsmall {height:12px;margin-right:3px; margin-left: 3px;vertical-align:middle;width:12px;}
|
||||
img.iconhelp, .helplink img {height:16px; padding-left:3px;vertical-align:text-bottom;width:16px;}
|
||||
.dir-rtl img.iconhelp, .dir-rtl .helplink img {padding-right: 3px; padding-left: 0; }
|
||||
img.iconlarge {height: 24px; width: 24px; vertical-align:middle;}
|
||||
@@ -149,7 +149,10 @@ h4 img.iconhelp,
|
||||
h5 img.icon,
|
||||
h5 img.iconhelp,
|
||||
h6 img.icon,
|
||||
h6 img.iconhelp {vertical-align: middle;}
|
||||
h6 img.iconhelp {
|
||||
vertical-align: middle;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
/** The 1-pixel padding is there to avoid phantom scroll bars on OS X (FF, Safari and Chrome)**/
|
||||
.no-overflow {overflow:auto;padding-bottom:1px;}
|
||||
@@ -1475,22 +1478,46 @@ img#persona_signin { cursor: pointer; }
|
||||
.jsenabled .moodle-actionmenu[data-enhance] {display: block;}
|
||||
.jsenabled .moodle-actionmenu[data-enhance] .menu {display: none;}
|
||||
.jsenabled .moodle-actionmenu[data-enhance] .toggle-display {display: inline;opacity: 0.5;filter: alpha(opacity=50);}
|
||||
|
||||
.jsenabled .moodle-actionmenu[data-enhance] .toggle-display.textmenu {
|
||||
display: block;
|
||||
margin-left: 4px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
.jsenabled .moodle-actionmenu[data-enhance] .toggle-display.textmenu .iconsmall {
|
||||
margin: 8px 4px 0px 2px;
|
||||
}
|
||||
|
||||
.jsenabled .moodle-actionmenu[data-enhance] .toggle-display.textmenu .caret {
|
||||
margin-top: 4px;
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
.jsenabled .moodle-actionmenu[data-enhanced] .toggle-display {opacity: 1;filter: alpha(opacity=100);}
|
||||
.jsenabled .moodle-actionmenu[data-enhanced] .menu-action-text {display: inline;}
|
||||
.jsenabled .moodle-actionmenu[data-enhanced] .menu-action-text {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.moodle-actionmenu[data-enhanced].show {position: relative;}
|
||||
.moodle-actionmenu[data-enhanced].show .menu {position: absolute;text-align:left;z-index: 1000;display: block;background-color: #fff;border: 1px solid #ccc;-webkit-border-radius: 5px;-moz-border-radius: 5px;border-radius: 5px;-webkit-box-shadow: 5px 5px 20px 0 #666666;-moz-box-shadow: 5px 5px 20px 0 #666666;box-shadow: 5px 5px 20px 0 #666666;}
|
||||
.moodle-actionmenu[data-enhanced].show .menu a {display: block;padding: 2px 1em 2px 24px;color: #333333;}
|
||||
.moodle-actionmenu[data-enhanced].show .menu a > img {margin-left:-20px;}
|
||||
.moodle-actionmenu[data-enhanced].show .menu a {
|
||||
display: block;
|
||||
padding: 4px 1em 4px 28px;
|
||||
color: #333333;
|
||||
}
|
||||
.moodle-actionmenu[data-enhanced].show .menu a > img {
|
||||
margin: 4px 4px 4px -24px;
|
||||
padding: 4px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
}
|
||||
.moodle-actionmenu[data-enhanced].show .menu a:hover,
|
||||
.moodle-actionmenu[data-enhanced].show .menu a:focus {color: #ffffff;background-color: #0088cc;}
|
||||
.moodle-actionmenu[data-enhanced].show .menu a:first-child {-webkit-border-top-right-radius: 4px;border-top-right-radius: 4px;-webkit-border-top-left-radius: 4px;border-top-left-radius: 4px;-moz-border-radius-topright: 4px;-moz-border-radius-topleft: 4px;}
|
||||
.moodle-actionmenu[data-enhanced].show .menu a:last-child {-webkit-border-bottom-right-radius: 4px;border-bottom-right-radius: 4px;-webkit-border-bottom-left-radius: 4px;border-bottom-left-radius: 4px;-moz-border-radius-bottomright: 4px;-moz-border-radius-bottomleft: 4px;}
|
||||
.moodle-actionmenu[data-enhanced].show .menu a.hidden {display: none;}
|
||||
.moodle-actionmenu[data-enhanced].show .menu img {vertical-align: middle;}
|
||||
.moodle-actionmenu[data-enhanced].show .menu .iconsmall {margin-right: 8px;}
|
||||
.moodle-actionmenu[data-enhanced].show .menu > li {display: block;}
|
||||
.action-menu-shown .moodle-actionmenu[data-enhanced] .toggle-display {background-color: #FFF;}
|
||||
.block .moodle-actionmenu {text-align: right;}
|
||||
|
||||
.dir-rtl .block .moodle-actionmenu {text-align: right;}
|
||||
@@ -1562,3 +1589,14 @@ a.disabled {
|
||||
font-style: italic;
|
||||
color: #808080;
|
||||
}
|
||||
|
||||
.caret {
|
||||
display: inline-block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
vertical-align: top;
|
||||
border-top: 4px solid #000;
|
||||
border-right: 4px solid transparent;
|
||||
border-left: 4px solid transparent;
|
||||
content: "";
|
||||
}
|
||||
|
||||
@@ -16,25 +16,86 @@
|
||||
.course-content ul.section { margin: 1em;}
|
||||
.sitetopic .section .activity img.activityicon,
|
||||
.course-content .section .activity img.activityicon {
|
||||
vertical-align: middle;
|
||||
vertical-align: text-bottom;
|
||||
margin-right: 3px;
|
||||
margin-left: 3px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
.section .activity .activityinstance .instancename {
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
.sitetopic .section .activity .activityinstance,
|
||||
.course-content .section .activity .activityinstance,
|
||||
.section .activity .activityinstance {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.section .activity .editing_move {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.dir-rtl .section .activity .editing_move {
|
||||
left: auto;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.section .activity .mod-indent {
|
||||
padding-left: 24px;
|
||||
}
|
||||
|
||||
.dir-rtl .section .activity .mod-indent {
|
||||
padding-left: auto;
|
||||
padding-right: 24px;
|
||||
}
|
||||
|
||||
.section .activity .actions {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.dir-rtl .section .activity .actions {
|
||||
left: 0;
|
||||
right: auto;
|
||||
}
|
||||
|
||||
.sitetopic .section .activity .activityinstance div,
|
||||
.course-content .section .activity .activityinstance div { display: inline;}
|
||||
.course-content .section .activity .activityinstance form { display: inline;}
|
||||
.sitetopic .section .activity .activityinstance,
|
||||
.course-content .section .activity .activityinstance { padding-right: 1em; }
|
||||
.course-content .section .activity .activityinstance {
|
||||
height: 2em;
|
||||
}
|
||||
|
||||
.editing .sitetopic .section .activity .activityinstance,
|
||||
.editing .course-content .section .activity .activityinstance {
|
||||
padding-right: 200px;
|
||||
height: 2em;
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
.dir-rtl.editing .sitetopic .section .activity .activityinstance,
|
||||
.dir-rtl.editing .course-content .section .activity .activityinstance {
|
||||
padding-left: 200px;
|
||||
padding-right: auto;
|
||||
}
|
||||
|
||||
.course-content .section .activity .filler {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin: 4px;
|
||||
display: inline-block;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
|
||||
.dir-rtl .sitetopic .section .activity .activityinstance,
|
||||
.dir-rtl .course-content .section .activity .activityinstance { padding-right: 0; padding-left: 3em;}
|
||||
.sitetopic .section .activity .commands,
|
||||
.course-content .section .activity .commands { white-space: nowrap; display: inline-block; padding: 0 3em 0 0;}
|
||||
.course-content .section .activity .commands {
|
||||
white-space: nowrap;
|
||||
display: inline-block;
|
||||
}
|
||||
.dir-rtl .sitetopic .section .activity .commands,
|
||||
.dir-rtl .course-content .section .activity .commands { padding: 0 0 0 3em;}
|
||||
|
||||
@@ -46,18 +107,24 @@
|
||||
.section .activity .moodle-actionmenu[data-enhanced] .menu > li > * {
|
||||
display: block;
|
||||
}
|
||||
.section .activity .moodle-actionmenu .menubar > li > img {
|
||||
margin-right: 5px;
|
||||
vertical-align: text-bottom;
|
||||
padding:0 3px 0 0;
|
||||
}
|
||||
.section .activity .moodle-actionmenu[data-enhanced] .menu {margin-left: -2.8em;}
|
||||
.section img.iconsmall {
|
||||
vertical-align: middle;
|
||||
vertical-align: text-bottom;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin: 4px;
|
||||
}
|
||||
.section .editing_title img.iconsmall {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
margin: 4px 8px 4px 0;
|
||||
}
|
||||
|
||||
.section .activity.editor_displayed a.editing_title,
|
||||
.section .activity.editor_displayed .moodle-actionmenu {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.single-section h3.sectionname {text-align:center;clear:both;}
|
||||
.sitetopic .section li.activity,
|
||||
.course-content .section li.activity {padding: .2em;}
|
||||
@@ -107,11 +174,7 @@
|
||||
|
||||
.path-site li.activity > div,
|
||||
.path-course-view li.activity > div {position:relative;}
|
||||
.path-course-view li.activity span.autocompletion,
|
||||
.path-course-view li.activity form.togglecompletion {position: absolute; top: 0; right: .2em;}
|
||||
.path-course-view li.activity span.autocompletion img,
|
||||
.path-course-view li.activity form.togglecompletion input {position:absolute; top: .25em; right: 0px;}
|
||||
.path-course-view li.activity form.togglecompletion .ajaxworking {position:absolute; right: 22px; top: 5px; width: 16px; height: 16px; background: url([[pix:i/ajaxloader]]) no-repeat;}
|
||||
.path-course-view li.activity form.togglecompletion .ajaxworking {position:absolute; right: 22px; width: 16px; height: 16px; background: url([[pix:i/ajaxloader]]) no-repeat;}
|
||||
.path-course-view li.activity form.togglecompletion div {display:inline;}
|
||||
.dir-rtl.path-course-view li.activity form.togglecompletion,
|
||||
.dir-rtl.path-course-view li.activity span.autocompletion {left:1.7em;right:auto;padding:0px;}
|
||||
@@ -214,6 +277,14 @@ li.section.hidden span.commands a.editing_show {cursor:default;}
|
||||
|
||||
.path-course .clearfloat {float:none; clear:both;height:0px;}
|
||||
|
||||
.section .spinner {
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
}
|
||||
.section .activity .spinner {
|
||||
margin: 4px;
|
||||
}
|
||||
|
||||
/* Quick edit of module name */
|
||||
|
||||
.sitetopic .section .activity form.activityinstance,
|
||||
@@ -235,7 +306,10 @@ span.editinstructions {
|
||||
border:1px solid #ddd;
|
||||
}
|
||||
.dir-rtl span.editinstructions { left: auto; right: 32px;}
|
||||
input.titleeditor { width: 330px; vertical-align: text-bottom; }
|
||||
input.titleeditor { vertical-align: text-bottom; }
|
||||
.editing .course-content .section .activity.editor_displayed .activityinstance {
|
||||
padding: initial;
|
||||
}
|
||||
|
||||
/* Course drag and drop upload styles */
|
||||
#dndupload-status {width:40%;margin:0 30%;padding:6px;border:1px solid #ddd;text-align:center;background:#ffc;position:absolute;z-index:9999;box-shadow:2px 2px 5px 1px #ccc;border-radius:0px 0px 8px 8px;z-index: 0;}
|
||||
@@ -296,6 +370,17 @@ input.titleeditor { width: 330px; vertical-align: text-bottom; }
|
||||
#course-category-listings .listing-actions .moodle-actionmenu:not([data-enhanced]) > .menubar a {color:inherit;}
|
||||
#course-category-listings .listing-actions .moodle-actionmenu:not([data-enhanced]) > .menubar a > img {display:none;}
|
||||
|
||||
.jsenabled #course-category-listings .moodle-actionmenu[data-enhance] .toggle-display img {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.jsenabled #course-category-listings .moodle-actionmenu[data-enhance] .toggle-display.textmenu {
|
||||
padding-right: 4px;
|
||||
}
|
||||
.jsenabled #course-category-listings .moodle-actionmenu[data-enhance] .toggle-display.textmenu .caret {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
#course-category-listings .item-actions {margin-right:1em;display:inline-block;display:initial;}
|
||||
#course-category-listings .item-actions img {margin: 0 4px;vertical-align:inherit;}
|
||||
#course-category-listings .item-actions .menu img {max-width:none;width:12px;}
|
||||
|
||||
@@ -104,7 +104,7 @@ fieldset#general {
|
||||
}
|
||||
|
||||
.editing .block .header .commands {
|
||||
padding: 2px 10px;
|
||||
padding: 2px 0;
|
||||
}
|
||||
|
||||
.block .header .block_action {
|
||||
|
||||
@@ -35,6 +35,10 @@
|
||||
height: 12px;
|
||||
}
|
||||
|
||||
.block .header .commands img.actionmenu {
|
||||
width:auto;
|
||||
}
|
||||
|
||||
.block .content {
|
||||
padding: 4px 14px;
|
||||
}
|
||||
|
||||
@@ -225,6 +225,7 @@ h4 img.iconhelp, h4 img.icon,
|
||||
h5 img.iconhelp, h5 img.icon,
|
||||
h6 img.iconhelp, h6 img.icon {
|
||||
vertical-align: middle;
|
||||
padding: 4px;
|
||||
}
|
||||
.dir-rtl img.iconhelp, .dir-rtl .helplink img {
|
||||
padding-right: 3px;
|
||||
@@ -2030,6 +2031,22 @@ img#persona_signin {
|
||||
display: inline; /** JS is enabled, we'll be using it so return display to normal **/
|
||||
.opacity(50);
|
||||
}
|
||||
.toggle-display.textmenu {
|
||||
display: block;
|
||||
margin-left: 4px;
|
||||
padding-left: 4px;
|
||||
|
||||
.iconsmall {
|
||||
margin: 4px 4px 4px 0px;
|
||||
padding: 8px 4px 0px 2px;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
|
||||
.caret {
|
||||
margin-top: 8px;
|
||||
margin-left: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.moodle-actionmenu[data-enhanced] {
|
||||
.toggle-display {
|
||||
@@ -2037,6 +2054,7 @@ img#persona_signin {
|
||||
}
|
||||
.menu-action-text {
|
||||
display:inline;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2059,7 +2077,7 @@ img#persona_signin {
|
||||
a {
|
||||
display: block;
|
||||
color: @dropdownLinkColor;
|
||||
padding:2px 1em 2px 24px;
|
||||
padding:2px 1em 2px 28px;
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: @dropdownLinkColorHover;
|
||||
@@ -2079,7 +2097,7 @@ img#persona_signin {
|
||||
vertical-align: middle;
|
||||
}
|
||||
.iconsmall {
|
||||
margin-left:-20px;
|
||||
margin: 4px 4px 4px -24px;
|
||||
}
|
||||
> li {
|
||||
display:block;
|
||||
@@ -2108,10 +2126,6 @@ img#persona_signin {
|
||||
}
|
||||
}
|
||||
|
||||
.action-menu-shown .moodle-actionmenu[data-enhanced] .toggle-display {
|
||||
background-color: #FFF;
|
||||
}
|
||||
|
||||
.block .moodle-actionmenu {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
@@ -38,8 +38,107 @@
|
||||
.course-content ul.section {
|
||||
margin: 1em;
|
||||
}
|
||||
.section .activity img.activityicon {
|
||||
.section {
|
||||
.spinner {
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
}
|
||||
.activity {
|
||||
.spinner {
|
||||
margin: 4px;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.editing_move {
|
||||
/* Move the move icon to the start of the line */
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.mod-indent {
|
||||
/**
|
||||
* Add appropriate padding such that nothing overlaps the
|
||||
* absolute positioned move icon.
|
||||
*/
|
||||
padding-left: 32px;
|
||||
}
|
||||
|
||||
/* The command block for each activity */
|
||||
.actions {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.activityinstance {
|
||||
.dimmed {
|
||||
img.activityicon {
|
||||
opacity: 0.5;
|
||||
filter: alpha(opacity=50);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.filler {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
padding: 0.3em;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.activity.editor_displayed {
|
||||
a.editing_title,
|
||||
.moodle-actionmenu {
|
||||
display: none;
|
||||
}
|
||||
div.activityinstance {
|
||||
padding: initial;
|
||||
|
||||
input {
|
||||
margin-bottom: initial;
|
||||
padding-top: initial;
|
||||
padding-bottom: initial;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dir-rtl .section {
|
||||
.activity {
|
||||
.spinner {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.editing_move {
|
||||
/* Move the move icon to the start of the line */
|
||||
left: auto;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.mod-indent {
|
||||
/**
|
||||
* Add appropriate padding such that nothing overlaps the
|
||||
* absolute positioned move icon.
|
||||
*/
|
||||
padding-left: auto;
|
||||
padding-right: 32px;
|
||||
}
|
||||
|
||||
/* The command block for each activity */
|
||||
.actions {
|
||||
left: 0;
|
||||
right: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.activity img.activityicon {
|
||||
margin-right: 6px;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
.dir-rtl .section .activity img.activityicon {
|
||||
margin-left: 6px;
|
||||
@@ -49,12 +148,30 @@
|
||||
.section .activity .activityinstance div {
|
||||
display: inline-block;
|
||||
}
|
||||
.editing .section .activity .activityinstance {
|
||||
min-width: 40%;
|
||||
.editing {
|
||||
.section {
|
||||
.activity {
|
||||
.activityinstance {
|
||||
min-width: 40%;
|
||||
display: table-cell;
|
||||
padding-right: 200px;
|
||||
min-height: 2em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.section .activity .activityinstance > a {
|
||||
display: block;
|
||||
|
||||
.dir-rtl.editing {
|
||||
.section {
|
||||
.activity {
|
||||
.activityinstance {
|
||||
padding-left: 200px;
|
||||
padding-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.editing_show + .editing_assign,
|
||||
.editing_hide + .editing_assign {
|
||||
// if roles icon missing, add space
|
||||
@@ -246,24 +363,20 @@
|
||||
position: relative;
|
||||
padding: 0 0 0 16px;
|
||||
}
|
||||
.path-course-view li.activity span.autocompletion,
|
||||
.path-course-view li.activity form.togglecompletion {
|
||||
float: right;
|
||||
width: 0; /* Reduce the width of the control to 0 and rely on natural overflow */
|
||||
.path-course-view li.activity span.autocompletion img {
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
.path-course-view li.activity span.autocompletion img,
|
||||
.path-course-view li.activity form.togglecompletion img {
|
||||
max-width: none; /* The width is 0 so ensure we don't end up with a relative max-width */
|
||||
}
|
||||
.path-course-view li.activity form.togglecompletion .ajaxworking {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
position: absolute;
|
||||
right: 22px;
|
||||
top: 3px;
|
||||
background: url([[pix:i/ajaxloader]]) no-repeat;
|
||||
}
|
||||
.dir-rtl.path-course-view li.activity form.togglecompletion,
|
||||
.dir-rtl.path-course-view li.activity span.autocompletion {
|
||||
float: left;
|
||||
}
|
||||
.dir-rtl.path-course-view .completionprogress {
|
||||
float: none;
|
||||
}
|
||||
@@ -613,15 +726,41 @@ span.editinstructions {
|
||||
margin: 10px 0 20px;
|
||||
}
|
||||
|
||||
.section .activity .moodle-actionmenu .iconsmall {
|
||||
max-width: none !important; /** reset sets 100% !important which breaks on IE8 without this !important */
|
||||
width:16px;
|
||||
height:16px;
|
||||
padding:0.3em;
|
||||
.section {
|
||||
.activity {
|
||||
.iconsmall {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
.editing_title {
|
||||
.iconsmall {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
margin: 8px 8px 0px 0;
|
||||
padding: 4px 8px 0px 0;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
}
|
||||
.moodle-actionmenu {
|
||||
.iconsmall {
|
||||
max-width: none !important; /** reset sets 100% !important which breaks on IE8 without this !important */
|
||||
width:16px;
|
||||
height:16px;
|
||||
padding: 4px;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
}
|
||||
.moodle-actionmenu[data-enhanced] {
|
||||
.menu {
|
||||
img {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Course management page
|
||||
* Palette
|
||||
@@ -667,6 +806,22 @@ span.editinstructions {
|
||||
.moodle-actionmenu {
|
||||
white-space:nowrap;
|
||||
}
|
||||
|
||||
.moodle-actionmenu[data-enhance] {
|
||||
.toggle-display {
|
||||
img {
|
||||
width: auto;
|
||||
}
|
||||
&.textmenu {
|
||||
padding-right: 4px;
|
||||
|
||||
.caret {
|
||||
margin-top: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.listing-actions {
|
||||
text-align:center;
|
||||
padding:0.4rem 0.3rem 0.3rem;
|
||||
|
||||
@@ -230,7 +230,6 @@
|
||||
border-bottom: thin solid #eee;
|
||||
}
|
||||
.course-content .section .activity .commands {
|
||||
display: block;
|
||||
text-align: right;
|
||||
}
|
||||
/** Handles display of the activity chooser on small screens **/
|
||||
@@ -375,18 +374,6 @@
|
||||
float: left;
|
||||
}
|
||||
|
||||
// Hide broken drag'n'drop options on touch devices MDL-38371
|
||||
// Not a great workaround, landscape iPads are wider than this,
|
||||
// and a resized window on a netbook could be smaller, but best
|
||||
// we can do with CSS. There might be a JS-based solution.
|
||||
.section .side,
|
||||
.editing_move {
|
||||
display: none;
|
||||
}
|
||||
.activityinstance > a {
|
||||
display: block;
|
||||
}
|
||||
|
||||
// GRID & CONTAINERS
|
||||
// -----------------
|
||||
// Remove width from containers
|
||||
|
||||
@@ -427,6 +427,7 @@ input[type=text],textarea,select,input[type=password]{
|
||||
clear:both;
|
||||
margin:0;
|
||||
padding:5px 0 0 10px;
|
||||
margin: 0 10px;
|
||||
}
|
||||
.block-region .block .content .commands{
|
||||
border:0 none;
|
||||
|
||||