Proyectos de Subversion Moodle

Rev

Autoría | Ultima modificación | Ver Log |

{"version":3,"file":"search.min.js","sources":["../src/search.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 * Search methods for finding contents in the content bank.\n *\n * @module     core_contentbank/search\n * @copyright  2020 Sara Arjona <sara@moodle.com>\n * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport $ from 'jquery';\nimport selectors from 'core_contentbank/selectors';\nimport {getString} from 'core/str';\nimport Pending from 'core/pending';\nimport {debounce} from 'core/utils';\n\n/**\n * Set up the search.\n *\n * @method init\n */\nexport const init = () => {\n    const pendingPromise = new Pending();\n\n    const root = $(selectors.regions.contentbank);\n    registerListenerEvents(root);\n\n    pendingPromise.resolve();\n};\n\n/**\n * Register contentbank search related event listeners.\n *\n * @method registerListenerEvents\n * @param {Object} root The root element for the contentbank.\n */\nconst registerListenerEvents = (root) => {\n\n    const searchInput = root.find(selectors.elements.searchinput)[0];\n\n    root.on('click', selectors.actions.search, function(e) {\n        e.preventDefault();\n        toggleSearchResultsView(root, searchInput.value);\n    });\n\n    root.on('click', selectors.actions.clearSearch, function(e) {\n        e.preventDefault();\n        searchInput.value = \"\";\n        searchInput.focus();\n        toggleSearchResultsView(root, searchInput.value);\n    });\n\n    // The search input is also triggered.\n    searchInput.addEventListener('input', debounce(() => {\n        // Display the search results.\n        toggleSearchResultsView(root, searchInput.value);\n    }, 300));\n\n};\n\n/**\n * Toggle (display/hide) the search results depending on the value of the search query.\n *\n * @method toggleSearchResultsView\n * @param {HTMLElement} body The root element for the contentbank.\n * @param {String} searchQuery The search query.\n */\nconst toggleSearchResultsView = async(body, searchQuery) => {\n    const clearSearchButton = body.find(selectors.actions.clearSearch)[0];\n\n    const navbarBreadcrumb = body.find(selectors.elements.cbnavbarbreadcrumb)[0];\n    const navbarTotal = body.find(selectors.elements.cbnavbartotalsearch)[0];\n    // Update the results.\n    const filteredContents = filterContents(body, searchQuery);\n    if (searchQuery.length > 0) {\n        // As the search query is present, search results should be displayed.\n\n        // Display the \"clear\" search button in the activity chooser search bar.\n        clearSearchButton.classList.remove('d-none');\n\n        // Change the cb-navbar to display total items found.\n        navbarBreadcrumb.classList.add('d-none');\n        navbarTotal.innerHTML = await getString('itemsfound', 'core_contentbank', filteredContents.length);\n        navbarTotal.classList.remove('d-none');\n    } else {\n        // As search query is not present, the search results should be removed.\n\n        // Hide the \"clear\" search button in the activity chooser search bar.\n        clearSearchButton.classList.add('d-none');\n\n        // Display again the breadcrumb in the navbar.\n        navbarBreadcrumb.classList.remove('d-none');\n        navbarTotal.classList.add('d-none');\n    }\n};\n\n/**\n * Return the list of contents which have a name that matches the given search term.\n *\n * @method filterContents\n * @param {HTMLElement} body The root element for the contentbank.\n * @param {String} searchTerm The search term to match.\n * @return {Array}\n */\nconst filterContents = (body, searchTerm) => {\n    const contents = Array.from(body.find(selectors.elements.listitem));\n    const searchResults = [];\n    contents.forEach((content) => {\n        const contentName = content.getAttribute('data-name');\n        if (searchTerm === '' || contentName.toLowerCase().includes(searchTerm.toLowerCase())) {\n            // The content matches the search criteria so it should be displayed and hightlighted.\n            searchResults.push(content);\n            const contentNameElement = content.querySelector(selectors.regions.cbcontentname);\n            contentNameElement.innerHTML = highlight(contentName, searchTerm);\n            content.classList.remove('d-none');\n        } else {\n            content.classList.add('d-none');\n        }\n    });\n\n    return searchResults;\n};\n\n/**\n * Highlight a given string in a text.\n *\n * @method highlight\n * @param  {String} text The whole text.\n * @param  {String} highlightText The piece of text to highlight.\n * @return {String}\n */\nconst highlight = (text, highlightText) => {\n    let result = text;\n    if (highlightText !== '') {\n        const pos = text.toLowerCase().indexOf(highlightText.toLowerCase());\n        if (pos > -1) {\n            result = text.substr(0, pos) + '<span class=\"matchtext\">' + text.substr(pos, highlightText.length) + '</span>' +\n                text.substr(pos + highlightText.length);\n        }\n    }\n\n    return result;\n};\n"],"names":["pendingPromise","Pending","root","selectors","regions","contentbank","registerListenerEvents","resolve","searchInput","find","elements","searchinput","on","actions","search","e","preventDefault","toggleSearchResultsView","value","clearSearch","focus","addEventListener","async","body","searchQuery","clearSearchButton","navbarBreadcrumb","cbnavbarbreadcrumb","navbarTotal","cbnavbartotalsearch","filteredContents","filterContents","length","classList","remove","add","innerHTML","searchTerm","contents","Array","from","listitem","searchResults","forEach","content","contentName","getAttribute","toLowerCase","includes","push","querySelector","cbcontentname","highlight","text","highlightText","result","pos","indexOf","substr"],"mappings":";;;;;;;gOAkCoB,WACVA,eAAiB,IAAIC,iBAErBC,MAAO,mBAAEC,mBAAUC,QAAQC,aACjCC,uBAAuBJ,MAEvBF,eAAeO,iBASbD,uBAA0BJ,aAEtBM,YAAcN,KAAKO,KAAKN,mBAAUO,SAASC,aAAa,GAE9DT,KAAKU,GAAG,QAAST,mBAAUU,QAAQC,QAAQ,SAASC,GAChDA,EAAEC,iBACFC,wBAAwBf,KAAMM,YAAYU,UAG9ChB,KAAKU,GAAG,QAAST,mBAAUU,QAAQM,aAAa,SAASJ,GACrDA,EAAEC,iBACFR,YAAYU,MAAQ,GACpBV,YAAYY,QACZH,wBAAwBf,KAAMM,YAAYU,UAI9CV,YAAYa,iBAAiB,SAAS,oBAAS,KAE3CJ,wBAAwBf,KAAMM,YAAYU,SAC3C,OAWDD,wBAA0BK,MAAMC,KAAMC,qBAClCC,kBAAoBF,KAAKd,KAAKN,mBAAUU,QAAQM,aAAa,GAE7DO,iBAAmBH,KAAKd,KAAKN,mBAAUO,SAASiB,oBAAoB,GACpEC,YAAcL,KAAKd,KAAKN,mBAAUO,SAASmB,qBAAqB,GAEhEC,iBAAmBC,eAAeR,KAAMC,aAC1CA,YAAYQ,OAAS,GAIrBP,kBAAkBQ,UAAUC,OAAO,UAGnCR,iBAAiBO,UAAUE,IAAI,UAC/BP,YAAYQ,gBAAkB,kBAAU,aAAc,mBAAoBN,iBAAiBE,QAC3FJ,YAAYK,UAAUC,OAAO,YAK7BT,kBAAkBQ,UAAUE,IAAI,UAGhCT,iBAAiBO,UAAUC,OAAO,UAClCN,YAAYK,UAAUE,IAAI,YAY5BJ,eAAiB,CAACR,KAAMc,oBACpBC,SAAWC,MAAMC,KAAKjB,KAAKd,KAAKN,mBAAUO,SAAS+B,WACnDC,cAAgB,UACtBJ,SAASK,SAASC,gBACRC,YAAcD,QAAQE,aAAa,gBACtB,KAAfT,YAAqBQ,YAAYE,cAAcC,SAASX,WAAWU,eAAgB,CAEnFL,cAAcO,KAAKL,SACQA,QAAQM,cAAc/C,mBAAUC,QAAQ+C,eAChDf,UAAYgB,UAAUP,YAAaR,YACtDO,QAAQX,UAAUC,OAAO,eAEzBU,QAAQX,UAAUE,IAAI,aAIvBO,eAWLU,UAAY,CAACC,KAAMC,qBACjBC,OAASF,QACS,KAAlBC,cAAsB,OAChBE,IAAMH,KAAKN,cAAcU,QAAQH,cAAcP,eACjDS,KAAO,IACPD,OAASF,KAAKK,OAAO,EAAGF,KAAO,2BAA6BH,KAAKK,OAAOF,IAAKF,cAActB,QAAU,UACjGqB,KAAKK,OAAOF,IAAMF,cAActB,gBAIrCuB"}