Liferay.Loader.define("frontend-js-web@4.0.43/liferay/aop/AOP.es", ['module', 'exports', 'require'], function (module, exports, require) {
  var define = undefined;
  var global = window;
  {
    Object.defineProperty(exports, "__esModule", {
      value: true
    });
    exports.AOP = exports.default = void 0;

    function _classCallCheck(instance, Constructor) {
      if (!(instance instanceof Constructor)) {
        throw new TypeError("Cannot call a class as a function");
      }
    }

    function _defineProperties(target, props) {
      for (var i = 0; i < props.length; i++) {
        var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);
      }
    }

    function _createClass(Constructor, protoProps, staticProps) {
      if (protoProps) _defineProperties(Constructor.prototype, protoProps);if (staticProps) _defineProperties(Constructor, staticProps);return Constructor;
    }

    /**
     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
     *
     * This library is free software; you can redistribute it and/or modify it under
     * the terms of the GNU Lesser General Public License as published by the Free
     * Software Foundation; either version 2.1 of the License, or (at your option)
     * any later version.
     *
     * This library 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 Lesser General Public License for more
     * details.
     */
    var ALTER_RETURN = 'alterReturn';
    var HALT = 'halt';
    var METAL_AOP = '__METAL_AOP__';
    var PREVENT = 'prevent';
    /**
     * AOP class
     */

    var AOP = /*#__PURE__*/function () {
      /**
       * Constructor for AOP class.
       * @param {!Object} obj The object containing the displaced function.
       * @param {!string} fnName The name of the displaced function.
       */
      function AOP(obj, fnName) {
        _classCallCheck(this, AOP);

        /**
         * Array of listeners that will invoke after the displaced function.
         * @type {!Array}
         * @protected
         */
        this.after_ = [];
        /**
         * Array of listeners that will invoke before the displaced function.
         * @type {!Array}
         * @protected
         */

        this.before_ = [];
        /**
         * The name of the displaced function.
         * @type {string}
         * @protected
         */

        this.fnName_ = fnName;
        /**
         * The displaced function.
         * @type {Function}
         * @protected
         */

        this.fn_ = obj[fnName];
        /**
         * The object hosting the method to displace.
         * @type {Object}
         * @protected
         */

        this.obj_ = obj;
      }
      /**
       * Creates handle for detaching listener from displaced function.
       * @param {!Function} fn The listener
       * @param {!boolean} before Determines when listener fires
       * @return {Object}
       */

      _createClass(AOP, [{
        key: "createHandle",
        value: function createHandle(fn, before) {
          return {
            detach: this.detach_.bind(this, fn, before)
          };
        }
        /**
         * Detaches listener from displaced function.
         * @param {!Function} fn The listener
         * @param {!boolean} before Determines when listener fires
         */

      }, {
        key: "detach_",
        value: function detach_(fn, before) {
          var listenerArray = before ? this.before_ : this.after_;
          listenerArray.splice(listenerArray.indexOf(fn), 1);
        }
        /**
         *
         * @param {any} args* Arguments are passed to the wrapping and wrapped functions.
         * @return {any} Return value of wrapped function.
         */

      }, {
        key: "exec",
        value: function exec() {
          var listenerRetVal;
          var prevented = false;
          var retVal;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          for (var i = 0; i < this.before_.length; i++) {
            listenerRetVal = this.before_[i].apply(this.obj_, args);

            if (listenerRetVal && listenerRetVal.type) {
              if (listenerRetVal.type === HALT) {
                return listenerRetVal.value;
              } else if (listenerRetVal.type === PREVENT) {
                prevented = true;
              }
            }
          }

          if (!prevented) {
            retVal = this.fn_.apply(this.obj_, args);
          }

          AOP.currentRetVal = retVal;
          AOP.originalRetVal = retVal;

          for (var _i = 0; _i < this.after_.length; _i++) {
            listenerRetVal = this.after_[_i].apply(this.obj_, args);

            if (listenerRetVal && listenerRetVal.type) {
              if (listenerRetVal.type === HALT) {
                return listenerRetVal.value;
              } else if (listenerRetVal.type === ALTER_RETURN) {
                retVal = listenerRetVal.value;
                AOP.currentRetVal = retVal;
              }
            }
          }

          return retVal;
        }
        /**
         * Registers an AOP listener.
         *
         * @param {!Function} fn the function to execute.
         * @param {boolean} before determines when the listener is invoked.
         * @return {EventHandle} Can be used to remove the listener.
         */

      }, {
        key: "register",
        value: function register(fn, before) {
          if (before) {
            this.before_.push(fn);
          } else {
            this.after_.push(fn);
          }

          return this.createHandle(fn, before);
        }
        /**
         * Executes the supplied method after the specified function.
         *
         * @param {!Function} fn the function to execute.
         * @param {!Object} obj the object hosting the method to displace.
         * @param {!string} fnName the name of the method to displace.
         * @return {EventHandle} Can be used to remove the listener.
         */

      }], [{
        key: "after",
        value: function after(fn, obj, fnName) {
          return AOP.inject(false, fn, obj, fnName);
        }
        /**
         * Return an alterReturn object when you want to change the result returned
         * from the core method to the caller.
         *
         * @param {any} value Return value passed to code that invoked the wrapped
         * function.
         * @return {Object}
         */

      }, {
        key: "alterReturn",
        value: function alterReturn(value) {
          return AOP.modify_(ALTER_RETURN, value);
        }
        /**
         * Executes the supplied method before the specified function.
         *
         * @param {!Function} fn the function to execute.
         * @param {!Object} obj the object hosting the method to displace.
         * @param {!string} fnName the name of the method to displace.
         * @return {EventHandle} Can be used to remove the listener.
         */

      }, {
        key: "before",
        value: function before(fn, obj, fnName) {
          return AOP.inject(true, fn, obj, fnName);
        }
        /**
         * Return a halt object when you want to terminate the execution
         * of all subsequent subscribers as well as the wrapped method
         * if it has not executed yet.
         *
         * @param {any} value Return value passed to code that invoked the wrapped
         * function.
         * @return {Object}
         */

      }, {
        key: "halt",
        value: function halt(value) {
          return AOP.modify_(HALT, value);
        }
        /**
         * Executes the supplied method before or after the specified function.
         *
         * @param {boolean} before determines when the listener is invoked.
         * @param {!Function} fn the function to execute.
         * @param {!Object} obj the object hosting the method to displace.
         * @param {!string} fnName the name of the method to displace.
         * @return {EventHandle} Can be used to remove the listener.
         */

      }, {
        key: "inject",
        value: function inject(before, fn, obj, fnName) {
          var aopObj = obj[METAL_AOP];

          if (!aopObj) {
            aopObj = obj[METAL_AOP] = {};
          }

          if (!aopObj[fnName]) {
            aopObj[fnName] = new AOP(obj, fnName);

            obj[fnName] = function () {
              var _aopObj$fnName;

              return (_aopObj$fnName = aopObj[fnName]).exec.apply(_aopObj$fnName, arguments);
            };
          }

          return aopObj[fnName].register(fn, before);
        }
        /**
         * Returns object which instructs `exec` method to modify the return
         * value or prevent default behavior of wrapped function.
         *
         * @param {!string} type The type of modification to be made
         * @param {any} value Return value passed to code that invoked the wrapped
         * function.
         * @return {Object}
         */

      }, {
        key: "modify_",
        value: function modify_(type, value) {
          return {
            type: type,
            value: value
          };
        }
        /**
         * Return a prevent object when you want to prevent the wrapped function
         * from executing, but want the remaining listeners to execute.
         * @return {Object}
         */

      }, {
        key: "prevent",
        value: function prevent() {
          return AOP.modify_(PREVENT);
        }
      }]);

      return AOP;
    }();

    exports.AOP = AOP;
    var _default = AOP;
    exports.default = _default;
    //# sourceMappingURL=AOP.es.js.map
  }
});
//# sourceMappingURL=AOP.es.js.map