@wordpress/editor 13.1.0 → 13.3.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 +4 -0
- package/LICENSE.md +1 -1
- package/build/components/error-boundary/index.js +24 -30
- package/build/components/error-boundary/index.js.map +1 -1
- package/build/components/media-categories/index.js +237 -0
- package/build/components/media-categories/index.js.map +1 -0
- package/build/components/page-attributes/parent.js +1 -1
- package/build/components/page-attributes/parent.js.map +1 -1
- package/build/components/post-author/select.js +1 -0
- package/build/components/post-author/select.js.map +1 -1
- package/build/components/post-format/index.js +1 -0
- package/build/components/post-format/index.js.map +1 -1
- package/build/components/post-publish-panel/postpublish.js +1 -0
- package/build/components/post-publish-panel/postpublish.js.map +1 -1
- package/build/components/post-slug/index.js +1 -0
- package/build/components/post-slug/index.js.map +1 -1
- package/build/components/post-taxonomies/hierarchical-term-selector.js +7 -3
- package/build/components/post-taxonomies/hierarchical-term-selector.js.map +1 -1
- package/build/components/post-template/index.js +8 -4
- package/build/components/post-template/index.js.map +1 -1
- package/build/components/post-url/index.js +1 -0
- package/build/components/post-url/index.js.map +1 -1
- package/build/components/provider/index.js +26 -8
- package/build/components/provider/index.js.map +1 -1
- package/build/components/provider/index.native.js +21 -14
- package/build/components/provider/index.native.js.map +1 -1
- package/build/components/provider/use-block-editor-settings.js +7 -4
- package/build/components/provider/use-block-editor-settings.js.map +1 -1
- package/build/components/provider/use-block-editor-settings.native.js +1 -2
- package/build/components/provider/use-block-editor-settings.native.js.map +1 -1
- package/build/components/table-of-contents/index.js +3 -1
- package/build/components/table-of-contents/index.js.map +1 -1
- package/build/components/unsaved-changes-warning/index.js +1 -1
- package/build/components/unsaved-changes-warning/index.js.map +1 -1
- package/build/experiments.js +20 -0
- package/build/experiments.js.map +1 -0
- package/build/hooks/custom-sources-backwards-compatibility.js +16 -8
- package/build/hooks/custom-sources-backwards-compatibility.js.map +1 -1
- package/build/hooks/default-autocompleters.js +2 -7
- package/build/hooks/default-autocompleters.js.map +1 -1
- package/build/index.js +14 -0
- package/build/index.js.map +1 -1
- package/build/index.native.js +14 -0
- package/build/index.native.js.map +1 -1
- package/build/lockUnlock.js +19 -0
- package/build/lockUnlock.js.map +1 -0
- package/build/store/defaults.js +1 -2
- package/build/store/defaults.js.map +1 -1
- package/build/store/selectors.js +1 -1
- package/build/store/selectors.js.map +1 -1
- package/build/utils/terms.js +9 -5
- package/build/utils/terms.js.map +1 -1
- package/build-module/components/error-boundary/index.js +24 -30
- package/build-module/components/error-boundary/index.js.map +1 -1
- package/build-module/components/media-categories/index.js +225 -0
- package/build-module/components/media-categories/index.js.map +1 -0
- package/build-module/components/page-attributes/parent.js +2 -2
- package/build-module/components/page-attributes/parent.js.map +1 -1
- package/build-module/components/post-author/select.js +1 -0
- package/build-module/components/post-author/select.js.map +1 -1
- package/build-module/components/post-format/index.js +1 -0
- package/build-module/components/post-format/index.js.map +1 -1
- package/build-module/components/post-publish-panel/postpublish.js +1 -0
- package/build-module/components/post-publish-panel/postpublish.js.map +1 -1
- package/build-module/components/post-slug/index.js +1 -0
- package/build-module/components/post-slug/index.js.map +1 -1
- package/build-module/components/post-taxonomies/hierarchical-term-selector.js +8 -5
- package/build-module/components/post-taxonomies/hierarchical-term-selector.js.map +1 -1
- package/build-module/components/post-template/index.js +9 -5
- package/build-module/components/post-template/index.js.map +1 -1
- package/build-module/components/post-url/index.js +1 -0
- package/build-module/components/post-url/index.js.map +1 -1
- package/build-module/components/provider/index.js +21 -9
- package/build-module/components/provider/index.js.map +1 -1
- package/build-module/components/provider/index.native.js +20 -12
- package/build-module/components/provider/index.native.js.map +1 -1
- package/build-module/components/provider/use-block-editor-settings.js +5 -5
- package/build-module/components/provider/use-block-editor-settings.js.map +1 -1
- package/build-module/components/provider/use-block-editor-settings.native.js +1 -2
- package/build-module/components/provider/use-block-editor-settings.native.js.map +1 -1
- package/build-module/components/table-of-contents/index.js +3 -1
- package/build-module/components/table-of-contents/index.js.map +1 -1
- package/build-module/components/unsaved-changes-warning/index.js +1 -1
- package/build-module/components/unsaved-changes-warning/index.js.map +1 -1
- package/build-module/experiments.js +10 -0
- package/build-module/experiments.js.map +1 -0
- package/build-module/hooks/custom-sources-backwards-compatibility.js +17 -9
- package/build-module/hooks/custom-sources-backwards-compatibility.js.map +1 -1
- package/build-module/hooks/default-autocompleters.js +2 -6
- package/build-module/hooks/default-autocompleters.js.map +1 -1
- package/build-module/index.js +1 -0
- package/build-module/index.js.map +1 -1
- package/build-module/index.native.js +1 -0
- package/build-module/index.native.js.map +1 -1
- package/build-module/lockUnlock.js +9 -0
- package/build-module/lockUnlock.js.map +1 -0
- package/build-module/store/defaults.js +1 -2
- package/build-module/store/defaults.js.map +1 -1
- package/build-module/store/selectors.js +1 -1
- package/build-module/store/selectors.js.map +1 -1
- package/build-module/utils/terms.js +9 -6
- package/build-module/utils/terms.js.map +1 -1
- package/build-style/style-rtl.css +0 -3
- package/build-style/style.css +0 -3
- package/package.json +30 -29
- package/src/components/autosave-monitor/test/index.js +8 -2
- package/src/components/editor-help/test/index.native.js +5 -5
- package/src/components/error-boundary/index.js +24 -37
- package/src/components/media-categories/index.js +247 -0
- package/src/components/page-attributes/parent.js +2 -2
- package/src/components/page-attributes/test/order.js +4 -14
- package/src/components/post-author/select.js +1 -0
- package/src/components/post-format/index.js +1 -0
- package/src/components/post-preview-button/test/index.js +5 -17
- package/src/components/post-publish-button/test/index.js +5 -17
- package/src/components/post-publish-panel/postpublish.js +1 -0
- package/src/components/post-publish-panel/style.scss +1 -5
- package/src/components/post-publish-panel/test/__snapshots__/index.js.snap +2 -18
- package/src/components/post-saved-state/test/index.js +1 -5
- package/src/components/post-slug/index.js +1 -0
- package/src/components/post-taxonomies/hierarchical-term-selector.js +23 -17
- package/src/components/post-template/index.js +4 -4
- package/src/components/post-url/index.js +1 -0
- package/src/components/provider/index.js +120 -91
- package/src/components/provider/index.native.js +26 -17
- package/src/components/provider/use-block-editor-settings.js +60 -49
- package/src/components/provider/use-block-editor-settings.native.js +1 -2
- package/src/components/table-of-contents/index.js +3 -1
- package/src/components/unsaved-changes-warning/index.js +1 -1
- package/src/experiments.js +10 -0
- package/src/hooks/custom-sources-backwards-compatibility.js +16 -13
- package/src/hooks/default-autocompleters.js +1 -6
- package/src/index.js +1 -0
- package/src/index.native.js +1 -0
- package/src/lockUnlock.js +9 -0
- package/src/store/defaults.js +0 -1
- package/src/store/selectors.js +1 -1
- package/src/utils/terms.js +8 -5
|
@@ -14,6 +14,18 @@ import { doAction } from '@wordpress/hooks';
|
|
|
14
14
|
*/
|
|
15
15
|
import { store as editorStore } from '../../store';
|
|
16
16
|
|
|
17
|
+
function getContent() {
|
|
18
|
+
try {
|
|
19
|
+
// While `select` in a component is generally discouraged, it is
|
|
20
|
+
// used here because it (a) reduces the chance of data loss in the
|
|
21
|
+
// case of additional errors by performing a direct retrieval and
|
|
22
|
+
// (b) avoids the performance cost associated with unnecessary
|
|
23
|
+
// content serialization throughout the lifetime of a non-erroring
|
|
24
|
+
// application.
|
|
25
|
+
return select( editorStore ).getEditedPostContent();
|
|
26
|
+
} catch ( error ) {}
|
|
27
|
+
}
|
|
28
|
+
|
|
17
29
|
function CopyButton( { text, children } ) {
|
|
18
30
|
const ref = useCopyToClipboard( text );
|
|
19
31
|
return (
|
|
@@ -27,34 +39,17 @@ class ErrorBoundary extends Component {
|
|
|
27
39
|
constructor() {
|
|
28
40
|
super( ...arguments );
|
|
29
41
|
|
|
30
|
-
this.reboot = this.reboot.bind( this );
|
|
31
|
-
this.getContent = this.getContent.bind( this );
|
|
32
|
-
|
|
33
42
|
this.state = {
|
|
34
43
|
error: null,
|
|
35
44
|
};
|
|
36
45
|
}
|
|
37
46
|
|
|
38
47
|
componentDidCatch( error ) {
|
|
39
|
-
this.setState( { error } );
|
|
40
|
-
|
|
41
48
|
doAction( 'editor.ErrorBoundary.errorLogged', error );
|
|
42
49
|
}
|
|
43
50
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
getContent() {
|
|
49
|
-
try {
|
|
50
|
-
// While `select` in a component is generally discouraged, it is
|
|
51
|
-
// used here because it (a) reduces the chance of data loss in the
|
|
52
|
-
// case of additional errors by performing a direct retrieval and
|
|
53
|
-
// (b) avoids the performance cost associated with unnecessary
|
|
54
|
-
// content serialization throughout the lifetime of a non-erroring
|
|
55
|
-
// application.
|
|
56
|
-
return select( editorStore ).getEditedPostContent();
|
|
57
|
-
} catch ( error ) {}
|
|
51
|
+
static getDerivedStateFromError( error ) {
|
|
52
|
+
return { error };
|
|
58
53
|
}
|
|
59
54
|
|
|
60
55
|
render() {
|
|
@@ -63,25 +58,17 @@ class ErrorBoundary extends Component {
|
|
|
63
58
|
return this.props.children;
|
|
64
59
|
}
|
|
65
60
|
|
|
61
|
+
const actions = [
|
|
62
|
+
<CopyButton key="copy-post" text={ getContent }>
|
|
63
|
+
{ __( 'Copy Post Text' ) }
|
|
64
|
+
</CopyButton>,
|
|
65
|
+
<CopyButton key="copy-error" text={ error.stack }>
|
|
66
|
+
{ __( 'Copy Error' ) }
|
|
67
|
+
</CopyButton>,
|
|
68
|
+
];
|
|
69
|
+
|
|
66
70
|
return (
|
|
67
|
-
<Warning
|
|
68
|
-
className="editor-error-boundary"
|
|
69
|
-
actions={ [
|
|
70
|
-
<Button
|
|
71
|
-
key="recovery"
|
|
72
|
-
onClick={ this.reboot }
|
|
73
|
-
variant="secondary"
|
|
74
|
-
>
|
|
75
|
-
{ __( 'Attempt Recovery' ) }
|
|
76
|
-
</Button>,
|
|
77
|
-
<CopyButton key="copy-post" text={ this.getContent }>
|
|
78
|
-
{ __( 'Copy Post Text' ) }
|
|
79
|
-
</CopyButton>,
|
|
80
|
-
<CopyButton key="copy-error" text={ error.stack }>
|
|
81
|
-
{ __( 'Copy Error' ) }
|
|
82
|
-
</CopyButton>,
|
|
83
|
-
] }
|
|
84
|
-
>
|
|
71
|
+
<Warning className="editor-error-boundary" actions={ actions }>
|
|
85
72
|
{ __( 'The editor has encountered an unexpected error.' ) }
|
|
86
73
|
</Warning>
|
|
87
74
|
);
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `editor` settings here need to be in sync with the corresponding ones in `editor` package.
|
|
3
|
+
* See `packages/editor/src/components/media-categories/index.js`.
|
|
4
|
+
*
|
|
5
|
+
* In the future we could consider creating an Openvese package that can be used in both `editor` and `site-editor`.
|
|
6
|
+
* The rest of the settings would still need to be in sync though.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* WordPress dependencies
|
|
11
|
+
*/
|
|
12
|
+
import { __, sprintf, _x } from '@wordpress/i18n';
|
|
13
|
+
import { resolveSelect } from '@wordpress/data';
|
|
14
|
+
import { decodeEntities } from '@wordpress/html-entities';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Internal dependencies
|
|
18
|
+
*/
|
|
19
|
+
import { store as coreStore } from '@wordpress/core-data';
|
|
20
|
+
|
|
21
|
+
/** @typedef {import('@wordpress/block-editor').InserterMediaRequest} InserterMediaRequest */
|
|
22
|
+
/** @typedef {import('@wordpress/block-editor').InserterMediaItem} InserterMediaItem */
|
|
23
|
+
/**
|
|
24
|
+
* Interface for inserter media category labels.
|
|
25
|
+
*
|
|
26
|
+
* @typedef {Object} InserterMediaCategoryLabels
|
|
27
|
+
* @property {string} name General name of the media category. It's used in the inserter media items list.
|
|
28
|
+
* @property {string} [search_items='Search'] Label for searching items. Default is ‘Search Posts’ / ‘Search Pages’.
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* Interface for inserter media category.
|
|
32
|
+
*
|
|
33
|
+
* @typedef {Object} InserterMediaCategory
|
|
34
|
+
* @property {string} name The name of the media category, that should be unique among all media categories.
|
|
35
|
+
* @property {InserterMediaCategoryLabels} labels Labels for the media category.
|
|
36
|
+
* @property {('image'|'audio'|'video')} mediaType The media type of the media category.
|
|
37
|
+
* @property {(InserterMediaRequest) => Promise<InserterMediaItem[]>} fetch The function to fetch media items for the category.
|
|
38
|
+
* @property {(InserterMediaItem) => string} [getReportUrl] If the media category supports reporting media items, this function should return
|
|
39
|
+
* the report url for the media item. It accepts the `InserterMediaItem` as an argument.
|
|
40
|
+
* @property {boolean} [isExternalResource] If the media category is an external resource, this should be set to true.
|
|
41
|
+
* This is used to avoid making a request to the external resource when the user
|
|
42
|
+
* opens the inserter for the first time.
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
const getExternalLink = ( url, text ) =>
|
|
46
|
+
`<a ${ getExternalLinkAttributes( url ) }>${ text }</a>`;
|
|
47
|
+
|
|
48
|
+
const getExternalLinkAttributes = ( url ) =>
|
|
49
|
+
`href="${ url }" target="_blank" rel="noreferrer noopener"`;
|
|
50
|
+
|
|
51
|
+
const getOpenverseLicense = ( license, licenseVersion ) => {
|
|
52
|
+
let licenseName = license.trim();
|
|
53
|
+
// PDM has no abbreviation
|
|
54
|
+
if ( license !== 'pdm' ) {
|
|
55
|
+
licenseName = license.toUpperCase().replace( 'SAMPLING', 'Sampling' );
|
|
56
|
+
}
|
|
57
|
+
// If version is known, append version to the name.
|
|
58
|
+
// The license has to have a version to be valid. Only
|
|
59
|
+
// PDM (public domain mark) doesn't have a version.
|
|
60
|
+
if ( licenseVersion ) {
|
|
61
|
+
licenseName += ` ${ licenseVersion }`;
|
|
62
|
+
}
|
|
63
|
+
// For licenses other than public-domain marks, prepend 'CC' to the name.
|
|
64
|
+
if ( ! [ 'pdm', 'cc0' ].includes( license ) ) {
|
|
65
|
+
licenseName = `CC ${ licenseName }`;
|
|
66
|
+
}
|
|
67
|
+
return licenseName;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const getOpenverseCaption = ( item ) => {
|
|
71
|
+
const {
|
|
72
|
+
title,
|
|
73
|
+
foreign_landing_url: foreignLandingUrl,
|
|
74
|
+
creator,
|
|
75
|
+
creator_url: creatorUrl,
|
|
76
|
+
license,
|
|
77
|
+
license_version: licenseVersion,
|
|
78
|
+
license_url: licenseUrl,
|
|
79
|
+
} = item;
|
|
80
|
+
const fullLicense = getOpenverseLicense( license, licenseVersion );
|
|
81
|
+
const _creator = decodeEntities( creator );
|
|
82
|
+
let _caption;
|
|
83
|
+
if ( _creator ) {
|
|
84
|
+
_caption = title
|
|
85
|
+
? sprintf(
|
|
86
|
+
// translators: %1s: Title of a media work from Openverse; %2s: Name of the work's creator; %3s: Work's licence e.g: "CC0 1.0".
|
|
87
|
+
_x( '"%1$s" by %2$s/ %3$s', 'caption' ),
|
|
88
|
+
getExternalLink(
|
|
89
|
+
foreignLandingUrl,
|
|
90
|
+
decodeEntities( title )
|
|
91
|
+
),
|
|
92
|
+
creatorUrl
|
|
93
|
+
? getExternalLink( creatorUrl, _creator )
|
|
94
|
+
: _creator,
|
|
95
|
+
licenseUrl
|
|
96
|
+
? getExternalLink(
|
|
97
|
+
`${ licenseUrl }?ref=openverse`,
|
|
98
|
+
fullLicense
|
|
99
|
+
)
|
|
100
|
+
: fullLicense
|
|
101
|
+
)
|
|
102
|
+
: sprintf(
|
|
103
|
+
// translators: %1s: Link attributes for a given Openverse media work; %2s: Name of the work's creator; %3s: Works's licence e.g: "CC0 1.0".
|
|
104
|
+
_x( '<a %1$s>Work</a> by %2$s/ %3$s', 'caption' ),
|
|
105
|
+
getExternalLinkAttributes( foreignLandingUrl ),
|
|
106
|
+
creatorUrl
|
|
107
|
+
? getExternalLink( creatorUrl, _creator )
|
|
108
|
+
: _creator,
|
|
109
|
+
licenseUrl
|
|
110
|
+
? getExternalLink(
|
|
111
|
+
`${ licenseUrl }?ref=openverse`,
|
|
112
|
+
fullLicense
|
|
113
|
+
)
|
|
114
|
+
: fullLicense
|
|
115
|
+
);
|
|
116
|
+
} else {
|
|
117
|
+
_caption = title
|
|
118
|
+
? sprintf(
|
|
119
|
+
// translators: %1s: Title of a media work from Openverse; %2s: Work's licence e.g: "CC0 1.0".
|
|
120
|
+
_x( '"%1$s"/ %2$s', 'caption' ),
|
|
121
|
+
getExternalLink(
|
|
122
|
+
foreignLandingUrl,
|
|
123
|
+
decodeEntities( title )
|
|
124
|
+
),
|
|
125
|
+
licenseUrl
|
|
126
|
+
? getExternalLink(
|
|
127
|
+
`${ licenseUrl }?ref=openverse`,
|
|
128
|
+
fullLicense
|
|
129
|
+
)
|
|
130
|
+
: fullLicense
|
|
131
|
+
)
|
|
132
|
+
: sprintf(
|
|
133
|
+
// translators: %1s: Link attributes for a given Openverse media work; %2s: Works's licence e.g: "CC0 1.0".
|
|
134
|
+
_x( '<a %1$s>Work</a>/ %3$s', 'caption' ),
|
|
135
|
+
getExternalLinkAttributes( foreignLandingUrl ),
|
|
136
|
+
licenseUrl
|
|
137
|
+
? getExternalLink(
|
|
138
|
+
`${ licenseUrl }?ref=openverse`,
|
|
139
|
+
fullLicense
|
|
140
|
+
)
|
|
141
|
+
: fullLicense
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
return _caption.replace( /\s{2}/g, ' ' );
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const coreMediaFetch = async ( query = {} ) => {
|
|
148
|
+
const mediaItems = await resolveSelect( coreStore ).getMediaItems( {
|
|
149
|
+
...query,
|
|
150
|
+
orderBy: !! query?.search ? 'relevance' : 'date',
|
|
151
|
+
} );
|
|
152
|
+
return mediaItems.map( ( mediaItem ) => ( {
|
|
153
|
+
...mediaItem,
|
|
154
|
+
alt: mediaItem.alt_text,
|
|
155
|
+
url: mediaItem.source_url,
|
|
156
|
+
previewUrl: mediaItem.media_details?.sizes?.medium?.source_url,
|
|
157
|
+
caption: mediaItem.caption?.raw,
|
|
158
|
+
} ) );
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
/** @type {InserterMediaCategory[]} */
|
|
162
|
+
const inserterMediaCategories = [
|
|
163
|
+
{
|
|
164
|
+
name: 'images',
|
|
165
|
+
labels: {
|
|
166
|
+
name: __( 'Images' ),
|
|
167
|
+
search_items: __( 'Search images' ),
|
|
168
|
+
},
|
|
169
|
+
mediaType: 'image',
|
|
170
|
+
async fetch( query = {} ) {
|
|
171
|
+
return coreMediaFetch( { ...query, media_type: 'image' } );
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
name: 'videos',
|
|
176
|
+
labels: {
|
|
177
|
+
name: __( 'Videos' ),
|
|
178
|
+
search_items: __( 'Search videos' ),
|
|
179
|
+
},
|
|
180
|
+
mediaType: 'video',
|
|
181
|
+
async fetch( query = {} ) {
|
|
182
|
+
return coreMediaFetch( { ...query, media_type: 'video' } );
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
name: 'audio',
|
|
187
|
+
labels: {
|
|
188
|
+
name: __( 'Audio' ),
|
|
189
|
+
search_items: __( 'Search audio' ),
|
|
190
|
+
},
|
|
191
|
+
mediaType: 'audio',
|
|
192
|
+
async fetch( query = {} ) {
|
|
193
|
+
return coreMediaFetch( { ...query, media_type: 'audio' } );
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
name: 'openverse',
|
|
198
|
+
labels: {
|
|
199
|
+
name: __( 'Openverse' ),
|
|
200
|
+
search_items: __( 'Search Openverse' ),
|
|
201
|
+
},
|
|
202
|
+
mediaType: 'image',
|
|
203
|
+
async fetch( query = {} ) {
|
|
204
|
+
const defaultArgs = {
|
|
205
|
+
mature: false,
|
|
206
|
+
excluded_source: 'flickr,inaturalist,wikimedia',
|
|
207
|
+
license: 'pdm,cc0',
|
|
208
|
+
};
|
|
209
|
+
const finalQuery = { ...query, ...defaultArgs };
|
|
210
|
+
const mapFromInserterMediaRequest = {
|
|
211
|
+
per_page: 'page_size',
|
|
212
|
+
search: 'q',
|
|
213
|
+
};
|
|
214
|
+
const url = new URL(
|
|
215
|
+
'https://api.openverse.engineering/v1/images/'
|
|
216
|
+
);
|
|
217
|
+
Object.entries( finalQuery ).forEach( ( [ key, value ] ) => {
|
|
218
|
+
const queryKey = mapFromInserterMediaRequest[ key ] || key;
|
|
219
|
+
url.searchParams.set( queryKey, value );
|
|
220
|
+
} );
|
|
221
|
+
const response = await window.fetch( url, {
|
|
222
|
+
headers: {
|
|
223
|
+
'User-Agent': 'WordPress/inserter-media-fetch',
|
|
224
|
+
},
|
|
225
|
+
} );
|
|
226
|
+
const jsonResponse = await response.json();
|
|
227
|
+
const results = jsonResponse.results;
|
|
228
|
+
return results.map( ( result ) => ( {
|
|
229
|
+
...result,
|
|
230
|
+
// This is a temp solution for better titles, until Openverse API
|
|
231
|
+
// completes the cleaning up of some titles of their upstream data.
|
|
232
|
+
title: result.title?.toLowerCase().startsWith( 'file:' )
|
|
233
|
+
? result.title.slice( 5 )
|
|
234
|
+
: result.title,
|
|
235
|
+
sourceId: result.id,
|
|
236
|
+
id: undefined,
|
|
237
|
+
caption: getOpenverseCaption( result ),
|
|
238
|
+
previewUrl: result.thumbnail,
|
|
239
|
+
} ) );
|
|
240
|
+
},
|
|
241
|
+
getReportUrl: ( { sourceId } ) =>
|
|
242
|
+
`https://wordpress.org/openverse/image/${ sourceId }/report/`,
|
|
243
|
+
isExternalResource: true,
|
|
244
|
+
},
|
|
245
|
+
];
|
|
246
|
+
|
|
247
|
+
export default inserterMediaCategories;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import { get
|
|
4
|
+
import { get } from 'lodash';
|
|
5
5
|
import removeAccents from 'remove-accents';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -93,7 +93,7 @@ export function PageAttributesParent() {
|
|
|
93
93
|
{
|
|
94
94
|
value: treeNode.id,
|
|
95
95
|
label:
|
|
96
|
-
'— '.repeat( level ) +
|
|
96
|
+
'— '.repeat( level ) + decodeEntities( treeNode.name ),
|
|
97
97
|
rawName: treeNode.name,
|
|
98
98
|
},
|
|
99
99
|
...getOptionsFromTree( treeNode.children || [], level + 1 ),
|
|
@@ -9,8 +9,6 @@ import userEvent from '@testing-library/user-event';
|
|
|
9
9
|
*/
|
|
10
10
|
import { PageAttributesOrder } from '../order';
|
|
11
11
|
|
|
12
|
-
jest.useFakeTimers();
|
|
13
|
-
|
|
14
12
|
describe( 'PageAttributesOrder', () => {
|
|
15
13
|
/**
|
|
16
14
|
* When starting to type inside the spinbutton, select the current value
|
|
@@ -22,9 +20,7 @@ describe( 'PageAttributesOrder', () => {
|
|
|
22
20
|
};
|
|
23
21
|
|
|
24
22
|
it( 'should reject invalid input', async () => {
|
|
25
|
-
const user = userEvent.setup(
|
|
26
|
-
advanceTimers: jest.advanceTimersByTime,
|
|
27
|
-
} );
|
|
23
|
+
const user = userEvent.setup();
|
|
28
24
|
|
|
29
25
|
const onUpdateOrder = jest.fn();
|
|
30
26
|
|
|
@@ -41,9 +37,7 @@ describe( 'PageAttributesOrder', () => {
|
|
|
41
37
|
} );
|
|
42
38
|
|
|
43
39
|
it( 'should update with zero input', async () => {
|
|
44
|
-
const user = userEvent.setup(
|
|
45
|
-
advanceTimers: jest.advanceTimersByTime,
|
|
46
|
-
} );
|
|
40
|
+
const user = userEvent.setup();
|
|
47
41
|
|
|
48
42
|
const onUpdateOrder = jest.fn();
|
|
49
43
|
|
|
@@ -59,9 +53,7 @@ describe( 'PageAttributesOrder', () => {
|
|
|
59
53
|
} );
|
|
60
54
|
|
|
61
55
|
it( 'should update with valid positive input', async () => {
|
|
62
|
-
const user = userEvent.setup(
|
|
63
|
-
advanceTimers: jest.advanceTimersByTime,
|
|
64
|
-
} );
|
|
56
|
+
const user = userEvent.setup();
|
|
65
57
|
|
|
66
58
|
const onUpdateOrder = jest.fn();
|
|
67
59
|
|
|
@@ -77,9 +69,7 @@ describe( 'PageAttributesOrder', () => {
|
|
|
77
69
|
} );
|
|
78
70
|
|
|
79
71
|
it( 'should update with valid negative input', async () => {
|
|
80
|
-
const user = userEvent.setup(
|
|
81
|
-
advanceTimers: jest.advanceTimersByTime,
|
|
82
|
-
} );
|
|
72
|
+
const user = userEvent.setup();
|
|
83
73
|
|
|
84
74
|
const onUpdateOrder = jest.fn();
|
|
85
75
|
|
|
@@ -9,8 +9,6 @@ import userEvent from '@testing-library/user-event';
|
|
|
9
9
|
*/
|
|
10
10
|
import { PostPreviewButton } from '../';
|
|
11
11
|
|
|
12
|
-
jest.useFakeTimers();
|
|
13
|
-
|
|
14
12
|
describe( 'PostPreviewButton', () => {
|
|
15
13
|
const documentWrite = jest.fn();
|
|
16
14
|
const documentTitle = jest.fn();
|
|
@@ -175,9 +173,7 @@ describe( 'PostPreviewButton', () => {
|
|
|
175
173
|
} );
|
|
176
174
|
|
|
177
175
|
it( 'should save post if `isDraft` is `true`', async () => {
|
|
178
|
-
const user = userEvent.setup(
|
|
179
|
-
advanceTimers: jest.advanceTimersByTime,
|
|
180
|
-
} );
|
|
176
|
+
const user = userEvent.setup();
|
|
181
177
|
const url = 'https://wordpress.org';
|
|
182
178
|
const savePost = jest.fn();
|
|
183
179
|
const autosave = jest.fn();
|
|
@@ -203,9 +199,7 @@ describe( 'PostPreviewButton', () => {
|
|
|
203
199
|
} );
|
|
204
200
|
|
|
205
201
|
it( 'should autosave post if `isDraft` is `false`', async () => {
|
|
206
|
-
const user = userEvent.setup(
|
|
207
|
-
advanceTimers: jest.advanceTimersByTime,
|
|
208
|
-
} );
|
|
202
|
+
const user = userEvent.setup();
|
|
209
203
|
const url = 'https://wordpress.org';
|
|
210
204
|
const savePost = jest.fn();
|
|
211
205
|
const autosave = jest.fn();
|
|
@@ -231,9 +225,7 @@ describe( 'PostPreviewButton', () => {
|
|
|
231
225
|
} );
|
|
232
226
|
|
|
233
227
|
it( 'should open a window with the specified target', async () => {
|
|
234
|
-
const user = userEvent.setup(
|
|
235
|
-
advanceTimers: jest.advanceTimersByTime,
|
|
236
|
-
} );
|
|
228
|
+
const user = userEvent.setup();
|
|
237
229
|
const postId = 123;
|
|
238
230
|
const url = 'https://wordpress.org';
|
|
239
231
|
|
|
@@ -257,9 +249,7 @@ describe( 'PostPreviewButton', () => {
|
|
|
257
249
|
} );
|
|
258
250
|
|
|
259
251
|
it( 'should set the location in the window properly', async () => {
|
|
260
|
-
const user = userEvent.setup(
|
|
261
|
-
advanceTimers: jest.advanceTimersByTime,
|
|
262
|
-
} );
|
|
252
|
+
const user = userEvent.setup();
|
|
263
253
|
const postId = 123;
|
|
264
254
|
const url = 'https://wordpress.org';
|
|
265
255
|
|
|
@@ -290,9 +280,7 @@ describe( 'PostPreviewButton', () => {
|
|
|
290
280
|
} );
|
|
291
281
|
|
|
292
282
|
it( 'should display a `Generating preview` message while waiting for autosaving', async () => {
|
|
293
|
-
const user = userEvent.setup(
|
|
294
|
-
advanceTimers: jest.advanceTimersByTime,
|
|
295
|
-
} );
|
|
283
|
+
const user = userEvent.setup();
|
|
296
284
|
const previewText = 'Generating preview…';
|
|
297
285
|
const url = 'https://wordpress.org';
|
|
298
286
|
const savePost = jest.fn();
|
|
@@ -9,8 +9,6 @@ import userEvent from '@testing-library/user-event';
|
|
|
9
9
|
*/
|
|
10
10
|
import { PostPublishButton } from '../';
|
|
11
11
|
|
|
12
|
-
jest.useFakeTimers();
|
|
13
|
-
|
|
14
12
|
describe( 'PostPublishButton', () => {
|
|
15
13
|
describe( 'aria-disabled', () => {
|
|
16
14
|
it( 'should be true if post is currently saving', () => {
|
|
@@ -92,9 +90,7 @@ describe( 'PostPublishButton', () => {
|
|
|
92
90
|
|
|
93
91
|
describe( 'publish status', () => {
|
|
94
92
|
it( 'should be pending for contributor', async () => {
|
|
95
|
-
const user = userEvent.setup(
|
|
96
|
-
advanceTimers: jest.advanceTimersByTime,
|
|
97
|
-
} );
|
|
93
|
+
const user = userEvent.setup();
|
|
98
94
|
const onStatusChange = jest.fn();
|
|
99
95
|
const onSave = jest.fn();
|
|
100
96
|
render(
|
|
@@ -115,9 +111,7 @@ describe( 'PostPublishButton', () => {
|
|
|
115
111
|
} );
|
|
116
112
|
|
|
117
113
|
it( 'should be future for scheduled post', async () => {
|
|
118
|
-
const user = userEvent.setup(
|
|
119
|
-
advanceTimers: jest.advanceTimersByTime,
|
|
120
|
-
} );
|
|
114
|
+
const user = userEvent.setup();
|
|
121
115
|
const onStatusChange = jest.fn();
|
|
122
116
|
const onSave = jest.fn();
|
|
123
117
|
render(
|
|
@@ -139,9 +133,7 @@ describe( 'PostPublishButton', () => {
|
|
|
139
133
|
} );
|
|
140
134
|
|
|
141
135
|
it( 'should be private for private visibility', async () => {
|
|
142
|
-
const user = userEvent.setup(
|
|
143
|
-
advanceTimers: jest.advanceTimersByTime,
|
|
144
|
-
} );
|
|
136
|
+
const user = userEvent.setup();
|
|
145
137
|
const onStatusChange = jest.fn();
|
|
146
138
|
const onSave = jest.fn();
|
|
147
139
|
render(
|
|
@@ -163,9 +155,7 @@ describe( 'PostPublishButton', () => {
|
|
|
163
155
|
} );
|
|
164
156
|
|
|
165
157
|
it( 'should be publish otherwise', async () => {
|
|
166
|
-
const user = userEvent.setup(
|
|
167
|
-
advanceTimers: jest.advanceTimersByTime,
|
|
168
|
-
} );
|
|
158
|
+
const user = userEvent.setup();
|
|
169
159
|
const onStatusChange = jest.fn();
|
|
170
160
|
const onSave = jest.fn();
|
|
171
161
|
render(
|
|
@@ -188,9 +178,7 @@ describe( 'PostPublishButton', () => {
|
|
|
188
178
|
|
|
189
179
|
describe( 'click', () => {
|
|
190
180
|
it( 'should save with status', async () => {
|
|
191
|
-
const user = userEvent.setup(
|
|
192
|
-
advanceTimers: jest.advanceTimersByTime,
|
|
193
|
-
} );
|
|
181
|
+
const user = userEvent.setup();
|
|
194
182
|
const onStatusChange = jest.fn();
|
|
195
183
|
const onSave = jest.fn();
|
|
196
184
|
render(
|
|
@@ -122,6 +122,7 @@ class PostPublishPanelPostpublish extends Component {
|
|
|
122
122
|
</p>
|
|
123
123
|
<div className="post-publish-panel__postpublish-post-address-container">
|
|
124
124
|
<TextControl
|
|
125
|
+
__nextHasNoMarginBottom
|
|
125
126
|
className="post-publish-panel__postpublish-post-address"
|
|
126
127
|
readOnly
|
|
127
128
|
label={ sprintf(
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
.editor-post-publish-panel__content {
|
|
6
6
|
// Ensure the post-publish panel accounts for the header and footer height.
|
|
7
|
-
min-height: calc(100% - #{
|
|
7
|
+
min-height: calc(100% - #{$header-height + 84px});
|
|
8
8
|
|
|
9
9
|
.components-spinner {
|
|
10
10
|
display: block;
|
|
@@ -157,10 +157,6 @@
|
|
|
157
157
|
align-items: flex-end;
|
|
158
158
|
margin-bottom: $grid-unit-20;
|
|
159
159
|
|
|
160
|
-
.components-base-control__field {
|
|
161
|
-
margin-bottom: 0;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
160
|
.post-publish-panel__postpublish-post-address {
|
|
165
161
|
flex: 1;
|
|
166
162
|
}
|
|
@@ -13,10 +13,6 @@ exports[`PostPublishPanel should render the post-publish panel if the post is pu
|
|
|
13
13
|
box-sizing: inherit;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
.emotion-2 {
|
|
17
|
-
margin-bottom: calc(4px * 2);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
16
|
.components-panel__row .emotion-2 {
|
|
21
17
|
margin-bottom: inherit;
|
|
22
18
|
}
|
|
@@ -31,10 +27,6 @@ exports[`PostPublishPanel should render the post-publish panel if the post is pu
|
|
|
31
27
|
padding: 0;
|
|
32
28
|
}
|
|
33
29
|
|
|
34
|
-
.components-panel__row .emotion-8 {
|
|
35
|
-
margin-bottom: inherit;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
30
|
<div>
|
|
39
31
|
<div
|
|
40
32
|
class="editor-post-publish-panel"
|
|
@@ -145,7 +137,7 @@ exports[`PostPublishPanel should render the post-publish panel if the post is pu
|
|
|
145
137
|
class="components-base-control components-checkbox-control emotion-0 emotion-1"
|
|
146
138
|
>
|
|
147
139
|
<div
|
|
148
|
-
class="components-base-control__field emotion-
|
|
140
|
+
class="components-base-control__field emotion-2 emotion-3"
|
|
149
141
|
>
|
|
150
142
|
<span
|
|
151
143
|
class="components-checkbox-control__input-container"
|
|
@@ -183,10 +175,6 @@ exports[`PostPublishPanel should render the post-publish panel if the post is sc
|
|
|
183
175
|
box-sizing: inherit;
|
|
184
176
|
}
|
|
185
177
|
|
|
186
|
-
.emotion-2 {
|
|
187
|
-
margin-bottom: calc(4px * 2);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
178
|
.components-panel__row .emotion-2 {
|
|
191
179
|
margin-bottom: inherit;
|
|
192
180
|
}
|
|
@@ -201,10 +189,6 @@ exports[`PostPublishPanel should render the post-publish panel if the post is sc
|
|
|
201
189
|
padding: 0;
|
|
202
190
|
}
|
|
203
191
|
|
|
204
|
-
.components-panel__row .emotion-8 {
|
|
205
|
-
margin-bottom: inherit;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
192
|
<div>
|
|
209
193
|
<div
|
|
210
194
|
class="editor-post-publish-panel"
|
|
@@ -315,7 +299,7 @@ exports[`PostPublishPanel should render the post-publish panel if the post is sc
|
|
|
315
299
|
class="components-base-control components-checkbox-control emotion-0 emotion-1"
|
|
316
300
|
>
|
|
317
301
|
<div
|
|
318
|
-
class="components-base-control__field emotion-
|
|
302
|
+
class="components-base-control__field emotion-2 emotion-3"
|
|
319
303
|
>
|
|
320
304
|
<span
|
|
321
305
|
class="components-checkbox-control__input-container"
|
|
@@ -15,8 +15,6 @@ import { useSelect } from '@wordpress/data';
|
|
|
15
15
|
*/
|
|
16
16
|
import PostSavedState from '../';
|
|
17
17
|
|
|
18
|
-
jest.useFakeTimers();
|
|
19
|
-
|
|
20
18
|
const mockSavePost = jest.fn();
|
|
21
19
|
|
|
22
20
|
jest.mock( '@wordpress/data/src/components/use-dispatch', () => {
|
|
@@ -96,9 +94,7 @@ describe( 'PostSavedState', () => {
|
|
|
96
94
|
} );
|
|
97
95
|
|
|
98
96
|
it( 'should return Save button if edits to be saved', async () => {
|
|
99
|
-
const user = userEvent.setup(
|
|
100
|
-
advanceTimers: jest.advanceTimersByTime,
|
|
101
|
-
} );
|
|
97
|
+
const user = userEvent.setup();
|
|
102
98
|
|
|
103
99
|
useSelect.mockImplementation( () => ( {
|
|
104
100
|
isDirty: true,
|