Liferay.Loader.define("frontend-js-web@4.0.39/liferay/component.es", ['module', 'exports', 'require', 'frontend-js-metal-web$metal'], function (module, exports, require) {
  var define = undefined;
  var global = window;
  {
    Object.defineProperty(exports, "__esModule", {
      value: true
    });
    exports.default = exports.initComponentCache = exports.getComponentCache = exports.destroyUnfulfilledPromises = exports.destroyComponents = exports.destroyComponent = exports.componentReady = exports.component = void 0;

    var _metal = require("frontend-js-metal-web$metal");

    /**
     * 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 componentConfigs = {};
    var componentPromiseWrappers = {};
    var components = {};
    var componentsCache = {};
    var componentsFn = {};
    var DEFAULT_CACHE_VALIDATION_PARAMS = ['p_p_id', 'p_p_lifecycle'];
    var DEFAULT_CACHE_VALIDATION_PORTLET_PARAMS = ['ddmStructureKey', 'fileEntryTypeId', 'folderId', 'navigation', 'status'];
    var LIFERAY_COMPONENT = 'liferay.component';

    var _createPromiseWrapper = function _createPromiseWrapper(value) {
      var promiseWrapper;

      if (value) {
        promiseWrapper = {
          promise: Promise.resolve(value),
          resolve: function resolve() {}
        };
      } else {
        var promiseResolve;
        var promise = new Promise(function (resolve) {
          promiseResolve = resolve;
        });
        promiseWrapper = {
          promise: promise,
          resolve: promiseResolve
        };
      }

      return promiseWrapper;
    };
    /**
     * Restores a previously cached component markup.
     *
     * @param {object} state The stored state associated with the registered task.
     * @param {object} params The additional params passed in the task registration.
     * @param {Fragment} node The temporary fragment holding the new markup.
     * @private
     */

    var _restoreTask = function _restoreTask(state, params, node) {
      var cache = state.data;
      var componentIds = Object.keys(cache);
      componentIds.forEach(function (componentId) {
        var container = node.querySelector("#".concat(componentId));

        if (container) {
          container.innerHTML = cache[componentId].html;
        }
      });
    };
    /**
     * Runs when an SPA navigation start is detected to
     *
     * <ul>
     * <li>
     * Cache the state and current markup of registered components that have
     * requested it through the <code>cacheState</code> configuration option. This
     * state can be used to initialize the component in the same state if it
     * persists throughout navigations.
     * </li>
     * <li>
     * Register a DOM task to restore the markup of components that are present in
     * the next screen to avoid a flickering effect due to state changes. This can
     * be done by querying the components screen cache using the
     * <code>Liferay.getComponentsCache</code> method.
     * </li>
     * </ul>
     *
     * @private
     */

    var _onStartNavigate = function _onStartNavigate(event) {
      var currentUri = new URL(window.location.href);
      var uri = new URL(event.path, window.location.href);
      var cacheableUri = DEFAULT_CACHE_VALIDATION_PARAMS.every(function (param) {
        return uri.searchParams.get(param) === currentUri.searchParams.get(param);
      });

      if (cacheableUri) {
        var componentIds = Object.keys(components);
        componentIds = componentIds.filter(function (componentId) {
          var component = components[componentId];
          var componentConfig = componentConfigs[componentId];
          var cacheablePortletUri = DEFAULT_CACHE_VALIDATION_PORTLET_PARAMS.every(function (param) {
            var cacheable = false;

            if (componentConfig) {
              var namespacedParam = "_".concat(componentConfig.portletId, "_").concat(param);
              cacheable = uri.searchParams.get(namespacedParam) === currentUri.searchParams.get(namespacedParam);
            }

            return cacheable;
          });
          var cacheableComponent = (0, _metal.isFunction)(component.isCacheable) ? component.isCacheable(uri) : false;
          return cacheableComponent && cacheablePortletUri && componentConfig && componentConfig.cacheState && component.element && component.getState;
        });
        componentsCache = componentIds.reduce(function (cache, componentId) {
          var component = components[componentId];
          var componentConfig = componentConfigs[componentId];
          var componentState = component.getState();
          var componentCache = componentConfig.cacheState.reduce(function (cache, stateKey) {
            cache[stateKey] = componentState[stateKey];
            return cache;
          }, {});
          cache[componentId] = {
            html: component.element.innerHTML,
            state: componentCache
          };
          return cache;
        }, []);
        Liferay.DOMTaskRunner.addTask({
          action: _restoreTask,
          condition: function condition(state) {
            return state.owner === LIFERAY_COMPONENT;
          }
        });
        Liferay.DOMTaskRunner.addTaskState({
          data: componentsCache,
          owner: LIFERAY_COMPONENT
        });
      } else {
        componentsCache = {};
      }
    };
    /**
     * Registers a component and retrieves its instance from the global registry.
     *
     * @param  {string} id The ID of the component to retrieve or register.
     * @param  {object} value The component instance or a component constructor. If
     *         a constructor is provided, it will be invoked the first time the
     *         component is requested and its result will be stored and returned as
     *         the component.
     * @param  {object} componentConfig The Custom component configuration. This can
     *         be used to provide additional hints for the system handling of the
     *         component lifecycle.
     * @return {object} The passed value, or the stored component for the provided
     *         ID.
     */

    var component = function component(id, value, componentConfig) {
      var retVal;

      if (arguments.length === 1) {
        var _component = components[id];

        if (_component && (0, _metal.isFunction)(_component)) {
          componentsFn[id] = _component;
          _component = _component();
          components[id] = _component;
        }

        retVal = _component;
      } else {
        if (components[id] && value !== null) {
          delete componentConfigs[id];
          delete componentPromiseWrappers[id];
          console.warn('Component with id "' + id + '" is being registered twice. This can lead to unexpected behaviour in the "Liferay.component" and "Liferay.componentReady" APIs, as well as in the "*:registered" events.');
        }

        retVal = components[id] = value;

        if (value === null) {
          delete componentConfigs[id];
          delete componentPromiseWrappers[id];
        } else {
          componentConfigs[id] = componentConfig;
          Liferay.fire(id + ':registered');
          var componentPromiseWrapper = componentPromiseWrappers[id];

          if (componentPromiseWrapper) {
            componentPromiseWrapper.resolve(value);
          } else {
            componentPromiseWrappers[id] = _createPromiseWrapper(value);
          }
        }
      }

      return retVal;
    };
    /**
     * Retrieves a list of component instances after they've been registered.
     *
     * @param {...string} componentId The IDs of the components to receive.
     * @return {Promise} A promise to be resolved with all the requested component
     *         instances after they've been successfully registered.
     */

    exports.component = component;

    var componentReady = function componentReady() {
      var component;
      var componentPromise;

      if (arguments.length === 1) {
        component = arguments[0];
      } else {
        component = [];

        for (var i = 0; i < arguments.length; i++) {
          component[i] = arguments[i];
        }
      }

      if (Array.isArray(component)) {
        componentPromise = Promise.all(component.map(function (id) {
          return componentReady(id);
        }));
      } else {
        var componentPromiseWrapper = componentPromiseWrappers[component];

        if (!componentPromiseWrapper) {
          componentPromiseWrappers[component] = componentPromiseWrapper = _createPromiseWrapper();
        }

        componentPromise = componentPromiseWrapper.promise;
      }

      return componentPromise;
    };
    /**
     * Destroys the component registered by the provided component ID. This invokes
     * the component's own destroy lifecycle methods (destroy or dispose) and
     * deletes the internal references to the component in the component registry.
     *
     * @param {string} componentId The ID of the component to destroy.
     */

    exports.componentReady = componentReady;

    var destroyComponent = function destroyComponent(componentId) {
      var component = components[componentId];

      if (component) {
        var destroyFn = component.destroy || component.dispose;

        if (destroyFn) {
          destroyFn.call(component);
        }

        delete componentConfigs[componentId];
        delete componentPromiseWrappers[componentId];
        delete componentsFn[componentId];
        delete components[componentId];
      }
    };
    /**
     * Destroys registered components matching the provided filter function. If no
     * filter function is provided, it destroys all registered components.
     *
     * @param {Function} filterFn A method that receives a component's destroy
     *        options and the component itself, and returns <code>true</code> if the
     *        component should be destroyed.
     */

    exports.destroyComponent = destroyComponent;

    var destroyComponents = function destroyComponents(filterFn) {
      var componentIds = Object.keys(components);

      if (filterFn) {
        componentIds = componentIds.filter(function (componentId) {
          return filterFn(components[componentId], componentConfigs[componentId] || {});
        });
      }

      componentIds.forEach(destroyComponent);
    };
    /**
     * Clears the component promises map to make sure pending promises don't get
     * accidentally resolved at a later stage if a component with the same ID
     * appears, causing stale code to run.
     */

    exports.destroyComponents = destroyComponents;

    var destroyUnfulfilledPromises = function destroyUnfulfilledPromises() {
      componentPromiseWrappers = {};
    };
    /**
     * Retrieves a registered component's cached state.
     *
     * @param {string} componentId The ID used to register the component.
     * @return {object} The state the component had prior to the previous navigation.
     */

    exports.destroyUnfulfilledPromises = destroyUnfulfilledPromises;

    var getComponentCache = function getComponentCache(componentId) {
      var componentCache = componentsCache[componentId];
      return componentCache ? componentCache.state : {};
    };
    /**
     * Initializes the component cache mechanism.
     */

    exports.getComponentCache = getComponentCache;

    var initComponentCache = function initComponentCache() {
      Liferay.on('startNavigate', _onStartNavigate);
    };

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