ckeditor5-symfony 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/dist/ckeditor5-symfony-error.d.ts +7 -0
  2. package/dist/ckeditor5-symfony-error.d.ts.map +1 -0
  3. package/dist/elements/context/context.d.ts +18 -0
  4. package/dist/elements/context/context.d.ts.map +1 -0
  5. package/dist/elements/context/contexts-registry.d.ts +9 -0
  6. package/dist/elements/context/contexts-registry.d.ts.map +1 -0
  7. package/dist/elements/context/index.d.ts +4 -0
  8. package/dist/elements/context/index.d.ts.map +1 -0
  9. package/dist/elements/context/typings.d.ts +34 -0
  10. package/dist/elements/context/typings.d.ts.map +1 -0
  11. package/dist/elements/editable.d.ts +18 -0
  12. package/dist/elements/editable.d.ts.map +1 -0
  13. package/dist/elements/editor/custom-editor-plugins.d.ts +54 -0
  14. package/dist/elements/editor/custom-editor-plugins.d.ts.map +1 -0
  15. package/dist/elements/editor/editor.d.ts +23 -0
  16. package/dist/elements/editor/editor.d.ts.map +1 -0
  17. package/dist/elements/editor/editors-registry.d.ts +9 -0
  18. package/dist/elements/editor/editors-registry.d.ts.map +1 -0
  19. package/dist/elements/editor/index.d.ts +3 -0
  20. package/dist/elements/editor/index.d.ts.map +1 -0
  21. package/dist/elements/editor/plugins/index.d.ts +2 -0
  22. package/dist/elements/editor/plugins/index.d.ts.map +1 -0
  23. package/dist/elements/editor/plugins/sync-editor-with-input.d.ts +6 -0
  24. package/dist/elements/editor/plugins/sync-editor-with-input.d.ts.map +1 -0
  25. package/dist/elements/editor/typings.d.ts +99 -0
  26. package/dist/elements/editor/typings.d.ts.map +1 -0
  27. package/dist/elements/editor/utils/create-editor-in-context.d.ts +44 -0
  28. package/dist/elements/editor/utils/create-editor-in-context.d.ts.map +1 -0
  29. package/dist/elements/editor/utils/index.d.ts +12 -0
  30. package/dist/elements/editor/utils/index.d.ts.map +1 -0
  31. package/dist/elements/editor/utils/is-single-root-editor.d.ts +9 -0
  32. package/dist/elements/editor/utils/is-single-root-editor.d.ts.map +1 -0
  33. package/dist/elements/editor/utils/load-editor-constructor.d.ts +9 -0
  34. package/dist/elements/editor/utils/load-editor-constructor.d.ts.map +1 -0
  35. package/dist/elements/editor/utils/load-editor-plugins.d.ts +20 -0
  36. package/dist/elements/editor/utils/load-editor-plugins.d.ts.map +1 -0
  37. package/dist/elements/editor/utils/load-editor-translations.d.ts +14 -0
  38. package/dist/elements/editor/utils/load-editor-translations.d.ts.map +1 -0
  39. package/dist/elements/editor/utils/normalize-custom-translations.d.ts +11 -0
  40. package/dist/elements/editor/utils/normalize-custom-translations.d.ts.map +1 -0
  41. package/dist/elements/editor/utils/query-all-editor-ids.d.ts +5 -0
  42. package/dist/elements/editor/utils/query-all-editor-ids.d.ts.map +1 -0
  43. package/dist/elements/editor/utils/query-editor-editables.d.ts +25 -0
  44. package/dist/elements/editor/utils/query-editor-editables.d.ts.map +1 -0
  45. package/dist/elements/editor/utils/resolve-editor-config-elements-references.d.ts +9 -0
  46. package/dist/elements/editor/utils/resolve-editor-config-elements-references.d.ts.map +1 -0
  47. package/dist/elements/editor/utils/set-editor-editable-height.d.ts +9 -0
  48. package/dist/elements/editor/utils/set-editor-editable-height.d.ts.map +1 -0
  49. package/dist/elements/editor/utils/wrap-with-watchdog.d.ts +24 -0
  50. package/dist/elements/editor/utils/wrap-with-watchdog.d.ts.map +1 -0
  51. package/dist/elements/index.d.ts +6 -0
  52. package/dist/elements/index.d.ts.map +1 -0
  53. package/dist/elements/register-custom-elements.d.ts +5 -0
  54. package/dist/elements/register-custom-elements.d.ts.map +1 -0
  55. package/dist/elements/ui-part.d.ts +18 -0
  56. package/dist/elements/ui-part.d.ts.map +1 -0
  57. package/dist/index.cjs +5 -0
  58. package/dist/index.cjs.map +1 -0
  59. package/dist/index.d.ts +3 -0
  60. package/dist/index.d.ts.map +1 -0
  61. package/dist/index.mjs +1089 -0
  62. package/dist/index.mjs.map +1 -0
  63. package/dist/shared/async-registry.d.ts +136 -0
  64. package/dist/shared/async-registry.d.ts.map +1 -0
  65. package/dist/shared/camel-case.d.ts +8 -0
  66. package/dist/shared/camel-case.d.ts.map +1 -0
  67. package/dist/shared/debounce.d.ts +2 -0
  68. package/dist/shared/debounce.d.ts.map +1 -0
  69. package/dist/shared/deep-camel-case-keys.d.ts +8 -0
  70. package/dist/shared/deep-camel-case-keys.d.ts.map +1 -0
  71. package/dist/shared/filter-object-values.d.ts +9 -0
  72. package/dist/shared/filter-object-values.d.ts.map +1 -0
  73. package/dist/shared/index.d.ts +15 -0
  74. package/dist/shared/index.d.ts.map +1 -0
  75. package/dist/shared/is-empty-object.d.ts +2 -0
  76. package/dist/shared/is-empty-object.d.ts.map +1 -0
  77. package/dist/shared/is-plain-object.d.ts +8 -0
  78. package/dist/shared/is-plain-object.d.ts.map +1 -0
  79. package/dist/shared/map-object-values.d.ts +11 -0
  80. package/dist/shared/map-object-values.d.ts.map +1 -0
  81. package/dist/shared/once.d.ts +2 -0
  82. package/dist/shared/once.d.ts.map +1 -0
  83. package/dist/shared/shallow-equal.d.ts +9 -0
  84. package/dist/shared/shallow-equal.d.ts.map +1 -0
  85. package/dist/shared/timeout.d.ts +8 -0
  86. package/dist/shared/timeout.d.ts.map +1 -0
  87. package/dist/shared/uid.d.ts +7 -0
  88. package/dist/shared/uid.d.ts.map +1 -0
  89. package/dist/shared/wait-for-dom-ready.d.ts +5 -0
  90. package/dist/shared/wait-for-dom-ready.d.ts.map +1 -0
  91. package/dist/shared/wait-for.d.ts +20 -0
  92. package/dist/shared/wait-for.d.ts.map +1 -0
  93. package/dist/types/can-be-promise.type.d.ts +2 -0
  94. package/dist/types/can-be-promise.type.d.ts.map +1 -0
  95. package/dist/types/index.d.ts +3 -0
  96. package/dist/types/index.d.ts.map +1 -0
  97. package/dist/types/required-by.type.d.ts +2 -0
  98. package/dist/types/required-by.type.d.ts.map +1 -0
  99. package/package.json +40 -0
  100. package/src/ckeditor5-symfony-error.ts +9 -0
  101. package/src/elements/context/context.test.ts +291 -0
  102. package/src/elements/context/context.ts +99 -0
  103. package/src/elements/context/contexts-registry.test.ts +10 -0
  104. package/src/elements/context/contexts-registry.ts +10 -0
  105. package/src/elements/context/index.ts +3 -0
  106. package/src/elements/context/typings.ts +39 -0
  107. package/src/elements/editable.test.ts +334 -0
  108. package/src/elements/editable.ts +114 -0
  109. package/src/elements/editor/custom-editor-plugins.test.ts +103 -0
  110. package/src/elements/editor/custom-editor-plugins.ts +86 -0
  111. package/src/elements/editor/editor.test.ts +438 -0
  112. package/src/elements/editor/editor.ts +279 -0
  113. package/src/elements/editor/editors-registry.test.ts +10 -0
  114. package/src/elements/editor/editors-registry.ts +10 -0
  115. package/src/elements/editor/index.ts +2 -0
  116. package/src/elements/editor/plugins/index.ts +1 -0
  117. package/src/elements/editor/plugins/sync-editor-with-input.ts +78 -0
  118. package/src/elements/editor/typings.ts +114 -0
  119. package/src/elements/editor/utils/create-editor-in-context.ts +90 -0
  120. package/src/elements/editor/utils/index.ts +11 -0
  121. package/src/elements/editor/utils/is-single-root-editor.test.ts +40 -0
  122. package/src/elements/editor/utils/is-single-root-editor.ts +11 -0
  123. package/src/elements/editor/utils/load-editor-constructor.test.ts +62 -0
  124. package/src/elements/editor/utils/load-editor-constructor.ts +29 -0
  125. package/src/elements/editor/utils/load-editor-plugins.test.ts +100 -0
  126. package/src/elements/editor/utils/load-editor-plugins.ts +73 -0
  127. package/src/elements/editor/utils/load-editor-translations.ts +233 -0
  128. package/src/elements/editor/utils/normalize-custom-translations.test.ts +152 -0
  129. package/src/elements/editor/utils/normalize-custom-translations.ts +18 -0
  130. package/src/elements/editor/utils/query-all-editor-ids.ts +9 -0
  131. package/src/elements/editor/utils/query-editor-editables.ts +101 -0
  132. package/src/elements/editor/utils/resolve-editor-config-elements-references.test.ts +93 -0
  133. package/src/elements/editor/utils/resolve-editor-config-elements-references.ts +36 -0
  134. package/src/elements/editor/utils/set-editor-editable-height.test.ts +131 -0
  135. package/src/elements/editor/utils/set-editor-editable-height.ts +15 -0
  136. package/src/elements/editor/utils/wrap-with-watchdog.test.ts +45 -0
  137. package/src/elements/editor/utils/wrap-with-watchdog.ts +51 -0
  138. package/src/elements/index.ts +14 -0
  139. package/src/elements/register-custom-elements.ts +24 -0
  140. package/src/elements/ui-part.test.ts +142 -0
  141. package/src/elements/ui-part.ts +80 -0
  142. package/src/index.ts +6 -0
  143. package/src/shared/async-registry.test.ts +737 -0
  144. package/src/shared/async-registry.ts +353 -0
  145. package/src/shared/camel-case.test.ts +35 -0
  146. package/src/shared/camel-case.ts +11 -0
  147. package/src/shared/debounce.test.ts +72 -0
  148. package/src/shared/debounce.ts +16 -0
  149. package/src/shared/deep-camel-case-keys.test.ts +34 -0
  150. package/src/shared/deep-camel-case-keys.ts +26 -0
  151. package/src/shared/filter-object-values.test.ts +25 -0
  152. package/src/shared/filter-object-values.ts +17 -0
  153. package/src/shared/index.ts +14 -0
  154. package/src/shared/is-empty-object.test.ts +78 -0
  155. package/src/shared/is-empty-object.ts +3 -0
  156. package/src/shared/is-plain-object.test.ts +38 -0
  157. package/src/shared/is-plain-object.ts +15 -0
  158. package/src/shared/map-object-values.test.ts +29 -0
  159. package/src/shared/map-object-values.ts +19 -0
  160. package/src/shared/once.test.ts +116 -0
  161. package/src/shared/once.ts +12 -0
  162. package/src/shared/shallow-equal.test.ts +51 -0
  163. package/src/shared/shallow-equal.ts +30 -0
  164. package/src/shared/timeout.test.ts +65 -0
  165. package/src/shared/timeout.ts +13 -0
  166. package/src/shared/uid.test.ts +25 -0
  167. package/src/shared/uid.ts +8 -0
  168. package/src/shared/wait-for-dom-ready.test.ts +87 -0
  169. package/src/shared/wait-for-dom-ready.ts +21 -0
  170. package/src/shared/wait-for.test.ts +24 -0
  171. package/src/shared/wait-for.ts +56 -0
  172. package/src/types/can-be-promise.type.ts +1 -0
  173. package/src/types/index.ts +2 -0
  174. package/src/types/required-by.type.ts +1 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","sources":["../src/shared/async-registry.ts","../src/shared/debounce.ts","../src/shared/filter-object-values.ts","../src/shared/is-empty-object.ts","../src/shared/map-object-values.ts","../src/shared/uid.ts","../src/shared/wait-for.ts","../src/shared/wait-for-dom-ready.ts","../src/elements/editor/utils/create-editor-in-context.ts","../src/elements/editor/utils/is-single-root-editor.ts","../src/ckeditor5-symfony-error.ts","../src/elements/editor/utils/load-editor-constructor.ts","../src/elements/editor/custom-editor-plugins.ts","../src/elements/editor/utils/load-editor-plugins.ts","../src/elements/editor/utils/load-editor-translations.ts","../src/elements/editor/utils/normalize-custom-translations.ts","../src/elements/editor/utils/query-all-editor-ids.ts","../src/elements/editor/utils/query-editor-editables.ts","../src/elements/editor/utils/resolve-editor-config-elements-references.ts","../src/elements/editor/utils/set-editor-editable-height.ts","../src/elements/editor/utils/wrap-with-watchdog.ts","../src/elements/context/contexts-registry.ts","../src/elements/context/context.ts","../src/elements/editor/editors-registry.ts","../src/elements/editable.ts","../src/elements/editor/plugins/sync-editor-with-input.ts","../src/elements/editor/editor.ts","../src/elements/ui-part.ts","../src/elements/register-custom-elements.ts","../src/index.ts"],"sourcesContent":["/**\n * Generic async registry for objects with an async destroy method.\n * Provides a way to register, unregister, and execute callbacks on objects by ID.\n */\nexport class AsyncRegistry<T extends Destructible> {\n /**\n * Map of registered items.\n */\n private readonly items = new Map<RegistryId | null, T>();\n\n /**\n * Map of initialization errors for items that failed to register.\n */\n private readonly initializationErrors = new Map<RegistryId | null, any>();\n\n /**\n * Map of pending callbacks waiting for items to be registered or fail.\n */\n private readonly pendingCallbacks = new Map<RegistryId | null, PendingCallbacks<T>>();\n\n /**\n * Set of watchers that observe changes to the registry.\n */\n private readonly watchers = new Set<RegistryWatcher<T>>();\n\n /**\n * Executes a function on an item.\n * If the item is not yet registered, it will wait for it to be registered.\n *\n * @param id The ID of the item.\n * @param onSuccess The function to execute.\n * @param onError Optional error callback.\n * @returns A promise that resolves with the result of the function.\n */\n execute<R, E extends T = T>(\n id: RegistryId | null,\n onSuccess: (item: E) => R,\n onError?: (error: any) => void,\n ): Promise<Awaited<R>> {\n const item = this.items.get(id);\n const error = this.initializationErrors.get(id);\n\n // If error exists and callback provided, invoke it immediately.\n if (error) {\n onError?.(error);\n return Promise.reject(error);\n }\n\n // If item exists, invoke callback immediately (synchronously via Promise.resolve).\n if (item) {\n return Promise.resolve(onSuccess(item as E));\n }\n\n // Item not ready yet - queue the callbacks.\n return new Promise((resolve, reject) => {\n const pending = this.getPendingCallbacks(id);\n\n pending.success.push(async (item: T) => {\n resolve(await onSuccess(item as E));\n });\n\n if (onError) {\n pending.error.push(onError);\n }\n else {\n pending.error.push(reject);\n }\n });\n }\n\n /**\n * Registers an item.\n *\n * @param id The ID of the item.\n * @param item The item instance.\n */\n register(id: RegistryId | null, item: T): void {\n if (this.items.has(id)) {\n throw new Error(`Item with ID \"${id}\" is already registered.`);\n }\n\n this.resetErrors(id);\n this.items.set(id, item);\n\n // Execute all pending callbacks for this item (synchronously).\n const pending = this.pendingCallbacks.get(id);\n\n if (pending) {\n pending.success.forEach(callback => callback(item));\n this.pendingCallbacks.delete(id);\n }\n\n // Register the first item as the default item (null ID).\n this.registerAsDefault(id, item);\n this.notifyWatchers();\n }\n\n /**\n * Registers an error for an item.\n *\n * @param id The ID of the item.\n * @param error The error to register.\n */\n error(id: RegistryId | null, error: any): void {\n this.items.delete(id);\n this.initializationErrors.set(id, error);\n\n // Execute all pending error callbacks for this item.\n const pending = this.pendingCallbacks.get(id);\n\n if (pending) {\n pending.error.forEach(callback => callback(error));\n this.pendingCallbacks.delete(id);\n }\n\n // Set as default error if this is the first error and no items exist.\n if (this.initializationErrors.size === 1 && !this.items.size) {\n this.error(null, error);\n }\n\n // Notify watchers about the error state.\n this.notifyWatchers();\n }\n\n /**\n * Resets errors for an item.\n *\n * @param id The ID of the item.\n */\n resetErrors(id: RegistryId | null): void {\n const { initializationErrors } = this;\n\n // Clear default error if it's the same as the specific error.\n if (initializationErrors.has(null) && initializationErrors.get(null) === initializationErrors.get(id)) {\n initializationErrors.delete(null);\n }\n\n initializationErrors.delete(id);\n }\n\n /**\n * Un-registers an item.\n *\n * @param id The ID of the item.\n */\n unregister(id: RegistryId | null): void {\n if (!this.items.has(id)) {\n throw new Error(`Item with ID \"${id}\" is not registered.`);\n }\n\n // If unregistering the default item, clear it.\n if (id && this.items.get(null) === this.items.get(id)) {\n this.unregister(null);\n }\n\n this.items.delete(id);\n this.pendingCallbacks.delete(id);\n\n this.notifyWatchers();\n }\n\n /**\n * Gets all registered items.\n *\n * @returns An array of all registered items.\n */\n getItems(): T[] {\n return Array.from(this.items.values());\n }\n\n /**\n * Checks if an item with the given ID is registered.\n *\n * @param id The ID of the item.\n * @returns `true` if the item is registered, `false` otherwise.\n */\n hasItem(id: RegistryId | null): boolean {\n return this.items.has(id);\n }\n\n /**\n * Gets a promise that resolves with the item instance for the given ID.\n * If the item is not registered yet, it will wait for it to be registered.\n *\n * @param id The ID of the item.\n * @param timeout Optional timeout in milliseconds.\n * @returns A promise that resolves with the item instance.\n */\n waitFor<E extends T = T>(id: RegistryId | null, timeout?: number): Promise<E> {\n return new Promise<E>((resolve, reject) => {\n let exceedTimeout = false;\n let timer: ReturnType<typeof setTimeout> | null = null;\n\n void this.execute(\n id,\n (value: E) => {\n if (exceedTimeout) {\n return;\n }\n\n if (timer !== null) {\n clearTimeout(timer!);\n }\n\n (resolve as (value: E) => void)(value);\n },\n (error: any) => {\n if (exceedTimeout) {\n return;\n }\n\n if (timer !== null) {\n clearTimeout(timer!);\n }\n\n reject(error);\n },\n );\n\n if (timeout) {\n timer = setTimeout(() => {\n exceedTimeout = true;\n reject(new Error(`Timeout waiting for item with ID \"${id}\" to be registered.`));\n }, timeout);\n }\n });\n }\n\n /**\n * Destroys all registered items and clears the registry.\n * This will call the `destroy` method on each item.\n */\n async destroyAll() {\n const promises = (\n Array\n .from(new Set(this.items.values()))\n .map(item => item.destroy())\n );\n\n this.items.clear();\n this.pendingCallbacks.clear();\n\n await Promise.all(promises);\n\n this.notifyWatchers();\n }\n\n /**\n * Registers a watcher that will be called whenever the registry changes.\n *\n * @param watcher The watcher function to register.\n * @returns A function to unregister the watcher.\n */\n watch(watcher: RegistryWatcher<T>): () => void {\n this.watchers.add(watcher);\n\n // Call the watcher immediately with the current state.\n watcher(\n new Map(this.items),\n new Map(this.initializationErrors),\n );\n\n return this.unwatch.bind(this, watcher);\n }\n\n /**\n * Un-registers a watcher.\n *\n * @param watcher The watcher function to unregister.\n */\n unwatch(watcher: RegistryWatcher<T>): void {\n this.watchers.delete(watcher);\n }\n\n /**\n * Resets the registry by clearing all items, errors, and pending callbacks.\n */\n reset(): void {\n this.items.clear();\n this.initializationErrors.clear();\n this.pendingCallbacks.clear();\n this.notifyWatchers();\n }\n\n /**\n * Notifies all watchers about changes to the registry.\n */\n private notifyWatchers(): void {\n this.watchers.forEach(\n watcher => watcher(\n new Map(this.items),\n new Map(this.initializationErrors),\n ),\n );\n }\n\n /**\n * Gets or creates pending callbacks for a specific ID.\n *\n * @param id The ID of the item.\n * @returns The pending callbacks structure.\n */\n private getPendingCallbacks(id: RegistryId | null): PendingCallbacks<T> {\n let pending = this.pendingCallbacks.get(id);\n\n if (!pending) {\n pending = { success: [], error: [] };\n this.pendingCallbacks.set(id, pending);\n }\n\n return pending;\n }\n\n /**\n * Registers an item as the default (null ID) item if it's the first one.\n *\n * @param id The ID of the item being registered.\n * @param item The item instance.\n */\n private registerAsDefault(id: RegistryId | null, item: T): void {\n if (this.items.size === 1 && id !== null) {\n this.register(null, item);\n }\n }\n}\n\n/**\n * Interface for objects that can be destroyed.\n */\nexport type Destructible = {\n destroy: () => Promise<any>;\n};\n\n/**\n * Identifier of the registry item.\n */\ntype RegistryId = string;\n\n/**\n * Structure holding pending success and error callbacks for an item.\n */\ntype PendingCallbacks<T> = {\n success: Array<(item: T) => void>;\n error: Array<(error: Error) => void>;\n};\n\n/**\n * Callback type for watching registry changes.\n */\ntype RegistryWatcher<T> = (\n items: Map<RegistryId | null, T>,\n errors: Map<RegistryId | null, Error>,\n) => void;\n","export function debounce<T extends (...args: any[]) => any>(\n delay: number,\n callback: T,\n): (...args: Parameters<T>) => void {\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n return (...args: Parameters<T>): void => {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n\n timeoutId = setTimeout(() => {\n callback(...args);\n }, delay);\n };\n}\n","/**\n * Filters the values of an object based on a provided filter function.\n *\n * @param obj The object to filter.\n * @param filter The filter function that determines whether a value should be included.\n * @returns A new object containing only the key-value pairs that passed the filter.\n */\nexport function filterObjectValues<T>(\n obj: Record<string, T>,\n filter: (value: T, key: string) => boolean,\n): Record<string, T> {\n const filteredEntries = Object\n .entries(obj)\n .filter(([key, value]) => filter(value, key));\n\n return Object.fromEntries(filteredEntries);\n}\n","export function isEmptyObject(obj: Record<string, unknown>): boolean {\n return Object.keys(obj).length === 0 && obj.constructor === Object;\n}\n","/**\n * Maps the values of an object using a provided mapper function.\n *\n * @param obj The object whose values will be mapped.\n * @param mapper A function that takes a value and its key, and returns a new value.\n * @template T The type of the original values in the object.\n * @template U The type of the new values in the object.\n * @returns A new object with the same keys as the original, but with values transformed by\n */\nexport function mapObjectValues<T, U>(\n obj: Record<string, T>,\n mapper: (value: T, key: string) => U,\n): Record<string, U> {\n const mappedEntries = Object\n .entries(obj)\n .map(([key, value]) => [key, mapper(value, key)] as const);\n\n return Object.fromEntries(mappedEntries);\n}\n","/**\n * Generates a unique identifier string\n *\n * @returns Random string that can be used as unique identifier\n */\nexport function uid() {\n return Math.random().toString(36).substring(2);\n}\n","import type { CanBePromise } from '../types';\n\n/**\n * Waits for the provided callback to succeed. The callback is executed multiple times until it succeeds or the timeout is reached.\n * It's executed immediately and then with a delay defined by the `retry` option.\n *\n * @param callback The callback to execute.\n * @param config Configuration for the function.\n * @param config.timeOutAfter The maximum time to wait for the callback to succeed, in milliseconds. Default is 500ms.\n * @param config.retryAfter The time to wait between retries, in milliseconds. Default is 100ms.\n * @returns A promise that resolves when the callback succeeds.\n */\nexport function waitFor<R>(\n callback: () => CanBePromise<R>,\n {\n timeOutAfter = 500,\n retryAfter = 100,\n }: WaitForConfig = {},\n): Promise<R> {\n return new Promise<R>((resolve, reject) => {\n const startTime = Date.now();\n let lastError: Error | null = null;\n\n const timeoutTimerId = setTimeout(() => {\n reject(lastError ?? new Error('Timeout'));\n }, timeOutAfter);\n\n const tick = async () => {\n try {\n const result = await callback();\n clearTimeout(timeoutTimerId);\n resolve(result);\n }\n catch (err: any) {\n lastError = err;\n\n if (Date.now() - startTime > timeOutAfter) {\n reject(err);\n }\n else {\n setTimeout(tick, retryAfter);\n }\n }\n };\n\n void tick();\n });\n}\n\n/**\n * Configuration for the `waitFor` function.\n */\nexport type WaitForConfig = {\n timeOutAfter?: number;\n retryAfter?: number;\n};\n","/**\n * Returns a promise that resolves when the DOM is fully loaded and ready.\n */\nexport function waitForDOMReady(): Promise<void> {\n return new Promise((resolve) => {\n switch (document.readyState) {\n case 'loading':\n document.addEventListener('DOMContentLoaded', () => resolve(), { once: true });\n break;\n\n case 'interactive':\n case 'complete':\n setTimeout(resolve, 0);\n break;\n\n default:\n console.warn('Unexpected document.readyState:', document.readyState);\n setTimeout(resolve, 0);\n }\n });\n}\n","import type { Context, ContextWatchdog, Editor, EditorConfig } from 'ckeditor5';\n\nimport type { EditorCreator } from './wrap-with-watchdog';\n\nimport { uid } from '../../../shared';\n\n/**\n * Symbol used to store the context watchdog on the editor instance.\n * Internal use only.\n */\nconst CONTEXT_EDITOR_WATCHDOG_SYMBOL = Symbol.for('context-editor-watchdog');\n\n/**\n * Creates a CKEditor 5 editor instance within a given context watchdog.\n *\n * @param params Parameters for editor creation.\n * @param params.element The DOM element or data for the editor.\n * @param params.context The context watchdog instance.\n * @param params.creator The editor creator utility.\n * @param params.config The editor configuration object.\n * @returns The created editor instance.\n */\nexport async function createEditorInContext({ element, context, creator, config }: Attrs) {\n const editorContextId = uid();\n\n await context.add({\n creator: (_element, _config) => creator.create(_element, _config),\n id: editorContextId,\n sourceElementOrData: element,\n type: 'editor',\n config,\n });\n\n const editor = context.getItem(editorContextId) as Editor;\n const contextDescriptor: EditorContextDescriptor = {\n state: 'available',\n editorContextId,\n context,\n };\n\n (editor as any)[CONTEXT_EDITOR_WATCHDOG_SYMBOL] = contextDescriptor;\n\n // Destroying of context is async. There can be situation when the destroy of the context\n // and the destroy of the editor is called in parallel. It often happens during unmounting of\n // phoenix hooks. Let's make sure that descriptor informs other components, that context is being\n // destroyed.\n const originalDestroy = context.destroy.bind(context);\n context.destroy = async () => {\n contextDescriptor.state = 'unavailable';\n return originalDestroy();\n };\n\n return {\n ...contextDescriptor,\n editor,\n };\n}\n\n/**\n * Retrieves the context watchdog from an editor instance, if available.\n *\n * @param editor The editor instance.\n * @returns The context watchdog or null if not found.\n */\nexport function unwrapEditorContext(editor: Editor): EditorContextDescriptor | null {\n if (CONTEXT_EDITOR_WATCHDOG_SYMBOL in editor) {\n return (editor as any)[CONTEXT_EDITOR_WATCHDOG_SYMBOL];\n }\n\n return null;\n}\n\n/**\n * Parameters for creating an editor in a context.\n */\ntype Attrs = {\n context: ContextWatchdog<Context>;\n creator: EditorCreator;\n element: HTMLElement;\n config: EditorConfig;\n};\n\n/**\n * Descriptor for an editor context.\n */\ntype EditorContextDescriptor = {\n state: 'available' | 'unavailable';\n editorContextId: string;\n context: ContextWatchdog<Context>;\n};\n","import type { EditorType } from '../typings';\n\n/**\n * Checks if the given editor type is one of the single editing-like editors.\n *\n * @param editorType - The type of the editor to check.\n * @returns `true` if the editor type is 'inline', 'classic', or 'balloon', otherwise `false`.\n */\nexport function isSingleRootEditor(editorType: EditorType): boolean {\n return ['inline', 'classic', 'balloon', 'decoupled'].includes(editorType);\n}\n","/**\n * Custom error class for CKEditor5 Symfony-related errors.\n */\nexport class CKEditor5SymfonyError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'CKEditor5SymfonyError';\n }\n}\n","import type { EditorType } from '../typings';\n\nimport { CKEditor5SymfonyError } from '../../../ckeditor5-symfony-error';\n\n/**\n * Returns the constructor for the specified CKEditor5 editor type.\n *\n * @param type - The type of the editor to load.\n * @returns A promise that resolves to the editor constructor.\n */\nexport async function loadEditorConstructor(type: EditorType) {\n const PKG = await import('ckeditor5');\n\n const editorMap = {\n inline: PKG.InlineEditor,\n balloon: PKG.BalloonEditor,\n classic: PKG.ClassicEditor,\n decoupled: PKG.DecoupledEditor,\n multiroot: PKG.MultiRootEditor,\n } as const;\n\n const EditorConstructor = editorMap[type];\n\n if (!EditorConstructor) {\n throw new CKEditor5SymfonyError(`Unsupported editor type: ${type}`);\n }\n\n return EditorConstructor;\n}\n","import type { PluginConstructor } from 'ckeditor5';\n\nimport type { CanBePromise } from '../../types';\n\nimport { CKEditor5SymfonyError } from '../../ckeditor5-symfony-error';\n\ntype PluginReader = () => CanBePromise<PluginConstructor>;\n\n/**\n * Registry for custom CKEditor plugins.\n * Allows registration and retrieval of custom plugins that can be used alongside built-in plugins.\n */\nexport class CustomEditorPluginsRegistry {\n static readonly the = new CustomEditorPluginsRegistry();\n\n /**\n * Map of registered custom plugins.\n */\n private readonly plugins = new Map<string, PluginReader>();\n\n /**\n * Private constructor to enforce singleton pattern.\n */\n private constructor() {}\n\n /**\n * Registers a custom plugin for the CKEditor.\n *\n * @param name The name of the plugin.\n * @param reader The plugin reader function that returns the plugin constructor.\n * @returns A function to unregister the plugin.\n */\n register(name: string, reader: PluginReader): () => void {\n if (this.plugins.has(name)) {\n throw new CKEditor5SymfonyError(`Plugin with name \"${name}\" is already registered.`);\n }\n\n this.plugins.set(name, reader);\n\n return this.unregister.bind(this, name);\n }\n\n /**\n * Removes a custom plugin by its name.\n *\n * @param name The name of the plugin to unregister.\n * @throws Will throw an error if the plugin is not registered.\n */\n unregister(name: string): void {\n if (!this.plugins.has(name)) {\n throw new CKEditor5SymfonyError(`Plugin with name \"${name}\" is not registered.`);\n }\n\n this.plugins.delete(name);\n }\n\n /**\n * Removes all custom editor plugins.\n * This is useful for cleanup in tests or when reloading plugins.\n */\n unregisterAll(): void {\n this.plugins.clear();\n }\n\n /**\n * Retrieves a custom plugin by its name.\n *\n * @param name The name of the plugin.\n * @returns The plugin constructor or undefined if not found.\n */\n async get(name: string): Promise<PluginConstructor | undefined> {\n const reader = this.plugins.get(name);\n\n return reader?.();\n }\n\n /**\n * Checks if a plugin with the given name is registered.\n *\n * @param name The name of the plugin.\n * @returns `true` if the plugin is registered, `false` otherwise.\n */\n has(name: string): boolean {\n return this.plugins.has(name);\n }\n}\n","import type { PluginConstructor } from 'ckeditor5';\n\nimport type { EditorPlugin } from '../typings';\n\nimport { CKEditor5SymfonyError } from '../../../ckeditor5-symfony-error';\nimport { CustomEditorPluginsRegistry } from '../custom-editor-plugins';\n\n/**\n * Loads CKEditor plugins from base and premium packages.\n * First tries to load from the base 'ckeditor5' package, then falls back to 'ckeditor5-premium-features'.\n *\n * @param plugins - Array of plugin names to load\n * @returns Promise that resolves to an array of loaded Plugin instances\n * @throws Error if a plugin is not found in either package\n */\nexport async function loadEditorPlugins(plugins: EditorPlugin[]): Promise<LoadedPlugins> {\n const basePackage = await import('ckeditor5');\n let premiumPackage: Record<string, any> | null = null;\n\n const loaders = plugins.map(async (plugin) => {\n // Let's first try to load the plugin from the base package.\n // Coverage is disabled due to Vitest issues with mocking dynamic imports.\n\n // If the plugin is not found in the base package, try custom plugins.\n const customPlugin = await CustomEditorPluginsRegistry.the.get(plugin);\n\n if (customPlugin) {\n return customPlugin;\n }\n\n // If not found, try to load from the base package.\n const { [plugin]: basePkgImport } = basePackage as Record<string, unknown>;\n\n if (basePkgImport) {\n return basePkgImport as PluginConstructor;\n }\n\n // Plugin not found in base package, try premium package.\n if (!premiumPackage) {\n try {\n premiumPackage = await import('ckeditor5-premium-features');\n /* v8 ignore next 6 */\n }\n catch (error) {\n console.error(`Failed to load premium package: ${error}`);\n throw new CKEditor5SymfonyError(`Plugin \"${plugin}\" not found in base package and failed to load premium package.`);\n }\n }\n\n /* v8 ignore next */\n const { [plugin]: premiumPkgImport } = premiumPackage || {};\n\n if (premiumPkgImport) {\n return premiumPkgImport as PluginConstructor;\n }\n\n // Plugin not found in either package, throw an error.\n throw new CKEditor5SymfonyError(`Plugin \"${plugin}\" not found in base or premium packages.`);\n });\n\n return {\n loadedPlugins: await Promise.all(loaders),\n hasPremium: !!premiumPackage,\n };\n}\n\n/**\n * Type representing the loaded plugins and whether premium features are available.\n */\ntype LoadedPlugins = {\n loadedPlugins: PluginConstructor<any>[];\n hasPremium: boolean;\n};\n","/**\n * Loads all required translations for the editor based on the language configuration.\n *\n * @param language - The language configuration object containing UI and content language codes.\n * @param language.ui - The UI language code.\n * @param language.content - The content language code.\n * @param hasPremium - Whether premium features are enabled and premium translations should be loaded.\n * @returns A promise that resolves to an array of loaded translation objects.\n */\nexport async function loadAllEditorTranslations(\n language: { ui: string; content: string; },\n hasPremium: boolean,\n) {\n const translations = [language.ui, language.content];\n const loadedTranslations = await Promise.all(\n [\n loadEditorPkgTranslations('ckeditor5', translations),\n /* v8 ignore next */\n hasPremium && loadEditorPkgTranslations('ckeditor5-premium-features', translations),\n ].filter(pkg => !!pkg),\n )\n .then(translations => translations.flat());\n\n return loadedTranslations;\n}\n\n/**\n * Loads the editor translations for the given languages.\n *\n * Make sure this function is properly compiled and bundled in self hosted environments!\n *\n * @param pkg - The package to load translations from ('ckeditor5' or 'ckeditor5-premium-features').\n * @param translations - The list of language codes to load translations for.\n * @returns A promise that resolves to an array of loaded translation packs.\n */\nasync function loadEditorPkgTranslations(\n pkg: EditorPkgName,\n translations: string[],\n) {\n /* v8 ignore next */\n return await Promise.all(\n translations\n .filter(lang => lang !== 'en') // 'en' is the default language, no need to load it.\n .map(async (lang) => {\n const pack = await loadEditorTranslation(pkg, lang);\n\n /* v8 ignore next */\n return pack?.default ?? pack;\n })\n .filter(Boolean),\n );\n}\n\n/**\n * Type representing the package name for CKEditor 5.\n */\ntype EditorPkgName = 'ckeditor5' | 'ckeditor5-premium-features';\n\n/**\n * Load translation for CKEditor 5\n * @param pkg - Package type: 'ckeditor5' or 'premium'\n * @param lang - Language code (e.g., 'pl', 'en', 'de')\n * @returns Translation object or null if failed\n */\nasync function loadEditorTranslation(pkg: EditorPkgName, lang: string): Promise<any> {\n try {\n /* v8 ignore next 2 */\n if (pkg === 'ckeditor5') {\n /* v8 ignore next 79 */\n switch (lang) {\n case 'af': return await import('ckeditor5/translations/af.js');\n case 'ar': return await import('ckeditor5/translations/ar.js');\n case 'ast': return await import('ckeditor5/translations/ast.js');\n case 'az': return await import('ckeditor5/translations/az.js');\n case 'bg': return await import('ckeditor5/translations/bg.js');\n case 'bn': return await import('ckeditor5/translations/bn.js');\n case 'bs': return await import('ckeditor5/translations/bs.js');\n case 'ca': return await import('ckeditor5/translations/ca.js');\n case 'cs': return await import('ckeditor5/translations/cs.js');\n case 'da': return await import('ckeditor5/translations/da.js');\n case 'de': return await import('ckeditor5/translations/de.js');\n case 'de-ch': return await import('ckeditor5/translations/de-ch.js');\n case 'el': return await import('ckeditor5/translations/el.js');\n case 'en': return await import('ckeditor5/translations/en.js');\n case 'en-au': return await import('ckeditor5/translations/en-au.js');\n case 'en-gb': return await import('ckeditor5/translations/en-gb.js');\n case 'eo': return await import('ckeditor5/translations/eo.js');\n case 'es': return await import('ckeditor5/translations/es.js');\n case 'es-co': return await import('ckeditor5/translations/es-co.js');\n case 'et': return await import('ckeditor5/translations/et.js');\n case 'eu': return await import('ckeditor5/translations/eu.js');\n case 'fa': return await import('ckeditor5/translations/fa.js');\n case 'fi': return await import('ckeditor5/translations/fi.js');\n case 'fr': return await import('ckeditor5/translations/fr.js');\n case 'gl': return await import('ckeditor5/translations/gl.js');\n case 'gu': return await import('ckeditor5/translations/gu.js');\n case 'he': return await import('ckeditor5/translations/he.js');\n case 'hi': return await import('ckeditor5/translations/hi.js');\n case 'hr': return await import('ckeditor5/translations/hr.js');\n case 'hu': return await import('ckeditor5/translations/hu.js');\n case 'hy': return await import('ckeditor5/translations/hy.js');\n case 'id': return await import('ckeditor5/translations/id.js');\n case 'it': return await import('ckeditor5/translations/it.js');\n case 'ja': return await import('ckeditor5/translations/ja.js');\n case 'jv': return await import('ckeditor5/translations/jv.js');\n case 'kk': return await import('ckeditor5/translations/kk.js');\n case 'km': return await import('ckeditor5/translations/km.js');\n case 'kn': return await import('ckeditor5/translations/kn.js');\n case 'ko': return await import('ckeditor5/translations/ko.js');\n case 'ku': return await import('ckeditor5/translations/ku.js');\n case 'lt': return await import('ckeditor5/translations/lt.js');\n case 'lv': return await import('ckeditor5/translations/lv.js');\n case 'ms': return await import('ckeditor5/translations/ms.js');\n case 'nb': return await import('ckeditor5/translations/nb.js');\n case 'ne': return await import('ckeditor5/translations/ne.js');\n case 'nl': return await import('ckeditor5/translations/nl.js');\n case 'no': return await import('ckeditor5/translations/no.js');\n case 'oc': return await import('ckeditor5/translations/oc.js');\n case 'pl': return await import('ckeditor5/translations/pl.js');\n case 'pt': return await import('ckeditor5/translations/pt.js');\n case 'pt-br': return await import('ckeditor5/translations/pt-br.js');\n case 'ro': return await import('ckeditor5/translations/ro.js');\n case 'ru': return await import('ckeditor5/translations/ru.js');\n case 'si': return await import('ckeditor5/translations/si.js');\n case 'sk': return await import('ckeditor5/translations/sk.js');\n case 'sl': return await import('ckeditor5/translations/sl.js');\n case 'sq': return await import('ckeditor5/translations/sq.js');\n case 'sr': return await import('ckeditor5/translations/sr.js');\n case 'sr-latn': return await import('ckeditor5/translations/sr-latn.js');\n case 'sv': return await import('ckeditor5/translations/sv.js');\n case 'th': return await import('ckeditor5/translations/th.js');\n case 'tk': return await import('ckeditor5/translations/tk.js');\n case 'tr': return await import('ckeditor5/translations/tr.js');\n case 'tt': return await import('ckeditor5/translations/tt.js');\n case 'ug': return await import('ckeditor5/translations/ug.js');\n case 'uk': return await import('ckeditor5/translations/uk.js');\n case 'ur': return await import('ckeditor5/translations/ur.js');\n case 'uz': return await import('ckeditor5/translations/uz.js');\n case 'vi': return await import('ckeditor5/translations/vi.js');\n case 'zh': return await import('ckeditor5/translations/zh.js');\n case 'zh-cn': return await import('ckeditor5/translations/zh-cn.js');\n default:\n console.warn(`Language ${lang} not found in ckeditor5 translations`);\n return null;\n }\n }\n /* v8 ignore next 79 */\n else {\n // Premium features translations\n switch (lang) {\n case 'af': return await import('ckeditor5-premium-features/translations/af.js');\n case 'ar': return await import('ckeditor5-premium-features/translations/ar.js');\n case 'ast': return await import('ckeditor5-premium-features/translations/ast.js');\n case 'az': return await import('ckeditor5-premium-features/translations/az.js');\n case 'bg': return await import('ckeditor5-premium-features/translations/bg.js');\n case 'bn': return await import('ckeditor5-premium-features/translations/bn.js');\n case 'bs': return await import('ckeditor5-premium-features/translations/bs.js');\n case 'ca': return await import('ckeditor5-premium-features/translations/ca.js');\n case 'cs': return await import('ckeditor5-premium-features/translations/cs.js');\n case 'da': return await import('ckeditor5-premium-features/translations/da.js');\n case 'de': return await import('ckeditor5-premium-features/translations/de.js');\n case 'de-ch': return await import('ckeditor5-premium-features/translations/de-ch.js');\n case 'el': return await import('ckeditor5-premium-features/translations/el.js');\n case 'en': return await import('ckeditor5-premium-features/translations/en.js');\n case 'en-au': return await import('ckeditor5-premium-features/translations/en-au.js');\n case 'en-gb': return await import('ckeditor5-premium-features/translations/en-gb.js');\n case 'eo': return await import('ckeditor5-premium-features/translations/eo.js');\n case 'es': return await import('ckeditor5-premium-features/translations/es.js');\n case 'es-co': return await import('ckeditor5-premium-features/translations/es-co.js');\n case 'et': return await import('ckeditor5-premium-features/translations/et.js');\n case 'eu': return await import('ckeditor5-premium-features/translations/eu.js');\n case 'fa': return await import('ckeditor5-premium-features/translations/fa.js');\n case 'fi': return await import('ckeditor5-premium-features/translations/fi.js');\n case 'fr': return await import('ckeditor5-premium-features/translations/fr.js');\n case 'gl': return await import('ckeditor5-premium-features/translations/gl.js');\n case 'gu': return await import('ckeditor5-premium-features/translations/gu.js');\n case 'he': return await import('ckeditor5-premium-features/translations/he.js');\n case 'hi': return await import('ckeditor5-premium-features/translations/hi.js');\n case 'hr': return await import('ckeditor5-premium-features/translations/hr.js');\n case 'hu': return await import('ckeditor5-premium-features/translations/hu.js');\n case 'hy': return await import('ckeditor5-premium-features/translations/hy.js');\n case 'id': return await import('ckeditor5-premium-features/translations/id.js');\n case 'it': return await import('ckeditor5-premium-features/translations/it.js');\n case 'ja': return await import('ckeditor5-premium-features/translations/ja.js');\n case 'jv': return await import('ckeditor5-premium-features/translations/jv.js');\n case 'kk': return await import('ckeditor5-premium-features/translations/kk.js');\n case 'km': return await import('ckeditor5-premium-features/translations/km.js');\n case 'kn': return await import('ckeditor5-premium-features/translations/kn.js');\n case 'ko': return await import('ckeditor5-premium-features/translations/ko.js');\n case 'ku': return await import('ckeditor5-premium-features/translations/ku.js');\n case 'lt': return await import('ckeditor5-premium-features/translations/lt.js');\n case 'lv': return await import('ckeditor5-premium-features/translations/lv.js');\n case 'ms': return await import('ckeditor5-premium-features/translations/ms.js');\n case 'nb': return await import('ckeditor5-premium-features/translations/nb.js');\n case 'ne': return await import('ckeditor5-premium-features/translations/ne.js');\n case 'nl': return await import('ckeditor5-premium-features/translations/nl.js');\n case 'no': return await import('ckeditor5-premium-features/translations/no.js');\n case 'oc': return await import('ckeditor5-premium-features/translations/oc.js');\n case 'pl': return await import('ckeditor5-premium-features/translations/pl.js');\n case 'pt': return await import('ckeditor5-premium-features/translations/pt.js');\n case 'pt-br': return await import('ckeditor5-premium-features/translations/pt-br.js');\n case 'ro': return await import('ckeditor5-premium-features/translations/ro.js');\n case 'ru': return await import('ckeditor5-premium-features/translations/ru.js');\n case 'si': return await import('ckeditor5-premium-features/translations/si.js');\n case 'sk': return await import('ckeditor5-premium-features/translations/sk.js');\n case 'sl': return await import('ckeditor5-premium-features/translations/sl.js');\n case 'sq': return await import('ckeditor5-premium-features/translations/sq.js');\n case 'sr': return await import('ckeditor5-premium-features/translations/sr.js');\n case 'sr-latn': return await import('ckeditor5-premium-features/translations/sr-latn.js');\n case 'sv': return await import('ckeditor5-premium-features/translations/sv.js');\n case 'th': return await import('ckeditor5-premium-features/translations/th.js');\n case 'tk': return await import('ckeditor5-premium-features/translations/tk.js');\n case 'tr': return await import('ckeditor5-premium-features/translations/tr.js');\n case 'tt': return await import('ckeditor5-premium-features/translations/tt.js');\n case 'ug': return await import('ckeditor5-premium-features/translations/ug.js');\n case 'uk': return await import('ckeditor5-premium-features/translations/uk.js');\n case 'ur': return await import('ckeditor5-premium-features/translations/ur.js');\n case 'uz': return await import('ckeditor5-premium-features/translations/uz.js');\n case 'vi': return await import('ckeditor5-premium-features/translations/vi.js');\n case 'zh': return await import('ckeditor5-premium-features/translations/zh.js');\n case 'zh-cn': return await import('ckeditor5-premium-features/translations/zh-cn.js');\n default:\n console.warn(`Language ${lang} not found in premium translations`);\n return await import('ckeditor5-premium-features/translations/en.js'); // fallback to English\n }\n }\n /* v8 ignore next 7 */\n }\n catch (error) {\n console.error(`Failed to load translation for ${pkg}/${lang}:`, error);\n return null;\n }\n}\n","import type { Translations } from 'ckeditor5';\n\nimport type { EditorCustomTranslationsDictionary } from '../typings';\n\nimport { mapObjectValues } from '../../../shared';\n\n/**\n * This function takes a custom translations object and maps it to the format expected by CKEditor5.\n * Each translation dictionary is wrapped in an object with a `dictionary` key.\n *\n * @param translations - The custom translations to normalize.\n * @returns A normalized translations object suitable for CKEditor5.\n */\nexport function normalizeCustomTranslations(translations: EditorCustomTranslationsDictionary): Translations {\n return mapObjectValues(translations, dictionary => ({\n dictionary,\n }));\n}\n","/**\n * Queries all CKEditor 5 editor IDs present in the document.\n */\nexport function queryAllEditorIds(): string[] {\n return Array\n .from(document.querySelectorAll<HTMLElement>('cke5-editor'))\n .map(element => element.getAttribute('data-cke-editor-id'))\n .filter((id): id is string => id !== null);\n}\n","import type { EditorId } from '../typings';\n\nimport { filterObjectValues, mapObjectValues } from '../../../shared';\n\n/**\n * Gets the initial root elements for the editor based on its type.\n *\n * @param editorId The editor's ID.\n * @returns The root element(s) for the editor.\n */\nexport function queryEditablesElements(editorId: EditorId) {\n const editables = queryAllEditorEditables(editorId);\n\n return mapObjectValues(editables, ({ element }) => element);\n}\n\n/**\n * Gets the initial data for the roots of the editor. If the editor is a single editing-like editor,\n * it retrieves the initial value from the element's attribute. Otherwise, it returns an object mapping\n * editable names to their initial values.\n *\n * @param editorId The editor's ID.\n * @returns The initial values for the editor's roots.\n */\nexport function queryEditablesSnapshotContent(editorId: EditorId) {\n const editables = queryAllEditorEditables(editorId);\n const values = mapObjectValues(editables, ({ content }) => content);\n\n return filterObjectValues(values, value => typeof value === 'string') as Record<string, string>;\n}\n\n/**\n * Queries all editable elements within a specific editor instance. It picks\n * initial values from actually rendered elements or from the editor container's.\n *\n * It may differ from the `initialData` used during editor creation, as it might\n * not set all roots or set different values.\n *\n * @param editorId The ID of the editor to query.\n * @returns An object mapping editable names to their corresponding elements and initial values.\n */\nfunction queryAllEditorEditables(editorId: EditorId) {\n const acc = (\n Array\n .from(document.querySelectorAll<HTMLElement>(`cke5-editable[data-cke-editor-id=\"${editorId}\"]`))\n .reduce<Record<string, EditableItem>>((acc, element) => {\n const rootName = element.getAttribute('data-cke-root-name')!;\n const content = element.getAttribute('data-cke-content');\n\n acc[rootName] = {\n element: element.querySelector<HTMLElement>('[data-cke-editable-content]')!,\n content,\n };\n\n return acc;\n }, Object.create({}))\n );\n\n const editor = document.querySelector<HTMLElement>(`cke5-editor[data-cke-editor-id=\"${editorId}\"]`);\n\n /* v8 ignore next 3 */\n if (!editor) {\n return acc;\n }\n\n const currentMain = acc['main'];\n const initialRootEditableValue = JSON.parse(editor.getAttribute('data-cke-content')!);\n const contentElement = document.querySelector<HTMLElement>(`#${editorId}_editor `);\n\n // If found `main` editable, but it has no content, try to fill it from the editor container.\n if (currentMain && initialRootEditableValue?.['main']) {\n return {\n ...acc,\n main: {\n ...currentMain,\n content: currentMain.content || initialRootEditableValue['main'],\n },\n };\n }\n\n // If no `main` editable found, try to create it from the editor container.\n if (contentElement) {\n return {\n ...acc,\n main: {\n element: contentElement,\n content: initialRootEditableValue?.['main'] || null,\n },\n };\n }\n\n return acc;\n}\n\n/**\n * Type representing an editable item within an editor.\n */\nexport type EditableItem = {\n element: HTMLElement;\n content: string | null;\n};\n","/**\n * Resolves element references in configuration object.\n * Looks for objects with { $element: \"selector\" } format and replaces them with actual DOM elements.\n *\n * @param obj - Configuration object to process\n * @returns Processed configuration object with resolved element references\n */\nexport function resolveEditorConfigElementReferences<T>(obj: T): T {\n if (!obj || typeof obj !== 'object') {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map(item => resolveEditorConfigElementReferences(item)) as T;\n }\n\n const anyObj = obj as any;\n\n if (anyObj.$element && typeof anyObj.$element === 'string') {\n const element = document.querySelector(anyObj.$element);\n\n if (!element) {\n console.warn(`Element not found for selector: ${anyObj.$element}`);\n }\n\n return (element || null) as T;\n }\n\n const result = Object.create(null);\n\n for (const [key, value] of Object.entries(obj)) {\n result[key] = resolveEditorConfigElementReferences(value);\n }\n\n return result as T;\n}\n","import type { Editor } from 'ckeditor5';\n\n/**\n * Sets the height of the editable area in the CKEditor instance.\n *\n * @param instance - The CKEditor instance to modify.\n * @param height - The height in pixels to set for the editable area.\n */\nexport function setEditorEditableHeight(instance: Editor, height: number): void {\n const { editing } = instance;\n\n editing.view.change((writer) => {\n writer.setStyle('height', `${height}px`, editing.view.document.getRoot()!);\n });\n}\n","import type { Editor, EditorWatchdog } from 'ckeditor5';\n\nconst EDITOR_WATCHDOG_SYMBOL = Symbol.for('elixir-editor-watchdog');\n\n/**\n * Wraps an Editor creator with a watchdog for automatic recovery.\n *\n * @param Editor - The Editor creator to wrap.\n * @returns The Editor creator wrapped with a watchdog.\n */\nexport async function wrapWithWatchdog(Editor: EditorCreator) {\n const { EditorWatchdog } = await import('ckeditor5');\n const watchdog = new EditorWatchdog(Editor);\n\n watchdog.setCreator(async (...args: Parameters<typeof Editor['create']>) => {\n const editor = await Editor.create(...args);\n\n (editor as any)[EDITOR_WATCHDOG_SYMBOL] = watchdog;\n\n return editor;\n });\n\n return {\n watchdog,\n Constructor: {\n create: async (...args: Parameters<typeof Editor['create']>) => {\n await watchdog.create(...args);\n\n return watchdog.editor!;\n },\n },\n };\n}\n\n/**\n * Unwraps the EditorWatchdog from the editor instance.\n */\nexport function unwrapEditorWatchdog(editor: Editor): EditorWatchdog | null {\n if (EDITOR_WATCHDOG_SYMBOL in editor) {\n return (editor as any)[EDITOR_WATCHDOG_SYMBOL] as EditorWatchdog;\n }\n\n return null;\n}\n\n/**\n * Type representing an Editor creator with a create method.\n */\nexport type EditorCreator = {\n create: (...args: any) => Promise<Editor>;\n};\n","import type { Context, ContextWatchdog } from 'ckeditor5';\n\nimport { AsyncRegistry } from '../../shared';\n\n/**\n * It provides a way to register contexts and execute callbacks on them when they are available.\n */\nexport class ContextsRegistry extends AsyncRegistry<ContextWatchdog<Context>> {\n static readonly the = new ContextsRegistry();\n}\n","import type { Context, ContextWatchdog } from 'ckeditor5';\n\nimport type { EditorLanguage } from '../editor';\nimport type { ContextConfig } from './typings';\n\nimport { isEmptyObject, waitForDOMReady } from '../../shared';\nimport {\n loadAllEditorTranslations,\n loadEditorPlugins,\n normalizeCustomTranslations,\n} from '../editor/utils';\nimport { ContextsRegistry } from './contexts-registry';\n\n/**\n * The Symfony hook that mounts CKEditor context instances.\n */\nexport class ContextComponentElement extends HTMLElement {\n /**\n * The promise that resolves to the context instance.\n */\n private contextPromise: Promise<ContextWatchdog<Context>> | null = null;\n\n /**\n * Mounts the context component.\n */\n async connectedCallback() {\n await waitForDOMReady();\n\n const contextId = this.getAttribute('data-cke-context-id')!;\n const language = JSON.parse(this.getAttribute('data-cke-language')!) as EditorLanguage;\n const contextConfig = JSON.parse(this.getAttribute('data-cke-context')!) as ContextConfig;\n\n const { customTranslations, watchdogConfig, config: { plugins, ...config } } = contextConfig;\n const { loadedPlugins, hasPremium } = await loadEditorPlugins(plugins ?? []);\n\n // Mix custom translations with loaded translations.\n const loadedTranslations = await loadAllEditorTranslations(language, hasPremium);\n const mixedTranslations = [\n ...loadedTranslations,\n normalizeCustomTranslations(customTranslations || {}),\n ]\n .filter(translations => !isEmptyObject(translations));\n\n // Initialize context with watchdog.\n this.contextPromise = (async () => {\n const { ContextWatchdog, Context } = await import('ckeditor5');\n\n const instance = new ContextWatchdog(Context, {\n crashNumberLimit: 10,\n ...watchdogConfig,\n });\n\n await instance.create({\n ...config,\n language,\n plugins: loadedPlugins,\n ...mixedTranslations.length && {\n translations: mixedTranslations,\n },\n });\n\n instance.on('itemError', (...args) => {\n console.error('Context item error:', ...args);\n });\n\n return instance;\n })();\n\n const context = await this.contextPromise;\n\n if (this.isConnected) {\n ContextsRegistry.the.register(contextId, context);\n }\n }\n\n /**\n * Destroys the context component. Unmounts root from the editor.\n */\n async disconnectedCallback() {\n const contextId = this.getAttribute('data-cke-context-id');\n\n // Let's hide the element during destruction to prevent flickering.\n this.style.display = 'none';\n\n // Let's wait for the mounted promise to resolve before proceeding with destruction.\n try {\n const context = await this.contextPromise;\n\n await context?.destroy();\n }\n finally {\n this.contextPromise = null;\n\n if (contextId && ContextsRegistry.the.hasItem(contextId)) {\n ContextsRegistry.the.unregister(contextId);\n }\n }\n }\n}\n","import type { Editor } from 'ckeditor5';\n\nimport { AsyncRegistry } from '../../shared/async-registry';\n\n/**\n * It provides a way to register editors and execute callbacks on them when they are available.\n */\nexport class EditorsRegistry extends AsyncRegistry<Editor> {\n static readonly the = new EditorsRegistry();\n}\n","import type { MultiRootEditor } from 'ckeditor5';\n\nimport { CKEditor5SymfonyError } from '../ckeditor5-symfony-error';\nimport { debounce, waitForDOMReady } from '../shared';\nimport { EditorsRegistry } from './editor/editors-registry';\nimport { queryAllEditorIds } from './editor/utils';\n\n/**\n * Editable hook for Symfony. It allows you to create editables for multi-root editors.\n */\nexport class EditableComponentElement extends HTMLElement {\n /**\n * The promise that resolves when the editable is mounted.\n */\n private editorPromise: Promise<MultiRootEditor> | null = null;\n\n /**\n * Mounts the editable component.\n */\n async connectedCallback() {\n await waitForDOMReady();\n\n if (!this.hasAttribute('data-cke-editor-id')) {\n this.setAttribute('data-cke-editor-id', queryAllEditorIds()[0]!);\n }\n\n const editorId = this.getAttribute('data-cke-editor-id');\n const rootName = this.getAttribute('data-cke-root-name');\n const content = this.getAttribute('data-cke-content');\n const saveDebounceMs = Number.parseInt(this.getAttribute('data-cke-save-debounce-ms')!, 10);\n\n /* v8 ignore next 3 */\n if (!editorId || !rootName) {\n throw new CKEditor5SymfonyError('Editor ID or Root Name is missing.');\n }\n\n // If the editor is not registered yet, we will wait for it to be registered.\n this.style.display = 'block';\n this.editorPromise = EditorsRegistry.the.execute(editorId, async (editor: MultiRootEditor) => {\n const input = this.querySelector('input') as HTMLInputElement | null;\n const { ui, editing, model } = editor;\n\n if (model.document.getRoot(rootName)) {\n // If the newly added root already exists, but the newly added editable has content,\n // we need to update the root data with the editable content.\n if (content !== null) {\n const data = editor.getData({ rootName });\n\n if (data && data !== content) {\n editor.setData({\n [rootName]: content,\n });\n }\n }\n\n return editor;\n }\n\n editor.addRoot(rootName, {\n isUndoable: false,\n ...content !== null && {\n data: content,\n },\n });\n\n const contentElement = this.querySelector('[data-cke-editable-content]') as HTMLElement | null;\n const editable = ui.view.createEditable(rootName, contentElement!);\n\n ui.addEditable(editable);\n editing.view.forceRender();\n\n // Sync data with socket and input element.\n const sync = () => {\n const html = editor.getData({ rootName });\n\n if (input) {\n input.value = html;\n input.dispatchEvent(new Event('input'));\n }\n\n this.dispatchEvent(new CustomEvent('change', { detail: { value: html } }));\n };\n\n editor.model.document.on('change:data', debounce(saveDebounceMs, sync));\n sync();\n\n return editor;\n });\n }\n\n /**\n * Destroys the editable component. Unmounts root from the editor.\n */\n async disconnectedCallback() {\n const rootName = this.getAttribute('data-cke-root-name');\n\n // Let's hide the element during destruction to prevent flickering.\n this.style.display = 'none';\n\n // Let's wait for the mounted promise to resolve before proceeding with destruction.\n const editor = await this.editorPromise;\n this.editorPromise = null;\n\n // Unmount root from the editor if editor is still registered.\n if (editor && editor.state !== 'destroyed' && rootName) {\n const root = editor.model.document.getRoot(rootName);\n\n if (root && 'detachEditable' in editor) {\n editor.detachEditable(root);\n editor.detachRoot(rootName, false);\n }\n }\n }\n}\n","import type { ClassicEditor, PluginConstructor } from 'ckeditor5';\n\nimport { debounce } from '../../../shared';\n\n/**\n * Creates a SyncEditorWithInput plugin class.\n */\nexport async function createSyncEditorWithInputPlugin(saveDebounceMs: number): Promise<PluginConstructor> {\n const { Plugin } = await import('ckeditor5');\n\n return class SyncEditorWithInput extends Plugin {\n /**\n * The input element to synchronize with.\n */\n private input: HTMLInputElement | null = null;\n\n /**\n * The form element reference for cleanup.\n */\n private form: HTMLFormElement | null = null;\n\n /**\n * The name of the plugin.\n */\n static get pluginName() {\n return 'SyncEditorWithInput' as const;\n }\n\n /**\n * Initializes the plugin.\n */\n public afterInit(): void {\n const { editor } = this;\n const editorElement = (editor as ClassicEditor).sourceElement as HTMLElement;\n\n // Try to find the associated input field.\n const editorId = editorElement.id.replace(/_editor$/, '');\n\n this.input = document.getElementById(`${editorId}_input`) as HTMLInputElement | null;\n\n if (!this.input) {\n return;\n }\n\n // Setup handlers.\n editor.model.document.on('change:data', debounce(saveDebounceMs, () => this.sync()));\n editor.once('ready', this.sync);\n\n // Setup form integration.\n this.form = this.input.closest('form');\n this.form?.addEventListener('submit', this.sync);\n }\n\n /**\n * Synchronizes the editor's content with the input field.\n */\n private sync = (): void => {\n if (this.input) {\n const newValue = this.editor.getData();\n\n this.input.value = newValue;\n this.input.dispatchEvent(new Event('input', { bubbles: true }));\n }\n };\n\n /**\n * Destroys the plugin.\n */\n public override destroy(): void {\n if (this.form) {\n this.form.removeEventListener('submit', this.sync);\n }\n\n this.input = null;\n this.form = null;\n }\n };\n}\n","import type { Editor } from 'ckeditor5';\n\nimport type { EditorId, EditorLanguage, EditorPreset } from './typings';\nimport type { EditorCreator } from './utils';\n\nimport { isEmptyObject, waitFor, waitForDOMReady } from '../../shared';\nimport { ContextsRegistry } from '../context';\nimport { EditorsRegistry } from './editors-registry';\nimport { createSyncEditorWithInputPlugin } from './plugins';\nimport {\n createEditorInContext,\n isSingleRootEditor,\n loadAllEditorTranslations,\n loadEditorConstructor,\n loadEditorPlugins,\n normalizeCustomTranslations,\n queryEditablesElements,\n queryEditablesSnapshotContent,\n resolveEditorConfigElementReferences,\n setEditorEditableHeight,\n unwrapEditorContext,\n unwrapEditorWatchdog,\n wrapWithWatchdog,\n} from './utils';\n\n/**\n * The Symfony hook that manages the lifecycle of CKEditor5 instances.\n */\nexport class EditorComponentElement extends HTMLElement {\n /**\n * The promise that resolves to the editor instance.\n */\n private editorPromise: Promise<Editor> | null = null;\n\n /**\n * Mounts the editor component.\n */\n async connectedCallback(): Promise<void> {\n await waitForDOMReady();\n\n const editorId = this.getAttribute('data-cke-editor-id')!;\n\n EditorsRegistry.the.resetErrors(editorId);\n\n try {\n this.style.display = 'block';\n this.editorPromise = this.createEditor();\n\n const editor = await this.editorPromise;\n\n // Do not even try to broadcast about the registration of the editor\n // if hook was immediately destroyed.\n if (this.isConnected) {\n EditorsRegistry.the.register(editorId, editor);\n\n editor.once('destroy', () => {\n if (EditorsRegistry.the.hasItem(editorId)) {\n EditorsRegistry.the.unregister(editorId);\n }\n });\n }\n /* v8 ignore next 6 */\n }\n catch (error: any) {\n console.error(`Error initializing CKEditor5 instance with ID \"${editorId}\":`, error);\n this.editorPromise = null;\n EditorsRegistry.the.error(editorId, error);\n }\n }\n\n /**\n * Destroys the editor instance when the component is destroyed.\n * This is important to prevent memory leaks and ensure that the editor is properly cleaned up.\n */\n async disconnectedCallback() {\n // Let's hide the element during destruction to prevent flickering.\n this.style.display = 'none';\n\n // Let's wait for the mounted promise to resolve before proceeding with destruction.\n try {\n const editor = await this.editorPromise;\n\n /* v8 ignore next 3 */\n if (!editor) {\n return;\n }\n\n const editorContext = unwrapEditorContext(editor);\n const watchdog = unwrapEditorWatchdog(editor);\n\n if (editorContext) {\n // If context is present, make sure it's not in unmounting phase, as it'll kill the editors.\n // If it's being destroyed, don't do anything, as the context will take care of it.\n if (editorContext.state !== 'unavailable') {\n await editorContext.context.remove(editorContext.editorContextId);\n }\n }\n else if (watchdog) {\n await watchdog.destroy();\n }\n else {\n await editor.destroy();\n }\n }\n finally {\n this.editorPromise = null;\n }\n }\n\n /**\n * Creates the CKEditor instance.\n */\n private async createEditor() {\n const editorId = this.getAttribute('data-cke-editor-id')!;\n const preset = JSON.parse(this.getAttribute('data-cke-preset')!) as EditorPreset;\n const contextId = this.getAttribute('data-cke-context-id');\n const editableHeight = this.getAttribute('data-cke-editable-height') ? Number.parseInt(this.getAttribute('data-cke-editable-height')!, 10) : null;\n const saveDebounceMs = Number.parseInt(this.getAttribute('data-cke-save-debounce-ms')!, 10);\n const language = JSON.parse(this.getAttribute('data-cke-language')!) as EditorLanguage;\n const watchdog = this.hasAttribute('data-cke-watchdog');\n const content = JSON.parse(this.getAttribute('data-cke-content')!) as Record<string, string>;\n\n const {\n customTranslations,\n editorType,\n licenseKey,\n config: { plugins, ...config },\n } = preset;\n\n // Wrap editor creator with watchdog if needed.\n let Constructor: EditorCreator = await loadEditorConstructor(editorType);\n const context = await (\n contextId\n ? ContextsRegistry.the.waitFor(contextId)\n : null\n );\n\n // Do not use editor specific watchdog if context is attached, as the context is by default protected.\n if (watchdog && !context) {\n const wrapped = await wrapWithWatchdog(Constructor);\n\n ({ Constructor } = wrapped);\n wrapped.watchdog.on('restart', () => {\n const newInstance = wrapped.watchdog.editor!;\n\n this.editorPromise = Promise.resolve(newInstance);\n\n EditorsRegistry.the.register(editorId, newInstance);\n });\n }\n\n const { loadedPlugins, hasPremium } = await loadEditorPlugins(plugins);\n\n if (isSingleRootEditor(editorType)) {\n loadedPlugins.push(\n await createSyncEditorWithInputPlugin(saveDebounceMs),\n );\n }\n\n // Mix custom translations with loaded translations.\n const loadedTranslations = await loadAllEditorTranslations(language, hasPremium);\n const mixedTranslations = [\n ...loadedTranslations,\n normalizeCustomTranslations(customTranslations || {}),\n ]\n .filter(translations => !isEmptyObject(translations));\n\n // Let's query all elements, and create basic configuration.\n let initialData: string | Record<string, string> = {\n ...content,\n ...queryEditablesSnapshotContent(editorId),\n };\n\n if (isSingleRootEditor(editorType)) {\n initialData = initialData['main'] || '';\n }\n\n // Depending of the editor type, and parent lookup for nearest context or initialize it without it.\n const editor = await (async () => {\n let sourceElementOrData: HTMLElement | Record<string, HTMLElement> = queryEditablesElements(editorId);\n\n // Handle special case when user specified `initialData` of several root elements, but editable components\n // are not yet present in the DOM. In other words - editor is initialized before attaching root elements.\n if (!sourceElementOrData['main']) {\n const requiredRoots = (\n isSingleRootEditor(editorType)\n ? ['main']\n : Object.keys(initialData as Record<string, string>)\n );\n\n if (!checkIfAllRootsArePresent(sourceElementOrData, requiredRoots)) {\n sourceElementOrData = await waitForAllRootsToBePresent(editorId, requiredRoots);\n initialData = {\n ...content,\n ...queryEditablesSnapshotContent(editorId),\n };\n }\n }\n\n // If single root editor, unwrap the element from the object.\n if (isSingleRootEditor(editorType) && 'main' in sourceElementOrData) {\n sourceElementOrData = sourceElementOrData['main'];\n }\n\n // Construct parsed config.\n const parsedConfig = {\n ...resolveEditorConfigElementReferences(config),\n initialData,\n licenseKey,\n plugins: loadedPlugins,\n language,\n ...mixedTranslations.length && {\n translations: mixedTranslations,\n },\n };\n\n if (!context || !(sourceElementOrData instanceof HTMLElement)) {\n return Constructor.create(sourceElementOrData as any, parsedConfig);\n }\n\n const result = await createEditorInContext({\n context,\n element: sourceElementOrData,\n creator: Constructor,\n config: parsedConfig,\n });\n\n return result.editor;\n })();\n\n if (isSingleRootEditor(editorType) && editableHeight) {\n setEditorEditableHeight(editor, editableHeight);\n }\n\n return editor;\n };\n}\n\n/**\n * Checks if all required root elements are present in the elements object.\n *\n * @param elements The elements object mapping root IDs to HTMLElements.\n * @param requiredRoots The list of required root IDs.\n * @returns True if all required roots are present, false otherwise.\n */\nfunction checkIfAllRootsArePresent(elements: Record<string, HTMLElement>, requiredRoots: string[]): boolean {\n return requiredRoots.every(rootId => elements[rootId]);\n}\n\n/**\n * Waits for all required root elements to be present in the DOM.\n *\n * @param editorId The editor's ID.\n * @param requiredRoots The list of required root IDs.\n * @returns A promise that resolves to the record of root elements.\n */\nasync function waitForAllRootsToBePresent(\n editorId: EditorId,\n requiredRoots: string[],\n): Promise<Record<string, HTMLElement>> {\n return waitFor(\n () => {\n const elements = queryEditablesElements(editorId) as unknown as Record<string, HTMLElement>;\n\n if (!checkIfAllRootsArePresent(elements, requiredRoots)) {\n throw new Error(\n 'It looks like not all required root elements are present yet.\\n'\n + '* If you want to wait for them, ensure they are registered before editor initialization.\\n'\n + '* If you want lazy initialize roots, consider removing root values from the `initialData` config '\n + 'and assign initial data in editable components.\\n'\n + `Missing roots: ${requiredRoots.filter(rootId => !elements[rootId]).join(', ')}.`,\n );\n }\n\n return elements;\n },\n { timeOutAfter: 2000, retryAfter: 100 },\n );\n}\n","import { CKEditor5SymfonyError } from '../ckeditor5-symfony-error';\nimport { waitForDOMReady } from '../shared';\nimport { EditorsRegistry } from './editor/editors-registry';\nimport { queryAllEditorIds } from './editor/utils';\n\n/**\n * UI Part hook for Symfony. It allows you to create UI parts for multi-root editors.\n */\nexport class UIPartComponentElement extends HTMLElement {\n /**\n * The promise that resolves when the UI part is mounted.\n */\n private mountedPromise: Promise<void> | null = null;\n\n /**\n * Mounts the UI part component.\n */\n async connectedCallback() {\n await waitForDOMReady();\n\n const editorId = this.getAttribute('data-cke-editor-id') || queryAllEditorIds()[0]!;\n const name = this.getAttribute('data-cke-name');\n\n /* v8 ignore next 3 */\n if (!editorId || !name) {\n return;\n }\n\n // If the editor is not registered yet, we will wait for it to be registered.\n this.style.display = 'block';\n this.mountedPromise = EditorsRegistry.the.execute(editorId, (editor) => {\n const { ui } = editor;\n\n const uiViewName = mapUIPartView(name);\n const uiPart = (ui.view as any)[uiViewName!];\n\n /* v8 ignore next 3 */\n if (!uiPart) {\n throw new CKEditor5SymfonyError(`Unknown UI part name: \"${name}\". Supported names are \"toolbar\" and \"menubar\".`);\n }\n\n this.appendChild(uiPart.element);\n });\n }\n\n /**\n * Destroys the UI part component. Unmounts UI parts from the editor.\n */\n async disconnectedCallback() {\n // Let's hide the element during destruction to prevent flickering.\n this.style.display = 'none';\n\n // Let's wait for the mounted promise to resolve before proceeding with destruction.\n await this.mountedPromise;\n this.mountedPromise = null;\n\n // Unmount all UI parts from the editor.\n this.innerHTML = '';\n }\n}\n\n/**\n * Maps the UI part name to the corresponding view in the editor.\n *\n * @param name The name of the UI part.\n * @returns The name of the view in the editor.\n */\nfunction mapUIPartView(name: string): string | null {\n switch (name) {\n case 'toolbar':\n return 'toolbar';\n\n case 'menubar':\n return 'menuBarView';\n\n /* v8 ignore next 3 */\n default:\n return null;\n }\n}\n","import { ContextComponentElement } from './context';\nimport { EditableComponentElement } from './editable';\nimport { EditorComponentElement } from './editor';\nimport { UIPartComponentElement } from './ui-part';\n\nconst CUSTOM_ELEMENTS = {\n 'cke5-editor': EditorComponentElement,\n 'cke5-context': ContextComponentElement,\n 'cke5-ui-part': UIPartComponentElement,\n 'cke5-editable': EditableComponentElement,\n};\n\n/**\n * Registers all available Symfony component hooks.\n */\nexport function registerCustomElements() {\n for (const [name, CustomElement] of Object.entries(CUSTOM_ELEMENTS)) {\n if (window.customElements.get(name)) {\n continue;\n }\n\n window.customElements.define(name, CustomElement);\n }\n}\n","import { registerCustomElements } from './elements';\n\nexport { CKEditor5SymfonyError } from './ckeditor5-symfony-error';\nexport * from './elements';\n\nregisterCustomElements();\n"],"names":["AsyncRegistry","id","onSuccess","onError","item","error","resolve","reject","pending","callback","initializationErrors","timeout","exceedTimeout","timer","value","promises","watcher","debounce","delay","timeoutId","args","filterObjectValues","obj","filter","filteredEntries","key","isEmptyObject","mapObjectValues","mapper","mappedEntries","uid","waitFor","timeOutAfter","retryAfter","startTime","lastError","timeoutTimerId","tick","result","err","waitForDOMReady","CONTEXT_EDITOR_WATCHDOG_SYMBOL","createEditorInContext","element","context","creator","config","editorContextId","_element","_config","editor","contextDescriptor","originalDestroy","unwrapEditorContext","isSingleRootEditor","editorType","CKEditor5SymfonyError","message","loadEditorConstructor","type","PKG","EditorConstructor","CustomEditorPluginsRegistry","name","reader","loadEditorPlugins","plugins","basePackage","premiumPackage","loaders","plugin","customPlugin","basePkgImport","premiumPkgImport","loadAllEditorTranslations","language","hasPremium","translations","loadEditorPkgTranslations","pkg","lang","pack","loadEditorTranslation","normalizeCustomTranslations","dictionary","queryAllEditorIds","queryEditablesElements","editorId","editables","queryAllEditorEditables","queryEditablesSnapshotContent","values","content","acc","rootName","currentMain","initialRootEditableValue","contentElement","resolveEditorConfigElementReferences","anyObj","setEditorEditableHeight","instance","height","editing","writer","EDITOR_WATCHDOG_SYMBOL","wrapWithWatchdog","Editor","EditorWatchdog","watchdog","unwrapEditorWatchdog","ContextsRegistry","ContextComponentElement","contextId","contextConfig","customTranslations","watchdogConfig","loadedPlugins","mixedTranslations","ContextWatchdog","Context","EditorsRegistry","EditableComponentElement","saveDebounceMs","input","ui","model","data","editable","sync","html","root","createSyncEditorWithInputPlugin","Plugin","newValue","EditorComponentElement","editorContext","preset","editableHeight","licenseKey","Constructor","wrapped","newInstance","initialData","sourceElementOrData","requiredRoots","checkIfAllRootsArePresent","waitForAllRootsToBePresent","parsedConfig","elements","rootId","UIPartComponentElement","uiViewName","mapUIPartView","uiPart","CUSTOM_ELEMENTS","registerCustomElements","CustomElement"],"mappings":"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"}
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Generic async registry for objects with an async destroy method.
3
+ * Provides a way to register, unregister, and execute callbacks on objects by ID.
4
+ */
5
+ export declare class AsyncRegistry<T extends Destructible> {
6
+ /**
7
+ * Map of registered items.
8
+ */
9
+ private readonly items;
10
+ /**
11
+ * Map of initialization errors for items that failed to register.
12
+ */
13
+ private readonly initializationErrors;
14
+ /**
15
+ * Map of pending callbacks waiting for items to be registered or fail.
16
+ */
17
+ private readonly pendingCallbacks;
18
+ /**
19
+ * Set of watchers that observe changes to the registry.
20
+ */
21
+ private readonly watchers;
22
+ /**
23
+ * Executes a function on an item.
24
+ * If the item is not yet registered, it will wait for it to be registered.
25
+ *
26
+ * @param id The ID of the item.
27
+ * @param onSuccess The function to execute.
28
+ * @param onError Optional error callback.
29
+ * @returns A promise that resolves with the result of the function.
30
+ */
31
+ execute<R, E extends T = T>(id: RegistryId | null, onSuccess: (item: E) => R, onError?: (error: any) => void): Promise<Awaited<R>>;
32
+ /**
33
+ * Registers an item.
34
+ *
35
+ * @param id The ID of the item.
36
+ * @param item The item instance.
37
+ */
38
+ register(id: RegistryId | null, item: T): void;
39
+ /**
40
+ * Registers an error for an item.
41
+ *
42
+ * @param id The ID of the item.
43
+ * @param error The error to register.
44
+ */
45
+ error(id: RegistryId | null, error: any): void;
46
+ /**
47
+ * Resets errors for an item.
48
+ *
49
+ * @param id The ID of the item.
50
+ */
51
+ resetErrors(id: RegistryId | null): void;
52
+ /**
53
+ * Un-registers an item.
54
+ *
55
+ * @param id The ID of the item.
56
+ */
57
+ unregister(id: RegistryId | null): void;
58
+ /**
59
+ * Gets all registered items.
60
+ *
61
+ * @returns An array of all registered items.
62
+ */
63
+ getItems(): T[];
64
+ /**
65
+ * Checks if an item with the given ID is registered.
66
+ *
67
+ * @param id The ID of the item.
68
+ * @returns `true` if the item is registered, `false` otherwise.
69
+ */
70
+ hasItem(id: RegistryId | null): boolean;
71
+ /**
72
+ * Gets a promise that resolves with the item instance for the given ID.
73
+ * If the item is not registered yet, it will wait for it to be registered.
74
+ *
75
+ * @param id The ID of the item.
76
+ * @param timeout Optional timeout in milliseconds.
77
+ * @returns A promise that resolves with the item instance.
78
+ */
79
+ waitFor<E extends T = T>(id: RegistryId | null, timeout?: number): Promise<E>;
80
+ /**
81
+ * Destroys all registered items and clears the registry.
82
+ * This will call the `destroy` method on each item.
83
+ */
84
+ destroyAll(): Promise<void>;
85
+ /**
86
+ * Registers a watcher that will be called whenever the registry changes.
87
+ *
88
+ * @param watcher The watcher function to register.
89
+ * @returns A function to unregister the watcher.
90
+ */
91
+ watch(watcher: RegistryWatcher<T>): () => void;
92
+ /**
93
+ * Un-registers a watcher.
94
+ *
95
+ * @param watcher The watcher function to unregister.
96
+ */
97
+ unwatch(watcher: RegistryWatcher<T>): void;
98
+ /**
99
+ * Resets the registry by clearing all items, errors, and pending callbacks.
100
+ */
101
+ reset(): void;
102
+ /**
103
+ * Notifies all watchers about changes to the registry.
104
+ */
105
+ private notifyWatchers;
106
+ /**
107
+ * Gets or creates pending callbacks for a specific ID.
108
+ *
109
+ * @param id The ID of the item.
110
+ * @returns The pending callbacks structure.
111
+ */
112
+ private getPendingCallbacks;
113
+ /**
114
+ * Registers an item as the default (null ID) item if it's the first one.
115
+ *
116
+ * @param id The ID of the item being registered.
117
+ * @param item The item instance.
118
+ */
119
+ private registerAsDefault;
120
+ }
121
+ /**
122
+ * Interface for objects that can be destroyed.
123
+ */
124
+ export type Destructible = {
125
+ destroy: () => Promise<any>;
126
+ };
127
+ /**
128
+ * Identifier of the registry item.
129
+ */
130
+ type RegistryId = string;
131
+ /**
132
+ * Callback type for watching registry changes.
133
+ */
134
+ type RegistryWatcher<T> = (items: Map<RegistryId | null, T>, errors: Map<RegistryId | null, Error>) => void;
135
+ export {};
136
+ //# sourceMappingURL=async-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"async-registry.d.ts","sourceRoot":"","sources":["../../../src/shared/async-registry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,aAAa,CAAC,CAAC,SAAS,YAAY;IAC/C;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmC;IAEzD;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAqC;IAE1E;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAqD;IAEtF;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiC;IAE1D;;;;;;;;OAQG;IACH,OAAO,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,EACxB,EAAE,EAAE,UAAU,GAAG,IAAI,EACrB,SAAS,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,EACzB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,GAC7B,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAgCtB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,EAAE,UAAU,GAAG,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI;IAqB9C;;;;;OAKG;IACH,KAAK,CAAC,EAAE,EAAE,UAAU,GAAG,IAAI,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI;IAqB9C;;;;OAIG;IACH,WAAW,CAAC,EAAE,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI;IAWxC;;;;OAIG;IACH,UAAU,CAAC,EAAE,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI;IAgBvC;;;;OAIG;IACH,QAAQ,IAAI,CAAC,EAAE;IAIf;;;;;OAKG;IACH,OAAO,CAAC,EAAE,EAAE,UAAU,GAAG,IAAI,GAAG,OAAO;IAIvC;;;;;;;OAOG;IACH,OAAO,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,UAAU,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAwC7E;;;OAGG;IACG,UAAU;IAehB;;;;;OAKG;IACH,KAAK,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI;IAY9C;;;;OAIG;IACH,OAAO,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,IAAI;IAI1C;;OAEG;IACH,KAAK,IAAI,IAAI;IAOb;;OAEG;IACH,OAAO,CAAC,cAAc;IAStB;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;IAW3B;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB;CAK1B;AAED;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;CAC7B,CAAC;AAEF;;GAEG;AACH,KAAK,UAAU,GAAG,MAAM,CAAC;AAUzB;;GAEG;AACH,KAAK,eAAe,CAAC,CAAC,IAAI,CACxB,KAAK,EAAE,GAAG,CAAC,UAAU,GAAG,IAAI,EAAE,CAAC,CAAC,EAChC,MAAM,EAAE,GAAG,CAAC,UAAU,GAAG,IAAI,EAAE,KAAK,CAAC,KAClC,IAAI,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Converts a string to camelCase.
3
+ *
4
+ * @param str The string to convert
5
+ * @returns The camelCased string
6
+ */
7
+ export declare function camelCase(str: string): string;
8
+ //# sourceMappingURL=camel-case.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"camel-case.d.ts","sourceRoot":"","sources":["../../../src/shared/camel-case.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAI7C"}
@@ -0,0 +1,2 @@
1
+ export declare function debounce<T extends (...args: any[]) => any>(delay: number, callback: T): (...args: Parameters<T>) => void;
2
+ //# sourceMappingURL=debounce.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debounce.d.ts","sourceRoot":"","sources":["../../../src/shared/debounce.ts"],"names":[],"mappings":"AAAA,wBAAgB,QAAQ,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EACxD,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,CAAC,GACV,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,CAYlC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Recursively converts all keys of a plain object or array to camelCase.
3
+ * Skips class instances and leaves them untouched.
4
+ *
5
+ * @param input The object or array to process
6
+ */
7
+ export declare function deepCamelCaseKeys<T>(input: T): T;
8
+ //# sourceMappingURL=deep-camel-case-keys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deep-camel-case-keys.d.ts","sourceRoot":"","sources":["../../../src/shared/deep-camel-case-keys.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAgBhD"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Filters the values of an object based on a provided filter function.
3
+ *
4
+ * @param obj The object to filter.
5
+ * @param filter The filter function that determines whether a value should be included.
6
+ * @returns A new object containing only the key-value pairs that passed the filter.
7
+ */
8
+ export declare function filterObjectValues<T>(obj: Record<string, T>, filter: (value: T, key: string) => boolean): Record<string, T>;
9
+ //# sourceMappingURL=filter-object-values.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter-object-values.d.ts","sourceRoot":"","sources":["../../../src/shared/filter-object-values.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,EACtB,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,GACzC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAMnB"}
@@ -0,0 +1,15 @@
1
+ export * from './async-registry';
2
+ export * from './camel-case';
3
+ export * from './debounce';
4
+ export * from './deep-camel-case-keys';
5
+ export * from './filter-object-values';
6
+ export * from './is-empty-object';
7
+ export * from './is-plain-object';
8
+ export * from './map-object-values';
9
+ export * from './once';
10
+ export * from './shallow-equal';
11
+ export * from './timeout';
12
+ export * from './uid';
13
+ export * from './wait-for';
14
+ export * from './wait-for-dom-ready';
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,QAAQ,CAAC;AACvB,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,OAAO,CAAC;AACtB,cAAc,YAAY,CAAC;AAC3B,cAAc,sBAAsB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function isEmptyObject(obj: Record<string, unknown>): boolean;
2
+ //# sourceMappingURL=is-empty-object.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"is-empty-object.d.ts","sourceRoot":"","sources":["../../../src/shared/is-empty-object.ts"],"names":[],"mappings":"AAAA,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAEnE"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Utility to check if a value is a plain object (not an array, not null, not a class instance).
3
+ *
4
+ * @param value The value to check.
5
+ * @returns True if the value is a plain object, false otherwise.
6
+ */
7
+ export declare function isPlainObject(value: unknown): value is Record<string, unknown>;
8
+ //# sourceMappingURL=is-plain-object.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"is-plain-object.d.ts","sourceRoot":"","sources":["../../../src/shared/is-plain-object.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAQ9E"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Maps the values of an object using a provided mapper function.
3
+ *
4
+ * @param obj The object whose values will be mapped.
5
+ * @param mapper A function that takes a value and its key, and returns a new value.
6
+ * @template T The type of the original values in the object.
7
+ * @template U The type of the new values in the object.
8
+ * @returns A new object with the same keys as the original, but with values transformed by
9
+ */
10
+ export declare function mapObjectValues<T, U>(obj: Record<string, T>, mapper: (value: T, key: string) => U): Record<string, U>;
11
+ //# sourceMappingURL=map-object-values.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"map-object-values.d.ts","sourceRoot":"","sources":["../../../src/shared/map-object-values.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,CAAC,EAClC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,EACtB,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC,GACnC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAMnB"}
@@ -0,0 +1,2 @@
1
+ export declare function once<T extends (...args: any[]) => any>(fn: T): T;
2
+ //# sourceMappingURL=once.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"once.d.ts","sourceRoot":"","sources":["../../../src/shared/once.ts"],"names":[],"mappings":"AAAA,wBAAgB,IAAI,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,CAWhE"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Performs a shallow comparison of two objects.
3
+ *
4
+ * @param objA - The first object to compare.
5
+ * @param objB - The second object to compare.
6
+ * @returns True if the objects are shallowly equal, false otherwise.
7
+ */
8
+ export declare function shallowEqual<T extends Record<string, unknown>>(objA: T, objB: T): boolean;
9
+ //# sourceMappingURL=shallow-equal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shallow-equal.d.ts","sourceRoot":"","sources":["../../../src/shared/shallow-equal.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5D,IAAI,EAAE,CAAC,EACP,IAAI,EAAE,CAAC,GACN,OAAO,CAmBT"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Returns a promise that resolves after a specified number of milliseconds.
3
+ *
4
+ * @param ms The number of milliseconds to wait.
5
+ * @returns A promise that resolves after the specified time.
6
+ */
7
+ export declare function timeout(ms: number): Promise<void>;
8
+ //# sourceMappingURL=timeout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeout.d.ts","sourceRoot":"","sources":["../../../src/shared/timeout.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMjD"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Generates a unique identifier string
3
+ *
4
+ * @returns Random string that can be used as unique identifier
5
+ */
6
+ export declare function uid(): string;
7
+ //# sourceMappingURL=uid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uid.d.ts","sourceRoot":"","sources":["../../../src/shared/uid.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,GAAG,WAElB"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Returns a promise that resolves when the DOM is fully loaded and ready.
3
+ */
4
+ export declare function waitForDOMReady(): Promise<void>;
5
+ //# sourceMappingURL=wait-for-dom-ready.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wait-for-dom-ready.d.ts","sourceRoot":"","sources":["../../../src/shared/wait-for-dom-ready.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAiB/C"}
@@ -0,0 +1,20 @@
1
+ import { CanBePromise } from '../types';
2
+ /**
3
+ * Waits for the provided callback to succeed. The callback is executed multiple times until it succeeds or the timeout is reached.
4
+ * It's executed immediately and then with a delay defined by the `retry` option.
5
+ *
6
+ * @param callback The callback to execute.
7
+ * @param config Configuration for the function.
8
+ * @param config.timeOutAfter The maximum time to wait for the callback to succeed, in milliseconds. Default is 500ms.
9
+ * @param config.retryAfter The time to wait between retries, in milliseconds. Default is 100ms.
10
+ * @returns A promise that resolves when the callback succeeds.
11
+ */
12
+ export declare function waitFor<R>(callback: () => CanBePromise<R>, { timeOutAfter, retryAfter, }?: WaitForConfig): Promise<R>;
13
+ /**
14
+ * Configuration for the `waitFor` function.
15
+ */
16
+ export type WaitForConfig = {
17
+ timeOutAfter?: number;
18
+ retryAfter?: number;
19
+ };
20
+ //# sourceMappingURL=wait-for.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wait-for.d.ts","sourceRoot":"","sources":["../../../src/shared/wait-for.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7C;;;;;;;;;GASG;AACH,wBAAgB,OAAO,CAAC,CAAC,EACvB,QAAQ,EAAE,MAAM,YAAY,CAAC,CAAC,CAAC,EAC/B,EACE,YAAkB,EAClB,UAAgB,GACjB,GAAE,aAAkB,GACpB,OAAO,CAAC,CAAC,CAAC,CA6BZ;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export type CanBePromise<T> = T | Promise<T>;
2
+ //# sourceMappingURL=can-be-promise.type.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"can-be-promise.type.d.ts","sourceRoot":"","sources":["../../../src/types/can-be-promise.type.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './can-be-promise.type';
2
+ export * from './required-by.type';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export type RequiredBy<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>;
2
+ //# sourceMappingURL=required-by.type.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"required-by.type.d.ts","sourceRoot":"","sources":["../../../src/types/required-by.type.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC"}