Your IP : 216.73.216.95


Current Path : /var/www/ljmtc/cbt/lib/amd/build/emoji/
Upload File :
Current File : /var/www/ljmtc/cbt/lib/amd/build/emoji/auto_complete.min.js.map

{"version":3,"sources":["../../src/emoji/auto_complete.js"],"names":["RECENT_EMOJIS_STORAGE_KEY","SELECTORS","EMOJI_BUTTON","ACTIVE_EMOJI_BUTTON","getRecentEmojis","storedData","LocalStorage","get","JSON","parse","addRecentEmoji","unified","shortName","newEmoji","shortnames","recentEmojis","newRecentEmojis","filter","emoji","slice","set","stringify","getEmojiTextFromShortName","EmojiData","byShortName","charCodes","split","map","code","String","fromCodePoint","apply","render","root","shortNames","renderContext","emojis","index","active","emojitext","displayshortname","shortname","html","innerHTML","searchEmojis","searchTerm","limit","data","toLowerCase","Object","keys","includes","getWordFromPosition","text","position","startMatches","match","endMatches","startText","endText","length","isCompleteShortName","test","isPartialShortName","getShortNameFromText","replace","getActiveEmojiSuggestion","querySelector","selectPreviousEmojiSuggestion","activeEmojiSuggestion","previousSuggestion","previousElementSibling","classList","remove","add","scrollIntoView","behaviour","inline","selectNextEmojiSuggestion","nextSuggestion","nextElementSibling","selectEmojiElement","element","selectCallback","getAttribute","trim","textArea","hasSuggestionCallback","hasSuggestions","previousSearchText","addEventListener","value","cursorPos","selectionStart","searchText","emojiText","suggestions","e","isModifierPressed","shiftKey","metaKey","altKey","ctrlKey","which","KeyCodes","escape","arrowLeft","preventDefault","arrowRight","enter","stopPropagation","target","matches"],"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 <http://www.gnu.org/licenses/>.\n\n/**\n * Emoji auto complete.\n *\n * @copyright  2019 Ryan Wyllie <ryan@moodle.com>\n * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport * as EmojiData from 'core/emoji/data';\nimport {render as renderTemplate} from 'core/templates';\nimport {debounce} from 'core/utils';\nimport LocalStorage from 'core/localstorage';\nimport KeyCodes from 'core/key_codes';\n\nconst INPUT_DEBOUNCE_TIMER = 200;\nconst SUGGESTION_LIMIT = 50;\nconst MAX_RECENT_COUNT = 27;\nconst RECENT_EMOJIS_STORAGE_KEY = 'moodle-recent-emojis';\n\nconst SELECTORS = {\n    EMOJI_BUTTON: '[data-region=\"emoji-button\"]',\n    ACTIVE_EMOJI_BUTTON: '[data-region=\"emoji-button\"].active',\n};\n\n/**\n * Get the list of recent emojis data from local storage.\n *\n * @return {Array}\n */\nconst getRecentEmojis = () => {\n    const storedData = LocalStorage.get(RECENT_EMOJIS_STORAGE_KEY);\n    return storedData ? JSON.parse(storedData) : [];\n};\n\n/**\n * Add an emoji data to the set of recent emojis. The new set of recent emojis are\n * saved in local storage.\n *\n * @param {String} unified The char chodes for the emoji\n * @param {String} shortName The emoji short name\n */\nconst addRecentEmoji = (unified, shortName) => {\n    const newEmoji = {\n        unified,\n        shortnames: [shortName]\n    };\n    const recentEmojis = getRecentEmojis();\n    // Add the new emoji to the start of the list of recent emojis.\n    let newRecentEmojis = [newEmoji, ...recentEmojis.filter(emoji => emoji.unified != newEmoji.unified)];\n    // Limit the number of recent emojis.\n    newRecentEmojis = newRecentEmojis.slice(0, MAX_RECENT_COUNT);\n\n    LocalStorage.set(RECENT_EMOJIS_STORAGE_KEY, JSON.stringify(newRecentEmojis));\n};\n\n/**\n * Get the actual emoji string from the short name.\n *\n * @param {String} shortName Emoji short name\n * @return {String|null}\n */\nconst getEmojiTextFromShortName = (shortName) => {\n    const unified = EmojiData.byShortName[shortName];\n\n    if (unified) {\n        const charCodes = unified.split('-').map(code => `0x${code}`);\n        return String.fromCodePoint.apply(null, charCodes);\n    } else {\n        return null;\n    }\n};\n\n/**\n * Render the auto complete list for the given short names.\n *\n * @param {Element} root The root container for the emoji auto complete\n * @param {Array} shortNames The list of short names for emoji suggestions to show\n */\nconst render = async (root, shortNames) => {\n    const renderContext = {\n        emojis: shortNames.map((shortName, index) => {\n            return {\n                active: index === 0,\n                emojitext: getEmojiTextFromShortName(shortName),\n                displayshortname: `:${shortName}:`,\n                shortname: shortName,\n                unified: EmojiData.byShortName[shortName]\n            };\n        })\n    };\n    const html = await renderTemplate('core/emoji/auto_complete', renderContext);\n    root.innerHTML = html;\n};\n\n/**\n * Get the list of emoji short names that include the given search term. If\n * the search term is an empty string then the list of recently used emojis\n * will be returned.\n *\n * @param {String} searchTerm Text to match on\n * @param {Number} limit Maximum number of results to return\n * @return {Array}\n */\nconst searchEmojis = (searchTerm, limit) => {\n    if (searchTerm === '') {\n        return getRecentEmojis().map(data => data.shortnames[0]).slice(0, limit);\n    } else {\n        searchTerm = searchTerm.toLowerCase();\n        return Object.keys(EmojiData.byShortName)\n                .filter(shortName => shortName.includes(searchTerm))\n                .slice(0, limit);\n    }\n};\n\n/**\n * Get the current word at the given position (index) within the text.\n *\n * @param {String} text The text to process\n * @param {Number} position The position (index) within the text to match the word\n * @return {String}\n */\nconst getWordFromPosition = (text, position) => {\n    const startMatches = text.slice(0, position).match(/(\\S*)$/);\n    const endMatches = text.slice(position).match(/^(\\S*)/);\n    let startText = '';\n    let endText = '';\n\n    if (startMatches) {\n        startText = startMatches[startMatches.length - 1];\n    }\n\n    if (endMatches) {\n        endText = endMatches[endMatches.length - 1];\n    }\n\n    return `${startText}${endText}`;\n};\n\n/**\n * Check if the given text is a full short name, i.e. has leading and trialing colon\n * characters.\n *\n * @param {String} text The text to process\n * @return {Bool}\n */\nconst isCompleteShortName = text => /^:[^:\\s]+:$/.test(text);\n\n/**\n * Check if the given text is a partial short name, i.e. has a leading colon but no\n * trailing colon.\n *\n * @param {String} text The text to process\n * @return {Bool}\n */\nconst isPartialShortName = text => /^:[^:\\s]*$/.test(text);\n\n/**\n * Remove the colon characters from the given text.\n *\n * @param {String} text The text to process\n * @return {String}\n */\nconst getShortNameFromText = text => text.replace(/:/g, '');\n\n/**\n * Get the currently active emoji button element in the list of suggestions.\n *\n * @param {Element} root The emoji auto complete container element\n * @return {Element|null}\n */\nconst getActiveEmojiSuggestion = (root) => {\n    return root.querySelector(SELECTORS.ACTIVE_EMOJI_BUTTON);\n};\n\n/**\n * Make the previous sibling of the current active emoji active.\n *\n * @param {Element} root The emoji auto complete container element\n */\nconst selectPreviousEmojiSuggestion = (root) => {\n    const activeEmojiSuggestion = getActiveEmojiSuggestion(root);\n    const previousSuggestion = activeEmojiSuggestion.previousElementSibling;\n\n    if (previousSuggestion) {\n        activeEmojiSuggestion.classList.remove('active');\n        previousSuggestion.classList.add('active');\n        previousSuggestion.scrollIntoView({behaviour: 'smooth', inline: 'center'});\n    }\n};\n\n/**\n * Make the next sibling to the current active emoji active.\n *\n * @param {Element} root The emoji auto complete container element\n */\nconst selectNextEmojiSuggestion = (root) => {\n    const activeEmojiSuggestion = getActiveEmojiSuggestion(root);\n    const nextSuggestion = activeEmojiSuggestion.nextElementSibling;\n\n    if (nextSuggestion) {\n        activeEmojiSuggestion.classList.remove('active');\n        nextSuggestion.classList.add('active');\n        nextSuggestion.scrollIntoView({behaviour: 'smooth', inline: 'center'});\n    }\n};\n\n/**\n * Trigger the select callback for the given emoji button element.\n *\n * @param {Element} element The emoji button element\n * @param {Function} selectCallback The callback for when the user selects an emoji\n */\nconst selectEmojiElement = (element, selectCallback) => {\n    const shortName = element.getAttribute('data-short-name');\n    const unified = element.getAttribute('data-unified');\n    addRecentEmoji(unified, shortName);\n    selectCallback(element.innerHTML.trim());\n};\n\n/**\n * Initialise the emoji auto complete.\n *\n * @param {Element} root The root container element for the auto complete\n * @param {Element} textArea The text area element to monitor for auto complete\n * @param {Function} hasSuggestionCallback Callback for when there are auto-complete suggestions\n * @param {Function} selectCallback Callback for when the user selects an emoji\n */\nexport default (root, textArea, hasSuggestionCallback, selectCallback) => {\n    let hasSuggestions = false;\n    let previousSearchText = '';\n\n    // Debounce the listener so that each keypress delays the execution of the handler. The\n    // handler should only run 200 milliseconds after the last keypress.\n    textArea.addEventListener('keyup', debounce(() => {\n        // This is a \"keyup\" listener so that it only executes after the text area value\n        // has been updated.\n        const text = textArea.value;\n        const cursorPos = textArea.selectionStart;\n        const searchText = getWordFromPosition(text, cursorPos);\n\n        if (searchText === previousSearchText) {\n            // Nothing has changed so no need to take any action.\n            return;\n        } else {\n            previousSearchText = searchText;\n        }\n\n        if (isCompleteShortName(searchText)) {\n            // If the user has entered a full short name (with leading and trialing colons)\n            // then see if we can find a match for it and auto complete it.\n            const shortName = getShortNameFromText(searchText);\n            const emojiText = getEmojiTextFromShortName(shortName);\n            hasSuggestions = false;\n            if (emojiText) {\n                addRecentEmoji(EmojiData.byShortName[shortName], shortName);\n                selectCallback(emojiText);\n            }\n        } else if (isPartialShortName(searchText)) {\n            // If the user has entered a partial short name (leading colon but no trailing) then\n            // search on the text to see if we can find some suggestions for them.\n            const suggestions = searchEmojis(getShortNameFromText(searchText), SUGGESTION_LIMIT);\n\n            if (suggestions.length) {\n                render(root, suggestions);\n                hasSuggestions = true;\n            } else {\n                hasSuggestions = false;\n            }\n        } else {\n            hasSuggestions = false;\n        }\n\n        hasSuggestionCallback(hasSuggestions);\n    }, INPUT_DEBOUNCE_TIMER));\n\n    textArea.addEventListener('keydown', (e) => {\n        if (hasSuggestions) {\n            const isModifierPressed = (e.shiftKey || e.metaKey || e.altKey || e.ctrlKey);\n            if (!isModifierPressed) {\n                switch (e.which) {\n                    case KeyCodes.escape:\n                        // Escape key closes the auto complete.\n                        hasSuggestions = false;\n                        hasSuggestionCallback(false);\n                        break;\n                    case KeyCodes.arrowLeft:\n                        // Arrow keys navigate through the list of suggetions.\n                        selectPreviousEmojiSuggestion(root);\n                        e.preventDefault();\n                        break;\n                    case KeyCodes.arrowRight:\n                        // Arrow keys navigate through the list of suggetions.\n                        selectNextEmojiSuggestion(root);\n                        e.preventDefault();\n                        break;\n                    case KeyCodes.enter:\n                        // Enter key selects the current suggestion.\n                        selectEmojiElement(getActiveEmojiSuggestion(root), selectCallback);\n                        e.preventDefault();\n                        e.stopPropagation();\n                        break;\n                }\n            }\n        }\n    });\n\n    root.addEventListener('click', (e) => {\n        const target = e.target;\n        if (target.matches(SELECTORS.EMOJI_BUTTON)) {\n            selectEmojiElement(target, selectCallback);\n        }\n    });\n};"],"file":"auto_complete.min.js"}