AutorÃa | Ultima modificación | Ver Log |
{"version":3,"file":"link.min.js","sources":["../src/link.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 * Link helper for Tiny Link plugin.\n *\n * @module tiny_link/link\n * @copyright 2023 Huong Nguyen <huongnv13@gmail.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Templates from 'co
re/templates';\nimport Pending from 'core/pending';\nimport Selectors from 'tiny_link/selectors';\n\n/**\n * Handle insertion of a new link, or update of an existing one.\n *\n * @param {Element} currentForm\n * @param {TinyMCE} editor\n */\nexport const setLink = (currentForm, editor) => {\n const input = currentForm.querySelector(Selectors.elements.urlEntry);\n let value = input.value;\n\n if (value !== '') {\n const pendingPromise = new Pending('tiny_link/setLink');\n // We add a prefix if it is not already prefixed.\n value = value.trim();\n const expr = new RegExp(/^[a-zA-Z]*\\.*\\/|^#|^[a-zA-Z]*:/);\n if (!expr.test(value)) {\n value = 'http://' + value;\n }\n\n // Add the link.\n setLinkOnSelection(currentForm, editor, value).then(pendingPromise.resolve);\n }\n};\n\n/**\n * Handle unlink of a link\n *\n * @param {TinyMCE} editor\n */\nexport const unSetLink = (editor) => {\n if (editor.hasPlugin('rtc', true)) {\n
editor.execCommand('unlink');\n } else {\n const dom = editor.dom;\n const selection = editor.selection;\n const bookmark = selection.getBookmark();\n const rng = selection.getRng().cloneRange();\n const startAnchorElm = dom.getParent(rng.startContainer, 'a[href]', editor.getBody());\n const endAnchorElm = dom.getParent(rng.endContainer, 'a[href]', editor.getBody());\n if (startAnchorElm) {\n rng.setStartBefore(startAnchorElm);\n }\n if (endAnchorElm) {\n rng.setEndAfter(endAnchorElm);\n }\n selection.setRng(rng);\n editor.execCommand('unlink');\n selection.moveToBookmark(bookmark);\n }\n};\n\n/**\n * Final step setting the anchor on the selection.\n *\n * @param {Element} currentForm\n * @param {TinyMCE} editor\n * @param {String} url URL the link will point to.\n */\nconst setLinkOnSelection = async(currentForm, editor, url) => {\n const urlText = currentForm.querySelector(Selectors.ele
ments.urlText);\n const target = currentForm.querySelector(Selectors.elements.openInNewWindow);\n let textToDisplay = urlText.value.replace(/(<([^>]+)>)/gi, \"\").trim();\n\n if (textToDisplay === '') {\n textToDisplay = url;\n }\n\n const context = {\n url: url,\n newwindow: target.checked,\n };\n if (urlText.getAttribute('data-link-on-element')) {\n context.title = textToDisplay;\n context.name = editor.selection.getNode().outerHTML;\n } else {\n context.name = textToDisplay;\n }\n const {html} = await Templates.renderForPromise('tiny_link/embed_link', context);\n const currentLink = getSelectedLink(editor);\n if (currentLink) {\n currentLink.outerHTML = html;\n } else {\n editor.insertContent(html);\n }\n};\n\n/**\n * Get current link data.\n *\n * @param {TinyMCE} editor\n * @returns {{}}\n */\nexport const getCurrentLinkData = (editor) => {\n let properties = {};\n const link = getSelectedLink(editor)
;\n if (link) {\n const url = link.getAttribute('href');\n const target = link.getAttribute('target');\n const textToDisplay = link.innerText;\n const title = link.getAttribute('title');\n\n if (url !== '') {\n properties.url = url;\n }\n if (target === '_blank') {\n properties.newwindow = true;\n }\n if (title && title !== '') {\n properties.urltext = title.trim();\n } else if (textToDisplay !== '') {\n properties.urltext = textToDisplay.trim();\n }\n } else {\n // Check if the user is selecting some text before clicking on the Link button.\n const selectedNode = editor.selection.getNode();\n if (selectedNode) {\n const textToDisplay = getTextSelection(editor);\n if (textToDisplay !== '') {\n properties.urltext = textToDisplay.trim();\n properties.hasTextToDisplay = true;\n properties.hasPlainTex
tSelected = true;\n } else {\n if (selectedNode.getAttribute('data-mce-selected')) {\n properties.setLinkOnElement = true;\n }\n }\n }\n }\n\n return properties;\n};\n\n/**\n * Get selected link.\n *\n * @param {TinyMCE} editor\n * @returns {Element}\n */\nconst getSelectedLink = (editor) => {\n return getAnchorElement(editor);\n};\n\n/**\n * Get anchor element.\n *\n * @param {TinyMCE} editor\n * @param {Element} selectedElm\n * @returns {Element}\n */\nconst getAnchorElement = (editor, selectedElm) => {\n selectedElm = selectedElm || editor.selection.getNode();\n return editor.dom.getParent(selectedElm, 'a[href]');\n};\n\n/**\n * Get only the selected text.\n * In some cases, window.getSelection() is not run as expected. We should only get the text value\n * For ex: <img src=\"\" alt=\"XYZ\">Some text here\n * window.getSelection() will return XYZSome text here\n *\n * @param {TinyMCE} editor\n * @return {
string} Selected text\n */\nconst getTextSelection = (editor) => {\n let selText = '';\n const sel = editor.selection.getSel();\n const rangeCount = sel.rangeCount;\n if (rangeCount) {\n let rangeTexts = [];\n for (let i = 0; i < rangeCount; ++i) {\n rangeTexts.push('' + sel.getRangeAt(i));\n }\n selText = rangeTexts.join('');\n }\n\n return selText;\n};\n\n/**\n * Check the current selected element is an anchor or not.\n *\n * @param {TinyMCE} editor\n * @param {Element} selectedElm\n * @returns {boolean}\n */\nconst isInAnchor = (editor, selectedElm) => getAnchorElement(editor, selectedElm) !== null;\n\n/**\n * Change state of button.\n *\n * @param {TinyMCE} editor\n * @param {function()} toggler\n * @returns {function()}\n */\nconst toggleState = (editor, toggler) => {\n editor.on('NodeChange', toggler);\n return () => editor.off('NodeChange', toggler);\n};\n\n/**\n * Change the active state of button.\n *\n * @param {TinyMCE} editor\n * @ret
urns {function(*): function(): *}\n */\nexport const toggleActiveState = (editor) => (api) => {\n const updateState = () => api.setActive(!editor.mode.isReadOnly() && isInAnchor(editor, editor.selection.getNode()));\n updateState();\n return toggleState(editor, updateState);\n};\n"],"names":["currentForm","editor","value","querySelector","Selectors","elements","urlEntry","pendingPromise","Pending","trim","RegExp","test","setLinkOnSelection","then","resolve","hasPlugin","execCommand","dom","selection","bookmark","getBookmark","rng","getRng","cloneRange","startAnchorElm","getParent","startContainer","getBody","endAnchorElm","endContainer","setStartBefore","setEndAfter","setRng","moveToBookmark","async","url","urlText","target","openInNewWindow","textToDisplay","replace","context","newwindow","checked","getAttribute","title","name","getNode","outerHTML","html","Templates","renderForPromise","currentLink","getSelectedLink","insertContent","properties","link","innerText","urltext","selectedNode","getText
Selection","hasTextToDisplay","hasPlainTextSelected","setLinkOnElement","getAnchorElement","selectedElm","selText","sel","getSel","rangeCount","rangeTexts","i","push","getRangeAt","join","api","updateState","setActive","mode","isReadOnly","isInAnchor","toggler","on","off","toggleState"],"mappings":"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"}