@wordpress/block-library 9.34.1-next.2f1c7c01b.0 → 9.35.1-next.16d95556a.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 +2 -0
- package/build/block/edit.js +2 -2
- package/build/block/edit.js.map +2 -2
- package/build/block-keyboard-shortcuts/index.js +17 -7
- package/build/block-keyboard-shortcuts/index.js.map +2 -2
- package/build/cover/deprecated.js +15 -3
- package/build/cover/deprecated.js.map +2 -2
- package/build/cover/edit/inspector-controls.js +1 -1
- package/build/cover/edit/inspector-controls.js.map +2 -2
- package/build/cover/transforms.js +10 -2
- package/build/cover/transforms.js.map +2 -2
- package/build/embed/icons.js +2 -2
- package/build/embed/icons.js.map +2 -2
- package/build/embed/variations.js +3 -3
- package/build/embed/variations.js.map +2 -2
- package/build/heading/index.js +3 -1
- package/build/heading/index.js.map +3 -3
- package/build/heading/transforms.js +10 -3
- package/build/heading/transforms.js.map +2 -2
- package/build/heading/variations.js +55 -0
- package/build/heading/variations.js.map +7 -0
- package/build/html/edit.js +54 -44
- package/build/html/edit.js.map +3 -3
- package/build/html/modal.js +328 -0
- package/build/html/modal.js.map +7 -0
- package/build/html/utils.js +72 -0
- package/build/html/utils.js.map +7 -0
- package/build/navigation-link/edit.js +25 -10
- package/build/navigation-link/edit.js.map +2 -2
- package/build/navigation-link/link-ui/index.js +8 -3
- package/build/navigation-link/link-ui/index.js.map +2 -2
- package/build/navigation-link/shared/controls.js +42 -7
- package/build/navigation-link/shared/controls.js.map +2 -2
- package/build/navigation-link/shared/use-entity-binding.js +31 -2
- package/build/navigation-link/shared/use-entity-binding.js.map +3 -3
- package/build/paragraph/block.json +1 -3
- package/build/paragraph/deprecated.js +65 -12
- package/build/paragraph/deprecated.js.map +2 -2
- package/build/paragraph/edit.js +14 -25
- package/build/paragraph/edit.js.map +2 -2
- package/build/paragraph/index.js +3 -1
- package/build/paragraph/index.js.map +3 -3
- package/build/paragraph/save.js +3 -3
- package/build/paragraph/save.js.map +2 -2
- package/build/paragraph/transforms.js +7 -1
- package/build/paragraph/transforms.js.map +2 -2
- package/build/paragraph/variations.js +57 -0
- package/build/paragraph/variations.js.map +7 -0
- package/build/pullquote/block.json +3 -2
- package/build/pullquote/transforms.js +0 -31
- package/build/pullquote/transforms.js.map +2 -2
- package/build/quote/transforms.js +0 -20
- package/build/quote/transforms.js.map +2 -2
- package/build-module/block/edit.js +2 -2
- package/build-module/block/edit.js.map +2 -2
- package/build-module/block-keyboard-shortcuts/index.js +17 -7
- package/build-module/block-keyboard-shortcuts/index.js.map +2 -2
- package/build-module/cover/deprecated.js +15 -3
- package/build-module/cover/deprecated.js.map +2 -2
- package/build-module/cover/edit/inspector-controls.js +1 -1
- package/build-module/cover/edit/inspector-controls.js.map +2 -2
- package/build-module/cover/transforms.js +10 -2
- package/build-module/cover/transforms.js.map +2 -2
- package/build-module/embed/icons.js +2 -2
- package/build-module/embed/icons.js.map +2 -2
- package/build-module/embed/variations.js +3 -3
- package/build-module/embed/variations.js.map +2 -2
- package/build-module/heading/index.js +3 -1
- package/build-module/heading/index.js.map +2 -2
- package/build-module/heading/transforms.js +10 -3
- package/build-module/heading/transforms.js.map +2 -2
- package/build-module/heading/variations.js +34 -0
- package/build-module/heading/variations.js.map +7 -0
- package/build-module/html/edit.js +62 -51
- package/build-module/html/edit.js.map +2 -2
- package/build-module/html/modal.js +304 -0
- package/build-module/html/modal.js.map +7 -0
- package/build-module/html/utils.js +46 -0
- package/build-module/html/utils.js.map +7 -0
- package/build-module/navigation-link/edit.js +25 -10
- package/build-module/navigation-link/edit.js.map +2 -2
- package/build-module/navigation-link/link-ui/index.js +8 -3
- package/build-module/navigation-link/link-ui/index.js.map +2 -2
- package/build-module/navigation-link/shared/controls.js +42 -7
- package/build-module/navigation-link/shared/controls.js.map +2 -2
- package/build-module/navigation-link/shared/use-entity-binding.js +35 -3
- package/build-module/navigation-link/shared/use-entity-binding.js.map +2 -2
- package/build-module/paragraph/block.json +1 -3
- package/build-module/paragraph/deprecated.js +65 -12
- package/build-module/paragraph/deprecated.js.map +2 -2
- package/build-module/paragraph/edit.js +14 -26
- package/build-module/paragraph/edit.js.map +2 -2
- package/build-module/paragraph/index.js +3 -1
- package/build-module/paragraph/index.js.map +2 -2
- package/build-module/paragraph/save.js +3 -3
- package/build-module/paragraph/save.js.map +2 -2
- package/build-module/paragraph/transforms.js +7 -1
- package/build-module/paragraph/transforms.js.map +2 -2
- package/build-module/paragraph/variations.js +36 -0
- package/build-module/paragraph/variations.js.map +7 -0
- package/build-module/pullquote/block.json +3 -2
- package/build-module/pullquote/transforms.js +0 -31
- package/build-module/pullquote/transforms.js.map +2 -2
- package/build-module/quote/transforms.js +0 -20
- package/build-module/quote/transforms.js.map +2 -2
- package/build-style/accordion-heading/style-rtl.css +19 -3
- package/build-style/accordion-heading/style.css +19 -3
- package/build-style/accordion-panel/style-rtl.css +4 -1
- package/build-style/accordion-panel/style.css +4 -1
- package/build-style/common-rtl.css +3 -3
- package/build-style/common.css +3 -3
- package/build-style/editor-rtl.css +62 -21
- package/build-style/editor.css +62 -21
- package/build-style/embed/style-rtl.css +5 -0
- package/build-style/embed/style.css +5 -0
- package/build-style/html/editor-rtl.css +55 -21
- package/build-style/html/editor.css +55 -21
- package/build-style/navigation-link/editor-rtl.css +7 -0
- package/build-style/navigation-link/editor.css +7 -0
- package/build-style/style-rtl.css +31 -7
- package/build-style/style.css +31 -7
- package/package.json +37 -37
- package/src/accordion-heading/style.scss +40 -7
- package/src/accordion-panel/style.scss +6 -1
- package/src/block/edit.js +2 -2
- package/src/block-keyboard-shortcuts/index.js +23 -9
- package/src/common.scss +6 -5
- package/src/cover/deprecated.js +15 -3
- package/src/cover/edit/inspector-controls.js +1 -1
- package/src/cover/transforms.js +10 -2
- package/src/embed/icons.js +2 -4
- package/src/embed/style.scss +6 -0
- package/src/embed/variations.js +3 -3
- package/src/heading/index.js +2 -0
- package/src/heading/test/__snapshots__/transforms.native.js.snap +0 -6
- package/src/heading/test/transforms.native.js +1 -5
- package/src/heading/transforms.js +10 -3
- package/src/heading/variations.js +37 -0
- package/src/html/edit.js +62 -56
- package/src/html/editor.scss +69 -10
- package/src/html/modal.js +290 -0
- package/src/html/test/utils.js +234 -0
- package/src/html/utils.js +75 -0
- package/src/navigation-link/edit.js +44 -13
- package/src/navigation-link/editor.scss +7 -0
- package/src/navigation-link/index.php +65 -2
- package/src/navigation-link/link-ui/index.js +9 -8
- package/src/navigation-link/shared/controls.js +70 -12
- package/src/navigation-link/shared/test/controls.js +5 -0
- package/src/navigation-link/shared/test/use-entity-binding.js +14 -1
- package/src/navigation-link/shared/use-entity-binding.js +57 -9
- package/src/paragraph/block.json +1 -3
- package/src/paragraph/deprecated.js +87 -20
- package/src/paragraph/edit.js +7 -18
- package/src/paragraph/edit.native.js +18 -6
- package/src/paragraph/index.js +2 -0
- package/src/paragraph/save.js +4 -3
- package/src/paragraph/test/__snapshots__/transforms.native.js.snap +0 -6
- package/src/paragraph/test/edit.native.js +5 -5
- package/src/paragraph/test/transforms.native.js +0 -1
- package/src/paragraph/transforms.js +7 -1
- package/src/paragraph/variations.js +39 -0
- package/src/pullquote/block.json +3 -2
- package/src/pullquote/test/__snapshots__/transforms.native.js.snap +5 -5
- package/src/pullquote/test/transforms.native.js +1 -1
- package/src/pullquote/transforms.js +0 -31
- package/src/quote/test/__snapshots__/transforms.native.js.snap +0 -6
- package/src/quote/test/transforms.native.js +1 -5
- package/src/quote/transforms.js +0 -25
- package/src/utils/transformation-categories.native.js +0 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/src/pullquote/test/edit.native.js +0 -73
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { __ } from '@wordpress/i18n';
|
|
5
|
+
import { Path, SVG } from '@wordpress/primitives';
|
|
6
|
+
import { heading } from '@wordpress/icons';
|
|
7
|
+
|
|
8
|
+
const variations = [
|
|
9
|
+
{
|
|
10
|
+
name: 'heading',
|
|
11
|
+
title: __( 'Heading' ),
|
|
12
|
+
description: __(
|
|
13
|
+
'Introduce new sections and organize content to help visitors (and search engines) understand the structure of your content.'
|
|
14
|
+
),
|
|
15
|
+
isDefault: true,
|
|
16
|
+
scope: [ 'inserter', 'transform' ],
|
|
17
|
+
attributes: { fitText: undefined },
|
|
18
|
+
icon: heading,
|
|
19
|
+
},
|
|
20
|
+
// There is a hardcoded workaround in packages/block-editor/src/store/selectors.js
|
|
21
|
+
// to make Stretchy variations appear as the last of their sections in the inserter.
|
|
22
|
+
{
|
|
23
|
+
name: 'stretchy-heading',
|
|
24
|
+
title: __( 'Stretchy Heading' ),
|
|
25
|
+
description: __( 'Heading that resizes to fit its container.' ),
|
|
26
|
+
icon: (
|
|
27
|
+
<SVG xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
|
28
|
+
<Path d="m3 18.6 6-4.7 6 4.7V5H3v13.6Zm16.2-9.8v1.5h2.2L17.7 14l1.1 1.1 3.7-3.7v2.2H24V8.8h-4.8Z" />
|
|
29
|
+
</SVG>
|
|
30
|
+
),
|
|
31
|
+
attributes: { fitText: true },
|
|
32
|
+
scope: [ 'inserter', 'transform' ],
|
|
33
|
+
isActive: ( blockAttributes ) => blockAttributes.fitText === true,
|
|
34
|
+
},
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
export default variations;
|
package/src/html/edit.js
CHANGED
|
@@ -2,88 +2,94 @@
|
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
4
|
import { __ } from '@wordpress/i18n';
|
|
5
|
-
import {
|
|
5
|
+
import { useState } from '@wordpress/element';
|
|
6
6
|
import {
|
|
7
7
|
BlockControls,
|
|
8
|
-
|
|
8
|
+
BlockIcon,
|
|
9
|
+
InspectorControls,
|
|
9
10
|
useBlockProps,
|
|
10
|
-
store as blockEditorStore,
|
|
11
11
|
} from '@wordpress/block-editor';
|
|
12
12
|
import {
|
|
13
13
|
ToolbarButton,
|
|
14
|
-
Disabled,
|
|
15
14
|
ToolbarGroup,
|
|
16
|
-
|
|
15
|
+
Placeholder,
|
|
16
|
+
Button,
|
|
17
|
+
__experimentalVStack as VStack,
|
|
17
18
|
} from '@wordpress/components';
|
|
18
|
-
import {
|
|
19
|
-
import { useInstanceId } from '@wordpress/compose';
|
|
19
|
+
import { code } from '@wordpress/icons';
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* Internal dependencies
|
|
23
23
|
*/
|
|
24
24
|
import Preview from './preview';
|
|
25
|
+
import HTMLEditModal from './modal';
|
|
25
26
|
|
|
26
27
|
export default function HTMLEdit( { attributes, setAttributes, isSelected } ) {
|
|
27
|
-
const [
|
|
28
|
-
const isDisabled = useContext( Disabled.Context );
|
|
29
|
-
|
|
30
|
-
const instanceId = useInstanceId( HTMLEdit, 'html-edit-desc' );
|
|
31
|
-
|
|
32
|
-
const isPreviewMode = useSelect( ( select ) => {
|
|
33
|
-
return select( blockEditorStore ).getSettings().isPreviewMode;
|
|
34
|
-
}, [] );
|
|
35
|
-
|
|
36
|
-
function switchToPreview() {
|
|
37
|
-
setIsPreview( true );
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function switchToHTML() {
|
|
41
|
-
setIsPreview( false );
|
|
42
|
-
}
|
|
43
|
-
|
|
28
|
+
const [ isModalOpen, setIsModalOpen ] = useState( false );
|
|
44
29
|
const blockProps = useBlockProps( {
|
|
45
30
|
className: 'block-library-html__edit',
|
|
46
|
-
'aria-describedby': isPreview ? instanceId : undefined,
|
|
47
31
|
} );
|
|
48
32
|
|
|
33
|
+
// Show placeholder when content is empty
|
|
34
|
+
if ( ! attributes.content?.trim() ) {
|
|
35
|
+
return (
|
|
36
|
+
<div { ...blockProps }>
|
|
37
|
+
<Placeholder
|
|
38
|
+
icon={ <BlockIcon icon={ code } /> }
|
|
39
|
+
label={ __( 'Custom HTML' ) }
|
|
40
|
+
instructions={ __(
|
|
41
|
+
'Add custom HTML code and preview how it looks.'
|
|
42
|
+
) }
|
|
43
|
+
>
|
|
44
|
+
<Button
|
|
45
|
+
__next40pxDefaultSize
|
|
46
|
+
variant="primary"
|
|
47
|
+
onClick={ () => setIsModalOpen( true ) }
|
|
48
|
+
>
|
|
49
|
+
{ __( 'Edit HTML' ) }
|
|
50
|
+
</Button>
|
|
51
|
+
</Placeholder>
|
|
52
|
+
<HTMLEditModal
|
|
53
|
+
isOpen={ isModalOpen }
|
|
54
|
+
onRequestClose={ () => setIsModalOpen( false ) }
|
|
55
|
+
content={ attributes.content }
|
|
56
|
+
setAttributes={ setAttributes }
|
|
57
|
+
/>
|
|
58
|
+
</div>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
49
62
|
return (
|
|
50
63
|
<div { ...blockProps }>
|
|
51
64
|
<BlockControls>
|
|
52
65
|
<ToolbarGroup>
|
|
53
|
-
<ToolbarButton
|
|
54
|
-
|
|
55
|
-
onClick={ switchToHTML }
|
|
56
|
-
>
|
|
57
|
-
HTML
|
|
58
|
-
</ToolbarButton>
|
|
59
|
-
<ToolbarButton
|
|
60
|
-
isPressed={ isPreview }
|
|
61
|
-
onClick={ switchToPreview }
|
|
62
|
-
>
|
|
63
|
-
{ __( 'Preview' ) }
|
|
66
|
+
<ToolbarButton onClick={ () => setIsModalOpen( true ) }>
|
|
67
|
+
{ __( 'Edit code' ) }
|
|
64
68
|
</ToolbarButton>
|
|
65
69
|
</ToolbarGroup>
|
|
66
70
|
</BlockControls>
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
) }
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
71
|
+
<InspectorControls>
|
|
72
|
+
<VStack
|
|
73
|
+
className="block-editor-block-inspector-edit-contents"
|
|
74
|
+
expanded
|
|
75
|
+
>
|
|
76
|
+
<Button
|
|
77
|
+
className="block-editor-block-inspector-edit-contents__button"
|
|
78
|
+
__next40pxDefaultSize
|
|
79
|
+
variant="secondary"
|
|
80
|
+
onClick={ () => setIsModalOpen( true ) }
|
|
81
|
+
>
|
|
82
|
+
{ __( 'Edit code' ) }
|
|
83
|
+
</Button>
|
|
84
|
+
</VStack>
|
|
85
|
+
</InspectorControls>
|
|
86
|
+
<Preview content={ attributes.content } isSelected={ isSelected } />
|
|
87
|
+
<HTMLEditModal
|
|
88
|
+
isOpen={ isModalOpen }
|
|
89
|
+
onRequestClose={ () => setIsModalOpen( false ) }
|
|
90
|
+
content={ attributes.content }
|
|
91
|
+
setAttributes={ setAttributes }
|
|
92
|
+
/>
|
|
87
93
|
</div>
|
|
88
94
|
);
|
|
89
95
|
}
|
package/src/html/editor.scss
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
@use "@wordpress/base-styles/mixins" as *;
|
|
2
|
+
@use "@wordpress/base-styles/variables" as *;
|
|
3
|
+
@use "@wordpress/base-styles/colors" as *;
|
|
2
4
|
|
|
3
5
|
.block-library-html__edit {
|
|
4
6
|
.block-library-html__preview-overlay {
|
|
@@ -8,16 +10,73 @@
|
|
|
8
10
|
top: 0;
|
|
9
11
|
left: 0;
|
|
10
12
|
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Modal styles
|
|
16
|
+
.block-library-html__modal {
|
|
17
|
+
// Make modal content scrollable
|
|
18
|
+
.components-modal__content {
|
|
19
|
+
display: flex;
|
|
20
|
+
flex-direction: column;
|
|
21
|
+
padding: 0;
|
|
22
|
+
min-height: 70vh;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.components-modal__children-container {
|
|
26
|
+
height: 100%;
|
|
27
|
+
padding: $grid-unit-20;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.block-library-html__modal-tabs {
|
|
32
|
+
height: 100%;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.block-library-html__modal-tab {
|
|
36
|
+
height: 100%;
|
|
37
|
+
display: flex;
|
|
38
|
+
flex-direction: column;
|
|
39
|
+
margin: 0;
|
|
40
|
+
box-sizing: border-box;
|
|
41
|
+
border: 1px solid $gray-200;
|
|
42
|
+
border-radius: 2px;
|
|
43
|
+
padding: $grid-unit-20;
|
|
44
|
+
font-family: $editor-html-font;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.block-library-html__modal-editor {
|
|
48
|
+
width: 100%;
|
|
49
|
+
height: 100%;
|
|
50
|
+
flex: 1;
|
|
51
|
+
// Reset textarea styles to inherit from pre
|
|
52
|
+
border: none;
|
|
53
|
+
background: transparent;
|
|
54
|
+
padding: 0;
|
|
55
|
+
font-family: inherit;
|
|
56
|
+
font-size: inherit;
|
|
57
|
+
line-height: inherit;
|
|
58
|
+
color: inherit;
|
|
59
|
+
resize: none;
|
|
60
|
+
// HTML input is always LTR regardless of language.
|
|
61
|
+
/*rtl:ignore*/
|
|
62
|
+
direction: ltr;
|
|
63
|
+
overflow-x: auto;
|
|
64
|
+
box-sizing: border-box;
|
|
11
65
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
display: block;
|
|
16
|
-
box-sizing: border-box;
|
|
17
|
-
max-height: 250px;
|
|
18
|
-
@include editor-input-reset();
|
|
19
|
-
// HTML input is always LTR regardless of language.
|
|
20
|
-
/*rtl:ignore*/
|
|
21
|
-
direction: ltr;
|
|
66
|
+
&:focus {
|
|
67
|
+
outline: none;
|
|
68
|
+
box-shadow: none;
|
|
22
69
|
}
|
|
23
70
|
}
|
|
71
|
+
|
|
72
|
+
.block-library-html__preview {
|
|
73
|
+
display: flex;
|
|
74
|
+
align-items: center;
|
|
75
|
+
justify-content: center;
|
|
76
|
+
padding: $grid-unit-60;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.block-library-html__modal-actions {
|
|
80
|
+
margin-top: $grid-unit-20;
|
|
81
|
+
padding: 0 $grid-unit-40 $grid-unit-40;
|
|
82
|
+
}
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { __ } from '@wordpress/i18n';
|
|
5
|
+
import { useState, useMemo } from '@wordpress/element';
|
|
6
|
+
import { useSelect } from '@wordpress/data';
|
|
7
|
+
import {
|
|
8
|
+
Modal,
|
|
9
|
+
Button,
|
|
10
|
+
Flex,
|
|
11
|
+
privateApis as componentsPrivateApis,
|
|
12
|
+
__experimentalHStack as HStack,
|
|
13
|
+
__experimentalVStack as VStack,
|
|
14
|
+
} from '@wordpress/components';
|
|
15
|
+
import { PlainText, store as blockEditorStore } from '@wordpress/block-editor';
|
|
16
|
+
import { fullscreen, square } from '@wordpress/icons';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Internal dependencies
|
|
20
|
+
*/
|
|
21
|
+
import { unlock } from '../lock-unlock';
|
|
22
|
+
import Preview from './preview';
|
|
23
|
+
import { parseContent, serializeContent } from './utils';
|
|
24
|
+
|
|
25
|
+
const { Tabs } = unlock( componentsPrivateApis );
|
|
26
|
+
|
|
27
|
+
export default function HTMLEditModal( {
|
|
28
|
+
isOpen,
|
|
29
|
+
onRequestClose,
|
|
30
|
+
content,
|
|
31
|
+
setAttributes,
|
|
32
|
+
} ) {
|
|
33
|
+
// Parse content into separate sections and use as initial state
|
|
34
|
+
const { html, css, js } = parseContent( content );
|
|
35
|
+
const [ editedHtml, setEditedHtml ] = useState( html );
|
|
36
|
+
const [ editedCss, setEditedCss ] = useState( css );
|
|
37
|
+
const [ editedJs, setEditedJs ] = useState( js );
|
|
38
|
+
const [ isDirty, setIsDirty ] = useState( false );
|
|
39
|
+
const [ showUnsavedWarning, setShowUnsavedWarning ] = useState( false );
|
|
40
|
+
const [ isFullscreen, setIsFullscreen ] = useState( false );
|
|
41
|
+
|
|
42
|
+
// Check if user has permission to save scripts and get editor styles
|
|
43
|
+
const { canUserUseUnfilteredHTML, editorStyles } = useSelect(
|
|
44
|
+
( select ) => {
|
|
45
|
+
const settings = select( blockEditorStore ).getSettings();
|
|
46
|
+
return {
|
|
47
|
+
canUserUseUnfilteredHTML:
|
|
48
|
+
settings.__experimentalCanUserUseUnfilteredHTML,
|
|
49
|
+
editorStyles: settings.styles,
|
|
50
|
+
};
|
|
51
|
+
},
|
|
52
|
+
[]
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
// Show JS tab if user has permission OR if block contains JavaScript
|
|
56
|
+
const shouldShowJsTab = canUserUseUnfilteredHTML || js.trim() !== '';
|
|
57
|
+
|
|
58
|
+
// Combine all editor styles to inject into modal
|
|
59
|
+
const styleContent = useMemo( () => {
|
|
60
|
+
if ( ! editorStyles ) {
|
|
61
|
+
return '';
|
|
62
|
+
}
|
|
63
|
+
return editorStyles
|
|
64
|
+
.filter( ( style ) => style.css )
|
|
65
|
+
.map( ( style ) => style.css )
|
|
66
|
+
.join( '\n' );
|
|
67
|
+
}, [ editorStyles ] );
|
|
68
|
+
|
|
69
|
+
if ( ! isOpen ) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const handleHtmlChange = ( value ) => {
|
|
74
|
+
setEditedHtml( value );
|
|
75
|
+
setIsDirty( true );
|
|
76
|
+
};
|
|
77
|
+
const handleCssChange = ( value ) => {
|
|
78
|
+
setEditedCss( value );
|
|
79
|
+
setIsDirty( true );
|
|
80
|
+
};
|
|
81
|
+
const handleJsChange = ( value ) => {
|
|
82
|
+
setEditedJs( value );
|
|
83
|
+
setIsDirty( true );
|
|
84
|
+
};
|
|
85
|
+
const handleUpdate = () => {
|
|
86
|
+
setAttributes( {
|
|
87
|
+
content: serializeContent( {
|
|
88
|
+
html: editedHtml,
|
|
89
|
+
css: editedCss,
|
|
90
|
+
js: editedJs,
|
|
91
|
+
} ),
|
|
92
|
+
} );
|
|
93
|
+
setIsDirty( false );
|
|
94
|
+
};
|
|
95
|
+
const handleCancel = () => {
|
|
96
|
+
setIsDirty( false );
|
|
97
|
+
onRequestClose();
|
|
98
|
+
};
|
|
99
|
+
const handleRequestClose = () => {
|
|
100
|
+
if ( isDirty ) {
|
|
101
|
+
setShowUnsavedWarning( true );
|
|
102
|
+
} else {
|
|
103
|
+
onRequestClose();
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
const handleDiscardChanges = () => {
|
|
107
|
+
setShowUnsavedWarning( false );
|
|
108
|
+
onRequestClose();
|
|
109
|
+
};
|
|
110
|
+
const handleContinueEditing = () => {
|
|
111
|
+
setShowUnsavedWarning( false );
|
|
112
|
+
};
|
|
113
|
+
const handleUpdateAndClose = () => {
|
|
114
|
+
handleUpdate();
|
|
115
|
+
onRequestClose();
|
|
116
|
+
};
|
|
117
|
+
const toggleFullscreen = () => {
|
|
118
|
+
setIsFullscreen( ( prevState ) => ! prevState );
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
return (
|
|
122
|
+
<>
|
|
123
|
+
<Modal
|
|
124
|
+
title={ __( 'Edit HTML' ) }
|
|
125
|
+
onRequestClose={ handleRequestClose }
|
|
126
|
+
className="block-library-html__modal"
|
|
127
|
+
size="large"
|
|
128
|
+
isDismissible={ false }
|
|
129
|
+
shouldCloseOnClickOutside={ ! isDirty }
|
|
130
|
+
shouldCloseOnEsc={ ! isDirty }
|
|
131
|
+
isFullScreen={ isFullscreen }
|
|
132
|
+
__experimentalHideHeader
|
|
133
|
+
>
|
|
134
|
+
{ styleContent && (
|
|
135
|
+
<style
|
|
136
|
+
dangerouslySetInnerHTML={ { __html: styleContent } }
|
|
137
|
+
/>
|
|
138
|
+
) }
|
|
139
|
+
<Tabs orientation="horizontal" defaultTabId="html">
|
|
140
|
+
<VStack spacing={ 4 } style={ { height: '100%' } }>
|
|
141
|
+
<HStack justify="space-between">
|
|
142
|
+
<div>
|
|
143
|
+
<Tabs.TabList>
|
|
144
|
+
<Tabs.Tab tabId="html">HTML</Tabs.Tab>
|
|
145
|
+
<Tabs.Tab tabId="css">CSS</Tabs.Tab>
|
|
146
|
+
{ shouldShowJsTab && (
|
|
147
|
+
<Tabs.Tab tabId="js">
|
|
148
|
+
{ __( 'JavaScript' ) }
|
|
149
|
+
</Tabs.Tab>
|
|
150
|
+
) }
|
|
151
|
+
</Tabs.TabList>
|
|
152
|
+
</div>
|
|
153
|
+
<div>
|
|
154
|
+
<Button
|
|
155
|
+
__next40pxDefaultSize
|
|
156
|
+
icon={ isFullscreen ? square : fullscreen }
|
|
157
|
+
label={ __( 'Enable/disable fullscreen' ) }
|
|
158
|
+
onClick={ toggleFullscreen }
|
|
159
|
+
variant="tertiary"
|
|
160
|
+
/>
|
|
161
|
+
</div>
|
|
162
|
+
</HStack>
|
|
163
|
+
<HStack
|
|
164
|
+
alignment="stretch"
|
|
165
|
+
justify="flex-start"
|
|
166
|
+
spacing={ 4 }
|
|
167
|
+
className="block-library-html__modal-tabs"
|
|
168
|
+
style={ { flexGrow: 1 } }
|
|
169
|
+
>
|
|
170
|
+
<div style={ { flexGrow: 1 } }>
|
|
171
|
+
<Tabs.TabPanel
|
|
172
|
+
tabId="html"
|
|
173
|
+
focusable={ false }
|
|
174
|
+
className="block-library-html__modal-tab"
|
|
175
|
+
>
|
|
176
|
+
<PlainText
|
|
177
|
+
value={ editedHtml }
|
|
178
|
+
onChange={ handleHtmlChange }
|
|
179
|
+
placeholder={ __( 'Write HTML…' ) }
|
|
180
|
+
aria-label={ __( 'HTML' ) }
|
|
181
|
+
className="block-library-html__modal-editor"
|
|
182
|
+
/>
|
|
183
|
+
</Tabs.TabPanel>
|
|
184
|
+
<Tabs.TabPanel
|
|
185
|
+
tabId="css"
|
|
186
|
+
focusable={ false }
|
|
187
|
+
className="block-library-html__modal-tab"
|
|
188
|
+
>
|
|
189
|
+
<PlainText
|
|
190
|
+
value={ editedCss }
|
|
191
|
+
onChange={ handleCssChange }
|
|
192
|
+
placeholder={ __( 'Write CSS…' ) }
|
|
193
|
+
aria-label={ __( 'CSS' ) }
|
|
194
|
+
className="block-library-html__modal-editor"
|
|
195
|
+
/>
|
|
196
|
+
</Tabs.TabPanel>
|
|
197
|
+
{ shouldShowJsTab && (
|
|
198
|
+
<Tabs.TabPanel
|
|
199
|
+
tabId="js"
|
|
200
|
+
focusable={ false }
|
|
201
|
+
className="block-library-html__modal-tab"
|
|
202
|
+
>
|
|
203
|
+
<PlainText
|
|
204
|
+
value={ editedJs }
|
|
205
|
+
onChange={ handleJsChange }
|
|
206
|
+
placeholder={ __(
|
|
207
|
+
'Write JavaScript…'
|
|
208
|
+
) }
|
|
209
|
+
aria-label={ __( 'JavaScript' ) }
|
|
210
|
+
className="block-library-html__modal-editor"
|
|
211
|
+
/>
|
|
212
|
+
</Tabs.TabPanel>
|
|
213
|
+
) }
|
|
214
|
+
</div>
|
|
215
|
+
<div
|
|
216
|
+
className="block-library-html__preview"
|
|
217
|
+
style={ { width: '50%' } }
|
|
218
|
+
>
|
|
219
|
+
<Preview
|
|
220
|
+
content={ serializeContent( {
|
|
221
|
+
html: editedHtml,
|
|
222
|
+
css: editedCss,
|
|
223
|
+
js: editedJs,
|
|
224
|
+
} ) }
|
|
225
|
+
/>
|
|
226
|
+
</div>
|
|
227
|
+
</HStack>
|
|
228
|
+
<HStack
|
|
229
|
+
alignment="center"
|
|
230
|
+
justify="flex-end"
|
|
231
|
+
spacing={ 4 }
|
|
232
|
+
>
|
|
233
|
+
<Button
|
|
234
|
+
__next40pxDefaultSize
|
|
235
|
+
variant="tertiary"
|
|
236
|
+
onClick={ handleCancel }
|
|
237
|
+
>
|
|
238
|
+
{ __( 'Cancel' ) }
|
|
239
|
+
</Button>
|
|
240
|
+
<Button
|
|
241
|
+
__next40pxDefaultSize
|
|
242
|
+
variant="primary"
|
|
243
|
+
onClick={ handleUpdateAndClose }
|
|
244
|
+
>
|
|
245
|
+
{ __( 'Update' ) }
|
|
246
|
+
</Button>
|
|
247
|
+
</HStack>
|
|
248
|
+
</VStack>
|
|
249
|
+
</Tabs>
|
|
250
|
+
</Modal>
|
|
251
|
+
|
|
252
|
+
{ showUnsavedWarning && (
|
|
253
|
+
<Modal
|
|
254
|
+
title={ __( 'Unsaved changes' ) }
|
|
255
|
+
onRequestClose={ handleContinueEditing }
|
|
256
|
+
size="medium"
|
|
257
|
+
>
|
|
258
|
+
<p>
|
|
259
|
+
{ __(
|
|
260
|
+
'You have unsaved changes. What would you like to do?'
|
|
261
|
+
) }
|
|
262
|
+
</p>
|
|
263
|
+
<Flex direction="row" justify="flex-end" gap={ 2 }>
|
|
264
|
+
<Button
|
|
265
|
+
__next40pxDefaultSize
|
|
266
|
+
variant="secondary"
|
|
267
|
+
onClick={ handleDiscardChanges }
|
|
268
|
+
>
|
|
269
|
+
{ __( 'Discard unsaved changes' ) }
|
|
270
|
+
</Button>
|
|
271
|
+
<Button
|
|
272
|
+
__next40pxDefaultSize
|
|
273
|
+
variant="secondary"
|
|
274
|
+
onClick={ handleContinueEditing }
|
|
275
|
+
>
|
|
276
|
+
{ __( 'Continue editing' ) }
|
|
277
|
+
</Button>
|
|
278
|
+
<Button
|
|
279
|
+
__next40pxDefaultSize
|
|
280
|
+
variant="primary"
|
|
281
|
+
onClick={ handleUpdateAndClose }
|
|
282
|
+
>
|
|
283
|
+
{ __( 'Update and close' ) }
|
|
284
|
+
</Button>
|
|
285
|
+
</Flex>
|
|
286
|
+
</Modal>
|
|
287
|
+
) }
|
|
288
|
+
</>
|
|
289
|
+
);
|
|
290
|
+
}
|