@elementor/wp-media 0.2.3 → 0.4.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
@@ -1,5 +1,21 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - af5fa42: Separate `getMediaAttachment` from react hook.
8
+
9
+ ### Patch Changes
10
+
11
+ - a2f5096: support restricting uploaded image type
12
+
13
+ ## 0.3.0
14
+
15
+ ### Minor Changes
16
+
17
+ - 4e5ea74: support SVG upload
18
+
3
19
  ## 0.2.3
4
20
 
5
21
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -25,13 +25,16 @@ type Attachment = {
25
25
  }>;
26
26
  };
27
27
 
28
+ type ImageExtension = 'avif' | 'bmp' | 'gif' | 'ico' | 'jpe' | 'jpeg' | 'jpg' | 'png' | 'svg' | 'webp';
29
+
28
30
  declare function useWpMediaAttachment(id: number | null): _tanstack_react_query.UseQueryResult<Attachment | null, Error>;
29
31
 
30
32
  type OpenOptions = {
31
33
  mode?: 'upload' | 'browse';
32
34
  };
33
35
  type Options = {
34
- types: Array<'image'>;
36
+ types: Array<'image' | 'image/svg+xml'>;
37
+ allowedExtensions?: ImageExtension[];
35
38
  title?: string;
36
39
  } & ({
37
40
  multiple: true;
@@ -46,4 +49,8 @@ declare function useWpMediaFrame(options: Options): {
46
49
  open: (openOptions?: OpenOptions) => void;
47
50
  };
48
51
 
49
- export { type Attachment, useWpMediaAttachment, useWpMediaFrame };
52
+ declare function getMediaAttachment({ id }: {
53
+ id: number | null;
54
+ }): Promise<Attachment | null>;
55
+
56
+ export { type Attachment, type ImageExtension, getMediaAttachment, useWpMediaAttachment, useWpMediaFrame };
package/dist/index.d.ts CHANGED
@@ -25,13 +25,16 @@ type Attachment = {
25
25
  }>;
26
26
  };
27
27
 
28
+ type ImageExtension = 'avif' | 'bmp' | 'gif' | 'ico' | 'jpe' | 'jpeg' | 'jpg' | 'png' | 'svg' | 'webp';
29
+
28
30
  declare function useWpMediaAttachment(id: number | null): _tanstack_react_query.UseQueryResult<Attachment | null, Error>;
29
31
 
30
32
  type OpenOptions = {
31
33
  mode?: 'upload' | 'browse';
32
34
  };
33
35
  type Options = {
34
- types: Array<'image'>;
36
+ types: Array<'image' | 'image/svg+xml'>;
37
+ allowedExtensions?: ImageExtension[];
35
38
  title?: string;
36
39
  } & ({
37
40
  multiple: true;
@@ -46,4 +49,8 @@ declare function useWpMediaFrame(options: Options): {
46
49
  open: (openOptions?: OpenOptions) => void;
47
50
  };
48
51
 
49
- export { type Attachment, useWpMediaAttachment, useWpMediaFrame };
52
+ declare function getMediaAttachment({ id }: {
53
+ id: number | null;
54
+ }): Promise<Attachment | null>;
55
+
56
+ export { type Attachment, type ImageExtension, getMediaAttachment, useWpMediaAttachment, useWpMediaFrame };
package/dist/index.js CHANGED
@@ -18,12 +18,13 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
 
20
20
  // src/index.ts
21
- var src_exports = {};
22
- __export(src_exports, {
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ getMediaAttachment: () => getMediaAttachment,
23
24
  useWpMediaAttachment: () => useWpMediaAttachment,
24
25
  useWpMediaFrame: () => useWpMediaFrame
25
26
  });
26
- module.exports = __toCommonJS(src_exports);
27
+ module.exports = __toCommonJS(index_exports);
27
28
 
28
29
  // src/hooks/use-wp-media-attachment.ts
29
30
  var import_query = require("@elementor/query");
@@ -34,6 +35,10 @@ var WpMediaNotAvailableError = (0, import_utils.createError)({
34
35
  code: "wp_media_not_available",
35
36
  message: "`wp.media` is not available, make sure the `media-models` handle is set in the dependencies array"
36
37
  });
38
+ var WpPluploadSettingsNotAvailableError = (0, import_utils.createError)({
39
+ code: "wp_plupload_settings_not_available",
40
+ message: "`_wpPluploadSettings` is not available, make sure a wp media uploader is open"
41
+ });
37
42
 
38
43
  // src/media.ts
39
44
  var wpMediaWindow = window;
@@ -60,15 +65,8 @@ function normalize(attachment) {
60
65
  };
61
66
  }
62
67
 
63
- // src/hooks/use-wp-media-attachment.ts
64
- function useWpMediaAttachment(id) {
65
- return (0, import_query.useQuery)({
66
- queryKey: ["wp-attachment", id],
67
- queryFn: getAttachment,
68
- enabled: !!id
69
- });
70
- }
71
- async function getAttachment({ queryKey: [, id] }) {
68
+ // src/get-media-attachment.ts
69
+ async function getMediaAttachment({ id }) {
72
70
  if (!id) {
73
71
  return null;
74
72
  }
@@ -85,8 +83,29 @@ async function getAttachment({ queryKey: [, id] }) {
85
83
  }
86
84
  }
87
85
 
86
+ // src/hooks/use-wp-media-attachment.ts
87
+ function useWpMediaAttachment(id) {
88
+ return (0, import_query.useQuery)({
89
+ queryKey: ["wp-attachment", id],
90
+ queryFn: () => getMediaAttachment({ id }),
91
+ enabled: !!id
92
+ });
93
+ }
94
+
88
95
  // src/hooks/use-wp-media-frame.ts
89
96
  var import_react = require("react");
97
+
98
+ // src/wp-plupload-settings.ts
99
+ var wpPluploadSettingsWindow = window;
100
+ var wp_plupload_settings_default = () => {
101
+ if (!wpPluploadSettingsWindow._wpPluploadSettings) {
102
+ throw new WpPluploadSettingsNotAvailableError();
103
+ }
104
+ return wpPluploadSettingsWindow._wpPluploadSettings;
105
+ };
106
+
107
+ // src/hooks/use-wp-media-frame.ts
108
+ var defaultImageExtensions = ["avif", "bmp", "gif", "ico", "jpe", "jpeg", "jpg", "png", "webp"];
90
109
  function useWpMediaFrame(options) {
91
110
  const frame = (0, import_react.useRef)();
92
111
  const open = (openOptions = {}) => {
@@ -103,7 +122,15 @@ function useWpMediaFrame(options) {
103
122
  open
104
123
  };
105
124
  }
106
- function createFrame({ onSelect, multiple, types, selected, title, mode = "browse" }) {
125
+ function createFrame({
126
+ onSelect,
127
+ multiple,
128
+ types,
129
+ selected,
130
+ title,
131
+ mode = "browse",
132
+ allowedExtensions
133
+ }) {
107
134
  const frame = media_default()({
108
135
  title,
109
136
  multiple,
@@ -111,9 +138,11 @@ function createFrame({ onSelect, multiple, types, selected, title, mode = "brows
111
138
  type: types
112
139
  }
113
140
  }).on("open", () => {
141
+ setTypeCaller(frame);
114
142
  applyMode(frame, mode);
115
143
  applySelection(frame, selected);
116
144
  }).on("close", () => cleanupFrame(frame)).on("insert select", () => select(frame, multiple, onSelect));
145
+ handleAllowedExtensions(frame, allowedExtensions);
117
146
  return frame;
118
147
  }
119
148
  function cleanupFrame(frame) {
@@ -132,8 +161,36 @@ function select(frame, multiple, onSelect) {
132
161
  const onSelectFn = onSelect;
133
162
  onSelectFn(multiple ? attachments : attachments[0]);
134
163
  }
164
+ function setTypeCaller(frame) {
165
+ frame.uploader.uploader.param("uploadTypeCaller", "elementor-wp-media-upload");
166
+ }
167
+ function handleAllowedExtensions(frame, allowedExtensions) {
168
+ const defaultExtensions = wp_plupload_settings_default().defaults.filters.mime_types?.[0]?.extensions;
169
+ frame.on("ready", () => {
170
+ wp_plupload_settings_default().defaults.filters.mime_types = [
171
+ { extensions: getAllowedExtensions(allowedExtensions) }
172
+ ];
173
+ });
174
+ frame.on("close", () => {
175
+ wp_plupload_settings_default().defaults.filters.mime_types = defaultExtensions ? [{ extensions: defaultExtensions }] : [];
176
+ });
177
+ }
178
+ function getAllowedExtensions(allowedExtensions) {
179
+ let extensions = [...defaultImageExtensions];
180
+ if (allowedExtensions) {
181
+ extensions = allowedExtensions;
182
+ } else if (isUnfilteredFilesUploadEnabled()) {
183
+ extensions.push("svg");
184
+ }
185
+ return extensions.join(",");
186
+ }
187
+ function isUnfilteredFilesUploadEnabled() {
188
+ const extendedWindow = window;
189
+ return Boolean(extendedWindow.elementorCommon.config.filesUpload.unfilteredFiles);
190
+ }
135
191
  // Annotate the CommonJS export names for ESM import in node:
136
192
  0 && (module.exports = {
193
+ getMediaAttachment,
137
194
  useWpMediaAttachment,
138
195
  useWpMediaFrame
139
196
  });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/hooks/use-wp-media-attachment.ts","../src/errors.ts","../src/media.ts","../src/normalize.ts","../src/hooks/use-wp-media-frame.ts"],"sourcesContent":["export type { Attachment } from './types/attachment';\n\nexport { default as useWpMediaAttachment } from './hooks/use-wp-media-attachment';\nexport { default as useWpMediaFrame } from './hooks/use-wp-media-frame';\n","import { useQuery } from '@elementor/query';\n\nimport media from '../media';\nimport normalize from '../normalize';\n\nexport default function useWpMediaAttachment( id: number | null ) {\n\treturn useQuery( {\n\t\tqueryKey: [ 'wp-attachment', id ],\n\t\tqueryFn: getAttachment,\n\t\tenabled: !! id,\n\t} );\n}\n\nasync function getAttachment( { queryKey: [ , id ] }: { queryKey: [ string, number | null ] } ) {\n\tif ( ! id ) {\n\t\treturn null;\n\t}\n\n\tconst model = media().attachment( id );\n\tconst wpAttachment = model.toJSON();\n\n\tconst isFetched = 'url' in wpAttachment;\n\n\tif ( isFetched ) {\n\t\treturn normalize( wpAttachment );\n\t}\n\n\ttry {\n\t\treturn normalize( await model.fetch() );\n\t} catch {\n\t\treturn null;\n\t}\n}\n","import { createError } from '@elementor/utils';\n\nexport const WpMediaNotAvailableError = createError( {\n\tcode: 'wp_media_not_available',\n\tmessage: '`wp.media` is not available, make sure the `media-models` handle is set in the dependencies array',\n} );\n","import { WpMediaNotAvailableError } from './errors';\nimport { type WpMediaWindow } from './types/wp-media';\n\nconst wpMediaWindow = window as unknown as WpMediaWindow;\n\nexport default () => {\n\tif ( ! wpMediaWindow.wp?.media ) {\n\t\tthrow new WpMediaNotAvailableError();\n\t}\n\n\treturn wpMediaWindow.wp.media;\n};\n","import { type Attachment } from './types/attachment';\nimport { type WpAttachmentJSON } from './types/wp-media';\n\nexport default function normalize( attachment: WpAttachmentJSON ): Attachment {\n\tconst { filesizeInBytes, filesizeHumanReadable, author, authorName, ...rest } = attachment;\n\n\treturn {\n\t\t...rest,\n\t\tfilesize: {\n\t\t\tinBytes: filesizeInBytes,\n\t\t\thumanReadable: filesizeHumanReadable,\n\t\t},\n\t\tauthor: {\n\t\t\tid: parseInt( author ),\n\t\t\tname: authorName,\n\t\t},\n\t};\n}\n","import { useEffect, useRef } from 'react';\n\nimport media from '../media';\nimport normalize from '../normalize';\nimport { type Attachment } from '../types/attachment';\nimport { type MediaFrame } from '../types/wp-media';\n\ntype OpenOptions = {\n\tmode?: 'upload' | 'browse';\n};\n\ntype Options = {\n\ttypes: Array< 'image' >;\n\ttitle?: string;\n} & (\n\t| {\n\t\t\tmultiple: true;\n\t\t\tselected: Array< number | null >;\n\t\t\tonSelect: ( val: Attachment[] ) => void;\n\t }\n\t| {\n\t\t\tmultiple: false;\n\t\t\tselected: number | null;\n\t\t\tonSelect: ( val: Attachment ) => void;\n\t }\n);\n\nexport default function useWpMediaFrame( options: Options ) {\n\tconst frame = useRef< MediaFrame >();\n\n\tconst open = ( openOptions: OpenOptions = {} ) => {\n\t\tcleanupFrame( frame.current );\n\n\t\tframe.current = createFrame( { ...options, ...openOptions } );\n\n\t\tframe.current?.open();\n\t};\n\n\tuseEffect( () => {\n\t\treturn () => {\n\t\t\tcleanupFrame( frame.current );\n\t\t};\n\t}, [] );\n\n\treturn {\n\t\topen,\n\t};\n}\n\nfunction createFrame( { onSelect, multiple, types, selected, title, mode = 'browse' }: Options & OpenOptions ) {\n\tconst frame: MediaFrame = media()( {\n\t\ttitle,\n\t\tmultiple,\n\t\tlibrary: {\n\t\t\ttype: types,\n\t\t},\n\t} )\n\t\t.on( 'open', () => {\n\t\t\tapplyMode( frame, mode );\n\t\t\tapplySelection( frame, selected );\n\t\t} )\n\t\t.on( 'close', () => cleanupFrame( frame ) )\n\t\t.on( 'insert select', () => select( frame, multiple, onSelect ) );\n\n\treturn frame;\n}\n\nfunction cleanupFrame( frame?: MediaFrame ) {\n\tframe?.detach();\n\tframe?.remove();\n}\n\nfunction applyMode( frame: MediaFrame, mode: OpenOptions[ 'mode' ] = 'browse' ) {\n\tframe.content.mode( mode );\n}\n\nfunction applySelection( frame: MediaFrame, selected: number | null | Array< number | null > ) {\n\tconst selectedAttachments = ( typeof selected === 'number' ? [ selected ] : selected )\n\t\t?.filter( ( id ) => !! id )\n\t\t.map( ( id ) => media().attachment( id as number ) );\n\n\tframe\n\t\t.state()\n\t\t.get( 'selection' )\n\t\t.set( selectedAttachments || [] );\n}\n\nfunction select( frame: MediaFrame, multiple: boolean, onSelect: Options[ 'onSelect' ] ) {\n\tconst attachments = frame.state().get( 'selection' ).toJSON().map( normalize );\n\n\tconst onSelectFn = onSelect as ( val: Attachment | Attachment[] ) => void;\n\n\tonSelectFn( multiple ? attachments : attachments[ 0 ] );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/hooks/use-wp-media-attachment.ts","../src/errors.ts","../src/media.ts","../src/normalize.ts","../src/get-media-attachment.ts","../src/hooks/use-wp-media-frame.ts","../src/wp-plupload-settings.ts"],"sourcesContent":["export type { Attachment } from './types/attachment';\nexport type { ImageExtension } from './types/image';\n\nexport { default as useWpMediaAttachment } from './hooks/use-wp-media-attachment';\nexport { default as useWpMediaFrame } from './hooks/use-wp-media-frame';\n\nexport { getMediaAttachment } from './get-media-attachment';\n","import { useQuery } from '@elementor/query';\n\nimport { getMediaAttachment } from '../get-media-attachment';\n\nexport default function useWpMediaAttachment( id: number | null ) {\n\treturn useQuery( {\n\t\tqueryKey: [ 'wp-attachment', id ],\n\t\tqueryFn: () => getMediaAttachment( { id } ),\n\t\tenabled: !! id,\n\t} );\n}\n","import { createError } from '@elementor/utils';\n\nexport const WpMediaNotAvailableError = createError( {\n\tcode: 'wp_media_not_available',\n\tmessage: '`wp.media` is not available, make sure the `media-models` handle is set in the dependencies array',\n} );\n\nexport const WpPluploadSettingsNotAvailableError = createError( {\n\tcode: 'wp_plupload_settings_not_available',\n\tmessage: '`_wpPluploadSettings` is not available, make sure a wp media uploader is open',\n} );\n","import { WpMediaNotAvailableError } from './errors';\nimport { type WpMediaWindow } from './types/wp-media';\n\nconst wpMediaWindow = window as unknown as WpMediaWindow;\n\nexport default () => {\n\tif ( ! wpMediaWindow.wp?.media ) {\n\t\tthrow new WpMediaNotAvailableError();\n\t}\n\n\treturn wpMediaWindow.wp.media;\n};\n","import { type Attachment } from './types/attachment';\nimport { type WpAttachmentJSON } from './types/wp-media';\n\nexport default function normalize( attachment: WpAttachmentJSON ): Attachment {\n\tconst { filesizeInBytes, filesizeHumanReadable, author, authorName, ...rest } = attachment;\n\n\treturn {\n\t\t...rest,\n\t\tfilesize: {\n\t\t\tinBytes: filesizeInBytes,\n\t\t\thumanReadable: filesizeHumanReadable,\n\t\t},\n\t\tauthor: {\n\t\t\tid: parseInt( author ),\n\t\t\tname: authorName,\n\t\t},\n\t};\n}\n","import media from './media';\nimport normalize from './normalize';\n\nexport async function getMediaAttachment( { id }: { id: number | null } ) {\n\tif ( ! id ) {\n\t\treturn null;\n\t}\n\n\tconst model = media().attachment( id );\n\tconst wpAttachment = model.toJSON();\n\n\tconst isFetched = 'url' in wpAttachment;\n\n\tif ( isFetched ) {\n\t\treturn normalize( wpAttachment );\n\t}\n\n\ttry {\n\t\treturn normalize( await model.fetch() );\n\t} catch {\n\t\treturn null;\n\t}\n}\n","import { useEffect, useRef } from 'react';\n\nimport media from '../media';\nimport normalize from '../normalize';\nimport { type Attachment } from '../types/attachment';\nimport { type ElementorCommonWindow } from '../types/elementor-common';\nimport { type ImageExtension } from '../types/image';\nimport { type MediaFrame } from '../types/wp-media';\nimport wpPluploadSettings from '../wp-plupload-settings';\n\ntype OpenOptions = {\n\tmode?: 'upload' | 'browse';\n};\n\ntype Options = {\n\ttypes: Array< 'image' | 'image/svg+xml' >;\n\tallowedExtensions?: ImageExtension[];\n\ttitle?: string;\n} & (\n\t| {\n\t\t\tmultiple: true;\n\t\t\tselected: Array< number | null >;\n\t\t\tonSelect: ( val: Attachment[] ) => void;\n\t }\n\t| {\n\t\t\tmultiple: false;\n\t\t\tselected: number | null;\n\t\t\tonSelect: ( val: Attachment ) => void;\n\t }\n);\n\nconst defaultImageExtensions: ImageExtension[] = [ 'avif', 'bmp', 'gif', 'ico', 'jpe', 'jpeg', 'jpg', 'png', 'webp' ];\n\nexport default function useWpMediaFrame( options: Options ) {\n\tconst frame = useRef< MediaFrame >();\n\n\tconst open = ( openOptions: OpenOptions = {} ) => {\n\t\tcleanupFrame( frame.current );\n\n\t\tframe.current = createFrame( { ...options, ...openOptions } );\n\n\t\tframe.current?.open();\n\t};\n\n\tuseEffect( () => {\n\t\treturn () => {\n\t\t\tcleanupFrame( frame.current );\n\t\t};\n\t}, [] );\n\n\treturn {\n\t\topen,\n\t};\n}\n\nfunction createFrame( {\n\tonSelect,\n\tmultiple,\n\ttypes,\n\tselected,\n\ttitle,\n\tmode = 'browse',\n\tallowedExtensions,\n}: Options & OpenOptions ) {\n\tconst frame: MediaFrame = media()( {\n\t\ttitle,\n\t\tmultiple,\n\t\tlibrary: {\n\t\t\ttype: types,\n\t\t},\n\t} )\n\t\t.on( 'open', () => {\n\t\t\tsetTypeCaller( frame );\n\t\t\tapplyMode( frame, mode );\n\t\t\tapplySelection( frame, selected );\n\t\t} )\n\t\t.on( 'close', () => cleanupFrame( frame ) )\n\t\t.on( 'insert select', () => select( frame, multiple, onSelect ) );\n\n\thandleAllowedExtensions( frame, allowedExtensions );\n\n\treturn frame;\n}\n\nfunction cleanupFrame( frame?: MediaFrame ) {\n\tframe?.detach();\n\tframe?.remove();\n}\n\nfunction applyMode( frame: MediaFrame, mode: OpenOptions[ 'mode' ] = 'browse' ) {\n\tframe.content.mode( mode );\n}\n\nfunction applySelection( frame: MediaFrame, selected: number | null | Array< number | null > ) {\n\tconst selectedAttachments = ( typeof selected === 'number' ? [ selected ] : selected )\n\t\t?.filter( ( id ) => !! id )\n\t\t.map( ( id ) => media().attachment( id as number ) );\n\n\tframe\n\t\t.state()\n\t\t.get( 'selection' )\n\t\t.set( selectedAttachments || [] );\n}\n\nfunction select( frame: MediaFrame, multiple: boolean, onSelect: Options[ 'onSelect' ] ) {\n\tconst attachments = frame.state().get( 'selection' ).toJSON().map( normalize );\n\n\tconst onSelectFn = onSelect as ( val: Attachment | Attachment[] ) => void;\n\n\tonSelectFn( multiple ? attachments : attachments[ 0 ] );\n}\n\nfunction setTypeCaller( frame: MediaFrame ) {\n\tframe.uploader.uploader.param( 'uploadTypeCaller', 'elementor-wp-media-upload' );\n}\n\nfunction handleAllowedExtensions( frame: MediaFrame, allowedExtensions?: ImageExtension[] ) {\n\tconst defaultExtensions = wpPluploadSettings().defaults.filters.mime_types?.[ 0 ]?.extensions;\n\n\t// Set the allowed extensions\n\tframe.on( 'ready', () => {\n\t\twpPluploadSettings().defaults.filters.mime_types = [\n\t\t\t{ extensions: getAllowedExtensions( allowedExtensions ) },\n\t\t];\n\t} );\n\n\t// Restore default upload extensions\n\tframe.on( 'close', () => {\n\t\twpPluploadSettings().defaults.filters.mime_types = defaultExtensions\n\t\t\t? [ { extensions: defaultExtensions } ]\n\t\t\t: [];\n\t} );\n}\n\nfunction getAllowedExtensions( allowedExtensions?: ImageExtension[] ) {\n\tlet extensions: ImageExtension[] = [ ...defaultImageExtensions ];\n\n\tif ( allowedExtensions ) {\n\t\textensions = allowedExtensions;\n\t} else if ( isUnfilteredFilesUploadEnabled() ) {\n\t\textensions.push( 'svg' );\n\t}\n\n\treturn extensions.join( ',' );\n}\n\nfunction isUnfilteredFilesUploadEnabled(): boolean {\n\tconst extendedWindow = window as unknown as ElementorCommonWindow;\n\n\treturn Boolean( extendedWindow.elementorCommon.config.filesUpload.unfilteredFiles );\n}\n","import { WpPluploadSettingsNotAvailableError } from './errors';\nimport { type WpPluploadSettingsWindow } from './types/plupload';\n\nconst wpPluploadSettingsWindow = window as unknown as WpPluploadSettingsWindow;\n\nexport default () => {\n\tif ( ! wpPluploadSettingsWindow._wpPluploadSettings ) {\n\t\tthrow new WpPluploadSettingsNotAvailableError();\n\t}\n\n\treturn wpPluploadSettingsWindow._wpPluploadSettings;\n};\n"],"mappings":"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","names":[]}
package/dist/index.mjs CHANGED
@@ -7,6 +7,10 @@ var WpMediaNotAvailableError = createError({
7
7
  code: "wp_media_not_available",
8
8
  message: "`wp.media` is not available, make sure the `media-models` handle is set in the dependencies array"
9
9
  });
10
+ var WpPluploadSettingsNotAvailableError = createError({
11
+ code: "wp_plupload_settings_not_available",
12
+ message: "`_wpPluploadSettings` is not available, make sure a wp media uploader is open"
13
+ });
10
14
 
11
15
  // src/media.ts
12
16
  var wpMediaWindow = window;
@@ -33,15 +37,8 @@ function normalize(attachment) {
33
37
  };
34
38
  }
35
39
 
36
- // src/hooks/use-wp-media-attachment.ts
37
- function useWpMediaAttachment(id) {
38
- return useQuery({
39
- queryKey: ["wp-attachment", id],
40
- queryFn: getAttachment,
41
- enabled: !!id
42
- });
43
- }
44
- async function getAttachment({ queryKey: [, id] }) {
40
+ // src/get-media-attachment.ts
41
+ async function getMediaAttachment({ id }) {
45
42
  if (!id) {
46
43
  return null;
47
44
  }
@@ -58,8 +55,29 @@ async function getAttachment({ queryKey: [, id] }) {
58
55
  }
59
56
  }
60
57
 
58
+ // src/hooks/use-wp-media-attachment.ts
59
+ function useWpMediaAttachment(id) {
60
+ return useQuery({
61
+ queryKey: ["wp-attachment", id],
62
+ queryFn: () => getMediaAttachment({ id }),
63
+ enabled: !!id
64
+ });
65
+ }
66
+
61
67
  // src/hooks/use-wp-media-frame.ts
62
68
  import { useEffect, useRef } from "react";
69
+
70
+ // src/wp-plupload-settings.ts
71
+ var wpPluploadSettingsWindow = window;
72
+ var wp_plupload_settings_default = () => {
73
+ if (!wpPluploadSettingsWindow._wpPluploadSettings) {
74
+ throw new WpPluploadSettingsNotAvailableError();
75
+ }
76
+ return wpPluploadSettingsWindow._wpPluploadSettings;
77
+ };
78
+
79
+ // src/hooks/use-wp-media-frame.ts
80
+ var defaultImageExtensions = ["avif", "bmp", "gif", "ico", "jpe", "jpeg", "jpg", "png", "webp"];
63
81
  function useWpMediaFrame(options) {
64
82
  const frame = useRef();
65
83
  const open = (openOptions = {}) => {
@@ -76,7 +94,15 @@ function useWpMediaFrame(options) {
76
94
  open
77
95
  };
78
96
  }
79
- function createFrame({ onSelect, multiple, types, selected, title, mode = "browse" }) {
97
+ function createFrame({
98
+ onSelect,
99
+ multiple,
100
+ types,
101
+ selected,
102
+ title,
103
+ mode = "browse",
104
+ allowedExtensions
105
+ }) {
80
106
  const frame = media_default()({
81
107
  title,
82
108
  multiple,
@@ -84,9 +110,11 @@ function createFrame({ onSelect, multiple, types, selected, title, mode = "brows
84
110
  type: types
85
111
  }
86
112
  }).on("open", () => {
113
+ setTypeCaller(frame);
87
114
  applyMode(frame, mode);
88
115
  applySelection(frame, selected);
89
116
  }).on("close", () => cleanupFrame(frame)).on("insert select", () => select(frame, multiple, onSelect));
117
+ handleAllowedExtensions(frame, allowedExtensions);
90
118
  return frame;
91
119
  }
92
120
  function cleanupFrame(frame) {
@@ -105,7 +133,35 @@ function select(frame, multiple, onSelect) {
105
133
  const onSelectFn = onSelect;
106
134
  onSelectFn(multiple ? attachments : attachments[0]);
107
135
  }
136
+ function setTypeCaller(frame) {
137
+ frame.uploader.uploader.param("uploadTypeCaller", "elementor-wp-media-upload");
138
+ }
139
+ function handleAllowedExtensions(frame, allowedExtensions) {
140
+ const defaultExtensions = wp_plupload_settings_default().defaults.filters.mime_types?.[0]?.extensions;
141
+ frame.on("ready", () => {
142
+ wp_plupload_settings_default().defaults.filters.mime_types = [
143
+ { extensions: getAllowedExtensions(allowedExtensions) }
144
+ ];
145
+ });
146
+ frame.on("close", () => {
147
+ wp_plupload_settings_default().defaults.filters.mime_types = defaultExtensions ? [{ extensions: defaultExtensions }] : [];
148
+ });
149
+ }
150
+ function getAllowedExtensions(allowedExtensions) {
151
+ let extensions = [...defaultImageExtensions];
152
+ if (allowedExtensions) {
153
+ extensions = allowedExtensions;
154
+ } else if (isUnfilteredFilesUploadEnabled()) {
155
+ extensions.push("svg");
156
+ }
157
+ return extensions.join(",");
158
+ }
159
+ function isUnfilteredFilesUploadEnabled() {
160
+ const extendedWindow = window;
161
+ return Boolean(extendedWindow.elementorCommon.config.filesUpload.unfilteredFiles);
162
+ }
108
163
  export {
164
+ getMediaAttachment,
109
165
  useWpMediaAttachment,
110
166
  useWpMediaFrame
111
167
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/hooks/use-wp-media-attachment.ts","../src/errors.ts","../src/media.ts","../src/normalize.ts","../src/hooks/use-wp-media-frame.ts"],"sourcesContent":["import { useQuery } from '@elementor/query';\n\nimport media from '../media';\nimport normalize from '../normalize';\n\nexport default function useWpMediaAttachment( id: number | null ) {\n\treturn useQuery( {\n\t\tqueryKey: [ 'wp-attachment', id ],\n\t\tqueryFn: getAttachment,\n\t\tenabled: !! id,\n\t} );\n}\n\nasync function getAttachment( { queryKey: [ , id ] }: { queryKey: [ string, number | null ] } ) {\n\tif ( ! id ) {\n\t\treturn null;\n\t}\n\n\tconst model = media().attachment( id );\n\tconst wpAttachment = model.toJSON();\n\n\tconst isFetched = 'url' in wpAttachment;\n\n\tif ( isFetched ) {\n\t\treturn normalize( wpAttachment );\n\t}\n\n\ttry {\n\t\treturn normalize( await model.fetch() );\n\t} catch {\n\t\treturn null;\n\t}\n}\n","import { createError } from '@elementor/utils';\n\nexport const WpMediaNotAvailableError = createError( {\n\tcode: 'wp_media_not_available',\n\tmessage: '`wp.media` is not available, make sure the `media-models` handle is set in the dependencies array',\n} );\n","import { WpMediaNotAvailableError } from './errors';\nimport { type WpMediaWindow } from './types/wp-media';\n\nconst wpMediaWindow = window as unknown as WpMediaWindow;\n\nexport default () => {\n\tif ( ! wpMediaWindow.wp?.media ) {\n\t\tthrow new WpMediaNotAvailableError();\n\t}\n\n\treturn wpMediaWindow.wp.media;\n};\n","import { type Attachment } from './types/attachment';\nimport { type WpAttachmentJSON } from './types/wp-media';\n\nexport default function normalize( attachment: WpAttachmentJSON ): Attachment {\n\tconst { filesizeInBytes, filesizeHumanReadable, author, authorName, ...rest } = attachment;\n\n\treturn {\n\t\t...rest,\n\t\tfilesize: {\n\t\t\tinBytes: filesizeInBytes,\n\t\t\thumanReadable: filesizeHumanReadable,\n\t\t},\n\t\tauthor: {\n\t\t\tid: parseInt( author ),\n\t\t\tname: authorName,\n\t\t},\n\t};\n}\n","import { useEffect, useRef } from 'react';\n\nimport media from '../media';\nimport normalize from '../normalize';\nimport { type Attachment } from '../types/attachment';\nimport { type MediaFrame } from '../types/wp-media';\n\ntype OpenOptions = {\n\tmode?: 'upload' | 'browse';\n};\n\ntype Options = {\n\ttypes: Array< 'image' >;\n\ttitle?: string;\n} & (\n\t| {\n\t\t\tmultiple: true;\n\t\t\tselected: Array< number | null >;\n\t\t\tonSelect: ( val: Attachment[] ) => void;\n\t }\n\t| {\n\t\t\tmultiple: false;\n\t\t\tselected: number | null;\n\t\t\tonSelect: ( val: Attachment ) => void;\n\t }\n);\n\nexport default function useWpMediaFrame( options: Options ) {\n\tconst frame = useRef< MediaFrame >();\n\n\tconst open = ( openOptions: OpenOptions = {} ) => {\n\t\tcleanupFrame( frame.current );\n\n\t\tframe.current = createFrame( { ...options, ...openOptions } );\n\n\t\tframe.current?.open();\n\t};\n\n\tuseEffect( () => {\n\t\treturn () => {\n\t\t\tcleanupFrame( frame.current );\n\t\t};\n\t}, [] );\n\n\treturn {\n\t\topen,\n\t};\n}\n\nfunction createFrame( { onSelect, multiple, types, selected, title, mode = 'browse' }: Options & OpenOptions ) {\n\tconst frame: MediaFrame = media()( {\n\t\ttitle,\n\t\tmultiple,\n\t\tlibrary: {\n\t\t\ttype: types,\n\t\t},\n\t} )\n\t\t.on( 'open', () => {\n\t\t\tapplyMode( frame, mode );\n\t\t\tapplySelection( frame, selected );\n\t\t} )\n\t\t.on( 'close', () => cleanupFrame( frame ) )\n\t\t.on( 'insert select', () => select( frame, multiple, onSelect ) );\n\n\treturn frame;\n}\n\nfunction cleanupFrame( frame?: MediaFrame ) {\n\tframe?.detach();\n\tframe?.remove();\n}\n\nfunction applyMode( frame: MediaFrame, mode: OpenOptions[ 'mode' ] = 'browse' ) {\n\tframe.content.mode( mode );\n}\n\nfunction applySelection( frame: MediaFrame, selected: number | null | Array< number | null > ) {\n\tconst selectedAttachments = ( typeof selected === 'number' ? [ selected ] : selected )\n\t\t?.filter( ( id ) => !! id )\n\t\t.map( ( id ) => media().attachment( id as number ) );\n\n\tframe\n\t\t.state()\n\t\t.get( 'selection' )\n\t\t.set( selectedAttachments || [] );\n}\n\nfunction select( frame: MediaFrame, multiple: boolean, onSelect: Options[ 'onSelect' ] ) {\n\tconst attachments = frame.state().get( 'selection' ).toJSON().map( normalize );\n\n\tconst onSelectFn = onSelect as ( val: Attachment | Attachment[] ) => void;\n\n\tonSelectFn( multiple ? attachments : attachments[ 0 ] );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/hooks/use-wp-media-attachment.ts","../src/errors.ts","../src/media.ts","../src/normalize.ts","../src/get-media-attachment.ts","../src/hooks/use-wp-media-frame.ts","../src/wp-plupload-settings.ts"],"sourcesContent":["import { useQuery } from '@elementor/query';\n\nimport { getMediaAttachment } from '../get-media-attachment';\n\nexport default function useWpMediaAttachment( id: number | null ) {\n\treturn useQuery( {\n\t\tqueryKey: [ 'wp-attachment', id ],\n\t\tqueryFn: () => getMediaAttachment( { id } ),\n\t\tenabled: !! id,\n\t} );\n}\n","import { createError } from '@elementor/utils';\n\nexport const WpMediaNotAvailableError = createError( {\n\tcode: 'wp_media_not_available',\n\tmessage: '`wp.media` is not available, make sure the `media-models` handle is set in the dependencies array',\n} );\n\nexport const WpPluploadSettingsNotAvailableError = createError( {\n\tcode: 'wp_plupload_settings_not_available',\n\tmessage: '`_wpPluploadSettings` is not available, make sure a wp media uploader is open',\n} );\n","import { WpMediaNotAvailableError } from './errors';\nimport { type WpMediaWindow } from './types/wp-media';\n\nconst wpMediaWindow = window as unknown as WpMediaWindow;\n\nexport default () => {\n\tif ( ! wpMediaWindow.wp?.media ) {\n\t\tthrow new WpMediaNotAvailableError();\n\t}\n\n\treturn wpMediaWindow.wp.media;\n};\n","import { type Attachment } from './types/attachment';\nimport { type WpAttachmentJSON } from './types/wp-media';\n\nexport default function normalize( attachment: WpAttachmentJSON ): Attachment {\n\tconst { filesizeInBytes, filesizeHumanReadable, author, authorName, ...rest } = attachment;\n\n\treturn {\n\t\t...rest,\n\t\tfilesize: {\n\t\t\tinBytes: filesizeInBytes,\n\t\t\thumanReadable: filesizeHumanReadable,\n\t\t},\n\t\tauthor: {\n\t\t\tid: parseInt( author ),\n\t\t\tname: authorName,\n\t\t},\n\t};\n}\n","import media from './media';\nimport normalize from './normalize';\n\nexport async function getMediaAttachment( { id }: { id: number | null } ) {\n\tif ( ! id ) {\n\t\treturn null;\n\t}\n\n\tconst model = media().attachment( id );\n\tconst wpAttachment = model.toJSON();\n\n\tconst isFetched = 'url' in wpAttachment;\n\n\tif ( isFetched ) {\n\t\treturn normalize( wpAttachment );\n\t}\n\n\ttry {\n\t\treturn normalize( await model.fetch() );\n\t} catch {\n\t\treturn null;\n\t}\n}\n","import { useEffect, useRef } from 'react';\n\nimport media from '../media';\nimport normalize from '../normalize';\nimport { type Attachment } from '../types/attachment';\nimport { type ElementorCommonWindow } from '../types/elementor-common';\nimport { type ImageExtension } from '../types/image';\nimport { type MediaFrame } from '../types/wp-media';\nimport wpPluploadSettings from '../wp-plupload-settings';\n\ntype OpenOptions = {\n\tmode?: 'upload' | 'browse';\n};\n\ntype Options = {\n\ttypes: Array< 'image' | 'image/svg+xml' >;\n\tallowedExtensions?: ImageExtension[];\n\ttitle?: string;\n} & (\n\t| {\n\t\t\tmultiple: true;\n\t\t\tselected: Array< number | null >;\n\t\t\tonSelect: ( val: Attachment[] ) => void;\n\t }\n\t| {\n\t\t\tmultiple: false;\n\t\t\tselected: number | null;\n\t\t\tonSelect: ( val: Attachment ) => void;\n\t }\n);\n\nconst defaultImageExtensions: ImageExtension[] = [ 'avif', 'bmp', 'gif', 'ico', 'jpe', 'jpeg', 'jpg', 'png', 'webp' ];\n\nexport default function useWpMediaFrame( options: Options ) {\n\tconst frame = useRef< MediaFrame >();\n\n\tconst open = ( openOptions: OpenOptions = {} ) => {\n\t\tcleanupFrame( frame.current );\n\n\t\tframe.current = createFrame( { ...options, ...openOptions } );\n\n\t\tframe.current?.open();\n\t};\n\n\tuseEffect( () => {\n\t\treturn () => {\n\t\t\tcleanupFrame( frame.current );\n\t\t};\n\t}, [] );\n\n\treturn {\n\t\topen,\n\t};\n}\n\nfunction createFrame( {\n\tonSelect,\n\tmultiple,\n\ttypes,\n\tselected,\n\ttitle,\n\tmode = 'browse',\n\tallowedExtensions,\n}: Options & OpenOptions ) {\n\tconst frame: MediaFrame = media()( {\n\t\ttitle,\n\t\tmultiple,\n\t\tlibrary: {\n\t\t\ttype: types,\n\t\t},\n\t} )\n\t\t.on( 'open', () => {\n\t\t\tsetTypeCaller( frame );\n\t\t\tapplyMode( frame, mode );\n\t\t\tapplySelection( frame, selected );\n\t\t} )\n\t\t.on( 'close', () => cleanupFrame( frame ) )\n\t\t.on( 'insert select', () => select( frame, multiple, onSelect ) );\n\n\thandleAllowedExtensions( frame, allowedExtensions );\n\n\treturn frame;\n}\n\nfunction cleanupFrame( frame?: MediaFrame ) {\n\tframe?.detach();\n\tframe?.remove();\n}\n\nfunction applyMode( frame: MediaFrame, mode: OpenOptions[ 'mode' ] = 'browse' ) {\n\tframe.content.mode( mode );\n}\n\nfunction applySelection( frame: MediaFrame, selected: number | null | Array< number | null > ) {\n\tconst selectedAttachments = ( typeof selected === 'number' ? [ selected ] : selected )\n\t\t?.filter( ( id ) => !! id )\n\t\t.map( ( id ) => media().attachment( id as number ) );\n\n\tframe\n\t\t.state()\n\t\t.get( 'selection' )\n\t\t.set( selectedAttachments || [] );\n}\n\nfunction select( frame: MediaFrame, multiple: boolean, onSelect: Options[ 'onSelect' ] ) {\n\tconst attachments = frame.state().get( 'selection' ).toJSON().map( normalize );\n\n\tconst onSelectFn = onSelect as ( val: Attachment | Attachment[] ) => void;\n\n\tonSelectFn( multiple ? attachments : attachments[ 0 ] );\n}\n\nfunction setTypeCaller( frame: MediaFrame ) {\n\tframe.uploader.uploader.param( 'uploadTypeCaller', 'elementor-wp-media-upload' );\n}\n\nfunction handleAllowedExtensions( frame: MediaFrame, allowedExtensions?: ImageExtension[] ) {\n\tconst defaultExtensions = wpPluploadSettings().defaults.filters.mime_types?.[ 0 ]?.extensions;\n\n\t// Set the allowed extensions\n\tframe.on( 'ready', () => {\n\t\twpPluploadSettings().defaults.filters.mime_types = [\n\t\t\t{ extensions: getAllowedExtensions( allowedExtensions ) },\n\t\t];\n\t} );\n\n\t// Restore default upload extensions\n\tframe.on( 'close', () => {\n\t\twpPluploadSettings().defaults.filters.mime_types = defaultExtensions\n\t\t\t? [ { extensions: defaultExtensions } ]\n\t\t\t: [];\n\t} );\n}\n\nfunction getAllowedExtensions( allowedExtensions?: ImageExtension[] ) {\n\tlet extensions: ImageExtension[] = [ ...defaultImageExtensions ];\n\n\tif ( allowedExtensions ) {\n\t\textensions = allowedExtensions;\n\t} else if ( isUnfilteredFilesUploadEnabled() ) {\n\t\textensions.push( 'svg' );\n\t}\n\n\treturn extensions.join( ',' );\n}\n\nfunction isUnfilteredFilesUploadEnabled(): boolean {\n\tconst extendedWindow = window as unknown as ElementorCommonWindow;\n\n\treturn Boolean( extendedWindow.elementorCommon.config.filesUpload.unfilteredFiles );\n}\n","import { WpPluploadSettingsNotAvailableError } from './errors';\nimport { type WpPluploadSettingsWindow } from './types/plupload';\n\nconst wpPluploadSettingsWindow = window as unknown as WpPluploadSettingsWindow;\n\nexport default () => {\n\tif ( ! wpPluploadSettingsWindow._wpPluploadSettings ) {\n\t\tthrow new WpPluploadSettingsNotAvailableError();\n\t}\n\n\treturn wpPluploadSettingsWindow._wpPluploadSettings;\n};\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@elementor/wp-media",
3
3
  "description": "An adapter for WordPress' media utils",
4
- "version": "0.2.3",
4
+ "version": "0.4.0",
5
5
  "private": false,
6
6
  "author": "Elementor Team",
7
7
  "homepage": "https://elementor.com/",
package/src/errors.ts CHANGED
@@ -4,3 +4,8 @@ export const WpMediaNotAvailableError = createError( {
4
4
  code: 'wp_media_not_available',
5
5
  message: '`wp.media` is not available, make sure the `media-models` handle is set in the dependencies array',
6
6
  } );
7
+
8
+ export const WpPluploadSettingsNotAvailableError = createError( {
9
+ code: 'wp_plupload_settings_not_available',
10
+ message: '`_wpPluploadSettings` is not available, make sure a wp media uploader is open',
11
+ } );
@@ -0,0 +1,23 @@
1
+ import media from './media';
2
+ import normalize from './normalize';
3
+
4
+ export async function getMediaAttachment( { id }: { id: number | null } ) {
5
+ if ( ! id ) {
6
+ return null;
7
+ }
8
+
9
+ const model = media().attachment( id );
10
+ const wpAttachment = model.toJSON();
11
+
12
+ const isFetched = 'url' in wpAttachment;
13
+
14
+ if ( isFetched ) {
15
+ return normalize( wpAttachment );
16
+ }
17
+
18
+ try {
19
+ return normalize( await model.fetch() );
20
+ } catch {
21
+ return null;
22
+ }
23
+ }
@@ -1,33 +1,11 @@
1
1
  import { useQuery } from '@elementor/query';
2
2
 
3
- import media from '../media';
4
- import normalize from '../normalize';
3
+ import { getMediaAttachment } from '../get-media-attachment';
5
4
 
6
5
  export default function useWpMediaAttachment( id: number | null ) {
7
6
  return useQuery( {
8
7
  queryKey: [ 'wp-attachment', id ],
9
- queryFn: getAttachment,
8
+ queryFn: () => getMediaAttachment( { id } ),
10
9
  enabled: !! id,
11
10
  } );
12
11
  }
13
-
14
- async function getAttachment( { queryKey: [ , id ] }: { queryKey: [ string, number | null ] } ) {
15
- if ( ! id ) {
16
- return null;
17
- }
18
-
19
- const model = media().attachment( id );
20
- const wpAttachment = model.toJSON();
21
-
22
- const isFetched = 'url' in wpAttachment;
23
-
24
- if ( isFetched ) {
25
- return normalize( wpAttachment );
26
- }
27
-
28
- try {
29
- return normalize( await model.fetch() );
30
- } catch {
31
- return null;
32
- }
33
- }
@@ -3,14 +3,18 @@ import { useEffect, useRef } from 'react';
3
3
  import media from '../media';
4
4
  import normalize from '../normalize';
5
5
  import { type Attachment } from '../types/attachment';
6
+ import { type ElementorCommonWindow } from '../types/elementor-common';
7
+ import { type ImageExtension } from '../types/image';
6
8
  import { type MediaFrame } from '../types/wp-media';
9
+ import wpPluploadSettings from '../wp-plupload-settings';
7
10
 
8
11
  type OpenOptions = {
9
12
  mode?: 'upload' | 'browse';
10
13
  };
11
14
 
12
15
  type Options = {
13
- types: Array< 'image' >;
16
+ types: Array< 'image' | 'image/svg+xml' >;
17
+ allowedExtensions?: ImageExtension[];
14
18
  title?: string;
15
19
  } & (
16
20
  | {
@@ -25,6 +29,8 @@ type Options = {
25
29
  }
26
30
  );
27
31
 
32
+ const defaultImageExtensions: ImageExtension[] = [ 'avif', 'bmp', 'gif', 'ico', 'jpe', 'jpeg', 'jpg', 'png', 'webp' ];
33
+
28
34
  export default function useWpMediaFrame( options: Options ) {
29
35
  const frame = useRef< MediaFrame >();
30
36
 
@@ -47,7 +53,15 @@ export default function useWpMediaFrame( options: Options ) {
47
53
  };
48
54
  }
49
55
 
50
- function createFrame( { onSelect, multiple, types, selected, title, mode = 'browse' }: Options & OpenOptions ) {
56
+ function createFrame( {
57
+ onSelect,
58
+ multiple,
59
+ types,
60
+ selected,
61
+ title,
62
+ mode = 'browse',
63
+ allowedExtensions,
64
+ }: Options & OpenOptions ) {
51
65
  const frame: MediaFrame = media()( {
52
66
  title,
53
67
  multiple,
@@ -56,12 +70,15 @@ function createFrame( { onSelect, multiple, types, selected, title, mode = 'brow
56
70
  },
57
71
  } )
58
72
  .on( 'open', () => {
73
+ setTypeCaller( frame );
59
74
  applyMode( frame, mode );
60
75
  applySelection( frame, selected );
61
76
  } )
62
77
  .on( 'close', () => cleanupFrame( frame ) )
63
78
  .on( 'insert select', () => select( frame, multiple, onSelect ) );
64
79
 
80
+ handleAllowedExtensions( frame, allowedExtensions );
81
+
65
82
  return frame;
66
83
  }
67
84
 
@@ -92,3 +109,43 @@ function select( frame: MediaFrame, multiple: boolean, onSelect: Options[ 'onSel
92
109
 
93
110
  onSelectFn( multiple ? attachments : attachments[ 0 ] );
94
111
  }
112
+
113
+ function setTypeCaller( frame: MediaFrame ) {
114
+ frame.uploader.uploader.param( 'uploadTypeCaller', 'elementor-wp-media-upload' );
115
+ }
116
+
117
+ function handleAllowedExtensions( frame: MediaFrame, allowedExtensions?: ImageExtension[] ) {
118
+ const defaultExtensions = wpPluploadSettings().defaults.filters.mime_types?.[ 0 ]?.extensions;
119
+
120
+ // Set the allowed extensions
121
+ frame.on( 'ready', () => {
122
+ wpPluploadSettings().defaults.filters.mime_types = [
123
+ { extensions: getAllowedExtensions( allowedExtensions ) },
124
+ ];
125
+ } );
126
+
127
+ // Restore default upload extensions
128
+ frame.on( 'close', () => {
129
+ wpPluploadSettings().defaults.filters.mime_types = defaultExtensions
130
+ ? [ { extensions: defaultExtensions } ]
131
+ : [];
132
+ } );
133
+ }
134
+
135
+ function getAllowedExtensions( allowedExtensions?: ImageExtension[] ) {
136
+ let extensions: ImageExtension[] = [ ...defaultImageExtensions ];
137
+
138
+ if ( allowedExtensions ) {
139
+ extensions = allowedExtensions;
140
+ } else if ( isUnfilteredFilesUploadEnabled() ) {
141
+ extensions.push( 'svg' );
142
+ }
143
+
144
+ return extensions.join( ',' );
145
+ }
146
+
147
+ function isUnfilteredFilesUploadEnabled(): boolean {
148
+ const extendedWindow = window as unknown as ElementorCommonWindow;
149
+
150
+ return Boolean( extendedWindow.elementorCommon.config.filesUpload.unfilteredFiles );
151
+ }
package/src/index.ts CHANGED
@@ -1,4 +1,7 @@
1
1
  export type { Attachment } from './types/attachment';
2
+ export type { ImageExtension } from './types/image';
2
3
 
3
4
  export { default as useWpMediaAttachment } from './hooks/use-wp-media-attachment';
4
5
  export { default as useWpMediaFrame } from './hooks/use-wp-media-frame';
6
+
7
+ export { getMediaAttachment } from './get-media-attachment';
@@ -0,0 +1,9 @@
1
+ export type ElementorCommonWindow = Window & {
2
+ elementorCommon: {
3
+ config: {
4
+ filesUpload: {
5
+ unfilteredFiles?: boolean;
6
+ };
7
+ };
8
+ };
9
+ };
@@ -0,0 +1 @@
1
+ export type ImageExtension = 'avif' | 'bmp' | 'gif' | 'ico' | 'jpe' | 'jpeg' | 'jpg' | 'png' | 'svg' | 'webp';
@@ -0,0 +1,18 @@
1
+ type PluploadFilters = {
2
+ mime_types?: PluploadFiltersMimeTypes[];
3
+ max_file_size?: number | string;
4
+ prevent_duplicates?: boolean;
5
+ };
6
+
7
+ type PluploadFiltersMimeTypes = {
8
+ title?: string;
9
+ extensions: string;
10
+ };
11
+
12
+ export type WpPluploadSettingsWindow = Window & {
13
+ _wpPluploadSettings?: {
14
+ defaults: {
15
+ filters: PluploadFilters;
16
+ };
17
+ };
18
+ };
@@ -21,6 +21,11 @@ export type MediaFrame = {
21
21
  content: {
22
22
  mode: ( mode: string ) => void;
23
23
  };
24
+ uploader: {
25
+ uploader: {
26
+ param: ( key: string, value: string ) => void;
27
+ };
28
+ };
24
29
  state: () => {
25
30
  get: ( key: 'selection' ) => {
26
31
  set: ( attachments: BackboneAttachmentModel[] ) => void;
@@ -0,0 +1,12 @@
1
+ import { WpPluploadSettingsNotAvailableError } from './errors';
2
+ import { type WpPluploadSettingsWindow } from './types/plupload';
3
+
4
+ const wpPluploadSettingsWindow = window as unknown as WpPluploadSettingsWindow;
5
+
6
+ export default () => {
7
+ if ( ! wpPluploadSettingsWindow._wpPluploadSettings ) {
8
+ throw new WpPluploadSettingsNotAvailableError();
9
+ }
10
+
11
+ return wpPluploadSettingsWindow._wpPluploadSettings;
12
+ };