AutorÃa | Ultima modificación | Ver Log |
{"version":3,"file":"discussion.min.js","sources":["../src/discussion.js"],"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 * Module for viewing a discussion.\n *\n * @module mod_forum/discussion\n * @copyright 2019 Ryan Wyllie <ryan@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(\n[\n 'j
query',\n 'core/custom_interaction_events',\n 'mod_forum/selectors',\n 'core/pubsub',\n 'mod_forum/forum_events',\n 'core/str',\n 'core/notification',\n],\nfunction(\n $,\n CustomEvents,\n Selectors,\n PubSub,\n ForumEvents,\n String,\n Notification\n) {\n\n /**\n * Set the focus on the previous post in the list. Previous post is calculated\n * based on position in list as viewed top to bottom.\n *\n * @param {Object} currentPost The post that currently has focus\n */\n var focusPreviousPost = function(currentPost) {\n // See if there is a previous sibling post.\n var prevPost = currentPost.prev(Selectors.post.post);\n\n if (prevPost.length) {\n // The previous post might have replies that appear visually between\n // it and the current post (see nested view) so if that's the case\n // then the last reply will be the previous post in the list.\n var replyPost = prevPost.find(Selec
tors.post.post).last();\n\n if (replyPost.length) {\n // Focus the last reply.\n replyPost.focus();\n } else {\n // No replies so we can focus straight on the sibling.\n prevPost.focus();\n }\n } else {\n // If there are no siblings then jump up the tree to the parent\n // post and focus the first parent post we find.\n currentPost.parents(Selectors.post.post).first().focus();\n }\n };\n\n /**\n * Set the focus on the next post in the list. Previous post is calculated\n * based on position in list as viewed top to bottom.\n *\n * @param {Object} currentPost The post that currently has focus\n */\n var focusNextPost = function(currentPost) {\n // The next post in the visual list would be the first reply to this one\n // so let's see if we have one.\n var replyPost = currentPost.find(Selectors.post.post).first();\n\n
if (replyPost.length) {\n // Got a reply.\n replyPost.focus();\n } else {\n // If we don't have a reply then the next post in the visual list would\n // be a sibling post (replying to the same parent).\n var siblingPost = currentPost.next(Selectors.post.post);\n\n if (siblingPost.length) {\n siblingPost.focus();\n } else {\n // No siblings either. That means we're the lowest level reply in a thread\n // so we need to walk back up the tree of posts and find an ancestor post that\n // has a sibling post we can focus.\n var parentPosts = currentPost.parents(Selectors.post.post).toArray();\n\n for (var i = 0; i < parentPosts.length; i++) {\n var ancestorSiblingPost = $(parentPosts[i]).next(Selectors.post.post);\n\n if (ancestorSiblingPost.length) {\n ancestorSiblingPost.focus();\n
break;\n }\n }\n }\n }\n };\n\n /**\n * Check if the element is inside the in page reply section.\n *\n * @param {Object} element The element to check\n * @return {Boolean}\n */\n var isElementInInPageReplySection = function(element) {\n var inPageReply = $(element).closest(Selectors.post.inpageReplyContent);\n return inPageReply.length ? true : false;\n };\n\n /**\n * Initialise the keyboard accessibility controls for the discussion.\n *\n * @param {Object} root The discussion root element\n */\n var initAccessibilityKeyboardNav = function(root) {\n var posts = root.find(Selectors.post.post);\n\n // Take each post action out of the tab index.\n posts.each(function(index, post) {\n var actions = $(post).find(Selectors.post.action);\n var firstAction = actions.first();\n actions.attr('tabindex', '-1');\n
firstAction.attr('tabindex', 0);\n });\n\n CustomEvents.define(root, [\n CustomEvents.events.up,\n CustomEvents.events.down,\n CustomEvents.events.next,\n CustomEvents.events.previous,\n CustomEvents.events.home,\n CustomEvents.events.end,\n ]);\n\n root.on(CustomEvents.events.up, function(e, data) {\n var activeElement = document.activeElement;\n\n if (isElementInInPageReplySection(activeElement)) {\n // Focus is currently inside the in page reply section so don't move focus\n // to another post.\n return;\n }\n\n var focusPost = $(activeElement).closest(Selectors.post.post);\n\n if (focusPost.length) {\n focusPreviousPost(focusPost);\n } else {\n root.find(Selectors.post.post).first().focus();\n }\n\n data.originalEvent.preventDefault();\n });\n\
n root.on(CustomEvents.events.down, function(e, data) {\n var activeElement = document.activeElement;\n\n if (isElementInInPageReplySection(activeElement)) {\n // Focus is currently inside the in page reply section so don't move focus\n // to another post.\n return;\n }\n\n var focusPost = $(activeElement).closest(Selectors.post.post);\n\n if (focusPost.length) {\n focusNextPost(focusPost);\n } else {\n root.find(Selectors.post.post).first().focus();\n }\n\n data.originalEvent.preventDefault();\n });\n\n root.on(CustomEvents.events.home, function(e, data) {\n if (isElementInInPageReplySection(document.activeElement)) {\n // Focus is currently inside the in page reply section so don't move focus\n // to another post.\n return;\n }\n root.find(Selectors
.post.post).first().focus();\n data.originalEvent.preventDefault();\n });\n\n root.on(CustomEvents.events.end, function(e, data) {\n if (isElementInInPageReplySection(document.activeElement)) {\n // Focus is currently inside the in page reply section so don't move focus\n // to another post.\n return;\n }\n root.find(Selectors.post.post).last().focus();\n data.originalEvent.preventDefault();\n });\n\n root.on(CustomEvents.events.next, Selectors.post.action, function(e, data) {\n var currentAction = $(e.target);\n var container = currentAction.closest(Selectors.post.actionsContainer);\n var actions = container.find(Selectors.post.action);\n var nextAction = currentAction.next(Selectors.post.action);\n\n actions.attr('tabindex', '-1');\n\n if (!nextAction.length) {\n nextAction = actions.first();\n
}\n\n nextAction.attr('tabindex', 0);\n nextAction.focus();\n\n data.originalEvent.preventDefault();\n });\n\n root.on(CustomEvents.events.previous, Selectors.post.action, function(e, data) {\n var currentAction = $(e.target);\n var container = currentAction.closest(Selectors.post.actionsContainer);\n var actions = container.find(Selectors.post.action);\n var nextAction = currentAction.prev(Selectors.post.action);\n\n actions.attr('tabindex', '-1');\n\n if (!nextAction.length) {\n nextAction = actions.last();\n }\n\n nextAction.attr('tabindex', 0);\n nextAction.focus();\n\n data.originalEvent.preventDefault();\n });\n\n root.on(CustomEvents.events.home, Selectors.post.action, function(e, data) {\n var currentAction = $(e.target);\n var container = currentAction.closest(Selectors.post.actionsContaine
r);\n var actions = container.find(Selectors.post.action);\n var firstAction = actions.first();\n\n actions.attr('tabindex', '-1');\n firstAction.attr('tabindex', 0);\n firstAction.focus();\n\n e.stopPropagation();\n data.originalEvent.preventDefault();\n });\n\n root.on(CustomEvents.events.end, Selectors.post.action, function(e, data) {\n var currentAction = $(e.target);\n var container = currentAction.closest(Selectors.post.actionsContainer);\n var actions = container.find(Selectors.post.action);\n var lastAction = actions.last();\n\n actions.attr('tabindex', '-1');\n lastAction.attr('tabindex', 0);\n lastAction.focus();\n\n e.stopPropagation();\n data.originalEvent.preventDefault();\n });\n\n PubSub.subscribe(ForumEvents.SUBSCRIPTION_TOGGLED, function(data) {\n var subscribed = data.subscriptio
nState;\n var updateMessage = subscribed ? 'discussionsubscribed' : 'discussionunsubscribed';\n String.get_string(updateMessage, \"forum\")\n .then(function(s) {\n return Notification.addNotification({\n message: s,\n type: \"info\"\n });\n })\n .catch(Notification.exception);\n });\n };\n\n return {\n init: function(root) {\n initAccessibilityKeyboardNav(root);\n }\n };\n});\n"],"names":["define","$","CustomEvents","Selectors","PubSub","ForumEvents","String","Notification","isElementInInPageReplySection","element","closest","post","inpageReplyContent","length","initAccessibilityKeyboardNav","root","find","each","index","actions","action","firstAction","first","attr","events","up","down","next","previous","home","end","on","e","data","activeElement","document","focusPost","currentPost","prevPost","prev","replyPost","las
t","focus","parents","focusPreviousPost","originalEvent","preventDefault","siblingPost","parentPosts","toArray","i","ancestorSiblingPost","focusNextPost","currentAction","target","actionsContainer","nextAction","stopPropagation","lastAction","subscribe","SUBSCRIPTION_TOGGLED","updateMessage","subscriptionState","get_string","then","s","addNotification","message","type","catch","exception","init"],"mappings":"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"}