AutorÃa | Ultima modificación | Ver Log |
{"version":3,"file":"debug.min.js","sources":["../../../src/local/reactive/debug.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 * Reactive module debug tools.\n *\n * @module core/local/reactive/debug\n * @copyright 2021 Ferran Recio <ferran@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ni
mport Reactive from 'core/local/reactive/reactive';\nimport log from 'core/log';\n\n// The list of reactives instances.\nconst reactiveInstances = {};\n\n// The reactive debugging objects.\nconst reactiveDebuggers = {};\n\n/**\n * Reactive module debug tools.\n *\n * If debug is enabled, this reactive module will spy all the reactive instances and keep a record\n * of the changes and components they have.\n *\n * It is important to note that the Debug class is also a Reactive module. The debug instance keeps\n * the reactive instances data as its own state. This way it is possible to implement development tools\n * that whatches this data.\n *\n * @class core/reactive/local/reactive/debug/Debug\n * @copyright 2021 Ferran Recio <ferran@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nclass Debug extends Reactive {\n\n /**\n * Set the initial state.\n *\n * @param {object} stateData the initial state data.\n */\n setInitialState(stateData) {
\n super.setInitialState(stateData);\n log.debug(`Debug module \"M.reactive\" loaded.`);\n }\n\n /**\n * List the currents page reactives instances.\n */\n get list() {\n return JSON.parse(JSON.stringify(this.state.reactives));\n }\n\n /**\n * Register a new Reactive instance.\n *\n * This method is called every time a \"new Reactive\" is executed.\n *\n * @param {Reactive} instance the reactive instance\n */\n registerNewInstance(instance) {\n\n // Generate a valid variable name for that instance.\n let name = instance.name ?? `instance${this.state.reactives.length}`;\n name = name.replace(/\\W/g, '');\n\n log.debug(`Registering new reactive instance \"M.reactive.${name}\"`);\n\n reactiveInstances[name] = instance;\n reactiveDebuggers[name] = new DebugInstance(reactiveInstances[name]);\n // Register also in the state.\n this.dispatch('putInstance', name, instance);\n // Add d
ebug watchers to instance.\n const refreshMethod = () => {\n this.dispatch('putInstance', name, instance);\n };\n instance.target.addEventListener('readmode:on', refreshMethod);\n instance.target.addEventListener('readmode:off', refreshMethod);\n instance.target.addEventListener('registerComponent:success', refreshMethod);\n instance.target.addEventListener('transaction:end', refreshMethod);\n // We store the last transaction into the state.\n const storeTransaction = ({detail}) => {\n const changes = detail?.changes;\n this.dispatch('lastTransaction', name, changes);\n };\n instance.target.addEventListener('transaction:start', storeTransaction);\n }\n\n /**\n * Returns a debugging object for a specific Reactive instance.\n *\n * A debugging object is a class that wraps a Reactive instance to quick access some of the\n * reactive methods using the browser JS console.\n *\n * @p
aram {string} name the Reactive instance name\n * @returns {DebugInstance} a debug object wrapping the Reactive instance\n */\n debug(name) {\n return reactiveDebuggers[name];\n }\n}\n\n/**\n * The debug state mutations class.\n *\n * @class core/reactive/local/reactive/debug/Mutations\n */\nclass Mutations {\n\n /**\n * Insert or update a new instance into the debug state.\n *\n * @param {StateManager} stateManager the debug state manager\n * @param {string} name the instance name\n * @param {Reactive} instance the reactive instance\n */\n putInstance(stateManager, name, instance) {\n const state = stateManager.state;\n\n stateManager.setReadOnly(false);\n\n if (state.reactives.has(name)) {\n state.reactives.get(name).countcomponents = instance.components.length;\n state.reactives.get(name).readOnly = instance.stateManager.readonly;\n state.reactives.get(name).modified = new Date().getTime();\n }
else {\n state.reactives.add({\n id: name,\n countcomponents: instance.components.length,\n readOnly: instance.stateManager.readonly,\n lastChanges: [],\n modified: new Date().getTime(),\n });\n }\n stateManager.setReadOnly(true);\n }\n\n /**\n * Update the lastChanges attribute with a list of changes\n *\n * @param {StateManager} stateManager the debug reactive state\n * @param {string} name tje instance name\n * @param {array} changes the list of changes\n */\n lastTransaction(stateManager, name, changes) {\n if (!changes || changes.length === 0) {\n return;\n }\n\n const state = stateManager.state;\n const lastChanges = ['transaction:start'];\n\n changes.forEach(change => {\n lastChanges.push(change.eventName);\n });\n\n lastChanges.push('transaction:end');\n\n stateManager.setReadOnly(f
alse);\n\n state.reactives.get(name).lastChanges = lastChanges;\n\n stateManager.setReadOnly(true);\n }\n}\n\n/**\n * Class used to debug a specific instance and manipulate the state from the JS console.\n *\n * @class core/reactive/local/reactive/debug/DebugInstance\n * @copyright 2021 Ferran Recio <ferran@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nclass DebugInstance {\n\n /**\n * Constructor.\n *\n * @param {Reactive} instance the reactive instance\n */\n constructor(instance) {\n this.instance = instance;\n // Add some debug data directly into the instance. This way we avoid having attributes\n // that will confuse the console aoutocomplete.\n if (instance._reactiveDebugData === undefined) {\n instance._reactiveDebugData = {\n highlighted: false,\n };\n }\n }\n\n /**\n * Set the read only mode.\n *\n * Quick access to the in
stance setReadOnly method.\n *\n * @param {bool} value the new read only value\n */\n set readOnly(value) {\n this.instance.stateManager.setReadOnly(value);\n }\n\n /**\n * Get the read only value\n *\n * @returns {bool}\n */\n get readOnly() {\n return this.instance.stateManager.readonly;\n }\n\n /**\n * Return the current state object.\n *\n * @returns {object}\n */\n get state() {\n return this.instance.state;\n }\n\n /**\n * Tooggle the reactive HTML element highlight registered in this reactive instance.\n *\n * @param {bool} value the highlight value\n */\n set highlight(value) {\n this.instance._reactiveDebugData.highlighted = value;\n this.instance.components.forEach(({element}) => {\n const border = (value) ? `thick solid #0000FF` : '';\n element.style.border = border;\n });\n }\n\n /**\n * Get the current highligh value.\n *\n *
@returns {bool}\n */\n get highlight() {\n return this.instance._reactiveDebugData.highlighted;\n }\n\n /**\n * List all the components registered in this instance.\n *\n * @returns {array}\n */\n get components() {\n return [...this.instance.components];\n }\n\n /**\n * List all the state changes evenet pending to dispatch.\n *\n * @returns {array}\n */\n get changes() {\n const result = [];\n this.instance.stateManager.eventsToPublish.forEach(\n (element) => {\n result.push(element.eventName);\n }\n );\n return result;\n }\n\n /**\n * Dispatch a change in the state.\n *\n * Usually reactive modules throw an error directly to the components when something\n * goes wrong. However, course editor can directly display a notification.\n *\n * @method dispatch\n * @param {*} args\n */\n async dispatch(...args) {\n this.instance.disp
atch(...args);\n }\n\n /**\n * Return all the HTML elements registered in the instance components.\n *\n * @returns {array}\n */\n get elements() {\n const result = [];\n this.instance.components.forEach(({element}) => {\n result.push(element);\n });\n return result;\n }\n\n /**\n * Return a plain copy of the state data.\n *\n * @returns {object}\n */\n get stateData() {\n return JSON.parse(JSON.stringify(this.state));\n }\n\n /**\n * Process an update state array.\n *\n * @param {array} updates an array of update state messages\n */\n processUpdates(updates) {\n this.instance.stateManager.processUpdates(updates);\n }\n}\n\nconst stateChangedEventName = 'core_reactive_debug:stateChanged';\n\n/**\n * Internal state changed event.\n *\n * @method dispatchStateChangedEvent\n * @param {object} detail the full state\n * @param {object} target the custom event target (document if none
provided)\n */\nfunction dispatchStateChangedEvent(detail, target) {\n if (target === undefined) {\n target = document;\n }\n target.dispatchEvent(\n new CustomEvent(\n stateChangedEventName,\n {\n bubbles: true,\n detail: detail,\n }\n )\n );\n}\n\n/**\n * The main init method to initialize the reactive debug.\n * @returns {object}\n */\nexport const initDebug = () => {\n const debug = new Debug({\n name: 'CoreReactiveDebug',\n eventName: stateChangedEventName,\n eventDispatch: dispatchStateChangedEvent,\n mutations: new Mutations(),\n state: {\n reactives: [],\n },\n });\n\n // The reactiveDebuggers will be used as a way of access the debug instances but also to register every new\n // instance. To ensure this will update the reactive debug state we add the registerNewInstance method to it.\n reactiveDebuggers.registerNewInstance = debug.registe
rNewInstance.bind(debug);\n\n return {\n debug,\n debuggers: reactiveDebuggers,\n };\n};\n"],"names":["reactiveInstances","reactiveDebuggers","Debug","Reactive","setInitialState","stateData","debug","list","JSON","parse","stringify","this","state","reactives","registerNewInstance","instance","name","length","replace","DebugInstance","dispatch","refreshMethod","target","addEventListener","_ref","detail","changes","Mutations","putInstance","stateManager","setReadOnly","has","get","countcomponents","components","readOnly","readonly","modified","Date","getTime","add","id","lastChanges","lastTransaction","forEach","change","push","eventName","constructor","undefined","_reactiveDebugData","highlighted","value","highlight","_ref2","element","border","style","result","eventsToPublish","elements","_ref3","processUpdates","updates","dispatchStateChangedEvent","document","dispatchEvent","CustomEvent","bubbles","eventDispatch","mutations","bind","debuggers"],"mappings":";;;;;;;2KA2BMA,kBAAoB,GAGpBC,k
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"}