Merge branch 'MDL-72668-master' of git://github.com/rezaies/moodle

This commit is contained in:
Jun Pataleta 2021-11-04 12:03:42 +08:00
commit 825b276b1a
12 changed files with 174 additions and 68 deletions

View File

@ -59,7 +59,7 @@ class core_badges_renderer extends plugin_renderer_base {
$name = html_writer::tag('span', $bname, array('class' => 'badge-name'));
$image = html_writer::empty_tag('img', array('src' => $imageurl, 'class' => 'badge-image'));
$image = html_writer::empty_tag('img', ['src' => $imageurl, 'class' => 'badge-image', 'alt' => $badge->imagecaption]);
if (!empty($badge->dateexpire) && $badge->dateexpire < time()) {
$image .= $this->output->pix_icon('i/expired',
get_string('expireddate', 'badges', userdate($badge->dateexpire)),

View File

@ -0,0 +1,2 @@
define ("block_private_files/files_tree",["exports","core/tree"],function(a,b){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;b=function(a){return a&&a.__esModule?a:{default:a}}(b);var c=function(a){new b.default("#".concat(a," [role=\"tree\"]"))};a.init=c});
//# sourceMappingURL=files_tree.min.js.map

View File

@ -0,0 +1 @@
{"version":3,"sources":["../src/files_tree.js"],"names":["init","blockId","Tree"],"mappings":"2JAsBA,uDAQO,GAAMA,CAAAA,CAAI,CAAG,SAACC,CAAD,CAAa,CAC7B,GAAIC,UAAJ,YAAaD,CAAb,qBACH,CAFM,C","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Changes the display of directories and files into a tree.\n *\n * @module block_private_files/files_tree\n * @copyright 2021 Shamim Rezaie <shamim@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Tree from 'core/tree';\n\n/**\n * The init function that does the job.\n * It changes the display of directories and files into a tree.\n *\n * @param {string} blockId\n */\nexport const init = (blockId) => {\n new Tree(`#${blockId} [role=\"tree\"]`);\n};\n"],"file":"files_tree.min.js"}

View File

@ -0,0 +1,33 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Changes the display of directories and files into a tree.
*
* @module block_private_files/files_tree
* @copyright 2021 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import Tree from 'core/tree';
/**
* The init function that does the job.
* It changes the display of directories and files into a tree.
*
* @param {string} blockId
*/
export const init = (blockId) => {
new Tree(`#${blockId} [role="tree"]`);
};

View File

@ -1,47 +0,0 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Init private files treeview
*
* @package block_private_files
* @copyright 2009 Petr Skoda (http://skodak.org)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
M.block_private_files = {};
M.block_private_files.init_tree = function(Y, expand_all, htmlid) {
Y.use('yui2-treeview', 'node-event-simulate', function(Y) {
var tree = new Y.YUI2.widget.TreeView(htmlid);
tree.subscribe("clickEvent", function(node, event) {
// we want normal clicking which redirects to url
return false;
});
tree.subscribe("enterKeyPressed", function(node) {
// We want keyboard activation to trigger a click on the first link.
Y.one(node.getContentEl()).one('a').simulate('click');
return false;
});
if (expand_all) {
tree.expandAll();
}
tree.render();
});
};

View File

@ -35,14 +35,13 @@ class block_private_files_renderer extends plugin_renderer_base {
}
public function render_private_files_tree(private_files_tree $tree) {
$module = array('name'=>'block_private_files', 'fullpath'=>'/blocks/private_files/module.js', 'requires'=>array('yui2-treeview'));
if (empty($tree->dir['subdirs']) && empty($tree->dir['files'])) {
$html = $this->output->box(get_string('nofilesavailable', 'repository'));
} else {
$htmlid = 'private_files_tree_'.uniqid();
$this->page->requires->js_init_call('M.block_private_files.init_tree', array(false, $htmlid));
$this->page->requires->js_call_amd('block_private_files/files_tree', 'init', [$htmlid]);
$html = '<div id="'.$htmlid.'">';
$html .= $this->htmllize_tree($tree, $tree->dir);
$html .= $this->htmllize_tree($tree, $tree->dir, true);
$html .= '</div>';
}
@ -50,26 +49,39 @@ class block_private_files_renderer extends plugin_renderer_base {
}
/**
* Internal function - creates htmls structure suitable for YUI tree.
* Internal function - creates htmls structure suitable for core/tree AMD.
*
* @param private_files_tree $tree The renderable tree.
* @param array $dir The directory in the tree
* @param bool $isroot If it is the root directory in the tree.
* @return string
*/
protected function htmllize_tree($tree, $dir) {
protected function htmllize_tree($tree, $dir, $isroot) {
global $CFG;
$yuiconfig = array();
$yuiconfig['type'] = 'html';
if (empty($dir['subdirs']) and empty($dir['files'])) {
return '';
}
$result = '<ul>';
if ($isroot) {
$result = '<ul role="tree" aria-label="' . s(get_string('privatefiles')) . '">';
} else {
$result = '<ul role="group" aria-hidden="true">';
}
foreach ($dir['subdirs'] as $subdir) {
$image = $this->output->pix_icon(file_folder_icon(), $subdir['dirname'], 'moodle', array('class'=>'icon'));
$result .= '<li yuiConfig=\''.json_encode($yuiconfig).'\'><div>'.$image.s($subdir['dirname']).'</div> '.$this->htmllize_tree($tree, $subdir).'</li>';
$image = $this->output->pix_icon(file_folder_icon(), '');
$content = $this->htmllize_tree($tree, $subdir, false);
if ($content) {
$result .= '<li role="treeitem" aria-expanded="false"><p>' . $image . s($subdir['dirname']) . '</p>' .
$content . '</li>';
} else {
$result .= '<li role="treeitem"><p>' . $image . s($subdir['dirname']) . '</p></li>';
}
}
foreach ($dir['files'] as $file) {
$url = file_encode_url("$CFG->wwwroot/pluginfile.php", '/'.$tree->context->id.'/user/private'.$file->get_filepath().$file->get_filename(), true);
$filename = $file->get_filename();
$image = $this->output->pix_icon(file_file_icon($file), $filename, 'moodle', array('class'=>'icon'));
$result .= '<li yuiConfig=\''.json_encode($yuiconfig).'\'><div>'.html_writer::link($url, $image.$filename).'</div></li>';
$image = $this->output->pix_icon(file_file_icon($file), '');
$result .= '<li role="treeitem">'.html_writer::link($url, $image.$filename, ['tabindex' => -1]).'</li>';
}
$result .= '</ul>';

View File

@ -8,3 +8,70 @@
padding: 10px 0 0;
margin-top: .5em;
}
.block_private_files ul[role="tree"] {
margin: 0;
padding: 0;
}
.block_private_files ul,
.block_private_files li {
list-style: none;
}
.block_private_files [role="treeitem"] {
padding-left: 22px;
cursor: pointer;
}
.block_private_files [role="treeitem"] p {
margin-bottom: 0;
}
.block_private_files [role="treeitem"][aria-expanded] {
padding-left: 0;
}
.block_private_files [role="treeitem"][aria-expanded="false"] > p::before {
/*rtl:remove*/
content: url('[[pix:t/collapsed]]');
/*rtl:raw:
content: url('[[pix:t/collapsed_rtl]]');
*/
vertical-align: sub;
margin-right: 5px;
}
.block_private_files [role="treeitem"][aria-expanded="true"] > p::before {
content: url('[[pix:t/expanded]]');
vertical-align: sub;
margin-right: 5px;
}
.block_private_files [role="treeitem"]:not([aria-expanded]) {
background-image:
repeating-linear-gradient(to right, rgba(0, 0, 0, .5) 0, rgba(0, 0, 0, .5) 1px, rgba(255, 255, 255, 0) 1px, rgba(255, 255, 255, 0) 2px),
repeating-linear-gradient(to top, rgba(0, 0, 0, 0.5) 0, rgba(0, 0, 0, 0.5) 1px, rgba(255, 255, 255, 0) 1px, rgba(255, 255, 255, 0) 2px);
background-repeat: no-repeat, no-repeat;
/*rtl:remove*/
background-position: left 10px top 50%, left 8px top 0;
/*rtl:raw:
background-position: right 10px top 50%, right 8px top 0;
*/
background-size: 11px 1px, 1px 100%;
}
.block_private_files [role="treeitem"]:not([aria-expanded]):last-child {
background-size: 11px 1px, 1px 50%;
}
.block_private_files [role="group"] {
background-image: repeating-linear-gradient(to top, rgba(0, 0, 0, 0.5) 0, rgba(0, 0, 0, 0.5) 1px, rgba(255, 255, 255, 0) 1px, rgba(255, 255, 255, 0) 2px);
background-repeat: no-repeat;
background-position: left 8px top 100%;
background-size: 1px 100%;
margin-left: 0;
}
.block_private_files [aria-hidden="true"]:not(.icon) {
display: none;
}

File diff suppressed because one or more lines are too long

View File

@ -418,7 +418,7 @@ define(['jquery'], function($) {
}).focus();
};
// If this is a goup item then collapse it and focus the parent group
// If this is a group item then collapse it and focus the parent group
// in accordance with the aria spec.
if (this.isGroupItem(item)) {
if (this.isGroupCollapsed(item)) {
@ -531,5 +531,5 @@ define(['jquery'], function($) {
}, SELECTORS.ITEM);
};
return /** @alias module:tool_lp/tree */ Tree;
return /** @alias module:core/tree */ Tree;
});

View File

@ -149,7 +149,8 @@ a.dropdown-toggle,
.modal-dialog[tabindex="0"],
.moodle-dialogue-base .closebutton,
button.close,
.form-autocomplete-selection {
.form-autocomplete-selection,
[role="treeitem"]:not([aria-expanded="true"]) {
&.focus,
&:focus {
outline: 0;
@ -160,6 +161,21 @@ button.close,
}
}
// We don't want to highlight the whole li when it's expanded. Only the first child is highlighted.
[role="treeitem"][aria-expanded="true"] {
outline: 0;
&.focus,
&:focus {
> *:first-child {
outline: 0;
box-shadow: $input-btn-focus-box-shadow;
}
}
&:focus:hover {
text-decoration: none;
}
}
// Accessible focus styling for autocomplete elements.
.form-autocomplete-suggestions li[aria-selected=true] {
outline: 0;

View File

@ -10001,7 +10001,9 @@ a.dropdown-toggle:focus,
button.close.focus,
button.close:focus,
.form-autocomplete-selection.focus,
.form-autocomplete-selection:focus {
.form-autocomplete-selection:focus,
[role="treeitem"]:not([aria-expanded="true"]).focus,
[role="treeitem"]:not([aria-expanded="true"]):focus {
outline: 0;
box-shadow: 0 0 0 0.2rem rgba(15, 111, 197, 0.75); }
@ -10021,9 +10023,18 @@ a.dropdown-toggle:focus:hover,
.modal-dialog[tabindex="0"]:focus:hover,
.moodle-dialogue-base .closebutton:focus:hover,
button.close:focus:hover,
.form-autocomplete-selection:focus:hover {
.form-autocomplete-selection:focus:hover,
[role="treeitem"]:not([aria-expanded="true"]):focus:hover {
text-decoration: none; }
[role="treeitem"][aria-expanded="true"] {
outline: 0; }
[role="treeitem"][aria-expanded="true"].focus > *:first-child, [role="treeitem"][aria-expanded="true"]:focus > *:first-child {
outline: 0;
box-shadow: 0 0 0 0.2rem rgba(15, 111, 197, 0.75); }
[role="treeitem"][aria-expanded="true"]:focus:hover {
text-decoration: none; }
.form-autocomplete-suggestions li[aria-selected=true] {
outline: 0;
box-shadow: 0 0 0 0.2rem rgba(15, 111, 197, 0.75); }

View File

@ -10001,7 +10001,9 @@ a.dropdown-toggle:focus,
button.close.focus,
button.close:focus,
.form-autocomplete-selection.focus,
.form-autocomplete-selection:focus {
.form-autocomplete-selection:focus,
[role="treeitem"]:not([aria-expanded="true"]).focus,
[role="treeitem"]:not([aria-expanded="true"]):focus {
outline: 0;
box-shadow: 0 0 0 0.2rem rgba(15, 111, 197, 0.75); }
@ -10021,9 +10023,18 @@ a.dropdown-toggle:focus:hover,
.modal-dialog[tabindex="0"]:focus:hover,
.moodle-dialogue-base .closebutton:focus:hover,
button.close:focus:hover,
.form-autocomplete-selection:focus:hover {
.form-autocomplete-selection:focus:hover,
[role="treeitem"]:not([aria-expanded="true"]):focus:hover {
text-decoration: none; }
[role="treeitem"][aria-expanded="true"] {
outline: 0; }
[role="treeitem"][aria-expanded="true"].focus > *:first-child, [role="treeitem"][aria-expanded="true"]:focus > *:first-child {
outline: 0;
box-shadow: 0 0 0 0.2rem rgba(15, 111, 197, 0.75); }
[role="treeitem"][aria-expanded="true"]:focus:hover {
text-decoration: none; }
.form-autocomplete-suggestions li[aria-selected=true] {
outline: 0;
box-shadow: 0 0 0 0.2rem rgba(15, 111, 197, 0.75); }