MDL-39814 frontend: redeveloped overlay to correct tab-flow
Also: * fixed zindex issue + spinner placement * added notes to course format and theme upgrade texts * fixed behat tests after action menu changes
This commit is contained in:
@@ -21,7 +21,8 @@ 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 |
|
||||
When I click on "Duplicate" "link" in the "#section-1" "css_element"
|
||||
And I click on "Actions" "link" in the "Test database name" activity
|
||||
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 fill the moodle form with:
|
||||
|
||||
@@ -2,6 +2,11 @@ This files describes API changes for course formats
|
||||
|
||||
Overview of this plugin type at http://docs.moodle.org/dev/Course_formats
|
||||
|
||||
=== 2.6 ===
|
||||
|
||||
* core_course_renderer::course_section_cm_edit_actions has two new optional arguments and now uses and action_menu component.
|
||||
* core_course_renderer::course_section_cm has been altered to call core_course_renderer::course_section_cm_edit_actions with the two new arguments
|
||||
|
||||
=== 2.5 ===
|
||||
|
||||
* Functions responsible for output in course/lib.php are deprecated, the code is moved to
|
||||
|
||||
+6
-6
@@ -1865,7 +1865,7 @@ function course_get_cm_edit_actions(cm_info $mod, $indent = -1, $sr = null) {
|
||||
}
|
||||
|
||||
// Duplicate (require both target import caps to be able to duplicate and backup2 support, see modduplicate.php)
|
||||
// note that restoring on front page is never allowed.
|
||||
// Note that restoring on front page is never allowed.
|
||||
if ($mod->course != SITEID && has_all_capabilities($dupecaps, $coursecontext) &&
|
||||
plugin_supports('mod', $mod->modname, FEATURE_BACKUP_MOODLE2)) {
|
||||
$actions['duplicate'] = new action_menu_secondary_action(
|
||||
@@ -1913,19 +1913,19 @@ function course_get_cm_edit_actions(cm_info $mod, $indent = -1, $sr = null) {
|
||||
$modgroupmode = $mod->groupmode;
|
||||
}
|
||||
if ($modgroupmode == SEPARATEGROUPS) {
|
||||
$groupmode = NOGROUPS;
|
||||
$nextgroupmode = VISIBLEGROUPS;
|
||||
$grouptitle = $str->groupsseparate;
|
||||
$forcedgrouptitle = $str->forcedgroupsseparate;
|
||||
$actionname = 'groupsseparate';
|
||||
$groupimage = 't/groups';
|
||||
} else if ($modgroupmode == VISIBLEGROUPS) {
|
||||
$groupmode = SEPARATEGROUPS;
|
||||
$nextgroupmode = NOGROUPS;
|
||||
$grouptitle = $str->groupsvisible;
|
||||
$forcedgrouptitle = $str->forcedgroupsvisible;
|
||||
$actionname = 'groupsvisible';
|
||||
$groupimage = 't/groupv';
|
||||
} else {
|
||||
$groupmode = VISIBLEGROUPS;
|
||||
$nextgroupmode = SEPARATEGROUPS;
|
||||
$grouptitle = $str->groupsnone;
|
||||
$forcedgrouptitle = $str->forcedgroupsnone;
|
||||
$actionname = 'groupsnone';
|
||||
@@ -1933,10 +1933,10 @@ function course_get_cm_edit_actions(cm_info $mod, $indent = -1, $sr = null) {
|
||||
}
|
||||
if (!$mod->coursegroupmodeforce) {
|
||||
$actions[$actionname] = new action_menu_primary_action(
|
||||
new moodle_url($baseurl, array('id' => $mod->id, 'groupmode' => $groupmode)),
|
||||
new moodle_url($baseurl, array('id' => $mod->id, 'groupmode' => $nextgroupmode)),
|
||||
new pix_icon($groupimage, $grouptitle, 'moodle', array('class' => 'iconsmall', 'title' => '')),
|
||||
$grouptitle,
|
||||
array('class' => 'editing_'. $actionname, 'data-action' => $actionname, 'data-groupmode' => $groupmode)
|
||||
array('class' => 'editing_'. $actionname, 'data-action' => $actionname, 'data-nextgroupmode' => $nextgroupmode)
|
||||
);
|
||||
} else {
|
||||
$actions[$actionname] = new pix_icon($groupimage, $forcedgrouptitle, 'moodle', array('title' => '', 'class' => 'iconsmall'));
|
||||
|
||||
@@ -26,7 +26,7 @@ Feature: Indent items on the course page
|
||||
When I indent right "Test glossary name" activity
|
||||
Then "#section-1 li.glossary div.mod-indent-1" "css_element" should exists
|
||||
And I indent right "Test glossary name" activity
|
||||
And "//li[@id='section-1']/descendant::li[contains(concat(' ', @class, ' '), ' glossary ')]/descendant::a[@title='Move left']" "xpath_element" should exists
|
||||
And "//li[@id='section-1']/descendant::li[contains(concat(' ', @class, ' '), ' glossary ')]/descendant::a[not(contains(concat(' ', @class, ' '), ' hidden '))]/descendant::span[normalize-space(.)='Move left']" "xpath_element" should exists
|
||||
And "#section-1 li.glossary div.mod-indent-2" "css_element" should exists
|
||||
And I reload the page
|
||||
And "#section-1 li.glossary div.mod-indent-2" "css_element" should exists
|
||||
@@ -34,4 +34,4 @@ Feature: Indent items on the course page
|
||||
And I indent left "Test glossary name" activity
|
||||
And "#section-1 li.glossary div.mod-indent-2" "css_element" should not exists
|
||||
And "#section-1 li.glossary div.mod-indent-1" "css_element" should not exists
|
||||
And "//li[@id='section-1']/descendant::li[contains(concat(' ', @class, ' '), ' glossary ')]/descendant::a[@title='Move left']" "xpath_element" should not exists
|
||||
And "//li[@id='section-1']/descendant::li[contains(concat(' ', @class, ' '), ' glossary ')]/descendant::a[not(contains(concat(' ', @class, ' '), ' hidden '))]/descendant::span[normalize-space(.)='Move left']" "xpath_element" should not exists
|
||||
|
||||
@@ -485,8 +485,10 @@ class behat_course extends behat_base {
|
||||
}
|
||||
|
||||
// Adding chr(10) to save changes.
|
||||
$activity = $this->escape($activityname);
|
||||
return array(
|
||||
new Given('I click on "' . get_string('edittitle') . '" "link" in the "' . $this->escape($activityname) .'" activity'),
|
||||
new Given('I click on "' . get_string('actions', 'moodle') . '" "link" in the "' . $activity . '" activity'),
|
||||
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')
|
||||
);
|
||||
@@ -500,9 +502,12 @@ class behat_course extends behat_base {
|
||||
*/
|
||||
public function i_indent_right_activity($activityname) {
|
||||
|
||||
$steps = array(
|
||||
new Given('I click on "' . get_string('moveright') . '" "link" in the "' . $this->escape($activityname) . '" activity')
|
||||
);
|
||||
$steps = array();
|
||||
$activity = $this->escape($activityname);
|
||||
if ($this->running_javascript()) {
|
||||
$steps[] = new Given('I click on "' . get_string('actions', 'moodle') . '" "link" in the "' . $activity . '" activity');
|
||||
}
|
||||
$steps[] = new Given('I click on "' . get_string('moveright') . '" "link" in the "' . $activity . '" activity');
|
||||
|
||||
if ($this->running_javascript()) {
|
||||
$steps[] = new Given('I wait "2" seconds');
|
||||
@@ -519,9 +524,12 @@ class behat_course extends behat_base {
|
||||
*/
|
||||
public function i_indent_left_activity($activityname) {
|
||||
|
||||
$steps = array(
|
||||
new Given('I click on "' . get_string('moveleft') . '" "link" in the "' . $this->escape($activityname) . '" activity')
|
||||
);
|
||||
$steps = array();
|
||||
$activity = $this->escape($activityname);
|
||||
if ($this->running_javascript()) {
|
||||
$steps[] = new Given('I click on "' . get_string('actions', 'moodle') . '" "link" in the "' . $activity . '" activity');
|
||||
}
|
||||
$steps[] = new Given('I click on "' . get_string('moveleft') . '" "link" in the "' . $activity . '" activity');
|
||||
|
||||
if ($this->running_javascript()) {
|
||||
$steps[] = new Given('I wait "2" seconds');
|
||||
@@ -572,11 +580,15 @@ class behat_course extends behat_base {
|
||||
* @param string $activityname
|
||||
*/
|
||||
public function i_duplicate_activity($activityname) {
|
||||
return array(
|
||||
new Given('I click on "' . get_string('duplicate') . '" "link" in the "' . $this->escape($activityname) . '" activity'),
|
||||
new Given('I press "' . get_string('continue') .'"'),
|
||||
new Given('I press "' . get_string('duplicatecontcourse') .'"')
|
||||
);
|
||||
$steps = array();
|
||||
$activity = $this->escape($activityname);
|
||||
if ($this->running_javascript()) {
|
||||
$steps[] = new Given('I click on "' . get_string('actions', 'moodle') . '" "link" in the "' . $activity . '" activity');
|
||||
}
|
||||
$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') .'"');
|
||||
return $steps;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -587,13 +599,17 @@ class behat_course extends behat_base {
|
||||
* @param TableNode $data
|
||||
*/
|
||||
public function i_duplicate_activity_editing_the_new_copy_with($activityname, TableNode $data) {
|
||||
return array(
|
||||
new Given('I click on "' . get_string('duplicate') . '" "link" in the "' . $this->escape($activityname) . '" activity'),
|
||||
new Given('I press "' . get_string('continue') .'"'),
|
||||
new Given('I press "' . get_string('duplicatecontedit') . '"'),
|
||||
new Given('I fill the moodle form with:', $data),
|
||||
new Given('I press "' . get_string('savechangesandreturntocourse') . '"')
|
||||
);
|
||||
$steps = array();
|
||||
$activity = $this->escape($activityname);
|
||||
if ($this->running_javascript()) {
|
||||
$steps[] = new Given('I click on "' . get_string('actions', 'moodle') . '" "link" in the "' . $activity . '" activity');
|
||||
}
|
||||
$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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -40,6 +40,7 @@ Feature: Course activity controls works as expected
|
||||
And I should see "Turn editing on"
|
||||
And "Turn editing on" "button" should exists
|
||||
And I turn editing mode on
|
||||
And I click on "Actions" "link" in the ".block_recent_activity" "css_element"
|
||||
And I click on "Delete Recent activity block" "link"
|
||||
And I press "Yes"
|
||||
And "#section-2" "css_element" <should_see_other_sections> exists
|
||||
@@ -54,11 +55,13 @@ 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 "Actions" "link" in the "Test forum name 1" activity
|
||||
And I click on "Update" "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"
|
||||
And "#section-2" "css_element" <should_see_other_sections> exists
|
||||
And I click on "Actions" "link" in the "Test forum name 1" activity
|
||||
And I click on "Hide" "link" in the "Test forum name 1" activity
|
||||
And "#section-2" "css_element" <should_see_other_sections> exists
|
||||
And I duplicate "Test forum name 2" activity editing the new copy with:
|
||||
@@ -111,6 +114,7 @@ Feature: Course activity controls works as expected
|
||||
And I should see "Turn editing on"
|
||||
And "Turn editing on" "button" should exists
|
||||
And I turn editing mode on
|
||||
And I click on "Actions" "link" in the ".block_recent_activity" "css_element"
|
||||
And I click on "Delete Recent activity block" "link"
|
||||
And I press "Yes"
|
||||
And "#section-2" "css_element" <should_see_other_sections> exists
|
||||
@@ -125,11 +129,13 @@ 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 "Actions" "link" in the "Test forum name 1" activity
|
||||
And I click on "Update" "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"
|
||||
And "#section-2" "css_element" <should_see_other_sections> exists
|
||||
And I click on "Actions" "link" in the "Test forum name 1" activity
|
||||
And I click on "Hide" "link" in the "Test forum name 1" activity
|
||||
And "#section-2" "css_element" <should_see_other_sections> exists
|
||||
And I delete "Test forum name 1" activity
|
||||
|
||||
Vendored
+41
-22
@@ -237,6 +237,7 @@ YUI.add('moodle-course-toolboxes', function(Y) {
|
||||
initializer : function(config) {
|
||||
M.course.coursebase.register_module(this);
|
||||
Y.all(SELECTOR.ACTIVITYLI).each(function(activity){
|
||||
activity.setData('toolbox', this);
|
||||
activity.all(SELECTOR.COMMANDSPAN+ ' ' + SELECTOR.ACTIVITYACTION).each(function(){
|
||||
this.setData('activity', activity);
|
||||
});
|
||||
@@ -343,11 +344,20 @@ YUI.add('moodle-course-toolboxes', function(Y) {
|
||||
'field' : 'indent',
|
||||
'value' : newindent,
|
||||
'id' : this.get_element_id(activity)
|
||||
};
|
||||
var spinner = M.util.add_spinner(Y, activity.one(SELECTOR.COMMANDSPAN));
|
||||
},
|
||||
commands = activity.one(SELECTOR.COMMANDSPAN),
|
||||
spinner = M.util.add_spinner(Y, commands).setStyles({
|
||||
position: 'absolute',
|
||||
top: 0
|
||||
});
|
||||
if (BODY.hasClass('dir-ltr')) {
|
||||
spinner.setStyle('left', '100%');
|
||||
} else {
|
||||
spinner.setStyle('right', '100%');
|
||||
}
|
||||
this.send_request(data, spinner);
|
||||
|
||||
// Handle removal/addition of the moveleft button
|
||||
// Handle removal/addition of the moveleft button.
|
||||
if (newindent == 0) {
|
||||
button.addClass('hidden');
|
||||
} else if (newindent == 1 && oldindent == 0) {
|
||||
@@ -507,14 +517,18 @@ YUI.add('moodle-course-toolboxes', function(Y) {
|
||||
ev.preventDefault();
|
||||
|
||||
// Current Mode
|
||||
var oldgroupmode = button.getData('groupmode');
|
||||
var groupmode = parseInt(oldgroupmode, 10) + 1;
|
||||
if (groupmode > 2) {
|
||||
groupmode = 0;
|
||||
var groupmode = parseInt(button.getData('nextgroupmode'), 10),
|
||||
newtitle = '',
|
||||
iconsrc = '',
|
||||
newtitlestr,
|
||||
data,
|
||||
spinner,
|
||||
nextgroupmode = groupmode + 1;
|
||||
|
||||
if (nextgroupmode > 2) {
|
||||
nextgroupmode = 0;
|
||||
}
|
||||
|
||||
var newtitle = '';
|
||||
var iconsrc = '';
|
||||
if (groupmode === this.GROUPS_NONE) {
|
||||
newtitle = 'groupsnone';
|
||||
iconsrc = M.util.image_url('t/groupn', 'moodle');
|
||||
@@ -525,24 +539,25 @@ YUI.add('moodle-course-toolboxes', function(Y) {
|
||||
newtitle = 'groupsvisible';
|
||||
iconsrc = M.util.image_url('t/groupv', 'moodle');
|
||||
}
|
||||
var newtitlestr = M.util.get_string(newtitle, 'moodle'),
|
||||
newtitlestr = M.util.get_string('clicktochangeinbrackets', 'moodle', newtitlestr);
|
||||
newtitlestr = M.util.get_string(newtitle, 'moodle'),
|
||||
newtitlestr = M.util.get_string('clicktochangeinbrackets', 'moodle', newtitlestr);
|
||||
|
||||
// Change the UI
|
||||
button.one('img').setAttrs({
|
||||
'alt' : newtitlestr,
|
||||
'src' : iconsrc
|
||||
});
|
||||
button.setAttribute('title', newtitlestr).setData('action', newtitle).setData('groupmode', groupmode);
|
||||
button.setAttribute('title', newtitlestr).setData('action', newtitle).setData('nextgroupmode', nextgroupmode);
|
||||
|
||||
// And send the request
|
||||
var data = {
|
||||
data = {
|
||||
'class' : 'resource',
|
||||
'field' : 'groupmode',
|
||||
'value' : groupmode,
|
||||
'id' : this.get_element_id(activity)
|
||||
};
|
||||
var spinner = M.util.add_spinner(Y, activity.one(SELECTOR.COMMANDSPAN));
|
||||
|
||||
spinner = M.util.add_spinner(Y, activity.one(SELECTOR.COMMANDSPAN));
|
||||
this.send_request(data, spinner);
|
||||
return false; // Need to return false to stop the delegate for the new state firing
|
||||
},
|
||||
@@ -696,15 +711,17 @@ YUI.add('moodle-course-toolboxes', function(Y) {
|
||||
* and 'visible' being the state that the visibility should be set to.
|
||||
*/
|
||||
set_visibility_resource_ui: function(args) {
|
||||
var element = args.element;
|
||||
var shouldbevisible = args.visible;
|
||||
var buttonnode = element.one(SELECTOR.SHOW);
|
||||
var visible = (buttonnode === null);
|
||||
var element = args.element,
|
||||
shouldbevisible = args.visible,
|
||||
buttonnode = element.one(SELECTOR.SHOW),
|
||||
visible = (buttonnode === null),
|
||||
status = 'hide';
|
||||
if (visible) {
|
||||
buttonnode = element.one(SELECTOR.HIDE);
|
||||
status = 'show'
|
||||
}
|
||||
if (visible != shouldbevisible) {
|
||||
this.change_visibility_ui(buttonnode);
|
||||
this.handle_resource_dim(buttonnode, buttonnode.get('activity'), status);
|
||||
}
|
||||
}
|
||||
}, {
|
||||
@@ -768,17 +785,19 @@ YUI.add('moodle-course-toolboxes', function(Y) {
|
||||
// The value to submit
|
||||
var value;
|
||||
// The status text for strings and images
|
||||
var status;
|
||||
var status,
|
||||
oldstatus;
|
||||
|
||||
if (!section.hasClass(CSS.SECTIONHIDDENCLASS)) {
|
||||
section.addClass(CSS.SECTIONHIDDENCLASS);
|
||||
value = 0;
|
||||
status = 'show';
|
||||
|
||||
oldstatus = 'hide';
|
||||
} else {
|
||||
section.removeClass(CSS.SECTIONHIDDENCLASS);
|
||||
value = 1;
|
||||
status = 'hide';
|
||||
oldstatus = 'show';
|
||||
}
|
||||
|
||||
var newstring = M.util.get_string(status + 'fromothers', 'format_' + this.get('format'));
|
||||
@@ -811,7 +830,7 @@ YUI.add('moodle-course-toolboxes', function(Y) {
|
||||
var activityid = this.get_element_id(node);
|
||||
|
||||
if (Y.Array.indexOf(response.resourcestotoggle, activityid) != -1) {
|
||||
this.change_visibility_ui(button);
|
||||
node.getData('toolbox').handle_resource_dim(button, node, oldstatus);
|
||||
}
|
||||
}, this);
|
||||
},
|
||||
|
||||
@@ -3044,6 +3044,8 @@ class tabtree extends tabobject {
|
||||
*/
|
||||
class action_menu implements renderable {
|
||||
|
||||
protected $instance = 0;
|
||||
|
||||
/**
|
||||
* An array of primary actions. Please use {@see action_menu::add_primary_action()} to add actions.
|
||||
* @var array
|
||||
@@ -3082,25 +3084,27 @@ class action_menu implements renderable {
|
||||
*/
|
||||
public function __construct(array $actions = array()) {
|
||||
static $initialised = 0;
|
||||
$this->instance = $initialised;
|
||||
$initialised++;
|
||||
|
||||
$this->attributes = array(
|
||||
'id' => 'action-menu-'.$initialised,
|
||||
'id' => 'action-menu-'.$this->instance,
|
||||
'class' => 'moodle-actionmenu',
|
||||
'data-enhance' => 'moodle-core-actionmenu'
|
||||
);
|
||||
$this->attributesprimary = array(
|
||||
'id' => 'action-menu-'.$initialised.'-primary',
|
||||
'id' => 'action-menu-'.$this->instance.'-primary',
|
||||
'class' => 'primary'
|
||||
);
|
||||
$this->attributessecondary = array(
|
||||
'id' => 'action-menu-'.$initialised.'-secondary',
|
||||
'id' => 'action-menu-'.$this->instance.'-secondary',
|
||||
'class' => 'secondary',
|
||||
'data-rel' => 'menu-content',
|
||||
'aria-labelledby' => 'action-menu-toggle-'.$this->instance,
|
||||
);
|
||||
foreach ($actions as $action) {
|
||||
$this->add($action);
|
||||
}
|
||||
// We've initialised!
|
||||
$initialised++;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3165,13 +3169,21 @@ class action_menu implements renderable {
|
||||
if ($output === null) {
|
||||
$output = $OUTPUT;
|
||||
}
|
||||
$actions = $this->primaryactions;
|
||||
$actions[] = $output->pix_icon(
|
||||
$title = get_string('actions', 'moodle');
|
||||
$pixicon = $output->pix_icon(
|
||||
't/contextmenu',
|
||||
get_string('actions', 'moodle'),
|
||||
$title,
|
||||
'moodle',
|
||||
array('class' => 'toggle-display iconsmall')
|
||||
array('class' => 'iconsmall')
|
||||
);
|
||||
|
||||
$actions = $this->primaryactions;
|
||||
$attributes = array(
|
||||
'class' => 'toggle-display',
|
||||
'title' => $title,
|
||||
'id' => 'action-menu-toggle-'.$this->instance
|
||||
);
|
||||
$actions[] = html_writer::link('#', $pixicon, $attributes);
|
||||
return $actions;
|
||||
}
|
||||
|
||||
|
||||
@@ -61,9 +61,9 @@ ACTIONMENU.prototype = {
|
||||
Y.log('Initialising action menu manager', 'note', ACTIONMENU.NAME);
|
||||
Y.all(SELECTOR.MENU).each(function() {
|
||||
var menucontent = this.one(SELECTOR.MENUCONTENT);
|
||||
menucontent.set('aria-hidden', true);
|
||||
if (menucontent.hasChildNodes()) {
|
||||
this.setAttribute('data-enhanced', '1');
|
||||
this.setData('menucontent', menucontent);
|
||||
}
|
||||
});
|
||||
BODY.delegate('click', this.toggleMenu, SELECTOR.MENU + ' ' + SELECTOR.TOGGLE, this);
|
||||
@@ -76,7 +76,13 @@ ACTIONMENU.prototype = {
|
||||
*/
|
||||
hideMenu : function() {
|
||||
if (this.dialogue) {
|
||||
this.dialogue.hide();
|
||||
this.dialogue.removeClass('show');
|
||||
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) {
|
||||
@@ -95,21 +101,27 @@ ACTIONMENU.prototype = {
|
||||
// Stop all immediate propogation of the events we attach later will be
|
||||
// triggered and the dialogue immediately hidden again.
|
||||
e.halt(true);
|
||||
this.showMenu(e.target.ancestor(SELECTOR.MENU), align = this.calculateAlign(e.target));
|
||||
this.hideMenu();
|
||||
this.showMenu(e.target.ancestor(SELECTOR.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));
|
||||
},
|
||||
|
||||
/**
|
||||
* Calculates the alignment point for the menu.
|
||||
* @param {Node} node
|
||||
* @returns {{node: *, points: Array}}
|
||||
* Hides the menu if the event happened outside the menu.
|
||||
*
|
||||
* @protected
|
||||
* @method hideIfOutside
|
||||
* @param {EventFacade} e
|
||||
*/
|
||||
calculateAlign : function(node) {
|
||||
var points = [Y.WidgetPositionAlign.TR, Y.WidgetPositionAlign.BR];
|
||||
if (BODY.hasClass('dir-rtl')) {
|
||||
points = [Y.WidgetPositionAlign.TL, Y.WidgetPositionAlign.BL];
|
||||
hideIfOutside : function(e) {
|
||||
if (!e.target.test('.secondary') && !e.target.ancestor('.secondary')) {
|
||||
this.hideMenu();
|
||||
}
|
||||
return {node: node, points : points};
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -118,67 +130,60 @@ ACTIONMENU.prototype = {
|
||||
* @param Array align
|
||||
* @returns {M.core.dialogue|dialogue}
|
||||
*/
|
||||
showMenu : function(menu, align) {
|
||||
showMenu : function(menu) {
|
||||
Y.log('Displaying action menu', 'note', ACTIONMENU.NAME);
|
||||
var bodyContent = menu.getData('menucontent'),
|
||||
ownerSelector = menu.getData('owner');
|
||||
var ownerSelector = menu.getData('owner'),
|
||||
menuContent = menu.one(SELECTOR.MENUCONTENT);
|
||||
this.owner = (ownerSelector) ? menu.ancestor(ownerSelector) : null;
|
||||
if (!this.dialogue) {
|
||||
this.dialogue = new M.core.dialogue({
|
||||
visible : false,
|
||||
bodyContent : bodyContent,
|
||||
align : align,
|
||||
lightbox : false,
|
||||
closeButton : false,
|
||||
additionalBaseClass : 'action-menu-dialogue',
|
||||
width : 'auto',
|
||||
constrain : BODY,
|
||||
hideOn : [
|
||||
{
|
||||
eventName: 'clickoutside'
|
||||
}
|
||||
]
|
||||
});
|
||||
this.dialogue.after('visibleChange', this.flagOwner, this);
|
||||
this.flagOwner({attrName: 'visible', newVal: true});
|
||||
} else {
|
||||
if (this.dialogue.get('visible')) {
|
||||
this.dialogue.hide();
|
||||
}
|
||||
this.dialogue.set('bodyContent', bodyContent);
|
||||
this.dialogue.set('align', align);
|
||||
this.dialogue.show();
|
||||
}
|
||||
return this.dialogue;
|
||||
this.dialogue = menu;
|
||||
menu.addClass('show');
|
||||
this.owner.addClass(CSS.MENUSHOWN);
|
||||
this.constrain(menuContent.set('aria-hidden', true));
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Flags the owner appropriately when the visibility of the dialogue changes.
|
||||
* @param {EventFacade} e
|
||||
* Constrains the node to its the page width.
|
||||
*
|
||||
* @method constrain
|
||||
* @param {Node} node
|
||||
*/
|
||||
flagOwner : function(e) {
|
||||
if (this.owner && e.attrName === 'visible') {
|
||||
if (e.newVal === true) {
|
||||
this.owner.addClass(CSS.MENUSHOWN);
|
||||
constrain : function(node) {
|
||||
var x = node.getX(),
|
||||
nodewidth = node.get('offsetWidth'),
|
||||
winwidth = node.get('winWidth'),
|
||||
newwidth = null,
|
||||
newleft = null;
|
||||
|
||||
if (x < 0) {
|
||||
x = 0;
|
||||
newleft = 0;
|
||||
} else if (x > winwidth) {
|
||||
x = winwidth;
|
||||
newleft = winwidth;
|
||||
}
|
||||
|
||||
if (x + nodewidth > winwidth) {
|
||||
if (nodewidth > winwidth) {
|
||||
newleft = 0;
|
||||
newwidth = winwidth;
|
||||
} else {
|
||||
this.owner.removeClass(CSS.MENUSHOWN);
|
||||
this.owner = null;
|
||||
newleft = winwidth - nodewidth;
|
||||
}
|
||||
}
|
||||
|
||||
if (newleft !== null) {
|
||||
node.setX(newleft);
|
||||
}
|
||||
if (newwidth !== null) {
|
||||
node.setStyle('width', newwidth.toString() + 'px');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Y.extend(ACTIONMENU, Y.Base, ACTIONMENU.prototype, {
|
||||
NAME : 'moodle-core-actionmenu',
|
||||
ATTRS : {
|
||||
/**
|
||||
* A selector to use to get the owner of the menu if there is one.
|
||||
* @attribute owner
|
||||
* @type String
|
||||
*/
|
||||
owner : {
|
||||
value : null
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -208,4 +213,4 @@ M.core.actionmenu.init = M.core.actionmenu.init || function(params) {
|
||||
};
|
||||
|
||||
|
||||
}, '@VERSION@', {"requires": ["base", "event", "moodle-core-notification"]});
|
||||
}, '@VERSION@', {"requires": ["base", "event"]});
|
||||
|
||||
@@ -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:"[data-enhance=moodle-core-actionmenu]",MENUCONTENT:"[data-rel=menu-content]",TOGGLE:".toggle-display"},s;s=function(){s.superclass.constructor.apply(this,arguments)},s.prototype={dialogue:null,events:[],owner:null,initializer:function(){e.all(i.MENU).each(function(){var e=this.one(i.MENUCONTENT);e.hasChildNodes()&&(this.setAttribute("data-enhanced","1"),this.setData("menucontent",e))}),n.delegate("click",this.toggleMenu,i.MENU+" "+i.TOGGLE,this),n.delegate("key",this.toggleMenu,"enter,space",i.MENU+" "+i.TOGGLE,this)},hideMenu:function(){this.dialogue&&this.dialogue.hide();for(var e in this.events)this.events[e].detach&&this.events[e].detach();this.events=[]},toggleMenu:function(e){e.halt(!0),this.showMenu(e.target.ancestor(i.MENU),align=this.calculateAlign(e.target)),this.events.push(n.on("key",this.hideMenu,"esc",this))},calculateAlign:function(t){var r=[e.WidgetPositionAlign.TR,e.WidgetPositionAlign.BR];return n.hasClass("dir-rtl")&&(r=[e.WidgetPositionAlign.TL,e.WidgetPositionAlign.BL]),{node:t,points:r}},showMenu:function(e,t){var r=e.getData("menucontent"),i=e.getData("owner");return this.owner=i?e.ancestor(i):null,this.dialogue?(this.dialogue.get("visible")&&this.dialogue.hide(),this.dialogue.set("bodyContent",r),this.dialogue.set("align",t),this.dialogue.show()):(this.dialogue=new M.core.dialogue({visible:!1,bodyContent:r,align:t,lightbox:!1,closeButton:!1,additionalBaseClass:"action-menu-dialogue",width:"auto",constrain:n,hideOn:[{eventName:"clickoutside"}]}),this.dialogue.after("visibleChange",this.flagOwner,this),this.flagOwner({attrName:"visible",newVal:!0})),this.dialogue},flagOwner:function(e){this.owner&&e.attrName==="visible"&&(e.newVal===!0?this.owner.addClass(r.MENUSHOWN):(this.owner.removeClass(r.MENUSHOWN),this.owner=null))}},e.extend(s,e.Base,s.prototype,{NAME:"moodle-core-actionmenu",ATTRS:{owner:{value:null}}}),M.core=M.core||{},M.core.actionmenu=M.core.actionmenu||{},M.core.actionmenu.init=M.core.actionmenu.init||function(e){M.core.actionmenu.instance=M.core.actionmenu.instance||new s(e)}},"@VERSION@",{requires:["base","event","moodle-core-notification"]});
|
||||
YUI.add("moodle-core-actionmenu",function(e,t){var n=e.one(e.config.doc.body),r={MENUSHOWN:"action-menu-shown"},i={MENU:"[data-enhance=moodle-core-actionmenu]",MENUCONTENT:"[data-rel=menu-content]",TOGGLE:".toggle-display"},s;s=function(){s.superclass.constructor.apply(this,arguments)},s.prototype={dialogue:null,events:[],owner:null,initializer:function(){e.all(i.MENU).each(function(){var e=this.one(i.MENUCONTENT);e.set("aria-hidden",!0),e.hasChildNodes()&&this.setAttribute("data-enhanced","1")}),n.delegate("click",this.toggleMenu,i.MENU+" "+i.TOGGLE,this),n.delegate("key",this.toggleMenu,"enter,space",i.MENU+" "+i.TOGGLE,this)},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){e.halt(!0),this.hideMenu(),this.showMenu(e.target.ancestor(i.MENU)),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(".secondary")&&!e.target.ancestor(".secondary")&&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.addClass(r.MENUSHOWN),this.constrain(n.set("aria-hidden",!0)),!0},constrain:function(e){var t=e.getX(),n=e.get("offsetWidth"),r=e.get("winWidth"),i=null,s=null;t<0?(t=0,s=0):t>r&&(t=r,s=r),t+n>r&&(n>r?(s=0,i=r):s=r-n),s!==null&&e.setX(s),i!==null&&e.setStyle("width",i.toString()+"px")}},e.extend(s,e.Base,s.prototype,{NAME:"moodle-core-actionmenu",ATTRS:{}}),M.core=M.core||{},M.core.actionmenu=M.core.actionmenu||{},M.core.actionmenu.init=M.core.actionmenu.init||function(e){M.core.actionmenu.instance=M.core.actionmenu.instance||new s(e)}},"@VERSION@",{requires:["base","event"]});
|
||||
|
||||
+63
-58
@@ -60,9 +60,9 @@ ACTIONMENU.prototype = {
|
||||
initializer : function() {
|
||||
Y.all(SELECTOR.MENU).each(function() {
|
||||
var menucontent = this.one(SELECTOR.MENUCONTENT);
|
||||
menucontent.set('aria-hidden', true);
|
||||
if (menucontent.hasChildNodes()) {
|
||||
this.setAttribute('data-enhanced', '1');
|
||||
this.setData('menucontent', menucontent);
|
||||
}
|
||||
});
|
||||
BODY.delegate('click', this.toggleMenu, SELECTOR.MENU + ' ' + SELECTOR.TOGGLE, this);
|
||||
@@ -75,7 +75,13 @@ ACTIONMENU.prototype = {
|
||||
*/
|
||||
hideMenu : function() {
|
||||
if (this.dialogue) {
|
||||
this.dialogue.hide();
|
||||
this.dialogue.removeClass('show');
|
||||
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) {
|
||||
@@ -94,21 +100,27 @@ ACTIONMENU.prototype = {
|
||||
// Stop all immediate propogation of the events we attach later will be
|
||||
// triggered and the dialogue immediately hidden again.
|
||||
e.halt(true);
|
||||
this.showMenu(e.target.ancestor(SELECTOR.MENU), align = this.calculateAlign(e.target));
|
||||
this.hideMenu();
|
||||
this.showMenu(e.target.ancestor(SELECTOR.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));
|
||||
},
|
||||
|
||||
/**
|
||||
* Calculates the alignment point for the menu.
|
||||
* @param {Node} node
|
||||
* @returns {{node: *, points: Array}}
|
||||
* Hides the menu if the event happened outside the menu.
|
||||
*
|
||||
* @protected
|
||||
* @method hideIfOutside
|
||||
* @param {EventFacade} e
|
||||
*/
|
||||
calculateAlign : function(node) {
|
||||
var points = [Y.WidgetPositionAlign.TR, Y.WidgetPositionAlign.BR];
|
||||
if (BODY.hasClass('dir-rtl')) {
|
||||
points = [Y.WidgetPositionAlign.TL, Y.WidgetPositionAlign.BL];
|
||||
hideIfOutside : function(e) {
|
||||
if (!e.target.test('.secondary') && !e.target.ancestor('.secondary')) {
|
||||
this.hideMenu();
|
||||
}
|
||||
return {node: node, points : points};
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -117,66 +129,59 @@ ACTIONMENU.prototype = {
|
||||
* @param Array align
|
||||
* @returns {M.core.dialogue|dialogue}
|
||||
*/
|
||||
showMenu : function(menu, align) {
|
||||
var bodyContent = menu.getData('menucontent'),
|
||||
ownerSelector = menu.getData('owner');
|
||||
showMenu : function(menu) {
|
||||
var ownerSelector = menu.getData('owner'),
|
||||
menuContent = menu.one(SELECTOR.MENUCONTENT);
|
||||
this.owner = (ownerSelector) ? menu.ancestor(ownerSelector) : null;
|
||||
if (!this.dialogue) {
|
||||
this.dialogue = new M.core.dialogue({
|
||||
visible : false,
|
||||
bodyContent : bodyContent,
|
||||
align : align,
|
||||
lightbox : false,
|
||||
closeButton : false,
|
||||
additionalBaseClass : 'action-menu-dialogue',
|
||||
width : 'auto',
|
||||
constrain : BODY,
|
||||
hideOn : [
|
||||
{
|
||||
eventName: 'clickoutside'
|
||||
}
|
||||
]
|
||||
});
|
||||
this.dialogue.after('visibleChange', this.flagOwner, this);
|
||||
this.flagOwner({attrName: 'visible', newVal: true});
|
||||
} else {
|
||||
if (this.dialogue.get('visible')) {
|
||||
this.dialogue.hide();
|
||||
}
|
||||
this.dialogue.set('bodyContent', bodyContent);
|
||||
this.dialogue.set('align', align);
|
||||
this.dialogue.show();
|
||||
}
|
||||
return this.dialogue;
|
||||
this.dialogue = menu;
|
||||
menu.addClass('show');
|
||||
this.owner.addClass(CSS.MENUSHOWN);
|
||||
this.constrain(menuContent.set('aria-hidden', true));
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Flags the owner appropriately when the visibility of the dialogue changes.
|
||||
* @param {EventFacade} e
|
||||
* Constrains the node to its the page width.
|
||||
*
|
||||
* @method constrain
|
||||
* @param {Node} node
|
||||
*/
|
||||
flagOwner : function(e) {
|
||||
if (this.owner && e.attrName === 'visible') {
|
||||
if (e.newVal === true) {
|
||||
this.owner.addClass(CSS.MENUSHOWN);
|
||||
constrain : function(node) {
|
||||
var x = node.getX(),
|
||||
nodewidth = node.get('offsetWidth'),
|
||||
winwidth = node.get('winWidth'),
|
||||
newwidth = null,
|
||||
newleft = null;
|
||||
|
||||
if (x < 0) {
|
||||
x = 0;
|
||||
newleft = 0;
|
||||
} else if (x > winwidth) {
|
||||
x = winwidth;
|
||||
newleft = winwidth;
|
||||
}
|
||||
|
||||
if (x + nodewidth > winwidth) {
|
||||
if (nodewidth > winwidth) {
|
||||
newleft = 0;
|
||||
newwidth = winwidth;
|
||||
} else {
|
||||
this.owner.removeClass(CSS.MENUSHOWN);
|
||||
this.owner = null;
|
||||
newleft = winwidth - nodewidth;
|
||||
}
|
||||
}
|
||||
|
||||
if (newleft !== null) {
|
||||
node.setX(newleft);
|
||||
}
|
||||
if (newwidth !== null) {
|
||||
node.setStyle('width', newwidth.toString() + 'px');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Y.extend(ACTIONMENU, Y.Base, ACTIONMENU.prototype, {
|
||||
NAME : 'moodle-core-actionmenu',
|
||||
ATTRS : {
|
||||
/**
|
||||
* A selector to use to get the owner of the menu if there is one.
|
||||
* @attribute owner
|
||||
* @type String
|
||||
*/
|
||||
owner : {
|
||||
value : null
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -206,4 +211,4 @@ M.core.actionmenu.init = M.core.actionmenu.init || function(params) {
|
||||
};
|
||||
|
||||
|
||||
}, '@VERSION@', {"requires": ["base", "event", "moodle-core-notification"]});
|
||||
}, '@VERSION@', {"requires": ["base", "event"]});
|
||||
|
||||
+62
-57
@@ -59,9 +59,9 @@ ACTIONMENU.prototype = {
|
||||
Y.log('Initialising action menu manager', 'note', ACTIONMENU.NAME);
|
||||
Y.all(SELECTOR.MENU).each(function() {
|
||||
var menucontent = this.one(SELECTOR.MENUCONTENT);
|
||||
menucontent.set('aria-hidden', true);
|
||||
if (menucontent.hasChildNodes()) {
|
||||
this.setAttribute('data-enhanced', '1');
|
||||
this.setData('menucontent', menucontent);
|
||||
}
|
||||
});
|
||||
BODY.delegate('click', this.toggleMenu, SELECTOR.MENU + ' ' + SELECTOR.TOGGLE, this);
|
||||
@@ -74,7 +74,13 @@ ACTIONMENU.prototype = {
|
||||
*/
|
||||
hideMenu : function() {
|
||||
if (this.dialogue) {
|
||||
this.dialogue.hide();
|
||||
this.dialogue.removeClass('show');
|
||||
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) {
|
||||
@@ -93,21 +99,27 @@ ACTIONMENU.prototype = {
|
||||
// Stop all immediate propogation of the events we attach later will be
|
||||
// triggered and the dialogue immediately hidden again.
|
||||
e.halt(true);
|
||||
this.showMenu(e.target.ancestor(SELECTOR.MENU), align = this.calculateAlign(e.target));
|
||||
this.hideMenu();
|
||||
this.showMenu(e.target.ancestor(SELECTOR.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));
|
||||
},
|
||||
|
||||
/**
|
||||
* Calculates the alignment point for the menu.
|
||||
* @param {Node} node
|
||||
* @returns {{node: *, points: Array}}
|
||||
* Hides the menu if the event happened outside the menu.
|
||||
*
|
||||
* @protected
|
||||
* @method hideIfOutside
|
||||
* @param {EventFacade} e
|
||||
*/
|
||||
calculateAlign : function(node) {
|
||||
var points = [Y.WidgetPositionAlign.TR, Y.WidgetPositionAlign.BR];
|
||||
if (BODY.hasClass('dir-rtl')) {
|
||||
points = [Y.WidgetPositionAlign.TL, Y.WidgetPositionAlign.BL];
|
||||
hideIfOutside : function(e) {
|
||||
if (!e.target.test('.secondary') && !e.target.ancestor('.secondary')) {
|
||||
this.hideMenu();
|
||||
}
|
||||
return {node: node, points : points};
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -116,67 +128,60 @@ ACTIONMENU.prototype = {
|
||||
* @param Array align
|
||||
* @returns {M.core.dialogue|dialogue}
|
||||
*/
|
||||
showMenu : function(menu, align) {
|
||||
showMenu : function(menu) {
|
||||
Y.log('Displaying action menu', 'note', ACTIONMENU.NAME);
|
||||
var bodyContent = menu.getData('menucontent'),
|
||||
ownerSelector = menu.getData('owner');
|
||||
var ownerSelector = menu.getData('owner'),
|
||||
menuContent = menu.one(SELECTOR.MENUCONTENT);
|
||||
this.owner = (ownerSelector) ? menu.ancestor(ownerSelector) : null;
|
||||
if (!this.dialogue) {
|
||||
this.dialogue = new M.core.dialogue({
|
||||
visible : false,
|
||||
bodyContent : bodyContent,
|
||||
align : align,
|
||||
lightbox : false,
|
||||
closeButton : false,
|
||||
additionalBaseClass : 'action-menu-dialogue',
|
||||
width : 'auto',
|
||||
constrain : BODY,
|
||||
hideOn : [
|
||||
{
|
||||
eventName: 'clickoutside'
|
||||
}
|
||||
]
|
||||
});
|
||||
this.dialogue.after('visibleChange', this.flagOwner, this);
|
||||
this.flagOwner({attrName: 'visible', newVal: true});
|
||||
} else {
|
||||
if (this.dialogue.get('visible')) {
|
||||
this.dialogue.hide();
|
||||
}
|
||||
this.dialogue.set('bodyContent', bodyContent);
|
||||
this.dialogue.set('align', align);
|
||||
this.dialogue.show();
|
||||
}
|
||||
return this.dialogue;
|
||||
this.dialogue = menu;
|
||||
menu.addClass('show');
|
||||
this.owner.addClass(CSS.MENUSHOWN);
|
||||
this.constrain(menuContent.set('aria-hidden', true));
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Flags the owner appropriately when the visibility of the dialogue changes.
|
||||
* @param {EventFacade} e
|
||||
* Constrains the node to its the page width.
|
||||
*
|
||||
* @method constrain
|
||||
* @param {Node} node
|
||||
*/
|
||||
flagOwner : function(e) {
|
||||
if (this.owner && e.attrName === 'visible') {
|
||||
if (e.newVal === true) {
|
||||
this.owner.addClass(CSS.MENUSHOWN);
|
||||
constrain : function(node) {
|
||||
var x = node.getX(),
|
||||
nodewidth = node.get('offsetWidth'),
|
||||
winwidth = node.get('winWidth'),
|
||||
newwidth = null,
|
||||
newleft = null;
|
||||
|
||||
if (x < 0) {
|
||||
x = 0;
|
||||
newleft = 0;
|
||||
} else if (x > winwidth) {
|
||||
x = winwidth;
|
||||
newleft = winwidth;
|
||||
}
|
||||
|
||||
if (x + nodewidth > winwidth) {
|
||||
if (nodewidth > winwidth) {
|
||||
newleft = 0;
|
||||
newwidth = winwidth;
|
||||
} else {
|
||||
this.owner.removeClass(CSS.MENUSHOWN);
|
||||
this.owner = null;
|
||||
newleft = winwidth - nodewidth;
|
||||
}
|
||||
}
|
||||
|
||||
if (newleft !== null) {
|
||||
node.setX(newleft);
|
||||
}
|
||||
if (newwidth !== null) {
|
||||
node.setStyle('width', newwidth.toString() + 'px');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Y.extend(ACTIONMENU, Y.Base, ACTIONMENU.prototype, {
|
||||
NAME : 'moodle-core-actionmenu',
|
||||
ATTRS : {
|
||||
/**
|
||||
* A selector to use to get the owner of the menu if there is one.
|
||||
* @attribute owner
|
||||
* @type String
|
||||
*/
|
||||
owner : {
|
||||
value : null
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
"moodle-core-actionmenu": {
|
||||
"requires": [
|
||||
"base",
|
||||
"event",
|
||||
"moodle-core-notification"
|
||||
"event"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
+24
-24
@@ -1373,30 +1373,30 @@ div.badge .expireimage { width: 100px; height: 100px; left: 20px; top: 0px; }
|
||||
|
||||
.path-mod-lesson .centerpadded { padding: 5px; text-align: center; }
|
||||
|
||||
.moodle-actionmenu .iconsmall {vertical-align: top;margin:0 3px;}
|
||||
|
||||
.moodle-actionmenu,
|
||||
.moodle-actionmenu .secondary {display: inline-block;}
|
||||
.moodle-actionmenu .toggle-display,
|
||||
.moodle-actionmenu .menu-action-text {display: none;}
|
||||
.jsenabled .block .editing_move {display: none;}
|
||||
.jsenabled .moodle-actionmenu [data-rel=menu-content] {display: none;margin-top: 4px;}
|
||||
.moodle-actionmenu .toggle-display {display: none;padding-right: 4px;padding-left: 4px;}
|
||||
.jsenabled .moodle-actionmenu .toggle-display {display: inline;opacity: 0.5;filter: alpha(opacity=50);}
|
||||
.moodle-actionmenu[data-enhanced] .toggle-display {opacity: 1;filter: alpha(opacity=100);}
|
||||
.statuses .actionlinktext {display: none;}
|
||||
.action-menu-dialogue {min-width:300px;}
|
||||
.action-menu-dialogue .moodle-dialogue-wrap {margin-top: 4px;margin-left: 4px;-webkit-border-radius: 4px;-moz-border-radius: 4px;border-radius: 4px;}
|
||||
.action-menu-dialogue .moodle-dialogue .moodle-dialogue-bd {padding: 0;}
|
||||
.action-menu-dialogue .moodle-dialogue-hd,
|
||||
.action-menu-dialogue .moodle-dialogue-ft {display: none;}
|
||||
.action-menu-dialogue a {display: block;padding: 2px 1em;color: #333333;}
|
||||
.action-menu-dialogue a.hidden {display: none;}
|
||||
.action-menu-dialogue .iconsmall {margin-right:8px;}
|
||||
.action-menu-dialogue a:hover,
|
||||
.action-menu-dialogue a:focus {color: #ffffff;background-color: #0088cc;}
|
||||
.action-menu-dialogue 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;}
|
||||
.action-menu-dialogue 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;}
|
||||
.jsenabled .moodle-actionmenu {display: block;}
|
||||
.jsenabled .moodle-actionmenu .secondary {display: none;margin-top: 4px;}
|
||||
.jsenabled .moodle-actionmenu[data-enhanced].show .secondary {display: block;}
|
||||
.jsenabled .moodle-actionmenu .toggle-display {display: inline;cursor: auto;opacity: 0.5;filter: alpha(opacity=50);}
|
||||
.jsenabled .moodle-actionmenu[data-enhanced] .toggle-display {opacity: 1;filter: alpha(opacity=100);}
|
||||
.jsenabled .moodle-actionmenu[data-enhanced] .menu-action-text {display: inline;}
|
||||
.moodle-actionmenu[data-enhanced].show {position: relative;}
|
||||
.moodle-actionmenu[data-enhanced].show .secondary {position: absolute;top: 100%;right: 0;left: auto;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;z-index:1000;}
|
||||
.moodle-actionmenu[data-enhanced].show .secondary a {display: block;padding: 2px 1em 2px 0.5em;color: #333333;}
|
||||
.moodle-actionmenu[data-enhanced].show .secondary a:hover,
|
||||
.moodle-actionmenu[data-enhanced].show .secondary a:focus {color: #ffffff;background-color: #0088cc;}
|
||||
.moodle-actionmenu[data-enhanced].show .secondary 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 .secondary 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 .secondary a.hidden {display: none;}
|
||||
.moodle-actionmenu[data-enhanced].show .secondary img {vertical-align: middle;}
|
||||
.moodle-actionmenu[data-enhanced].show .secondary .iconsmall {margin-right: 8px;}
|
||||
.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: left;}
|
||||
|
||||
.dir-rtl .block moodle-actionmenu {text-align: left;}
|
||||
.dir-rtl .action-menu-dialogue a {padding:2px 0.5em 2px 1em;}
|
||||
.dir-rtl .action-menu-dialogue .iconsmall {margin-right:0;margin-left:8px;}
|
||||
.dir-rtl .moodle-actionmenu .toggle-display {padding-left:0;padding-right:4px;}
|
||||
.dir-rtl .moodle-actionmenu[data-enhanced].show .secondary {right: auto;left: 0;}
|
||||
.dir-rtl .moodle-actionmenu[data-enhanced].show .secondary .iconsmall {margin-right: 0;margin-left: 8px;}
|
||||
.dir-rtl .block .moodle-actionmenu {text-align: right;}
|
||||
@@ -28,8 +28,8 @@
|
||||
.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; }
|
||||
.sitetopic .section .activity .commands img,
|
||||
.course-content .section .activity .commands img { vertical-align: baseline; padding: 0 2px; }
|
||||
.section .activity .moodle-actionmenu .iconsmall {ertical-align: baseline;width:16px;height:16px;width:1rem;height:1rem;padding:0 0.5em 0.3em;}
|
||||
|
||||
.sitetopic .section li.activity,
|
||||
.course-content .section li.activity {padding: .2em;}
|
||||
.section .activity .activityinstance .groupinglabel { padding-left: .45em; }
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
padding: 3px 5px;
|
||||
}
|
||||
.block .header .block_action {
|
||||
padding:4px;
|
||||
float: right;
|
||||
}
|
||||
.block .header .commands {
|
||||
|
||||
@@ -1911,121 +1911,110 @@ div.badge .expireimage {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.jsenabled .block .editing_move {
|
||||
display:none;
|
||||
.moodle-actionmenu,
|
||||
.moodle-actionmenu .secondary {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.jsenabled .moodle-actionmenu [data-rel=menu-content] {
|
||||
display:none;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.moodle-actionmenu .toggle-display {
|
||||
padding-left: 4px;
|
||||
.moodle-actionmenu .toggle-display,
|
||||
.moodle-actionmenu .menu-action-text {
|
||||
display: none; /** Hidden by default, display none so that we don't take up space. **/
|
||||
cursor:auto;
|
||||
}
|
||||
.jsenabled .moodle-actionmenu .toggle-display {
|
||||
display: inline; /** JS is enabled, we'll be using it so return display to normal **/
|
||||
.opacity(50);
|
||||
|
||||
.jsenabled {
|
||||
.block .editing_move {
|
||||
display:none;
|
||||
}
|
||||
.moodle-actionmenu {
|
||||
display: block;
|
||||
.secondary {
|
||||
display:none;
|
||||
margin-top: 4px;
|
||||
}
|
||||
}
|
||||
.moodle-actionmenu[data-enhanced].show .secondary {
|
||||
display:block;
|
||||
}
|
||||
|
||||
.moodle-actionmenu .toggle-display {
|
||||
display: inline; /** JS is enabled, we'll be using it so return display to normal **/
|
||||
cursor:auto;
|
||||
.opacity(50);
|
||||
}
|
||||
.moodle-actionmenu[data-enhanced] {
|
||||
.toggle-display {
|
||||
.opacity(100);
|
||||
}
|
||||
.menu-action-text {
|
||||
display:inline;
|
||||
}
|
||||
}
|
||||
}
|
||||
.moodle-actionmenu[data-enhanced] .toggle-display {
|
||||
.opacity(100);
|
||||
|
||||
.moodle-actionmenu[data-enhanced].show {
|
||||
|
||||
position: relative;
|
||||
|
||||
.secondary {
|
||||
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
right: 0;
|
||||
left: auto;
|
||||
background-color: #fff;
|
||||
border: 1px solid #ccc;
|
||||
z-index:1000;
|
||||
.border-radius(5px);
|
||||
.box-shadow(5px 5px 20px 0 #666);
|
||||
|
||||
a {
|
||||
display: block;
|
||||
color: @dropdownLinkColor;
|
||||
padding:2px 1em 2px 0.5em;
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: @dropdownLinkColorHover;
|
||||
background-color: @dropdownLinkBackgroundHover;
|
||||
}
|
||||
&:first-child {
|
||||
.border-top-radius(4px);
|
||||
}
|
||||
&:last-child {
|
||||
.border-bottom-radius(4px);
|
||||
}
|
||||
}
|
||||
a.hidden {
|
||||
display: none;
|
||||
}
|
||||
img {
|
||||
vertical-align: middle;
|
||||
}
|
||||
.iconsmall {
|
||||
margin-right:8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.action-menu-shown .moodle-actionmenu[data-enhanced] .toggle-display {
|
||||
background-color: #FFF;
|
||||
}
|
||||
|
||||
.moodle-actionmenu,
|
||||
.moodle-actionmenu .secondary {
|
||||
display: inline-block;
|
||||
}
|
||||
.jsenabled .moodle-actionmenu,
|
||||
.jsenabled .moodle-actionmenu .secondary {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.moodle-actionmenu .menu-action-text {
|
||||
display:none;
|
||||
}
|
||||
.jsenabled .moodle-actionmenu[data-enhanced] .menu-action-text {
|
||||
display:inline;
|
||||
}
|
||||
|
||||
.block .moodle-actionmenu {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.jsenabled #page .moodle-actionmenu .secondary {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.action-menu-dialogue {
|
||||
|
||||
.moodle-dialogue-wrap {
|
||||
margin-top:4px;
|
||||
margin-left:4px;
|
||||
.border-radius(4px);
|
||||
}
|
||||
|
||||
.moodle-dialogue {
|
||||
.moodle-dialogue-bd {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.moodle-dialogue-hd,
|
||||
.moodle-dialogue-ft {
|
||||
display: none;
|
||||
}
|
||||
a {
|
||||
display: block;
|
||||
color: @dropdownLinkColor;
|
||||
padding:2px 1em 2px 0.5em;
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: @dropdownLinkColorHover;
|
||||
background-color: @dropdownLinkBackgroundHover;
|
||||
}
|
||||
&:first-child {
|
||||
.border-top-radius(4px);
|
||||
}
|
||||
&:last-child {
|
||||
.border-bottom-radius(4px);
|
||||
}
|
||||
}
|
||||
a.hidden {
|
||||
display: none;
|
||||
}
|
||||
img {
|
||||
vertical-align: middle;
|
||||
}
|
||||
.iconsmall {
|
||||
margin-right:8px;
|
||||
}
|
||||
}
|
||||
|
||||
.safari .action-menu-dialogue .moodle-dialogue {
|
||||
/** Safari specific bug here **/
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.dir-rtl {
|
||||
.moodle-actionmenu[data-enhanced].show {
|
||||
.secondary {
|
||||
left: 0;
|
||||
right: auto;
|
||||
.iconsmall {
|
||||
margin-right:0;
|
||||
margin-left:8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.block .moodle-actionmenu {
|
||||
text-align: left;
|
||||
}
|
||||
.action-menu-dialogue {
|
||||
a {
|
||||
padding:2px 0.5em 2px 1em;
|
||||
}
|
||||
.iconsmall {
|
||||
margin-right:0;
|
||||
margin-left:8px;
|
||||
}
|
||||
}
|
||||
.moodle-actionmenu .toggle-display {
|
||||
padding-left:0;
|
||||
padding-right:4px;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -596,8 +596,7 @@ span.editinstructions {
|
||||
margin: 10px 0 20px;
|
||||
}
|
||||
|
||||
.section .activity .moodle-actionmenu .iconsmall,
|
||||
.section .activity .moodle-actionmenu .toggle-display {
|
||||
.section .activity .moodle-actionmenu .iconsmall {
|
||||
width:16px;
|
||||
height:16px;
|
||||
width:1rem;
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,6 +1,19 @@
|
||||
This files describes API changes in /theme/* themes,
|
||||
information provided here is intended especially for theme designer.
|
||||
|
||||
=== 2.6 ===
|
||||
|
||||
Notes:
|
||||
* A new component action_menu is now used to display editing icons for courses and blocks within a drop down. If you have a theme that doesn't
|
||||
extend base, canvas, or clean then you will need to style for this new component within your theme.
|
||||
|
||||
Renderer changes:
|
||||
* core_course_renderer::course_section_cm_edit_actions has two new optional arguments and now uses and action_menu component.
|
||||
* core_course_renderer::course_section_cm has been altered to call core_course_renderer::course_section_cm_edit_actions with the two new arguments.
|
||||
* core_renderer::block_controls has a new optional argument (the block id) and has been altered to use the new action_menu component.
|
||||
* core_renderer::block_header has been altered to give core_renderer::block_controls the new second argument, the block id.
|
||||
* core_renderer::action_link has a new argument, and optional icon that can be rendererd into the link.
|
||||
|
||||
=== 2.5.1 ===
|
||||
|
||||
Notes:
|
||||
|
||||
Reference in New Issue
Block a user