Rev 1 | AutorÃa | Comparar con el anterior | Ultima modificación | Ver Log |
{"version":3,"file":"message_drawer.min.js","sources":["../src/message_drawer.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 * Controls the message drawer.\n *\n * @module core_message/message_drawer\n * @copyright 2018 Ryan Wyllie <ryan@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(
\n[\n 'jquery',\n 'core/custom_interaction_events',\n 'core/pubsub',\n 'core_message/message_drawer_view_contact',\n 'core_message/message_drawer_view_contacts',\n 'core_message/message_drawer_view_conversation',\n 'core_message/message_drawer_view_group_info',\n 'core_message/message_drawer_view_overview',\n 'core_message/message_drawer_view_search',\n 'core_message/message_drawer_view_settings',\n 'core_message/message_drawer_router',\n 'core_message/message_drawer_routes',\n 'core_message/message_drawer_events',\n 'core_message/message_drawer_helper',\n 'core/pending',\n 'core/drawer',\n 'core/toast',\n 'core/str',\n 'core/config',\n 'core/ajax',\n 'core/local/aria/focuslock',\n 'core/modal_backdrop',\n 'core/templates',\n 'core/local/aria/selectors',\n],\nfunction(\n $,\n CustomEvents,\n PubSub,\n ViewContact,\n ViewContacts,\n ViewConversation,\n ViewGroupInfo,\n ViewOverview,\n ViewSearch,\n ViewSettin
gs,\n Router,\n Routes,\n Events,\n Helper,\n Pending,\n Drawer,\n Toast,\n Str,\n Config,\n Ajax,\n FocusLock,\n ModalBackdrop,\n Templates,\n AriaSelectors,\n) {\n\n var SELECTORS = {\n DRAWER: '[data-region=\"right-hand-drawer\"]',\n PANEL_BODY_CONTAINER: '[data-region=\"panel-body-container\"]',\n PANEL_HEADER_CONTAINER: '[data-region=\"panel-header-container\"]',\n VIEW_CONTACT: '[data-region=\"view-contact\"]',\n VIEW_CONTACTS: '[data-region=\"view-contacts\"]',\n VIEW_CONVERSATION: '[data-region=\"view-conversation\"]',\n VIEW_CONVERSATION_WITH_ID: '[data-region=\"view-conversation\"][data-conversation-id]',\n VIEW_CONVERSATION_WITH_USER: '[data-region=\"view-conversation\"][data-other-user-id]',\n VIEW_GROUP_INFO: '[data-region=\"view-group-info\"]',\n VIEW_OVERVIEW: '[data-region=\"view-overview\"]',\n VIEW_SEARCH: '[data-region=\"view-search\"]',\n VIEW_SETTINGS: '[data-r
egion=\"view-settings\"]',\n ROUTES: '[data-route]',\n ROUTES_BACK: '[data-route-back]',\n HEADER_CONTAINER: '[data-region=\"header-container\"]',\n BODY_CONTAINER: '[data-region=\"body-container\"]',\n FOOTER_CONTAINER: '[data-region=\"footer-container\"]',\n CLOSE_BUTTON: '[data-action=\"closedrawer\"]',\n MESSAGE_INDEX: '[data-region=\"message-index\"]',\n MESSAGE_TEXT_AREA: '[data-region=\"send-message-txt\"]',\n };\n\n /**\n * Get elements for route.\n *\n * @param {String} namespace Unique identifier for the Routes\n * @param {Object} root The message drawer container.\n * @param {string} selector The route container.\n *\n * @return {array} elements Found route container objects.\n */\n var getParametersForRoute = function(namespace, root, selector) {\n\n var header = root.find(SELECTORS.HEADER_CONTAINER).find(selector);\n if (!header.length) {\n header = root.find(SELECTORS.PANEL_
HEADER_CONTAINER).find(selector);\n }\n var body = root.find(SELECTORS.BODY_CONTAINER).find(selector);\n if (!body.length) {\n body = root.find(SELECTORS.PANEL_BODY_CONTAINER).find(selector);\n }\n var footer = root.find(SELECTORS.FOOTER_CONTAINER).find(selector);\n\n return [\n namespace,\n header.length ? header : null,\n body.length ? body : null,\n footer.length ? footer : null\n ];\n };\n\n var routes = [\n [Routes.VIEW_CONTACT, SELECTORS.VIEW_CONTACT, ViewContact.show, ViewContact.description],\n [Routes.VIEW_CONTACTS, SELECTORS.VIEW_CONTACTS, ViewContacts.show, ViewContacts.description],\n [Routes.VIEW_CONVERSATION, SELECTORS.VIEW_CONVERSATION, ViewConversation.show, ViewConversation.description],\n [Routes.VIEW_GROUP_INFO, SELECTORS.VIEW_GROUP_INFO, ViewGroupInfo.show, ViewGroupInfo.description],\n [Routes.VIEW_OVERVIEW, SELECTORS.VIEW_OVERVIEW, ViewOverview
.show, ViewOverview.description],\n [Routes.VIEW_SEARCH, SELECTORS.VIEW_SEARCH, ViewSearch.show, ViewSearch.description],\n [Routes.VIEW_SETTINGS, SELECTORS.VIEW_SETTINGS, ViewSettings.show, ViewSettings.description]\n ];\n\n /**\n * Create routes.\n *\n * @param {String} namespace Unique identifier for the Routes\n * @param {Object} root The message drawer container.\n */\n var createRoutes = function(namespace, root) {\n routes.forEach(function(route) {\n Router.add(namespace, route[0], getParametersForRoute(namespace, root, route[1]), route[2], route[3]);\n });\n };\n\n let backdropPromise = null;\n\n /**\n * Set the focus on the drawer.\n *\n * This method also creates or destroy any necessary backdrop zone and focus trap.\n *\n * @param {Object} root The message drawer container.\n * @param {Boolean} hasFocus Whether the drawer has focus or not.\n */\n var setFocus = function(root, hasFocus) {\n
var drawerRoot = Drawer.getDrawerRoot(root);\n if (!drawerRoot.length) {\n return;\n }\n if (!backdropPromise) {\n backdropPromise = Templates.render('core/modal_backdrop', {})\n .then(html => new ModalBackdrop(html));\n }\n const backdropWithAdjustments = backdropPromise.then(modalBackdrop => {\n const messageDrawerZIndex = window.getComputedStyle(drawerRoot[0]).zIndex;\n if (messageDrawerZIndex) {\n modalBackdrop.setZIndex(messageDrawerZIndex - 1);\n }\n modalBackdrop.getAttachmentPoint().get(0).addEventListener('click', e => {\n PubSub.publish(Events.HIDE, {});\n e.preventDefault();\n });\n return modalBackdrop;\n });\n if (hasFocus) {\n FocusLock.trapFocus(root[0]);\n // eslint-disable-next-line promise/catch-or-return\n backdropWithAdjustments.then(modalBackdrop => {\n
if (modalBackdrop) {\n modalBackdrop.show();\n const pageWrapper = document.getElementById('page');\n pageWrapper.style.overflow = 'hidden';\n // Set the focus on the close button so when we press enter, it closes the drawer as it did before\n var closeButton = root.find(SELECTORS.CLOSE_BUTTON);\n if (closeButton.length) {\n closeButton.focus();\n }\n }\n return modalBackdrop;\n });\n } else {\n // eslint-disable-next-line promise/catch-or-return\n backdropWithAdjustments.then(modalBackdrop => {\n if (modalBackdrop) {\n FocusLock.untrapFocus();\n var button = $(SELECTORS.DRAWER).attr('data-origin');\n if (button) {\n $('#' + button).focus();\n }\n
modalBackdrop.hide();\n const pageWrapper = document.getElementById('page');\n pageWrapper.style.overflow = 'visible';\n }\n return modalBackdrop;\n });\n }\n };\n /**\n * Show the message drawer.\n *\n * @param {string} namespace The route namespace.\n * @param {Object} root The message drawer container.\n */\n var show = function(namespace, root) {\n if (!root.attr('data-shown')) {\n Router.go(namespace, Routes.VIEW_OVERVIEW);\n root.attr('data-shown', true);\n }\n\n var drawerRoot = Drawer.getDrawerRoot(root);\n if (drawerRoot.length) {\n setFocus(root, true);\n Drawer.show(drawerRoot);\n }\n };\n\n /**\n * Hide the message drawer.\n *\n * @param {Object} root The message drawer container.\n */\n var hide = function(root) {\n var drawerRoot = Drawer.getDrawerRoot(root);\n
if (drawerRoot.length) {\n setFocus(root, false);\n Drawer.hide(drawerRoot);\n }\n };\n\n /**\n * Check if the drawer is visible.\n *\n * @param {Object} root The message drawer container.\n * @return {boolean}\n */\n var isVisible = function(root) {\n var drawerRoot = Drawer.getDrawerRoot(root);\n if (drawerRoot.length) {\n return Drawer.isVisible(drawerRoot);\n }\n return true;\n };\n\n /**\n * Set Jump from button\n *\n * @param {String} buttonid The originating button id\n */\n var setJumpFrom = function(buttonid) {\n $(SELECTORS.DRAWER).attr('data-origin', buttonid);\n };\n\n /**\n * Store an unsent message.\n *\n * Don't store this if the user has already seen the unsent message.\n * This avoids spamming and ensures the user is only reminded once per unsent message.\n * If the unsent message is sent, this attribute is removed and notification is pos
sible again (see sendMessage).\n */\n const storeUnsentMessage = async() => {\n const messageTextArea = document.querySelector(SELECTORS.MESSAGE_TEXT_AREA);\n\n if (messageTextArea.value.trim().length > 0 && !messageTextArea.hasAttribute('data-unsent-message-viewed')) {\n\n let message = messageTextArea.value;\n let conversationid = 0;\n let otheruserid = 0;\n\n // We don't always have a conversation to link the unsent message to, so let's check for that.\n const conversationId = document.querySelector(SELECTORS.VIEW_CONVERSATION_WITH_ID);\n if (conversationId) {\n const conversationWithId = messageTextArea.closest(SELECTORS.VIEW_CONVERSATION_WITH_ID);\n conversationid = conversationWithId.getAttribute('data-conversation-id');\n }\n // Store the 'other' user id if it is there. This can be used to create conversations.\n const conversationUser = document.querySe
lector(SELECTORS.VIEW_CONVERSATION_WITH_USER);\n if (conversationUser) {\n const conversationWithUser = messageTextArea.closest(SELECTORS.VIEW_CONVERSATION_WITH_USER);\n otheruserid = conversationWithUser.getAttribute('data-other-user-id');\n }\n\n setStoredUnsentMessage(message, conversationid, otheruserid);\n }\n };\n\n /**\n * Get the stored unsent message from the session via web service.\n *\n * @returns {Promise}\n */\n const getStoredUnsentMessage = () => Ajax.call([{\n methodname: 'core_message_get_unsent_message',\n args: {}\n }])[0];\n\n /**\n * Set the unsent message value in the session via web service.\n *\n * SendBeacon is used here because this is called on 'beforeunload'.\n *\n * @param {string} message The message string.\n * @param {number} conversationid The conversation id.\n * @param {number} otheruserid The other user id.\n * @returns {Promis
e}\n */\n const setStoredUnsentMessage = (message, conversationid, otheruserid) => {\n const method = 'core_message_set_unsent_message';\n const requestUrl = new URL(`${Config.wwwroot}/lib/ajax/service.php`);\n requestUrl.searchParams.set('sesskey', Config.sesskey);\n requestUrl.searchParams.set('info', method);\n\n navigator.sendBeacon(requestUrl, JSON.stringify([{\n index: 0,\n methodname: method,\n args: {\n message: message,\n conversationid: conversationid,\n otheruserid: otheruserid,\n }\n }]));\n };\n\n /**\n * Check for an unsent message.\n *\n * @param {String} uniqueId Unique identifier for the Routes.\n * @param {Object} root The message drawer container.\n */\n const getUnsentMessage = async(uniqueId, root) => {\n let type;\n let messageRoot;\n\n // We need to check if we are on the message/index page.\n
// This logic is needed to handle the two message widgets here and ensure we are targetting the right one.\n const messageIndex = document.querySelector(SELECTORS.MESSAGE_INDEX);\n if (messageIndex !== null) {\n type = 'index';\n messageRoot = document.getElementById(`message-index-${uniqueId}`);\n if (!messageRoot) {\n // This is not the correct widget.\n return;\n }\n\n } else {\n type = 'drawer';\n messageRoot = document.getElementById(`message-drawer-${uniqueId}`);\n }\n\n const storedMessage = await getStoredUnsentMessage();\n const messageTextArea = messageRoot.querySelector(SELECTORS.MESSAGE_TEXT_AREA);\n if (storedMessage.message && messageTextArea !== null) {\n showUnsentMessage(messageTextArea, storedMessage, type, uniqueId, root);\n }\n };\n\n /**\n * Show an unsent message.\n *\n * There are two message widgets on the
message/index page.\n * Because of that, we need to try and target the correct widget.\n *\n * @param {String} textArea The textarea element.\n * @param {Object} stored The stored message content.\n * @param {String} type Is this from the drawer or index page?\n * @param {String} uniqueId Unique identifier for the Routes.\n * @param {Object} root The message drawer container.\n */\n const showUnsentMessage = (textArea, stored, type, uniqueId, root) => {\n // The user has already been notified.\n if (textArea.hasAttribute('data-unsent-message-viewed')) {\n return;\n }\n\n // Depending on the type, show the conversation with the data we have available.\n // A conversation can be continued if there is a conversationid.\n // If the user was messaging a new non-contact, we won't have a conversationid yet.\n // In that case, we use the otheruserid value to start a conversation with them.\n switch (type) {\n
case 'index':\n // Show the conversation in the main panel on the message/index page.\n if (stored.conversationid) {\n Router.go(uniqueId, Routes.VIEW_CONVERSATION, stored.conversationid, 'frompanel');\n // There was no conversation id, let's get a conversation going using the user id.\n } else if (stored.otheruserid) {\n Router.go(uniqueId, Routes.VIEW_CONVERSATION, null, 'create', stored.otheruserid);\n }\n break;\n\n case 'drawer':\n // Open the drawer and show the conversation.\n if (stored.conversationid) {\n let args = {\n conversationid: stored.conversationid\n };\n Helper.showConversation(args);\n // There was no conversation id, let's get a conversation going using the user id.\n } else if (stored.otheruserid) {\n
show(uniqueId, root);\n Router.go(uniqueId, Routes.VIEW_CONVERSATION, null, 'create', stored.otheruserid);\n }\n break;\n }\n\n // Populate the text area.\n textArea.value = stored.message;\n textArea.setAttribute('data-unsent-message-viewed', 1);\n\n // Notify the user.\n Toast.add(Str.get_string('unsentmessagenotification', 'core_message'));\n };\n\n /**\n * Listen to and handle events for routing, showing and hiding the message drawer.\n *\n * @param {string} namespace The route namespace.\n * @param {Object} root The message drawer container.\n * @param {bool} alwaysVisible Is this messaging app always shown?\n */\n var registerEventListeners = function(namespace, root, alwaysVisible) {\n CustomEvents.define(root, [CustomEvents.events.activate, CustomEvents.events.escape]);\n var paramRegex = /^data-route-param-?(\\d*)$/;\n\n root.on(CustomEvents.ev
ents.activate, SELECTORS.ROUTES, function(e, data) {\n var element = $(e.target).closest(SELECTORS.ROUTES);\n var route = element.attr('data-route');\n var attributes = [];\n\n for (var i = 0; i < element[0].attributes.length; i++) {\n attributes.push(element[0].attributes[i]);\n }\n\n var paramAttributes = attributes.filter(function(attribute) {\n var name = attribute.nodeName;\n var match = paramRegex.test(name);\n return match;\n });\n paramAttributes.sort(function(a, b) {\n var aParts = paramRegex.exec(a.nodeName);\n var bParts = paramRegex.exec(b.nodeName);\n var aIndex = aParts.length > 1 ? aParts[1] : 0;\n var bIndex = bParts.length > 1 ? bParts[1] : 0;\n\n if (aIndex < bIndex) {\n return -1;\n } else if (bIndex < aIndex) {\n retu
rn 1;\n } else {\n return 0;\n }\n });\n\n var params = paramAttributes.map(function(attribute) {\n return attribute.nodeValue;\n });\n\n var routeParams = [namespace, route].concat(params);\n\n Router.go.apply(null, routeParams);\n\n data.originalEvent.preventDefault();\n });\n\n root.on(CustomEvents.events.activate, SELECTORS.ROUTES_BACK, function(e, data) {\n Router.back(namespace);\n\n data.originalEvent.preventDefault();\n });\n\n // Close the message drawer if the drawer is visible and the click happened outside the drawer and the toggle button.\n $(document).on(CustomEvents.events.activate, e => {\n var drawer = $(e.target).closest(SELECTORS.DRAWER);\n var toggleButtonId = $(SELECTORS.DRAWER)?.attr('data-origin');\n var toggleButton = '';\n if (toggleButtonId !== undefined &
& toggleButtonId) {\n toggleButton = $(e.target).closest(\"#\" + toggleButtonId);\n }\n\n if (!drawer.length && !toggleButton.length && isVisible(root)) {\n // Determine if the element that was clicked is focusable.\n var focusableElement = $(e.target).closest(AriaSelectors.elements.focusable);\n if (focusableElement.length) {\n // We need to move the focus to the clicked element after the drawer is hidden,\n // so we need to clear the `data-origin` attribute first.\n $(SELECTORS.DRAWER).attr('data-origin', '');\n }\n // Hide the drawer.\n hide(root);\n // Move the focus to the clicked element if it is focusable.\n if (focusableElement.length) {\n focusableElement.focus();\n }\n }\n });\n\n // These are theme-specific to help us fix random
behat fails.\n // These events target those events defined in BS3 and BS4 onwards.\n root[0].querySelectorAll('.collapse').forEach((collapse) => {\n collapse.addEventListener('hide.bs.collapse', (e) => {\n var pendingPromise = new Pending();\n e.target.addEventListener('hidden.bs.collapse', function() {\n pendingPromise.resolve();\n }, {once: true});\n });\n });\n\n root[0].querySelectorAll('.collapse').forEach((collapse) => {\n collapse.addEventListener('show.bs.collapse', (e) => {\n var pendingPromise = new Pending();\n e.target.addEventListener('shown.bs.collapse', function() {\n pendingPromise.resolve();\n }, {once: true});\n });\n });\n\n $(SELECTORS.JUMPTO).focus(function() {\n var firstInput = root.find(SELECTORS.CLOSE_BUTTON);\n if (firstInput.length) {\n
firstInput.focus();\n } else {\n $(SELECTORS.HEADER_CONTAINER).find(SELECTORS.ROUTES_BACK).focus();\n }\n });\n\n $(SELECTORS.DRAWER).focus(function() {\n var button = $(this).attr('data-origin');\n if (button) {\n $('#' + button).focus();\n }\n });\n\n if (!alwaysVisible) {\n PubSub.subscribe(Events.SHOW, function() {\n show(namespace, root);\n });\n\n PubSub.subscribe(Events.HIDE, function() {\n hide(root);\n });\n\n PubSub.subscribe(Events.TOGGLE_VISIBILITY, function(buttonid) {\n const buttonElement = document.getElementById(buttonid);\n if (isVisible(root)) {\n hide(root);\n buttonElement?.setAttribute('aria-expanded', false);\n $(SELECTORS.JUMPTO).attr('tabindex', -1);\n } else {\n show(
namespace, root);\n buttonElement?.setAttribute('aria-expanded', true);\n setJumpFrom(buttonid);\n $(SELECTORS.JUMPTO).attr('tabindex', 0);\n }\n });\n root.on(CustomEvents.events.escape, function() {\n PubSub.publish(Events.HIDE, {});\n });\n }\n\n PubSub.subscribe(Events.SHOW_CONVERSATION, function(args) {\n setJumpFrom(args.buttonid);\n show(namespace, root);\n Router.go(namespace, Routes.VIEW_CONVERSATION, args.conversationid);\n });\n\n var closebutton = root.find(SELECTORS.CLOSE_BUTTON);\n closebutton.on(CustomEvents.events.activate, function(e, data) {\n data.originalEvent.preventDefault();\n setFocus(root, false);\n var button = $(SELECTORS.DRAWER).attr('data-origin');\n if (button) {\n $('#' + button).focus();\n }\n PubSub.publish(Even
ts.TOGGLE_VISIBILITY, button);\n });\n\n PubSub.subscribe(Events.CREATE_CONVERSATION_WITH_USER, function(args) {\n setJumpFrom(args.buttonid);\n show(namespace, root);\n Router.go(namespace, Routes.VIEW_CONVERSATION, null, 'create', args.userid);\n });\n\n PubSub.subscribe(Events.SHOW_SETTINGS, function() {\n show(namespace, root);\n Router.go(namespace, Routes.VIEW_SETTINGS);\n });\n\n PubSub.subscribe(Events.PREFERENCES_UPDATED, function(preferences) {\n var filteredPreferences = preferences.filter(function(preference) {\n return preference.type == 'message_entertosend';\n });\n var enterToSendPreference = filteredPreferences.length ? filteredPreferences[0] : null;\n\n if (enterToSendPreference) {\n var viewConversationFooter = root.find(SELECTORS.FOOTER_CONTAINER).find(SELECTORS.VIEW_CONVERSATION);\n viewConversationFooter
.attr('data-enter-to-send', enterToSendPreference.value);\n }\n });\n\n // If our textarea is modified, remove the attribute which indicates the user has seen the unsent message notification.\n // This will allow the user to be notified again.\n const textArea = document.querySelector(SELECTORS.MESSAGE_TEXT_AREA);\n if (textArea) {\n textArea.addEventListener('keyup', function() {\n textArea.removeAttribute('data-unsent-message-viewed');\n });\n }\n\n // Catch any unsent messages and store them.\n window.addEventListener('beforeunload', storeUnsentMessage);\n };\n\n /**\n * Initialise the message drawer.\n *\n * @param {Object} root The message drawer container.\n * @param {String} uniqueId Unique identifier for the Routes\n * @param {bool} alwaysVisible Should we show the app now, or wait for the user?\n * @param {Object} route\n */\n var init = function(root, uniqueId
, alwaysVisible, route) {\n root = $(root);\n createRoutes(uniqueId, root);\n registerEventListeners(uniqueId, root, alwaysVisible);\n\n if (alwaysVisible) {\n show(uniqueId, root);\n\n if (route) {\n var routeParams = route.params || [];\n routeParams = [uniqueId, route.path].concat(routeParams);\n Router.go.apply(null, routeParams);\n }\n }\n\n // Mark the drawer as ready.\n Helper.markDrawerReady();\n\n // Get and show any unsent message.\n getUnsentMessage(uniqueId, root);\n };\n\n return {\n init: init,\n };\n});\n"],"names":["define","$","CustomEvents","PubSub","ViewContact","ViewContacts","ViewConversation","ViewGroupInfo","ViewOverview","ViewSearch","ViewSettings","Router","Routes","Events","Helper","Pending","Drawer","Toast","Str","Config","Ajax","FocusLock","ModalBackdrop","Templates","AriaSelectors","SELECTORS","DRAWER","PANEL_BODY_CONTAINER",
"PANEL_HEADER_CONTAINER","VIEW_CONTACT","VIEW_CONTACTS","VIEW_CONVERSATION","VIEW_CONVERSATION_WITH_ID","VIEW_CONVERSATION_WITH_USER","VIEW_GROUP_INFO","VIEW_OVERVIEW","VIEW_SEARCH","VIEW_SETTINGS","ROUTES","ROUTES_BACK","HEADER_CONTAINER","BODY_CONTAINER","FOOTER_CONTAINER","CLOSE_BUTTON","MESSAGE_INDEX","MESSAGE_TEXT_AREA","routes","show","description","createRoutes","namespace","root","forEach","route","add","selector","header","find","length","body","footer","getParametersForRoute","backdropPromise","setFocus","hasFocus","drawerRoot","getDrawerRoot","render","then","html","backdropWithAdjustments","modalBackdrop","messageDrawerZIndex","window","getComputedStyle","zIndex","setZIndex","getAttachmentPoint","get","addEventListener","e","publish","HIDE","preventDefault","trapFocus","document","getElementById","style","overflow","closeButton","focus","untrapFocus","button","attr","hide","go","isVisible","setJumpFrom","buttonid","storeUnsentMessage","async","messageTextArea","querySelector","value","trim","hasA
ttribute","message","conversationid","otheruserid","closest","getAttribute","setStoredUnsentMessage","method","requestUrl","URL","wwwroot","searchParams","set","sesskey","navigator","sendBeacon","JSON","stringify","index","methodname","args","getUnsentMessage","uniqueId","type","messageRoot","storedMessage","call","showUnsentMessage","textArea","stored","showConversation","setAttribute","get_string","init","alwaysVisible","events","activate","escape","paramRegex","on","data","element","target","attributes","i","push","paramAttributes","filter","attribute","name","nodeName","test","sort","a","b","aParts","exec","bParts","aIndex","bIndex","params","map","nodeValue","routeParams","concat","apply","originalEvent","back","drawer","toggleButtonId","_$","toggleButton","undefined","focusableElement","elements","focusable","querySelectorAll","collapse","pendingPromise","resolve","once","JUMPTO","firstInput","this","subscribe","SHOW","TOGGLE_VISIBILITY","buttonElement","SHOW_CONVERSATION","CREATE_CONVERSATION_WITH_USE
R","userid","SHOW_SETTINGS","PREFERENCES_UPDATED","preferences","filteredPreferences","preference","enterToSendPreference","removeAttribute","registerEventListeners","path","markDrawerReady"],"mappings":"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"}