mirror of
https://github.com/moodle/moodle.git
synced 2025-04-21 00:12:56 +02:00
Merge branch 'MDL-74800-master' of https://github.com/ferranrecio/moodle
This commit is contained in:
commit
5d90181c6e
@ -102,7 +102,7 @@ class block_site_main_menu extends block_list {
|
||||
'contentwithoutlink activity-item activity'
|
||||
);
|
||||
} else {
|
||||
$cmname = new $cmnameclass($format, $cm->get_section_info(), $cm, $isediting);
|
||||
$cmname = new $cmnameclass($format, $cm->get_section_info(), $cm);
|
||||
$activitybasis = html_writer::div(
|
||||
$indent . $courserenderer->render($cmname),
|
||||
'activity-basis d-flex align-items-center');
|
||||
@ -214,7 +214,7 @@ class block_site_main_menu extends block_list {
|
||||
'contentwithoutlink activity-item activity'
|
||||
);
|
||||
} else {
|
||||
$cmname = new $cmnameclass($format, $mod->get_section_info(), $mod, $isediting);
|
||||
$cmname = new $cmnameclass($format, $mod->get_section_info(), $mod);
|
||||
$activitybasis = html_writer::div(
|
||||
$moveaction .
|
||||
$indent .
|
||||
|
@ -99,7 +99,7 @@ class block_social_activities extends block_list {
|
||||
$this->content->items[] = $content;
|
||||
$this->content->icons[] = '';
|
||||
} else {
|
||||
$cmname = new $cmnameclass($format, $cm->get_section_info(), $cm, $isediting);
|
||||
$cmname = new $cmnameclass($format, $cm->get_section_info(), $cm);
|
||||
$activitybasis = html_writer::div(
|
||||
$courserenderer->render($cmname),
|
||||
'activity-basis d-flex align-items-center');
|
||||
@ -205,7 +205,7 @@ class block_social_activities extends block_list {
|
||||
$this->content->items[] = $content;
|
||||
$this->content->icons[] = '';
|
||||
} else {
|
||||
$cmname = new $cmnameclass($format, $mod->get_section_info(), $mod, $isediting);
|
||||
$cmname = new $cmnameclass($format, $mod->get_section_info(), $mod);
|
||||
$activitybasis = html_writer::div(
|
||||
$courserenderer->render($cmname) .
|
||||
$editbuttons,
|
||||
|
@ -59,12 +59,6 @@ class cm implements named_templatable, renderable {
|
||||
/** @var array optional display options */
|
||||
protected $displayoptions;
|
||||
|
||||
/** @var string activity link css classes */
|
||||
protected $linkclasses = null;
|
||||
|
||||
/** @var string text css classes */
|
||||
protected $textclasses = null;
|
||||
|
||||
/** @var string the activity name output class name */
|
||||
protected $cmnameclass;
|
||||
|
||||
@ -88,10 +82,8 @@ class cm implements named_templatable, renderable {
|
||||
$this->mod = $mod;
|
||||
|
||||
// Add extra display options.
|
||||
$this->load_classes();
|
||||
$displayoptions['linkclasses'] = $this->get_link_classes();
|
||||
$displayoptions['textclasses'] = $this->get_text_classes();
|
||||
$this->displayoptions = $displayoptions;
|
||||
$this->load_classes();
|
||||
|
||||
// Get the necessary classes.
|
||||
$this->cmnameclass = $format->get_output_classname('content\\cm\\cmname');
|
||||
@ -148,11 +140,11 @@ class cm implements named_templatable, renderable {
|
||||
$this->format,
|
||||
$this->section,
|
||||
$this->mod,
|
||||
$this->format->show_editor(),
|
||||
null,
|
||||
$this->displayoptions
|
||||
);
|
||||
$data->cmname = $cmname->export_for_template($output);
|
||||
$data->hasname = !empty($data->cmname['displayvalue']);
|
||||
$data->hasname = $cmname->has_name();
|
||||
return $data->hasname;
|
||||
}
|
||||
|
||||
@ -323,8 +315,9 @@ class cm implements named_templatable, renderable {
|
||||
$textclasses .= ' conditionalhidden';
|
||||
}
|
||||
}
|
||||
$this->linkclasses = $linkclasses;
|
||||
$this->textclasses = $textclasses;
|
||||
$this->displayoptions['linkclasses'] = $linkclasses;
|
||||
$this->displayoptions['textclasses'] = $textclasses;
|
||||
$this->displayoptions['onclick'] = htmlspecialchars_decode($mod->onclick, ENT_QUOTES);;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -333,7 +326,7 @@ class cm implements named_templatable, renderable {
|
||||
* @return string the activity link classes.
|
||||
*/
|
||||
public function get_link_classes(): string {
|
||||
return $this->linkclasses;
|
||||
return $this->displayoptions['linkclasses'] ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
@ -342,6 +335,15 @@ class cm implements named_templatable, renderable {
|
||||
* @return string the activity text classes.
|
||||
*/
|
||||
public function get_text_classes(): string {
|
||||
return $this->textclasses;
|
||||
return $this->displayoptions['textclasses'] ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the activity onclick code.
|
||||
*
|
||||
* @return string the activity onclick.
|
||||
*/
|
||||
public function get_onclick_code(): string {
|
||||
return $this->displayoptions['onclick'];
|
||||
}
|
||||
}
|
||||
|
@ -25,13 +25,9 @@
|
||||
namespace core_courseformat\output\local\content\cm;
|
||||
|
||||
use cm_info;
|
||||
use context_module;
|
||||
use core\output\inplace_editable;
|
||||
use core\output\named_templatable;
|
||||
use core_courseformat\base as course_format;
|
||||
use core_courseformat\output\local\courseformat_named_templatable;
|
||||
use external_api;
|
||||
use lang_string;
|
||||
use renderable;
|
||||
use section_info;
|
||||
use stdClass;
|
||||
@ -43,7 +39,7 @@ use stdClass;
|
||||
* @copyright 2020 Ferran Recio <ferran@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class cmname extends inplace_editable implements named_templatable, renderable {
|
||||
class cmname implements named_templatable, renderable {
|
||||
|
||||
use courseformat_named_templatable;
|
||||
|
||||
@ -56,9 +52,6 @@ class cmname extends inplace_editable implements named_templatable, renderable {
|
||||
/** @var cm_info the course module instance */
|
||||
protected $mod;
|
||||
|
||||
/** @var editable if the title is editable */
|
||||
protected $editable;
|
||||
|
||||
/** @var array optional display options */
|
||||
protected $displayoptions;
|
||||
|
||||
@ -71,14 +64,14 @@ class cmname extends inplace_editable implements named_templatable, renderable {
|
||||
* @param course_format $format the course format
|
||||
* @param section_info $section the section info
|
||||
* @param cm_info $mod the course module ionfo
|
||||
* @param bool $editable if it is editable
|
||||
* @param bool|null $editable if it is editable (not used)
|
||||
* @param array $displayoptions optional extra display options
|
||||
*/
|
||||
public function __construct(
|
||||
course_format $format,
|
||||
section_info $section,
|
||||
cm_info $mod,
|
||||
bool $editable,
|
||||
?bool $editable = null,
|
||||
array $displayoptions = []
|
||||
) {
|
||||
$this->format = $format;
|
||||
@ -86,25 +79,8 @@ class cmname extends inplace_editable implements named_templatable, renderable {
|
||||
$this->mod = $mod;
|
||||
$this->displayoptions = $displayoptions;
|
||||
|
||||
$this->editable = $editable && has_capability(
|
||||
'moodle/course:manageactivities',
|
||||
$mod->context
|
||||
);
|
||||
|
||||
// Get the necessary classes.
|
||||
$this->titleclass = $format->get_output_classname('content\\cm\\title');
|
||||
|
||||
// Setup inplace editable.
|
||||
parent::__construct(
|
||||
'core_course',
|
||||
'activityname',
|
||||
$mod->id,
|
||||
$this->editable,
|
||||
$mod->name,
|
||||
$mod->name,
|
||||
new lang_string('edittitle'),
|
||||
new lang_string('newactivityname', '', $mod->get_formatted_name())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -114,51 +90,49 @@ class cmname extends inplace_editable implements named_templatable, renderable {
|
||||
* @return stdClass data context for a mustache template
|
||||
*/
|
||||
public function export_for_template(\renderer_base $output): array {
|
||||
global $PAGE;
|
||||
$mod = $this->mod;
|
||||
$displayoptions = $this->displayoptions;
|
||||
|
||||
// Inplace editable uses core renderer by default. However, course elements require
|
||||
// the format specific renderer.
|
||||
$courseoutput = $this->format->get_renderer($PAGE);
|
||||
if (!$this->has_name()) {
|
||||
// Nothing to be displayed to the user.
|
||||
return [];
|
||||
}
|
||||
|
||||
// Inplace editable uses pre-rendered elements and does not allow line beaks in the UI value.
|
||||
$data = [
|
||||
'url' => $mod->url,
|
||||
'icon' => $mod->get_icon_url(),
|
||||
'modname' => $mod->modname,
|
||||
'pluginname' => get_string('pluginname', 'mod_' . $mod->modname),
|
||||
'textclasses' => $displayoptions['textclasses'] ?? '',
|
||||
'purpose' => plugin_supports('mod', $mod->modname, FEATURE_MOD_PURPOSE, MOD_PURPOSE_OTHER),
|
||||
'activityname' => $this->get_title_data($output),
|
||||
];
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the title data.
|
||||
*
|
||||
* @param \renderer_base $output typically, the renderer that's calling this function
|
||||
* @return array data context for a mustache template
|
||||
*/
|
||||
protected function get_title_data(\renderer_base $output): array {
|
||||
$title = new $this->titleclass(
|
||||
$this->format,
|
||||
$this->section,
|
||||
$this->mod,
|
||||
$this->displayoptions
|
||||
);
|
||||
$this->displayvalue = str_replace("\n", "", $courseoutput->render($title));
|
||||
|
||||
if (trim($this->displayvalue) == '') {
|
||||
$this->editable = false;
|
||||
}
|
||||
$data = parent::export_for_template($output);
|
||||
|
||||
return $data;
|
||||
return (array) $title->export_for_template($output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates course module name
|
||||
* Return if the activity has a visible name.
|
||||
*
|
||||
* @param int $itemid course module id
|
||||
* @param string $newvalue new name
|
||||
* @return static
|
||||
* @return bool if the title is visible.
|
||||
*/
|
||||
public static function update($itemid, $newvalue) {
|
||||
$context = context_module::instance($itemid);
|
||||
// Check access.
|
||||
external_api::validate_context($context);
|
||||
require_capability('moodle/course:manageactivities', $context);
|
||||
|
||||
// Trim module name and Update value.
|
||||
set_coursemodule_name($itemid, trim($newvalue));
|
||||
$coursemodulerecord = get_coursemodule_from_id('', $itemid, 0, false, MUST_EXIST);
|
||||
// Return instance.
|
||||
$modinfo = get_fast_modinfo($coursemodulerecord->course);
|
||||
$cm = $modinfo->get_cm($itemid);
|
||||
$section = $modinfo->get_section_info($cm->sectionnum);
|
||||
|
||||
$format = course_get_format($cm->course);
|
||||
return new static($format, $section, $cm, true);
|
||||
public function has_name(): bool {
|
||||
return $this->mod->is_visible_on_course_page() && $this->mod->url;
|
||||
}
|
||||
}
|
||||
|
@ -27,13 +27,16 @@
|
||||
namespace core_courseformat\output\local\content\cm;
|
||||
|
||||
use cm_info;
|
||||
use core\output\inplace_editable;
|
||||
use core\output\named_templatable;
|
||||
use core_courseformat\base as course_format;
|
||||
use core_courseformat\output\local\courseformat_named_templatable;
|
||||
use core_text;
|
||||
use lang_string;
|
||||
use renderable;
|
||||
use section_info;
|
||||
use stdClass;
|
||||
use external_api;
|
||||
use context_module;
|
||||
|
||||
/**
|
||||
* Base class to render a course module title inside a course format.
|
||||
@ -42,9 +45,7 @@ use stdClass;
|
||||
* @copyright 2020 Ferran Recio <ferran@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class title implements named_templatable, renderable {
|
||||
|
||||
use courseformat_named_templatable;
|
||||
class title extends inplace_editable implements named_templatable, renderable {
|
||||
|
||||
/** @var course_format the course format */
|
||||
protected $format;
|
||||
@ -58,6 +59,12 @@ class title implements named_templatable, renderable {
|
||||
/** @var array optional display options */
|
||||
protected $displayoptions;
|
||||
|
||||
/** @var editable if the title is editable */
|
||||
protected $editable;
|
||||
|
||||
/** @var displaytemplate the default display template */
|
||||
protected $displaytemplate = 'core_courseformat/local/content/cm/title';
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
@ -65,12 +72,52 @@ class title implements named_templatable, renderable {
|
||||
* @param section_info $section the section info
|
||||
* @param cm_info $mod the course module ionfo
|
||||
* @param array $displayoptions optional extra display options
|
||||
* @param bool|null $editable force editable value
|
||||
*/
|
||||
public function __construct(course_format $format, section_info $section, cm_info $mod, array $displayoptions = []) {
|
||||
public function __construct(
|
||||
course_format $format,
|
||||
section_info $section,
|
||||
cm_info $mod,
|
||||
array $displayoptions = [],
|
||||
?bool $editable = null
|
||||
) {
|
||||
$this->format = $format;
|
||||
$this->section = $section;
|
||||
$this->mod = $mod;
|
||||
$this->displayoptions = $displayoptions;
|
||||
|
||||
// Usually displayoptions are loaded in the main cm output. However when the user uses the inplace editor
|
||||
// the cmname output does not calculate the css classes.
|
||||
$this->displayoptions = $this->load_display_options($displayoptions);
|
||||
|
||||
if ($editable === null) {
|
||||
$editable = $format->show_editor() && has_capability(
|
||||
'moodle/course:manageactivities',
|
||||
$mod->context
|
||||
);
|
||||
}
|
||||
$this->editable = $editable;
|
||||
|
||||
// Setup inplace editable.
|
||||
parent::__construct(
|
||||
'core_course',
|
||||
'activityname',
|
||||
$mod->id,
|
||||
$this->editable,
|
||||
$mod->name,
|
||||
$mod->name,
|
||||
new lang_string('edittitle'),
|
||||
new lang_string('newactivityname', '', $mod->get_formatted_name())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the template to use for this templatable.
|
||||
*
|
||||
* @param \renderer_base $renderer The renderer requesting the template name
|
||||
* @return string
|
||||
*/
|
||||
public function get_template_name(\renderer_base $renderer): string {
|
||||
return 'core/inplace_editable';
|
||||
}
|
||||
|
||||
/**
|
||||
@ -79,41 +126,35 @@ class title implements named_templatable, renderable {
|
||||
* @param \renderer_base $output typically, the renderer that's calling this function
|
||||
* @return stdClass data context for a mustache template
|
||||
*/
|
||||
public function export_for_template(\renderer_base $output): stdClass {
|
||||
public function export_for_template(\renderer_base $output): array {
|
||||
|
||||
// Inplace editable uses pre-rendered elements and does not allow line beaks in the UI value.
|
||||
$this->displayvalue = str_replace("\n", "", $this->get_title_displayvalue());
|
||||
|
||||
if (trim($this->displayvalue) == '') {
|
||||
$this->editable = false;
|
||||
}
|
||||
return parent::export_for_template($output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the title template data to be used inside the inplace editable.
|
||||
*
|
||||
*/
|
||||
protected function get_title_displayvalue (): string {
|
||||
global $PAGE;
|
||||
|
||||
// Inplace editable uses core renderer by default. However, course elements require
|
||||
// the format specific renderer.
|
||||
$courseoutput = $this->format->get_renderer($PAGE);
|
||||
|
||||
$format = $this->format;
|
||||
$mod = $this->mod;
|
||||
$displayoptions = $this->displayoptions;
|
||||
|
||||
if (!$mod->is_visible_on_course_page() || !$mod->url) {
|
||||
// Nothing to be displayed to the user.
|
||||
return new stdClass();
|
||||
}
|
||||
|
||||
// Usually classes are loaded in the main cm output. However when the user uses the inplace editor
|
||||
// the cmname output does not calculate the css classes.
|
||||
if (!isset($displayoptions['linkclasses']) || !isset($displayoptions['textclasses'])) {
|
||||
$cmclass = $format->get_output_classname('content\\cm');
|
||||
$cmoutput = new $cmclass(
|
||||
$format,
|
||||
$this->section,
|
||||
$mod,
|
||||
$displayoptions
|
||||
);
|
||||
$displayoptions['linkclasses'] = $cmoutput->get_link_classes();
|
||||
$displayoptions['textclasses'] = $cmoutput->get_text_classes();
|
||||
}
|
||||
|
||||
$data = (object)[
|
||||
'url' => $mod->url,
|
||||
'instancename' => $mod->get_formatted_name(),
|
||||
'uservisible' => $mod->uservisible,
|
||||
'icon' => $mod->get_icon_url(),
|
||||
'modname' => $mod->modname,
|
||||
'pluginname' => get_string('pluginname', 'mod_' . $mod->modname),
|
||||
'linkclasses' => $displayoptions['linkclasses'],
|
||||
'textclasses' => $displayoptions['textclasses'],
|
||||
'purpose' => plugin_supports('mod', $mod->modname, FEATURE_MOD_PURPOSE, MOD_PURPOSE_OTHER),
|
||||
'linkclasses' => $this->displayoptions['linkclasses'],
|
||||
];
|
||||
|
||||
// File type after name, for alphabetic lists (screen reader).
|
||||
@ -128,6 +169,71 @@ class title implements named_templatable, renderable {
|
||||
// has already been encoded for display (puke).
|
||||
$data->onclick = htmlspecialchars_decode($mod->onclick, ENT_QUOTES);
|
||||
|
||||
return $data;
|
||||
return $courseoutput->render_from_template(
|
||||
$this->displaytemplate,
|
||||
$data
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the required display options if not present already.
|
||||
*
|
||||
* In most cases, display options are provided as a param when creating the
|
||||
* object. However, inplace_editable and some blocks does not know all of them as it is
|
||||
* called in a webservice and we need to ensure it is calculated.
|
||||
*
|
||||
* @param array $displayoptions the provided dispaly options
|
||||
* @return array the full display options list
|
||||
*/
|
||||
protected function load_display_options(array $displayoptions): array {
|
||||
$format = $this->format;
|
||||
$mod = $this->mod;
|
||||
|
||||
if (
|
||||
isset($displayoptions['linkclasses']) &&
|
||||
isset($displayoptions['textclasses']) &&
|
||||
isset($displayoptions['onclick'])
|
||||
) {
|
||||
return $displayoptions;
|
||||
}
|
||||
|
||||
$cmclass = $format->get_output_classname('content\\cm');
|
||||
$cmoutput = new $cmclass(
|
||||
$format,
|
||||
$this->section,
|
||||
$mod,
|
||||
$displayoptions
|
||||
);
|
||||
$displayoptions['linkclasses'] = $cmoutput->get_link_classes();
|
||||
$displayoptions['textclasses'] = $cmoutput->get_text_classes();
|
||||
$displayoptions['onclick'] = $cmoutput->get_onclick_code();
|
||||
return $displayoptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates course module name.
|
||||
*
|
||||
* This method is used mainly by inplace_editable webservice.
|
||||
*
|
||||
* @param int $itemid course module id
|
||||
* @param string $newvalue new name
|
||||
* @return static
|
||||
*/
|
||||
public static function update($itemid, $newvalue) {
|
||||
$context = context_module::instance($itemid);
|
||||
// Check access.
|
||||
external_api::validate_context($context);
|
||||
require_capability('moodle/course:manageactivities', $context);
|
||||
|
||||
// Trim module name and Update value.
|
||||
set_coursemodule_name($itemid, trim($newvalue));
|
||||
$coursemodulerecord = get_coursemodule_from_id('', $itemid, 0, false, MUST_EXIST);
|
||||
// Return instance.
|
||||
$modinfo = get_fast_modinfo($coursemodulerecord->course);
|
||||
$cm = $modinfo->get_cm($itemid);
|
||||
$section = $modinfo->get_section_info($cm->sectionnum);
|
||||
|
||||
$format = course_get_format($cm->course);
|
||||
return new static($format, $section, $cm, [], true);
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,7 @@
|
||||
}
|
||||
}}
|
||||
{{#showaddsection}}
|
||||
<div id="changenumsections" class="mdl-left py-2">
|
||||
<div class="mdl-left py-2 changenumsections">
|
||||
{{#increase}}
|
||||
<a href="{{{url}}}" class="increase-sections">
|
||||
{{#pix}}t/switch_plus, moodle, {{#str}} increasesections, moodle {{/str}}{{/pix}}
|
||||
|
@ -65,9 +65,9 @@
|
||||
{{/ core_courseformat/local/content/cm/badges }}
|
||||
{{/hasname}}
|
||||
{{#cmname}}
|
||||
{{$ core/inplace_editable }}
|
||||
{{> core/inplace_editable }}
|
||||
{{/ core/inplace_editable }}
|
||||
{{$ core_courseformat/local/content/cm/cmname }}
|
||||
{{> core_courseformat/local/content/cm/cmname }}
|
||||
{{/ core_courseformat/local/content/cm/cmname }}
|
||||
{{/cmname}}
|
||||
{{#afterlink}}
|
||||
<div class="afterlink">
|
||||
|
@ -23,18 +23,44 @@
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"displayvalue" : "<a href=\"#\">Moodle</a>",
|
||||
"value" : "Moodle",
|
||||
"itemid" : "1",
|
||||
"component" : "core_unknown",
|
||||
"itemtype" : "unknown",
|
||||
"edithint" : "Edit this",
|
||||
"editlabel" : "New name for this",
|
||||
"type" : "text",
|
||||
"options" : "",
|
||||
"linkeverything": 0
|
||||
"url": "#",
|
||||
"icon": "../../../pix/help.svg",
|
||||
"pluginname": "File",
|
||||
"textclasses": "",
|
||||
"purpose": "content",
|
||||
"modname": "resource",
|
||||
"activityname": {
|
||||
"displayvalue" : "<a href=\"#\">Moodle</a>",
|
||||
"value" : "Moodle",
|
||||
"itemid" : "1",
|
||||
"component" : "core_unknown",
|
||||
"itemtype" : "unknown",
|
||||
"edithint" : "Edit this",
|
||||
"editlabel" : "New name for this",
|
||||
"type" : "text",
|
||||
"options" : "",
|
||||
"linkeverything": 0
|
||||
}
|
||||
}
|
||||
}}
|
||||
{{$ core/inplace_editable }}
|
||||
{{> core/inplace_editable }}
|
||||
{{/ core/inplace_editable }}
|
||||
{{#url}}
|
||||
<div class="activity-instance d-flex flex-column">
|
||||
<div class="activitytitle media {{textclasses}} modtype_{{modname}} position-relative align-self-start">
|
||||
<div class="activityiconcontainer {{purpose}} courseicon align-self-start mr-3">
|
||||
<img src="{{{icon}}}" class="activityicon " alt="{{{modname}}} icon">
|
||||
</div>
|
||||
<div class="media-body align-self-center">
|
||||
<div class="text-uppercase small">
|
||||
{{{pluginname}}}
|
||||
</div>
|
||||
<div class="activityname">
|
||||
{{#activityname}}
|
||||
{{$ core/inplace_editable }}
|
||||
{{> core/inplace_editable }}
|
||||
{{/ core/inplace_editable }}
|
||||
{{/activityname}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/url}}
|
||||
|
@ -24,39 +24,19 @@
|
||||
"url": "#",
|
||||
"instancename": "Activity name",
|
||||
"uservisible": true,
|
||||
"icon": "../../../pix/help.svg",
|
||||
"onclick": "alert('ok')",
|
||||
"pluginname": "File",
|
||||
"altname": "PDF file",
|
||||
"linkclasses": "",
|
||||
"textclasses": "",
|
||||
"purpose": "content",
|
||||
"modname": "resource"
|
||||
}
|
||||
}}
|
||||
{{#url}}
|
||||
<div class="activity-instance d-flex flex-column">
|
||||
<div class="activitytitle media {{textclasses}} modtype_{{modname}} position-relative align-self-start">
|
||||
<div class="activityiconcontainer {{purpose}} courseicon align-self-start mr-3">
|
||||
<img src="{{{icon}}}" class="activityicon " alt="{{{modname}}} icon">
|
||||
</div>
|
||||
<div class="media-body align-self-center">
|
||||
<div class="text-uppercase small">
|
||||
{{{pluginname}}}
|
||||
</div>
|
||||
<div class="activityname">
|
||||
{{#uservisible}}
|
||||
<a href="{{url}}" class="{{linkclasses}} aalink stretched-link" onclick="{{{onclick}}}">
|
||||
<span class="instancename">{{{instancename}}} {{{altname}}}</span>
|
||||
</a>
|
||||
{{/uservisible}}
|
||||
{{^uservisible}}
|
||||
<span class="instancename">
|
||||
{{{instancename}}} {{{altname}}}
|
||||
</span>
|
||||
{{/uservisible}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/url}}
|
||||
{{#uservisible}}
|
||||
<a href="{{url}}" class="{{linkclasses}} aalink stretched-link" onclick="{{{onclick}}}">
|
||||
<span class="instancename">{{{instancename}}} {{{altname}}}</span>
|
||||
</a>
|
||||
{{/uservisible}}
|
||||
{{^uservisible}}
|
||||
<span class="instancename">
|
||||
{{{instancename}}} {{{altname}}}
|
||||
</span>
|
||||
{{/uservisible}}
|
||||
|
@ -3663,7 +3663,7 @@ function course_get_tagged_courses($tag, $exclusivemode = false, $fromctx = 0, $
|
||||
*/
|
||||
function core_course_inplace_editable($itemtype, $itemid, $newvalue) {
|
||||
if ($itemtype === 'activityname') {
|
||||
return \core_courseformat\output\local\content\cm\cmname::update($itemid, $newvalue);
|
||||
return \core_courseformat\output\local\content\cm\title::update($itemid, $newvalue);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -606,14 +606,12 @@ class core_course_renderer extends plugin_renderer_base {
|
||||
$format,
|
||||
$mod->get_section_info(),
|
||||
$mod,
|
||||
$this->page->user_is_editing(),
|
||||
null,
|
||||
$displayoptions
|
||||
);
|
||||
|
||||
$data = $cmname->export_for_template($this->output);
|
||||
|
||||
return $this->output->render_from_template('core/inplace_editable', $data) .
|
||||
$groupinglabel;
|
||||
$renderer = $format->get_renderer($this->page);
|
||||
return $renderer->render($cmname) . $groupinglabel;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4,6 +4,11 @@ information provided here is intended especially for developers.
|
||||
=== 4.1 ===
|
||||
* The function course_modchooser() has been finally deprecated and can not be used anymore. Please use
|
||||
course_activitychooser() instead.
|
||||
* A critical accessibility issue is been found (MDL-74800) at the output class
|
||||
core_courseformat\output\local\content\cm\cmname. To solve the problem this output element is not
|
||||
rendered anymore using inplace_editable but using a regular named_templatable interface.
|
||||
Some format plugins that override the deprecated renderer method course_section_cm_name can be affected.
|
||||
Check the current course_section_cm_name code to see how to render it properly.
|
||||
|
||||
=== 4.0 ===
|
||||
* All activity icons have been replaced with black monochrome icons. The background
|
||||
|
@ -108,6 +108,7 @@ class behat_partial_named_selector extends \Behat\Mink\Selector\PartialNamedSele
|
||||
'link' => 'link',
|
||||
'link_or_button' => 'link_or_button',
|
||||
'list_item' => 'list_item',
|
||||
'menuitem' => 'menuitem',
|
||||
'optgroup' => 'optgroup',
|
||||
'option' => 'option',
|
||||
'question' => 'question',
|
||||
@ -201,6 +202,9 @@ XPATH
|
||||
XPATH
|
||||
, 'list_item' => <<<XPATH
|
||||
.//li[contains(normalize-space(.), %locator%) and not(.//li[contains(normalize-space(.), %locator%)])]
|
||||
XPATH
|
||||
, 'menuitem' => <<<XPATH
|
||||
.//*[@role='menuitem'][%titleMatch% or %ariaLabelMatch% or text()[contains(., %locator%)]]
|
||||
XPATH
|
||||
, 'question' => <<<XPATH
|
||||
.//div[contains(concat(' ', normalize-space(@class), ' '), ' que ')]
|
||||
|
@ -4577,6 +4577,12 @@ class action_menu implements renderable, templatable {
|
||||
*/
|
||||
public function export_for_template(renderer_base $output) {
|
||||
$data = new stdClass();
|
||||
// Assign a role of menubar to this action menu when:
|
||||
// - it contains 2 or more primary actions; or
|
||||
// - if it contains a primary action and secondary actions.
|
||||
if (count($this->primaryactions) > 1 || (!empty($this->primaryactions) && !empty($this->secondaryactions))) {
|
||||
$this->attributes['role'] = 'menubar';
|
||||
}
|
||||
$attributes = $this->attributes;
|
||||
$attributesprimary = $this->attributesprimary;
|
||||
$attributessecondary = $this->attributessecondary;
|
||||
@ -4617,6 +4623,12 @@ class action_menu implements renderable, templatable {
|
||||
$actionicon = new pix_icon('t/edit_menu', '', 'moodle', $iconattributes);
|
||||
}
|
||||
|
||||
// If the menu trigger is within the menubar, assign a role of menuitem. Otherwise, assign as a button.
|
||||
$primary->triggerrole = 'button';
|
||||
if (isset($attributes['role']) && $attributes['role'] === 'menubar') {
|
||||
$primary->triggerrole = 'menuitem';
|
||||
}
|
||||
|
||||
if ($actionicon instanceof pix_icon) {
|
||||
$primary->icon = $actionicon->export_for_pix();
|
||||
if (!empty($actionicon->attributes['alt'])) {
|
||||
|
@ -22,11 +22,19 @@
|
||||
Example context (json):
|
||||
{
|
||||
"classes": "",
|
||||
"instance": "1",
|
||||
"primary": {
|
||||
"items": [{"rawhtml": "<p>Item in primary menu</p>"}]
|
||||
},
|
||||
"secondary": {
|
||||
"items": [{"rawhtml": "<p>Item in secondary menu</p>"}]
|
||||
"attributes": [
|
||||
{"name": "id", "value": "action-menu-1-menu"}
|
||||
],
|
||||
"items": [
|
||||
{
|
||||
"rawhtml": "<p>Item in secondary menu</p>"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}}
|
||||
|
@ -79,7 +79,7 @@
|
||||
}
|
||||
}}
|
||||
<div class="dropdown{{^secondary.items}} hidden{{/secondary.items}}">
|
||||
<a href="#" tabindex="0" class="{{triggerextraclasses}} dropdown-toggle icon-no-margin" id="action-menu-toggle-{{instance}}" aria-label="{{title}}" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false" aria-controls="action-menu-{{instance}}-menu">
|
||||
<a href="#" tabindex="0" class="{{triggerextraclasses}} dropdown-toggle icon-no-margin" id="action-menu-toggle-{{instance}}" aria-label="{{title}}" data-toggle="dropdown" role="{{triggerrole}}" aria-haspopup="true" aria-expanded="false" aria-controls="action-menu-{{instance}}-menu">
|
||||
{{{actiontext}}}
|
||||
{{{menutrigger}}}
|
||||
{{#icon}}
|
||||
|
@ -27,7 +27,8 @@
|
||||
"edit": 1,
|
||||
"adminedit": true,
|
||||
"checked": "",
|
||||
"string": "Edit on"
|
||||
"string": "Edit on",
|
||||
"legacyseturl": "/editmode.php"
|
||||
}
|
||||
}}
|
||||
<div class="divider border-left h-75 align-self-center ml-1 mr-3"></div>
|
||||
@ -40,10 +41,7 @@
|
||||
<input type="checkbox"{{!
|
||||
}} name="setmode"{{!
|
||||
}}{{#checked}}{{!
|
||||
}} aria-checked="true" checked{{!
|
||||
}}{{/checked}}{{!
|
||||
}}{{^checked}}{{!
|
||||
}} aria-checked="false"{{!
|
||||
}} checked{{!
|
||||
}}{{/checked}}{{!
|
||||
}} class="custom-control-input"{{!
|
||||
}} id="{{uniqid}}-editingswitch"{{!
|
||||
|
@ -50,7 +50,12 @@ class behat_action_menu extends behat_base {
|
||||
*/
|
||||
public function i_open_the_action_menu_in($element, $selectortype) {
|
||||
// Gets the node based on the requested selector type and locator.
|
||||
$node = $this->get_node_in_container("css_element", "[role=button][aria-haspopup=true]", $selectortype, $element);
|
||||
$node = $this->get_node_in_container(
|
||||
"css_element",
|
||||
"[role=button][aria-haspopup=true],[role=menuitem][aria-haspopup=true]",
|
||||
$selectortype,
|
||||
$element
|
||||
);
|
||||
|
||||
// Check if it is not already opened.
|
||||
if ($node->getAttribute('aria-expanded') === 'true') {
|
||||
|
@ -933,6 +933,9 @@ BLOCKREGION.prototype = {
|
||||
this.get('node').all('.' + CSS.BLOCK + ' a.' + CSS.EDITINGMOVE).each(function(moveicon) {
|
||||
moveicon.setStyle('cursor', 'move');
|
||||
handle = manager.get_drag_handle(moveicon.getAttribute('title'), '', 'icon', true);
|
||||
// Dragdrop module assigns this with a button role by default.
|
||||
// However, the block move icon is part of a menubar, so it should have a menuitem role.
|
||||
handle.setAttribute('role', 'menuitem');
|
||||
moveicon.replace(handle);
|
||||
});
|
||||
},
|
||||
|
File diff suppressed because one or more lines are too long
@ -926,6 +926,9 @@ BLOCKREGION.prototype = {
|
||||
this.get('node').all('.' + CSS.BLOCK + ' a.' + CSS.EDITINGMOVE).each(function(moveicon) {
|
||||
moveicon.setStyle('cursor', 'move');
|
||||
handle = manager.get_drag_handle(moveicon.getAttribute('title'), '', 'icon', true);
|
||||
// Dragdrop module assigns this with a button role by default.
|
||||
// However, the block move icon is part of a menubar, so it should have a menuitem role.
|
||||
handle.setAttribute('role', 'menuitem');
|
||||
moveicon.replace(handle);
|
||||
});
|
||||
},
|
||||
|
3
lib/yui/src/blocks/js/blockregion.js
vendored
3
lib/yui/src/blocks/js/blockregion.js
vendored
@ -100,6 +100,9 @@ BLOCKREGION.prototype = {
|
||||
this.get('node').all('.' + CSS.BLOCK + ' a.' + CSS.EDITINGMOVE).each(function(moveicon) {
|
||||
moveicon.setStyle('cursor', 'move');
|
||||
handle = manager.get_drag_handle(moveicon.getAttribute('title'), '', 'icon', true);
|
||||
// Dragdrop module assigns this with a button role by default.
|
||||
// However, the block move icon is part of a menubar, so it should have a menuitem role.
|
||||
handle.setAttribute('role', 'menuitem');
|
||||
moveicon.replace(handle);
|
||||
});
|
||||
},
|
||||
|
@ -42,11 +42,19 @@
|
||||
{{$classes}}popover-region-notifications{{/classes}}
|
||||
{{$attributes}}id="nav-notification-popover-container" data-userid="{{userid}}"{{/attributes}}
|
||||
|
||||
{{$togglelabel}}{{#str}} shownotificationwindownonew, message {{/str}}{{/togglelabel}}
|
||||
{{$togglelabel}}{{!
|
||||
}}{{^unreadcount}} {{#str}} shownotificationwindownonew, message {{/str}} {{/unreadcount}} {{!
|
||||
}}{{#unreadcount}} {{#str}} shownotificationwindowwithcount, message, {{.}} {{/str}} {{/unreadcount}} {{!
|
||||
}}{{/togglelabel}}
|
||||
{{$togglecontent}}
|
||||
{{#pix}} i/notifications, core, {{#str}} togglenotificationmenu, message {{/str}} {{/pix}}
|
||||
<div class="count-container {{^unreadcount}}hidden{{/unreadcount}}" data-region="count-container"
|
||||
aria-label="{{#str}} unreadnotifications, core_message, {{unreadcount}} {{/str}}">{{unreadcount}}</div>
|
||||
<div
|
||||
class="count-container {{^unreadcount}}hidden{{/unreadcount}}"
|
||||
data-region="count-container"
|
||||
aria-hidden=true
|
||||
>
|
||||
{{unreadcount}}
|
||||
</div>
|
||||
{{/togglecontent}}
|
||||
|
||||
{{$containerlabel}}{{#str}} notificationwindow, message {{/str}}{{/containerlabel}}
|
||||
@ -81,9 +89,9 @@
|
||||
{{/content}}
|
||||
{{/ core/popover_region }}
|
||||
{{#js}}
|
||||
require(['jquery', 'message_popup/notification_popover_controller'], function($, controller) {
|
||||
require(['jquery', 'message_popup/notification_popover_controller'], function($, Controller) {
|
||||
var container = $('#nav-notification-popover-container');
|
||||
var controller = new controller(container);
|
||||
var controller = new Controller(container);
|
||||
controller.registerEventListeners();
|
||||
controller.registerListNavigationEventListeners();
|
||||
});
|
||||
|
@ -100,9 +100,9 @@
|
||||
<span
|
||||
class="badge badge-pill badge-primary {{^unreadcount}}hidden{{/unreadcount}}"
|
||||
data-region="unread-count"
|
||||
aria-label="{{#str}} unreadmessages, core_message, {{unreadcount}} {{/str}}"
|
||||
>
|
||||
{{unreadcount}}
|
||||
<span aria-hidden="true">{{unreadcount}}</span>
|
||||
<span class="sr-only">{{#str}} unreadmessages, core_message, {{unreadcount}} {{/str}}</span>
|
||||
</span>
|
||||
|
||||
<div class="text-muted ml-auto">
|
||||
|
@ -65,9 +65,10 @@
|
||||
>
|
||||
{{#str}} requests {{/str}}
|
||||
<span class="badge badge-primary bg-primary ml-2 {{^contactrequestcount}}hidden{{/contactrequestcount}}"
|
||||
data-region="contact-request-count"
|
||||
aria-label="{{#str}} pendingcontactrequests, core_message, {{contactrequestcount}} {{/str}}">
|
||||
{{contactrequestcount}}
|
||||
data-region="contact-request-count"
|
||||
>
|
||||
<span aria-hidden="true">{{contactrequestcount}}</span>
|
||||
<span class="sr-only">{{#str}} pendingcontactrequests, core_message, {{contactrequestcount}} {{/str}}</span>
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
@ -95,4 +96,4 @@
|
||||
{{/ core_message/message_drawer_view_contacts_body_section_requests }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -59,13 +59,17 @@
|
||||
<div class="w-100 text-truncate ml-2">
|
||||
<div class="d-flex">
|
||||
<strong class="m-0 text-truncate">{{name}}</strong>
|
||||
<span class="{{^isfavourite}}hidden{{/isfavourite}} ml-1 text-primary" data-region="favourite-icon-container"
|
||||
aria-label="{{#str}} favourites, core {{/str}}">
|
||||
{{#pix}} i/star-rating, core {{/pix}}
|
||||
<span
|
||||
class="{{^isfavourite}}hidden{{/isfavourite}} ml-1 text-primary"
|
||||
data-region="favourite-icon-container"
|
||||
>
|
||||
{{#pix}} i/star-rating, core, {{#str}} favourites, core {{/str}} {{/pix}}
|
||||
</span>
|
||||
<span class="{{^ismuted}}hidden{{/ismuted}} ml-1 text-primary" data-region="muted-icon-container"
|
||||
aria-label="{{#str}} mutedconversation, core_message {{/str}}">
|
||||
{{#pix}} i/muted, core {{/pix}}
|
||||
<span
|
||||
class="{{^ismuted}}hidden{{/ismuted}} ml-1 text-primary"
|
||||
data-region="muted-icon-container"
|
||||
>
|
||||
{{#pix}} i/muted, core, {{#str}} mutedconversation, core_message {{/str}} {{/pix}}
|
||||
</span>
|
||||
</div>
|
||||
{{#showonlinestatus}}
|
||||
|
@ -58,13 +58,17 @@
|
||||
<div class="w-100 text-truncate ml-2">
|
||||
<div class="d-flex">
|
||||
<strong class="m-0 text-truncate">{{name}}</strong>
|
||||
<span class="{{^isfavourite}}hidden{{/isfavourite}} ml-1 text-primary" data-region="favourite-icon-container"
|
||||
aria-label="{{#str}} favourites, core {{/str}}">
|
||||
{{#pix}} i/star-rating, core {{/pix}}
|
||||
<span
|
||||
class="{{^isfavourite}}hidden{{/isfavourite}} ml-1 text-primary"
|
||||
data-region="favourite-icon-container"
|
||||
>
|
||||
{{#pix}} i/star-rating, core, {{#str}} favourites, core {{/str}} {{/pix}}
|
||||
</span>
|
||||
<span class="{{^ismuted}}hidden{{/ismuted}} ml-1 text-primary" data-region="muted-icon-container"
|
||||
aria-label="{{#str}} mutedconversation, core_message {{/str}}">
|
||||
{{#pix}} i/muted, core {{/pix}}
|
||||
<span
|
||||
class="{{^ismuted}}hidden{{/ismuted}} ml-1 text-primary"
|
||||
data-region="muted-icon-container"
|
||||
>
|
||||
{{#pix}} i/muted, core, {{#str}} mutedconversation, core_message {{/str}} {{/pix}}
|
||||
</span>
|
||||
</div>
|
||||
{{#showonlinestatus}}
|
||||
@ -75,4 +79,4 @@
|
||||
{{/showonlinestatus}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -58,13 +58,17 @@
|
||||
<div class="w-100 text-truncate ml-2">
|
||||
<div class="d-flex">
|
||||
<strong class="m-0 text-truncate">{{name}}</strong>
|
||||
<span class="{{^isfavourite}}hidden{{/isfavourite}} ml-1 text-primary"
|
||||
data-region="favourite-icon-container" aria-label="{{#str}} favourites, core {{/str}}">
|
||||
{{#pix}} i/star-rating, core {{/pix}}
|
||||
<span
|
||||
class="{{^isfavourite}}hidden{{/isfavourite}} ml-1 text-primary"
|
||||
data-region="favourite-icon-container"
|
||||
>
|
||||
{{#pix}} i/star-rating, core, {{#str}} favourites, core {{/str}} {{/pix}}
|
||||
</span>
|
||||
<span class="{{^ismuted}}hidden{{/ismuted}} ml-1 text-primary" data-region="muted-icon-container"
|
||||
aria-label="{{#str}} mutedconversation, core_message {{/str}}">
|
||||
{{#pix}} i/muted, core {{/pix}}
|
||||
<span
|
||||
class="{{^ismuted}}hidden{{/ismuted}} ml-1 text-primary"
|
||||
data-region="muted-icon-container"
|
||||
>
|
||||
{{#pix}} i/muted, core, {{#str}} mutedconversation, core_message {{/str}} {{/pix}}
|
||||
</span>
|
||||
</div>
|
||||
<p class="m-0 text-truncate">{{subname}}</p>
|
||||
|
@ -67,10 +67,12 @@
|
||||
<a href="#" data-route="view-contacts" role="button">
|
||||
{{#pix}} i/user, core {{/pix}}
|
||||
{{#str}} contacts, core_message {{/str}}
|
||||
<span class="badge badge-primary bg-primary ml-2 {{^contactrequestcount}}hidden{{/contactrequestcount}}"
|
||||
data-region="contact-request-count"
|
||||
aria-label="{{#str}} pendingcontactrequests, core_message, {{contactrequestcount}} {{/str}}">
|
||||
{{contactrequestcount}}
|
||||
<span
|
||||
class="badge badge-primary bg-primary ml-2 {{^contactrequestcount}}hidden{{/contactrequestcount}}"
|
||||
data-region="contact-request-count"
|
||||
>
|
||||
<span aria-hidden="true">{{contactrequestcount}}</span>
|
||||
<span class="sr-only">{{#str}} pendingcontactrequests, core_message, {{contactrequestcount}} {{/str}}</span>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
|
@ -54,17 +54,19 @@
|
||||
{{#pix}} t/expanded, core {{/pix}}
|
||||
</span>
|
||||
<span class="font-weight-bold">{{$title}}{{/title}}</span>
|
||||
<small class="hidden ml-1" data-region="section-total-count-container"
|
||||
aria-label="{{#str}} totalconversations, core_message, {{count.total}} {{/str}}">
|
||||
(<span data-region="section-total-count">{{count.total}}</span>)
|
||||
<small class="hidden ml-1" data-region="section-total-count-container">
|
||||
(<span aria-hidden="true" data-region="section-total-count">{{count.total}}</span>{{!
|
||||
}}<span class="sr-only">{{#str}} totalconversations, core_message, {{count.total}} {{/str}}</span>)
|
||||
</small>
|
||||
<span class="hidden ml-2" data-region="loading-icon-container">
|
||||
{{> core/loading }}
|
||||
</span>
|
||||
<span class="{{^count.unread}}hidden{{/count.unread}} badge badge-pill badge-primary ml-auto bg-primary"
|
||||
data-region="section-unread-count"
|
||||
{{#count.unread}}aria-label="{{#str}} unreadconversations, core_message, {{count.unread}} {{/str}}"{{/count.unread}}>
|
||||
{{count.unread}}
|
||||
<span
|
||||
class="{{^count.unread}}hidden{{/count.unread}} badge badge-pill badge-primary ml-auto bg-primary"
|
||||
data-region="section-unread-count"
|
||||
>
|
||||
<span aria-hidden="true">{{count.unread}}</span>
|
||||
<span class="sr-only">{{#str}} unreadconversations, core_message, {{count.unread}} {{/str}}</span>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -39,8 +39,13 @@
|
||||
<a id="message-drawer-toggle-{{uniqid}}" class="nav-link popover-region-toggle position-relative icon-no-margin" href="#"
|
||||
role="button">
|
||||
{{#pix}} t/message, core, {{#str}} togglemessagemenu, message {{/str}} {{/pix}}
|
||||
<div class="count-container {{^unreadcount}}hidden{{/unreadcount}}" data-region="count-container"
|
||||
aria-label="{{#str}} unreadconversations, core_message, {{unreadcount}} {{/str}}">{{unreadcount}}</div>
|
||||
<div
|
||||
class="count-container {{^unreadcount}}hidden{{/unreadcount}}"
|
||||
data-region="count-container"
|
||||
>
|
||||
<span aria-hidden="true">{{unreadcount}}</span>
|
||||
<span class="sr-only">{{#str}} unreadconversations, core_message, {{unreadcount}} {{/str}}</span>
|
||||
</div>
|
||||
</a>
|
||||
{{> core_message/message_jumpto }}
|
||||
</div>
|
||||
|
@ -34,7 +34,7 @@ Feature: Star and unstar conversations
|
||||
And "Group 1" "core_message > Message" should exist
|
||||
And I select "Group 1" conversation in messaging
|
||||
And I open contact menu
|
||||
And I click on "Star" "link" in the "//div[@data-region='header-container']" "xpath_element"
|
||||
And I click on "Star conversation" "link" in the "conversation-actions-menu" "region"
|
||||
And I go back in "view-conversation" message drawer
|
||||
And I open the "Starred" conversations list
|
||||
And I should see "Group 1" in the "favourites" "core_message > Message list area"
|
||||
@ -48,13 +48,13 @@ Feature: Star and unstar conversations
|
||||
And "Group 1" "core_message > Message" should exist
|
||||
And I select "Group 1" conversation in messaging
|
||||
And I open contact menu
|
||||
And I click on "Star" "link" in the "//div[@data-region='header-container']" "xpath_element"
|
||||
And I click on "Star conversation" "link" in the "conversation-actions-menu" "region"
|
||||
And I go back in "view-conversation" message drawer
|
||||
And I open the "Starred" conversations list
|
||||
And I should see "Group 1" in the "favourites" "core_message > Message list area"
|
||||
And I select "Group 1" conversation in messaging
|
||||
And I open contact menu
|
||||
And I click on "Unstar" "link" in the "//div[@data-region='header-container']" "xpath_element"
|
||||
And I click on "Unstar" "link" in the "conversation-actions-menu" "region"
|
||||
And I go back in "view-conversation" message drawer
|
||||
And I open the "Starred" conversations list
|
||||
And I should not see "Group 1" in the "favourites" "core_message > Message list area"
|
||||
@ -71,7 +71,7 @@ Feature: Star and unstar conversations
|
||||
And "Student 2" "core_message > Message" should exist
|
||||
And I select "Student 2" conversation in messaging
|
||||
And I open contact menu
|
||||
And I click on "Star" "link" in the "//div[@data-region='header-container']" "xpath_element"
|
||||
And I click on "Star conversation" "link" in the "conversation-actions-menu" "region"
|
||||
And I go back in "view-conversation" message drawer
|
||||
And I open the "Starred" conversations list
|
||||
And I should see "Student 2" in the "favourites" "core_message > Message list area"
|
||||
@ -90,7 +90,7 @@ Feature: Star and unstar conversations
|
||||
And I should see "Student 2" in the "favourites" "core_message > Message list area"
|
||||
And I select "Student 2" conversation in messaging
|
||||
And I open contact menu
|
||||
And I click on "Unstar" "link" in the "//div[@data-region='header-container']" "xpath_element"
|
||||
And I click on "Unstar" "link" in the "conversation-actions-menu" "region"
|
||||
And I go back in "view-conversation" message drawer
|
||||
And I open the "Starred" conversations list
|
||||
And I should not see "Group 1" in the "favourites" "core_message > Message list area"
|
||||
|
@ -50,7 +50,7 @@ Feature: Message send messages
|
||||
Then "Group 1" "core_message > Message" should exist
|
||||
And I select "Group 1" conversation in the "group-messages" conversations list
|
||||
And I open contact menu
|
||||
And I click on "Star" "link" in the "//div[@data-region='header-container']" "xpath_element"
|
||||
And I click on "Star conversation" "link" in the "conversation-actions-menu" "region"
|
||||
And I go back in "view-conversation" message drawer
|
||||
And I open the "Starred" conversations list
|
||||
And I should see "Group 1"
|
||||
|
@ -38,7 +38,7 @@ Feature: Mute and unmute conversations
|
||||
And I select "Group 1" conversation in messaging
|
||||
And "muted" "icon_container" in the "Group 1" "core_message > Message header" should not be visible
|
||||
And I open contact menu
|
||||
And I click on "Mute" "link" in the "[data-region='header-container']" "css_element"
|
||||
And I click on "Mute" "link" in the "conversation-actions-menu" "region"
|
||||
And "muted" "icon_container" in the "Group 1" "core_message > Message header" should be visible
|
||||
And I go back in "view-conversation" message drawer
|
||||
And "muted" "icon_container" in the "Group 1" "core_message > Message" should be visible
|
||||
@ -53,7 +53,7 @@ Feature: Mute and unmute conversations
|
||||
And I select "Student 2" conversation in messaging
|
||||
And "muted" "icon_container" in the "[data-action='view-contact']" "css_element" should not be visible
|
||||
And I open contact menu
|
||||
And I click on "Mute" "link" in the "[data-region='header-container']" "css_element"
|
||||
And I click on "Mute" "link" in the "conversation-actions-menu" "region"
|
||||
And "muted" "icon_container" in the "[data-action='view-contact']" "css_element" should be visible
|
||||
And I go back in "view-conversation" message drawer
|
||||
And "muted" "icon_container" in the "Student 2" "core_message > Message" should be visible
|
||||
@ -70,7 +70,7 @@ Feature: Mute and unmute conversations
|
||||
And I select "Group 1" conversation in messaging
|
||||
And "muted" "icon_container" in the "Group 1" "core_message > Message header" should be visible
|
||||
And I open contact menu
|
||||
And I click on "Unmute" "link" in the "[data-region='header-container']" "css_element"
|
||||
And I click on "Unmute" "link" in the "conversation-actions-menu" "region"
|
||||
And "muted" "icon_container" in the "Group 1" "core_message > Message header" should not be visible
|
||||
And I go back in "view-conversation" message drawer
|
||||
And "muted" "icon_container" in the "Group 1" "core_message > Message" should not be visible
|
||||
@ -88,7 +88,7 @@ Feature: Mute and unmute conversations
|
||||
And I select "Student 2" conversation in messaging
|
||||
And "muted" "icon_container" in the "[data-action='view-contact']" "css_element" should be visible
|
||||
And I open contact menu
|
||||
And I click on "Unmute" "link" in the "[data-region='header-container']" "css_element"
|
||||
And I click on "Unmute" "link" in the "conversation-actions-menu" "region"
|
||||
And "muted" "icon_container" in the "[data-action='view-contact']" "css_element" should not be visible
|
||||
And I go back in "view-conversation" message drawer
|
||||
And "muted" "icon_container" in the "Student 2" "core_message > Message" should not be visible
|
||||
|
@ -101,14 +101,14 @@ Feature: Run tests over my courses.
|
||||
| Default region | Right |
|
||||
And I press "Save changes"
|
||||
And I should see "This is visible on all pages"
|
||||
And "Move Text on all pages block" "button" should exist in the "Text on all pages" "block"
|
||||
And "Move Text on all pages block" "menuitem" should exist in the "Text on all pages" "block"
|
||||
When I am on the "My courses" page
|
||||
# Check blocks visible but are "locked" in place.
|
||||
Then "Course overview" "text" should exist in the "region-main" "region"
|
||||
And I should not see "Add a block"
|
||||
And I should see "This is visible on all pages"
|
||||
And "Move Text on all pages block" "button" should not exist in the "Text on all pages" "block"
|
||||
And "Move Course overview block" "button" should not exist in the "Course overview" "block"
|
||||
And "Move Text on all pages block" "menuitem" should not exist in the "Text on all pages" "block"
|
||||
And "Move Course overview block" "menuitem" should not exist in the "Course overview" "block"
|
||||
And I click on "Actions menu" "icon" in the "Course overview" "block"
|
||||
And I should not see "Delete Course overview block"
|
||||
|
||||
|
@ -1258,7 +1258,7 @@ $activity-add-hover: theme-color-level('primary', -10) !default;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#changenumsections {
|
||||
.changenumsections {
|
||||
border-top: $border-width solid $primary-light-border;
|
||||
}
|
||||
|
||||
@ -1437,9 +1437,16 @@ $activity-add-hover: theme-color-level('primary', -10) !default;
|
||||
flex: 0 1 auto;
|
||||
max-width: 100%;
|
||||
}
|
||||
.inplaceeditable .quickeditlink,
|
||||
.afterlink {
|
||||
margin: 1.5rem 0 0.2rem 0.5rem;
|
||||
|
||||
/* Prevent bootstrap strech-link from covering the inplace editable button using z-index. */
|
||||
.activityname {
|
||||
.afterlink {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
.inplaceeditable .quickeditlink {
|
||||
z-index: 2;
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.action-menu-item {
|
||||
|
@ -14731,7 +14731,7 @@ span.editinstructions {
|
||||
.block-add:hover .activity-add-text {
|
||||
text-decoration: underline; }
|
||||
|
||||
#changenumsections {
|
||||
.changenumsections {
|
||||
border-top: 1px solid #3584c9; }
|
||||
|
||||
.section-collapsemenu .collapseall {
|
||||
@ -14821,7 +14821,8 @@ span.editinstructions {
|
||||
|
||||
.activity-item {
|
||||
position: relative;
|
||||
border-radius: 0.5rem; }
|
||||
border-radius: 0.5rem;
|
||||
/* Prevent bootstrap strech-link from covering the inplace editable button using z-index. */ }
|
||||
.activity-item:not(.activityinline) {
|
||||
border: 1px solid #dee2e6;
|
||||
padding: 1rem; }
|
||||
@ -14841,9 +14842,11 @@ span.editinstructions {
|
||||
display: flex;
|
||||
flex: 0 1 auto;
|
||||
max-width: 100%; }
|
||||
.activity-item .inplaceeditable .quickeditlink,
|
||||
.activity-item .afterlink {
|
||||
margin: 1.5rem 0 0.2rem 0.5rem; }
|
||||
.activity-item .activityname .afterlink {
|
||||
margin-left: 0.5rem; }
|
||||
.activity-item .activityname .inplaceeditable .quickeditlink {
|
||||
z-index: 2;
|
||||
margin-left: 0.5rem; }
|
||||
.activity-item .action-menu-item {
|
||||
display: flex;
|
||||
align-items: center; }
|
||||
|
@ -14731,7 +14731,7 @@ span.editinstructions {
|
||||
.block-add:hover .activity-add-text {
|
||||
text-decoration: underline; }
|
||||
|
||||
#changenumsections {
|
||||
.changenumsections {
|
||||
border-top: 1px solid #3584c9; }
|
||||
|
||||
.section-collapsemenu .collapseall {
|
||||
@ -14821,7 +14821,8 @@ span.editinstructions {
|
||||
|
||||
.activity-item {
|
||||
position: relative;
|
||||
border-radius: 0.25rem; }
|
||||
border-radius: 0.25rem;
|
||||
/* Prevent bootstrap strech-link from covering the inplace editable button using z-index. */ }
|
||||
.activity-item:not(.activityinline) {
|
||||
border: 1px solid #dee2e6;
|
||||
padding: 1rem; }
|
||||
@ -14841,9 +14842,11 @@ span.editinstructions {
|
||||
display: flex;
|
||||
flex: 0 1 auto;
|
||||
max-width: 100%; }
|
||||
.activity-item .inplaceeditable .quickeditlink,
|
||||
.activity-item .afterlink {
|
||||
margin: 1.5rem 0 0.2rem 0.5rem; }
|
||||
.activity-item .activityname .afterlink {
|
||||
margin-left: 0.5rem; }
|
||||
.activity-item .activityname .inplaceeditable .quickeditlink {
|
||||
z-index: 2;
|
||||
margin-left: 0.5rem; }
|
||||
.activity-item .action-menu-item {
|
||||
display: flex;
|
||||
align-items: center; }
|
||||
|
Loading…
x
Reference in New Issue
Block a user