@elementor/editor-v1-adapters 0.3.0 → 0.5.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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,28 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [0.5.0](https://github.com/elementor/elementor-packages/compare/@elementor/editor-v1-adapters@0.4.0...@elementor/editor-v1-adapters@0.5.0) (2023-06-11)
7
+
8
+
9
+ ### Features
10
+
11
+ * **editor-panels:** init [ED-10804] ([#44](https://github.com/elementor/elementor-packages/issues/44)) ([1ed4113](https://github.com/elementor/elementor-packages/commit/1ed41131db8fb9151163175bfa614f784159e04b))
12
+
13
+
14
+
15
+
16
+
17
+ # [0.4.0](https://github.com/elementor/elementor-packages/compare/@elementor/editor-v1-adapters@0.3.0...@elementor/editor-v1-adapters@0.4.0) (2023-06-06)
18
+
19
+
20
+ ### Features
21
+
22
+ * drop support for React 17 [ED-10982] ([#50](https://github.com/elementor/elementor-packages/issues/50)) ([59c576c](https://github.com/elementor/elementor-packages/commit/59c576ca218947dc0992616311d4d399a20e91a6))
23
+
24
+
25
+
26
+
27
+
6
28
  # 0.3.0 (2023-06-01)
7
29
 
8
30
 
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  declare function runCommand(command: string, args?: object): Promise<any>;
2
- declare function openRoute(route: string): Promise<void>;
2
+ declare function openRoute(route: string): Promise<unknown>;
3
+ declare function registerRoute(route: string): Promise<unknown>;
3
4
 
4
5
  declare function useIsPreviewMode(): boolean;
5
6
 
@@ -78,4 +79,4 @@ type EditMode = 'edit' | 'preview' | 'picker';
78
79
  declare function isRouteActive(route: string): boolean;
79
80
  declare function getCurrentEditMode(): EditMode;
80
81
 
81
- export { CommandEvent, CommandEventDescriptor, EventDescriptor, ExtendedWindow, ListenerCallback, ListenerEvent, RouteEvent, RouteEventDescriptor, WindowEvent, WindowEventDescriptor, commandEndEvent, commandStartEvent, dispatchReadyEvent, editModeChangeEvent, flushListeners, getCurrentEditMode, isReady, isRouteActive, listenTo, openRoute, routeCloseEvent, routeOpenEvent, runCommand, setReady, useIsPreviewMode, useIsRouteActive, useListenTo, useRouteStatus, v1ReadyEvent, windowEvent };
82
+ export { CommandEvent, CommandEventDescriptor, EventDescriptor, ExtendedWindow, ListenerCallback, ListenerEvent, RouteEvent, RouteEventDescriptor, WindowEvent, WindowEventDescriptor, commandEndEvent, commandStartEvent, dispatchReadyEvent, editModeChangeEvent, flushListeners, getCurrentEditMode, isReady, isRouteActive, listenTo, openRoute, registerRoute, routeCloseEvent, routeOpenEvent, runCommand, setReady, useIsPreviewMode, useIsRouteActive, useListenTo, useRouteStatus, v1ReadyEvent, windowEvent };
package/dist/index.js CHANGED
@@ -30,6 +30,7 @@ __export(src_exports, {
30
30
  isRouteActive: () => isRouteActive,
31
31
  listenTo: () => listenTo,
32
32
  openRoute: () => openRoute,
33
+ registerRoute: () => registerRoute,
33
34
  routeCloseEvent: () => routeCloseEvent,
34
35
  routeOpenEvent: () => routeOpenEvent,
35
36
  runCommand: () => runCommand,
@@ -81,6 +82,25 @@ function openRoute(route) {
81
82
  return Promise.reject(e);
82
83
  }
83
84
  }
85
+ function registerRoute(route) {
86
+ const extendedWindow = window;
87
+ if (!extendedWindow.$e?.routes?.register) {
88
+ return Promise.reject("`$e.routes.register()` is not available");
89
+ }
90
+ const routeParts = route.split("/");
91
+ if (routeParts.length < 2) {
92
+ return Promise.reject(`\`${route}\` is an invalid route`);
93
+ }
94
+ const componentRoute = routeParts.pop();
95
+ const component = routeParts.join("/");
96
+ try {
97
+ return Promise.resolve(
98
+ extendedWindow.$e.routes.register(component, componentRoute, () => null)
99
+ );
100
+ } catch (e) {
101
+ return Promise.reject(e);
102
+ }
103
+ }
84
104
 
85
105
  // src/hooks/use-listen-to.ts
86
106
  var import_react = require("react");
@@ -320,6 +340,7 @@ function useRouteStatus(route, {
320
340
  isRouteActive,
321
341
  listenTo,
322
342
  openRoute,
343
+ registerRoute,
323
344
  routeCloseEvent,
324
345
  routeOpenEvent,
325
346
  runCommand,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/dispatchers/utils.ts","../src/dispatchers/dispatchers.ts","../src/hooks/use-listen-to.ts","../src/listeners/event-creators.ts","../src/listeners/is-ready.ts","../src/listeners/utils.ts","../src/listeners/listeners.ts","../src/readers/index.ts","../src/hooks/use-is-preview-mode.ts","../src/hooks/use-is-route-active.ts","../src/hooks/use-route-status.ts"],"sourcesContent":["export * from './dispatchers';\nexport * from './hooks';\nexport * from './listeners';\nexport * from './readers';\n","import { jQueryDeferred } from './types';\n\nexport function isJQueryDeferred<T>( value: unknown ): value is jQueryDeferred<T> {\n\t// TODO: Copied from:\n\t// https://github.com/elementor/elementor/blob/6a74fc9/modules/web-cli/assets/js/core/commands.js#L410\n\n\treturn ( !! value ) &&\n\t\t'object' === typeof value &&\n\t\tObject.hasOwn( value, 'promise' ) &&\n\t\tObject.hasOwn( value, 'then' ) &&\n\t\tObject.hasOwn( value, 'fail' );\n}\n\nexport function promisifyJQueryDeferred<T>( deferred: jQueryDeferred<T> ): Promise<T> {\n\treturn new Promise( ( resolve, reject ) => {\n\t\tdeferred.then( resolve, reject );\n\t} );\n}\n","import { ExtendedWindow } from './types';\nimport { isJQueryDeferred, promisifyJQueryDeferred } from './utils';\n\nexport function runCommand( command: string, args?: object ) {\n\tconst extendedWindow = window as unknown as ExtendedWindow;\n\n\tif ( ! extendedWindow.$e?.run ) {\n\t\treturn Promise.reject( '`$e.run()` is not available' );\n\t}\n\n\tconst result = extendedWindow.$e.run( command, args );\n\n\tif ( result instanceof Promise ) {\n\t\treturn result;\n\t}\n\n\tif ( isJQueryDeferred( result ) ) {\n\t\treturn promisifyJQueryDeferred( result );\n\t}\n\n\treturn Promise.resolve( result );\n}\n\nexport function openRoute( route: string ) {\n\tconst extendedWindow = window as unknown as ExtendedWindow;\n\n\tif ( ! extendedWindow.$e?.route ) {\n\t\treturn Promise.reject( '`$e.route()` is not available' );\n\t}\n\n\ttry {\n\t\treturn Promise.resolve(\n\t\t\textendedWindow.$e.route( route )\n\t\t);\n\t} catch ( e ) {\n\t\treturn Promise.reject( e );\n\t}\n}\n","import { useEffect, useState } from 'react';\nimport { EventDescriptor, listenTo } from '../listeners';\n\nexport default function useListenTo<T>(\n\tevent: EventDescriptor | EventDescriptor[],\n\tgetSnapshot: () => T,\n\tdeps: unknown[] = []\n) {\n\tconst [ snapshot, setSnapshot ] = useState( () => getSnapshot() );\n\n\tuseEffect( () => {\n\t\tconst updateState = () => setSnapshot( getSnapshot() );\n\n\t\t// Ensure the state is re-calculated when the dependencies have been changed.\n\t\tupdateState();\n\n\t\treturn listenTo( event, updateState );\n\t}, deps ); // eslint-disable-line react-hooks/exhaustive-deps\n\n\treturn snapshot;\n}\n","import { CommandEventDescriptor, RouteEventDescriptor, WindowEventDescriptor } from './types';\n\nexport const commandStartEvent = ( command: CommandEventDescriptor['name'] ): CommandEventDescriptor => {\n\treturn {\n\t\ttype: 'command',\n\t\tname: command,\n\t\tstate: 'before',\n\t};\n};\n\nexport const commandEndEvent = ( command: CommandEventDescriptor['name'] ): CommandEventDescriptor => {\n\treturn {\n\t\ttype: 'command',\n\t\tname: command,\n\t\tstate: 'after',\n\t};\n};\n\nexport const routeOpenEvent = ( route: RouteEventDescriptor['name'] ): RouteEventDescriptor => {\n\treturn {\n\t\ttype: 'route',\n\t\tname: route,\n\t\tstate: 'open',\n\t};\n};\n\nexport const routeCloseEvent = ( route: RouteEventDescriptor['name'] ): RouteEventDescriptor => {\n\treturn {\n\t\ttype: 'route',\n\t\tname: route,\n\t\tstate: 'close',\n\t};\n};\n\nexport const windowEvent = ( event: WindowEventDescriptor['name'] ): WindowEventDescriptor => {\n\treturn {\n\t\ttype: 'window-event',\n\t\tname: event,\n\t};\n};\n\nexport const v1ReadyEvent = () => {\n\treturn windowEvent( 'elementor/initialized' );\n};\n\nexport const editModeChangeEvent = () => {\n\treturn windowEvent( 'elementor/edit-mode/change' );\n};\n","/**\n * This file is used to store the state of the isReady variable, which is used to determine\n * if the adapter is ready to receive events (editor v1 and v2 are loaded).\n */\n\nlet ready = false;\n\nexport function isReady() {\n\treturn ready;\n}\n\nexport function setReady( value: boolean ) {\n\tready = value;\n}\n","import { ExtendedWindow, ListenerEvent } from './types';\nimport { setReady } from './is-ready';\n\nexport function dispatchReadyEvent() {\n\treturn getV1LoadingPromise().then( () => {\n\t\tsetReady( true );\n\t\twindow.dispatchEvent( new CustomEvent( 'elementor/initialized' ) );\n\t} );\n}\n\nfunction getV1LoadingPromise() {\n\tconst v1LoadingPromise = ( window as unknown as ExtendedWindow ).__elementorEditorV1LoadingPromise;\n\n\tif ( ! v1LoadingPromise ) {\n\t\treturn Promise.reject( 'Elementor Editor V1 is not loaded' );\n\t}\n\n\treturn v1LoadingPromise;\n}\n\nexport function normalizeEvent( e: ListenerEvent['originalEvent'] ): ListenerEvent {\n\tif ( e instanceof CustomEvent && e.detail?.command ) {\n\t\treturn {\n\t\t\ttype: 'command',\n\t\t\tcommand: e.detail.command,\n\t\t\targs: e.detail.args,\n\t\t\toriginalEvent: e,\n\t\t};\n\t}\n\n\tif ( e instanceof CustomEvent && e.detail?.route ) {\n\t\treturn {\n\t\t\ttype: 'route',\n\t\t\troute: e.detail.route,\n\t\t\toriginalEvent: e,\n\t\t};\n\t}\n\n\treturn {\n\t\ttype: 'window-event',\n\t\tevent: e.type,\n\t\toriginalEvent: e,\n\t};\n}\n","import { normalizeEvent } from './utils';\nimport {\n\tCommandEventDescriptor,\n\tEventDescriptor,\n\tListenerCallback,\n\tRouteEventDescriptor,\n\tWindowEventDescriptor,\n} from './types';\nimport { isReady, setReady } from './is-ready';\n\nconst callbacksByEvent = new Map<EventDescriptor['name'], ListenerCallback[]>();\nlet abortController = new AbortController();\n\nexport function listenTo(\n\teventDescriptors: EventDescriptor | EventDescriptor[],\n\tcallback: ListenerCallback\n) {\n\tif ( ! Array.isArray( eventDescriptors ) ) {\n\t\teventDescriptors = [ eventDescriptors ];\n\t}\n\n\t// @see https://github.com/typescript-eslint/typescript-eslint/issues/2841\n\t// eslint-disable-next-line array-callback-return -- Clashes with typescript.\n\tconst cleanups = eventDescriptors.map( ( event ) => {\n\t\tconst { type, name } = event;\n\n\t\tswitch ( type ) {\n\t\t\tcase 'command':\n\t\t\t\treturn registerCommandListener( name, event.state, callback );\n\n\t\t\tcase 'route':\n\t\t\t\treturn registerRouteListener( name, event.state, callback );\n\n\t\t\tcase 'window-event':\n\t\t\t\treturn registerWindowEventListener( name, callback );\n\t\t}\n\t} );\n\n\treturn () => {\n\t\tcleanups.forEach( ( cleanup ) => cleanup() );\n\t};\n}\n\nexport function flushListeners() {\n\tabortController.abort();\n\tcallbacksByEvent.clear();\n\tsetReady( false );\n\n\tabortController = new AbortController();\n}\n\nfunction registerCommandListener(\n\tcommand: CommandEventDescriptor['name'],\n\tstate: CommandEventDescriptor['state'],\n\tcallback: ListenerCallback\n) {\n\treturn registerWindowEventListener( `elementor/commands/run/${ state }`, ( e ) => {\n\t\tconst shouldRunCallback = e.type === 'command' && e.command === command;\n\n\t\tif ( shouldRunCallback ) {\n\t\t\tcallback( e );\n\t\t}\n\t} );\n}\n\nfunction registerRouteListener(\n\troute: RouteEventDescriptor['name'],\n\tstate: RouteEventDescriptor['state'],\n\tcallback: ListenerCallback\n) {\n\treturn registerWindowEventListener( `elementor/routes/${ state }`, ( e ) => {\n\t\tconst shouldRunCallback = e.type === 'route' && e.route.startsWith( route );\n\n\t\tif ( shouldRunCallback ) {\n\t\t\tcallback( e );\n\t\t}\n\t} );\n}\n\nfunction registerWindowEventListener( event: WindowEventDescriptor['name'], callback: ListenerCallback ) {\n\tconst isFirstListener = ! callbacksByEvent.has( event );\n\n\tif ( isFirstListener ) {\n\t\tcallbacksByEvent.set( event, [] );\n\n\t\taddListener( event );\n\t}\n\n\tcallbacksByEvent.get( event )?.push( callback );\n\n\treturn () => {\n\t\tconst callbacks = callbacksByEvent.get( event );\n\n\t\tif ( ! callbacks?.length ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst filtered = callbacks.filter( ( cb ) => cb !== callback );\n\n\t\tcallbacksByEvent.set( event, filtered );\n\t};\n}\n\nfunction addListener( event: EventDescriptor['name'] ) {\n\twindow.addEventListener(\n\t\tevent,\n\t\tmakeEventHandler( event ),\n\t\t{ signal: abortController.signal }\n\t);\n}\n\nfunction makeEventHandler( event: EventDescriptor['name'] ): EventListener {\n\treturn ( e ) => {\n\t\tif ( ! isReady() ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst normalizedEvent = normalizeEvent( e );\n\n\t\tcallbacksByEvent.get( event )?.forEach( ( callback ) => {\n\t\t\tcallback( normalizedEvent );\n\t\t} );\n\t};\n}\n","import { ExtendedWindow } from './types';\n\nexport function isRouteActive( route: string ) {\n\tconst extendedWindow = window as unknown as ExtendedWindow;\n\n\treturn !! extendedWindow.$e?.routes?.isPartOf( route );\n}\n\nexport function getCurrentEditMode() {\n\tconst extendedWindow = window as unknown as ExtendedWindow;\n\n\treturn extendedWindow.elementor?.channels?.dataEditMode?.request?.( 'activeMode' );\n}\n","import useListenTo from './use-listen-to';\nimport { getCurrentEditMode } from '../readers';\nimport { editModeChangeEvent } from '../listeners';\n\nexport default function useIsPreviewMode() {\n\treturn useListenTo(\n\t\teditModeChangeEvent(),\n\t\t() => getCurrentEditMode() === 'preview'\n\t);\n}\n","import useListenTo from './use-listen-to';\nimport { isRouteActive } from '../readers';\nimport { routeCloseEvent, routeOpenEvent, RouteEventDescriptor } from '../listeners';\n\nexport default function useIsRouteActive( route: RouteEventDescriptor['name'] ) {\n\treturn useListenTo(\n\t\t[\n\t\t\trouteOpenEvent( route ),\n\t\t\trouteCloseEvent( route ),\n\t\t],\n\t\t() => isRouteActive( route ),\n\t\t[ route ]\n\t);\n}\n","import useIsPreviewMode from './use-is-preview-mode';\nimport useIsRouteActive from './use-is-route-active';\nimport { RouteEventDescriptor } from '../listeners';\n\ntype Options = {\n\tblockOnKitRoutes?: boolean,\n\tblockOnPreviewMode?: boolean,\n}\n\nexport default function useRouteStatus(\n\troute: RouteEventDescriptor['name'],\n\t{\n\t\tblockOnKitRoutes = true,\n\t\tblockOnPreviewMode = true,\n\t}: Options = {}\n) {\n\tconst isRouteActive = useIsRouteActive( route );\n\tconst isKitRouteActive = useIsRouteActive( 'panel/global' );\n\tconst isPreviewMode = useIsPreviewMode();\n\n\tconst isActive = isRouteActive && ! ( blockOnPreviewMode && isPreviewMode );\n\n\tconst isBlocked = (\n\t\t( blockOnPreviewMode && isPreviewMode ) ||\n\t\t( blockOnKitRoutes && isKitRouteActive )\n\t);\n\n\treturn {\n\t\tisActive,\n\t\tisBlocked,\n\t};\n}\n"],"mappings":"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","names":["isRouteActive"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/dispatchers/utils.ts","../src/dispatchers/dispatchers.ts","../src/hooks/use-listen-to.ts","../src/listeners/event-creators.ts","../src/listeners/is-ready.ts","../src/listeners/utils.ts","../src/listeners/listeners.ts","../src/readers/index.ts","../src/hooks/use-is-preview-mode.ts","../src/hooks/use-is-route-active.ts","../src/hooks/use-route-status.ts"],"sourcesContent":["export * from './dispatchers';\nexport * from './hooks';\nexport * from './listeners';\nexport * from './readers';\n","import { jQueryDeferred } from './types';\n\nexport function isJQueryDeferred<T>( value: unknown ): value is jQueryDeferred<T> {\n\t// TODO: Copied from:\n\t// https://github.com/elementor/elementor/blob/6a74fc9/modules/web-cli/assets/js/core/commands.js#L410\n\n\treturn ( !! value ) &&\n\t\t'object' === typeof value &&\n\t\tObject.hasOwn( value, 'promise' ) &&\n\t\tObject.hasOwn( value, 'then' ) &&\n\t\tObject.hasOwn( value, 'fail' );\n}\n\nexport function promisifyJQueryDeferred<T>( deferred: jQueryDeferred<T> ): Promise<T> {\n\treturn new Promise( ( resolve, reject ) => {\n\t\tdeferred.then( resolve, reject );\n\t} );\n}\n","import { ExtendedWindow } from './types';\nimport { isJQueryDeferred, promisifyJQueryDeferred } from './utils';\n\nexport function runCommand( command: string, args?: object ) {\n\tconst extendedWindow = window as unknown as ExtendedWindow;\n\n\tif ( ! extendedWindow.$e?.run ) {\n\t\treturn Promise.reject( '`$e.run()` is not available' );\n\t}\n\n\tconst result = extendedWindow.$e.run( command, args );\n\n\tif ( result instanceof Promise ) {\n\t\treturn result;\n\t}\n\n\tif ( isJQueryDeferred( result ) ) {\n\t\treturn promisifyJQueryDeferred( result );\n\t}\n\n\treturn Promise.resolve( result );\n}\n\nexport function openRoute( route: string ) {\n\tconst extendedWindow = window as unknown as ExtendedWindow;\n\n\tif ( ! extendedWindow.$e?.route ) {\n\t\treturn Promise.reject( '`$e.route()` is not available' );\n\t}\n\n\ttry {\n\t\treturn Promise.resolve(\n\t\t\textendedWindow.$e.route( route )\n\t\t);\n\t} catch ( e ) {\n\t\treturn Promise.reject( e );\n\t}\n}\n\nexport function registerRoute( route: string ) {\n\tconst extendedWindow = window as unknown as ExtendedWindow;\n\n\tif ( ! extendedWindow.$e?.routes?.register ) {\n\t\treturn Promise.reject( '`$e.routes.register()` is not available' );\n\t}\n\n\tconst routeParts = route.split( '/' );\n\n\tif ( routeParts.length < 2 ) {\n\t\treturn Promise.reject( `\\`${ route }\\` is an invalid route` );\n\t}\n\n\tconst componentRoute = routeParts.pop() as string; // routeParts.length must be >= 2\n\tconst component = routeParts.join( '/' );\n\n\ttry {\n\t\treturn Promise.resolve(\n\t\t\textendedWindow.$e.routes.register( component, componentRoute, () => null )\n\t\t);\n\t} catch ( e ) {\n\t\treturn Promise.reject( e );\n\t}\n}\n","import { useEffect, useState } from 'react';\nimport { EventDescriptor, listenTo } from '../listeners';\n\nexport default function useListenTo<T>(\n\tevent: EventDescriptor | EventDescriptor[],\n\tgetSnapshot: () => T,\n\tdeps: unknown[] = []\n) {\n\tconst [ snapshot, setSnapshot ] = useState( () => getSnapshot() );\n\n\tuseEffect( () => {\n\t\tconst updateState = () => setSnapshot( getSnapshot() );\n\n\t\t// Ensure the state is re-calculated when the dependencies have been changed.\n\t\tupdateState();\n\n\t\treturn listenTo( event, updateState );\n\t}, deps ); // eslint-disable-line react-hooks/exhaustive-deps\n\n\treturn snapshot;\n}\n","import { CommandEventDescriptor, RouteEventDescriptor, WindowEventDescriptor } from './types';\n\nexport const commandStartEvent = ( command: CommandEventDescriptor['name'] ): CommandEventDescriptor => {\n\treturn {\n\t\ttype: 'command',\n\t\tname: command,\n\t\tstate: 'before',\n\t};\n};\n\nexport const commandEndEvent = ( command: CommandEventDescriptor['name'] ): CommandEventDescriptor => {\n\treturn {\n\t\ttype: 'command',\n\t\tname: command,\n\t\tstate: 'after',\n\t};\n};\n\nexport const routeOpenEvent = ( route: RouteEventDescriptor['name'] ): RouteEventDescriptor => {\n\treturn {\n\t\ttype: 'route',\n\t\tname: route,\n\t\tstate: 'open',\n\t};\n};\n\nexport const routeCloseEvent = ( route: RouteEventDescriptor['name'] ): RouteEventDescriptor => {\n\treturn {\n\t\ttype: 'route',\n\t\tname: route,\n\t\tstate: 'close',\n\t};\n};\n\nexport const windowEvent = ( event: WindowEventDescriptor['name'] ): WindowEventDescriptor => {\n\treturn {\n\t\ttype: 'window-event',\n\t\tname: event,\n\t};\n};\n\nexport const v1ReadyEvent = () => {\n\treturn windowEvent( 'elementor/initialized' );\n};\n\nexport const editModeChangeEvent = () => {\n\treturn windowEvent( 'elementor/edit-mode/change' );\n};\n","/**\n * This file is used to store the state of the isReady variable, which is used to determine\n * if the adapter is ready to receive events (editor v1 and v2 are loaded).\n */\n\nlet ready = false;\n\nexport function isReady() {\n\treturn ready;\n}\n\nexport function setReady( value: boolean ) {\n\tready = value;\n}\n","import { ExtendedWindow, ListenerEvent } from './types';\nimport { setReady } from './is-ready';\n\nexport function dispatchReadyEvent() {\n\treturn getV1LoadingPromise().then( () => {\n\t\tsetReady( true );\n\t\twindow.dispatchEvent( new CustomEvent( 'elementor/initialized' ) );\n\t} );\n}\n\nfunction getV1LoadingPromise() {\n\tconst v1LoadingPromise = ( window as unknown as ExtendedWindow ).__elementorEditorV1LoadingPromise;\n\n\tif ( ! v1LoadingPromise ) {\n\t\treturn Promise.reject( 'Elementor Editor V1 is not loaded' );\n\t}\n\n\treturn v1LoadingPromise;\n}\n\nexport function normalizeEvent( e: ListenerEvent['originalEvent'] ): ListenerEvent {\n\tif ( e instanceof CustomEvent && e.detail?.command ) {\n\t\treturn {\n\t\t\ttype: 'command',\n\t\t\tcommand: e.detail.command,\n\t\t\targs: e.detail.args,\n\t\t\toriginalEvent: e,\n\t\t};\n\t}\n\n\tif ( e instanceof CustomEvent && e.detail?.route ) {\n\t\treturn {\n\t\t\ttype: 'route',\n\t\t\troute: e.detail.route,\n\t\t\toriginalEvent: e,\n\t\t};\n\t}\n\n\treturn {\n\t\ttype: 'window-event',\n\t\tevent: e.type,\n\t\toriginalEvent: e,\n\t};\n}\n","import { normalizeEvent } from './utils';\nimport {\n\tCommandEventDescriptor,\n\tEventDescriptor,\n\tListenerCallback,\n\tRouteEventDescriptor,\n\tWindowEventDescriptor,\n} from './types';\nimport { isReady, setReady } from './is-ready';\n\nconst callbacksByEvent = new Map<EventDescriptor['name'], ListenerCallback[]>();\nlet abortController = new AbortController();\n\nexport function listenTo(\n\teventDescriptors: EventDescriptor | EventDescriptor[],\n\tcallback: ListenerCallback\n) {\n\tif ( ! Array.isArray( eventDescriptors ) ) {\n\t\teventDescriptors = [ eventDescriptors ];\n\t}\n\n\t// @see https://github.com/typescript-eslint/typescript-eslint/issues/2841\n\t// eslint-disable-next-line array-callback-return -- Clashes with typescript.\n\tconst cleanups = eventDescriptors.map( ( event ) => {\n\t\tconst { type, name } = event;\n\n\t\tswitch ( type ) {\n\t\t\tcase 'command':\n\t\t\t\treturn registerCommandListener( name, event.state, callback );\n\n\t\t\tcase 'route':\n\t\t\t\treturn registerRouteListener( name, event.state, callback );\n\n\t\t\tcase 'window-event':\n\t\t\t\treturn registerWindowEventListener( name, callback );\n\t\t}\n\t} );\n\n\treturn () => {\n\t\tcleanups.forEach( ( cleanup ) => cleanup() );\n\t};\n}\n\nexport function flushListeners() {\n\tabortController.abort();\n\tcallbacksByEvent.clear();\n\tsetReady( false );\n\n\tabortController = new AbortController();\n}\n\nfunction registerCommandListener(\n\tcommand: CommandEventDescriptor['name'],\n\tstate: CommandEventDescriptor['state'],\n\tcallback: ListenerCallback\n) {\n\treturn registerWindowEventListener( `elementor/commands/run/${ state }`, ( e ) => {\n\t\tconst shouldRunCallback = e.type === 'command' && e.command === command;\n\n\t\tif ( shouldRunCallback ) {\n\t\t\tcallback( e );\n\t\t}\n\t} );\n}\n\nfunction registerRouteListener(\n\troute: RouteEventDescriptor['name'],\n\tstate: RouteEventDescriptor['state'],\n\tcallback: ListenerCallback\n) {\n\treturn registerWindowEventListener( `elementor/routes/${ state }`, ( e ) => {\n\t\tconst shouldRunCallback = e.type === 'route' && e.route.startsWith( route );\n\n\t\tif ( shouldRunCallback ) {\n\t\t\tcallback( e );\n\t\t}\n\t} );\n}\n\nfunction registerWindowEventListener( event: WindowEventDescriptor['name'], callback: ListenerCallback ) {\n\tconst isFirstListener = ! callbacksByEvent.has( event );\n\n\tif ( isFirstListener ) {\n\t\tcallbacksByEvent.set( event, [] );\n\n\t\taddListener( event );\n\t}\n\n\tcallbacksByEvent.get( event )?.push( callback );\n\n\treturn () => {\n\t\tconst callbacks = callbacksByEvent.get( event );\n\n\t\tif ( ! callbacks?.length ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst filtered = callbacks.filter( ( cb ) => cb !== callback );\n\n\t\tcallbacksByEvent.set( event, filtered );\n\t};\n}\n\nfunction addListener( event: EventDescriptor['name'] ) {\n\twindow.addEventListener(\n\t\tevent,\n\t\tmakeEventHandler( event ),\n\t\t{ signal: abortController.signal }\n\t);\n}\n\nfunction makeEventHandler( event: EventDescriptor['name'] ): EventListener {\n\treturn ( e ) => {\n\t\tif ( ! isReady() ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst normalizedEvent = normalizeEvent( e );\n\n\t\tcallbacksByEvent.get( event )?.forEach( ( callback ) => {\n\t\t\tcallback( normalizedEvent );\n\t\t} );\n\t};\n}\n","import { ExtendedWindow } from './types';\n\nexport function isRouteActive( route: string ) {\n\tconst extendedWindow = window as unknown as ExtendedWindow;\n\n\treturn !! extendedWindow.$e?.routes?.isPartOf( route );\n}\n\nexport function getCurrentEditMode() {\n\tconst extendedWindow = window as unknown as ExtendedWindow;\n\n\treturn extendedWindow.elementor?.channels?.dataEditMode?.request?.( 'activeMode' );\n}\n","import useListenTo from './use-listen-to';\nimport { getCurrentEditMode } from '../readers';\nimport { editModeChangeEvent } from '../listeners';\n\nexport default function useIsPreviewMode() {\n\treturn useListenTo(\n\t\teditModeChangeEvent(),\n\t\t() => getCurrentEditMode() === 'preview'\n\t);\n}\n","import useListenTo from './use-listen-to';\nimport { isRouteActive } from '../readers';\nimport { routeCloseEvent, routeOpenEvent, RouteEventDescriptor } from '../listeners';\n\nexport default function useIsRouteActive( route: RouteEventDescriptor['name'] ) {\n\treturn useListenTo(\n\t\t[\n\t\t\trouteOpenEvent( route ),\n\t\t\trouteCloseEvent( route ),\n\t\t],\n\t\t() => isRouteActive( route ),\n\t\t[ route ]\n\t);\n}\n","import useIsPreviewMode from './use-is-preview-mode';\nimport useIsRouteActive from './use-is-route-active';\nimport { RouteEventDescriptor } from '../listeners';\n\ntype Options = {\n\tblockOnKitRoutes?: boolean,\n\tblockOnPreviewMode?: boolean,\n}\n\nexport default function useRouteStatus(\n\troute: RouteEventDescriptor['name'],\n\t{\n\t\tblockOnKitRoutes = true,\n\t\tblockOnPreviewMode = true,\n\t}: Options = {}\n) {\n\tconst isRouteActive = useIsRouteActive( route );\n\tconst isKitRouteActive = useIsRouteActive( 'panel/global' );\n\tconst isPreviewMode = useIsPreviewMode();\n\n\tconst isActive = isRouteActive && ! ( blockOnPreviewMode && isPreviewMode );\n\n\tconst isBlocked = (\n\t\t( blockOnPreviewMode && isPreviewMode ) ||\n\t\t( blockOnKitRoutes && isKitRouteActive )\n\t);\n\n\treturn {\n\t\tisActive,\n\t\tisBlocked,\n\t};\n}\n"],"mappings":"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","names":["isRouteActive"]}
package/dist/index.mjs CHANGED
@@ -36,6 +36,25 @@ function openRoute(route) {
36
36
  return Promise.reject(e);
37
37
  }
38
38
  }
39
+ function registerRoute(route) {
40
+ const extendedWindow = window;
41
+ if (!extendedWindow.$e?.routes?.register) {
42
+ return Promise.reject("`$e.routes.register()` is not available");
43
+ }
44
+ const routeParts = route.split("/");
45
+ if (routeParts.length < 2) {
46
+ return Promise.reject(`\`${route}\` is an invalid route`);
47
+ }
48
+ const componentRoute = routeParts.pop();
49
+ const component = routeParts.join("/");
50
+ try {
51
+ return Promise.resolve(
52
+ extendedWindow.$e.routes.register(component, componentRoute, () => null)
53
+ );
54
+ } catch (e) {
55
+ return Promise.reject(e);
56
+ }
57
+ }
39
58
 
40
59
  // src/hooks/use-listen-to.ts
41
60
  import { useEffect, useState } from "react";
@@ -274,6 +293,7 @@ export {
274
293
  isRouteActive,
275
294
  listenTo,
276
295
  openRoute,
296
+ registerRoute,
277
297
  routeCloseEvent,
278
298
  routeOpenEvent,
279
299
  runCommand,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/dispatchers/utils.ts","../src/dispatchers/dispatchers.ts","../src/hooks/use-listen-to.ts","../src/listeners/event-creators.ts","../src/listeners/is-ready.ts","../src/listeners/utils.ts","../src/listeners/listeners.ts","../src/readers/index.ts","../src/hooks/use-is-preview-mode.ts","../src/hooks/use-is-route-active.ts","../src/hooks/use-route-status.ts"],"sourcesContent":["import { jQueryDeferred } from './types';\n\nexport function isJQueryDeferred<T>( value: unknown ): value is jQueryDeferred<T> {\n\t// TODO: Copied from:\n\t// https://github.com/elementor/elementor/blob/6a74fc9/modules/web-cli/assets/js/core/commands.js#L410\n\n\treturn ( !! value ) &&\n\t\t'object' === typeof value &&\n\t\tObject.hasOwn( value, 'promise' ) &&\n\t\tObject.hasOwn( value, 'then' ) &&\n\t\tObject.hasOwn( value, 'fail' );\n}\n\nexport function promisifyJQueryDeferred<T>( deferred: jQueryDeferred<T> ): Promise<T> {\n\treturn new Promise( ( resolve, reject ) => {\n\t\tdeferred.then( resolve, reject );\n\t} );\n}\n","import { ExtendedWindow } from './types';\nimport { isJQueryDeferred, promisifyJQueryDeferred } from './utils';\n\nexport function runCommand( command: string, args?: object ) {\n\tconst extendedWindow = window as unknown as ExtendedWindow;\n\n\tif ( ! extendedWindow.$e?.run ) {\n\t\treturn Promise.reject( '`$e.run()` is not available' );\n\t}\n\n\tconst result = extendedWindow.$e.run( command, args );\n\n\tif ( result instanceof Promise ) {\n\t\treturn result;\n\t}\n\n\tif ( isJQueryDeferred( result ) ) {\n\t\treturn promisifyJQueryDeferred( result );\n\t}\n\n\treturn Promise.resolve( result );\n}\n\nexport function openRoute( route: string ) {\n\tconst extendedWindow = window as unknown as ExtendedWindow;\n\n\tif ( ! extendedWindow.$e?.route ) {\n\t\treturn Promise.reject( '`$e.route()` is not available' );\n\t}\n\n\ttry {\n\t\treturn Promise.resolve(\n\t\t\textendedWindow.$e.route( route )\n\t\t);\n\t} catch ( e ) {\n\t\treturn Promise.reject( e );\n\t}\n}\n","import { useEffect, useState } from 'react';\nimport { EventDescriptor, listenTo } from '../listeners';\n\nexport default function useListenTo<T>(\n\tevent: EventDescriptor | EventDescriptor[],\n\tgetSnapshot: () => T,\n\tdeps: unknown[] = []\n) {\n\tconst [ snapshot, setSnapshot ] = useState( () => getSnapshot() );\n\n\tuseEffect( () => {\n\t\tconst updateState = () => setSnapshot( getSnapshot() );\n\n\t\t// Ensure the state is re-calculated when the dependencies have been changed.\n\t\tupdateState();\n\n\t\treturn listenTo( event, updateState );\n\t}, deps ); // eslint-disable-line react-hooks/exhaustive-deps\n\n\treturn snapshot;\n}\n","import { CommandEventDescriptor, RouteEventDescriptor, WindowEventDescriptor } from './types';\n\nexport const commandStartEvent = ( command: CommandEventDescriptor['name'] ): CommandEventDescriptor => {\n\treturn {\n\t\ttype: 'command',\n\t\tname: command,\n\t\tstate: 'before',\n\t};\n};\n\nexport const commandEndEvent = ( command: CommandEventDescriptor['name'] ): CommandEventDescriptor => {\n\treturn {\n\t\ttype: 'command',\n\t\tname: command,\n\t\tstate: 'after',\n\t};\n};\n\nexport const routeOpenEvent = ( route: RouteEventDescriptor['name'] ): RouteEventDescriptor => {\n\treturn {\n\t\ttype: 'route',\n\t\tname: route,\n\t\tstate: 'open',\n\t};\n};\n\nexport const routeCloseEvent = ( route: RouteEventDescriptor['name'] ): RouteEventDescriptor => {\n\treturn {\n\t\ttype: 'route',\n\t\tname: route,\n\t\tstate: 'close',\n\t};\n};\n\nexport const windowEvent = ( event: WindowEventDescriptor['name'] ): WindowEventDescriptor => {\n\treturn {\n\t\ttype: 'window-event',\n\t\tname: event,\n\t};\n};\n\nexport const v1ReadyEvent = () => {\n\treturn windowEvent( 'elementor/initialized' );\n};\n\nexport const editModeChangeEvent = () => {\n\treturn windowEvent( 'elementor/edit-mode/change' );\n};\n","/**\n * This file is used to store the state of the isReady variable, which is used to determine\n * if the adapter is ready to receive events (editor v1 and v2 are loaded).\n */\n\nlet ready = false;\n\nexport function isReady() {\n\treturn ready;\n}\n\nexport function setReady( value: boolean ) {\n\tready = value;\n}\n","import { ExtendedWindow, ListenerEvent } from './types';\nimport { setReady } from './is-ready';\n\nexport function dispatchReadyEvent() {\n\treturn getV1LoadingPromise().then( () => {\n\t\tsetReady( true );\n\t\twindow.dispatchEvent( new CustomEvent( 'elementor/initialized' ) );\n\t} );\n}\n\nfunction getV1LoadingPromise() {\n\tconst v1LoadingPromise = ( window as unknown as ExtendedWindow ).__elementorEditorV1LoadingPromise;\n\n\tif ( ! v1LoadingPromise ) {\n\t\treturn Promise.reject( 'Elementor Editor V1 is not loaded' );\n\t}\n\n\treturn v1LoadingPromise;\n}\n\nexport function normalizeEvent( e: ListenerEvent['originalEvent'] ): ListenerEvent {\n\tif ( e instanceof CustomEvent && e.detail?.command ) {\n\t\treturn {\n\t\t\ttype: 'command',\n\t\t\tcommand: e.detail.command,\n\t\t\targs: e.detail.args,\n\t\t\toriginalEvent: e,\n\t\t};\n\t}\n\n\tif ( e instanceof CustomEvent && e.detail?.route ) {\n\t\treturn {\n\t\t\ttype: 'route',\n\t\t\troute: e.detail.route,\n\t\t\toriginalEvent: e,\n\t\t};\n\t}\n\n\treturn {\n\t\ttype: 'window-event',\n\t\tevent: e.type,\n\t\toriginalEvent: e,\n\t};\n}\n","import { normalizeEvent } from './utils';\nimport {\n\tCommandEventDescriptor,\n\tEventDescriptor,\n\tListenerCallback,\n\tRouteEventDescriptor,\n\tWindowEventDescriptor,\n} from './types';\nimport { isReady, setReady } from './is-ready';\n\nconst callbacksByEvent = new Map<EventDescriptor['name'], ListenerCallback[]>();\nlet abortController = new AbortController();\n\nexport function listenTo(\n\teventDescriptors: EventDescriptor | EventDescriptor[],\n\tcallback: ListenerCallback\n) {\n\tif ( ! Array.isArray( eventDescriptors ) ) {\n\t\teventDescriptors = [ eventDescriptors ];\n\t}\n\n\t// @see https://github.com/typescript-eslint/typescript-eslint/issues/2841\n\t// eslint-disable-next-line array-callback-return -- Clashes with typescript.\n\tconst cleanups = eventDescriptors.map( ( event ) => {\n\t\tconst { type, name } = event;\n\n\t\tswitch ( type ) {\n\t\t\tcase 'command':\n\t\t\t\treturn registerCommandListener( name, event.state, callback );\n\n\t\t\tcase 'route':\n\t\t\t\treturn registerRouteListener( name, event.state, callback );\n\n\t\t\tcase 'window-event':\n\t\t\t\treturn registerWindowEventListener( name, callback );\n\t\t}\n\t} );\n\n\treturn () => {\n\t\tcleanups.forEach( ( cleanup ) => cleanup() );\n\t};\n}\n\nexport function flushListeners() {\n\tabortController.abort();\n\tcallbacksByEvent.clear();\n\tsetReady( false );\n\n\tabortController = new AbortController();\n}\n\nfunction registerCommandListener(\n\tcommand: CommandEventDescriptor['name'],\n\tstate: CommandEventDescriptor['state'],\n\tcallback: ListenerCallback\n) {\n\treturn registerWindowEventListener( `elementor/commands/run/${ state }`, ( e ) => {\n\t\tconst shouldRunCallback = e.type === 'command' && e.command === command;\n\n\t\tif ( shouldRunCallback ) {\n\t\t\tcallback( e );\n\t\t}\n\t} );\n}\n\nfunction registerRouteListener(\n\troute: RouteEventDescriptor['name'],\n\tstate: RouteEventDescriptor['state'],\n\tcallback: ListenerCallback\n) {\n\treturn registerWindowEventListener( `elementor/routes/${ state }`, ( e ) => {\n\t\tconst shouldRunCallback = e.type === 'route' && e.route.startsWith( route );\n\n\t\tif ( shouldRunCallback ) {\n\t\t\tcallback( e );\n\t\t}\n\t} );\n}\n\nfunction registerWindowEventListener( event: WindowEventDescriptor['name'], callback: ListenerCallback ) {\n\tconst isFirstListener = ! callbacksByEvent.has( event );\n\n\tif ( isFirstListener ) {\n\t\tcallbacksByEvent.set( event, [] );\n\n\t\taddListener( event );\n\t}\n\n\tcallbacksByEvent.get( event )?.push( callback );\n\n\treturn () => {\n\t\tconst callbacks = callbacksByEvent.get( event );\n\n\t\tif ( ! callbacks?.length ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst filtered = callbacks.filter( ( cb ) => cb !== callback );\n\n\t\tcallbacksByEvent.set( event, filtered );\n\t};\n}\n\nfunction addListener( event: EventDescriptor['name'] ) {\n\twindow.addEventListener(\n\t\tevent,\n\t\tmakeEventHandler( event ),\n\t\t{ signal: abortController.signal }\n\t);\n}\n\nfunction makeEventHandler( event: EventDescriptor['name'] ): EventListener {\n\treturn ( e ) => {\n\t\tif ( ! isReady() ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst normalizedEvent = normalizeEvent( e );\n\n\t\tcallbacksByEvent.get( event )?.forEach( ( callback ) => {\n\t\t\tcallback( normalizedEvent );\n\t\t} );\n\t};\n}\n","import { ExtendedWindow } from './types';\n\nexport function isRouteActive( route: string ) {\n\tconst extendedWindow = window as unknown as ExtendedWindow;\n\n\treturn !! extendedWindow.$e?.routes?.isPartOf( route );\n}\n\nexport function getCurrentEditMode() {\n\tconst extendedWindow = window as unknown as ExtendedWindow;\n\n\treturn extendedWindow.elementor?.channels?.dataEditMode?.request?.( 'activeMode' );\n}\n","import useListenTo from './use-listen-to';\nimport { getCurrentEditMode } from '../readers';\nimport { editModeChangeEvent } from '../listeners';\n\nexport default function useIsPreviewMode() {\n\treturn useListenTo(\n\t\teditModeChangeEvent(),\n\t\t() => getCurrentEditMode() === 'preview'\n\t);\n}\n","import useListenTo from './use-listen-to';\nimport { isRouteActive } from '../readers';\nimport { routeCloseEvent, routeOpenEvent, RouteEventDescriptor } from '../listeners';\n\nexport default function useIsRouteActive( route: RouteEventDescriptor['name'] ) {\n\treturn useListenTo(\n\t\t[\n\t\t\trouteOpenEvent( route ),\n\t\t\trouteCloseEvent( route ),\n\t\t],\n\t\t() => isRouteActive( route ),\n\t\t[ route ]\n\t);\n}\n","import useIsPreviewMode from './use-is-preview-mode';\nimport useIsRouteActive from './use-is-route-active';\nimport { RouteEventDescriptor } from '../listeners';\n\ntype Options = {\n\tblockOnKitRoutes?: boolean,\n\tblockOnPreviewMode?: boolean,\n}\n\nexport default function useRouteStatus(\n\troute: RouteEventDescriptor['name'],\n\t{\n\t\tblockOnKitRoutes = true,\n\t\tblockOnPreviewMode = true,\n\t}: Options = {}\n) {\n\tconst isRouteActive = useIsRouteActive( route );\n\tconst isKitRouteActive = useIsRouteActive( 'panel/global' );\n\tconst isPreviewMode = useIsPreviewMode();\n\n\tconst isActive = isRouteActive && ! ( blockOnPreviewMode && isPreviewMode );\n\n\tconst isBlocked = (\n\t\t( blockOnPreviewMode && isPreviewMode ) ||\n\t\t( blockOnKitRoutes && isKitRouteActive )\n\t);\n\n\treturn {\n\t\tisActive,\n\t\tisBlocked,\n\t};\n}\n"],"mappings":"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","names":["isRouteActive"]}
1
+ {"version":3,"sources":["../src/dispatchers/utils.ts","../src/dispatchers/dispatchers.ts","../src/hooks/use-listen-to.ts","../src/listeners/event-creators.ts","../src/listeners/is-ready.ts","../src/listeners/utils.ts","../src/listeners/listeners.ts","../src/readers/index.ts","../src/hooks/use-is-preview-mode.ts","../src/hooks/use-is-route-active.ts","../src/hooks/use-route-status.ts"],"sourcesContent":["import { jQueryDeferred } from './types';\n\nexport function isJQueryDeferred<T>( value: unknown ): value is jQueryDeferred<T> {\n\t// TODO: Copied from:\n\t// https://github.com/elementor/elementor/blob/6a74fc9/modules/web-cli/assets/js/core/commands.js#L410\n\n\treturn ( !! value ) &&\n\t\t'object' === typeof value &&\n\t\tObject.hasOwn( value, 'promise' ) &&\n\t\tObject.hasOwn( value, 'then' ) &&\n\t\tObject.hasOwn( value, 'fail' );\n}\n\nexport function promisifyJQueryDeferred<T>( deferred: jQueryDeferred<T> ): Promise<T> {\n\treturn new Promise( ( resolve, reject ) => {\n\t\tdeferred.then( resolve, reject );\n\t} );\n}\n","import { ExtendedWindow } from './types';\nimport { isJQueryDeferred, promisifyJQueryDeferred } from './utils';\n\nexport function runCommand( command: string, args?: object ) {\n\tconst extendedWindow = window as unknown as ExtendedWindow;\n\n\tif ( ! extendedWindow.$e?.run ) {\n\t\treturn Promise.reject( '`$e.run()` is not available' );\n\t}\n\n\tconst result = extendedWindow.$e.run( command, args );\n\n\tif ( result instanceof Promise ) {\n\t\treturn result;\n\t}\n\n\tif ( isJQueryDeferred( result ) ) {\n\t\treturn promisifyJQueryDeferred( result );\n\t}\n\n\treturn Promise.resolve( result );\n}\n\nexport function openRoute( route: string ) {\n\tconst extendedWindow = window as unknown as ExtendedWindow;\n\n\tif ( ! extendedWindow.$e?.route ) {\n\t\treturn Promise.reject( '`$e.route()` is not available' );\n\t}\n\n\ttry {\n\t\treturn Promise.resolve(\n\t\t\textendedWindow.$e.route( route )\n\t\t);\n\t} catch ( e ) {\n\t\treturn Promise.reject( e );\n\t}\n}\n\nexport function registerRoute( route: string ) {\n\tconst extendedWindow = window as unknown as ExtendedWindow;\n\n\tif ( ! extendedWindow.$e?.routes?.register ) {\n\t\treturn Promise.reject( '`$e.routes.register()` is not available' );\n\t}\n\n\tconst routeParts = route.split( '/' );\n\n\tif ( routeParts.length < 2 ) {\n\t\treturn Promise.reject( `\\`${ route }\\` is an invalid route` );\n\t}\n\n\tconst componentRoute = routeParts.pop() as string; // routeParts.length must be >= 2\n\tconst component = routeParts.join( '/' );\n\n\ttry {\n\t\treturn Promise.resolve(\n\t\t\textendedWindow.$e.routes.register( component, componentRoute, () => null )\n\t\t);\n\t} catch ( e ) {\n\t\treturn Promise.reject( e );\n\t}\n}\n","import { useEffect, useState } from 'react';\nimport { EventDescriptor, listenTo } from '../listeners';\n\nexport default function useListenTo<T>(\n\tevent: EventDescriptor | EventDescriptor[],\n\tgetSnapshot: () => T,\n\tdeps: unknown[] = []\n) {\n\tconst [ snapshot, setSnapshot ] = useState( () => getSnapshot() );\n\n\tuseEffect( () => {\n\t\tconst updateState = () => setSnapshot( getSnapshot() );\n\n\t\t// Ensure the state is re-calculated when the dependencies have been changed.\n\t\tupdateState();\n\n\t\treturn listenTo( event, updateState );\n\t}, deps ); // eslint-disable-line react-hooks/exhaustive-deps\n\n\treturn snapshot;\n}\n","import { CommandEventDescriptor, RouteEventDescriptor, WindowEventDescriptor } from './types';\n\nexport const commandStartEvent = ( command: CommandEventDescriptor['name'] ): CommandEventDescriptor => {\n\treturn {\n\t\ttype: 'command',\n\t\tname: command,\n\t\tstate: 'before',\n\t};\n};\n\nexport const commandEndEvent = ( command: CommandEventDescriptor['name'] ): CommandEventDescriptor => {\n\treturn {\n\t\ttype: 'command',\n\t\tname: command,\n\t\tstate: 'after',\n\t};\n};\n\nexport const routeOpenEvent = ( route: RouteEventDescriptor['name'] ): RouteEventDescriptor => {\n\treturn {\n\t\ttype: 'route',\n\t\tname: route,\n\t\tstate: 'open',\n\t};\n};\n\nexport const routeCloseEvent = ( route: RouteEventDescriptor['name'] ): RouteEventDescriptor => {\n\treturn {\n\t\ttype: 'route',\n\t\tname: route,\n\t\tstate: 'close',\n\t};\n};\n\nexport const windowEvent = ( event: WindowEventDescriptor['name'] ): WindowEventDescriptor => {\n\treturn {\n\t\ttype: 'window-event',\n\t\tname: event,\n\t};\n};\n\nexport const v1ReadyEvent = () => {\n\treturn windowEvent( 'elementor/initialized' );\n};\n\nexport const editModeChangeEvent = () => {\n\treturn windowEvent( 'elementor/edit-mode/change' );\n};\n","/**\n * This file is used to store the state of the isReady variable, which is used to determine\n * if the adapter is ready to receive events (editor v1 and v2 are loaded).\n */\n\nlet ready = false;\n\nexport function isReady() {\n\treturn ready;\n}\n\nexport function setReady( value: boolean ) {\n\tready = value;\n}\n","import { ExtendedWindow, ListenerEvent } from './types';\nimport { setReady } from './is-ready';\n\nexport function dispatchReadyEvent() {\n\treturn getV1LoadingPromise().then( () => {\n\t\tsetReady( true );\n\t\twindow.dispatchEvent( new CustomEvent( 'elementor/initialized' ) );\n\t} );\n}\n\nfunction getV1LoadingPromise() {\n\tconst v1LoadingPromise = ( window as unknown as ExtendedWindow ).__elementorEditorV1LoadingPromise;\n\n\tif ( ! v1LoadingPromise ) {\n\t\treturn Promise.reject( 'Elementor Editor V1 is not loaded' );\n\t}\n\n\treturn v1LoadingPromise;\n}\n\nexport function normalizeEvent( e: ListenerEvent['originalEvent'] ): ListenerEvent {\n\tif ( e instanceof CustomEvent && e.detail?.command ) {\n\t\treturn {\n\t\t\ttype: 'command',\n\t\t\tcommand: e.detail.command,\n\t\t\targs: e.detail.args,\n\t\t\toriginalEvent: e,\n\t\t};\n\t}\n\n\tif ( e instanceof CustomEvent && e.detail?.route ) {\n\t\treturn {\n\t\t\ttype: 'route',\n\t\t\troute: e.detail.route,\n\t\t\toriginalEvent: e,\n\t\t};\n\t}\n\n\treturn {\n\t\ttype: 'window-event',\n\t\tevent: e.type,\n\t\toriginalEvent: e,\n\t};\n}\n","import { normalizeEvent } from './utils';\nimport {\n\tCommandEventDescriptor,\n\tEventDescriptor,\n\tListenerCallback,\n\tRouteEventDescriptor,\n\tWindowEventDescriptor,\n} from './types';\nimport { isReady, setReady } from './is-ready';\n\nconst callbacksByEvent = new Map<EventDescriptor['name'], ListenerCallback[]>();\nlet abortController = new AbortController();\n\nexport function listenTo(\n\teventDescriptors: EventDescriptor | EventDescriptor[],\n\tcallback: ListenerCallback\n) {\n\tif ( ! Array.isArray( eventDescriptors ) ) {\n\t\teventDescriptors = [ eventDescriptors ];\n\t}\n\n\t// @see https://github.com/typescript-eslint/typescript-eslint/issues/2841\n\t// eslint-disable-next-line array-callback-return -- Clashes with typescript.\n\tconst cleanups = eventDescriptors.map( ( event ) => {\n\t\tconst { type, name } = event;\n\n\t\tswitch ( type ) {\n\t\t\tcase 'command':\n\t\t\t\treturn registerCommandListener( name, event.state, callback );\n\n\t\t\tcase 'route':\n\t\t\t\treturn registerRouteListener( name, event.state, callback );\n\n\t\t\tcase 'window-event':\n\t\t\t\treturn registerWindowEventListener( name, callback );\n\t\t}\n\t} );\n\n\treturn () => {\n\t\tcleanups.forEach( ( cleanup ) => cleanup() );\n\t};\n}\n\nexport function flushListeners() {\n\tabortController.abort();\n\tcallbacksByEvent.clear();\n\tsetReady( false );\n\n\tabortController = new AbortController();\n}\n\nfunction registerCommandListener(\n\tcommand: CommandEventDescriptor['name'],\n\tstate: CommandEventDescriptor['state'],\n\tcallback: ListenerCallback\n) {\n\treturn registerWindowEventListener( `elementor/commands/run/${ state }`, ( e ) => {\n\t\tconst shouldRunCallback = e.type === 'command' && e.command === command;\n\n\t\tif ( shouldRunCallback ) {\n\t\t\tcallback( e );\n\t\t}\n\t} );\n}\n\nfunction registerRouteListener(\n\troute: RouteEventDescriptor['name'],\n\tstate: RouteEventDescriptor['state'],\n\tcallback: ListenerCallback\n) {\n\treturn registerWindowEventListener( `elementor/routes/${ state }`, ( e ) => {\n\t\tconst shouldRunCallback = e.type === 'route' && e.route.startsWith( route );\n\n\t\tif ( shouldRunCallback ) {\n\t\t\tcallback( e );\n\t\t}\n\t} );\n}\n\nfunction registerWindowEventListener( event: WindowEventDescriptor['name'], callback: ListenerCallback ) {\n\tconst isFirstListener = ! callbacksByEvent.has( event );\n\n\tif ( isFirstListener ) {\n\t\tcallbacksByEvent.set( event, [] );\n\n\t\taddListener( event );\n\t}\n\n\tcallbacksByEvent.get( event )?.push( callback );\n\n\treturn () => {\n\t\tconst callbacks = callbacksByEvent.get( event );\n\n\t\tif ( ! callbacks?.length ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst filtered = callbacks.filter( ( cb ) => cb !== callback );\n\n\t\tcallbacksByEvent.set( event, filtered );\n\t};\n}\n\nfunction addListener( event: EventDescriptor['name'] ) {\n\twindow.addEventListener(\n\t\tevent,\n\t\tmakeEventHandler( event ),\n\t\t{ signal: abortController.signal }\n\t);\n}\n\nfunction makeEventHandler( event: EventDescriptor['name'] ): EventListener {\n\treturn ( e ) => {\n\t\tif ( ! isReady() ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst normalizedEvent = normalizeEvent( e );\n\n\t\tcallbacksByEvent.get( event )?.forEach( ( callback ) => {\n\t\t\tcallback( normalizedEvent );\n\t\t} );\n\t};\n}\n","import { ExtendedWindow } from './types';\n\nexport function isRouteActive( route: string ) {\n\tconst extendedWindow = window as unknown as ExtendedWindow;\n\n\treturn !! extendedWindow.$e?.routes?.isPartOf( route );\n}\n\nexport function getCurrentEditMode() {\n\tconst extendedWindow = window as unknown as ExtendedWindow;\n\n\treturn extendedWindow.elementor?.channels?.dataEditMode?.request?.( 'activeMode' );\n}\n","import useListenTo from './use-listen-to';\nimport { getCurrentEditMode } from '../readers';\nimport { editModeChangeEvent } from '../listeners';\n\nexport default function useIsPreviewMode() {\n\treturn useListenTo(\n\t\teditModeChangeEvent(),\n\t\t() => getCurrentEditMode() === 'preview'\n\t);\n}\n","import useListenTo from './use-listen-to';\nimport { isRouteActive } from '../readers';\nimport { routeCloseEvent, routeOpenEvent, RouteEventDescriptor } from '../listeners';\n\nexport default function useIsRouteActive( route: RouteEventDescriptor['name'] ) {\n\treturn useListenTo(\n\t\t[\n\t\t\trouteOpenEvent( route ),\n\t\t\trouteCloseEvent( route ),\n\t\t],\n\t\t() => isRouteActive( route ),\n\t\t[ route ]\n\t);\n}\n","import useIsPreviewMode from './use-is-preview-mode';\nimport useIsRouteActive from './use-is-route-active';\nimport { RouteEventDescriptor } from '../listeners';\n\ntype Options = {\n\tblockOnKitRoutes?: boolean,\n\tblockOnPreviewMode?: boolean,\n}\n\nexport default function useRouteStatus(\n\troute: RouteEventDescriptor['name'],\n\t{\n\t\tblockOnKitRoutes = true,\n\t\tblockOnPreviewMode = true,\n\t}: Options = {}\n) {\n\tconst isRouteActive = useIsRouteActive( route );\n\tconst isKitRouteActive = useIsRouteActive( 'panel/global' );\n\tconst isPreviewMode = useIsPreviewMode();\n\n\tconst isActive = isRouteActive && ! ( blockOnPreviewMode && isPreviewMode );\n\n\tconst isBlocked = (\n\t\t( blockOnPreviewMode && isPreviewMode ) ||\n\t\t( blockOnKitRoutes && isKitRouteActive )\n\t);\n\n\treturn {\n\t\tisActive,\n\t\tisBlocked,\n\t};\n}\n"],"mappings":"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","names":["isRouteActive"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elementor/editor-v1-adapters",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "private": false,
5
5
  "author": "Elementor Team",
6
6
  "homepage": "https://elementor.com/",
@@ -32,7 +32,7 @@
32
32
  "dev": "tsup --config=../../tsup.dev.ts"
33
33
  },
34
34
  "peerDependencies": {
35
- "react": "17.x || 18.x"
35
+ "react": "18.x"
36
36
  },
37
- "gitHead": "2ee431a07ec6af6ca2b9930c0b830e78696b194a"
37
+ "gitHead": "70a2c6139730b7afa69d13eb65023b0e6612f23b"
38
38
  }
@@ -1,15 +1,10 @@
1
- import { openRoute, runCommand } from '../index';
2
-
3
- type ExtendedWindow = Window & {
4
- $e: {
5
- run: jest.Mock;
6
- route: jest.Mock;
7
- },
8
- }
1
+ import { openRoute, registerRoute, runCommand } from '../index';
2
+ import { ExtendedWindow } from '../types';
9
3
 
10
4
  describe( '@elementor/editor-v1-adapters/dispatchers', () => {
11
5
  let eRun: jest.Mock,
12
- eRoute: jest.Mock;
6
+ eRoute: jest.Mock,
7
+ eRegisterRoute: jest.Mock;
13
8
 
14
9
  beforeEach( () => {
15
10
  const extendedWindow = window as unknown as ExtendedWindow;
@@ -17,10 +12,14 @@ describe( '@elementor/editor-v1-adapters/dispatchers', () => {
17
12
  extendedWindow.$e = {
18
13
  run: jest.fn(),
19
14
  route: jest.fn(),
15
+ routes: {
16
+ register: jest.fn(),
17
+ },
20
18
  };
21
19
 
22
- eRun = extendedWindow.$e.run;
23
- eRoute = extendedWindow.$e.route;
20
+ eRun = jest.mocked( extendedWindow.$e.run );
21
+ eRoute = jest.mocked( extendedWindow.$e.route );
22
+ eRegisterRoute = jest.mocked( extendedWindow.$e?.routes?.register || jest.fn() );
24
23
  } );
25
24
 
26
25
  it( 'should run a V1 command that returns Promise', () => {
@@ -68,16 +67,6 @@ describe( '@elementor/editor-v1-adapters/dispatchers', () => {
68
67
  expect( result ).toEqual( Promise.resolve( 'result' ) );
69
68
  } );
70
69
 
71
- it( 'should reject when trying to run a V1 command and `$e.run()` is unavailable', () => {
72
- // Arrange.
73
- delete ( window as { $e?: unknown } ).$e;
74
-
75
- // Act & Assert.
76
- expect( () => runCommand( 'editor/documents/open' ) )
77
- .rejects
78
- .toEqual( '`$e.run()` is not available' );
79
- } );
80
-
81
70
  it( 'should open a V1 route', () => {
82
71
  // Arrange.
83
72
  const route = 'test/route';
@@ -104,14 +93,36 @@ describe( '@elementor/editor-v1-adapters/dispatchers', () => {
104
93
  .toEqual( 'Cannot find test/route' );
105
94
  } );
106
95
 
107
- it( 'should reject when trying to open a V1 route and `$e.route()` is unavailable', () => {
96
+ it.each( [
97
+ [ 'test/route', [ 'test', 'route' ] ],
98
+ [ 'test/test2/route', [ 'test/test2', 'route' ] ],
99
+ ] )( 'should register the route `%s` in v1', ( route, params ) => {
100
+ // Act.
101
+ registerRoute( route );
102
+
103
+ // Assert.
104
+ expect( eRegisterRoute ).toHaveBeenCalledWith( ...params, expect.any( Function ) );
105
+ } );
106
+
107
+ it( 'should throw if trying to register invalid route', () => {
108
+ // Act & Assert.
109
+ expect( () => registerRoute( 'test' ) )
110
+ .rejects
111
+ .toEqual( '`test` is an invalid route' );
112
+ } );
113
+
114
+ it.each( [
115
+ [ '$e.route()', () => openRoute( 'test/route' ) ],
116
+ [ '$e.run()', () => runCommand( 'editor/documents/open' ) ],
117
+ [ '$e.routes.register()', () => registerRoute( 'test/route' ) ],
118
+ ] )( 'should reject when trying to use V1 and `%s` is unavailable', ( v1Method, action ) => {
108
119
  // Arrange.
109
120
  delete ( window as { $e?: unknown } ).$e;
110
121
 
111
122
  // Act & Assert.
112
- expect( () => openRoute( 'test/route' ) )
123
+ expect( () => action() )
113
124
  .rejects
114
- .toEqual( '`$e.route()` is not available' );
125
+ .toEqual( `\`${ v1Method }\` is not available` );
115
126
  } );
116
127
  } );
117
128
 
@@ -36,3 +36,28 @@ export function openRoute( route: string ) {
36
36
  return Promise.reject( e );
37
37
  }
38
38
  }
39
+
40
+ export function registerRoute( route: string ) {
41
+ const extendedWindow = window as unknown as ExtendedWindow;
42
+
43
+ if ( ! extendedWindow.$e?.routes?.register ) {
44
+ return Promise.reject( '`$e.routes.register()` is not available' );
45
+ }
46
+
47
+ const routeParts = route.split( '/' );
48
+
49
+ if ( routeParts.length < 2 ) {
50
+ return Promise.reject( `\`${ route }\` is an invalid route` );
51
+ }
52
+
53
+ const componentRoute = routeParts.pop() as string; // routeParts.length must be >= 2
54
+ const component = routeParts.join( '/' );
55
+
56
+ try {
57
+ return Promise.resolve(
58
+ extendedWindow.$e.routes.register( component, componentRoute, () => null )
59
+ );
60
+ } catch ( e ) {
61
+ return Promise.reject( e );
62
+ }
63
+ }
@@ -5,6 +5,13 @@ export type jQueryDeferred<T> = {
5
5
  export type ExtendedWindow = Window & {
6
6
  $e: {
7
7
  run: ( command: string, args?: object ) => unknown;
8
- route: ( route: string ) => void;
8
+ route: ( route: string ) => unknown;
9
+ routes?: {
10
+ register?: (
11
+ component: string,
12
+ route: string,
13
+ callback: () => unknown
14
+ ) => unknown;
15
+ }
9
16
  },
10
17
  }