diff --git a/mod/forum/amd/build/discussion_nested_v2.min.js b/mod/forum/amd/build/discussion_nested_v2.min.js index 0f3d72be84e..0a76ceea053 100644 --- a/mod/forum/amd/build/discussion_nested_v2.min.js +++ b/mod/forum/amd/build/discussion_nested_v2.min.js @@ -1,2 +1,2 @@ -define ("mod_forum/discussion_nested_v2",["exports","jquery","core/auto_rows","core/custom_interaction_events","core/notification","core/templates","mod_forum/discussion","mod_forum/inpage_reply","mod_forum/lock_toggle","mod_forum/favourite_toggle","mod_forum/pin_toggle","mod_forum/selectors","mod_forum/subscription_toggle"],function(a,b,c,d,e,f,g,h,i,j,k,l,m){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;b=n(b);c=n(c);d=n(d);e=n(e);f=n(f);g=n(g);h=n(h);i=n(i);j=n(j);k=n(k);l=n(l);m=n(m);function n(a){return a&&a.__esModule?a:{default:a}}function o(a){for(var b=1;b.\n\n/**\n * Module for viewing a discussion in nested v2 view.\n *\n * @copyright 2019 Ryan Wyllie \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport $ from 'jquery';\nimport AutoRows from 'core/auto_rows';\nimport CustomEvents from 'core/custom_interaction_events';\nimport Notification from 'core/notification';\nimport Templates from 'core/templates';\nimport Discussion from 'mod_forum/discussion';\nimport InPageReply from 'mod_forum/inpage_reply';\nimport LockToggle from 'mod_forum/lock_toggle';\nimport FavouriteToggle from 'mod_forum/favourite_toggle';\nimport Pin from 'mod_forum/pin_toggle';\nimport Selectors from 'mod_forum/selectors';\nimport Subscribe from 'mod_forum/subscription_toggle';\n\nconst ANIMATION_DURATION = 150;\n\n/**\n * Get the closest post container element from the given element.\n *\n * @param {Object} element jQuery element to search from\n * @return {Object} jQuery element\n */\nconst getPostContainer = (element) => {\n return element.closest(Selectors.post.post);\n};\n\n/**\n * Get the closest post container element from the given element.\n *\n * @param {Object} element jQuery element to search from\n * @param {Number} id Id of the post to find.\n * @return {Object} jQuery element\n */\nconst getPostContainerById = (element, id) => {\n return element.find(`${Selectors.post.post}[data-post-id=${id}]`);\n};\n\n/**\n * Get the parent post container elements from the given element.\n *\n * @param {Object} element jQuery element to search from\n * @return {Object} jQuery element\n */\nconst getParentPostContainers = (element) => {\n return element.parents(Selectors.post.post);\n};\n\n/**\n * Get the post content container element from the post container element.\n *\n * @param {Object} postContainer jQuery element for the post container\n * @return {Object} jQuery element\n */\nconst getPostContentContainer = (postContainer) => {\n return postContainer.children().not(Selectors.post.repliesContainer).find(Selectors.post.forumCoreContent);\n};\n\n/**\n * Get the in page reply container element from the post container element.\n *\n * @param {Object} postContainer jQuery element for the post container\n * @return {Object} jQuery element\n */\nconst getInPageReplyContainer = (postContainer) => {\n return postContainer.children().filter(Selectors.post.inpageReplyContainer);\n};\n\n/**\n * Get the in page reply form element from the post container element.\n *\n * @param {Object} postContainer jQuery element for the post container\n * @return {Object} jQuery element\n */\nconst getInPageReplyForm = (postContainer) => {\n return getInPageReplyContainer(postContainer).find(Selectors.post.inpageReplyContent);\n};\n\n/**\n * Get the in page reply create (reply) button element from the post container element.\n *\n * @param {Object} postContainer jQuery element for the post container\n * @return {Object} jQuery element\n */\nconst getInPageReplyCreateButton = (postContainer) => {\n return getPostContentContainer(postContainer).find(Selectors.post.inpageReplyCreateButton);\n};\n\n/**\n * Get the replies visibility toggle container (show/hide replies button container) element\n * from the post container element.\n *\n * @param {Object} postContainer jQuery element for the post container\n * @return {Object} jQuery element\n */\nconst getRepliesVisibilityToggleContainer = (postContainer) => {\n return postContainer.children(Selectors.post.repliesVisibilityToggleContainer);\n};\n\n/**\n * Get the replies container element from the post container element.\n *\n * @param {Object} postContainer jQuery element for the post container\n * @return {Object} jQuery element\n */\nconst getRepliesContainer = (postContainer) => {\n return postContainer.children(Selectors.post.repliesContainer);\n};\n\n/**\n * Check if the post has any replies.\n *\n * @param {Object} postContainer jQuery element for the post container\n * @return {Bool}\n */\nconst hasReplies = (postContainer) => {\n return getRepliesContainer(postContainer).children().length > 0;\n};\n\n/**\n * Get the show replies button element from the replies visibility toggle container element.\n *\n * @param {Object} replyVisibilityToggleContainer jQuery element for the toggle container\n * @return {Object} jQuery element\n */\nconst getShowRepliesButton = (replyVisibilityToggleContainer) => {\n return replyVisibilityToggleContainer.find(Selectors.post.showReplies);\n};\n\n/**\n * Get the hide replies button element from the replies visibility toggle container element.\n *\n * @param {Object} replyVisibilityToggleContainer jQuery element for the toggle container\n * @return {Object} jQuery element\n */\nconst getHideRepliesButton = (replyVisibilityToggleContainer) => {\n return replyVisibilityToggleContainer.find(Selectors.post.hideReplies);\n};\n\n/**\n * Check if the replies are visible.\n *\n * @param {Object} postContainer jQuery element for the post container\n * @return {Bool}\n */\nconst repliesVisible = (postContainer) => {\n const repliesContainer = getRepliesContainer(postContainer);\n return repliesContainer.is(':visible');\n};\n\n/**\n * Show the post replies.\n *\n * @param {Object} postContainer jQuery element for the post container\n * @param {Number|null} postIdToSee Id of the post to scroll into view (if any)\n */\nconst showReplies = (postContainer, postIdToSee = null) => {\n const repliesContainer = getRepliesContainer(postContainer);\n const replyVisibilityToggleContainer = getRepliesVisibilityToggleContainer(postContainer);\n const showButton = getShowRepliesButton(replyVisibilityToggleContainer);\n const hideButton = getHideRepliesButton(replyVisibilityToggleContainer);\n\n showButton.addClass('hidden');\n hideButton.removeClass('hidden');\n\n repliesContainer.slideDown({\n duration: ANIMATION_DURATION,\n queue: false,\n complete: () => {\n if (postIdToSee) {\n const postContainerToSee = getPostContainerById(repliesContainer, postIdToSee);\n if (postContainerToSee.length) {\n postContainerToSee[0].scrollIntoView();\n }\n }\n }\n }).css('display', 'none').fadeIn(ANIMATION_DURATION);\n};\n\n/**\n * Hide the post replies.\n *\n * @param {Object} postContainer jQuery element for the post container\n */\nconst hideReplies = (postContainer) => {\n const repliesContainer = getRepliesContainer(postContainer);\n const replyVisibilityToggleContainer = getRepliesVisibilityToggleContainer(postContainer);\n const showButton = getShowRepliesButton(replyVisibilityToggleContainer);\n const hideButton = getHideRepliesButton(replyVisibilityToggleContainer);\n\n showButton.removeClass('hidden');\n hideButton.addClass('hidden');\n\n repliesContainer.slideUp({\n duration: ANIMATION_DURATION,\n queue: false\n }).fadeOut(ANIMATION_DURATION);\n};\n\n/** Variable to hold the showInPageReplyForm function after it's built. */\nlet showInPageReplyForm = null;\n\n/**\n * Build the showInPageReplyForm function with the given additional template context.\n *\n * @param {Object} additionalTemplateContext Additional render context for the in page reply template.\n * @return {Function}\n */\nconst buildShowInPageReplyFormFunction = (additionalTemplateContext) => {\n /**\n * Show the in page reply form in the given in page reply container. The form\n * display will be animated.\n *\n * @param {Object} postContainer jQuery element for the post container\n */\n return async (postContainer) => {\n\n const inPageReplyContainer = getInPageReplyContainer(postContainer);\n const repliesVisibilityToggleContainer = getRepliesVisibilityToggleContainer(postContainer);\n const inPageReplyCreateButton = getInPageReplyCreateButton(postContainer);\n\n if (!hasInPageReplyForm(inPageReplyContainer)) {\n try {\n const html = await renderInPageReplyTemplate(additionalTemplateContext, inPageReplyCreateButton, postContainer);\n Templates.appendNodeContents(inPageReplyContainer, html, '');\n } catch (e) {\n Notification.exception(e);\n }\n }\n\n inPageReplyCreateButton.fadeOut(ANIMATION_DURATION, () => {\n const inPageReplyForm = getInPageReplyForm(postContainer);\n inPageReplyForm.slideDown({\n duration: ANIMATION_DURATION,\n queue: false,\n complete: () => {\n inPageReplyForm.find('textarea').focus();\n }\n }).css('display', 'none').fadeIn(ANIMATION_DURATION);\n\n if (repliesVisibilityToggleContainer.length && hasReplies(postContainer)) {\n repliesVisibilityToggleContainer.fadeIn(ANIMATION_DURATION);\n hideReplies(postContainer);\n }\n });\n };\n};\n\n/**\n * Hide the in page reply form in the given in page reply container. The form\n * display will be animated.\n *\n * @param {Object} postContainer jQuery element for the post container\n * @param {Number|null} postIdToSee Id of the post to scroll into view (if any)\n */\nconst hideInPageReplyForm = (postContainer, postIdToSee = null) => {\n const inPageReplyForm = getInPageReplyForm(postContainer);\n const inPageReplyCreateButton = getInPageReplyCreateButton(postContainer);\n const repliesVisibilityToggleContainer = getRepliesVisibilityToggleContainer(postContainer);\n\n if (repliesVisibilityToggleContainer.length && hasReplies(postContainer)) {\n repliesVisibilityToggleContainer.fadeOut(ANIMATION_DURATION);\n if (!repliesVisible(postContainer)) {\n showReplies(postContainer, postIdToSee);\n }\n }\n\n inPageReplyForm.slideUp({\n duration: ANIMATION_DURATION,\n queue: false,\n complete: () => {\n inPageReplyCreateButton.fadeIn(ANIMATION_DURATION);\n }\n }).fadeOut(200);\n};\n\n/**\n * Check if the in page reply container contains the in page reply form.\n *\n * @param {Object} inPageReplyContainer jQuery element for the in page reply container\n * @return {Bool}\n */\nconst hasInPageReplyForm = (inPageReplyContainer) => {\n return inPageReplyContainer.find(Selectors.post.inpageReplyContent).length > 0;\n};\n\n/**\n * Render the template to generate the in page reply form HTML.\n *\n * @param {Object} additionalTemplateContext Additional render context for the in page reply template\n * @param {Object} button jQuery element for the reply button that was clicked\n * @param {Object} postContainer jQuery element for the post container\n * @return {Object} jQuery promise\n */\nconst renderInPageReplyTemplate = (additionalTemplateContext, button, postContainer) => {\n const postContentContainer = getPostContentContainer(postContainer);\n const currentSubject = postContentContainer.find(Selectors.post.forumSubject).text();\n const currentAuthorName = postContentContainer.find(Selectors.post.authorName).text();\n const context = {\n postid: postContainer.data('post-id'),\n \"reply_url\": button.attr('data-href'),\n sesskey: M.cfg.sesskey,\n parentsubject: currentSubject,\n parentauthorname: currentAuthorName,\n canreplyprivately: button.data('can-reply-privately'),\n postformat: InPageReply.CONTENT_FORMATS.MOODLE,\n ...additionalTemplateContext\n };\n\n return Templates.render('mod_forum/inpage_reply_v2', context);\n};\n\n/**\n * Increment the total reply count in the show/hide replies buttons for the post.\n *\n * @param {Object} postContainer jQuery element for the post container\n */\nconst incrementTotalReplyCount = (postContainer) => {\n getRepliesVisibilityToggleContainer(postContainer).find(Selectors.post.replyCount).each((index, element) => {\n const currentCount = parseInt(element.innerText, 10);\n element.innerText = currentCount + 1;\n });\n};\n\n/**\n * Create all of the event listeners for the discussion.\n *\n * @param {Object} root jQuery element for the discussion container\n */\nconst registerEventListeners = (root) => {\n CustomEvents.define(root, [CustomEvents.events.activate]);\n // Auto expanding text area for in page reply.\n AutoRows.init(root);\n\n // Reply button is clicked.\n root.on(CustomEvents.events.activate, Selectors.post.inpageReplyCreateButton, (e, data) => {\n data.originalEvent.preventDefault();\n const postContainer = getPostContainer($(e.currentTarget));\n showInPageReplyForm(postContainer);\n });\n\n // Cancel in page reply button.\n root.on(CustomEvents.events.activate, Selectors.post.inpageReplyCancelButton, (e, data) => {\n data.originalEvent.preventDefault();\n const postContainer = getPostContainer($(e.currentTarget));\n hideInPageReplyForm(postContainer);\n });\n\n // Show replies button clicked.\n root.on(CustomEvents.events.activate, Selectors.post.showReplies, (e, data) => {\n data.originalEvent.preventDefault();\n const postContainer = getPostContainer($(e.target));\n showReplies(postContainer);\n });\n\n // Hide replies button clicked.\n root.on(CustomEvents.events.activate, Selectors.post.hideReplies, (e, data) => {\n data.originalEvent.preventDefault();\n const postContainer = getPostContainer($(e.target));\n hideReplies(postContainer);\n });\n\n // Post created with in page reply.\n root.on(InPageReply.EVENTS.POST_CREATED, Selectors.post.inpageSubmitBtn, (e, newPostId) => {\n const currentTarget = $(e.currentTarget);\n const postContainer = getPostContainer(currentTarget);\n const postContainers = getParentPostContainers(currentTarget);\n hideInPageReplyForm(postContainer, newPostId);\n\n postContainers.each((index, container) => {\n incrementTotalReplyCount($(container));\n });\n });\n};\n\n/**\n * Initialise the javascript for the discussion in nested v2 display mode.\n *\n * @param {Object} root jQuery element for the discussion container\n * @param {Object} context Additional render context for the in page reply template\n */\nexport const init = (root, context) => {\n // Build the showInPageReplyForm function with the additional render context.\n showInPageReplyForm = buildShowInPageReplyFormFunction(context);\n // Add discussion event listeners.\n registerEventListeners(root);\n // Initialise default discussion javascript (keyboard nav etc).\n Discussion.init(root);\n // Add in page reply javascript.\n InPageReply.init(root);\n\n // Initialise the settings menu javascript.\n const discussionToolsContainer = root.find(Selectors.discussion.tools);\n LockToggle.init(discussionToolsContainer, false);\n FavouriteToggle.init(discussionToolsContainer, false, (toggleElement, response) => {\n const newTargetState = response.userstate.favourited ? 0 : 1;\n return toggleElement.data('targetstate', newTargetState);\n });\n Pin.init(discussionToolsContainer, false, (toggleElement, response) => {\n const newTargetState = response.pinned ? 0 : 1;\n return toggleElement.data('targetstate', newTargetState);\n });\n Subscribe.init(discussionToolsContainer, false, (toggleElement, response) => {\n const newTargetState = response.userstate.subscribed ? 0 : 1;\n toggleElement.data('targetstate', newTargetState);\n });\n};\n"],"file":"discussion_nested_v2.min.js"} \ No newline at end of file +{"version":3,"sources":["../src/discussion_nested_v2.js"],"names":["getPostContainer","element","closest","Selectors","post","getPostContainerById","id","find","getParentPostContainers","parents","getPostContentContainer","postContainer","children","not","repliesContainer","forumCoreContent","getInPageReplyContainer","filter","inpageReplyContainer","getInPageReplyForm","inpageReplyContent","getInPageReplyCreateButton","inpageReplyCreateButton","getRepliesVisibilityToggleContainer","repliesVisibilityToggleContainer","getRepliesContainer","hasReplies","length","getShowRepliesButton","replyVisibilityToggleContainer","showReplies","getHideRepliesButton","hideReplies","repliesVisible","is","postIdToSee","showButton","hideButton","addClass","removeClass","slideDown","duration","queue","complete","postContainerToSee","scrollIntoView","css","fadeIn","slideUp","fadeOut","showInPageReplyForm","buildShowInPageReplyFormFunction","additionalTemplateContext","inPageReplyContainer","inPageReplyCreateButton","hasInPageReplyForm","renderInPageReplyTemplate","html","Templates","appendNodeContents","Notification","exception","then","Y","Promise","resolve","use","M","core_formchangechecker","init","formid","one","querySelector","generateID","catch","inPageReplyForm","focus","hideInPageReplyForm","button","postContentContainer","currentSubject","forumSubject","text","currentAuthorName","authorName","context","postid","data","attr","sesskey","cfg","parentsubject","parentauthorname","canreplyprivately","postformat","InPageReply","CONTENT_FORMATS","MOODLE","render","incrementTotalReplyCount","replyCount","each","index","currentCount","parseInt","innerText","registerEventListeners","root","CustomEvents","define","events","activate","AutoRows","on","e","originalEvent","preventDefault","currentTarget","inpageReplyCancelButton","target","EVENTS","POST_CREATED","inpageSubmitBtn","newPostId","postContainers","container","Discussion","discussionToolsContainer","discussion","tools","LockToggle","FavouriteToggle","toggleElement","response","newTargetState","userstate","favourited","Pin","pinned","Subscribe","subscribed"],"mappings":"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","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 .\n\n/**\n * Module for viewing a discussion in nested v2 view.\n *\n * @copyright 2019 Ryan Wyllie \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport $ from 'jquery';\nimport AutoRows from 'core/auto_rows';\nimport CustomEvents from 'core/custom_interaction_events';\nimport Notification from 'core/notification';\nimport Templates from 'core/templates';\nimport Discussion from 'mod_forum/discussion';\nimport InPageReply from 'mod_forum/inpage_reply';\nimport LockToggle from 'mod_forum/lock_toggle';\nimport FavouriteToggle from 'mod_forum/favourite_toggle';\nimport Pin from 'mod_forum/pin_toggle';\nimport Selectors from 'mod_forum/selectors';\nimport Subscribe from 'mod_forum/subscription_toggle';\n\nconst ANIMATION_DURATION = 150;\n\n/**\n * Get the closest post container element from the given element.\n *\n * @param {Object} element jQuery element to search from\n * @return {Object} jQuery element\n */\nconst getPostContainer = (element) => {\n return element.closest(Selectors.post.post);\n};\n\n/**\n * Get the closest post container element from the given element.\n *\n * @param {Object} element jQuery element to search from\n * @param {Number} id Id of the post to find.\n * @return {Object} jQuery element\n */\nconst getPostContainerById = (element, id) => {\n return element.find(`${Selectors.post.post}[data-post-id=${id}]`);\n};\n\n/**\n * Get the parent post container elements from the given element.\n *\n * @param {Object} element jQuery element to search from\n * @return {Object} jQuery element\n */\nconst getParentPostContainers = (element) => {\n return element.parents(Selectors.post.post);\n};\n\n/**\n * Get the post content container element from the post container element.\n *\n * @param {Object} postContainer jQuery element for the post container\n * @return {Object} jQuery element\n */\nconst getPostContentContainer = (postContainer) => {\n return postContainer.children().not(Selectors.post.repliesContainer).find(Selectors.post.forumCoreContent);\n};\n\n/**\n * Get the in page reply container element from the post container element.\n *\n * @param {Object} postContainer jQuery element for the post container\n * @return {Object} jQuery element\n */\nconst getInPageReplyContainer = (postContainer) => {\n return postContainer.children().filter(Selectors.post.inpageReplyContainer);\n};\n\n/**\n * Get the in page reply form element from the post container element.\n *\n * @param {Object} postContainer jQuery element for the post container\n * @return {Object} jQuery element\n */\nconst getInPageReplyForm = (postContainer) => {\n return getInPageReplyContainer(postContainer).find(Selectors.post.inpageReplyContent);\n};\n\n/**\n * Get the in page reply create (reply) button element from the post container element.\n *\n * @param {Object} postContainer jQuery element for the post container\n * @return {Object} jQuery element\n */\nconst getInPageReplyCreateButton = (postContainer) => {\n return getPostContentContainer(postContainer).find(Selectors.post.inpageReplyCreateButton);\n};\n\n/**\n * Get the replies visibility toggle container (show/hide replies button container) element\n * from the post container element.\n *\n * @param {Object} postContainer jQuery element for the post container\n * @return {Object} jQuery element\n */\nconst getRepliesVisibilityToggleContainer = (postContainer) => {\n return postContainer.children(Selectors.post.repliesVisibilityToggleContainer);\n};\n\n/**\n * Get the replies container element from the post container element.\n *\n * @param {Object} postContainer jQuery element for the post container\n * @return {Object} jQuery element\n */\nconst getRepliesContainer = (postContainer) => {\n return postContainer.children(Selectors.post.repliesContainer);\n};\n\n/**\n * Check if the post has any replies.\n *\n * @param {Object} postContainer jQuery element for the post container\n * @return {Bool}\n */\nconst hasReplies = (postContainer) => {\n return getRepliesContainer(postContainer).children().length > 0;\n};\n\n/**\n * Get the show replies button element from the replies visibility toggle container element.\n *\n * @param {Object} replyVisibilityToggleContainer jQuery element for the toggle container\n * @return {Object} jQuery element\n */\nconst getShowRepliesButton = (replyVisibilityToggleContainer) => {\n return replyVisibilityToggleContainer.find(Selectors.post.showReplies);\n};\n\n/**\n * Get the hide replies button element from the replies visibility toggle container element.\n *\n * @param {Object} replyVisibilityToggleContainer jQuery element for the toggle container\n * @return {Object} jQuery element\n */\nconst getHideRepliesButton = (replyVisibilityToggleContainer) => {\n return replyVisibilityToggleContainer.find(Selectors.post.hideReplies);\n};\n\n/**\n * Check if the replies are visible.\n *\n * @param {Object} postContainer jQuery element for the post container\n * @return {Bool}\n */\nconst repliesVisible = (postContainer) => {\n const repliesContainer = getRepliesContainer(postContainer);\n return repliesContainer.is(':visible');\n};\n\n/**\n * Show the post replies.\n *\n * @param {Object} postContainer jQuery element for the post container\n * @param {Number|null} postIdToSee Id of the post to scroll into view (if any)\n */\nconst showReplies = (postContainer, postIdToSee = null) => {\n const repliesContainer = getRepliesContainer(postContainer);\n const replyVisibilityToggleContainer = getRepliesVisibilityToggleContainer(postContainer);\n const showButton = getShowRepliesButton(replyVisibilityToggleContainer);\n const hideButton = getHideRepliesButton(replyVisibilityToggleContainer);\n\n showButton.addClass('hidden');\n hideButton.removeClass('hidden');\n\n repliesContainer.slideDown({\n duration: ANIMATION_DURATION,\n queue: false,\n complete: () => {\n if (postIdToSee) {\n const postContainerToSee = getPostContainerById(repliesContainer, postIdToSee);\n if (postContainerToSee.length) {\n postContainerToSee[0].scrollIntoView();\n }\n }\n }\n }).css('display', 'none').fadeIn(ANIMATION_DURATION);\n};\n\n/**\n * Hide the post replies.\n *\n * @param {Object} postContainer jQuery element for the post container\n */\nconst hideReplies = (postContainer) => {\n const repliesContainer = getRepliesContainer(postContainer);\n const replyVisibilityToggleContainer = getRepliesVisibilityToggleContainer(postContainer);\n const showButton = getShowRepliesButton(replyVisibilityToggleContainer);\n const hideButton = getHideRepliesButton(replyVisibilityToggleContainer);\n\n showButton.removeClass('hidden');\n hideButton.addClass('hidden');\n\n repliesContainer.slideUp({\n duration: ANIMATION_DURATION,\n queue: false\n }).fadeOut(ANIMATION_DURATION);\n};\n\n/** Variable to hold the showInPageReplyForm function after it's built. */\nlet showInPageReplyForm = null;\n\n/**\n * Build the showInPageReplyForm function with the given additional template context.\n *\n * @param {Object} additionalTemplateContext Additional render context for the in page reply template.\n * @return {Function}\n */\nconst buildShowInPageReplyFormFunction = (additionalTemplateContext) => {\n /**\n * Show the in page reply form in the given in page reply container. The form\n * display will be animated.\n *\n * @param {Object} postContainer jQuery element for the post container\n */\n return async (postContainer) => {\n\n const inPageReplyContainer = getInPageReplyContainer(postContainer);\n const repliesVisibilityToggleContainer = getRepliesVisibilityToggleContainer(postContainer);\n const inPageReplyCreateButton = getInPageReplyCreateButton(postContainer);\n\n if (!hasInPageReplyForm(inPageReplyContainer)) {\n try {\n const html = await renderInPageReplyTemplate(additionalTemplateContext, inPageReplyCreateButton, postContainer);\n Templates.appendNodeContents(inPageReplyContainer, html, '');\n } catch (e) {\n Notification.exception(e);\n }\n\n // Load formchangechecker module.\n import('core/yui')\n .then(Y => {\n return new Promise(resolve => {\n Y.use('moodle-core-formchangechecker', Y => {\n resolve(Y);\n });\n });\n })\n .then(Y => {\n M.core_formchangechecker.init({formid: Y.one(postContainer[0].querySelector('form')).generateID()});\n return Y;\n })\n .catch();\n }\n\n inPageReplyCreateButton.fadeOut(ANIMATION_DURATION, () => {\n const inPageReplyForm = getInPageReplyForm(postContainer);\n inPageReplyForm.slideDown({\n duration: ANIMATION_DURATION,\n queue: false,\n complete: () => {\n inPageReplyForm.find('textarea').focus();\n }\n }).css('display', 'none').fadeIn(ANIMATION_DURATION);\n\n if (repliesVisibilityToggleContainer.length && hasReplies(postContainer)) {\n repliesVisibilityToggleContainer.fadeIn(ANIMATION_DURATION);\n hideReplies(postContainer);\n }\n });\n };\n};\n\n/**\n * Hide the in page reply form in the given in page reply container. The form\n * display will be animated.\n *\n * @param {Object} postContainer jQuery element for the post container\n * @param {Number|null} postIdToSee Id of the post to scroll into view (if any)\n */\nconst hideInPageReplyForm = (postContainer, postIdToSee = null) => {\n const inPageReplyForm = getInPageReplyForm(postContainer);\n const inPageReplyCreateButton = getInPageReplyCreateButton(postContainer);\n const repliesVisibilityToggleContainer = getRepliesVisibilityToggleContainer(postContainer);\n\n if (repliesVisibilityToggleContainer.length && hasReplies(postContainer)) {\n repliesVisibilityToggleContainer.fadeOut(ANIMATION_DURATION);\n if (!repliesVisible(postContainer)) {\n showReplies(postContainer, postIdToSee);\n }\n }\n\n inPageReplyForm.slideUp({\n duration: ANIMATION_DURATION,\n queue: false,\n complete: () => {\n inPageReplyCreateButton.fadeIn(ANIMATION_DURATION);\n }\n }).fadeOut(200);\n};\n\n/**\n * Check if the in page reply container contains the in page reply form.\n *\n * @param {Object} inPageReplyContainer jQuery element for the in page reply container\n * @return {Bool}\n */\nconst hasInPageReplyForm = (inPageReplyContainer) => {\n return inPageReplyContainer.find(Selectors.post.inpageReplyContent).length > 0;\n};\n\n/**\n * Render the template to generate the in page reply form HTML.\n *\n * @param {Object} additionalTemplateContext Additional render context for the in page reply template\n * @param {Object} button jQuery element for the reply button that was clicked\n * @param {Object} postContainer jQuery element for the post container\n * @return {Object} jQuery promise\n */\nconst renderInPageReplyTemplate = (additionalTemplateContext, button, postContainer) => {\n const postContentContainer = getPostContentContainer(postContainer);\n const currentSubject = postContentContainer.find(Selectors.post.forumSubject).text();\n const currentAuthorName = postContentContainer.find(Selectors.post.authorName).text();\n const context = {\n postid: postContainer.data('post-id'),\n \"reply_url\": button.attr('data-href'),\n sesskey: M.cfg.sesskey,\n parentsubject: currentSubject,\n parentauthorname: currentAuthorName,\n canreplyprivately: button.data('can-reply-privately'),\n postformat: InPageReply.CONTENT_FORMATS.MOODLE,\n ...additionalTemplateContext\n };\n\n return Templates.render('mod_forum/inpage_reply_v2', context);\n};\n\n/**\n * Increment the total reply count in the show/hide replies buttons for the post.\n *\n * @param {Object} postContainer jQuery element for the post container\n */\nconst incrementTotalReplyCount = (postContainer) => {\n getRepliesVisibilityToggleContainer(postContainer).find(Selectors.post.replyCount).each((index, element) => {\n const currentCount = parseInt(element.innerText, 10);\n element.innerText = currentCount + 1;\n });\n};\n\n/**\n * Create all of the event listeners for the discussion.\n *\n * @param {Object} root jQuery element for the discussion container\n */\nconst registerEventListeners = (root) => {\n CustomEvents.define(root, [CustomEvents.events.activate]);\n // Auto expanding text area for in page reply.\n AutoRows.init(root);\n\n // Reply button is clicked.\n root.on(CustomEvents.events.activate, Selectors.post.inpageReplyCreateButton, (e, data) => {\n data.originalEvent.preventDefault();\n const postContainer = getPostContainer($(e.currentTarget));\n showInPageReplyForm(postContainer);\n });\n\n // Cancel in page reply button.\n root.on(CustomEvents.events.activate, Selectors.post.inpageReplyCancelButton, (e, data) => {\n data.originalEvent.preventDefault();\n const postContainer = getPostContainer($(e.currentTarget));\n hideInPageReplyForm(postContainer);\n });\n\n // Show replies button clicked.\n root.on(CustomEvents.events.activate, Selectors.post.showReplies, (e, data) => {\n data.originalEvent.preventDefault();\n const postContainer = getPostContainer($(e.target));\n showReplies(postContainer);\n });\n\n // Hide replies button clicked.\n root.on(CustomEvents.events.activate, Selectors.post.hideReplies, (e, data) => {\n data.originalEvent.preventDefault();\n const postContainer = getPostContainer($(e.target));\n hideReplies(postContainer);\n });\n\n // Post created with in page reply.\n root.on(InPageReply.EVENTS.POST_CREATED, Selectors.post.inpageSubmitBtn, (e, newPostId) => {\n const currentTarget = $(e.currentTarget);\n const postContainer = getPostContainer(currentTarget);\n const postContainers = getParentPostContainers(currentTarget);\n hideInPageReplyForm(postContainer, newPostId);\n\n postContainers.each((index, container) => {\n incrementTotalReplyCount($(container));\n });\n });\n};\n\n/**\n * Initialise the javascript for the discussion in nested v2 display mode.\n *\n * @param {Object} root jQuery element for the discussion container\n * @param {Object} context Additional render context for the in page reply template\n */\nexport const init = (root, context) => {\n // Build the showInPageReplyForm function with the additional render context.\n showInPageReplyForm = buildShowInPageReplyFormFunction(context);\n // Add discussion event listeners.\n registerEventListeners(root);\n // Initialise default discussion javascript (keyboard nav etc).\n Discussion.init(root);\n // Add in page reply javascript.\n InPageReply.init(root);\n\n // Initialise the settings menu javascript.\n const discussionToolsContainer = root.find(Selectors.discussion.tools);\n LockToggle.init(discussionToolsContainer, false);\n FavouriteToggle.init(discussionToolsContainer, false, (toggleElement, response) => {\n const newTargetState = response.userstate.favourited ? 0 : 1;\n return toggleElement.data('targetstate', newTargetState);\n });\n Pin.init(discussionToolsContainer, false, (toggleElement, response) => {\n const newTargetState = response.pinned ? 0 : 1;\n return toggleElement.data('targetstate', newTargetState);\n });\n Subscribe.init(discussionToolsContainer, false, (toggleElement, response) => {\n const newTargetState = response.userstate.subscribed ? 0 : 1;\n toggleElement.data('targetstate', newTargetState);\n });\n};\n"],"file":"discussion_nested_v2.min.js"} \ No newline at end of file diff --git a/mod/forum/amd/build/inpage_reply.min.js b/mod/forum/amd/build/inpage_reply.min.js index 7a3bc75c653..997e1c3957f 100644 --- a/mod/forum/amd/build/inpage_reply.min.js +++ b/mod/forum/amd/build/inpage_reply.min.js @@ -1,2 +1,2 @@ -define ("mod_forum/inpage_reply",["jquery","core/templates","core/notification","mod_forum/repository","mod_forum/selectors"],function(a,b,c,d,f){var g={NESTED_V2:4,THREADED:2,NESTED:3,FLAT_OLDEST_FIRST:1,FLAT_NEWEST_FIRST:-1},h={POST_CREATED:"mod_forum-post-created"},i={MOODLE:0},j=function(a){var b=a.find(f.post.inpageSubmitBtnText),c=a.find(f.post.loadingIconContainer),d=a.outerWidth();a.css("width",d);b.addClass("hidden");c.removeClass("hidden")},k=function(a){var b=a.find(f.post.inpageSubmitBtnText),c=a.find(f.post.loadingIconContainer);a.css("width","");b.removeClass("hidden");c.addClass("hidden")},l=function(l){l.on("click",f.post.inpageSubmitBtn,function(m){m.preventDefault();var e=a(m.currentTarget),n=e.parent().find(f.post.inpageReplyButton),o=e.parents(f.post.inpageReplyForm).get(0),p=o.elements.post.value.trim(),q=i.MOODLE,r=o.elements.reply.value,s=o.elements.subject.value,t=e.closest(f.post.post),u=o.elements.privatereply!=void 0?o.elements.privatereply.checked:!1,v=l.find(f.post.modeSelect),w=v.length?parseInt(v.get(0).value):null,x;if(p.length){j(e);n.prop("disabled",!0);d.addDiscussionPost(r,s,p,q,u,!0).then(function(a){var b=a.messages.reduce(function(a,b){if("success"==b.type){a+="

"+b.message+"

"}return a},"");c.addNotification({message:b,type:"success"});return a}).then(function(a){o.reset();var c=a.post;x=c.id;switch(w){case g.NESTED_V2:var d=c.capabilities,e=t.children().not(f.post.repliesContainer).find(f.post.authorName).text();c.parentauthorname=e;c.showactionmenu=d.view||d.controlreadstatus||d.edit||d.split||d.delete||d.export||c.urls.viewparent;return b.render("mod_forum/forum_discussion_nested_v2_post_reply",c);case g.THREADED:return b.render("mod_forum/forum_discussion_threaded_post",c);case g.NESTED:return b.render("mod_forum/forum_discussion_nested_post",c);default:return b.render("mod_forum/forum_discussion_post",c);}}).then(function(a,c){var d=t.find(f.post.repliesContainer).first();if(w==g.FLAT_NEWEST_FIRST){return b.prependNodeContents(d,a,c)}else{return b.appendNodeContents(d,a,c)}}).then(function(){e.trigger(h.POST_CREATED,x);k(e);n.prop("disabled",!1);return t.find(f.post.inpageReplyContent).hide()}).then(function(){location.href="#p"+x}).catch(function(a){k(e);n.prop("disabled",!1);return c.exception(a)})}})};return{init:function init(a){l(a)},CONTENT_FORMATS:i,EVENTS:h}}); +define ("mod_forum/inpage_reply",["jquery","core/templates","core/notification","mod_forum/repository","mod_forum/selectors"],function(a,b,c,d,f){var g={NESTED_V2:4,THREADED:2,NESTED:3,FLAT_OLDEST_FIRST:1,FLAT_NEWEST_FIRST:-1},h={POST_CREATED:"mod_forum-post-created"},i={MOODLE:0},j=function(a){var b=a.find(f.post.inpageSubmitBtnText),c=a.find(f.post.loadingIconContainer),d=a.outerWidth();a.css("width",d);b.addClass("hidden");c.removeClass("hidden")},k=function(a){var b=a.find(f.post.inpageSubmitBtnText),c=a.find(f.post.loadingIconContainer);a.css("width","");b.removeClass("hidden");c.addClass("hidden")},l=function(l){l.on("click",f.post.inpageSubmitBtn,function(m){m.preventDefault();var e=a(m.currentTarget),n=e.parent().find(f.post.inpageReplyButton),o=e.parents(f.post.inpageReplyForm).get(0),p=o.elements.post.value.trim(),q=i.MOODLE,r=o.elements.reply.value,s=o.elements.subject.value,t=e.closest(f.post.post),u=o.elements.privatereply!=void 0?o.elements.privatereply.checked:!1,v=l.find(f.post.modeSelect),w=v.length?parseInt(v.get(0).value):null,x;if(p.length){j(e);n.prop("disabled",!0);d.addDiscussionPost(r,s,p,q,u,!0).then(function(a){var b=a.messages.reduce(function(a,b){if("success"==b.type){a+="

"+b.message+"

"}return a},"");c.addNotification({message:b,type:"success"});return a}).then(function(a){o.reset();var c=a.post;x=c.id;switch(w){case g.NESTED_V2:var d=c.capabilities,e=t.children().not(f.post.repliesContainer).find(f.post.authorName).text();c.parentauthorname=e;c.showactionmenu=d.view||d.controlreadstatus||d.edit||d.split||d.delete||d.export||c.urls.viewparent;return b.render("mod_forum/forum_discussion_nested_v2_post_reply",c);case g.THREADED:return b.render("mod_forum/forum_discussion_threaded_post",c);case g.NESTED:return b.render("mod_forum/forum_discussion_nested_post",c);default:return b.render("mod_forum/forum_discussion_post",c);}}).then(function(a,c){var d=t.find(f.post.repliesContainer).first();if(w==g.FLAT_NEWEST_FIRST){return b.prependNodeContents(d,a,c)}else{return b.appendNodeContents(d,a,c)}}).then(function(){e.trigger(h.POST_CREATED,x);k(e);n.prop("disabled",!1);if("undefined"!=typeof M.core_formchangechecker){M.core_formchangechecker.reset_form_dirty_state()}return t.find(f.post.inpageReplyContent).hide()}).then(function(){location.href="#p"+x}).catch(function(a){k(e);n.prop("disabled",!1);return c.exception(a)})}})};return{init:function init(a){l(a)},CONTENT_FORMATS:i,EVENTS:h}}); //# sourceMappingURL=inpage_reply.min.js.map diff --git a/mod/forum/amd/build/inpage_reply.min.js.map b/mod/forum/amd/build/inpage_reply.min.js.map index 81728888911..8dd41f9ad25 100644 --- a/mod/forum/amd/build/inpage_reply.min.js.map +++ b/mod/forum/amd/build/inpage_reply.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["../src/inpage_reply.js"],"names":["define","$","Templates","Notification","Repository","Selectors","DISPLAYCONSTANTS","NESTED_V2","THREADED","NESTED","FLAT_OLDEST_FIRST","FLAT_NEWEST_FIRST","EVENTS","POST_CREATED","CONTENT_FORMATS","MOODLE","showSubmitButtonLoadingIcon","button","textContainer","find","post","inpageSubmitBtnText","loadingIconContainer","width","outerWidth","css","addClass","removeClass","hideSubmitButtonLoadingIcon","registerEventListeners","root","on","inpageSubmitBtn","e","preventDefault","submitButton","currentTarget","allButtons","parent","inpageReplyButton","form","parents","inpageReplyForm","get","message","elements","value","trim","messageformat","postid","reply","subject","currentRoot","closest","isprivatereply","privatereply","checked","modeSelector","modeSelect","mode","length","parseInt","newid","prop","addDiscussionPost","then","context","messages","reduce","carry","type","addNotification","reset","id","capabilities","currentAuthorName","children","not","repliesContainer","authorName","text","parentauthorname","showactionmenu","view","controlreadstatus","edit","split","delete","export","urls","viewparent","render","html","js","repliesnode","first","prependNodeContents","appendNodeContents","trigger","inpageReplyContent","hide","location","href","catch","error","exception","init"],"mappings":"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","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 .\n\n/**\n * This module handles the in page replying to forum posts.\n *\n * @module mod_forum/inpage_reply\n * @package mod_forum\n * @copyright 2019 Peter Dias\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n 'jquery',\n 'core/templates',\n 'core/notification',\n 'mod_forum/repository',\n 'mod_forum/selectors',\n ], function(\n $,\n Templates,\n Notification,\n Repository,\n Selectors\n ) {\n\n var DISPLAYCONSTANTS = {\n NESTED_V2: 4,\n THREADED: 2,\n NESTED: 3,\n FLAT_OLDEST_FIRST: 1,\n FLAT_NEWEST_FIRST: -1\n };\n\n var EVENTS = {\n POST_CREATED: 'mod_forum-post-created'\n };\n\n /**\n * Moodle formats taken from the FORMAT_* constants declared in lib/weblib.php.\n * @type {Object}\n */\n var CONTENT_FORMATS = {\n MOODLE: 0\n };\n /**\n * Show the loading icon for the submit button.\n *\n * @param {Object} button The submit button element\n */\n var showSubmitButtonLoadingIcon = function(button) {\n var textContainer = button.find(Selectors.post.inpageSubmitBtnText);\n var loadingIconContainer = button.find(Selectors.post.loadingIconContainer);\n var width = button.outerWidth();\n // Fix the width so that the button size doesn't change when we show the loading icon.\n button.css('width', width);\n textContainer.addClass('hidden');\n loadingIconContainer.removeClass('hidden');\n };\n\n /**\n * Hide the loading icon for the submit button.\n *\n * @param {Object} button The submit button element\n */\n var hideSubmitButtonLoadingIcon = function(button) {\n var textContainer = button.find(Selectors.post.inpageSubmitBtnText);\n var loadingIconContainer = button.find(Selectors.post.loadingIconContainer);\n // Reset the width back to it's default.\n button.css('width', '');\n textContainer.removeClass('hidden');\n loadingIconContainer.addClass('hidden');\n };\n\n /**\n * Register the event listeners for the submit button of the in page reply.\n *\n * @param {Object} root The discussion container element.\n */\n var registerEventListeners = function(root) {\n root.on('click', Selectors.post.inpageSubmitBtn, function(e) {\n e.preventDefault();\n var submitButton = $(e.currentTarget);\n var allButtons = submitButton.parent().find(Selectors.post.inpageReplyButton);\n var form = submitButton.parents(Selectors.post.inpageReplyForm).get(0);\n var message = form.elements.post.value.trim();\n // For now, we consider the inline reply post written using the FORMAT_MOODLE (because a textarea is displayed).\n // In the future, other formats should be supported, letting users to use their preferred editor and format.\n var messageformat = CONTENT_FORMATS.MOODLE;\n // The message post will be converted from messageformat to FORMAT_HTML.\n var topreferredformat = true;\n var postid = form.elements.reply.value;\n var subject = form.elements.subject.value;\n var currentRoot = submitButton.closest(Selectors.post.post);\n var isprivatereply = form.elements.privatereply != undefined ? form.elements.privatereply.checked : false;\n var modeSelector = root.find(Selectors.post.modeSelect);\n var mode = modeSelector.length ? parseInt(modeSelector.get(0).value) : null;\n var newid;\n\n if (message.length) {\n showSubmitButtonLoadingIcon(submitButton);\n allButtons.prop('disabled', true);\n\n Repository.addDiscussionPost(postid, subject, message, messageformat, isprivatereply, topreferredformat)\n .then(function(context) {\n var message = context.messages.reduce(function(carry, message) {\n if (message.type == 'success') {\n carry += '

' + message.message + '

';\n }\n return carry;\n }, '');\n Notification.addNotification({\n message: message,\n type: \"success\"\n });\n\n return context;\n })\n .then(function(context) {\n form.reset();\n var post = context.post;\n newid = post.id;\n\n switch (mode) {\n case DISPLAYCONSTANTS.NESTED_V2:\n var capabilities = post.capabilities;\n var currentAuthorName = currentRoot.children()\n .not(Selectors.post.repliesContainer)\n .find(Selectors.post.authorName)\n .text();\n post.parentauthorname = currentAuthorName;\n post.showactionmenu = capabilities.view ||\n capabilities.controlreadstatus ||\n capabilities.edit ||\n capabilities.split ||\n capabilities.delete ||\n capabilities.export ||\n post.urls.viewparent;\n return Templates.render('mod_forum/forum_discussion_nested_v2_post_reply', post);\n case DISPLAYCONSTANTS.THREADED:\n return Templates.render('mod_forum/forum_discussion_threaded_post', post);\n case DISPLAYCONSTANTS.NESTED:\n return Templates.render('mod_forum/forum_discussion_nested_post', post);\n default:\n return Templates.render('mod_forum/forum_discussion_post', post);\n }\n })\n .then(function(html, js) {\n var repliesnode = currentRoot.find(Selectors.post.repliesContainer).first();\n\n if (mode == DISPLAYCONSTANTS.FLAT_NEWEST_FIRST) {\n return Templates.prependNodeContents(repliesnode, html, js);\n } else {\n return Templates.appendNodeContents(repliesnode, html, js);\n }\n })\n .then(function() {\n submitButton.trigger(EVENTS.POST_CREATED, newid);\n hideSubmitButtonLoadingIcon(submitButton);\n allButtons.prop('disabled', false);\n return currentRoot.find(Selectors.post.inpageReplyContent).hide();\n })\n .then(function() {\n location.href = \"#p\" + newid;\n return;\n })\n .catch(function(error) {\n hideSubmitButtonLoadingIcon(submitButton);\n allButtons.prop('disabled', false);\n return Notification.exception(error);\n });\n }\n });\n };\n\n return {\n init: function(root) {\n registerEventListeners(root);\n },\n CONTENT_FORMATS: CONTENT_FORMATS,\n EVENTS: EVENTS\n };\n});\n"],"file":"inpage_reply.min.js"} \ No newline at end of file +{"version":3,"sources":["../src/inpage_reply.js"],"names":["define","$","Templates","Notification","Repository","Selectors","DISPLAYCONSTANTS","NESTED_V2","THREADED","NESTED","FLAT_OLDEST_FIRST","FLAT_NEWEST_FIRST","EVENTS","POST_CREATED","CONTENT_FORMATS","MOODLE","showSubmitButtonLoadingIcon","button","textContainer","find","post","inpageSubmitBtnText","loadingIconContainer","width","outerWidth","css","addClass","removeClass","hideSubmitButtonLoadingIcon","registerEventListeners","root","on","inpageSubmitBtn","e","preventDefault","submitButton","currentTarget","allButtons","parent","inpageReplyButton","form","parents","inpageReplyForm","get","message","elements","value","trim","messageformat","postid","reply","subject","currentRoot","closest","isprivatereply","privatereply","checked","modeSelector","modeSelect","mode","length","parseInt","newid","prop","addDiscussionPost","then","context","messages","reduce","carry","type","addNotification","reset","id","capabilities","currentAuthorName","children","not","repliesContainer","authorName","text","parentauthorname","showactionmenu","view","controlreadstatus","edit","split","delete","export","urls","viewparent","render","html","js","repliesnode","first","prependNodeContents","appendNodeContents","trigger","M","core_formchangechecker","reset_form_dirty_state","inpageReplyContent","hide","location","href","catch","error","exception","init"],"mappings":"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","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 .\n\n/**\n * This module handles the in page replying to forum posts.\n *\n * @module mod_forum/inpage_reply\n * @package mod_forum\n * @copyright 2019 Peter Dias\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n 'jquery',\n 'core/templates',\n 'core/notification',\n 'mod_forum/repository',\n 'mod_forum/selectors',\n ], function(\n $,\n Templates,\n Notification,\n Repository,\n Selectors\n ) {\n\n var DISPLAYCONSTANTS = {\n NESTED_V2: 4,\n THREADED: 2,\n NESTED: 3,\n FLAT_OLDEST_FIRST: 1,\n FLAT_NEWEST_FIRST: -1\n };\n\n var EVENTS = {\n POST_CREATED: 'mod_forum-post-created'\n };\n\n /**\n * Moodle formats taken from the FORMAT_* constants declared in lib/weblib.php.\n * @type {Object}\n */\n var CONTENT_FORMATS = {\n MOODLE: 0\n };\n /**\n * Show the loading icon for the submit button.\n *\n * @param {Object} button The submit button element\n */\n var showSubmitButtonLoadingIcon = function(button) {\n var textContainer = button.find(Selectors.post.inpageSubmitBtnText);\n var loadingIconContainer = button.find(Selectors.post.loadingIconContainer);\n var width = button.outerWidth();\n // Fix the width so that the button size doesn't change when we show the loading icon.\n button.css('width', width);\n textContainer.addClass('hidden');\n loadingIconContainer.removeClass('hidden');\n };\n\n /**\n * Hide the loading icon for the submit button.\n *\n * @param {Object} button The submit button element\n */\n var hideSubmitButtonLoadingIcon = function(button) {\n var textContainer = button.find(Selectors.post.inpageSubmitBtnText);\n var loadingIconContainer = button.find(Selectors.post.loadingIconContainer);\n // Reset the width back to it's default.\n button.css('width', '');\n textContainer.removeClass('hidden');\n loadingIconContainer.addClass('hidden');\n };\n\n /**\n * Register the event listeners for the submit button of the in page reply.\n *\n * @param {Object} root The discussion container element.\n */\n var registerEventListeners = function(root) {\n root.on('click', Selectors.post.inpageSubmitBtn, function(e) {\n e.preventDefault();\n var submitButton = $(e.currentTarget);\n var allButtons = submitButton.parent().find(Selectors.post.inpageReplyButton);\n var form = submitButton.parents(Selectors.post.inpageReplyForm).get(0);\n var message = form.elements.post.value.trim();\n // For now, we consider the inline reply post written using the FORMAT_MOODLE (because a textarea is displayed).\n // In the future, other formats should be supported, letting users to use their preferred editor and format.\n var messageformat = CONTENT_FORMATS.MOODLE;\n // The message post will be converted from messageformat to FORMAT_HTML.\n var topreferredformat = true;\n var postid = form.elements.reply.value;\n var subject = form.elements.subject.value;\n var currentRoot = submitButton.closest(Selectors.post.post);\n var isprivatereply = form.elements.privatereply != undefined ? form.elements.privatereply.checked : false;\n var modeSelector = root.find(Selectors.post.modeSelect);\n var mode = modeSelector.length ? parseInt(modeSelector.get(0).value) : null;\n var newid;\n\n if (message.length) {\n showSubmitButtonLoadingIcon(submitButton);\n allButtons.prop('disabled', true);\n\n Repository.addDiscussionPost(postid, subject, message, messageformat, isprivatereply, topreferredformat)\n .then(function(context) {\n var message = context.messages.reduce(function(carry, message) {\n if (message.type == 'success') {\n carry += '

' + message.message + '

';\n }\n return carry;\n }, '');\n Notification.addNotification({\n message: message,\n type: \"success\"\n });\n\n return context;\n })\n .then(function(context) {\n form.reset();\n var post = context.post;\n newid = post.id;\n\n switch (mode) {\n case DISPLAYCONSTANTS.NESTED_V2:\n var capabilities = post.capabilities;\n var currentAuthorName = currentRoot.children()\n .not(Selectors.post.repliesContainer)\n .find(Selectors.post.authorName)\n .text();\n post.parentauthorname = currentAuthorName;\n post.showactionmenu = capabilities.view ||\n capabilities.controlreadstatus ||\n capabilities.edit ||\n capabilities.split ||\n capabilities.delete ||\n capabilities.export ||\n post.urls.viewparent;\n return Templates.render('mod_forum/forum_discussion_nested_v2_post_reply', post);\n case DISPLAYCONSTANTS.THREADED:\n return Templates.render('mod_forum/forum_discussion_threaded_post', post);\n case DISPLAYCONSTANTS.NESTED:\n return Templates.render('mod_forum/forum_discussion_nested_post', post);\n default:\n return Templates.render('mod_forum/forum_discussion_post', post);\n }\n })\n .then(function(html, js) {\n var repliesnode = currentRoot.find(Selectors.post.repliesContainer).first();\n\n if (mode == DISPLAYCONSTANTS.FLAT_NEWEST_FIRST) {\n return Templates.prependNodeContents(repliesnode, html, js);\n } else {\n return Templates.appendNodeContents(repliesnode, html, js);\n }\n })\n .then(function() {\n submitButton.trigger(EVENTS.POST_CREATED, newid);\n hideSubmitButtonLoadingIcon(submitButton);\n allButtons.prop('disabled', false);\n\n // Tell formchangechecker we submitted the form.\n if (typeof M.core_formchangechecker !== 'undefined') {\n M.core_formchangechecker.reset_form_dirty_state();\n }\n\n return currentRoot.find(Selectors.post.inpageReplyContent).hide();\n })\n .then(function() {\n location.href = \"#p\" + newid;\n return;\n })\n .catch(function(error) {\n hideSubmitButtonLoadingIcon(submitButton);\n allButtons.prop('disabled', false);\n return Notification.exception(error);\n });\n }\n });\n };\n\n return {\n init: function(root) {\n registerEventListeners(root);\n },\n CONTENT_FORMATS: CONTENT_FORMATS,\n EVENTS: EVENTS\n };\n});\n"],"file":"inpage_reply.min.js"} \ No newline at end of file diff --git a/mod/forum/amd/build/posts_list.min.js b/mod/forum/amd/build/posts_list.min.js index 12d10bbcf57..b8bb0af33c6 100644 --- a/mod/forum/amd/build/posts_list.min.js +++ b/mod/forum/amd/build/posts_list.min.js @@ -1,2 +1,2 @@ -define ("mod_forum/posts_list",["jquery","core/templates","core/notification","core/pending","mod_forum/selectors","mod_forum/inpage_reply"],function(a,b,c,d,f,g){var h=function(e){e.on("click",f.post.inpageReplyLink,function(h){h.preventDefault();if(window.location.hash){var e=window.location.href.split("#")[0];history.pushState({},document.title,e)}var i=new d("inpage-reply"),j=a(h.currentTarget).parents(f.post.forumCoreContent),k=j.find(f.post.forumSubject),l=a(h.currentTarget).parents(f.post.forumContent),m={postid:a(l).data("post-id"),reply_url:a(h.currentTarget).attr("href"),sesskey:M.cfg.sesskey,parentsubject:k.data("replySubject"),canreplyprivately:a(h.currentTarget).data("can-reply-privately"),postformat:g.CONTENT_FORMATS.MOODLE};if(!l.find(f.post.inpageReplyContent).length){b.render("mod_forum/inpage_reply",m).then(function(a,c){return b.appendNodeContents(j,a,c)}).then(function(){return l.find(f.post.inpageReplyContent).slideToggle(300,i.resolve).find("textarea").focus()}).fail(c.exception)}else{var n=l.find(f.post.inpageReplyContent);n.slideToggle(300,i.resolve);if(n.is(":visible")){n.find("textarea").focus()}}})};return{init:function init(a){h(a);g.init(a)}}}); +define ("mod_forum/posts_list",["jquery","core/templates","core/notification","core/pending","core/yui","mod_forum/selectors","mod_forum/inpage_reply"],function(a,b,c,d,e,f,g){var h=function(h){h.on("click",f.post.inpageReplyLink,function(h){h.preventDefault();if(window.location.hash){var i=window.location.href.split("#")[0];history.pushState({},document.title,i)}var j=new d("inpage-reply"),k=a(h.currentTarget).parents(f.post.forumCoreContent),l=k.find(f.post.forumSubject),m=a(h.currentTarget).parents(f.post.forumContent),n={postid:a(m).data("post-id"),reply_url:a(h.currentTarget).attr("href"),sesskey:M.cfg.sesskey,parentsubject:l.data("replySubject"),canreplyprivately:a(h.currentTarget).data("can-reply-privately"),postformat:g.CONTENT_FORMATS.MOODLE};if(!m.find(f.post.inpageReplyContent).length){b.render("mod_forum/inpage_reply",n).then(function(a,c){return b.appendNodeContents(k,a,c)}).then(function(){return m.find(f.post.inpageReplyContent).slideToggle(300,j.resolve).find("textarea").focus()}).then(function(){e.use("moodle-core-formchangechecker",function(){M.core_formchangechecker.init({formid:"inpage-reply-".concat(n.postid)})})}).fail(c.exception)}else{var o=m.find(f.post.inpageReplyContent);o.slideToggle(300,j.resolve);if(o.is(":visible")){o.find("textarea").focus()}}})};return{init:function init(a){h(a);g.init(a)}}}); //# sourceMappingURL=posts_list.min.js.map diff --git a/mod/forum/amd/build/posts_list.min.js.map b/mod/forum/amd/build/posts_list.min.js.map index 0423c5e42c5..a9833fff278 100644 --- a/mod/forum/amd/build/posts_list.min.js.map +++ b/mod/forum/amd/build/posts_list.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["../src/posts_list.js"],"names":["define","$","Templates","Notification","Pending","Selectors","InPageReply","registerEventListeners","root","on","post","inpageReplyLink","e","preventDefault","window","location","hash","url","href","split","history","pushState","document","title","pending","currentTarget","parents","forumCoreContent","currentSubject","find","forumSubject","currentRoot","forumContent","context","postid","data","attr","sesskey","M","cfg","parentsubject","canreplyprivately","postformat","CONTENT_FORMATS","MOODLE","inpageReplyContent","length","render","then","html","js","appendNodeContents","slideToggle","resolve","focus","fail","exception","form","is","init"],"mappings":"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","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 .\n\n/**\n * This module is the highest level module for the calendar. It is\n * responsible for initialising all of the components required for\n * the calendar to run. It also coordinates the interaction between\n * components by listening for and responding to different events\n * triggered within the calendar UI.\n *\n * @module mod_forum/posts_list\n * @package mod_forum\n * @copyright 2019 Peter Dias\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n 'jquery',\n 'core/templates',\n 'core/notification',\n 'core/pending',\n 'mod_forum/selectors',\n 'mod_forum/inpage_reply',\n ], function(\n $,\n Templates,\n Notification,\n Pending,\n Selectors,\n InPageReply\n ) {\n\n var registerEventListeners = function(root) {\n root.on('click', Selectors.post.inpageReplyLink, function(e) {\n e.preventDefault();\n // After adding a reply a url hash is being generated that scrolls (points) to the newly added reply.\n // The hash being present causes this scrolling behavior to the particular reply to persists even when\n // another, non-related in-page replay link is being clicked which ultimately causes a bad user experience.\n // A particular solution for this problem would be changing the browser's history state when a url hash is\n // present.\n if (window.location.hash) {\n // Remove the fragment identifier from the url.\n var url = window.location.href.split('#')[0];\n history.pushState({}, document.title, url);\n }\n var pending = new Pending('inpage-reply');\n var currentTarget = $(e.currentTarget).parents(Selectors.post.forumCoreContent);\n var currentSubject = currentTarget.find(Selectors.post.forumSubject);\n var currentRoot = $(e.currentTarget).parents(Selectors.post.forumContent);\n var context = {\n postid: $(currentRoot).data('post-id'),\n \"reply_url\": $(e.currentTarget).attr('href'),\n sesskey: M.cfg.sesskey,\n parentsubject: currentSubject.data('replySubject'),\n canreplyprivately: $(e.currentTarget).data('can-reply-privately'),\n postformat: InPageReply.CONTENT_FORMATS.MOODLE\n };\n\n if (!currentRoot.find(Selectors.post.inpageReplyContent).length) {\n Templates.render('mod_forum/inpage_reply', context)\n .then(function(html, js) {\n return Templates.appendNodeContents(currentTarget, html, js);\n })\n .then(function() {\n return currentRoot.find(Selectors.post.inpageReplyContent)\n .slideToggle(300, pending.resolve).find('textarea').focus();\n })\n .fail(Notification.exception);\n } else {\n var form = currentRoot.find(Selectors.post.inpageReplyContent);\n form.slideToggle(300, pending.resolve);\n if (form.is(':visible')) {\n form.find('textarea').focus();\n }\n }\n });\n };\n\n return {\n init: function(root) {\n registerEventListeners(root);\n InPageReply.init(root);\n }\n };\n});\n"],"file":"posts_list.min.js"} \ No newline at end of file +{"version":3,"sources":["../src/posts_list.js"],"names":["define","$","Templates","Notification","Pending","Y","Selectors","InPageReply","registerEventListeners","root","on","post","inpageReplyLink","e","preventDefault","window","location","hash","url","href","split","history","pushState","document","title","pending","currentTarget","parents","forumCoreContent","currentSubject","find","forumSubject","currentRoot","forumContent","context","postid","data","attr","sesskey","M","cfg","parentsubject","canreplyprivately","postformat","CONTENT_FORMATS","MOODLE","inpageReplyContent","length","render","then","html","js","appendNodeContents","slideToggle","resolve","focus","use","core_formchangechecker","init","formid","fail","exception","form","is"],"mappings":"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","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 .\n\n/**\n * This module is the highest level module for the calendar. It is\n * responsible for initialising all of the components required for\n * the calendar to run. It also coordinates the interaction between\n * components by listening for and responding to different events\n * triggered within the calendar UI.\n *\n * @module mod_forum/posts_list\n * @package mod_forum\n * @copyright 2019 Peter Dias\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n 'jquery',\n 'core/templates',\n 'core/notification',\n 'core/pending',\n 'core/yui',\n 'mod_forum/selectors',\n 'mod_forum/inpage_reply',\n ], function(\n $,\n Templates,\n Notification,\n Pending,\n Y,\n Selectors,\n InPageReply\n ) {\n\n var registerEventListeners = function(root) {\n root.on('click', Selectors.post.inpageReplyLink, function(e) {\n e.preventDefault();\n // After adding a reply a url hash is being generated that scrolls (points) to the newly added reply.\n // The hash being present causes this scrolling behavior to the particular reply to persists even when\n // another, non-related in-page replay link is being clicked which ultimately causes a bad user experience.\n // A particular solution for this problem would be changing the browser's history state when a url hash is\n // present.\n if (window.location.hash) {\n // Remove the fragment identifier from the url.\n var url = window.location.href.split('#')[0];\n history.pushState({}, document.title, url);\n }\n var pending = new Pending('inpage-reply');\n var currentTarget = $(e.currentTarget).parents(Selectors.post.forumCoreContent);\n var currentSubject = currentTarget.find(Selectors.post.forumSubject);\n var currentRoot = $(e.currentTarget).parents(Selectors.post.forumContent);\n var context = {\n postid: $(currentRoot).data('post-id'),\n \"reply_url\": $(e.currentTarget).attr('href'),\n sesskey: M.cfg.sesskey,\n parentsubject: currentSubject.data('replySubject'),\n canreplyprivately: $(e.currentTarget).data('can-reply-privately'),\n postformat: InPageReply.CONTENT_FORMATS.MOODLE\n };\n\n if (!currentRoot.find(Selectors.post.inpageReplyContent).length) {\n Templates.render('mod_forum/inpage_reply', context)\n .then(function(html, js) {\n return Templates.appendNodeContents(currentTarget, html, js);\n })\n .then(function() {\n return currentRoot.find(Selectors.post.inpageReplyContent)\n .slideToggle(300, pending.resolve).find('textarea').focus();\n })\n .then(function() {\n // Load formchangechecker module.\n Y.use('moodle-core-formchangechecker', () => {\n M.core_formchangechecker.init({formid: `inpage-reply-${context.postid}`});\n });\n return;\n })\n .fail(Notification.exception);\n } else {\n var form = currentRoot.find(Selectors.post.inpageReplyContent);\n form.slideToggle(300, pending.resolve);\n if (form.is(':visible')) {\n form.find('textarea').focus();\n }\n }\n });\n };\n\n return {\n init: function(root) {\n registerEventListeners(root);\n InPageReply.init(root);\n }\n };\n});\n"],"file":"posts_list.min.js"} \ No newline at end of file diff --git a/mod/forum/amd/src/discussion_nested_v2.js b/mod/forum/amd/src/discussion_nested_v2.js index 6c0e89c8a20..1b8f3d2b063 100644 --- a/mod/forum/amd/src/discussion_nested_v2.js +++ b/mod/forum/amd/src/discussion_nested_v2.js @@ -245,6 +245,21 @@ const buildShowInPageReplyFormFunction = (additionalTemplateContext) => { } catch (e) { Notification.exception(e); } + + // Load formchangechecker module. + import('core/yui') + .then(Y => { + return new Promise(resolve => { + Y.use('moodle-core-formchangechecker', Y => { + resolve(Y); + }); + }); + }) + .then(Y => { + M.core_formchangechecker.init({formid: Y.one(postContainer[0].querySelector('form')).generateID()}); + return Y; + }) + .catch(); } inPageReplyCreateButton.fadeOut(ANIMATION_DURATION, () => { diff --git a/mod/forum/amd/src/inpage_reply.js b/mod/forum/amd/src/inpage_reply.js index 0f2d1c96e80..7a3e524b4ee 100644 --- a/mod/forum/amd/src/inpage_reply.js +++ b/mod/forum/amd/src/inpage_reply.js @@ -169,6 +169,12 @@ define([ submitButton.trigger(EVENTS.POST_CREATED, newid); hideSubmitButtonLoadingIcon(submitButton); allButtons.prop('disabled', false); + + // Tell formchangechecker we submitted the form. + if (typeof M.core_formchangechecker !== 'undefined') { + M.core_formchangechecker.reset_form_dirty_state(); + } + return currentRoot.find(Selectors.post.inpageReplyContent).hide(); }) .then(function() { diff --git a/mod/forum/amd/src/posts_list.js b/mod/forum/amd/src/posts_list.js index ca92955b8d1..fe88af34500 100644 --- a/mod/forum/amd/src/posts_list.js +++ b/mod/forum/amd/src/posts_list.js @@ -30,6 +30,7 @@ define([ 'core/templates', 'core/notification', 'core/pending', + 'core/yui', 'mod_forum/selectors', 'mod_forum/inpage_reply', ], function( @@ -37,6 +38,7 @@ define([ Templates, Notification, Pending, + Y, Selectors, InPageReply ) { @@ -76,6 +78,13 @@ define([ return currentRoot.find(Selectors.post.inpageReplyContent) .slideToggle(300, pending.resolve).find('textarea').focus(); }) + .then(function() { + // Load formchangechecker module. + Y.use('moodle-core-formchangechecker', () => { + M.core_formchangechecker.init({formid: `inpage-reply-${context.postid}`}); + }); + return; + }) .fail(Notification.exception); } else { var form = currentRoot.find(Selectors.post.inpageReplyContent);