aria-hidden="{{#show}}false{{/show}}{{^show}}true{{/show}}"
data-region="right-hand-drawer"
role="region"
- tabindex="-1"
+ tabindex="0"
>
{{$drawercontent}}{{/drawercontent}}
</div>
) {
var SELECTORS = {
+ DRAWER: '[data-region="right-hand-drawer"]',
+ JUMPTO: '.popover-region [data-region="jumpto"]',
PANEL_BODY_CONTAINER: '[data-region="panel-body-container"]',
PANEL_HEADER_CONTAINER: '[data-region="panel-header-container"]',
VIEW_CONTACT: '[data-region="view-contact"]',
return true;
};
+ /**
+ * Set Jump from button
+ *
+ * @param {String} buttonid The originating button id
+ */
+ var setJumpFrom = function(buttonid) {
+ $(SELECTORS.DRAWER).attr('data-origin', buttonid);
+ };
+
/**
* Listen to and handle events for routing, showing and hiding the message drawer.
*
});
});
+ $(SELECTORS.JUMPTO).focus(function() {
+ var firstInput = $(SELECTORS.HEADER_CONTAINER).find('input:visible');
+ if (firstInput.length) {
+ firstInput.focus();
+ } else {
+ $(SELECTORS.HEADER_CONTAINER).find(SELECTORS.ROUTES_BACK).focus();
+ }
+ });
+
+ $(SELECTORS.DRAWER).focus(function() {
+ var button = $(this).attr('data-origin');
+ if (button) {
+ $('#' + button).focus();
+ }
+ });
+
if (!alwaysVisible) {
PubSub.subscribe(Events.SHOW, function() {
show(namespace, root);
hide(root);
});
- PubSub.subscribe(Events.TOGGLE_VISIBILITY, function() {
+ PubSub.subscribe(Events.TOGGLE_VISIBILITY, function(buttonid) {
if (isVisible(root)) {
hide(root);
+ $(SELECTORS.JUMPTO).attr('tabindex', -1);
} else {
show(namespace, root);
+ setJumpFrom(buttonid);
+ $(SELECTORS.JUMPTO).attr('tabindex', 0);
}
});
}
- PubSub.subscribe(Events.SHOW_CONVERSATION, function(conversationId) {
+ PubSub.subscribe(Events.SHOW_CONVERSATION, function(args) {
+ setJumpFrom(args.buttonid);
show(namespace, root);
- Router.go(namespace, Routes.VIEW_CONVERSATION, conversationId);
+ Router.go(namespace, Routes.VIEW_CONVERSATION, args.conversationid);
});
- PubSub.subscribe(Events.CREATE_CONVERSATION_WITH_USER, function(userId) {
+ PubSub.subscribe(Events.CREATE_CONVERSATION_WITH_USER, function(args) {
+ setJumpFrom(args.buttonid);
show(namespace, root);
- Router.go(namespace, Routes.VIEW_CONVERSATION, null, 'create', userId);
+ Router.go(namespace, Routes.VIEW_CONVERSATION, null, 'create', args.userid);
});
PubSub.subscribe(Events.SHOW_SETTINGS, function() {
*
* @param {Number} userId The user id to start a conversation.
*/
- var createConversationWithUser = function(userId) {
- PubSub.publish(MessageDrawerEvents.CREATE_CONVERSATION_WITH_USER, userId);
+ var createConversationWithUser = function(args) {
+ PubSub.publish(MessageDrawerEvents.CREATE_CONVERSATION_WITH_USER, args);
+ };
+
+ /**
+ * Trigger an event to hide the message drawer.
+ */
+ var hide = function() {
+ PubSub.publish(MessageDrawerEvents.HIDE);
};
/**
*
* @param {int} conversationId Id for the conversation to show.
*/
- var showConversation = function(conversationId) {
- PubSub.publish(MessageDrawerEvents.SHOW_CONVERSATION, conversationId);
+ var showConversation = function(args) {
+ PubSub.publish(MessageDrawerEvents.SHOW_CONVERSATION, args);
};
/**
return {
createConversationWithUser: createConversationWithUser,
+ hide: hide,
show: show,
showConversation: showConversation,
showSettings: showSettings
/**
* Toggle the message drawer visibility.
+ *
+ * @param {String} button The button id for the popover.
*/
- var toggleMessageDrawerVisibility = function() {
- PubSub.publish(MessageDrawerEvents.TOGGLE_VISIBILITY);
+ var toggleMessageDrawerVisibility = function(buttonid) {
+ PubSub.publish(MessageDrawerEvents.TOGGLE_VISIBILITY, buttonid);
};
/**
* Decrement the unread conversation count in the nav bar if a conversation
* is read. When there are no unread conversations then hide the counter.
*
- * @param {Object} root The root element for the popover.
+ * @param {Object} button The button element for the popover.
* @return {Function}
*/
- var handleDecrementConversationCount = function(root) {
+ var handleDecrementConversationCount = function(button) {
return function() {
- var countContainer = root.find(SELECTORS.COUNT_CONTAINER);
+ var countContainer = button.find(SELECTORS.COUNT_CONTAINER);
var count = parseInt(countContainer.text(), 10);
if (isNaN(count)) {
* Add events listeners for when the popover icon is clicked and when conversations
* are read.
*
- * @param {Object} root The root element for the popover.
+ * @param {Object} button The button element for the popover.
*/
- var registerEventListeners = function(root) {
- CustomEvents.define(root, [CustomEvents.events.activate]);
+ var registerEventListeners = function(button) {
+ CustomEvents.define(button, [CustomEvents.events.activate]);
- root.on(CustomEvents.events.activate, function(e, data) {
- toggleMessageDrawerVisibility();
+ button.on(CustomEvents.events.activate, function(e, data) {
+ toggleMessageDrawerVisibility(button.attr('id'));
+ button.focus();
data.originalEvent.preventDefault();
});
- PubSub.subscribe(MessageDrawerEvents.CONVERSATION_READ, handleDecrementConversationCount(root));
- PubSub.subscribe(MessageDrawerEvents.CONTACT_REQUEST_ACCEPTED, handleDecrementConversationCount(root));
- PubSub.subscribe(MessageDrawerEvents.CONTACT_REQUEST_DECLINED, handleDecrementConversationCount(root));
+ PubSub.subscribe(MessageDrawerEvents.CONVERSATION_READ, handleDecrementConversationCount(button));
+ PubSub.subscribe(MessageDrawerEvents.CONTACT_REQUEST_ACCEPTED, handleDecrementConversationCount(button));
+ PubSub.subscribe(MessageDrawerEvents.CONTACT_REQUEST_DECLINED, handleDecrementConversationCount(button));
};
/**
* Initialise the message popover.
*
- * @param {Object} root The root element for the popover.
+ * @param {Object} button The button element for the popover.
*/
- var init = function(root) {
- root = $(root);
- registerEventListeners(root);
+ var init = function(button) {
+ button = $(button);
+ registerEventListeners(button);
};
return {
* @copyright 2019 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-define(['jquery', 'core/custom_interaction_events', 'core_message/message_drawer_helper'],
- function($, CustomEvents, MessageDrawerHelper) {
+define(['jquery', 'core/custom_interaction_events', 'core_message/message_drawer_helper', 'core/templates'],
+ function($, CustomEvents, MessageDrawerHelper, Templates) {
+
+
+ var SELECTORS = {
+ MESSAGE_TEXTAREA: '[data-region="send-message-txt"]',
+ MESSAGE_USER_BUTTON: '#message-user-button',
+ MESSAGE_JUMP: '[data-region="jumpto"]'
+ };
+
+ var TEMPLATES = {
+ CONTENT: 'core_message/message_jumpto'
+ };
/**
* Get the id for the user being messaged.
var send = function(element) {
element = $(element);
+ var args = {
+ conversationid: getConversationId(element),
+ buttonid: $(element).attr('id'),
+ userid: getUserId(element)
+ };
+
+ Templates.render(TEMPLATES.CONTENT, {})
+ .then(function(html) {
+ element.after(html);
+ })
+ .then(function() {
+ $(SELECTORS.MESSAGE_USER_BUTTON).next().focus(function() {
+ $(SELECTORS.MESSAGE_TEXTAREA).focus();
+ });
+ });
+
CustomEvents.define(element, [CustomEvents.events.activate]);
element.on(CustomEvents.events.activate, function(e, data) {
- var conversationid = getConversationId(element);
- if (conversationid) {
- MessageDrawerHelper.showConversation(conversationid);
+ if ($(e.target).hasClass('active')) {
+ MessageDrawerHelper.hide();
+ $(SELECTORS.MESSAGE_USER_BUTTON).next().attr('tabindex', -1);
} else {
- MessageDrawerHelper.createConversationWithUser(getUserId(element));
+ $(SELECTORS.MESSAGE_USER_BUTTON).next().attr('tabindex', 0);
+ if (args.conversationid) {
+ MessageDrawerHelper.showConversation(args);
+ } else {
+ MessageDrawerHelper.createConversationWithUser(args);
+ }
}
+ $(e.target).focus();
+ $(e.target).toggleClass('active');
e.preventDefault();
data.originalEvent.preventDefault();
});
--- /dev/null
+{{!
+ 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/>.
+}}
+{{!
+ @template core_message/message_jump_botton
+
+ This template will render the jump button used for keyboard navigation.
+
+ Example context (json):
+ {
+ }
+
+}}
+<span class="sr-only sr-only-focusable" data-region="jumpto" tabindex="-1"></span>
\ No newline at end of file
<div class="count-container {{^unreadcount}}hidden{{/unreadcount}}" data-region="count-container"
aria-label="{{#str}} unreadconversations, core_message, {{unreadcount}} {{/str}}">{{unreadcount}}</div>
</a>
+ {{> core_message/message_jumpto }}
</div>
{{#js}}