"use strict";
/*
 * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
 * This devtool is neither made for production nor for readable output files.
 * It uses "eval()" calls to create a separate source file in the browser devtools.
 * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
 * or disable the default devtool with "devtool: false".
 * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
 */
exports.id = "src_WidgetsInitializerInternal_copy_js";
exports.ids = ["src_WidgetsInitializerInternal_copy_js"];
exports.modules = {

/***/ "./src/WidgetsInitializerInternal copy.js":
/*!************************************************!*\
  !*** ./src/WidgetsInitializerInternal copy.js ***!
  \************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   WidgetsInitializer: () => (/* binding */ WidgetsInitializer),\n/* harmony export */   WidgetsInitializerInternal: () => (/* binding */ WidgetsInitializerInternal)\n/* harmony export */ });\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./utils */ \"./src/utils.js\");\n/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\");\n/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(lodash__WEBPACK_IMPORTED_MODULE_1__);\n\r\n\r\n\r\nclass WidgetsInitializerInternal {\r\n  constructor() {\r\n    if ((typeof window !== 'undefined' ? window : global).WidgetsInitializer !== undefined) {\r\n      throw new Error('Only one instance of WidgetsInitializerInternal is allowed!')\r\n    }\r\n  }\r\n\r\n  defaultOptions = {\r\n    /** custom Widget classes dynamic loader.\r\n     * \r\n     * If provided this one will be used to load Widget classes (instead of import()), example:\r\n     * ```\r\n     * (path) => new Promise()\r\n     * ```\r\n     */\r\n    resolver: undefined,\r\n    debug: false,\r\n  };\r\n  config = this.defaultOptions;\r\n  /** Contains only root nodes (the targetNode passed to WidgetsInitializer.init())\r\n   * to mark which nodes are during initialization. Only the top level, not nested ones.\r\n   * \r\n   * Elements are removed after this node has finished its initialization (with or without errors).\r\n   * \r\n   * NOTE: we have to store list of nodes that are currently initialized outside of widget because it can be\r\n   *       some not widget node, like simple div that contains widgets inside.\r\n   * \r\n   * contains elements like:\r\n   * ```\r\n   * [\r\n   *  {\r\n   *    targetNode: HTMLElement,\r\n   *    domPath: string,\r\n   *    errorsInjected[key: ErrorTypes]: [IWidgetDestroyedErrorDetails | IOtherErrorTypeErrorDetails] // list of errors that will be injected into async WidgetsInitializer.init() if they happen before it finishes, for ex. .destroy() call may rise WidgetDestroyed\r\n   *    // IOtherErrorTypeErrorDetails - of course this interface doesn't exist right now, it is here just to show the idea\r\n   *  },\r\n   * ]\r\n   * \r\n   * interface IWidgetDestroyedErrorDetails {\r\n   *    domPath: string, // path where this error should be applied\r\n   * }\r\n   * ```\r\n  */\r\n  nodesDuringInitialization = [];\r\n  /** Contains nodes of initialized (or during initialization) widgets\r\n   * \r\n   * contains elements like:\r\n   * <HTMLElement, string | WidgetClass instance>\r\n   * value:\r\n   * string - WidgetClass has not been loaded (yet or by some error)\r\n   * WidgetClass - loaded instance of the class\r\n   */\r\n  initializedWidgets = new WeakMap();\r\n  /** contains elements like:\r\n   * [\r\n   *  { domPath: '', type, debugMsgs: [] },\r\n   * ]\r\n   */\r\n  debugLog = [];\r\n\r\n  /**\r\n   * \r\n   * @param {*} widgetPath path where widget class is located, the one from [widget] attribute \r\n   * @returns The widget class\r\n   */\r\n  async loadWidgetClass(widgetPath) {\r\n    try {\r\n      if (this.config.resolver !== undefined) {\r\n        const module = await this.config.resolver(widgetPath);\r\n        return module.default;\r\n      } else {\r\n        const module = await __webpack_require__(\"./src lazy recursive ^\\\\.\\\\/.*\\\\.js$\")(`./${widgetPath}.js`);\r\n        return module.default;\r\n      }\r\n    } catch (err) {\r\n      console.error(err);\r\n      throw err;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * \r\n   * @param {*} targetNode \r\n   * @param {*} callback \r\n   * @param {*} options \r\n   * @param {boolean} addToNodesDI used internally with false to avoid adding nested paths to this.nodesDuringInitialization\r\n   */\r\n  async init(targetNode, callback, options = {}, addToNodesDI = true) { // TODO: options here - make them configurable per instance (.init() call) because right now 2nd call will overwrite first one and will be common for all\r\n    // TODO: cleanup debugLog for this targetNodeDomPath\r\n    // TODO: check if targetNode isn't already initializing! (also including parents if they are not initializing)\r\n    this.config = { ...this.config, ...options };\r\n    const targetNodeDomPath = (0,_utils__WEBPACK_IMPORTED_MODULE_0__.getDomPath)(targetNode);\r\n    if (addToNodesDI) {\r\n      this.nodesDuringInitialization.push({\r\n        targetNode,\r\n        domPath: targetNodeDomPath,\r\n        errorsInjected: {},\r\n      });\r\n    }\r\n    const isDonePromises = [];\r\n\r\n    // TODO: fill in this.initializedWidgets with all nodes (also nested ones) synchronously to prevent async init nested widget somewhere else\r\n    //       NOTE: the above will not work if we add widgets in widget init markup!!!\r\n    //             Remember path to targetNode?\r\n    //             Or maybe create separate this.initializedInitializers .set(targetNode, something)\r\n    //             and during initialization check if all parents of targetNode does not\r\n    //             exist in this.initializedInitializers.\r\n    const nodesToInit = (0,_utils__WEBPACK_IMPORTED_MODULE_0__.getFirstLevelWidgetNodes)(targetNode); // TODO: targetNode can be a widget itself, if it is this line should look like: const nodesToInit = [targetNode]; <- test it\r\n    const initPromises = Array.from(nodesToInit).map(async widgetNode => {\r\n      let widgetNodeFromInstance = undefined;\r\n      const widgetPath = widgetNode.getAttribute('widget');\r\n      this.initializedWidgets.set( // TODO: check if it isn't already initializing/initialized! if exist in this array then: continue\r\n        widgetNode,\r\n        widgetPath // TODO: change to relativeSelector\r\n      ); // no lock here is required, because right now we have to remember that this line have to be before any await in this function!!!\r\n      // TODO: create test to test in case somebody gives await in the future before above line,\r\n      //       because in this case this.initializedWidgets cannot be guaranteed to be filled in properly if for\r\n      //       example two nested paths are started with .init() This should be enough in test:\r\n      //       WidgetsInitializer.init();\r\n      //       WidgetsInitializer.init();\r\n      try {\r\n        const WidgetClass = await this.loadWidgetClass(widgetPath);\r\n        const widgetInstance = new WidgetClass(widgetNode, widgetPath, (0,_utils__WEBPACK_IMPORTED_MODULE_0__.getDomPath)(widgetNode));\r\n        widgetNodeFromInstance = widgetInstance.widgetNode;\r\n        this.initializedWidgets.set(widgetNodeFromInstance, widgetInstance); // TODO: consider to store instances in separate WeakMap or just type (string/object) will indicate initialization state\r\n        isDonePromises.push(widgetInstance.isDonePromise);\r\n        widgetInstance.init(\r\n          err => {\r\n            if (err) {\r\n              this.addDebugMsg(widgetNodeFromInstance, err, _utils__WEBPACK_IMPORTED_MODULE_0__.DebugTypes.error);\r\n              widgetInstance.setIsDone(this);\r\n            } else {\r\n              // init all children\r\n              WidgetsInitializer.init(\r\n                widgetNodeFromInstance,\r\n                (errChildren) => {\r\n                  if (errChildren) {\r\n                    this.addDebugMsg(widgetNodeFromInstance, `${widgetPath} initialization FAILED because children failed, calling setIsDone()...`, _utils__WEBPACK_IMPORTED_MODULE_0__.DebugTypes.error);\r\n                  } else {\r\n                    this.addDebugMsg(widgetNodeFromInstance, `${widgetPath} FULLY Initialized, calling setIsDone()...`, _utils__WEBPACK_IMPORTED_MODULE_0__.DebugTypes.info);\r\n                  }\r\n                  widgetInstance.setIsDone(this);\r\n                },\r\n                this.config,\r\n                false\r\n              ).catch((err) => {\r\n                this.addDebugMsg(widgetNodeFromInstance, err, _utils__WEBPACK_IMPORTED_MODULE_0__.DebugTypes.error);\r\n                widgetInstance.setIsDone(this);\r\n              }); \r\n            }\r\n          },\r\n          this.config\r\n        ).catch((err) => {\r\n          this.addDebugMsg(widgetNodeFromInstance, err, _utils__WEBPACK_IMPORTED_MODULE_0__.DebugTypes.error);\r\n          widgetInstance.setIsDone(this);\r\n        });\r\n      } catch (err) {\r\n        this.addDebugMsg(widgetNodeFromInstance ?? widgetNode, err, _utils__WEBPACK_IMPORTED_MODULE_0__.DebugTypes.error);\r\n      }\r\n    });\r\n    // TODO: targetNode may be outdated here because of replaceWith in BaseWidget.constructor\r\n    try {\r\n      await Promise.all(initPromises); // await here is important to wait for all to add to: this.initializedWidgets\r\n    \r\n      this.addDebugMsg(targetNode, `WAITING FOR ALL WIDGETS (inside ${this.initializedWidgets.get(targetNode)?.constructor.name || ''}: ${targetNodeDomPath}) to finish...`, _utils__WEBPACK_IMPORTED_MODULE_0__.DebugTypes.info);\r\n      await Promise.all(isDonePromises);\r\n      this.addDebugMsg(targetNode, `ALL WIDGETS (inside ${this.initializedWidgets.get(targetNode)?.constructor.name || ''}: ${targetNodeDomPath}) finished initialization. (with or without errors!), cleanup...`, _utils__WEBPACK_IMPORTED_MODULE_0__.DebugTypes.info);\r\n\r\n      const errors = this.debugLog.filter(log => log.domPath.startsWith(targetNodeDomPath) && log.type === _utils__WEBPACK_IMPORTED_MODULE_0__.DebugTypes.error);\r\n\r\n      // cleanup (handle errorsInjected)\r\n      const parentDI = this.isNodeDuringInitialization(targetNode.parentNode);\r\n      if (parentDI !== undefined) {\r\n        // some upper node is still during initialization - do nothing, it will do cleanup later on\r\n      } else {\r\n        // targetNode is finalizing it's initialization\r\n        const targetNodeDI = this.nodesDuringInitialization.find((obj) => obj.targetNode === targetNode);\r\n        let nodesToDestroy = [];\r\n        if (targetNodeDI.errorsInjected[_utils__WEBPACK_IMPORTED_MODULE_0__.ErrorTypes.WidgetDestroyed]) {\r\n          nodesToDestroy = this.findWidgetDestroyedErrorsInjectedRootPathsOnly(targetNodeDI.errorsInjected[_utils__WEBPACK_IMPORTED_MODULE_0__.ErrorTypes.WidgetDestroyed])\r\n            .map((wdErr) => Array.from(targetNode.ownerDocument.querySelectorAll(wdErr.domPath))) // select nodes from DOM basing on domPath\r\n            .flat();\r\n\r\n          delete targetNodeDI.errorsInjected[_utils__WEBPACK_IMPORTED_MODULE_0__.ErrorTypes.WidgetDestroyed];\r\n        }\r\n\r\n        // handle other errors here if any in the future\r\n\r\n        if (Object.keys(targetNodeDI.errorsInjected).length > 0) {\r\n          this.addDebugMsg(targetNode, `Not all errorsInjected handled: ${Object.keys(targetNodeDI.errorsInjected).join(', ')} (inside ${this.initializedWidgets.get(targetNode)?.constructor.name || ''}: ${targetNodeDomPath})`, _utils__WEBPACK_IMPORTED_MODULE_0__.DebugTypes.error);\r\n        }\r\n        \r\n        (0,lodash__WEBPACK_IMPORTED_MODULE_1__.remove)(this.nodesDuringInitialization, (obj) => obj.targetNode === targetNode);\r\n        \r\n        nodesToDestroy.forEach(nodeToDestroy => this.destroy(nodeToDestroy)); // yes, in here, it have to be called after remove(this.nodesDuringInitialization...\r\n      }\r\n\r\n      callback(errors.length ? errors : null);\r\n    } catch (err) {\r\n      this.addDebugMsg(targetNode, err, _utils__WEBPACK_IMPORTED_MODULE_0__.DebugTypes.error);\r\n      callback(err);\r\n    }\r\n  }\r\n\r\n  destroy(targetNode) {\r\n    const targetNodeDomPath = (0,_utils__WEBPACK_IMPORTED_MODULE_0__.getDomPath)(targetNode); \r\n    const targetNodeDI = this.isNodeDuringInitialization(targetNode);\r\n    if (targetNodeDI !== undefined) {\r\n      // targetNode is during initialization OR\r\n      // targetNode is inside node that didn't finish yet it's initialization\r\n      // -> send WidgetDestroyed error\r\n      this.addDebugMsg(targetNode, `WidgetsInitializer.destroy(): targetNode is during initialization -> send WidgetDestroyed error (${targetNodeDomPath})`, _utils__WEBPACK_IMPORTED_MODULE_0__.DebugTypes.info);\r\n      this.addToErrorsInjected(\r\n        targetNodeDI.errorsInjected,\r\n        _utils__WEBPACK_IMPORTED_MODULE_0__.ErrorTypes.WidgetDestroyed,\r\n        { domPath: targetNodeDomPath }, // use targetNodeDomPath because it can be different then targetNodeDI.domPath (if targetNode is nested inside initializing path)\r\n      );\r\n    } else {\r\n      // no parents in nodesDuringInitialization -> targetNode is NOT inside already initialized path:\r\n      this.addDebugMsg(targetNode, `WidgetsInitializer.destroy(): no parents in nodesDuringInitialization -> targetNode is NOT inside already initialized path (${targetNodeDomPath})`, _utils__WEBPACK_IMPORTED_MODULE_0__.DebugTypes.info);\r\n      const widgetAttribute = targetNode.getAttribute('widget')\r\n      const widgetNodesToDestroy = widgetAttribute === null\r\n        ? (0,_utils__WEBPACK_IMPORTED_MODULE_0__.getFirstLevelWidgetNodes)(targetNode) // not a [widget] node\r\n        : [targetNode];\r\n      this.destroyNodes(widgetNodesToDestroy);\r\n    }\r\n\r\n    this.addDebugMsg(targetNode, `WidgetsInitializer.destroy(): END (${targetNodeDomPath})`, _utils__WEBPACK_IMPORTED_MODULE_0__.DebugTypes.info);\r\n  }\r\n\r\n  /** destroys widgetNodesToDestroy recursively.\r\n   * Can be called only after making sure nodes are not inside other already initializing nodes\r\n   * but nodes in passed array can be during initialization.\r\n   * \r\n   * a) find root widget nodes\r\n   * b) destroy them 1 by 1 synchronously\r\n   * c) if some of them is during initialization mark it to receive WidgetDestroyed error after initialization finishes\r\n   * d) destroy the rest synchronously 1 by 1\r\n   */\r\n  destroyNodes(widgetNodesToDestroy) {\r\n    Array.from(widgetNodesToDestroy).forEach((widgetNode) => {\r\n      const widgetNodeDomPath = (0,_utils__WEBPACK_IMPORTED_MODULE_0__.getDomPath)(widgetNode);\r\n      const widgetNodeDI = this.isNodeDuringInitialization(widgetNode);\r\n      if (widgetNodeDI !== undefined) {\r\n        // widgetNode is during initialization -> send WidgetDestroyed error\r\n        // NOTE: widget class may be not loaded yet, we cannot use it here\r\n        this.addDebugMsg(widgetNode, `WidgetsInitializer.destroyNodes(): widgetNode is during initialization -> send WidgetDestroyed error (${widgetNodeDomPath})`, _utils__WEBPACK_IMPORTED_MODULE_0__.DebugTypes.info);\r\n        if (\r\n          widgetNodeDI.domPath !== widgetNodeDomPath ||\r\n          widgetNodeDI.targetNode !== widgetNode\r\n        ) {\r\n          this.addDebugMsg(widgetNode, `WidgetsInitializer.destroyNodes(): unexpected error, widgetNodeDI.domPath !== widgetNodeDomPath (${widgetNodeDomPath})`, _utils__WEBPACK_IMPORTED_MODULE_0__.DebugTypes.error);\r\n          // widgetNodeDI.targetNode here should be the widgetNode because this method\r\n          // \"Can be called only after making sure nodes are not inside other already initializing nodes\"\r\n        }\r\n        this.addToErrorsInjected(\r\n          widgetNodeDI.errorsInjected,\r\n          _utils__WEBPACK_IMPORTED_MODULE_0__.ErrorTypes.WidgetDestroyed,\r\n          { domPath: widgetNodeDI.domPath }\r\n        );\r\n        return;\r\n      } else {\r\n        // widget finished initialization (with or without errors)\r\n        const widgetClassInstance = this.initializedWidgets.get(widgetNode);\r\n        if (widgetClassInstance === undefined) {\r\n          // NOT INITIALIZED, cannot destroy not initialized, do nothing\r\n          this.addDebugMsg(widgetNode, `WidgetsInitializer.destroyNodes(): NOT INITIALIZED, cannot destroy not initialized, do nothing (${widgetNodeDomPath})`, _utils__WEBPACK_IMPORTED_MODULE_0__.DebugTypes.info);\r\n        } else if (typeof(widgetClassInstance) === 'string') {\r\n          // widget class has not been loaded, there had to be error during loading widget class\r\n          // cleanup\r\n          this.addDebugMsg(widgetNode, `WidgetsInitializer.destroyNodes(): widget class has not been loaded, there had to be error during loading widget class (${widgetNodeDomPath})`, _utils__WEBPACK_IMPORTED_MODULE_0__.DebugTypes.info);\r\n          this.initializedWidgets.delete(widgetNode);\r\n          return;\r\n        } else {\r\n          this.addDebugMsg(widgetNode, `WidgetsInitializer.destroyNodes(): calling ${widgetClassInstance.constructor.name}.destroy()... (${widgetNodeDomPath})`, _utils__WEBPACK_IMPORTED_MODULE_0__.DebugTypes.info);\r\n          widgetClassInstance.destroy();\r\n          this.initializedWidgets.delete(widgetNode);\r\n        }\r\n      }\r\n      this.addDebugMsg(widgetNodeDomPath, `WidgetsInitializer.destroyNodes(): FINISHED DESTROYING (${widgetNodeDomPath})`, _utils__WEBPACK_IMPORTED_MODULE_0__.DebugTypes.info);\r\n    });\r\n  }\r\n\r\n  /** Traverse up (starting from targetNode inclusive) if it is in this.nodesDuringInitialization */\r\n  isNodeDuringInitialization(targetNode) {\r\n    let currentNode = targetNode;\r\n\r\n    while (currentNode) {\r\n      const nodeDI = this.nodesDuringInitialization.find((obj) => obj.targetNode === currentNode);\r\n      if (nodeDI !== undefined) {\r\n        return nodeDI;\r\n      }\r\n      currentNode = currentNode.parentNode;\r\n    }\r\n\r\n    return undefined;\r\n  }\r\n  \r\n  /**\r\n   * \r\n   * @param {{ domPath: string }} widgetDestroyedErrorsInjected \r\n   * @returns filters out only root paths (domPath)\r\n   */\r\n  findWidgetDestroyedErrorsInjectedRootPathsOnly(widgetDestroyedErrorsInjected) {\r\n    let result = [...widgetDestroyedErrorsInjected];\r\n\r\n    // TODO: it probably can be written in more optimal way, but let's leave it right now as is\r\n    widgetDestroyedErrorsInjected.forEach(widgetDestroyedError => {\r\n      result = result.filter(resultError =>\r\n        !resultError.domPath.startsWith(widgetDestroyedError.domPath + _utils__WEBPACK_IMPORTED_MODULE_0__.PATH_SEPARATOR) // all that don't start with this + separator\r\n      );\r\n    });\r\n\r\n    return result;\r\n}\r\n\r\n  addDebugMsg(targetNodeOrPath, msg, type = _utils__WEBPACK_IMPORTED_MODULE_0__.DebugTypes.info) {\r\n    // if (!WEBPACK_isProd) {\r\n    if (\r\n      this.config.debug ||\r\n      type !== _utils__WEBPACK_IMPORTED_MODULE_0__.DebugTypes.info // errors (and other debug messages other then \"info\", like maybe someday warnings) should be always added to debugLog, because they are later on returned in callback\r\n    ) {\r\n      if (Array.isArray(msg)) {\r\n        msg.forEach((m) => this.addDebugMsg(targetNodeOrPath, m.msg, m.type));\r\n        return;\r\n      }\r\n      console.log(msg);\r\n      const targetNodeDomPath = typeof(targetNodeOrPath) === 'string'\r\n        ? targetNodeOrPath\r\n        : (0,_utils__WEBPACK_IMPORTED_MODULE_0__.getDomPath)(targetNodeOrPath);\r\n      this.debugLog.push({\r\n        domPath: targetNodeDomPath,\r\n        type,\r\n        debugMsg: msg,\r\n      })\r\n    }\r\n  }\r\n\r\n  addToErrorsInjected(errorsInjected, errorType, obj) {\r\n    if (errorsInjected[errorType] === undefined) {\r\n      errorsInjected[errorType] = [];\r\n    }\r\n    errorsInjected[errorType].push(obj);\r\n  }\r\n}\r\n\r\n(typeof window !== 'undefined' ? window : global).WidgetsInitializer = new WidgetsInitializerInternal();\r\nconst WidgetsInitializer = (typeof window !== 'undefined' ? window : global).WidgetsInitializer;\n\n//# sourceURL=webpack://widgets-initializer/./src/WidgetsInitializerInternal_copy.js?");

/***/ })

};
;