PHP Classes

File: toastui/src/js/invoker.js

Recommend this page to a friend!
  Classes of Mark de Leon  >  PHP Document Scanner using SANE or eSCL AirPrint  >  toastui/src/js/invoker.js  >  Download  
File: toastui/src/js/invoker.js
Role: Auxiliary data
Content type: text/plain
Description: Auxiliary data
Class: PHP Document Scanner using SANE or eSCL AirPrint
Web interface to scan printed documents
Author: By
Last change:
Date: 1 year ago
Size: 6,355 bytes
 

Contents

Class file image Download
/**
 * @author NHN Ent. FE Development Team <dl_javascript@nhn.com>
 * @fileoverview Invoker - invoke commands
 */
import snippet from 'tui-code-snippet';
import Promise from 'core-js/library/es6/promise';
import commandFactory from './factory/command';
import consts from './consts';

const {eventNames, rejectMessages} = consts;
const {isFunction, isString, CustomEvents} = snippet;

/**
 * Invoker
 * @class
 * @ignore
 */
class Invoker {
    constructor() {
        /**
         * Undo stack
         * @type {Array.<Command>}
         * @private
         */
        this._undoStack = [];

        /**
         * Redo stack
         * @type {Array.<Command>}
         * @private
         */
        this._redoStack = [];

        /**
         * Lock-flag for executing command
         * @type {boolean}
         * @private
         */
        this._isLocked = false;
    }

    /**
     * Invoke command execution
     * @param {Command} command - Command
     * @returns {Promise}
     * @private
     */
    _invokeExecution(command) {
        this.lock();

        let {args} = command;
        if (!args) {
            args = [];
        }

        return command.execute(...args)
            .then(value => {
                this.pushUndoStack(command);
                this.unlock();
                if (isFunction(command.executeCallback)) {
                    command.executeCallback(value);
                }

                return value;
            })['catch'](message => {
                this.unlock();

                return Promise.reject(message);
            });
    }

    /**
     * Invoke command undo
     * @param {Command} command - Command
     * @returns {Promise}
     * @private
     */
    _invokeUndo(command) {
        this.lock();

        let {args} = command;
        if (!args) {
            args = [];
        }

        return command.undo(...args)
            .then(value => {
                this.pushRedoStack(command);
                this.unlock();
                if (isFunction(command.undoCallback)) {
                    command.undoCallback(value);
                }

                return value;
            })['catch'](message => {
                this.unlock();

                return Promise.reject(message);
            });
    }

    /**
     * fire REDO_STACK_CHANGED event
     * @private
     */
    _fireRedoStackChanged() {
        this.fire(eventNames.REDO_STACK_CHANGED, this._redoStack.length);
    }

    /**
     * fire UNDO_STACK_CHANGED event
     * @private
     */
    _fireUndoStackChanged() {
        this.fire(eventNames.UNDO_STACK_CHANGED, this._undoStack.length);
    }

    /**
     * Lock this invoker
     */
    lock() {
        this._isLocked = true;
    }

    /**
     * Unlock this invoker
     */
    unlock() {
        this._isLocked = false;
    }

    /**
     * Invoke command
     * Store the command to the undoStack
     * Clear the redoStack
     * @param {String} commandName - Command name
     * @param {...*} args - Arguments for creating command
     * @returns {Promise}
     */
    execute(...args) {
        if (this._isLocked) {
            return Promise.reject(rejectMessages.isLock);
        }

        let [command] = args;
        if (isString(command)) {
            command = commandFactory.create(...args);
        }

        return this._invokeExecution(command)
            .then(value => {
                this.clearRedoStack();

                return value;
            });
    }

    /**
     * Undo command
     * @returns {Promise}
     */
    undo() {
        let command = this._undoStack.pop();
        let promise;
        let message = '';

        if (command && this._isLocked) {
            this.pushUndoStack(command, true);
            command = null;
        }
        if (command) {
            if (this.isEmptyUndoStack()) {
                this._fireUndoStackChanged();
            }
            promise = this._invokeUndo(command);
        } else {
            message = rejectMessages.undo;
            if (this._isLocked) {
                message = `${message} Because ${rejectMessages.isLock}`;
            }
            promise = Promise.reject(message);
        }

        return promise;
    }

    /**
     * Redo command
     * @returns {Promise}
     */
    redo() {
        let command = this._redoStack.pop();
        let promise;
        let message = '';

        if (command && this._isLocked) {
            this.pushRedoStack(command, true);
            command = null;
        }
        if (command) {
            if (this.isEmptyRedoStack()) {
                this._fireRedoStackChanged();
            }
            promise = this._invokeExecution(command);
        } else {
            message = rejectMessages.redo;
            if (this._isLocked) {
                message = `${message} Because ${rejectMessages.isLock}`;
            }
            promise = Promise.reject(message);
        }

        return promise;
    }

    /**
     * Push undo stack
     * @param {Command} command - command
     * @param {boolean} [isSilent] - Fire event or not
     */
    pushUndoStack(command, isSilent) {
        this._undoStack.push(command);
        if (!isSilent) {
            this._fireUndoStackChanged();
        }
    }

    /**
     * Push redo stack
     * @param {Command} command - command
     * @param {boolean} [isSilent] - Fire event or not
     */
    pushRedoStack(command, isSilent) {
        this._redoStack.push(command);
        if (!isSilent) {
            this._fireRedoStackChanged();
        }
    }

    /**
     * Return whether the redoStack is empty
     * @returns {boolean}
     */
    isEmptyRedoStack() {
        return this._redoStack.length === 0;
    }

    /**
     * Return whether the undoStack is empty
     * @returns {boolean}
     */
    isEmptyUndoStack() {
        return this._undoStack.length === 0;
    }

    /**
     * Clear undoStack
     */
    clearUndoStack() {
        if (!this.isEmptyUndoStack()) {
            this._undoStack = [];
            this._fireUndoStackChanged();
        }
    }

    /**
     * Clear redoStack
     */
    clearRedoStack() {
        if (!this.isEmptyRedoStack()) {
            this._redoStack = [];
            this._fireRedoStackChanged();
        }
    }
}

CustomEvents.mixin(Invoker);
module.exports = Invoker;
For more information send a message to info at phpclasses dot org.