Proyectos de Subversion Moodle

Rev

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

{"version":3,"file":"usertours.min.js","sources":["../src/usertours.js"],"sourcesContent":["/**\n * User tour control library.\n *\n * @module     tool_usertours/usertours\n * @copyright  2016 Andrew Nicols <andrew@nicols.co.uk>\n */\nimport BootstrapTour from './tour';\nimport Templates from 'core/templates';\nimport log from 'core/log';\nimport notification from 'core/notification';\nimport * as tourRepository from './repository';\nimport Pending from 'core/pending';\nimport {eventTypes} from './events';\n\nlet currentTour = null;\nlet tourId = null;\nlet restartTourAndKeepProgress = false;\nlet currentStepNo = null;\n\n/**\n * Find the first matching tour.\n *\n * @param {object[]} tourDetails\n * @param {object[]} filters\n * @returns {null|object}\n */\nconst findMatchingTour = (tourDetails, filters) => {\n    return tourDetails.find(tour => filters.some(filter => {\n        if (filter && filter.filterMatches) {\n            return filter.filterMatches(tour);\n        }\n\n        return true;\n    }));\n};\n\n/**\n * Initialise the user tour for the current page.\n *\n * @method  init\n * @param   {Array}    tourDetails      The matching tours for this page.\n * @param   {Array}    filters          The names of all client side filters.\n */\nexport const init = async(tourDetails, filters) => {\n    const requirements = [];\n    filters.forEach((filter) => {\n        requirements.push(import(filter));\n    });\n\n    const filterPlugins = await Promise.all(requirements);\n\n    const matchingTour = findMatchingTour(tourDetails, filterPlugins);\n    if (!matchingTour) {\n        return;\n    }\n\n    // Only one tour per page is allowed.\n    tourId = matchingTour.tourId;\n\n    let startTour = matchingTour.startTour;\n    if (typeof startTour === 'undefined') {\n        startTour = true;\n    }\n\n    if (startTour) {\n        // Fetch the tour configuration.\n        fetchTour(tourId);\n    }\n\n    addResetLink();\n\n    // Watch for the reset link.\n    document.querySelector('body').addEventListener('click', e => {\n        const resetLink = e.target.closest('#resetpagetour');\n        if (resetLink) {\n            e.preventDefault();\n            resetTourState(tourId);\n        }\n    });\n\n    // Watch for the resize event.\n    window.addEventListener(\"resize\", () => {\n        // Only listen for the running tour.\n        if (currentTour && currentTour.tourRunning) {\n            clearTimeout(window.resizedFinished);\n            window.resizedFinished = setTimeout(() => {\n                // Wait until the resize event has finished.\n                currentStepNo = currentTour.getCurrentStepNumber();\n                restartTourAndKeepProgress = true;\n                resetTourState(tourId);\n            }, 250);\n        }\n    });\n};\n\n/**\n * Fetch the configuration specified tour, and start the tour when it has been fetched.\n *\n * @method  fetchTour\n * @param   {Number}    tourId      The ID of the tour to start.\n */\nconst fetchTour = async tourId => {\n    const pendingPromise = new Pending(`admin_usertour_fetchTour:${tourId}`);\n\n    try {\n        // If we don't have any tour config (because it doesn't need showing for the current user), return early.\n        const response = await tourRepository.fetchTour(tourId);\n        if (response.hasOwnProperty('tourconfig')) {\n            const {html} = await Templates.renderForPromise('tool_usertours/tourstep', response.tourconfig);\n            startBootstrapTour(tourId, html, response.tourconfig);\n        }\n        pendingPromise.resolve();\n    } catch (error) {\n        pendingPromise.resolve();\n        notification.exception(error);\n    }\n};\n\nconst getPreferredResetLocation = () => {\n    let location = document.querySelector('.tool_usertours-resettourcontainer');\n    if (location) {\n        return location;\n    }\n\n    location = document.querySelector('.logininfo');\n    if (location) {\n        return location;\n    }\n\n    location = document.querySelector('footer');\n    if (location) {\n        return location;\n    }\n\n    return document.body;\n};\n\n/**\n * Add a reset link to the page.\n *\n * @method  addResetLink\n */\nconst addResetLink = () => {\n    const pendingPromise = new Pending('admin_usertour_addResetLink');\n\n    Templates.render('tool_usertours/resettour', {})\n    .then(function(html, js) {\n        // Append the link to the most suitable place on the page with fallback to legacy selectors and finally the body if\n        // there is no better place.\n        Templates.appendNodeContents(getPreferredResetLocation(), html, js);\n\n        return;\n    })\n    .catch()\n    .then(pendingPromise.resolve)\n    .catch();\n};\n\n/**\n * Start the specified tour.\n *\n * @method  startBootstrapTour\n * @param   {Number}    tourId      The ID of the tour to start.\n * @param   {String}    template    The template to use.\n * @param   {Object}    tourConfig  The tour configuration.\n * @return  {Object}\n */\nconst startBootstrapTour = (tourId, template, tourConfig) => {\n    if (currentTour && currentTour.tourRunning) {\n        // End the current tour.\n        currentTour.endTour();\n        currentTour = null;\n    }\n\n    document.addEventListener(eventTypes.tourEnded, markTourComplete);\n    document.addEventListener(eventTypes.stepRenderer, markStepShown);\n\n    // Sort out the tour name.\n    tourConfig.tourName = tourConfig.name;\n    delete tourConfig.name;\n\n    // Add the template to the configuration.\n    // This enables translations of the buttons.\n    tourConfig.template = template;\n\n    tourConfig.steps = tourConfig.steps.map(function(step) {\n        if (typeof step.element !== 'undefined') {\n            step.target = step.element;\n            delete step.element;\n        }\n\n        if (typeof step.reflex !== 'undefined') {\n            step.moveOnClick = !!step.reflex;\n            delete step.reflex;\n        }\n\n        if (typeof step.content !== 'undefined') {\n            step.body = step.content;\n            delete step.content;\n        }\n\n        return step;\n    });\n\n    currentTour = new BootstrapTour(tourConfig);\n    let startAt = 0;\n    if (restartTourAndKeepProgress && currentStepNo) {\n        startAt = currentStepNo;\n        restartTourAndKeepProgress = false;\n        currentStepNo = null;\n    }\n    return currentTour.startTour(startAt);\n};\n\n/**\n * Mark the specified step as being shownd by the user.\n *\n * @method  markStepShown\n * @param   {Event} e\n */\nconst markStepShown = e => {\n    const tour = e.detail.tour;\n    const stepConfig = tour.getStepConfig(tour.getCurrentStepNumber());\n    tourRepository.markStepShown(\n        stepConfig.stepid,\n        tourId,\n        tour.getCurrentStepNumber()\n    ).catch(log.error);\n};\n\n/**\n * Mark the specified tour as being completed by the user.\n *\n * @method  markTourComplete\n * @param   {Event} e\n * @listens tool_usertours/stepRendered\n */\nconst markTourComplete = e => {\n    document.removeEventListener(eventTypes.tourEnded, markTourComplete);\n    document.removeEventListener(eventTypes.stepRenderer, markStepShown);\n\n    const tour = e.detail.tour;\n    const stepConfig = tour.getStepConfig(tour.getCurrentStepNumber());\n    tourRepository.markTourComplete(\n        stepConfig.stepid,\n        tourId,\n        tour.getCurrentStepNumber()\n    ).catch(log.error);\n};\n\n/**\n * Reset the state, and restart the the tour on the current page.\n *\n * @method  resetTourState\n * @param   {Number}    tourId      The ID of the tour to start.\n * @returns {Promise}\n */\nexport const resetTourState = tourId => tourRepository.resetTourState(tourId)\n.then(response => {\n    if (response.startTour) {\n        fetchTour(response.startTour);\n    }\n    return;\n}).catch(notification.exception);\n"],"names":["currentTour","tourId","restartTourAndKeepProgress","currentStepNo","async","tourDetails","filters","requirements","forEach","filter","push","matchingTour","find","tour","some","filterMatches","findMatchingTour","Promise","all","startTour","fetchTour","addResetLink","document","querySelector","addEventListener","e","target","closest","preventDefault","resetTourState","window","tourRunning","clearTimeout","resizedFinished","setTimeout","getCurrentStepNumber","pendingPromise","Pending","response","tourRepository","hasOwnProperty","html","Templates","renderForPromise","tourconfig","startBootstrapTour","resolve","error","exception","render","then","js","appendNodeContents","location","body","getPreferredResetLocation","catch","template","tourConfig","endTour","eventTypes","tourEnded","markTourComplete","stepRenderer","markStepShown","tourName","name","steps","map","step","element","reflex","moveOnClick","content","BootstrapTour","startAt","detail","stepConfig","getStepConfig","stepid","log","removeEventListener","notification"],"mappings":"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"}