Full Site Editing - Version 3.28276

Version Description

Download this release

Release Info

Developer mattwiebe
Plugin Icon wp plugin Full Site Editing
Version 3.28276
Comparing to
See all releases

Code changes from version 3.27812 to 3.28276

Files changed (53) hide show
  1. dotcom-fse/blocks/navigation-menu/edit.js +0 -94
  2. dotcom-fse/blocks/navigation-menu/index.js +0 -27
  3. dotcom-fse/blocks/navigation-menu/style.scss +0 -3
  4. dotcom-fse/blocks/post-content/edit.js +0 -55
  5. dotcom-fse/blocks/post-content/index.js +0 -51
  6. dotcom-fse/blocks/post-content/save.js +0 -3
  7. dotcom-fse/blocks/post-content/style.scss +0 -69
  8. dotcom-fse/blocks/site-credit/edit.js +0 -67
  9. dotcom-fse/blocks/site-credit/footer-credit-choices.js +0 -21
  10. dotcom-fse/blocks/site-credit/index.js +0 -35
  11. dotcom-fse/blocks/site-credit/style.scss +0 -37
  12. dotcom-fse/blocks/site-description/edit.js +0 -136
  13. dotcom-fse/blocks/site-description/index.js +0 -55
  14. dotcom-fse/blocks/site-description/style.scss +0 -12
  15. dotcom-fse/blocks/site-title/edit.js +0 -117
  16. dotcom-fse/blocks/site-title/index.js +0 -44
  17. dotcom-fse/blocks/site-title/style.scss +0 -12
  18. dotcom-fse/blocks/template/edit.js +0 -200
  19. dotcom-fse/blocks/template/index.js +0 -56
  20. dotcom-fse/blocks/template/site-logo.js +0 -14
  21. dotcom-fse/blocks/template/style.scss +0 -124
  22. dotcom-fse/class-full-site-editing.php +0 -506
  23. dotcom-fse/dist/dotcom-fse.asset.php +0 -1
  24. dotcom-fse/dist/dotcom-fse.css +0 -1
  25. dotcom-fse/dist/dotcom-fse.js +0 -6
  26. dotcom-fse/dist/dotcom-fse.rtl.css +0 -1
  27. dotcom-fse/editor/block-inserter/index.js +0 -55
  28. dotcom-fse/editor/block-inserter/post-content-block-appender.js +0 -30
  29. dotcom-fse/editor/image-block-keywords/index.js +0 -20
  30. dotcom-fse/editor/index.js +0 -7
  31. dotcom-fse/editor/remove-editor-panels/index.js +0 -28
  32. dotcom-fse/editor/style.scss +0 -107
  33. dotcom-fse/editor/suppress-draft-action/index.js +0 -35
  34. dotcom-fse/editor/suppress-trash-action/index.js +0 -23
  35. dotcom-fse/editor/template-validity-override/index.js +0 -20
  36. dotcom-fse/helpers.php +4 -20
  37. dotcom-fse/index.js +0 -10
  38. dotcom-fse/lib/index.js +0 -1
  39. dotcom-fse/lib/site-options/index.js +0 -2
  40. dotcom-fse/lib/site-options/use-previous.js +0 -19
  41. dotcom-fse/lib/site-options/use-site-options.js +0 -125
  42. dotcom-fse/lib/site-options/with-site-options.js +0 -90
  43. dotcom-fse/plugins/close-button-override/index.js +0 -93
  44. dotcom-fse/plugins/close-button-override/style.scss +0 -91
  45. dotcom-fse/plugins/editor-template-classes/index.js +0 -62
  46. dotcom-fse/plugins/template-update-notice/index.js +0 -18
  47. dotcom-fse/sass/_mixins.scss +0 -17
  48. dotcom-fse/serialize-block-fallback.php +0 -70
  49. dotcom-fse/templates/class-rest-templates-controller.php +0 -69
  50. dotcom-fse/templates/class-template-image-inserter.php +0 -174
  51. dotcom-fse/templates/class-wp-template-inserter.php +10 -13
  52. full-site-editing-plugin.php +2 -2
  53. readme.txt +1 -1
dotcom-fse/blocks/navigation-menu/edit.js DELETED
@@ -1,94 +0,0 @@
1
- /* eslint-disable wpcalypso/jsx-classname-namespace */
2
-
3
- import {
4
- AlignmentToolbar,
5
- BlockControls,
6
- ContrastChecker,
7
- FontSizePicker,
8
- InspectorControls,
9
- PanelColorSettings,
10
- withColors,
11
- withFontSizes,
12
- } from '@wordpress/block-editor';
13
- import { PanelBody } from '@wordpress/components';
14
- import { compose } from '@wordpress/compose';
15
- import { withSelect } from '@wordpress/data';
16
- import { Fragment } from '@wordpress/element';
17
- import { __ } from '@wordpress/i18n';
18
- import ServerSideRender from '@wordpress/server-side-render';
19
-
20
- const NavigationMenuEdit = ( {
21
- attributes,
22
- backgroundColor,
23
- fontSize,
24
- setAttributes,
25
- setBackgroundColor,
26
- setFontSize,
27
- setTextColor,
28
- textColor,
29
- isPublished,
30
- } ) => {
31
- const { customFontSize, textAlign } = attributes;
32
-
33
- const actualFontSize = customFontSize || fontSize.size;
34
-
35
- return (
36
- <Fragment>
37
- <BlockControls>
38
- <AlignmentToolbar
39
- value={ textAlign }
40
- onChange={ ( nextAlign ) => {
41
- setAttributes( { textAlign: nextAlign } );
42
- } }
43
- />
44
- </BlockControls>
45
- <InspectorControls>
46
- <PanelBody
47
- className="blocks-font-size"
48
- title={ __( 'Text Settings', 'full-site-editing' ) }
49
- >
50
- <FontSizePicker onChange={ setFontSize } value={ actualFontSize } />
51
- </PanelBody>
52
- <PanelColorSettings
53
- title={ __( 'Color Settings', 'full-site-editing' ) }
54
- initialOpen={ false }
55
- colorSettings={ [
56
- {
57
- value: backgroundColor.color,
58
- onChange: setBackgroundColor,
59
- label: __( 'Background Color', 'full-site-editing' ),
60
- },
61
- {
62
- value: textColor.color,
63
- onChange: setTextColor,
64
- label: __( 'Text Color', 'full-site-editing' ),
65
- },
66
- ] }
67
- >
68
- <ContrastChecker
69
- { ...{
70
- textColor: textColor.color,
71
- backgroundColor: backgroundColor.color,
72
- } }
73
- fontSize={ actualFontSize }
74
- />
75
- </PanelColorSettings>
76
- </InspectorControls>
77
- <ServerSideRender
78
- isPublished={ isPublished }
79
- block="a8c/navigation-menu"
80
- attributes={ attributes }
81
- />
82
- </Fragment>
83
- );
84
- };
85
-
86
- export default compose( [
87
- withColors( 'backgroundColor', { textColor: 'color' } ),
88
- withFontSizes( 'fontSize' ),
89
- withSelect( ( select ) => {
90
- return {
91
- isPublished: select( 'core/editor' ).isCurrentPostPublished(),
92
- };
93
- } ),
94
- ] )( NavigationMenuEdit );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/blocks/navigation-menu/index.js DELETED
@@ -1,27 +0,0 @@
1
- import { registerBlockType } from '@wordpress/blocks';
2
- import { __ } from '@wordpress/i18n';
3
- import { getCategoryWithFallbacks } from '../../../block-helpers';
4
- import edit from './edit';
5
-
6
- import './style.scss';
7
-
8
- const icon = (
9
- <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
10
- <path fill="none" d="M0 0h24v24H0V0z" />
11
- <path d="M12 7.27l4.28 10.43-3.47-1.53-.81-.36-.81.36-3.47 1.53L12 7.27M12 2L4.5 20.29l.71.71L12 18l6.79 3 .71-.71L12 2z" />
12
- </svg>
13
- );
14
-
15
- registerBlockType( 'a8c/navigation-menu', {
16
- title: __( 'Navigation Menu', 'full-site-editing' ),
17
- description: __( 'Visual placeholder for site-wide navigation and menus.', 'full-site-editing' ),
18
- icon,
19
- category: getCategoryWithFallbacks( 'design', 'layout' ),
20
- supports: {
21
- align: [ 'wide', 'full', 'right', 'left' ],
22
- html: false,
23
- reusable: false,
24
- },
25
- edit,
26
- save: () => null,
27
- } );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/blocks/navigation-menu/style.scss DELETED
@@ -1,3 +0,0 @@
1
- .wp-block-a8c-navigation-menu.main-navigation {
2
- pointer-events: none;
3
- }
 
 
 
dotcom-fse/blocks/post-content/edit.js DELETED
@@ -1,55 +0,0 @@
1
- /* eslint-disable wpcalypso/jsx-classname-namespace */
2
-
3
- import { InnerBlocks } from '@wordpress/block-editor';
4
- import { compose, withState } from '@wordpress/compose';
5
- import { withSelect } from '@wordpress/data';
6
- import { PostTitle } from '@wordpress/editor';
7
- import { Component, Fragment } from '@wordpress/element';
8
- import classNames from 'classnames';
9
-
10
- class PostContentEdit extends Component {
11
- toggleEditing() {
12
- const { isEditing, setState } = this.props;
13
- setState( { isEditing: ! isEditing } );
14
- }
15
-
16
- onSelectPost( { id, type } ) {
17
- this.props.setState( {
18
- isEditing: false,
19
- selectedPostId: id,
20
- selectedPostType: type,
21
- } );
22
- }
23
-
24
- render() {
25
- const { attributes } = this.props;
26
- const { align } = attributes;
27
-
28
- return (
29
- <Fragment>
30
- <div
31
- className={ classNames( 'post-content-block', {
32
- [ `align${ align }` ]: align,
33
- } ) }
34
- >
35
- <PostTitle />
36
- <InnerBlocks templateLock={ false } />
37
- </div>
38
- </Fragment>
39
- );
40
- }
41
- }
42
-
43
- export default compose( [
44
- withState( {
45
- isEditing: false,
46
- selectedPostId: undefined,
47
- selectedPostType: undefined,
48
- } ),
49
- withSelect( ( select, { selectedPostId, selectedPostType } ) => {
50
- const { getEntityRecord } = select( 'core' );
51
- return {
52
- selectedPost: getEntityRecord( 'postType', selectedPostType, selectedPostId ),
53
- };
54
- } ),
55
- ] )( PostContentEdit );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/blocks/post-content/index.js DELETED
@@ -1,51 +0,0 @@
1
- import { registerBlockType } from '@wordpress/blocks';
2
- import { createHigherOrderComponent } from '@wordpress/compose';
3
- import { addFilter } from '@wordpress/hooks';
4
- import { __ } from '@wordpress/i18n';
5
- import { getCategoryWithFallbacks } from '../../../block-helpers';
6
- import edit from './edit';
7
- import save from './save';
8
-
9
- import './style.scss';
10
-
11
- registerBlockType( 'a8c/post-content', {
12
- title: __( 'Content', 'full-site-editing' ),
13
- description: __( 'The page content.', 'full-site-editing' ),
14
- icon: 'layout',
15
- category: getCategoryWithFallbacks( 'design', 'layout' ),
16
- supports: {
17
- align: [ 'full' ],
18
- anchor: false,
19
- customClassName: false,
20
- html: false,
21
- inserter: false,
22
- multiple: false,
23
- reusable: false,
24
- },
25
- attributes: {
26
- align: {
27
- type: 'string',
28
- default: 'full',
29
- },
30
- },
31
- edit,
32
- save,
33
- } );
34
-
35
- const addContentSlotClassname = createHigherOrderComponent( ( BlockListBlock ) => {
36
- return ( props ) => {
37
- if ( props.name !== 'a8c/post-content' ) {
38
- return <BlockListBlock { ...props } />;
39
- }
40
-
41
- return <BlockListBlock { ...props } className={ 'post-content__block' } />;
42
- };
43
- }, 'addContentSlotClassname' );
44
-
45
- // Must be 9 or this breaks on Simple Sites
46
- addFilter(
47
- 'editor.BlockListBlock',
48
- 'full-site-editing/blocks/post-content',
49
- addContentSlotClassname,
50
- 9
51
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/blocks/post-content/save.js DELETED
@@ -1,3 +0,0 @@
1
- import { InnerBlocks } from '@wordpress/block-editor';
2
-
3
- export default () => <InnerBlocks.Content />;
 
 
 
dotcom-fse/blocks/post-content/style.scss DELETED
@@ -1,69 +0,0 @@
1
- .post-content-block__selector {
2
- width: 300px;
3
- a {
4
- font-family: sans-serif;
5
- font-size: 13px;
6
- padding-left: 8px;
7
- }
8
- }
9
-
10
- .post-content-block__preview {
11
- pointer-events: none;
12
- &::after {
13
- content: '';
14
- clear: both;
15
- display: table;
16
- }
17
- }
18
-
19
- .post-content-block .editor-post-title {
20
- display: none;
21
- }
22
-
23
- .show-post-title-before-content {
24
- .editor-post-title {
25
- display: none;
26
- }
27
-
28
- .post-content-block .editor-post-title {
29
- display: block;
30
- }
31
- }
32
-
33
- /**
34
- * Hide the content slot block UI
35
- *
36
- * @TODO: Remove this once Gutenberg gets support for hiding block UI.
37
- *
38
- * @see https://github.com/WordPress/gutenberg/issues/7469
39
- * @see https://github.com/WordPress/gutenberg/pull/18173
40
- */
41
- .block-editor-block-list__layout {
42
- .post-content__block {
43
- &.is-selected {
44
- .block-editor-block-contextual-toolbar {
45
- display: none;
46
- }
47
- }
48
-
49
- &.block-editor-block-list__block {
50
- // Need to get super specific to override the core css selectors:
51
- &,
52
- &.has-child-selected,
53
- &.is-navigate-mode,
54
- &.is-hovered {
55
- > .block-editor-block-list__block-edit {
56
- &::before {
57
- transition: none;
58
- border: none;
59
- outline: none;
60
- box-shadow: none;
61
- }
62
- > .block-editor-block-list__breadcrumb {
63
- display: none;
64
- }
65
- }
66
- }
67
- }
68
- }
69
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/blocks/site-credit/edit.js DELETED
@@ -1,67 +0,0 @@
1
- /* eslint-disable wpcalypso/jsx-classname-namespace */
2
- /* global fullSiteEditing */
3
-
4
- import { AlignmentToolbar, BlockControls } from '@wordpress/block-editor';
5
- import { SelectControl } from '@wordpress/components';
6
- import { compose } from '@wordpress/compose';
7
- import { Fragment } from '@wordpress/element';
8
- import { __ } from '@wordpress/i18n';
9
- import classNames from 'classnames';
10
- import { withSiteOptions } from '../../lib';
11
- import { RenderedCreditChoice } from './footer-credit-choices';
12
-
13
- const { footerCreditOptions, defaultCreditOption } = fullSiteEditing;
14
-
15
- function SiteCreditEdit( {
16
- attributes: { textAlign = 'center' },
17
- isSelected,
18
- setAttributes,
19
- footerCreditOption: { value: wpCredit, updateValue: updateCredit },
20
- siteTitleOption: { value: siteTitle },
21
- } ) {
22
- const footerCreditChoice = wpCredit || defaultCreditOption;
23
- return (
24
- <Fragment>
25
- <BlockControls>
26
- <AlignmentToolbar
27
- value={ textAlign }
28
- onChange={ ( nextAlign ) => {
29
- setAttributes( { textAlign: nextAlign } );
30
- } }
31
- />
32
- </BlockControls>
33
- <div
34
- className={ classNames( 'site-info', 'site-credit__block', {
35
- [ `has-text-align-${ textAlign }` ]: textAlign,
36
- } ) }
37
- >
38
- <span className="site-name">{ siteTitle }</span>
39
- <span className="comma">,</span>
40
- <span className="site-credit__selection">
41
- { isSelected ? (
42
- <SelectControl
43
- onChange={ updateCredit }
44
- value={ footerCreditChoice }
45
- options={ footerCreditOptions }
46
- />
47
- ) : (
48
- <RenderedCreditChoice choice={ footerCreditChoice } />
49
- ) }
50
- </span>
51
- </div>
52
- </Fragment>
53
- );
54
- }
55
-
56
- export default compose( [
57
- withSiteOptions( {
58
- siteTitleOption: {
59
- optionName: 'title',
60
- defaultValue: __( 'Site title loading…', 'full-site-editing' ),
61
- },
62
- footerCreditOption: {
63
- optionName: 'footer_credit',
64
- defaultValue: __( 'Footer credit loading…', 'full-site-editing' ),
65
- },
66
- } ),
67
- ] )( SiteCreditEdit );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/blocks/site-credit/footer-credit-choices.js DELETED
@@ -1,21 +0,0 @@
1
- /* global fullSiteEditing */
2
-
3
- // eslint-disable-next-line no-restricted-imports
4
- import { Icon } from '@wordpress/components';
5
-
6
- const { footerCreditOptions } = fullSiteEditing;
7
-
8
- export const RenderedCreditChoice = ( { choice } ) => {
9
- const selection = footerCreditOptions.find( ( { value } ) => value === choice );
10
- if ( ! selection ) {
11
- return null;
12
- }
13
-
14
- const { renderType, renderProps, label } = selection;
15
- // Allows label to be overriden by renderProps if needed.
16
- const props = { label, ...renderProps };
17
- if ( 'icon' === renderType ) {
18
- return <Icon { ...props } />;
19
- }
20
- return <span> { props.label } </span>;
21
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/blocks/site-credit/index.js DELETED
@@ -1,35 +0,0 @@
1
- import { registerBlockType } from '@wordpress/blocks';
2
- import { __ } from '@wordpress/i18n';
3
- import { getCategoryWithFallbacks } from '../../../block-helpers';
4
- import edit from './edit';
5
-
6
- import './style.scss';
7
-
8
- registerBlockType( 'a8c/site-credit', {
9
- title: __( 'WordPress.com Credit', 'full-site-editing' ),
10
- description: __(
11
- "This block tells the world that you're using WordPress.com.",
12
- 'full-site-editing'
13
- ),
14
- icon: 'wordpress-alt',
15
- category: getCategoryWithFallbacks( 'design', 'layout' ),
16
- supports: {
17
- align: [ 'wide', 'full' ],
18
- html: false,
19
- multiple: false,
20
- reusable: false,
21
- removal: false,
22
- },
23
- attributes: {
24
- align: {
25
- type: 'string',
26
- default: 'wide',
27
- },
28
- textAlign: {
29
- type: 'string',
30
- default: 'center',
31
- },
32
- },
33
- edit,
34
- save: () => null,
35
- } );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/blocks/site-credit/style.scss DELETED
@@ -1,37 +0,0 @@
1
- .site-credit__block {
2
- display: flex;
3
- flex-direction: row;
4
- align-items: center;
5
- // @TODO: Pull these styles from the theme.
6
- font-size: 14px;
7
- color: gray;
8
-
9
- // Justify all elements based on text alignment.
10
- &.has-text-align-center {
11
- justify-content: center;
12
- }
13
- &.has-text-align-left {
14
- justify-content: flex-start;
15
- }
16
- &.has-text-align-right {
17
- justify-content: flex-end;
18
- }
19
-
20
- .site-name {
21
- font-weight: bold;
22
- }
23
-
24
- .site-credit__selection {
25
- margin-left: 5px;
26
-
27
- // Also align items vertically center in the selection area.
28
- display: flex;
29
- flex-direction: row;
30
- align-items: center;
31
-
32
- .components-base-control .components-base-control__field {
33
- // Reset extra margin added by @wordpress/components in the select field.
34
- margin-bottom: 0;
35
- }
36
- }
37
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/blocks/site-description/edit.js DELETED
@@ -1,136 +0,0 @@
1
- /* eslint-disable wpcalypso/jsx-classname-namespace */
2
-
3
- import {
4
- AlignmentToolbar,
5
- BlockControls,
6
- ContrastChecker,
7
- FontSizePicker,
8
- InspectorControls,
9
- PanelColorSettings,
10
- RichText,
11
- withColors,
12
- withFontSizes,
13
- } from '@wordpress/block-editor';
14
- import { PanelBody } from '@wordpress/components';
15
- import { compose } from '@wordpress/compose';
16
- import { withSelect, withDispatch } from '@wordpress/data';
17
- import { Fragment } from '@wordpress/element';
18
- import { __ } from '@wordpress/i18n';
19
- import classNames from 'classnames';
20
- import { withSiteOptions } from '../../lib';
21
-
22
- const noop = () => {};
23
-
24
- function SiteDescriptionEdit( {
25
- attributes,
26
- backgroundColor,
27
- className,
28
- fontSize,
29
- insertDefaultBlock,
30
- setAttributes,
31
- setBackgroundColor,
32
- setFontSize,
33
- setTextColor,
34
- siteDescription,
35
- textColor,
36
- } ) {
37
- const { customFontSize, textAlign } = attributes;
38
-
39
- const actualFontSize = customFontSize || fontSize.size;
40
-
41
- const { value, updateValue } = siteDescription;
42
-
43
- return (
44
- <Fragment>
45
- <BlockControls>
46
- <AlignmentToolbar
47
- value={ textAlign }
48
- onChange={ ( nextAlign ) => {
49
- setAttributes( { textAlign: nextAlign } );
50
- } }
51
- />
52
- </BlockControls>
53
- <InspectorControls>
54
- <PanelBody
55
- className="blocks-font-size"
56
- title={ __( 'Text Settings', 'full-site-editing' ) }
57
- >
58
- <FontSizePicker onChange={ setFontSize } value={ actualFontSize } />
59
- </PanelBody>
60
- <PanelColorSettings
61
- title={ __( 'Color Settings', 'full-site-editing' ) }
62
- initialOpen={ false }
63
- colorSettings={ [
64
- {
65
- value: backgroundColor.color,
66
- onChange: setBackgroundColor,
67
- label: __( 'Background Color', 'full-site-editing' ),
68
- },
69
- {
70
- value: textColor.color,
71
- onChange: setTextColor,
72
- label: __( 'Text Color', 'full-site-editing' ),
73
- },
74
- ] }
75
- >
76
- <ContrastChecker
77
- { ...{
78
- textColor: textColor.color,
79
- backgroundColor: backgroundColor.color,
80
- } }
81
- fontSize={ actualFontSize }
82
- />
83
- </PanelColorSettings>
84
- </InspectorControls>
85
- <RichText
86
- allowedFormats={ [] }
87
- aria-label={ __( 'Site Description', 'full-site-editing' ) }
88
- className={ classNames( 'site-description', className, {
89
- 'has-text-color': textColor.color,
90
- 'has-background': backgroundColor.color,
91
- [ `has-text-align-${ textAlign }` ]: textAlign,
92
- [ backgroundColor.class ]: backgroundColor.class,
93
- [ textColor.class ]: textColor.class,
94
- [ fontSize.class ]: ! customFontSize && fontSize.class,
95
- } ) }
96
- identifier="content"
97
- onChange={ updateValue }
98
- onReplace={ insertDefaultBlock }
99
- onSplit={ noop }
100
- placeholder={ __( 'Add a Site Description', 'full-site-editing' ) }
101
- style={ {
102
- backgroundColor: backgroundColor.color,
103
- color: textColor.color,
104
- fontSize: actualFontSize ? actualFontSize + 'px' : undefined,
105
- } }
106
- tagName="p"
107
- value={ value }
108
- />
109
- </Fragment>
110
- );
111
- }
112
-
113
- export default compose( [
114
- withColors( 'backgroundColor', { textColor: 'color' } ),
115
- withFontSizes( 'fontSize' ),
116
- withSelect( ( select, { clientId } ) => {
117
- const { getBlockIndex, getBlockRootClientId, getTemplateLock } = select( 'core/block-editor' );
118
- const rootClientId = getBlockRootClientId( clientId );
119
-
120
- return {
121
- blockIndex: getBlockIndex( clientId, rootClientId ),
122
- isLocked: !! getTemplateLock( rootClientId ),
123
- rootClientId,
124
- };
125
- } ),
126
- withDispatch( ( dispatch, { blockIndex, rootClientId } ) => ( {
127
- insertDefaultBlock: () =>
128
- dispatch( 'core/block-editor' ).insertDefaultBlock( {}, rootClientId, blockIndex + 1 ),
129
- } ) ),
130
- withSiteOptions( {
131
- siteDescription: {
132
- optionName: 'description',
133
- defaultValue: __( 'Site description loading…', 'full-site-editing' ),
134
- },
135
- } ),
136
- ] )( SiteDescriptionEdit );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/blocks/site-description/index.js DELETED
@@ -1,55 +0,0 @@
1
- import { registerBlockType } from '@wordpress/blocks';
2
- import { __ } from '@wordpress/i18n';
3
- import { getCategoryWithFallbacks } from '../../../block-helpers';
4
- import edit from './edit';
5
-
6
- import './style.scss';
7
-
8
- registerBlockType( 'a8c/site-description', {
9
- title: __( 'Site Description', 'full-site-editing' ),
10
- description: __( 'Site description, also known as the tagline.', 'full-site-editing' ),
11
- icon: (
12
- <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24">
13
- <path fill="none" d="M0 0h24v24H0z" />
14
- <path d="M4 9h16v2H4V9zm0 4h10v2H4v-2z" />
15
- </svg>
16
- ),
17
- category: getCategoryWithFallbacks( 'design', 'layout' ),
18
- supports: {
19
- align: [ 'wide', 'full' ],
20
- html: false,
21
- multiple: false,
22
- reusable: false,
23
- },
24
- attributes: {
25
- align: {
26
- type: 'string',
27
- default: 'wide',
28
- },
29
- textAlign: {
30
- type: 'string',
31
- default: 'center',
32
- },
33
- textColor: {
34
- type: 'string',
35
- },
36
- customTextColor: {
37
- type: 'string',
38
- },
39
- backgroundColor: {
40
- type: 'string',
41
- },
42
- customBackgroundColor: {
43
- type: 'string',
44
- },
45
- fontSize: {
46
- type: 'string',
47
- default: 'small',
48
- },
49
- customFontSize: {
50
- type: 'number',
51
- },
52
- },
53
- edit,
54
- save: () => null,
55
- } );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/blocks/site-description/style.scss DELETED
@@ -1,12 +0,0 @@
1
- @import '../../sass/mixins';
2
-
3
- .block-editor {
4
- .wp-block-a8c-site-description:focus {
5
- box-shadow: none;
6
- background-color: transparent;
7
- }
8
-
9
- .wp-block.is-selected .wp-block-a8c-site-description {
10
- @include hide-input-placeholder;
11
- }
12
- }
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/blocks/site-title/edit.js DELETED
@@ -1,117 +0,0 @@
1
- /* eslint-disable wpcalypso/jsx-classname-namespace */
2
-
3
- import {
4
- AlignmentToolbar,
5
- BlockControls,
6
- FontSizePicker,
7
- InspectorControls,
8
- PanelColorSettings,
9
- RichText,
10
- withColors,
11
- withFontSizes,
12
- } from '@wordpress/block-editor';
13
- import { PanelBody } from '@wordpress/components';
14
- import { compose } from '@wordpress/compose';
15
- import { withSelect, withDispatch } from '@wordpress/data';
16
- import { Fragment } from '@wordpress/element';
17
- import { __ } from '@wordpress/i18n';
18
- import classNames from 'classnames';
19
- import { withSiteOptions } from '../../lib';
20
-
21
- const noop = () => {};
22
-
23
- function SiteTitleEdit( {
24
- attributes,
25
- className,
26
- fontSize,
27
- insertDefaultBlock,
28
- setAttributes,
29
- setFontSize,
30
- setTextColor,
31
- siteTitle,
32
- textColor,
33
- } ) {
34
- const { customFontSize, textAlign } = attributes;
35
-
36
- const actualFontSize = customFontSize || fontSize.size;
37
-
38
- const { value, updateValue } = siteTitle;
39
-
40
- return (
41
- <Fragment>
42
- <BlockControls>
43
- <AlignmentToolbar
44
- value={ textAlign }
45
- onChange={ ( nextAlign ) => {
46
- setAttributes( { textAlign: nextAlign } );
47
- } }
48
- />
49
- </BlockControls>
50
- <InspectorControls>
51
- <PanelBody
52
- className="blocks-font-size"
53
- title={ __( 'Text Settings', 'full-site-editing' ) }
54
- >
55
- <FontSizePicker onChange={ setFontSize } value={ actualFontSize } />
56
- </PanelBody>
57
- <PanelColorSettings
58
- title={ __( 'Color Settings', 'full-site-editing' ) }
59
- initialOpen={ false }
60
- colorSettings={ [
61
- {
62
- value: textColor.color,
63
- onChange: setTextColor,
64
- label: __( 'Text Color', 'full-site-editing' ),
65
- },
66
- ] }
67
- />
68
- </InspectorControls>
69
- <RichText
70
- allowedFormats={ [] }
71
- aria-label={ __( 'Site Title', 'full-site-editing' ) }
72
- className={ classNames( 'site-title', className, {
73
- 'has-text-color': textColor.color,
74
- [ `has-text-align-${ textAlign }` ]: textAlign,
75
- [ textColor.class ]: textColor.class,
76
- [ fontSize.class ]: ! customFontSize && fontSize.class,
77
- } ) }
78
- identifier="content"
79
- onChange={ updateValue }
80
- onReplace={ insertDefaultBlock }
81
- onSplit={ noop }
82
- placeholder={ __( 'Add a Site Title', 'full-site-editing' ) }
83
- style={ {
84
- color: textColor.color,
85
- fontSize: actualFontSize ? actualFontSize + 'px' : undefined,
86
- } }
87
- tagName="h1"
88
- value={ value }
89
- />
90
- </Fragment>
91
- );
92
- }
93
-
94
- export default compose( [
95
- withColors( { textColor: 'color' } ),
96
- withFontSizes( 'fontSize' ),
97
- withSelect( ( select, { clientId } ) => {
98
- const { getBlockIndex, getBlockRootClientId, getTemplateLock } = select( 'core/block-editor' );
99
- const rootClientId = getBlockRootClientId( clientId );
100
-
101
- return {
102
- blockIndex: getBlockIndex( clientId, rootClientId ),
103
- isLocked: !! getTemplateLock( rootClientId ),
104
- rootClientId,
105
- };
106
- } ),
107
- withDispatch( ( dispatch, { blockIndex, rootClientId } ) => ( {
108
- insertDefaultBlock: () =>
109
- dispatch( 'core/block-editor' ).insertDefaultBlock( {}, rootClientId, blockIndex + 1 ),
110
- } ) ),
111
- withSiteOptions( {
112
- siteTitle: {
113
- optionName: 'title',
114
- defaultValue: __( 'Site title loading…', 'full-site-editing' ),
115
- },
116
- } ),
117
- ] )( SiteTitleEdit );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/blocks/site-title/index.js DELETED
@@ -1,44 +0,0 @@
1
- import { registerBlockType } from '@wordpress/blocks';
2
- import { __ } from '@wordpress/i18n';
3
- import { getCategoryWithFallbacks } from '../../../block-helpers';
4
- import edit from './edit';
5
-
6
- import './style.scss';
7
-
8
- registerBlockType( 'a8c/site-title', {
9
- title: __( 'Site Title', 'full-site-editing' ),
10
- description: __( 'Your site title.', 'full-site-editing' ),
11
- icon: 'layout',
12
- category: getCategoryWithFallbacks( 'design', 'layout' ),
13
- supports: {
14
- align: [ 'wide', 'full' ],
15
- html: false,
16
- multiple: false,
17
- reusable: false,
18
- },
19
- attributes: {
20
- align: {
21
- type: 'string',
22
- default: 'wide',
23
- },
24
- textAlign: {
25
- type: 'string',
26
- default: 'center',
27
- },
28
- textColor: {
29
- type: 'string',
30
- },
31
- customTextColor: {
32
- type: 'string',
33
- },
34
- fontSize: {
35
- type: 'string',
36
- default: 'normal',
37
- },
38
- customFontSize: {
39
- type: 'number',
40
- },
41
- },
42
- edit,
43
- save: () => null,
44
- } );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/blocks/site-title/style.scss DELETED
@@ -1,12 +0,0 @@
1
- @import '../../sass/mixins';
2
-
3
- .block-editor {
4
- .wp-block-a8c-site-title:focus {
5
- box-shadow: none;
6
- background-color: transparent;
7
- }
8
-
9
- .wp-block.is-selected .wp-block-a8c-site-title {
10
- @include hide-input-placeholder;
11
- }
12
- }
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/blocks/template/edit.js DELETED
@@ -1,200 +0,0 @@
1
- /* eslint-disable wpcalypso/jsx-classname-namespace */
2
- /* global fullSiteEditing */
3
-
4
- import { BlockEdit } from '@wordpress/block-editor';
5
- import { parse, createBlock } from '@wordpress/blocks';
6
- import { Button, Placeholder, Spinner, Disabled } from '@wordpress/components';
7
- import { compose, withState } from '@wordpress/compose';
8
- import { withDispatch, withSelect } from '@wordpress/data';
9
- import { Fragment, useEffect, useState, createRef } from '@wordpress/element';
10
- import { __, sprintf } from '@wordpress/i18n';
11
- import { addQueryArgs } from '@wordpress/url';
12
- import classNames from 'classnames';
13
- import { get } from 'lodash';
14
-
15
- import './style.scss';
16
-
17
- const noop = () => {};
18
-
19
- const TemplateEdit = compose(
20
- withState( { templateClientId: null } ),
21
- withSelect( ( select, { attributes, templateClientId } ) => {
22
- const { getEntityRecord } = select( 'core' );
23
- const { getCurrentPostId, isEditedPostDirty } = select( 'core/editor' );
24
- const { getBlock, getSelectedBlock } = select( 'core/block-editor' );
25
- const { isEditorSidebarOpened } = select( 'core/edit-post' );
26
- const { templateId } = attributes;
27
- const currentPostId = getCurrentPostId();
28
- const template = templateId && getEntityRecord( 'postType', 'wp_template_part', templateId );
29
- const editTemplateUrl = addQueryArgs( fullSiteEditing.editTemplateBaseUrl, {
30
- post: templateId,
31
- fse_parent_post: currentPostId,
32
- } );
33
- const selectedBlock = getSelectedBlock();
34
-
35
- return {
36
- currentPostId,
37
- editTemplateUrl,
38
- template,
39
- templateBlock: getBlock( templateClientId ),
40
- templateTitle: get( template, [ 'title', 'rendered' ], '' ),
41
- isDirty: isEditedPostDirty(),
42
- isEditorSidebarOpened: !! isEditorSidebarOpened(),
43
- isAnyTemplateBlockSelected: selectedBlock && 'a8c/template' === selectedBlock.name,
44
- };
45
- } ),
46
- withDispatch( ( dispatch, ownProps ) => {
47
- const { receiveBlocks } = dispatch( 'core/block-editor' );
48
- const { openGeneralSidebar } = dispatch( 'core/edit-post' );
49
- const { template, templateClientId, setState } = ownProps;
50
- return {
51
- savePost: dispatch( 'core/editor' ).savePost,
52
- receiveTemplateBlocks: () => {
53
- if ( ! template || templateClientId ) {
54
- return;
55
- }
56
-
57
- const templateBlocks = parse( get( template, [ 'content', 'raw' ], '' ) );
58
- const templateBlock = createBlock( 'core/group', {}, templateBlocks );
59
-
60
- receiveBlocks( [ templateBlock ] );
61
- setState( { templateClientId: templateBlock.clientId } );
62
- },
63
- openGeneralSidebar,
64
- };
65
- } )
66
- )(
67
- ( {
68
- attributes,
69
- editTemplateUrl,
70
- receiveTemplateBlocks,
71
- template,
72
- templateBlock,
73
- templateTitle,
74
- isDirty,
75
- savePost,
76
- isEditorSidebarOpened,
77
- openGeneralSidebar,
78
- isAnyTemplateBlockSelected,
79
- } ) => {
80
- if ( ! template ) {
81
- return (
82
- <Placeholder className="template-block__placeholder">
83
- <Spinner />
84
- </Placeholder>
85
- );
86
- }
87
- const navButton = createRef();
88
- const [ navigateToTemplate, setNavigateToTemplate ] = useState( false );
89
- useEffect( () => {
90
- if ( navigateToTemplate && ! isDirty ) {
91
- // Since we cancelled the click event to save the post
92
- // we trigger it again here. We do this instead of setting
93
- // window.location.href because in WordPress.com, the navigation
94
- // scheme is different and not available to us here.
95
- navButton.current.click();
96
- }
97
- receiveTemplateBlocks();
98
- } );
99
-
100
- useEffect( () => {
101
- // Since the Block Sidebar (`edit-post/block`) is not available for the Template block,
102
- // if the sidebar is open, we force toggle to the Document Sidebar, and hide the Block button.
103
- const blockSidebarButton = document.querySelector(
104
- '.edit-post-sidebar__panel-tabs ul li:last-child'
105
- );
106
- if ( isEditorSidebarOpened && blockSidebarButton ) {
107
- if ( isAnyTemplateBlockSelected ) {
108
- openGeneralSidebar( 'edit-post/document' );
109
- blockSidebarButton.classList.add( 'hidden' );
110
- return;
111
- }
112
- blockSidebarButton.classList.remove( 'hidden' );
113
- }
114
- }, [ isAnyTemplateBlockSelected, isEditorSidebarOpened, openGeneralSidebar ] );
115
-
116
- const { align, className } = attributes;
117
-
118
- const save = ( event ) => {
119
- event.stopPropagation();
120
- setNavigateToTemplate( true );
121
- if ( ! isDirty ) {
122
- return;
123
- }
124
- /**
125
- * This must be after setNavigateToTemplate so that local navigation
126
- * (without wpcom overrides) still works correctly.
127
- */
128
- event.preventDefault();
129
- savePost();
130
- };
131
-
132
- /**
133
- * IMPORTANT: Be careful about changes to the overlay button. There is code in
134
- * iframe-bridge-server.js (setupEditTemplateLinks) which looks for two
135
- * elements matching '.template__block-container .template-block__overlay a'.
136
- * This code updates the href of the button to match the calypso URL (which is
137
- * sent through the iFrame port) since editTemplateUrl here will be the wpadmin URL.
138
- *
139
- * If you make changes to the button, navigation to the template editor MAY BREAK.
140
- *
141
- * For example, if the button does not exist in the DOM as the editor is loaded,
142
- * the links may not be updated in time, or an interval will continuously try to
143
- * find them (which is bad for performance).
144
- *
145
- * This has already broken several times, so be careful!
146
- */
147
-
148
- return (
149
- <div
150
- className={ classNames( 'template-block', {
151
- [ `align${ align }` ]: align,
152
- 'is-navigating-to-template': navigateToTemplate,
153
- } ) }
154
- >
155
- { templateBlock && (
156
- <Fragment>
157
- <Disabled>
158
- <div className={ className }>
159
- <BlockEdit
160
- attributes={ templateBlock.attributes }
161
- block={ templateBlock }
162
- clientId={ templateBlock.clientId }
163
- isSelected={ false }
164
- name={ templateBlock.name }
165
- setAttributes={ noop }
166
- />
167
- </div>
168
- </Disabled>
169
- <Placeholder className="template-block__overlay" onClick={ save }>
170
- { navigateToTemplate && (
171
- <div className="template-block__loading">
172
- <Spinner />{ ' ' }
173
- {
174
- /* translators: %s is a template title. */
175
- sprintf( __( 'Loading editor for: %s', 'full-site-editing' ), templateTitle )
176
- }
177
- </div>
178
- ) }
179
- <Button
180
- className={ navigateToTemplate ? 'hidden' : null }
181
- href={ editTemplateUrl }
182
- onClick={ save }
183
- isDefault
184
- isLarge
185
- ref={ navButton }
186
- >
187
- {
188
- /* translators: %s is a template title. */
189
- sprintf( __( 'Edit %s', 'full-site-editing' ), templateTitle )
190
- }
191
- </Button>
192
- </Placeholder>
193
- </Fragment>
194
- ) }
195
- </div>
196
- );
197
- }
198
- );
199
-
200
- export default TemplateEdit;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/blocks/template/index.js DELETED
@@ -1,56 +0,0 @@
1
- /* global fullSiteEditing */
2
-
3
- import { registerBlockType } from '@wordpress/blocks';
4
- import { createHigherOrderComponent } from '@wordpress/compose';
5
- import { addFilter } from '@wordpress/hooks';
6
- import { __ } from '@wordpress/i18n';
7
- import { getCategoryWithFallbacks } from '../../../block-helpers';
8
- import edit from './edit';
9
-
10
- import './style.scss';
11
- import './site-logo';
12
-
13
- if ( 'wp_template_part' !== fullSiteEditing.editorPostType ) {
14
- registerBlockType( 'a8c/template', {
15
- title: __( 'Template Part', 'full-site-editing' ),
16
- __experimentalDisplayName: 'label',
17
- description: __( 'Display a Template Part.', 'full-site-editing' ),
18
- icon: 'layout',
19
- category: getCategoryWithFallbacks( 'design', 'layout' ),
20
- attributes: {
21
- templateId: { type: 'number' },
22
- className: { type: 'string' },
23
- label: { type: 'string' },
24
- },
25
- supports: {
26
- anchor: false,
27
- customClassName: false,
28
- html: false,
29
- inserter: false,
30
- reusable: false,
31
- },
32
- edit,
33
- save: () => null,
34
- getEditWrapperProps() {
35
- return { 'data-align': 'full' };
36
- },
37
- } );
38
- }
39
-
40
- const addFSETemplateClassname = createHigherOrderComponent( ( BlockListBlock ) => {
41
- return ( props ) => {
42
- if ( props.name !== 'a8c/template' ) {
43
- return <BlockListBlock { ...props } />;
44
- }
45
-
46
- return <BlockListBlock { ...props } className="template__block-container" />;
47
- };
48
- }, 'addFSETemplateClassname' );
49
-
50
- // Must be 9 or this breaks on Simple Sites
51
- addFilter(
52
- 'editor.BlockListBlock',
53
- 'full-site-editing/blocks/template',
54
- addFSETemplateClassname,
55
- 9
56
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/blocks/template/site-logo.js DELETED
@@ -1,14 +0,0 @@
1
- import { createHigherOrderComponent } from '@wordpress/compose';
2
- import { addFilter } from '@wordpress/hooks';
3
-
4
- const addFSESiteLogoClassname = createHigherOrderComponent( ( BlockListBlock ) => {
5
- return ( props ) => {
6
- if ( props.attributes.className !== 'fse-site-logo' ) {
7
- return <BlockListBlock { ...props } />;
8
- }
9
-
10
- return <BlockListBlock { ...props } className="template__site-logo" />;
11
- };
12
- }, 'addFSESiteLogoClassname' );
13
-
14
- addFilter( 'editor.BlockListBlock', 'full-site-editing/blocks/template', addFSESiteLogoClassname );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/blocks/template/style.scss DELETED
@@ -1,124 +0,0 @@
1
- .template-block {
2
- min-height: 200px;
3
- // Prevent blur bleeding
4
- overflow: hidden;
5
- position: relative;
6
- margin-top: 20px;
7
- }
8
-
9
- // Override some very specific theme styles.
10
- .post-type-page .editor-styles-wrapper .template-block .fse-template-part {
11
- padding: 0;
12
- }
13
-
14
- .components-popover.block-editor-block-list__block-popover .components-popover__content .block-editor-block-contextual-toolbar[data-type='a8c/template'] {
15
- display: none;
16
- }
17
-
18
- .template__block-container {
19
- &::before {
20
- display: none;
21
- }
22
-
23
- &:hover {
24
- cursor: pointer;
25
- }
26
-
27
- .block-editor-block-list__block-edit [data-block] {
28
- margin: 0;
29
- }
30
-
31
- &:hover,
32
- &.is-selected,
33
- .is-navigating-to-template {
34
- .components-disabled {
35
- filter: blur( 2px );
36
- transition: filter 0.2s linear;
37
- }
38
- .template-block__overlay {
39
- opacity: 1;
40
- transition: opacity 0.2s linear;
41
- .components-button {
42
- opacity: 1;
43
- transition: opacity 0.2s linear;
44
- }
45
- }
46
- }
47
-
48
- .components-disabled {
49
- filter: blur( 0 );
50
- transition: filter 0.2s linear 0s;
51
- }
52
-
53
- // Hide the block toolbar and border
54
- .block-editor-block-contextual-toolbar,
55
- .block-editor-block-list__block-mobile-toolbar,
56
- .block-editor-block-list__insertion-point,
57
- .block-editor-block-list__breadcrumb,
58
- .block-editor-block-list__block-edit::before {
59
- display: none;
60
- }
61
-
62
- .template-block__overlay {
63
- background: rgba( #ffffff, 0.8 );
64
- border: 0 solid rgba( #7b86a2, 0.3 ); // Gutenberg $dark-opacity-light-600
65
- bottom: 0;
66
- left: 0;
67
- margin: 0;
68
- opacity: 0;
69
- padding: 0;
70
- position: absolute;
71
- right: 0;
72
- transition: opacity 0.2s linear 0s;
73
- top: 0;
74
- z-index: 2;
75
-
76
- .is-selected & {
77
- border-color: rgba( #425863, 0.4 ); // Gutenberg $dark-opacity-light-800
78
- }
79
-
80
- .block-editor-block-list__block:first-child & {
81
- border-bottom-width: 1px;
82
- }
83
-
84
- .block-editor-block-list__block:last-child & {
85
- border-top-width: 1px;
86
- }
87
-
88
- @media only screen and ( min-width: 768px ) {
89
- border-width: 1px;
90
- }
91
-
92
- .components-button {
93
- opacity: 0;
94
- transition: opacity 0.2s linear 0s;
95
- margin: 0 auto;
96
- &.hidden {
97
- display: none;
98
- }
99
- }
100
-
101
- .template-block__loading {
102
- display: flex;
103
- align-items: center;
104
- color: #191e23;
105
- }
106
- }
107
- }
108
-
109
- // Hide the site logo description and buttons when not editing the Template
110
- .block-editor-page:not( .post-type-wp_template_part ) {
111
- .fse-site-logo {
112
- .components-placeholder__fieldset,
113
- .components-placeholder__instructions {
114
- display: none;
115
- }
116
- }
117
- }
118
-
119
- // Center initial loading spinner in placeholder block.
120
- .template-block__placeholder {
121
- .components-spinner {
122
- margin: 0 auto;
123
- }
124
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/class-full-site-editing.php CHANGED
@@ -18,13 +18,6 @@ class Full_Site_Editing {
18
  */
19
  private static $instance = null;
20
 
21
- /**
22
- * Custom post types.
23
- *
24
- * @var array
25
- */
26
- private $template_post_types = array( 'wp_template_part' );
27
-
28
  /**
29
  * Current theme slug.
30
  *
@@ -45,23 +38,6 @@ class Full_Site_Editing {
45
  private function __construct() {
46
  add_action( 'init', array( $this, 'register_blocks' ), 100 );
47
  add_action( 'init', array( $this, 'register_template_post_types' ) );
48
- add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_script_and_style' ), 100 );
49
- add_action( 'the_post', array( $this, 'merge_template_and_post' ) );
50
- add_filter( 'wp_insert_post_data', array( $this, 'remove_template_components' ), 10, 2 );
51
- add_filter( 'admin_body_class', array( $this, 'toggle_editor_post_title_visibility' ) );
52
- add_filter( 'block_editor_settings', array( $this, 'set_block_template' ) );
53
- add_filter( 'body_class', array( $this, 'add_fse_body_class' ) );
54
-
55
- add_filter( 'post_row_actions', array( $this, 'remove_trash_row_action_for_template_post_types' ), 10, 2 );
56
- add_filter( 'bulk_actions-edit-wp_template', array( $this, 'remove_trash_bulk_action_for_template_post_type' ) );
57
- add_action( 'wp_trash_post', array( $this, 'restrict_template_deletion' ) );
58
- add_action( 'before_delete_post', array( $this, 'restrict_template_deletion' ) );
59
- add_filter( 'wp_template_type_row_actions', array( $this, 'remove_delete_row_action_for_template_taxonomy' ), 10, 2 );
60
- add_filter( 'bulk_actions-edit-wp_template_type', array( $this, 'remove_delete_bulk_action_for_template_taxonomy' ) );
61
- add_action( 'pre_delete_term', array( $this, 'restrict_template_taxonomy_deletion' ), 10, 2 );
62
- add_action( 'transition_post_status', array( $this, 'restrict_template_drafting' ), 10, 3 );
63
- add_action( 'admin_menu', array( $this, 'remove_wp_admin_menu_items' ) );
64
- add_filter( 'block_editor_rest_api_preload_paths', array( $this, 'preload_template_parts' ), 10, 2 );
65
 
66
  $this->theme_slug = normalize_theme_slug( get_stylesheet() );
67
  $this->wp_template_inserter = new WP_Template_Inserter( $this->theme_slug );
@@ -80,22 +56,6 @@ class Full_Site_Editing {
80
  return self::$instance;
81
  }
82
 
83
- /**
84
- * Inserts template data for the theme we are currently switching to.
85
- *
86
- * This insertion will only happen if theme supports dotcom FSE.
87
- * It is hooked into after_switch_theme action.
88
- */
89
- public function insert_default_data() {
90
- // Bail if current theme doesn't support dotcom FSE.
91
- if ( ! is_theme_supported() ) {
92
- return;
93
- }
94
-
95
- $this->wp_template_inserter->insert_default_template_data();
96
- $this->wp_template_inserter->insert_default_pages();
97
- }
98
-
99
  /**
100
  * Register post types.
101
  */
@@ -103,51 +63,6 @@ class Full_Site_Editing {
103
  $this->wp_template_inserter->register_template_post_types();
104
  }
105
 
106
- /**
107
- * Auth callback.
108
- *
109
- * @return mixed
110
- */
111
- public function meta_template_id_auth_callback() {
112
- return current_user_can( 'edit_theme_options' );
113
- }
114
-
115
- /**
116
- * Enqueue assets.
117
- */
118
- public function enqueue_script_and_style() {
119
- $asset_file = include plugin_dir_path( __FILE__ ) . 'dist/dotcom-fse.asset.php';
120
- $script_dependencies = $asset_file['dependencies'];
121
- wp_enqueue_script(
122
- 'a8c-full-site-editing-script',
123
- plugins_url( 'dist/dotcom-fse.js', __FILE__ ),
124
- is_array( $script_dependencies ) ? $script_dependencies : array(),
125
- filemtime( plugin_dir_path( __FILE__ ) . 'dist/dotcom-fse.js' ),
126
- true
127
- );
128
-
129
- wp_localize_script(
130
- 'a8c-full-site-editing-script',
131
- 'fullSiteEditing',
132
- array(
133
- 'editorPostType' => get_current_screen()->post_type,
134
- 'closeButtonLabel' => $this->get_close_button_label(),
135
- 'closeButtonUrl' => esc_url( $this->get_close_button_url() ),
136
- 'editTemplateBaseUrl' => esc_url( $this->get_edit_template_base_url() ),
137
- )
138
- );
139
-
140
- $style_file = is_rtl()
141
- ? 'dotcom-fse.rtl.css'
142
- : 'dotcom-fse.css';
143
- wp_enqueue_style(
144
- 'a8c-full-site-editing-style',
145
- plugins_url( 'dist/' . $style_file, __FILE__ ),
146
- 'wp-edit-post',
147
- filemtime( plugin_dir_path( __FILE__ ) . 'dist/' . $style_file )
148
- );
149
- }
150
-
151
  /**
152
  * Register blocks.
153
  */
@@ -221,425 +136,4 @@ class Full_Site_Editing {
221
  );
222
  }
223
 
224
- /**
225
- * Returns the parent post ID if sent as query param when editing a Template from a
226
- * Post/Page or a Template.
227
- *
228
- * @return null|string The parent post ID, or null if not set.
229
- */
230
- public function get_parent_post_id() {
231
- // phpcs:disable WordPress.Security.NonceVerification
232
- if ( ! isset( $_GET['fse_parent_post'] ) ) {
233
- return null;
234
- }
235
-
236
- $parent_post_id = absint( $_GET['fse_parent_post'] );
237
- // phpcs:enable WordPress.Security.NonceVerification
238
-
239
- if ( empty( $parent_post_id ) ) {
240
- return null;
241
- }
242
-
243
- return $parent_post_id;
244
- }
245
-
246
- /**
247
- * Returns the label for the Gutenberg close button.
248
- *
249
- * When we edit a Template from a Post/Page or a Template, we want to replace
250
- * the close icon with a "Back to" button, to clarify that it will take us
251
- * back to the previous editing view, and not the Template CPT list.
252
- *
253
- * @return null|string Override label string if it should be inserted, or null otherwise.
254
- */
255
- public function get_close_button_label() {
256
- $parent_post_id = $this->get_parent_post_id();
257
-
258
- if ( ! $parent_post_id ) {
259
- return null;
260
- }
261
-
262
- $parent_post_type = get_post_type( $parent_post_id );
263
-
264
- // See https://github.com/Automattic/wp-calypso/issues/38075#issuecomment-559900054.
265
- if ( 'page' === $parent_post_type ) {
266
- return __( 'Page Layout', 'full-site-editing' );
267
- }
268
-
269
- $parent_post_type_object = get_post_type_object( $parent_post_type );
270
-
271
- /* translators: %s: "Back to Post", "Back to Page", "Back to Template", etc. */
272
- return sprintf( __( 'Back to %s', 'full-site-editing' ), $parent_post_type_object->labels->singular_name );
273
- }
274
-
275
- /**
276
- * Returns the URL for the Gutenberg close button.
277
- *
278
- * In some cases we want to override the default value which would take us to post listing
279
- * for a given post type. For example, when navigating back from Header, we want to show the
280
- * parent page editing view, and not the Template CPT list.
281
- *
282
- * @return null|string Override URL string if it should be inserted, or null otherwise.
283
- */
284
- public function get_close_button_url() {
285
- $parent_post_id = $this->get_parent_post_id();
286
-
287
- if ( ! $parent_post_id ) {
288
- return null;
289
- }
290
-
291
- $close_button_url = get_edit_post_link( $parent_post_id );
292
-
293
- /**
294
- * Filter the Gutenberg's close button URL when editing Template CPTs.
295
- *
296
- * @since 0.1
297
- *
298
- * @param string Current close button URL.
299
- */
300
- return apply_filters( 'a8c_fse_close_button_link', $close_button_url );
301
- }
302
-
303
- /**
304
- * Returns the base URL for the Edit Template button. The URL does not contain neither
305
- * the post ID nor the template ID. Those query arguments should be provided by
306
- * the Template on the Block.
307
- *
308
- * @return string edit link without post ID
309
- */
310
- public function get_edit_template_base_url() {
311
- $edit_post_link = remove_query_arg( 'post', get_edit_post_link( 0, 'edit' ) );
312
-
313
- /**
314
- * Filter the Gutenberg's edit template button base URL
315
- * when editing pages or posts.
316
- *
317
- * @since 0.2
318
- *
319
- * @param string Current edit button URL.
320
- */
321
- return apply_filters( 'a8c_fse_edit_template_base_url', $edit_post_link );
322
- }
323
-
324
- /** This will merge the post content with the post template, modifiying the $post parameter.
325
- *
326
- * @param \WP_Post $post Post instance.
327
- */
328
- public function merge_template_and_post( $post ) {
329
- // Bail if not a REST API Request and not in the editor.
330
- if ( ! $this->should_merge_template_and_post( $post ) ) {
331
- return;
332
- }
333
-
334
- $template = new WP_Template();
335
- $template_content = $template->get_page_template_content();
336
-
337
- // Bail if the template has no post content block.
338
- if ( ! has_block( 'a8c/post-content', $template_content ) ) {
339
- return;
340
- }
341
-
342
- $post->post_content = preg_replace( '@(<!-- wp:a8c/post-content)(.*?)(/-->)@', "$1$2-->$post->post_content<!-- /wp:a8c/post-content -->", $template_content );
343
- }
344
-
345
- /**
346
- * Detects if we are in a context where the template and post should be merged.
347
- *
348
- * Conditions:
349
- * 1. Current theme supports it
350
- * 2. AND in a REST API request (either flavour)
351
- * 3. OR on a block editor screen (inlined requests using `rest_preload_api_request` )
352
- * 4. AND editing a post_type that supports full site editing
353
- *
354
- * @param \WP_Post $post object for the check.
355
- * @return bool
356
- */
357
- private function should_merge_template_and_post( $post ) {
358
- $is_rest_api_wpcom = ( defined( 'REST_API_REQUEST' ) && REST_API_REQUEST );
359
- $is_rest_api_core = ( defined( 'REST_REQUEST' ) && REST_REQUEST );
360
- $is_block_editor_screen = ( function_exists( 'get_current_screen' ) && get_current_screen() && get_current_screen()->is_block_editor() );
361
-
362
- if ( ! ( $is_block_editor_screen || $is_rest_api_core || $is_rest_api_wpcom ) ) {
363
- return false;
364
- }
365
- return $this->is_full_site_page( $post );
366
- }
367
-
368
- /**
369
- * This will extract the inner blocks of the post content and
370
- * serialize them back to HTML for saving.
371
- *
372
- * @param array $data An array of slashed post data.
373
- * @param array $postarr An array of sanitized, but otherwise unmodified post data.
374
- * @return array
375
- */
376
- public function remove_template_components( $data, $postarr ) {
377
- // Bail if the post type is one of the template post types.
378
- if ( in_array( $postarr['post_type'], $this->template_post_types, true ) ) {
379
- return $data;
380
- }
381
-
382
- $post_content = wp_unslash( $data['post_content'] );
383
-
384
- // Bail if post content has no blocks.
385
- if ( ! has_blocks( $post_content ) ) {
386
- return $data;
387
- }
388
-
389
- $post_content_blocks = parse_blocks( $post_content );
390
- $post_content_key = array_search( 'a8c/post-content', array_column( $post_content_blocks, 'blockName' ), true );
391
-
392
- // Bail if no post content block found.
393
- if ( ! $post_content_key ) {
394
- return $data;
395
- }
396
-
397
- $data['post_content'] = wp_slash( serialize_blocks( $post_content_blocks[ $post_content_key ]['innerBlocks'] ) );
398
- return $data;
399
- }
400
-
401
- /**
402
- * Return an extra class that will be assigned to the body element if a full site page is being edited.
403
- *
404
- * That class hides the default post title of the editor and displays a new post title rendered by the post content
405
- * block in order to have it just before the content of the post.
406
- *
407
- * @param string $classes Space-separated list of CSS classes.
408
- * @return string
409
- */
410
- public function toggle_editor_post_title_visibility( $classes ) {
411
- if ( get_current_screen()->is_block_editor() && $this->is_full_site_page() ) {
412
- $classes .= ' show-post-title-before-content ';
413
- }
414
- return $classes;
415
- }
416
-
417
- /**
418
- * Sets the block template to be loaded by the editor when creating a new full site page.
419
- *
420
- * @param array $editor_settings Default editor settings.
421
- * @return array Editor settings with the updated template setting.
422
- */
423
- public function set_block_template( $editor_settings ) {
424
- if ( $this->is_full_site_page() ) {
425
- $fse_template = new WP_Template();
426
- $template_blocks = $fse_template->get_template_blocks();
427
-
428
- $template = array();
429
- foreach ( $template_blocks as $block ) {
430
- $template[] = $this->fse_map_block_to_editor_template_setting( $block );
431
- }
432
- $editor_settings['template'] = $template;
433
- $editor_settings['templateLock'] = 'all';
434
- }
435
- return $editor_settings;
436
- }
437
-
438
- /**
439
- * Determine if the current edited post is a full site page.
440
- * So far we only support static pages.
441
- *
442
- * @param object $post optional post object, if not passed in then current post is checked.
443
- * @return boolean
444
- */
445
- public function is_full_site_page( $post = null ) {
446
- $post_type = get_post_type( $post );
447
- return 'page' === $post_type || ( 'revision' === $post_type && 'page' === get_post_type( $post->post_parent ) );
448
- }
449
-
450
- /**
451
- * Determines whether given post belongs to FSE template CPTs.
452
- *
453
- * @param WP_Post $post Check if this post belongs to templates.
454
- *
455
- * @return boolean
456
- */
457
- public function is_template_post_type( $post ) {
458
- return in_array( $post->post_type, $this->template_post_types, true );
459
- }
460
-
461
- /**
462
- * Add fse-enabled class to body so we can target css only if plugin enabled.
463
- *
464
- * @param array $classes classes to be applied to body.
465
- * @return array classes to be applied to body.
466
- */
467
- public function add_fse_body_class( $classes ) {
468
- $classes[] = 'fse-enabled';
469
- return $classes;
470
- }
471
-
472
- /**
473
- * Returns an array with the expected format of the block template setting syntax.
474
- *
475
- * @see https://github.com/WordPress/gutenberg/blob/1414cf0ad1ec3d0f3e86a40815513c15938bb522/docs/designers-developers/developers/block-api/block-templates.md
476
- *
477
- * @param array $block Block to convert.
478
- * @return array
479
- */
480
- private function fse_map_block_to_editor_template_setting( $block ) {
481
- $block_name = $block['blockName'];
482
- $attrs = $block['attrs'];
483
- $inner_blocks = $block['innerBlocks'];
484
-
485
- $inner_blocks_template = array();
486
- foreach ( $inner_blocks as $inner_block ) {
487
- $inner_blocks[] = fse_map_block_to_editor_template_setting( $inner_block );
488
- }
489
- return array( $block_name, $attrs, $inner_blocks_template );
490
- }
491
-
492
- /**
493
- * Removes the Trash action from the quick actions on the Templates list
494
- *
495
- * @param array $actions Array of row action links.
496
- * @param WP_Post $post The post object.
497
- * @return array
498
- */
499
- public function remove_trash_row_action_for_template_post_types( $actions, $post ) {
500
- if ( $this->is_template_post_type( $post ) ) {
501
- unset( $actions['trash'] );
502
- }
503
- return $actions;
504
- }
505
-
506
- /**
507
- * Removes the Trash bulk action from the Template List page.
508
- *
509
- * @param array $bulk_actions Array of bulk actions.
510
- * @return array;
511
- */
512
- public function remove_trash_bulk_action_for_template_post_type( $bulk_actions ) {
513
- unset( $bulk_actions['trash'] );
514
- return $bulk_actions;
515
- }
516
-
517
- /**
518
- * Prevents posts for the template post types to be deleted.
519
- *
520
- * @param integer $post_id The post id.
521
- */
522
- public function restrict_template_deletion( $post_id ) {
523
- if ( $this->is_template_post_type( get_post( $post_id ) ) ) {
524
- wp_die( esc_html__( 'Templates cannot be deleted.', 'full-site-editing' ) );
525
- }
526
- }
527
-
528
- // phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
529
- /**
530
- * Prevents draftinig of template post types.
531
- *
532
- * @param string $new_status New post status.
533
- * @param string $old_status Old post status.
534
- * @param object $post Post object for which the status change is attempted.
535
- */
536
- public function restrict_template_drafting( $new_status, $old_status, $post ) {
537
- if ( 'draft' === $new_status && $this->is_template_post_type( $post ) ) {
538
- wp_die( esc_html__( 'Templates cannot be moved to drafts.', 'full-site-editing' ) );
539
- }
540
- }
541
- // phpcs:enable Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
542
-
543
- /**
544
- * Removes the Delete action from the quick actions for the template taxonomy.
545
- *
546
- * @param array $actions Array of row action links.
547
- * @param WP_Term $term The Term object.
548
- * @return array
549
- */
550
- public function remove_delete_row_action_for_template_taxonomy( $actions, $term ) {
551
- if ( 'wp_template_part_type' === $term->taxonomy ) {
552
- unset( $actions['delete'] );
553
- }
554
- return $actions;
555
- }
556
-
557
- /**
558
- * Removes the Delete bulk action from the Template Taxonomy list.
559
- *
560
- * @param array $bulk_actions Array of bulk actions.
561
- * @return array
562
- */
563
- public function remove_delete_bulk_action_for_template_taxonomy( $bulk_actions ) {
564
- unset( $bulk_actions['delete'] );
565
- return $bulk_actions;
566
- }
567
-
568
- /**
569
- * Prevents template types to be deleted.
570
- *
571
- * @param integer $term The Term Id.
572
- * @param string $taxonomy Taxonomy name.
573
- */
574
- public function restrict_template_taxonomy_deletion( $term, $taxonomy ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
575
- if ( 'wp_template_part_type' === $taxonomy ) {
576
- wp_die( esc_html__( 'Template Types cannon be deleted.', 'full-site-editing' ) );
577
- }
578
- }
579
-
580
- /**
581
- * Removes wp admin menu items we don't want like Customize and Widgets.
582
- */
583
- public function remove_wp_admin_menu_items() {
584
- global $submenu;
585
-
586
- // For safety.
587
- if ( ! \A8C\FSE\is_full_site_editing_active() ) {
588
- return;
589
- }
590
-
591
- // Remove widget submenu.
592
- remove_submenu_page( 'themes.php', 'widgets.php' );
593
-
594
- /*
595
- * This position is hardcoded in `wp-admin/menu.php` and we can't use `remove_submenu_page`
596
- * because the customize URL varies depending on the current screen.
597
- *
598
- * We also want to access the customizer through the URL, so we shouldn't deny URL access.
599
- */
600
- if ( isset( $submenu['themes.php'][6] ) ) {
601
- unset( $submenu['themes.php'][6] );
602
- }
603
- }
604
-
605
- /**
606
- * Registers the footer credit option for API use.
607
- */
608
- public function register_footer_credit_setting() {
609
- /**
610
- * Note: We do not want to create the option if it doesn't exist. This
611
- * way, the default option can theoretically change if the user switches
612
- * site types without changing an option in the list at all. As soon as
613
- * they make a change to the selection, however, it will be persisted.
614
- */
615
-
616
- // Registers the footercredit option for API use.
617
- register_setting(
618
- 'general',
619
- 'footercredit',
620
- array(
621
- 'show_in_rest' => array(
622
- 'name' => 'footer_credit',
623
- ),
624
- 'type' => 'string',
625
- 'description' => __( 'WordPress Footer Credit', 'full-site-editing' ),
626
- )
627
- );
628
- }
629
-
630
- /**
631
- * Preload the path used to request a template part post when editing it in the block editor.
632
- *
633
- * @param array $paths Preload paths.
634
- * @param WP_Block_Editor_Context $context Current editor context.
635
- * @return $paths Filtered preload paths.
636
- */
637
- public function preload_template_parts( $paths, $context ) {
638
- $post = $context->post;
639
-
640
- if ( $post && 'wp_template_part' === $post->post_type ) {
641
- $paths[] = sprintf( '/wp/v2/template_parts?wp_id=%s&context=edit', $post->ID );
642
- }
643
- return $paths;
644
- }
645
  }
18
  */
19
  private static $instance = null;
20
 
 
 
 
 
 
 
 
21
  /**
22
  * Current theme slug.
23
  *
38
  private function __construct() {
39
  add_action( 'init', array( $this, 'register_blocks' ), 100 );
40
  add_action( 'init', array( $this, 'register_template_post_types' ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
  $this->theme_slug = normalize_theme_slug( get_stylesheet() );
43
  $this->wp_template_inserter = new WP_Template_Inserter( $this->theme_slug );
56
  return self::$instance;
57
  }
58
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  /**
60
  * Register post types.
61
  */
63
  $this->wp_template_inserter->register_template_post_types();
64
  }
65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  /**
67
  * Register blocks.
68
  */
136
  );
137
  }
138
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  }
dotcom-fse/dist/dotcom-fse.asset.php DELETED
@@ -1 +0,0 @@
1
- <?php return array('dependencies' => array('lodash', 'react', 'react-dom', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-data', 'wp-dom-ready', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-html-entities', 'wp-i18n', 'wp-plugins', 'wp-polyfill', 'wp-server-side-render', 'wp-url'), 'version' => '53a3f59f20e01a961325e1fed36acb9d');
 
dotcom-fse/dist/dotcom-fse.css DELETED
@@ -1 +0,0 @@
1
- .wp-block-a8c-navigation-menu.main-navigation{pointer-events:none}.post-content-block__selector{width:300px}.post-content-block__selector a{font-family:sans-serif;font-size:13px;padding-left:8px}.post-content-block__preview{pointer-events:none}.post-content-block__preview:after{clear:both;content:"";display:table}.post-content-block .editor-post-title,.show-post-title-before-content .editor-post-title{display:none}.show-post-title-before-content .post-content-block .editor-post-title{display:block}.block-editor-block-list__layout .post-content__block.is-selected .block-editor-block-contextual-toolbar{display:none}.block-editor-block-list__layout .post-content__block.block-editor-block-list__block.has-child-selected>.block-editor-block-list__block-edit:before,.block-editor-block-list__layout .post-content__block.block-editor-block-list__block.is-hovered>.block-editor-block-list__block-edit:before,.block-editor-block-list__layout .post-content__block.block-editor-block-list__block.is-navigate-mode>.block-editor-block-list__block-edit:before,.block-editor-block-list__layout .post-content__block.block-editor-block-list__block>.block-editor-block-list__block-edit:before{border:none;box-shadow:none;outline:none;transition:none}.block-editor-block-list__layout .post-content__block.block-editor-block-list__block.has-child-selected>.block-editor-block-list__block-edit>.block-editor-block-list__breadcrumb,.block-editor-block-list__layout .post-content__block.block-editor-block-list__block.is-hovered>.block-editor-block-list__block-edit>.block-editor-block-list__breadcrumb,.block-editor-block-list__layout .post-content__block.block-editor-block-list__block.is-navigate-mode>.block-editor-block-list__block-edit>.block-editor-block-list__breadcrumb,.block-editor-block-list__layout .post-content__block.block-editor-block-list__block>.block-editor-block-list__block-edit>.block-editor-block-list__breadcrumb{display:none}.site-credit__block{align-items:center;color:gray;display:flex;flex-direction:row;font-size:14px}.site-credit__block.has-text-align-center{justify-content:center}.site-credit__block.has-text-align-left{justify-content:flex-start}.site-credit__block.has-text-align-right{justify-content:flex-end}.site-credit__block .site-name{font-weight:700}.site-credit__block .site-credit__selection{align-items:center;display:flex;flex-direction:row;margin-left:5px}.site-credit__block .site-credit__selection .components-base-control .components-base-control__field{margin-bottom:0}.block-editor .wp-block-a8c-site-description:focus{background-color:transparent;box-shadow:none}.block-editor .wp-block.is-selected .wp-block-a8c-site-description::-webkit-input-placeholder{color:transparent}.block-editor .wp-block.is-selected .wp-block-a8c-site-description:-moz-placeholder,.block-editor .wp-block.is-selected .wp-block-a8c-site-description::-moz-placeholder{color:transparent}.block-editor .wp-block.is-selected .wp-block-a8c-site-description:-ms-input-placeholder{color:transparent}.block-editor .wp-block-a8c-site-title:focus{background-color:transparent;box-shadow:none}.block-editor .wp-block.is-selected .wp-block-a8c-site-title::-webkit-input-placeholder{color:transparent}.block-editor .wp-block.is-selected .wp-block-a8c-site-title:-moz-placeholder,.block-editor .wp-block.is-selected .wp-block-a8c-site-title::-moz-placeholder{color:transparent}.block-editor .wp-block.is-selected .wp-block-a8c-site-title:-ms-input-placeholder{color:transparent}.template-block{margin-top:20px;min-height:200px;overflow:hidden;position:relative}.post-type-page .editor-styles-wrapper .template-block .fse-template-part{padding:0}.components-popover.block-editor-block-list__block-popover .components-popover__content .block-editor-block-contextual-toolbar[data-type="a8c/template"],.template__block-container:before{display:none}.template__block-container:hover{cursor:pointer}.template__block-container .block-editor-block-list__block-edit [data-block]{margin:0}.template__block-container .is-navigating-to-template .components-disabled,.template__block-container.is-selected .components-disabled,.template__block-container:hover .components-disabled{filter:blur(2px);transition:filter .2s linear}.template__block-container .is-navigating-to-template .template-block__overlay,.template__block-container .is-navigating-to-template .template-block__overlay .components-button,.template__block-container.is-selected .template-block__overlay,.template__block-container.is-selected .template-block__overlay .components-button,.template__block-container:hover .template-block__overlay,.template__block-container:hover .template-block__overlay .components-button{opacity:1;transition:opacity .2s linear}.template__block-container .components-disabled{filter:blur(0);transition:filter .2s linear 0s}.template__block-container .block-editor-block-contextual-toolbar,.template__block-container .block-editor-block-list__block-edit:before,.template__block-container .block-editor-block-list__block-mobile-toolbar,.template__block-container .block-editor-block-list__breadcrumb,.template__block-container .block-editor-block-list__insertion-point{display:none}.template__block-container .template-block__overlay{background:hsla(0,0%,100%,.8);border:0 solid rgba(123,134,162,.3);bottom:0;left:0;margin:0;opacity:0;padding:0;position:absolute;right:0;top:0;transition:opacity .2s linear 0s;z-index:2}.is-selected .template__block-container .template-block__overlay{border-color:rgba(66,88,99,.4)}.block-editor-block-list__block:first-child .template__block-container .template-block__overlay{border-bottom-width:1px}.block-editor-block-list__block:last-child .template__block-container .template-block__overlay{border-top-width:1px}@media only screen and (min-width:768px){.template__block-container .template-block__overlay{border-width:1px}}.template__block-container .template-block__overlay .components-button{margin:0 auto;opacity:0;transition:opacity .2s linear 0s}.template__block-container .template-block__overlay .components-button.hidden{display:none}.template__block-container .template-block__overlay .template-block__loading{align-items:center;color:#191e23;display:flex}.block-editor-page:not(.post-type-wp_template_part) .fse-site-logo .components-placeholder__fieldset,.block-editor-page:not(.post-type-wp_template_part) .fse-site-logo .components-placeholder__instructions{display:none}.template-block__placeholder .components-spinner{margin:0 auto}.close-button-override-thin,.post-type-page .edit-post-fullscreen-mode-close__toolbar,.post-type-page .edit-post-header .edit-post-fullscreen-mode-close,.post-type-post .edit-post-fullscreen-mode-close__toolbar,.post-type-post .edit-post-header .edit-post-fullscreen-mode-close,.post-type-wp_template_part .edit-post-fullscreen-mode-close__toolbar,.post-type-wp_template_part .edit-post-header .edit-post-fullscreen-mode-close{display:none}.post-type-page .edit-post-fullscreen-mode-close__toolbar__override,.post-type-post .edit-post-fullscreen-mode-close__toolbar__override,.post-type-wp_template_part .edit-post-fullscreen-mode-close__toolbar__override{align-items:center;border:none;border-right:1px solid #e2e4e7;display:flex;margin-right:10px}.post-type-page .edit-post-fullscreen-mode-close__toolbar__override a,.post-type-page .edit-post-fullscreen-mode-close__toolbar__override a:active,.post-type-page .edit-post-fullscreen-mode-close__toolbar__override a:hover,.post-type-page .edit-post-fullscreen-mode-close__toolbar__override a:link,.post-type-page .edit-post-fullscreen-mode-close__toolbar__override a:visited,.post-type-post .edit-post-fullscreen-mode-close__toolbar__override a,.post-type-post .edit-post-fullscreen-mode-close__toolbar__override a:active,.post-type-post .edit-post-fullscreen-mode-close__toolbar__override a:hover,.post-type-post .edit-post-fullscreen-mode-close__toolbar__override a:link,.post-type-post .edit-post-fullscreen-mode-close__toolbar__override a:visited,.post-type-wp_template_part .edit-post-fullscreen-mode-close__toolbar__override a,.post-type-wp_template_part .edit-post-fullscreen-mode-close__toolbar__override a:active,.post-type-wp_template_part .edit-post-fullscreen-mode-close__toolbar__override a:hover,.post-type-wp_template_part .edit-post-fullscreen-mode-close__toolbar__override a:link,.post-type-wp_template_part .edit-post-fullscreen-mode-close__toolbar__override a:visited{text-decoration:none}.post-type-page .edit-post-fullscreen-mode-close__toolbar__override .close-button-override__label,.post-type-post .edit-post-fullscreen-mode-close__toolbar__override .close-button-override__label,.post-type-wp_template_part .edit-post-fullscreen-mode-close__toolbar__override .close-button-override__label{font-size:13px}.post-type-page .edit-post-fullscreen-mode-close__toolbar__override .dashicons-arrow-left-alt2,.post-type-post .edit-post-fullscreen-mode-close__toolbar__override .dashicons-arrow-left-alt2,.post-type-wp_template_part .edit-post-fullscreen-mode-close__toolbar__override .dashicons-arrow-left-alt2{margin-left:-7px}@media(max-width:599px){.post-type-page .edit-post-fullscreen-mode-close__toolbar__override,.post-type-post .edit-post-fullscreen-mode-close__toolbar__override,.post-type-wp_template_part .edit-post-fullscreen-mode-close__toolbar__override{margin-left:-2px}}@media(max-width:400px){.post-type-page .edit-post-fullscreen-mode-close__toolbar__override .close-button-override-wide,.post-type-post .edit-post-fullscreen-mode-close__toolbar__override .close-button-override-wide,.post-type-wp_template_part .edit-post-fullscreen-mode-close__toolbar__override .close-button-override-wide{display:none}.post-type-page .edit-post-fullscreen-mode-close__toolbar__override .close-button-override-thin,.post-type-post .edit-post-fullscreen-mode-close__toolbar__override .close-button-override-thin,.post-type-wp_template_part .edit-post-fullscreen-mode-close__toolbar__override .close-button-override-thin{display:flex}.post-type-page .edit-post-fullscreen-mode-close__toolbar__override .close-button-override__label,.post-type-post .edit-post-fullscreen-mode-close__toolbar__override .close-button-override__label,.post-type-wp_template_part .edit-post-fullscreen-mode-close__toolbar__override .close-button-override__label{display:none}}.post-type-page .block-editor-editor-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override,.post-type-page .interface-interface-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override,.post-type-post .block-editor-editor-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override,.post-type-post .interface-interface-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override,.post-type-wp_template_part .block-editor-editor-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override,.post-type-wp_template_part .interface-interface-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override{margin-right:24px}@media(max-width:782px){.post-type-page .block-editor-editor-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override,.post-type-page .interface-interface-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override,.post-type-post .block-editor-editor-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override,.post-type-post .interface-interface-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override,.post-type-wp_template_part .block-editor-editor-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override,.post-type-wp_template_part .interface-interface-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override{display:none}}@media(max-width:960px){.post-type-page .block-editor-editor-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override .close-button-override__label,.post-type-page .interface-interface-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override .close-button-override__label,.post-type-post .block-editor-editor-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override .close-button-override__label,.post-type-post .interface-interface-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override .close-button-override__label,.post-type-wp_template_part .block-editor-editor-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override .close-button-override__label,.post-type-wp_template_part .interface-interface-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override .close-button-override__label{display:none}}.post-type-page .edit-post-header-toolbar__left>.edit-post-header-toolbar__inserter-toggle,.post-type-wp_template_part .edit-post-post-status,.post-type-wp_template_part .editor-post-switch-to-draft,.post-type-wp_template_part .editor-post-title,.post-type-wp_template_part .editor-post-trash{display:none}@media(min-width:768px){.post-type-page .block-editor-editor-skeleton__content,.post-type-page .edit-post-editor-regions__content,.post-type-wp_template_part .block-editor-editor-skeleton__content,.post-type-wp_template_part .edit-post-editor-regions__content{background:#eee}.post-type-page .edit-post-editor-regions__content .edit-post-visual-editor,.post-type-page .edit-post-visual-editor.editor-styles-wrapper,.post-type-wp_template_part .edit-post-editor-regions__content .edit-post-visual-editor,.post-type-wp_template_part .edit-post-visual-editor.editor-styles-wrapper{box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.12),0 1px 5px 0 rgba(0,0,0,.2);flex:none;margin:36px 32px}}.post-type-page .block-editor-block-list__layout,.post-type-wp_template_part .block-editor-block-list__layout{padding-left:0;padding-right:0}.post-type-page .block-editor-block-list__block[data-align=full]>.block-editor-block-list__block-edit,.post-type-page .block-editor-block-list__layout .block-editor-block-list__block[data-align=full],.post-type-page .block-editor-block-list__layout .wp-block[data-align=full],.post-type-wp_template_part .block-editor-block-list__block[data-align=full]>.block-editor-block-list__block-edit,.post-type-wp_template_part .block-editor-block-list__layout .block-editor-block-list__block[data-align=full],.post-type-wp_template_part .block-editor-block-list__layout .wp-block[data-align=full]{margin-left:0;margin-right:0}.post-type-page .block-editor-block-list__block[data-align=wide]>.block-editor-block-list__block-edit,.post-type-wp_template_part .block-editor-block-list__block[data-align=wide]>.block-editor-block-list__block-edit{margin-left:14px;margin-right:14px}@media(max-width:1200px){.post-type-page .wp-block:not([data-align=full]):not([data-align=wide]),.post-type-wp_template_part .wp-block:not([data-align=full]):not([data-align=wide]){max-width:580px}.post-type-page .is-sidebar-opened .wp-block:not([data-align=full]):not([data-align=wide]),.post-type-wp_template_part .is-sidebar-opened .wp-block:not([data-align=full]):not([data-align=wide]){max-width:400px}}.post-type-page .block-editor-writing-flow__click-redirect,.post-type-wp_template_part .block-editor-writing-flow__click-redirect{display:none}.editor-styles-wrapper{background:#fff}.post-type-page .edit-post-visual-editor{padding-top:0}.post-type-page .block-editor-writing-flow{display:block}.post-type-page .wp-block.template__block-container .wp-block-column [data-type="core/social-links"] [data-block]{margin:0}@media(max-width:600px){.components-dropdown.table-of-contents{display:none}}
 
dotcom-fse/dist/dotcom-fse.js DELETED
@@ -1,6 +0,0 @@
1
- !function(){var e={2779:function(e,t){var o;
2
- /*!
3
- Copyright (c) 2018 Jed Watson.
4
- Licensed under the MIT License (MIT), see
5
- http://jedwatson.github.io/classnames
6
- */!function(){"use strict";var n={}.hasOwnProperty;function i(){for(var e=[],t=0;t<arguments.length;t++){var o=arguments[t];if(o){var l=typeof o;if("string"===l||"number"===l)e.push(o);else if(Array.isArray(o)){if(o.length){var r=i.apply(null,o);r&&e.push(r)}}else if("object"===l)if(o.toString===Object.prototype.toString)for(var s in o)n.call(o,s)&&o[s]&&e.push(s);else e.push(o.toString())}}return e.join(" ")}e.exports?(i.default=i,e.exports=i):void 0===(o=function(){return i}.apply(t,[]))||(e.exports=o)}()},3541:function(){},8937:function(){},9942:function(){},9888:function(){},7511:function(){},9537:function(){},3284:function(){},521:function(){},1428:function(e,t,o){"use strict";o.d(t,{R:function(){return i}});var n=o(4981);function i(){const e=(0,n.getCategories)();for(var t=arguments.length,o=new Array(t),i=0;i<t;i++)o[i]=arguments[i];for(const n of o)if(e.some((e=>{let{slug:t}=e;return t===n})))return n;throw new Error(`Could not find a category from the provided list: ${o.join(",")}`)}},49:function(e,t,o){"use strict";var n=o(9307),i=o(2175),l=o(5609),r=o(4333),s=o(9818),a=o(5736),c=o(8423),u=o.n(c);const __=a.__;t.Z=(0,r.compose)([(0,i.withColors)("backgroundColor",{textColor:"color"}),(0,i.withFontSizes)("fontSize"),(0,s.withSelect)((e=>({isPublished:e("core/editor").isCurrentPostPublished()})))])((e=>{let{attributes:t,backgroundColor:o,fontSize:r,setAttributes:s,setBackgroundColor:a,setFontSize:c,setTextColor:d,textColor:p,isPublished:f}=e;const{customFontSize:g,textAlign:m}=t,h=g||r.size;return(0,n.createElement)(n.Fragment,null,(0,n.createElement)(i.BlockControls,null,(0,n.createElement)(i.AlignmentToolbar,{value:m,onChange:e=>{s({textAlign:e})}})),(0,n.createElement)(i.InspectorControls,null,(0,n.createElement)(l.PanelBody,{className:"blocks-font-size",title:__("Text Settings","full-site-editing")},(0,n.createElement)(i.FontSizePicker,{onChange:c,value:h})),(0,n.createElement)(i.PanelColorSettings,{title:__("Color Settings","full-site-editing"),initialOpen:!1,colorSettings:[{value:o.color,onChange:a,label:__("Background Color","full-site-editing")},{value:p.color,onChange:d,label:__("Text Color","full-site-editing")}]},(0,n.createElement)(i.ContrastChecker,{textColor:p.color,backgroundColor:o.color,fontSize:h}))),(0,n.createElement)(u(),{isPublished:f,block:"a8c/navigation-menu",attributes:t}))}))},4018:function(e,t,o){"use strict";var n=o(9307),i=o(4981),l=o(5736),r=o(1428),s=o(49);o(3541);const __=l.__,a=(0,n.createElement)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},(0,n.createElement)("path",{fill:"none",d:"M0 0h24v24H0V0z"}),(0,n.createElement)("path",{d:"M12 7.27l4.28 10.43-3.47-1.53-.81-.36-.81.36-3.47 1.53L12 7.27M12 2L4.5 20.29l.71.71L12 18l6.79 3 .71-.71L12 2z"}));(0,i.registerBlockType)("a8c/navigation-menu",{title:__("Navigation Menu","full-site-editing"),description:__("Visual placeholder for site-wide navigation and menus.","full-site-editing"),icon:a,category:(0,r.R)("design","layout"),supports:{align:["wide","full","right","left"],html:!1,reusable:!1},edit:s.Z,save:()=>null})},966:function(e,t,o){"use strict";var n=o(9307),i=o(2175),l=o(4333),r=o(9818),s=o(2238),a=o(2779),c=o.n(a);class u extends n.Component{toggleEditing(){const{isEditing:e,setState:t}=this.props;t({isEditing:!e})}onSelectPost(e){let{id:t,type:o}=e;this.props.setState({isEditing:!1,selectedPostId:t,selectedPostType:o})}render(){const{attributes:e}=this.props,{align:t}=e;return(0,n.createElement)(n.Fragment,null,(0,n.createElement)("div",{className:c()("post-content-block",{[`align${t}`]:t})},(0,n.createElement)(s.PostTitle,null),(0,n.createElement)(i.InnerBlocks,{templateLock:!1})))}}t.Z=(0,l.compose)([(0,l.withState)({isEditing:!1,selectedPostId:void 0,selectedPostType:void 0}),(0,r.withSelect)(((e,t)=>{let{selectedPostId:o,selectedPostType:n}=t;const{getEntityRecord:i}=e("core");return{selectedPost:i("postType",n,o)}}))])(u)},7308:function(e,t,o){"use strict";var n=o(7896),i=o(9307),l=o(4981),r=o(4333),s=o(2694),a=o(5736),c=o(1428),u=o(966),d=o(3175);o(8937);const __=a.__;(0,l.registerBlockType)("a8c/post-content",{title:__("Content","full-site-editing"),description:__("The page content.","full-site-editing"),icon:"layout",category:(0,c.R)("design","layout"),supports:{align:["full"],anchor:!1,customClassName:!1,html:!1,inserter:!1,multiple:!1,reusable:!1},attributes:{align:{type:"string",default:"full"}},edit:u.Z,save:d.Z});const p=(0,r.createHigherOrderComponent)((e=>t=>"a8c/post-content"!==t.name?(0,i.createElement)(e,t):(0,i.createElement)(e,(0,n.Z)({},t,{className:"post-content__block"}))),"addContentSlotClassname");(0,s.addFilter)("editor.BlockListBlock","full-site-editing/blocks/post-content",p,9)},3175:function(e,t,o){"use strict";var n=o(9307),i=o(2175);t.Z=()=>(0,n.createElement)(i.InnerBlocks.Content,null)},1097:function(e,t,o){"use strict";var n=o(9307),i=o(2175),l=o(5609),r=o(4333),s=o(5736),a=o(2779),c=o.n(a),u=o(6284),d=o(8558);const __=s.__,{footerCreditOptions:p,defaultCreditOption:f}=fullSiteEditing;t.Z=(0,r.compose)([(0,u.g)({siteTitleOption:{optionName:"title",defaultValue:__("Site title loading…","full-site-editing")},footerCreditOption:{optionName:"footer_credit",defaultValue:__("Footer credit loading…","full-site-editing")}})])((function(e){let{attributes:{textAlign:t="center"},isSelected:o,setAttributes:r,footerCreditOption:{value:s,updateValue:a},siteTitleOption:{value:u}}=e;const g=s||f;return(0,n.createElement)(n.Fragment,null,(0,n.createElement)(i.BlockControls,null,(0,n.createElement)(i.AlignmentToolbar,{value:t,onChange:e=>{r({textAlign:e})}})),(0,n.createElement)("div",{className:c()("site-info","site-credit__block",{[`has-text-align-${t}`]:t})},(0,n.createElement)("span",{className:"site-name"},u),(0,n.createElement)("span",{className:"comma"},","),(0,n.createElement)("span",{className:"site-credit__selection"},o?(0,n.createElement)(l.SelectControl,{onChange:a,value:g,options:p}):(0,n.createElement)(d.U,{choice:g}))))}))},8558:function(e,t,o){"use strict";o.d(t,{U:function(){return r}});var n=o(9307),i=o(5609);const{footerCreditOptions:l}=fullSiteEditing,r=e=>{let{choice:t}=e;const o=l.find((e=>{let{value:o}=e;return o===t}));if(!o)return null;const{renderType:r,renderProps:s,label:a}=o,c={label:a,...s};return"icon"===r?(0,n.createElement)(i.Icon,c):(0,n.createElement)("span",null," ",c.label," ")}},6367:function(e,t,o){"use strict";var n=o(4981),i=o(5736),l=o(1428),r=o(1097);o(9942);const __=i.__;(0,n.registerBlockType)("a8c/site-credit",{title:__("WordPress.com Credit","full-site-editing"),description:__("This block tells the world that you're using WordPress.com.","full-site-editing"),icon:"wordpress-alt",category:(0,l.R)("design","layout"),supports:{align:["wide","full"],html:!1,multiple:!1,reusable:!1,removal:!1},attributes:{align:{type:"string",default:"wide"},textAlign:{type:"string",default:"center"}},edit:r.Z,save:()=>null})},942:function(e,t,o){"use strict";var n=o(9307),i=o(2175),l=o(5609),r=o(4333),s=o(9818),a=o(5736),c=o(2779),u=o.n(c),d=o(6284);const __=a.__,p=()=>{};t.Z=(0,r.compose)([(0,i.withColors)("backgroundColor",{textColor:"color"}),(0,i.withFontSizes)("fontSize"),(0,s.withSelect)(((e,t)=>{let{clientId:o}=t;const{getBlockIndex:n,getBlockRootClientId:i,getTemplateLock:l}=e("core/block-editor"),r=i(o);return{blockIndex:n(o,r),isLocked:!!l(r),rootClientId:r}})),(0,s.withDispatch)(((e,t)=>{let{blockIndex:o,rootClientId:n}=t;return{insertDefaultBlock:()=>e("core/block-editor").insertDefaultBlock({},n,o+1)}})),(0,d.g)({siteDescription:{optionName:"description",defaultValue:__("Site description loading…","full-site-editing")}})])((function(e){let{attributes:t,backgroundColor:o,className:r,fontSize:s,insertDefaultBlock:a,setAttributes:c,setBackgroundColor:d,setFontSize:f,setTextColor:g,siteDescription:m,textColor:h}=e;const{customFontSize:b,textAlign:v}=t,w=b||s.size,{value:E,updateValue:y}=m;return(0,n.createElement)(n.Fragment,null,(0,n.createElement)(i.BlockControls,null,(0,n.createElement)(i.AlignmentToolbar,{value:v,onChange:e=>{c({textAlign:e})}})),(0,n.createElement)(i.InspectorControls,null,(0,n.createElement)(l.PanelBody,{className:"blocks-font-size",title:__("Text Settings","full-site-editing")},(0,n.createElement)(i.FontSizePicker,{onChange:f,value:w})),(0,n.createElement)(i.PanelColorSettings,{title:__("Color Settings","full-site-editing"),initialOpen:!1,colorSettings:[{value:o.color,onChange:d,label:__("Background Color","full-site-editing")},{value:h.color,onChange:g,label:__("Text Color","full-site-editing")}]},(0,n.createElement)(i.ContrastChecker,{textColor:h.color,backgroundColor:o.color,fontSize:w}))),(0,n.createElement)(i.RichText,{allowedFormats:[],"aria-label":__("Site Description","full-site-editing"),className:u()("site-description",r,{"has-text-color":h.color,"has-background":o.color,[`has-text-align-${v}`]:v,[o.class]:o.class,[h.class]:h.class,[s.class]:!b&&s.class}),identifier:"content",onChange:y,onReplace:a,onSplit:p,placeholder:__("Add a Site Description","full-site-editing"),style:{backgroundColor:o.color,color:h.color,fontSize:w?w+"px":void 0},tagName:"p",value:E}))}))},5129:function(e,t,o){"use strict";var n=o(9307),i=o(4981),l=o(5736),r=o(1428),s=o(942);o(9888);const __=l.__;(0,i.registerBlockType)("a8c/site-description",{title:__("Site Description","full-site-editing"),description:__("Site description, also known as the tagline.","full-site-editing"),icon:(0,n.createElement)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24"},(0,n.createElement)("path",{fill:"none",d:"M0 0h24v24H0z"}),(0,n.createElement)("path",{d:"M4 9h16v2H4V9zm0 4h10v2H4v-2z"})),category:(0,r.R)("design","layout"),supports:{align:["wide","full"],html:!1,multiple:!1,reusable:!1},attributes:{align:{type:"string",default:"wide"},textAlign:{type:"string",default:"center"},textColor:{type:"string"},customTextColor:{type:"string"},backgroundColor:{type:"string"},customBackgroundColor:{type:"string"},fontSize:{type:"string",default:"small"},customFontSize:{type:"number"}},edit:s.Z,save:()=>null})},512:function(e,t,o){"use strict";var n=o(9307),i=o(2175),l=o(5609),r=o(4333),s=o(9818),a=o(5736),c=o(2779),u=o.n(c),d=o(6284);const __=a.__,p=()=>{};t.Z=(0,r.compose)([(0,i.withColors)({textColor:"color"}),(0,i.withFontSizes)("fontSize"),(0,s.withSelect)(((e,t)=>{let{clientId:o}=t;const{getBlockIndex:n,getBlockRootClientId:i,getTemplateLock:l}=e("core/block-editor"),r=i(o);return{blockIndex:n(o,r),isLocked:!!l(r),rootClientId:r}})),(0,s.withDispatch)(((e,t)=>{let{blockIndex:o,rootClientId:n}=t;return{insertDefaultBlock:()=>e("core/block-editor").insertDefaultBlock({},n,o+1)}})),(0,d.g)({siteTitle:{optionName:"title",defaultValue:__("Site title loading…","full-site-editing")}})])((function(e){let{attributes:t,className:o,fontSize:r,insertDefaultBlock:s,setAttributes:a,setFontSize:c,setTextColor:d,siteTitle:f,textColor:g}=e;const{customFontSize:m,textAlign:h}=t,b=m||r.size,{value:v,updateValue:w}=f;return(0,n.createElement)(n.Fragment,null,(0,n.createElement)(i.BlockControls,null,(0,n.createElement)(i.AlignmentToolbar,{value:h,onChange:e=>{a({textAlign:e})}})),(0,n.createElement)(i.InspectorControls,null,(0,n.createElement)(l.PanelBody,{className:"blocks-font-size",title:__("Text Settings","full-site-editing")},(0,n.createElement)(i.FontSizePicker,{onChange:c,value:b})),(0,n.createElement)(i.PanelColorSettings,{title:__("Color Settings","full-site-editing"),initialOpen:!1,colorSettings:[{value:g.color,onChange:d,label:__("Text Color","full-site-editing")}]})),(0,n.createElement)(i.RichText,{allowedFormats:[],"aria-label":__("Site Title","full-site-editing"),className:u()("site-title",o,{"has-text-color":g.color,[`has-text-align-${h}`]:h,[g.class]:g.class,[r.class]:!m&&r.class}),identifier:"content",onChange:w,onReplace:s,onSplit:p,placeholder:__("Add a Site Title","full-site-editing"),style:{color:g.color,fontSize:b?b+"px":void 0},tagName:"h1",value:v}))}))},5725:function(e,t,o){"use strict";var n=o(4981),i=o(5736),l=o(1428),r=o(512);o(7511);const __=i.__;(0,n.registerBlockType)("a8c/site-title",{title:__("Site Title","full-site-editing"),description:__("Your site title.","full-site-editing"),icon:"layout",category:(0,l.R)("design","layout"),supports:{align:["wide","full"],html:!1,multiple:!1,reusable:!1},attributes:{align:{type:"string",default:"wide"},textAlign:{type:"string",default:"center"},textColor:{type:"string"},customTextColor:{type:"string"},fontSize:{type:"string",default:"normal"},customFontSize:{type:"number"}},edit:r.Z,save:()=>null})},6594:function(e,t,o){"use strict";var n=o(9307),i=o(2175),l=o(4981),r=o(5609),s=o(4333),a=o(9818),c=o(5736),u=o(6483),d=o(2779),p=o.n(d),f=o(2819);o(9537);const __=c.__,g=()=>{},m=(0,s.compose)((0,s.withState)({templateClientId:null}),(0,a.withSelect)(((e,t)=>{let{attributes:o,templateClientId:n}=t;const{getEntityRecord:i}=e("core"),{getCurrentPostId:l,isEditedPostDirty:r}=e("core/editor"),{getBlock:s,getSelectedBlock:a}=e("core/block-editor"),{isEditorSidebarOpened:c}=e("core/edit-post"),{templateId:d}=o,p=l(),g=d&&i("postType","wp_template_part",d),m=(0,u.addQueryArgs)(fullSiteEditing.editTemplateBaseUrl,{post:d,fse_parent_post:p}),h=a();return{currentPostId:p,editTemplateUrl:m,template:g,templateBlock:s(n),templateTitle:(0,f.get)(g,["title","rendered"],""),isDirty:r(),isEditorSidebarOpened:!!c(),isAnyTemplateBlockSelected:h&&"a8c/template"===h.name}})),(0,a.withDispatch)(((e,t)=>{const{receiveBlocks:o}=e("core/block-editor"),{openGeneralSidebar:n}=e("core/edit-post"),{template:i,templateClientId:r,setState:s}=t;return{savePost:e("core/editor").savePost,receiveTemplateBlocks:()=>{if(!i||r)return;const e=(0,l.parse)((0,f.get)(i,["content","raw"],"")),t=(0,l.createBlock)("core/group",{},e);o([t]),s({templateClientId:t.clientId})},openGeneralSidebar:n}})))((e=>{let{attributes:t,editTemplateUrl:o,receiveTemplateBlocks:l,template:s,templateBlock:a,templateTitle:u,isDirty:d,savePost:f,isEditorSidebarOpened:m,openGeneralSidebar:h,isAnyTemplateBlockSelected:b}=e;if(!s)return(0,n.createElement)(r.Placeholder,{className:"template-block__placeholder"},(0,n.createElement)(r.Spinner,null));const v=(0,n.createRef)(),[w,E]=(0,n.useState)(!1);(0,n.useEffect)((()=>{w&&!d&&v.current.click(),l()})),(0,n.useEffect)((()=>{const e=document.querySelector(".edit-post-sidebar__panel-tabs ul li:last-child");if(m&&e){if(b)return h("edit-post/document"),void e.classList.add("hidden");e.classList.remove("hidden")}}),[b,m,h]);const{align:y,className:S}=t,k=e=>{e.stopPropagation(),E(!0),d&&(e.preventDefault(),f())};return(0,n.createElement)("div",{className:p()("template-block",{[`align${y}`]:y,"is-navigating-to-template":w})},a&&(0,n.createElement)(n.Fragment,null,(0,n.createElement)(r.Disabled,null,(0,n.createElement)("div",{className:S},(0,n.createElement)(i.BlockEdit,{attributes:a.attributes,block:a,clientId:a.clientId,isSelected:!1,name:a.name,setAttributes:g}))),(0,n.createElement)(r.Placeholder,{className:"template-block__overlay",onClick:k},w&&(0,n.createElement)("div",{className:"template-block__loading"},(0,n.createElement)(r.Spinner,null)," ",(0,c.sprintf)(__("Loading editor for: %s","full-site-editing"),u)),(0,n.createElement)(r.Button,{className:w?"hidden":null,href:o,onClick:k,isDefault:!0,isLarge:!0,ref:v},(0,c.sprintf)(__("Edit %s","full-site-editing"),u)))))}));t.Z=m},4987:function(e,t,o){"use strict";var n=o(7896),i=o(9307),l=o(4981),r=o(4333),s=o(2694),a=o(5736),c=o(1428),u=o(6594);o(9537),o(4498);const __=a.__;"wp_template_part"!==fullSiteEditing.editorPostType&&(0,l.registerBlockType)("a8c/template",{title:__("Template Part","full-site-editing"),__experimentalDisplayName:"label",description:__("Display a Template Part.","full-site-editing"),icon:"layout",category:(0,c.R)("design","layout"),attributes:{templateId:{type:"number"},className:{type:"string"},label:{type:"string"}},supports:{anchor:!1,customClassName:!1,html:!1,inserter:!1,reusable:!1},edit:u.Z,save:()=>null,getEditWrapperProps:()=>({"data-align":"full"})});const d=(0,r.createHigherOrderComponent)((e=>t=>"a8c/template"!==t.name?(0,i.createElement)(e,t):(0,i.createElement)(e,(0,n.Z)({},t,{className:"template__block-container"}))),"addFSETemplateClassname");(0,s.addFilter)("editor.BlockListBlock","full-site-editing/blocks/template",d,9)},4498:function(e,t,o){"use strict";var n=o(7896),i=o(9307),l=o(4333),r=o(2694);const s=(0,l.createHigherOrderComponent)((e=>t=>"fse-site-logo"!==t.attributes.className?(0,i.createElement)(e,t):(0,i.createElement)(e,(0,n.Z)({},t,{className:"template__site-logo"}))),"addFSESiteLogoClassname");(0,r.addFilter)("editor.BlockListBlock","full-site-editing/blocks/template",s)},9987:function(e,t,o){"use strict";var n=o(9307),i=o(7701),l=o.n(i),r=o(8259);const s="fse-post-content-block-inserter";function a(){if(document.getElementById(s))return;const e=document.querySelector(".edit-post-header-toolbar");if(!e)return;const t=document.createElement("div");t.className="fse-post-content-block-inserter",t.id=s,e.insertBefore(t,e.firstChild),(0,n.render)((0,n.createElement)(r.Z,null),t)}l()((function(){if("page"!==fullSiteEditing.editorPostType)return;const e=setInterval((()=>{if(!document.querySelector(".edit-post-header-toolbar"))return;clearInterval(e),a();if(document.getElementById("wpbody")&&void 0!==window.MutationObserver){new window.MutationObserver(a).observe(document.getElementById("wpbody"),{subtree:!0,childList:!0})}}))}))},8259:function(e,t,o){"use strict";var n=o(9307),i=o(2175),l=o(4333),r=o(9818);const s=(0,l.compose)((0,r.withSelect)((e=>{const{getEditorSettings:t}=e("core/editor"),{getBlocks:o}=e("core/block-editor"),{getEditorMode:n}=e("core/edit-post"),i=o().find((e=>"a8c/post-content"===e.name));return{rootClientId:i?i.clientId:"",showInserter:"visual"===n()&&t().richEditingEnabled}})))((e=>{let{rootClientId:t,showInserter:o}=e;return(0,n.createElement)(i.Inserter,{rootClientId:t,disabled:!o,position:"bottom right",toggleProps:{isPrimary:!0}})}));t.Z=s},6970:function(e,t,o){"use strict";var n=o(2694);const i=["logo","brand","emblem","hallmark"];(0,n.addFilter)("blocks.registerBlockType","full-site-editing/editor/image-block-keywords",((e,t)=>"core/image"!==t?e:e={...e,keywords:e.keywords.concat(i)}))},7111:function(e,t,o){"use strict";o(9987),o(1860),o(6970),o(3284),o(3644),o(711),o(1321)},1321:function(e,t,o){"use strict";var n=o(9818);const i=(0,n.subscribe)((()=>{const{removeEditorPanel:e}=(0,n.dispatch)("core/edit-post");return"page"===fullSiteEditing.editorPostType&&e("featured-image"),"wp_template_part"===fullSiteEditing.editorPostType&&e("post-status"),i()}))},711:function(e,t,o){"use strict";var n=o(9818);(0,n.use)((e=>({dispatch:t=>{const o={...e.dispatch(t)},{editorPostType:n}=fullSiteEditing;if("core/editor"===t&&o.editPost&&"wp_template_part"===n){const e=o.editPost;o.editPost=t=>{const{status:o}=t;"draft"!==o&&e(t)}}return o}})))},3644:function(e,t,o){"use strict";var n=o(9818);(0,n.use)((e=>({dispatch:t=>{const o={...e.dispatch(t)},{editorPostType:n}=fullSiteEditing;return"core/editor"===t&&o.trashPost&&"wp_template_part"===n&&(o.trashPost=()=>{}),o}})))},1860:function(e,t,o){"use strict";var n=o(9818);const i=(0,n.subscribe)((()=>{if("page"!==fullSiteEditing.editorPostType)return i();!1===(0,n.select)("core/block-editor").isValidTemplate()&&(0,n.dispatch)("core/block-editor").setTemplateValidity(!0)}))},6284:function(e,t,o){"use strict";o.d(t,{g:function(){return n.g}});var n=o(4825)},4825:function(e,t,o){"use strict";o.d(t,{g:function(){return n.g}});o(4351);var n=o(29)},5333:function(e,t,o){"use strict";o.d(t,{D:function(){return i}});var n=o(9307);function i(e){const t=(0,n.useRef)();return(0,n.useEffect)((()=>{t.current=e}),[e]),t.current}},4351:function(e,t,o){"use strict";o.d(t,{s:function(){return c}});var n=o(6989),i=o.n(n),l=o(9307),r=o(2629),s=o(5736),a=o(5333);const __=s.__;function c(e,t,o,n,c,u){const[d,p]=(0,l.useState)({option:t,previousOption:"",loaded:!1,error:!1}),f=(0,a.D)(n),g=(0,a.D)(c);function m(){p({...d,option:d.previousOption,isSaving:!1})}return(0,l.useEffect)((()=>{d.loaded||d.error?function(){const{option:t,previousOption:l}=d,r=!l&&!t||t&&l&&t.trim()===l.trim(),a=!t||0===t.trim().length;!n&&f&&a&&m();if(!c||r)return;!g&&c&&function(t){p({...d,isSaving:!0}),i()({path:"/wp/v2/settings",method:"POST",data:{[e]:t}}).then((()=>function(e){p({...d,previousOption:e,isDirty:!1,isSaving:!1})}(t))).catch((()=>{o((0,s.sprintf)(__("Unable to save site %s","full-site-editing"),e)),m()}))}(t)}():i()({path:"/wp/v2/settings"}).then((t=>p({...d,option:(0,r.decodeEntities)(t[e]),previousOption:(0,r.decodeEntities)(t[e]),loaded:!0,error:!1}))).catch((()=>{o((0,s.sprintf)(__("Unable to load site %s","full-site-editing"),e)),p({...d,option:(0,s.sprintf)(__("Error loading site %s","full-site-editing"),e),error:!0})}))})),{siteOptions:d,handleChange:function(e){u({updated:Date.now()}),p({...d,option:e})}}}},29:function(e,t,o){"use strict";o.d(t,{g:function(){return a}});var n=o(7896),i=o(9307),l=o(4333),r=o(9818),s=o(4351);const a=e=>(0,l.createHigherOrderComponent)((t=>(0,l.pure)((o=>{const l=(0,r.useSelect)((e=>{const{isSavingPost:t,isPublishingPost:o,isAutosavingPost:n,isCurrentPostPublished:i}=e("core/editor");return(t()&&i()||o())&&!n()})),a=(0,r.useDispatch)((e=>e("core/notices").createErrorNotice)),{isSelected:c,setAttributes:u}=o,d=Object.keys(e).reduce(((t,o)=>{const{optionName:n,defaultValue:i}=e[o],{siteOptions:r,handleChange:d}=(0,s.s)(n,i,a,c,l,u);return t[o]={value:r.option,updateValue:d,loaded:r.loaded},t}),{});return(0,i.createElement)(t,(0,n.Z)({},o,d))}))),"withSiteOptions")},3427:function(e,t,o){"use strict";var n=o(9307),i=o(5609),l=o(7701),r=o.n(l),s=o(5736),a=o(1850),c=o.n(a);o(521);const __=s.__;function u(e){let{defaultLabel:t,defaultUrl:o}=e;const[l,r]=(0,n.useState)(t),[s,a]=(0,n.useState)(o);return window.wp.hooks.addAction("updateCloseButtonOverrides","a8c-fse",(e=>{r(e.label),a(e.closeUrl)})),(0,n.createElement)("a",{href:s,"aria-label":l},(0,n.createElement)(i.Button,{className:"components-button components-icon-button"},(0,n.createElement)(i.Dashicon,{icon:"arrow-left-alt2"}),(0,n.createElement)("div",{className:"close-button-override__label"},l)))}r()((()=>{const{editorPostType:e}=fullSiteEditing;if("wp_template_part"!==e&&"page"!==e&&"post"!==e)return;const t=setInterval((()=>{const o=document.querySelector(".edit-post-header__toolbar");if(!o)return;clearInterval(t);const i=document.createElement("div");i.className="components-toolbar edit-post-fullscreen-mode-close__toolbar edit-post-fullscreen-mode-close__toolbar__override",o.prepend(i);let{closeButtonLabel:l,closeButtonUrl:r}=fullSiteEditing;const{calypsoifyGutenberg:s}=window;s&&s.closeUrl&&(r=s.closeUrl),s&&s.closeButtonLabel&&(l=s.closeButtonLabel);const a=r||`edit.php?post_type=${e}`;let d=l||"Back";"page"!==e||l?"post"!==e||l?"wp_template_part"!==e||l||(d=__("Template Parts","full-site-editing")):d=__("Posts","full-site-editing"):d=__("Pages","full-site-editing"),c().render((0,n.createElement)(u,{defaultLabel:d,defaultUrl:a}),i)}))}))},601:function(e,t,o){"use strict";var n=o(9818),i=o(8817),l=o(2779),r=o.n(l),s=o(2819),a=o(9196);const c=(0,n.withSelect)((e=>{const{getEntityRecord:t}=e("core"),{getEditedPostAttribute:o}=e("core/editor");return{templateClasses:(0,s.map)(o("template_part_types"),(e=>{const o=(0,s.get)(t("taxonomy","wp_template_part_type",e),"name","");return o.endsWith("-header")?"fse-header":o.endsWith("-footer")?"fse-footer":void 0}))}}))((e=>{let{templateClasses:t}=e;return(0,a.useEffect)((()=>{if(!t.some((e=>e)))return;const e=setInterval((()=>{const o=document.querySelector(".editor-styles-wrapper > .block-editor-block-list__layout");o&&(clearInterval(e),o.className.includes("a8c-template-editor fse-template-part")||(o.className=r()(o.className,"a8c-template-editor fse-template-part",...t)))}),100);return()=>clearInterval(e)}),[...t]),null}));"wp_template_part"===fullSiteEditing.editorPostType&&(0,i.registerPlugin)("fse-editor-template-classes",{render:c})},5052:function(e,t,o){"use strict";var n=o(9818),i=o(7701),l=o.n(i),r=o(5736);const __=r.__;l()((()=>{"wp_template_part"===fullSiteEditing.editorPostType&&(0,n.dispatch)("core/notices").createNotice("info",__("Updates to this template will affect all pages on your site.","full-site-editing"),{isDismissible:!1})}))},9196:function(e){"use strict";e.exports=window.React},1850:function(e){"use strict";e.exports=window.ReactDOM},2819:function(e){"use strict";e.exports=window.lodash},6989:function(e){"use strict";e.exports=window.wp.apiFetch},2175:function(e){"use strict";e.exports=window.wp.blockEditor},4981:function(e){"use strict";e.exports=window.wp.blocks},5609:function(e){"use strict";e.exports=window.wp.components},4333:function(e){"use strict";e.exports=window.wp.compose},9818:function(e){"use strict";e.exports=window.wp.data},7701:function(e){"use strict";e.exports=window.wp.domReady},2238:function(e){"use strict";e.exports=window.wp.editor},9307:function(e){"use strict";e.exports=window.wp.element},2694:function(e){"use strict";e.exports=window.wp.hooks},2629:function(e){"use strict";e.exports=window.wp.htmlEntities},5736:function(e){"use strict";e.exports=window.wp.i18n},8817:function(e){"use strict";e.exports=window.wp.plugins},8423:function(e){"use strict";e.exports=window.wp.serverSideRender},6483:function(e){"use strict";e.exports=window.wp.url},7896:function(e,t,o){"use strict";function n(){return n=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var o=arguments[t];for(var n in o)Object.prototype.hasOwnProperty.call(o,n)&&(e[n]=o[n])}return e},n.apply(this,arguments)}o.d(t,{Z:function(){return n}})}},t={};function o(n){var i=t[n];if(void 0!==i)return i.exports;var l=t[n]={exports:{}};return e[n](l,l.exports,o),l.exports}o.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(t,{a:t}),t},o.d=function(e,t){for(var n in t)o.o(t,n)&&!o.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},o.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},o.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var n={};!function(){"use strict";o.r(n);o(4018),o(7308),o(6367),o(5129),o(5725),o(4987),o(3427),o(601),o(5052),o(7111)}(),window.EditingToolkit=n}();
 
 
 
 
 
 
dotcom-fse/dist/dotcom-fse.rtl.css DELETED
@@ -1 +0,0 @@
1
- .wp-block-a8c-navigation-menu.main-navigation{pointer-events:none}.post-content-block__selector{width:300px}.post-content-block__selector a{font-family:sans-serif;font-size:13px;padding-right:8px}.post-content-block__preview{pointer-events:none}.post-content-block__preview:after{clear:both;content:"";display:table}.post-content-block .editor-post-title,.show-post-title-before-content .editor-post-title{display:none}.show-post-title-before-content .post-content-block .editor-post-title{display:block}.block-editor-block-list__layout .post-content__block.is-selected .block-editor-block-contextual-toolbar{display:none}.block-editor-block-list__layout .post-content__block.block-editor-block-list__block.has-child-selected>.block-editor-block-list__block-edit:before,.block-editor-block-list__layout .post-content__block.block-editor-block-list__block.is-hovered>.block-editor-block-list__block-edit:before,.block-editor-block-list__layout .post-content__block.block-editor-block-list__block.is-navigate-mode>.block-editor-block-list__block-edit:before,.block-editor-block-list__layout .post-content__block.block-editor-block-list__block>.block-editor-block-list__block-edit:before{border:none;box-shadow:none;outline:none;transition:none}.block-editor-block-list__layout .post-content__block.block-editor-block-list__block.has-child-selected>.block-editor-block-list__block-edit>.block-editor-block-list__breadcrumb,.block-editor-block-list__layout .post-content__block.block-editor-block-list__block.is-hovered>.block-editor-block-list__block-edit>.block-editor-block-list__breadcrumb,.block-editor-block-list__layout .post-content__block.block-editor-block-list__block.is-navigate-mode>.block-editor-block-list__block-edit>.block-editor-block-list__breadcrumb,.block-editor-block-list__layout .post-content__block.block-editor-block-list__block>.block-editor-block-list__block-edit>.block-editor-block-list__breadcrumb{display:none}.site-credit__block{align-items:center;color:gray;display:flex;flex-direction:row;font-size:14px}.site-credit__block.has-text-align-center{justify-content:center}.site-credit__block.has-text-align-left{justify-content:flex-start}.site-credit__block.has-text-align-right{justify-content:flex-end}.site-credit__block .site-name{font-weight:700}.site-credit__block .site-credit__selection{align-items:center;display:flex;flex-direction:row;margin-right:5px}.site-credit__block .site-credit__selection .components-base-control .components-base-control__field{margin-bottom:0}.block-editor .wp-block-a8c-site-description:focus{background-color:transparent;box-shadow:none}.block-editor .wp-block.is-selected .wp-block-a8c-site-description::-webkit-input-placeholder{color:transparent}.block-editor .wp-block.is-selected .wp-block-a8c-site-description:-moz-placeholder,.block-editor .wp-block.is-selected .wp-block-a8c-site-description::-moz-placeholder{color:transparent}.block-editor .wp-block.is-selected .wp-block-a8c-site-description:-ms-input-placeholder{color:transparent}.block-editor .wp-block-a8c-site-title:focus{background-color:transparent;box-shadow:none}.block-editor .wp-block.is-selected .wp-block-a8c-site-title::-webkit-input-placeholder{color:transparent}.block-editor .wp-block.is-selected .wp-block-a8c-site-title:-moz-placeholder,.block-editor .wp-block.is-selected .wp-block-a8c-site-title::-moz-placeholder{color:transparent}.block-editor .wp-block.is-selected .wp-block-a8c-site-title:-ms-input-placeholder{color:transparent}.template-block{margin-top:20px;min-height:200px;overflow:hidden;position:relative}.post-type-page .editor-styles-wrapper .template-block .fse-template-part{padding:0}.components-popover.block-editor-block-list__block-popover .components-popover__content .block-editor-block-contextual-toolbar[data-type="a8c/template"],.template__block-container:before{display:none}.template__block-container:hover{cursor:pointer}.template__block-container .block-editor-block-list__block-edit [data-block]{margin:0}.template__block-container .is-navigating-to-template .components-disabled,.template__block-container.is-selected .components-disabled,.template__block-container:hover .components-disabled{filter:blur(2px);transition:filter .2s linear}.template__block-container .is-navigating-to-template .template-block__overlay,.template__block-container .is-navigating-to-template .template-block__overlay .components-button,.template__block-container.is-selected .template-block__overlay,.template__block-container.is-selected .template-block__overlay .components-button,.template__block-container:hover .template-block__overlay,.template__block-container:hover .template-block__overlay .components-button{opacity:1;transition:opacity .2s linear}.template__block-container .components-disabled{filter:blur(0);transition:filter .2s linear 0s}.template__block-container .block-editor-block-contextual-toolbar,.template__block-container .block-editor-block-list__block-edit:before,.template__block-container .block-editor-block-list__block-mobile-toolbar,.template__block-container .block-editor-block-list__breadcrumb,.template__block-container .block-editor-block-list__insertion-point{display:none}.template__block-container .template-block__overlay{background:hsla(0,0%,100%,.8);border:0 solid rgba(123,134,162,.3);bottom:0;left:0;margin:0;opacity:0;padding:0;position:absolute;right:0;top:0;transition:opacity .2s linear 0s;z-index:2}.is-selected .template__block-container .template-block__overlay{border-color:rgba(66,88,99,.4)}.block-editor-block-list__block:first-child .template__block-container .template-block__overlay{border-bottom-width:1px}.block-editor-block-list__block:last-child .template__block-container .template-block__overlay{border-top-width:1px}@media only screen and (min-width:768px){.template__block-container .template-block__overlay{border-width:1px}}.template__block-container .template-block__overlay .components-button{margin:0 auto;opacity:0;transition:opacity .2s linear 0s}.template__block-container .template-block__overlay .components-button.hidden{display:none}.template__block-container .template-block__overlay .template-block__loading{align-items:center;color:#191e23;display:flex}.block-editor-page:not(.post-type-wp_template_part) .fse-site-logo .components-placeholder__fieldset,.block-editor-page:not(.post-type-wp_template_part) .fse-site-logo .components-placeholder__instructions{display:none}.template-block__placeholder .components-spinner{margin:0 auto}.close-button-override-thin,.post-type-page .edit-post-fullscreen-mode-close__toolbar,.post-type-page .edit-post-header .edit-post-fullscreen-mode-close,.post-type-post .edit-post-fullscreen-mode-close__toolbar,.post-type-post .edit-post-header .edit-post-fullscreen-mode-close,.post-type-wp_template_part .edit-post-fullscreen-mode-close__toolbar,.post-type-wp_template_part .edit-post-header .edit-post-fullscreen-mode-close{display:none}.post-type-page .edit-post-fullscreen-mode-close__toolbar__override,.post-type-post .edit-post-fullscreen-mode-close__toolbar__override,.post-type-wp_template_part .edit-post-fullscreen-mode-close__toolbar__override{align-items:center;border:none;border-left:1px solid #e2e4e7;display:flex;margin-left:10px}.post-type-page .edit-post-fullscreen-mode-close__toolbar__override a,.post-type-page .edit-post-fullscreen-mode-close__toolbar__override a:active,.post-type-page .edit-post-fullscreen-mode-close__toolbar__override a:hover,.post-type-page .edit-post-fullscreen-mode-close__toolbar__override a:link,.post-type-page .edit-post-fullscreen-mode-close__toolbar__override a:visited,.post-type-post .edit-post-fullscreen-mode-close__toolbar__override a,.post-type-post .edit-post-fullscreen-mode-close__toolbar__override a:active,.post-type-post .edit-post-fullscreen-mode-close__toolbar__override a:hover,.post-type-post .edit-post-fullscreen-mode-close__toolbar__override a:link,.post-type-post .edit-post-fullscreen-mode-close__toolbar__override a:visited,.post-type-wp_template_part .edit-post-fullscreen-mode-close__toolbar__override a,.post-type-wp_template_part .edit-post-fullscreen-mode-close__toolbar__override a:active,.post-type-wp_template_part .edit-post-fullscreen-mode-close__toolbar__override a:hover,.post-type-wp_template_part .edit-post-fullscreen-mode-close__toolbar__override a:link,.post-type-wp_template_part .edit-post-fullscreen-mode-close__toolbar__override a:visited{text-decoration:none}.post-type-page .edit-post-fullscreen-mode-close__toolbar__override .close-button-override__label,.post-type-post .edit-post-fullscreen-mode-close__toolbar__override .close-button-override__label,.post-type-wp_template_part .edit-post-fullscreen-mode-close__toolbar__override .close-button-override__label{font-size:13px}.post-type-page .edit-post-fullscreen-mode-close__toolbar__override .dashicons-arrow-left-alt2,.post-type-post .edit-post-fullscreen-mode-close__toolbar__override .dashicons-arrow-left-alt2,.post-type-wp_template_part .edit-post-fullscreen-mode-close__toolbar__override .dashicons-arrow-left-alt2{margin-right:-7px}@media(max-width:599px){.post-type-page .edit-post-fullscreen-mode-close__toolbar__override,.post-type-post .edit-post-fullscreen-mode-close__toolbar__override,.post-type-wp_template_part .edit-post-fullscreen-mode-close__toolbar__override{margin-right:-2px}}@media(max-width:400px){.post-type-page .edit-post-fullscreen-mode-close__toolbar__override .close-button-override-wide,.post-type-post .edit-post-fullscreen-mode-close__toolbar__override .close-button-override-wide,.post-type-wp_template_part .edit-post-fullscreen-mode-close__toolbar__override .close-button-override-wide{display:none}.post-type-page .edit-post-fullscreen-mode-close__toolbar__override .close-button-override-thin,.post-type-post .edit-post-fullscreen-mode-close__toolbar__override .close-button-override-thin,.post-type-wp_template_part .edit-post-fullscreen-mode-close__toolbar__override .close-button-override-thin{display:flex}.post-type-page .edit-post-fullscreen-mode-close__toolbar__override .close-button-override__label,.post-type-post .edit-post-fullscreen-mode-close__toolbar__override .close-button-override__label,.post-type-wp_template_part .edit-post-fullscreen-mode-close__toolbar__override .close-button-override__label{display:none}}.post-type-page .block-editor-editor-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override,.post-type-page .interface-interface-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override,.post-type-post .block-editor-editor-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override,.post-type-post .interface-interface-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override,.post-type-wp_template_part .block-editor-editor-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override,.post-type-wp_template_part .interface-interface-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override{margin-left:24px}@media(max-width:782px){.post-type-page .block-editor-editor-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override,.post-type-page .interface-interface-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override,.post-type-post .block-editor-editor-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override,.post-type-post .interface-interface-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override,.post-type-wp_template_part .block-editor-editor-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override,.post-type-wp_template_part .interface-interface-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override{display:none}}@media(max-width:960px){.post-type-page .block-editor-editor-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override .close-button-override__label,.post-type-page .interface-interface-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override .close-button-override__label,.post-type-post .block-editor-editor-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override .close-button-override__label,.post-type-post .interface-interface-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override .close-button-override__label,.post-type-wp_template_part .block-editor-editor-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override .close-button-override__label,.post-type-wp_template_part .interface-interface-skeleton__header .edit-post-fullscreen-mode-close__toolbar__override .close-button-override__label{display:none}}.post-type-page .edit-post-header-toolbar__left>.edit-post-header-toolbar__inserter-toggle,.post-type-wp_template_part .edit-post-post-status,.post-type-wp_template_part .editor-post-switch-to-draft,.post-type-wp_template_part .editor-post-title,.post-type-wp_template_part .editor-post-trash{display:none}@media(min-width:768px){.post-type-page .block-editor-editor-skeleton__content,.post-type-page .edit-post-editor-regions__content,.post-type-wp_template_part .block-editor-editor-skeleton__content,.post-type-wp_template_part .edit-post-editor-regions__content{background:#eee}.post-type-page .edit-post-editor-regions__content .edit-post-visual-editor,.post-type-page .edit-post-visual-editor.editor-styles-wrapper,.post-type-wp_template_part .edit-post-editor-regions__content .edit-post-visual-editor,.post-type-wp_template_part .edit-post-visual-editor.editor-styles-wrapper{box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.12),0 1px 5px 0 rgba(0,0,0,.2);flex:none;margin:36px 32px}}.post-type-page .block-editor-block-list__layout,.post-type-wp_template_part .block-editor-block-list__layout{padding-left:0;padding-right:0}.post-type-page .block-editor-block-list__block[data-align=full]>.block-editor-block-list__block-edit,.post-type-page .block-editor-block-list__layout .block-editor-block-list__block[data-align=full],.post-type-page .block-editor-block-list__layout .wp-block[data-align=full],.post-type-wp_template_part .block-editor-block-list__block[data-align=full]>.block-editor-block-list__block-edit,.post-type-wp_template_part .block-editor-block-list__layout .block-editor-block-list__block[data-align=full],.post-type-wp_template_part .block-editor-block-list__layout .wp-block[data-align=full]{margin-left:0;margin-right:0}.post-type-page .block-editor-block-list__block[data-align=wide]>.block-editor-block-list__block-edit,.post-type-wp_template_part .block-editor-block-list__block[data-align=wide]>.block-editor-block-list__block-edit{margin-left:14px;margin-right:14px}@media(max-width:1200px){.post-type-page .wp-block:not([data-align=full]):not([data-align=wide]),.post-type-wp_template_part .wp-block:not([data-align=full]):not([data-align=wide]){max-width:580px}.post-type-page .is-sidebar-opened .wp-block:not([data-align=full]):not([data-align=wide]),.post-type-wp_template_part .is-sidebar-opened .wp-block:not([data-align=full]):not([data-align=wide]){max-width:400px}}.post-type-page .block-editor-writing-flow__click-redirect,.post-type-wp_template_part .block-editor-writing-flow__click-redirect{display:none}.editor-styles-wrapper{background:#fff}.post-type-page .edit-post-visual-editor{padding-top:0}.post-type-page .block-editor-writing-flow{display:block}.post-type-page .wp-block.template__block-container .wp-block-column [data-type="core/social-links"] [data-block]{margin:0}@media(max-width:600px){.components-dropdown.table-of-contents{display:none}}
 
dotcom-fse/editor/block-inserter/index.js DELETED
@@ -1,55 +0,0 @@
1
- /* global fullSiteEditing */
2
-
3
- import domReady from '@wordpress/dom-ready';
4
- import { render } from '@wordpress/element';
5
- import PostContentBlockAppender from './post-content-block-appender';
6
-
7
- const CONTAINER_CLASS_NAME = 'fse-post-content-block-inserter';
8
- const CONTAINER_ID = 'fse-post-content-block-inserter';
9
-
10
- /**
11
- * Renders a custom block inserter that will append new blocks inside the post content block.
12
- */
13
- function renderPostContentBlockInserter() {
14
- if ( 'page' !== fullSiteEditing.editorPostType ) {
15
- return;
16
- }
17
-
18
- const editPostHeaderToolbarInception = setInterval( () => {
19
- const headerToolbar = document.querySelector( '.edit-post-header-toolbar' );
20
-
21
- if ( ! headerToolbar ) {
22
- return;
23
- }
24
- clearInterval( editPostHeaderToolbarInception );
25
- injectBlockInserter();
26
-
27
- // Re-inject the FSE inserter as needed in case React re-renders the header
28
- const wpbody = document.getElementById( 'wpbody' );
29
- if ( wpbody && typeof window.MutationObserver !== 'undefined' ) {
30
- const observer = new window.MutationObserver( injectBlockInserter );
31
- observer.observe( document.getElementById( 'wpbody' ), { subtree: true, childList: true } );
32
- }
33
- } );
34
- }
35
-
36
- function injectBlockInserter() {
37
- if ( document.getElementById( CONTAINER_ID ) ) {
38
- return;
39
- }
40
-
41
- const headerToolbar = document.querySelector( '.edit-post-header-toolbar' );
42
- if ( ! headerToolbar ) {
43
- return;
44
- }
45
-
46
- const blockInserterContainer = document.createElement( 'div' );
47
- blockInserterContainer.className = CONTAINER_CLASS_NAME;
48
- blockInserterContainer.id = CONTAINER_ID;
49
-
50
- headerToolbar.insertBefore( blockInserterContainer, headerToolbar.firstChild );
51
-
52
- render( <PostContentBlockAppender />, blockInserterContainer );
53
- }
54
-
55
- domReady( renderPostContentBlockInserter );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/editor/block-inserter/post-content-block-appender.js DELETED
@@ -1,30 +0,0 @@
1
- import { Inserter } from '@wordpress/block-editor';
2
- import { compose } from '@wordpress/compose';
3
- import { withSelect } from '@wordpress/data';
4
-
5
- const PostContentBlockAppender = compose(
6
- withSelect( ( select ) => {
7
- const { getEditorSettings } = select( 'core/editor' );
8
- const { getBlocks } = select( 'core/block-editor' );
9
- const { getEditorMode } = select( 'core/edit-post' );
10
-
11
- const postContentBlock = getBlocks().find( ( block ) => block.name === 'a8c/post-content' );
12
-
13
- return {
14
- rootClientId: postContentBlock ? postContentBlock.clientId : '',
15
- showInserter: getEditorMode() === 'visual' && getEditorSettings().richEditingEnabled,
16
- };
17
- } )
18
- )( ( { rootClientId, showInserter } ) => {
19
- const inserterToggleProps = { isPrimary: true };
20
- return (
21
- <Inserter
22
- rootClientId={ rootClientId }
23
- disabled={ ! showInserter }
24
- position="bottom right"
25
- toggleProps={ inserterToggleProps }
26
- />
27
- );
28
- } );
29
-
30
- export default PostContentBlockAppender;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/editor/image-block-keywords/index.js DELETED
@@ -1,20 +0,0 @@
1
- import { addFilter } from '@wordpress/hooks';
2
-
3
- const additionalKeywords = [ 'logo', 'brand', 'emblem', 'hallmark' ];
4
-
5
- addFilter(
6
- 'blocks.registerBlockType',
7
- 'full-site-editing/editor/image-block-keywords',
8
- ( settings, name ) => {
9
- if ( name !== 'core/image' ) {
10
- return settings;
11
- }
12
-
13
- settings = {
14
- ...settings,
15
- keywords: settings.keywords.concat( additionalKeywords ),
16
- };
17
-
18
- return settings;
19
- }
20
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/editor/index.js DELETED
@@ -1,7 +0,0 @@
1
- import './block-inserter';
2
- import './template-validity-override';
3
- import './image-block-keywords';
4
- import './style.scss';
5
- import './suppress-trash-action';
6
- import './suppress-draft-action';
7
- import './remove-editor-panels';
 
 
 
 
 
 
 
dotcom-fse/editor/remove-editor-panels/index.js DELETED
@@ -1,28 +0,0 @@
1
- /* global fullSiteEditing */
2
-
3
- import { dispatch, subscribe } from '@wordpress/data';
4
-
5
- /**
6
- * Disables specific sidebar editor panels in the FSE context.
7
- *
8
- * In particular, we remove the featured image panel for pages,
9
- * and we remove the post status panel for templates.
10
- *
11
- * Note that we only need to remove the panel once as it is persisted
12
- * in the redux state.
13
- */
14
- const unsubscribe = subscribe( () => {
15
- const { removeEditorPanel } = dispatch( 'core/edit-post' );
16
- if ( 'page' === fullSiteEditing.editorPostType ) {
17
- removeEditorPanel( 'featured-image' );
18
- }
19
-
20
- // @TODO Since the post status component doesn't check to see if it is removed, the
21
- // removeEditorPanel action won't have the desired effect. See:
22
- // https://github.com/WordPress/gutenberg/pull/17117
23
- // When support is added, we should remove the CSS hack at '../style.scss'
24
- if ( 'wp_template_part' === fullSiteEditing.editorPostType ) {
25
- removeEditorPanel( 'post-status' );
26
- }
27
- return unsubscribe();
28
- } );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/editor/style.scss DELETED
@@ -1,107 +0,0 @@
1
- .post-type-page .edit-post-header-toolbar__left > .edit-post-header-toolbar__inserter-toggle {
2
- display: none;
3
- }
4
-
5
- .post-type-wp_template_part {
6
- .editor-post-title,
7
- .editor-post-trash {
8
- display: none;
9
- }
10
-
11
- // @TODO: Remove this when Gutenberg support is added for
12
- // removing the PostStatus panel:
13
- .edit-post-post-status {
14
- display: none;
15
- }
16
-
17
- .editor-post-switch-to-draft {
18
- display: none;
19
- }
20
- }
21
-
22
- .post-type-page,
23
- .post-type-wp_template_part {
24
- @media ( min-width: 768px ) {
25
- // @TODO Remove the "regions content" class after G2 is available everywhere.
26
- .block-editor-editor-skeleton__content,
27
- .edit-post-editor-regions__content {
28
- background: #eee;
29
- }
30
-
31
- // @TODO Remove the "regions content" class after G2 is available everywhere.
32
- .edit-post-visual-editor.editor-styles-wrapper,
33
- .edit-post-editor-regions__content .edit-post-visual-editor {
34
- box-shadow: 0 2px 2px 0 rgba( 0, 0, 0, 0.14 ), 0 3px 1px -2px rgba( 0, 0, 0, 0.12 ),
35
- 0 1px 5px 0 rgba( 0, 0, 0, 0.2 );
36
- flex: none;
37
- margin: 36px 32px;
38
- }
39
- }
40
-
41
- .block-editor-block-list__layout {
42
- padding-left: 0;
43
- padding-right: 0;
44
-
45
- .block-editor-block-list__block[data-align='full'],
46
- .wp-block[data-align='full'] { // Gutenberg >= 8.0.0
47
- margin-left: 0;
48
- margin-right: 0;
49
- }
50
- }
51
-
52
- .block-editor-block-list__block[data-align='full'] > .block-editor-block-list__block-edit {
53
- margin-right: 0;
54
- margin-left: 0;
55
- }
56
-
57
- .block-editor-block-list__block[data-align='wide'] > .block-editor-block-list__block-edit {
58
- margin-right: 14px;
59
- margin-left: 14px;
60
- }
61
-
62
- @media ( max-width: 1200px ) {
63
- // Try to ensure that normally-aligned blocks work properly.
64
- .wp-block:not( [data-align='full'] ):not( [data-align='wide'] ) {
65
- max-width: 580px;
66
- }
67
- .is-sidebar-opened .wp-block:not( [data-align='full'] ):not( [data-align='wide'] ) {
68
- max-width: 400px;
69
- }
70
- }
71
-
72
- // Remove the 50vh bottom padding that looks off with the FSE frame.
73
- .block-editor-writing-flow__click-redirect {
74
- display: none;
75
- }
76
- }
77
-
78
- // We separate this from the other styles so that
79
- // the theme style can override this class without
80
- // having to get as specific.
81
- .editor-styles-wrapper {
82
- background: #fff;
83
- }
84
-
85
- .post-type-page {
86
- .edit-post-visual-editor {
87
- padding-top: 0;
88
- }
89
-
90
- .block-editor-writing-flow {
91
- display: block;
92
- }
93
-
94
- .wp-block.template__block-container
95
- .wp-block-column
96
- [data-type='core/social-links']
97
- [data-block] {
98
- margin: 0;
99
- }
100
- }
101
-
102
- @media ( max-width: 600px ) {
103
- // Table of contents button is not displayed in mobile view.
104
- .components-dropdown.table-of-contents {
105
- display: none;
106
- }
107
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/editor/suppress-draft-action/index.js DELETED
@@ -1,35 +0,0 @@
1
- /* global fullSiteEditing */
2
-
3
- import { use } from '@wordpress/data';
4
-
5
- // The purpose of this override is to prevent Switch to Draft action for template CPTs.
6
- use( ( registry ) => {
7
- return {
8
- dispatch: ( namespace ) => {
9
- const actions = { ...registry.dispatch( namespace ) };
10
- const { editorPostType } = fullSiteEditing;
11
-
12
- if (
13
- namespace === 'core/editor' &&
14
- actions.editPost &&
15
- editorPostType === 'wp_template_part'
16
- ) {
17
- const originalEditPost = actions.editPost;
18
-
19
- actions.editPost = ( edits ) => {
20
- const { status } = edits;
21
-
22
- // Bail if editPost is attempting to set draft as status.
23
- if ( status === 'draft' ) {
24
- return;
25
- }
26
-
27
- // Proceed with the usual call otherwise.
28
- originalEditPost( edits );
29
- };
30
- }
31
-
32
- return actions;
33
- },
34
- };
35
- } );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/editor/suppress-trash-action/index.js DELETED
@@ -1,23 +0,0 @@
1
- /* global fullSiteEditing */
2
-
3
- import { use } from '@wordpress/data';
4
-
5
- // The purpose of this override is to prevent trash action from deleting template CPTs.
6
- use( ( registry ) => {
7
- return {
8
- dispatch: ( namespace ) => {
9
- const actions = { ...registry.dispatch( namespace ) };
10
- const { editorPostType } = fullSiteEditing;
11
-
12
- if (
13
- namespace === 'core/editor' &&
14
- actions.trashPost &&
15
- editorPostType === 'wp_template_part'
16
- ) {
17
- actions.trashPost = () => {};
18
- }
19
-
20
- return actions;
21
- },
22
- };
23
- } );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/editor/template-validity-override/index.js DELETED
@@ -1,20 +0,0 @@
1
- /* global fullSiteEditing */
2
-
3
- import { select, dispatch, subscribe } from '@wordpress/data';
4
-
5
- /**
6
- * Forces the template validity.
7
- *
8
- * This is a work-around for the existing core issue that is showing a template mismatch warning when there is a parent
9
- * block with a locked template containing a nested InnerBlocks with an unlocked template.
10
- *
11
- * @see https://github.com/WordPress/gutenberg/issues/11681
12
- */
13
- const unsubscribe = subscribe( () => {
14
- if ( 'page' !== fullSiteEditing.editorPostType ) {
15
- return unsubscribe();
16
- }
17
- if ( select( 'core/block-editor' ).isValidTemplate() === false ) {
18
- dispatch( 'core/block-editor' ).setTemplateValidity( true );
19
- }
20
- } );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/helpers.php CHANGED
@@ -24,11 +24,8 @@ function dangerously_load_full_site_editing_files() {
24
  require_once __DIR__ . '/blocks/site-title/index.php';
25
  require_once __DIR__ . '/blocks/template/index.php';
26
  require_once __DIR__ . '/class-full-site-editing.php';
27
- require_once __DIR__ . '/templates/class-rest-templates-controller.php';
28
  require_once __DIR__ . '/templates/class-wp-template.php';
29
  require_once __DIR__ . '/templates/class-wp-template-inserter.php';
30
- require_once __DIR__ . '/templates/class-template-image-inserter.php';
31
- require_once __DIR__ . '/serialize-block-fallback.php';
32
  }
33
 
34
  /**
@@ -38,23 +35,12 @@ function dangerously_load_full_site_editing_files() {
38
  * @returns bool True if FSE is active, false otherwise.
39
  */
40
  function is_full_site_editing_active() {
41
- /**
42
- * There are times when this function is called from the WordPress.com public
43
- * API context. In this case, we need to switch to the correct blog so that
44
- * the functions reference the correct blog context.
45
- */
46
- $multisite_id = apply_filters( 'a8c_fse_get_multisite_id', false );
47
- $should_switch = is_multisite() && $multisite_id;
48
- if ( $should_switch ) {
49
- switch_to_blog( $multisite_id );
50
  }
51
 
52
- $is_active = is_site_eligible_for_full_site_editing() && is_theme_supported() && did_insert_template_parts();
53
-
54
- if ( $should_switch ) {
55
- restore_current_blog();
56
- }
57
- return $is_active;
58
  }
59
 
60
  /**
@@ -196,8 +182,6 @@ function populate_wp_template_data() {
196
  if ( ! is_theme_supported() ) {
197
  return;
198
  }
199
-
200
- require_once __DIR__ . '/templates/class-template-image-inserter.php';
201
  require_once __DIR__ . '/templates/class-wp-template-inserter.php';
202
 
203
  $theme_slug = normalize_theme_slug( get_theme_slug() );
24
  require_once __DIR__ . '/blocks/site-title/index.php';
25
  require_once __DIR__ . '/blocks/template/index.php';
26
  require_once __DIR__ . '/class-full-site-editing.php';
 
27
  require_once __DIR__ . '/templates/class-wp-template.php';
28
  require_once __DIR__ . '/templates/class-wp-template-inserter.php';
 
 
29
  }
30
 
31
  /**
35
  * @returns bool True if FSE is active, false otherwise.
36
  */
37
  function is_full_site_editing_active() {
38
+ // We will always return false in admin and REST API contexts as we work towards getting rid of this.
39
+ if ( defined( 'REST_API_REQUEST' ) && REST_API_REQUEST ) {
40
+ return false;
 
 
 
 
 
 
41
  }
42
 
43
+ return is_site_eligible_for_full_site_editing() && is_theme_supported() && did_insert_template_parts();
 
 
 
 
 
44
  }
45
 
46
  /**
182
  if ( ! is_theme_supported() ) {
183
  return;
184
  }
 
 
185
  require_once __DIR__ . '/templates/class-wp-template-inserter.php';
186
 
187
  $theme_slug = normalize_theme_slug( get_theme_slug() );
dotcom-fse/index.js DELETED
@@ -1,10 +0,0 @@
1
- import './blocks/navigation-menu';
2
- import './blocks/post-content';
3
- import './blocks/site-credit';
4
- import './blocks/site-description';
5
- import './blocks/site-title';
6
- import './blocks/template';
7
- import './plugins/close-button-override';
8
- import './plugins/editor-template-classes';
9
- import './plugins/template-update-notice';
10
- import './editor';
 
 
 
 
 
 
 
 
 
 
dotcom-fse/lib/index.js DELETED
@@ -1 +0,0 @@
1
- export * from './site-options';
 
dotcom-fse/lib/site-options/index.js DELETED
@@ -1,2 +0,0 @@
1
- export * from './use-site-options';
2
- export * from './with-site-options';
 
 
dotcom-fse/lib/site-options/use-previous.js DELETED
@@ -1,19 +0,0 @@
1
- import { useEffect, useRef } from '@wordpress/element';
2
-
3
- /**
4
- * Custom hook to provide the previous value of state or props in a functional component
5
- *
6
- * see https://reactjs.org/docs/hooks-faq.html#how-to-get-the-previous-props-or-state
7
- *
8
- * @param {any} value state or prop value for which previous value is required
9
- * @returns {any} previous value of requested state or prop value
10
- */
11
- export function usePrevious( value ) {
12
- const ref = useRef();
13
-
14
- useEffect( () => {
15
- ref.current = value;
16
- }, [ value ] );
17
-
18
- return ref.current;
19
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/lib/site-options/use-site-options.js DELETED
@@ -1,125 +0,0 @@
1
- import apiFetch from '@wordpress/api-fetch';
2
- import { useState, useEffect } from '@wordpress/element';
3
- import { decodeEntities } from '@wordpress/html-entities';
4
- import { __, sprintf } from '@wordpress/i18n';
5
- import { usePrevious } from './use-previous';
6
-
7
- export function useSiteOptions(
8
- siteOption,
9
- inititalOption,
10
- createErrorNotice,
11
- isSelected,
12
- shouldUpdateSiteOption,
13
- setAttributes
14
- ) {
15
- const [ siteOptions, setSiteOptions ] = useState( {
16
- option: inititalOption,
17
- previousOption: '',
18
- loaded: false,
19
- error: false,
20
- } );
21
-
22
- const previousIsSelected = usePrevious( isSelected );
23
- const previousShouldUpdateSiteOption = usePrevious( shouldUpdateSiteOption );
24
-
25
- useEffect( () => {
26
- if ( ! siteOptions.loaded && ! siteOptions.error ) {
27
- loadSiteOption();
28
- } else {
29
- updateSiteOption();
30
- }
31
- } );
32
-
33
- function loadSiteOption() {
34
- apiFetch( { path: '/wp/v2/settings' } )
35
- .then( ( result ) =>
36
- setSiteOptions( {
37
- ...siteOptions,
38
- option: decodeEntities( result[ siteOption ] ),
39
- previousOption: decodeEntities( result[ siteOption ] ),
40
- loaded: true,
41
- error: false,
42
- } )
43
- )
44
- .catch( () => {
45
- createErrorNotice(
46
- /* translators: %s is a site option (e.g. `title`, `description`, etc.). */
47
- sprintf( __( 'Unable to load site %s', 'full-site-editing' ), siteOption )
48
- );
49
- setSiteOptions( {
50
- ...siteOptions,
51
- /* translators: %s is a site option (e.g. `title`, `description`, etc.). */
52
- option: sprintf( __( 'Error loading site %s', 'full-site-editing' ), siteOption ),
53
- error: true,
54
- } );
55
- } );
56
- }
57
-
58
- function updateSiteOption() {
59
- const { option, previousOption } = siteOptions;
60
-
61
- /**
62
- * 1. Both `previousOption` and `option` are falsey.
63
- * OR
64
- * 2. Both `previousOption` and `option` are the same value after trim.
65
- */
66
- const optionUnchanged =
67
- ( ! previousOption && ! option ) ||
68
- ( option && previousOption && option.trim() === previousOption.trim() );
69
- const optionIsEmpty = ! option || option.trim().length === 0;
70
-
71
- // Reset to initial value if user de-selects the block with an empty value.
72
- if ( ! isSelected && previousIsSelected && optionIsEmpty ) {
73
- revertOption();
74
- }
75
-
76
- // Don't do anything further if we shouldn't update the site option or the value is unchanged.
77
- if ( ! shouldUpdateSiteOption || optionUnchanged ) {
78
- return;
79
- }
80
-
81
- if ( ! previousShouldUpdateSiteOption && shouldUpdateSiteOption ) {
82
- saveSiteOption( option );
83
- }
84
- }
85
-
86
- function saveSiteOption( option ) {
87
- setSiteOptions( { ...siteOptions, isSaving: true } );
88
- apiFetch( { path: '/wp/v2/settings', method: 'POST', data: { [ siteOption ]: option } } )
89
- .then( () => updatePreviousOption( option ) )
90
- .catch( () => {
91
- createErrorNotice(
92
- /* translators: %s is a site option (e.g. `title`, `description`, etc.). */
93
- sprintf( __( 'Unable to save site %s', 'full-site-editing' ), siteOption )
94
- );
95
- revertOption();
96
- } );
97
- }
98
-
99
- function revertOption() {
100
- setSiteOptions( {
101
- ...siteOptions,
102
- option: siteOptions.previousOption,
103
- isSaving: false,
104
- } );
105
- }
106
-
107
- function updatePreviousOption( option ) {
108
- setSiteOptions( {
109
- ...siteOptions,
110
- previousOption: option,
111
- isDirty: false,
112
- isSaving: false,
113
- } );
114
- }
115
-
116
- function handleChange( value ) {
117
- // The following is a temporary fix. Setting this fake attribute is used to flag
118
- // the content as dirty to editor and enable Update/Publish button. This should be
119
- // removed once updating of site options handled in core editor
120
- setAttributes( { updated: Date.now() } );
121
- setSiteOptions( { ...siteOptions, option: value } );
122
- }
123
-
124
- return { siteOptions, handleChange };
125
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/lib/site-options/with-site-options.js DELETED
@@ -1,90 +0,0 @@
1
- /* eslint-disable jsdoc/no-undefined-types */
2
-
3
- import { createHigherOrderComponent, pure } from '@wordpress/compose';
4
- import { useSelect, useDispatch } from '@wordpress/data';
5
- import { useSiteOptions } from './use-site-options';
6
-
7
- /**
8
- * Higher Order Component used to inject site options.
9
- *
10
- * The option value is requested from the WordPress API. Note that arbitrary
11
- * options can only be retrieved if they have been registered as site settings.
12
- *
13
- * Updates are persisted to the database when the post is saved.
14
- *
15
- * In the component, every specified `optionName` will be a prop which maps to
16
- * an object with the keys `value`, `updateValue`, and `loaded`. `value`
17
- * contains the actual value of the WordPress option, and `updateValue` can be
18
- * used to update the option. `updateValue` will re-render the component with
19
- * the new `value`.
20
- *
21
- * @param {object} options An object of site options to retrieve. Keys should be
22
- * option names you wish to have locally. They can be
23
- * named whatever makes sense in the context of your
24
- * component. Any key's value should be another object
25
- * whih contains `optionName`, the actual name of the
26
- * WordPress option to fetch, and `defaultValue`, the
27
- * value to use while the option is fetching.
28
- * @returns {Component} The higher order component.
29
- *
30
- * In the following example, withSiteOptions is called with an object mapping a
31
- * name for the option to some information about it. In particular, optionName
32
- * needs to match the name of the option in WordPress, and defaultValue is used
33
- * while the option is loading from the API.
34
- * @example
35
- * function Component( { mySiteOption } ) {
36
- * const { value, updateValue } = mySiteOption;
37
- * // `updateValue( 'foo' )` the component will re-render if called.
38
- * return <span>{ value }</span>;
39
- * }
40
- *
41
- * export default compose( [
42
- * withSiteOptions( {
43
- * mySiteOption: { optionName: 'title', defaultValue: __( 'Site title loading…' ) },
44
- * } ),
45
- * ] )( Component );
46
- */
47
- export const withSiteOptions = ( options ) =>
48
- createHigherOrderComponent(
49
- ( WrappedComponent ) =>
50
- pure( ( ownProps ) => {
51
- const shouldUpdateSiteOption = useSelect( ( select ) => {
52
- const {
53
- isSavingPost,
54
- isPublishingPost,
55
- isAutosavingPost,
56
- isCurrentPostPublished,
57
- } = select( 'core/editor' );
58
- return (
59
- ( ( isSavingPost() && isCurrentPostPublished() ) || isPublishingPost() ) &&
60
- ! isAutosavingPost()
61
- );
62
- } );
63
-
64
- const createErrorNotice = useDispatch(
65
- ( dispatch ) => dispatch( 'core/notices' ).createErrorNotice
66
- );
67
-
68
- const { isSelected, setAttributes } = ownProps;
69
- const allOptions = Object.keys( options ).reduce( ( accumulator, name ) => {
70
- const { optionName, defaultValue } = options[ name ];
71
- const { siteOptions, handleChange } = useSiteOptions(
72
- optionName,
73
- defaultValue,
74
- createErrorNotice,
75
- isSelected,
76
- shouldUpdateSiteOption,
77
- setAttributes
78
- );
79
- accumulator[ name ] = {
80
- value: siteOptions.option,
81
- updateValue: handleChange,
82
- loaded: siteOptions.loaded,
83
- };
84
- return accumulator;
85
- }, {} );
86
-
87
- return <WrappedComponent { ...ownProps } { ...allOptions } />;
88
- } ),
89
- 'withSiteOptions'
90
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/plugins/close-button-override/index.js DELETED
@@ -1,93 +0,0 @@
1
- /* global fullSiteEditing */
2
-
3
- // eslint-disable-next-line no-restricted-imports
4
- import { Button, Dashicon } from '@wordpress/components';
5
- import domReady from '@wordpress/dom-ready';
6
- import { useState } from '@wordpress/element';
7
- import { __ } from '@wordpress/i18n';
8
- import ReactDOM from 'react-dom';
9
-
10
- import './style.scss';
11
-
12
- function BackButtonOverride( { defaultLabel, defaultUrl } ) {
13
- const [ label, updateLabel ] = useState( defaultLabel );
14
- const [ url, updateUrl ] = useState( defaultUrl );
15
- window.wp.hooks.addAction( 'updateCloseButtonOverrides', 'a8c-fse', ( data ) => {
16
- updateLabel( data.label );
17
- updateUrl( data.closeUrl );
18
- } );
19
-
20
- return (
21
- <a href={ url } aria-label={ label }>
22
- { /* eslint-disable-next-line wpcalypso/jsx-classname-namespace */ }
23
- <Button className="components-button components-icon-button">
24
- <Dashicon icon="arrow-left-alt2" />
25
- <div className="close-button-override__label">{ label }</div>
26
- </Button>
27
- </a>
28
- );
29
- }
30
-
31
- domReady( () => {
32
- const { editorPostType } = fullSiteEditing;
33
-
34
- // Only alter for the page, post, and template part editors.
35
- if (
36
- 'wp_template_part' !== editorPostType &&
37
- 'page' !== editorPostType &&
38
- 'post' !== editorPostType
39
- ) {
40
- return;
41
- }
42
-
43
- const editPostHeaderInception = setInterval( () => {
44
- // Cycle through interval until header toolbar is found.
45
- const toolbar = document.querySelector( '.edit-post-header__toolbar' );
46
-
47
- if ( ! toolbar ) {
48
- return;
49
- }
50
- clearInterval( editPostHeaderInception );
51
-
52
- // Add components toolbar with override class name (original will be hidden in ./style.scss).
53
- const componentsToolbar = document.createElement( 'div' );
54
- componentsToolbar.className =
55
- 'components-toolbar edit-post-fullscreen-mode-close__toolbar edit-post-fullscreen-mode-close__toolbar__override';
56
- toolbar.prepend( componentsToolbar );
57
-
58
- // These should go here so that they have any updates that happened while querying for the selector.
59
- let { closeButtonLabel, closeButtonUrl } = fullSiteEditing;
60
-
61
- /**
62
- * We have to reference calypsoifyGutenberg off of the window object
63
- * directly to handle the case where it is undefined. Otherwise, the
64
- * variable declariation itself won't exist, causing a runtime error.
65
- */
66
- const { calypsoifyGutenberg } = window;
67
-
68
- // Use wpcom close button/url if they exist.
69
- if ( calypsoifyGutenberg && calypsoifyGutenberg.closeUrl ) {
70
- closeButtonUrl = calypsoifyGutenberg.closeUrl;
71
- }
72
-
73
- if ( calypsoifyGutenberg && calypsoifyGutenberg.closeButtonLabel ) {
74
- closeButtonLabel = calypsoifyGutenberg.closeButtonLabel;
75
- }
76
-
77
- const defaultUrl = closeButtonUrl || `edit.php?post_type=${ editorPostType }`;
78
-
79
- let defaultLabel = closeButtonLabel || 'Back';
80
- if ( 'page' === editorPostType && ! closeButtonLabel ) {
81
- defaultLabel = __( 'Pages', 'full-site-editing' );
82
- } else if ( 'post' === editorPostType && ! closeButtonLabel ) {
83
- defaultLabel = __( 'Posts', 'full-site-editing' );
84
- } else if ( 'wp_template_part' === editorPostType && ! closeButtonLabel ) {
85
- defaultLabel = __( 'Template Parts', 'full-site-editing' );
86
- }
87
-
88
- ReactDOM.render(
89
- <BackButtonOverride defaultLabel={ defaultLabel } defaultUrl={ defaultUrl } />,
90
- componentsToolbar
91
- );
92
- } );
93
- } );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/plugins/close-button-override/style.scss DELETED
@@ -1,91 +0,0 @@
1
- .post-type-wp_template_part .edit-post-header .edit-post-fullscreen-mode-close,
2
- .post-type-page .edit-post-header .edit-post-fullscreen-mode-close,
3
- .post-type-post .edit-post-header .edit-post-fullscreen-mode-close,
4
- .close-button-override-thin,
5
- // keep legacy selectors for backward compatibility with Gutenberg plugin < v7.7
6
- .post-type-wp_template_part .edit-post-fullscreen-mode-close__toolbar,
7
- .post-type-page .edit-post-fullscreen-mode-close__toolbar,
8
- .post-type-post .edit-post-fullscreen-mode-close__toolbar {
9
- display: none;
10
- }
11
-
12
- .post-type-wp_template_part .edit-post-fullscreen-mode-close__toolbar__override,
13
- .post-type-page .edit-post-fullscreen-mode-close__toolbar__override,
14
- .post-type-post .edit-post-fullscreen-mode-close__toolbar__override {
15
- display: flex;
16
- align-items: center;
17
- margin-right: 10px;
18
- border: none;
19
- border-right: 1px solid #e2e4e7;
20
-
21
- a,
22
- a:link,
23
- a:visited,
24
- a:hover,
25
- a:active {
26
- text-decoration: none;
27
- }
28
-
29
- .close-button-override__label {
30
- font-size: 13px;
31
- }
32
-
33
- .dashicons-arrow-left-alt2 {
34
- margin-left: -7px;
35
- }
36
-
37
- @media ( max-width: 599px ) {
38
- margin-left: -2px;
39
- }
40
-
41
- @media ( max-width: 400px ) {
42
- .close-button-override-wide {
43
- display: none;
44
- }
45
- .close-button-override-thin {
46
- display: flex;
47
- }
48
- .close-button-override__label {
49
- display: none;
50
- }
51
- }
52
- }
53
-
54
- // add an extra class specific for the new Gutenberg plugin version so the main override above stays compatible with < v7.7
55
- // includes additional `.interface-interface-skeleton__header` classes for compatibility with Gutenberg >= 8.0.0
56
- .post-type-wp_template_part
57
- .block-editor-editor-skeleton__header
58
- .edit-post-fullscreen-mode-close__toolbar__override,
59
- .post-type-page
60
- .block-editor-editor-skeleton__header
61
- .edit-post-fullscreen-mode-close__toolbar__override,
62
- .post-type-post
63
- .block-editor-editor-skeleton__header
64
- .edit-post-fullscreen-mode-close__toolbar__override,
65
- .post-type-wp_template_part
66
- .interface-interface-skeleton__header
67
- .edit-post-fullscreen-mode-close__toolbar__override,
68
- .post-type-page
69
- .interface-interface-skeleton__header
70
- .edit-post-fullscreen-mode-close__toolbar__override,
71
- .post-type-post
72
- .interface-interface-skeleton__header
73
- .edit-post-fullscreen-mode-close__toolbar__override {
74
- // Close button override doesn't need the extraneous left-padding
75
- // provided by .edit-post-header__toolbar from WP. So here we
76
- // offset the -24px padding and then restore the 24px padding
77
- // for other toolbar buttons that comes after this button.
78
- margin-right: 24px;
79
-
80
- // Back button is not displayed in mobile & tablet view.
81
- @media ( max-width: 782px ) {
82
- display: none;
83
- }
84
-
85
- // Hide label to make room for others
86
- @media ( max-width: 960px ) {
87
- .close-button-override__label {
88
- display: none;
89
- }
90
- }
91
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/plugins/editor-template-classes/index.js DELETED
@@ -1,62 +0,0 @@
1
- /* global fullSiteEditing */
2
-
3
- import { withSelect } from '@wordpress/data';
4
- import { registerPlugin } from '@wordpress/plugins';
5
- import classNames from 'classnames';
6
- import { get, map } from 'lodash';
7
- import { useEffect } from 'react';
8
-
9
- const EditorTemplateClasses = withSelect( ( select ) => {
10
- const { getEntityRecord } = select( 'core' );
11
- const { getEditedPostAttribute } = select( 'core/editor' );
12
- const templateClasses = map( getEditedPostAttribute( 'template_part_types' ), ( typeId ) => {
13
- const typeName = get(
14
- getEntityRecord( 'taxonomy', 'wp_template_part_type', typeId ),
15
- 'name',
16
- ''
17
- );
18
- if ( typeName.endsWith( '-header' ) ) {
19
- return 'fse-header';
20
- }
21
- if ( typeName.endsWith( '-footer' ) ) {
22
- return 'fse-footer';
23
- }
24
- } );
25
- return { templateClasses };
26
- } )( ( { templateClasses } ) => {
27
- useEffect( () => {
28
- // templateClasses will be an array with an undefined element when loading.
29
- if ( ! templateClasses.some( ( templateClass ) => templateClass ) ) {
30
- return;
31
- }
32
-
33
- const blockListInception = setInterval( () => {
34
- const blockListParent = document.querySelector(
35
- '.editor-styles-wrapper > .block-editor-block-list__layout'
36
- );
37
-
38
- if ( ! blockListParent ) {
39
- return;
40
- }
41
-
42
- clearInterval( blockListInception );
43
-
44
- if ( ! blockListParent.className.includes( 'a8c-template-editor fse-template-part' ) ) {
45
- blockListParent.className = classNames(
46
- blockListParent.className,
47
- 'a8c-template-editor fse-template-part',
48
- ...templateClasses
49
- );
50
- }
51
- }, 100 );
52
-
53
- return () => clearInterval( blockListInception );
54
- }, [ ...templateClasses ] ); // eslint-disable-line react-hooks/exhaustive-deps
55
- return null;
56
- } );
57
-
58
- if ( 'wp_template_part' === fullSiteEditing.editorPostType ) {
59
- registerPlugin( 'fse-editor-template-classes', {
60
- render: EditorTemplateClasses,
61
- } );
62
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/plugins/template-update-notice/index.js DELETED
@@ -1,18 +0,0 @@
1
- /* global fullSiteEditing */
2
-
3
- import { dispatch } from '@wordpress/data';
4
- import domReady from '@wordpress/dom-ready';
5
- import { __ } from '@wordpress/i18n';
6
-
7
- domReady( () => {
8
- if ( 'wp_template_part' !== fullSiteEditing.editorPostType ) {
9
- return;
10
- }
11
- dispatch( 'core/notices' ).createNotice(
12
- 'info',
13
- __( 'Updates to this template will affect all pages on your site.', 'full-site-editing' ),
14
- {
15
- isDismissible: false,
16
- }
17
- );
18
- } );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/sass/_mixins.scss DELETED
@@ -1,17 +0,0 @@
1
- @mixin hide-input-placeholder {
2
- &::-webkit-input-placeholder {
3
- color: transparent;
4
- }
5
-
6
- &:-moz-placeholder {
7
- color: transparent;
8
- }
9
-
10
- &::-moz-placeholder {
11
- color: transparent;
12
- }
13
-
14
- &:-ms-input-placeholder {
15
- color: transparent;
16
- }
17
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/serialize-block-fallback.php DELETED
@@ -1,70 +0,0 @@
1
- <?php
2
- /**
3
- * Fallback to provide serialize_block support being added to WP 5.3.0
4
- *
5
- * @package A8C\FSE
6
- */
7
-
8
- if ( ! function_exists( 'serialize_block' ) ) {
9
- /**
10
- * Renders an HTML-serialized form of a block object
11
- * from https://core.trac.wordpress.org/ticket/47375
12
- *
13
- * Should be available since WordPress 5.3.0.
14
- *
15
- * @param array $block The block being rendered.
16
- * @return string The HTML-serialized form of the block
17
- */
18
- function serialize_block( $block ) {
19
- // Non-block content has no block name.
20
- if ( null === $block['blockName'] ) {
21
- return $block['innerHTML'];
22
- }
23
-
24
- $unwanted = array( '--', '<', '>', '&', '\"' );
25
- $wanted = array( '\u002d\u002d', '\u003c', '\u003e', '\u0026', '\u0022' );
26
-
27
- $name = 0 === strpos( $block['blockName'], 'core/' ) ? substr( $block['blockName'], 5 ) : $block['blockName'];
28
- $has_attrs = ! empty( $block['attrs'] );
29
- $attrs = $has_attrs ? str_replace( $unwanted, $wanted, wp_json_encode( $block['attrs'] ) ) : '';
30
-
31
- // Early abort for void blocks holding no content.
32
- if ( empty( $block['innerContent'] ) ) {
33
- return $has_attrs
34
- ? "<!-- wp:{$name} {$attrs} /-->"
35
- : "<!-- wp:{$name} /-->";
36
- }
37
-
38
- $output = $has_attrs
39
- ? "<!-- wp:{$name} {$attrs} -->\n"
40
- : "<!-- wp:{$name} -->\n";
41
-
42
- $inner_block_index = 0;
43
- foreach ( $block['innerContent'] as $chunk ) {
44
- $output .= null === $chunk
45
- ? serialize_block( $block['innerBlocks'][ $inner_block_index++ ] )
46
- : $chunk;
47
-
48
- $output .= "\n";
49
- }
50
-
51
- $output .= "<!-- /wp:{$name} -->";
52
-
53
- return $output;
54
- }
55
- }
56
-
57
- if ( ! function_exists( 'serialize_blocks' ) ) {
58
- /**
59
- * Renders an HTML-serialized form of a list of block objects
60
- * from https://core.trac.wordpress.org/ticket/47375
61
- *
62
- * Should be available since WordPress 5.3.0.
63
- *
64
- * @param array $blocks The list of parsed block objects.
65
- * @return string The HTML-serialized form of the list of blocks.
66
- */
67
- function serialize_blocks( $blocks ) {
68
- return implode( "\n\n", array_map( 'serialize_block', $blocks ) );
69
- }
70
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/templates/class-rest-templates-controller.php DELETED
@@ -1,69 +0,0 @@
1
- <?php
2
- /**
3
- * REST Templates Controller file.
4
- *
5
- * @package A8C\FSE
6
- */
7
-
8
- namespace A8C\FSE;
9
-
10
- /**
11
- * Based on `WP_REST_Blocks_Controller` from core
12
- */
13
- class REST_Templates_Controller extends \WP_REST_Posts_Controller {
14
- /**
15
- * Override the get_items method.
16
- *
17
- * Gutenberg uses the route `/wp/v2/template_parts?wp_id=%s&context=edit` to retrieve the current post data when editing
18
- * a template or template part, so we handle that here.
19
- *
20
- * @see https://github.com/WordPress/gutenberg/blob/6c94fb7a233e849e0fff51deffba6ab2866c60f4/packages/edit-post/src/editor.js#L71
21
- *
22
- * @param WP_REST_Request $request API request for template parts.
23
- * @return WP_REST_Response
24
- */
25
- public function get_items( $request ) {
26
- $template_id = $request['wp_id'];
27
-
28
- if ( $template_id ) {
29
- $request->set_param( 'include', array( $template_id ) );
30
- }
31
-
32
- return parent::get_items( $request );
33
- }
34
-
35
- /**
36
- * Checks if a template can be read.
37
- *
38
- * @param object $post Post object that backs the template.
39
- * @return bool Whether the template can be read.
40
- */
41
- public function check_read_permission( $post ) {
42
- // Ensure that the user is logged in and has the edit_posts capability.
43
- $post_type = get_post_type_object( $post->post_type );
44
- if ( ! current_user_can( $post_type->cap->read_post, $post->ID ) ) {
45
- return false;
46
- }
47
-
48
- return parent::check_read_permission( $post );
49
- }
50
-
51
- /**
52
- * Retrieves the template's schema, conforming to JSON Schema.
53
- *
54
- * @return array Item schema data.
55
- */
56
- public function get_item_schema() {
57
- $schema = parent::get_item_schema();
58
-
59
- /*
60
- * Allow all contexts to access `title.raw` and `content.raw`. Clients always
61
- * need the raw markup of a reusable template to do anything useful, e.g. parse
62
- * it or display it in an editor.
63
- */
64
- $schema['properties']['title']['properties']['raw']['context'] = array( 'view', 'edit' );
65
- $schema['properties']['content']['properties']['raw']['context'] = array( 'view', 'edit' );
66
-
67
- return $schema;
68
- }
69
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/templates/class-template-image-inserter.php DELETED
@@ -1,174 +0,0 @@
1
- <?php
2
- /**
3
- * Full site editing file.
4
- *
5
- * @package A8C\FSE
6
- */
7
-
8
- namespace A8C\FSE;
9
-
10
- /**
11
- * Class Template_Image_Inserter
12
- */
13
- class Template_Image_Inserter {
14
- /**
15
- * Uploads specific images to the media libraray
16
- *
17
- * It then checks if any of the passed image URLs are also in the post content
18
- * of any of the passed post IDs. If so, then the post content is updated to
19
- * use the new local URL instead of the passed URL.
20
- *
21
- * @param array $img_urls URLs of images which should be uploaded.
22
- * @param array $post_ids An array of posts IDs which should be updated with newly uploaded image URLs.
23
- */
24
- public function copy_images_and_update_posts( $img_urls = array(), $post_ids = array() ) {
25
- do_action(
26
- 'a8c_fse_log',
27
- 'template_image_sideload_begin',
28
- array(
29
- 'context' => 'Template_Image_Inserter->copy_images_and_update_posts',
30
- 'image_urls' => $img_urls,
31
- )
32
- );
33
-
34
- if ( empty( $img_urls ) || empty( $post_ids ) ) {
35
- return;
36
- }
37
-
38
- $images = $this->upload_images( $img_urls );
39
- foreach ( $post_ids as $id ) {
40
- $this->update_post_images( $id, $images );
41
- }
42
- }
43
-
44
- /**
45
- * Upload an array of images to the media library.
46
- *
47
- * If an file fails to upload, the error is logged to the FSE error handler.
48
- *
49
- * @param array $image_urls Images URLs to upload.
50
- * @return array Each entry contains the old and new URL of an image if successfully uploaded.
51
- */
52
- public function upload_images( $image_urls ) {
53
- return array_reduce(
54
- $image_urls,
55
- function ( $accumulator, $url ) {
56
- // 1. Attempt to sideload the image and get the local URL.
57
- $local_url = $this->upload_image( $url );
58
-
59
- // 2. Check if anything went wrong during upload.
60
- $error_msg = null;
61
- if ( is_wp_error( $local_url ) ) {
62
- $error_msg = $local_url->get_error_message();
63
- } elseif ( ! is_string( $local_url ) ) {
64
- $error_msg = 'Issue uploading the image.';
65
- }
66
-
67
- // 3. If there was an error, report it.
68
- if ( is_string( $error_msg ) ) {
69
- do_action(
70
- 'a8c_fse_log',
71
- 'image_sideload_failure',
72
- array(
73
- 'context' => 'Template_Image_Inserter->upload_images',
74
- 'error' => $error_msg,
75
- 'remote_image_url' => $url,
76
- )
77
- );
78
- } else {
79
- // 4. Otherwise, save the url.
80
- $accumulator[] = array(
81
- 'old_url' => $url,
82
- 'new_url' => $local_url,
83
- );
84
- }
85
- return $accumulator;
86
- },
87
- array()
88
- );
89
- }
90
-
91
- /**
92
- * Sideload a remote image URL and return the local attachment URL.
93
- *
94
- * @param string $image_url The URL to sideload to the local site.
95
- * @return string The local URL of the newly uploaded image.
96
- */
97
- public function upload_image( $image_url ) {
98
- if ( ! function_exists( 'media_handle_sideload' ) ) {
99
- require_once ABSPATH . '/wp-admin/includes/file.php';
100
- require_once ABSPATH . '/wp-admin/includes/media.php';
101
- require_once ABSPATH . '/wp-admin/includes/image.php';
102
- }
103
-
104
- // 1. Download the image.
105
- $local_file = download_url( $image_url );
106
- if ( is_wp_error( $local_file ) ) {
107
- return $local_file;
108
- }
109
-
110
- // 2. Create a file object.
111
- $file_name = basename( wp_parse_url( $image_url, PHP_URL_PATH ) );
112
- $desc = 'Template Part Image';
113
- $file_array = array(
114
- 'name' => $file_name,
115
- 'tmp_name' => $local_file,
116
- );
117
-
118
- // 3. Sideload, remove tmp file, and return the local URL.
119
- $id = media_handle_sideload( $file_array, 0, $desc );
120
- // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
121
- @unlink( $local_file );
122
-
123
- if ( is_wp_error( $id ) ) {
124
- return $id;
125
- }
126
-
127
- return wp_get_attachment_url( $id );
128
- }
129
-
130
- /**
131
- * Upload an image URL.
132
- *
133
- * @param array $post_id The post ID which should be updated with the new URLs.
134
- * @param array $images An array of old/new image URLs to replace.
135
- */
136
- public function update_post_images( $post_id, $images ) {
137
- $content = get_post_field( 'post_content', $post_id );
138
- if ( empty( $content ) ) {
139
- do_action(
140
- 'a8c_fse_log',
141
- 'update_post_with_new_images_get_post_failure',
142
- array(
143
- 'context' => 'Template_Image_Inserter->update_post_images',
144
- 'error' => 'Could not retrieve post content.',
145
- 'post_id' => $post_id,
146
- )
147
- );
148
- return;
149
- }
150
-
151
- // Replace the matching images in the content and update the post.
152
- foreach ( $images as $image ) {
153
- $content = str_replace( $image['old_url'], $image['new_url'], $content );
154
- }
155
- $res = wp_update_post(
156
- array(
157
- 'ID' => $post_id,
158
- 'post_content' => $content,
159
- )
160
- );
161
-
162
- if ( ! $res ) {
163
- do_action(
164
- 'a8c_fse_log',
165
- 'update_post_with_new_images_update_post_failure',
166
- array(
167
- 'context' => 'Template_Image_Inserter->update_post_images',
168
- 'error' => 'Issue updating the post with the new image URLs.',
169
- 'image_urls' => $images,
170
- )
171
- );
172
- }
173
- }
174
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dotcom-fse/templates/class-wp-template-inserter.php CHANGED
@@ -431,7 +431,7 @@ class WP_Template_Inserter {
431
  register_post_type(
432
  'wp_template_part', // phpcs:ignore WordPress.NamingConventions.ValidPostTypeSlug.ReservedPrefix
433
  array(
434
- 'labels' => array(
435
  'name' => _x( 'Template Parts', 'post type general name', 'full-site-editing' ),
436
  'singular_name' => _x( 'Template Part', 'post type singular name', 'full-site-editing' ),
437
  'menu_name' => _x( 'Template Parts', 'admin menu', 'full-site-editing' ),
@@ -454,16 +454,13 @@ class WP_Template_Inserter {
454
  'item_scheduled' => __( 'Template part scheduled.', 'full-site-editing' ),
455
  'item_updated' => __( 'Template part updated.', 'full-site-editing' ),
456
  ),
457
- 'menu_icon' => 'dashicons-layout',
458
- 'public' => false,
459
- 'show_ui' => true, // Otherwise we'd get permission error when trying to edit them.
460
- 'show_in_menu' => false,
461
- 'rewrite' => false,
462
- 'show_in_rest' => true, // Otherwise previews won't be generated in full page view.
463
- 'rest_base' => 'template_parts',
464
- 'rest_controller_class' => __NAMESPACE__ . '\REST_Templates_Controller',
465
- 'capability_type' => 'template_part',
466
- 'capabilities' => array(
467
  // You need to be able to edit posts, in order to read templates in their raw form.
468
  'read' => 'edit_posts',
469
  // You need to be able to customize, in order to create templates.
@@ -476,8 +473,8 @@ class WP_Template_Inserter {
476
  'delete_others_posts' => 'edit_theme_options',
477
  'publish_posts' => 'edit_theme_options',
478
  ),
479
- 'map_meta_cap' => true,
480
- 'supports' => array(
481
  'title',
482
  'editor',
483
  'revisions',
431
  register_post_type(
432
  'wp_template_part', // phpcs:ignore WordPress.NamingConventions.ValidPostTypeSlug.ReservedPrefix
433
  array(
434
+ 'labels' => array(
435
  'name' => _x( 'Template Parts', 'post type general name', 'full-site-editing' ),
436
  'singular_name' => _x( 'Template Part', 'post type singular name', 'full-site-editing' ),
437
  'menu_name' => _x( 'Template Parts', 'admin menu', 'full-site-editing' ),
454
  'item_scheduled' => __( 'Template part scheduled.', 'full-site-editing' ),
455
  'item_updated' => __( 'Template part updated.', 'full-site-editing' ),
456
  ),
457
+ 'menu_icon' => 'dashicons-layout',
458
+ 'public' => false,
459
+ 'show_ui' => true, // Otherwise we'd get permission error when trying to edit them.
460
+ 'show_in_menu' => false,
461
+ 'rewrite' => false,
462
+ 'capability_type' => 'template_part',
463
+ 'capabilities' => array(
 
 
 
464
  // You need to be able to edit posts, in order to read templates in their raw form.
465
  'read' => 'edit_posts',
466
  // You need to be able to customize, in order to create templates.
473
  'delete_others_posts' => 'edit_theme_options',
474
  'publish_posts' => 'edit_theme_options',
475
  ),
476
+ 'map_meta_cap' => true,
477
+ 'supports' => array(
478
  'title',
479
  'editor',
480
  'revisions',
full-site-editing-plugin.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Plugin Name: WordPress.com Editing Toolkit
4
  * Description: Enhances your page creation workflow within the Block Editor.
5
- * Version: 3.27812
6
  * Author: Automattic
7
  * Author URI: https://automattic.com/wordpress-plugins/
8
  * License: GPLv2 or later
@@ -42,7 +42,7 @@ namespace A8C\FSE;
42
  *
43
  * @var string
44
  */
45
- define( 'A8C_ETK_PLUGIN_VERSION', '3.27812' );
46
 
47
  // Always include these helper files for dotcom FSE.
48
  require_once __DIR__ . '/dotcom-fse/helpers.php';
2
  /**
3
  * Plugin Name: WordPress.com Editing Toolkit
4
  * Description: Enhances your page creation workflow within the Block Editor.
5
+ * Version: 3.28276
6
  * Author: Automattic
7
  * Author URI: https://automattic.com/wordpress-plugins/
8
  * License: GPLv2 or later
42
  *
43
  * @var string
44
  */
45
+ define( 'A8C_ETK_PLUGIN_VERSION', '3.28276' );
46
 
47
  // Always include these helper files for dotcom FSE.
48
  require_once __DIR__ . '/dotcom-fse/helpers.php';
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: automattic
3
  Tags: block, blocks, editor, gutenberg, page
4
  Requires at least: 5.5
5
  Tested up to: 5.6
6
- Stable tag: 3.27812
7
  Requires PHP: 5.6.20
8
  License: GPLv2 or later
9
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
3
  Tags: block, blocks, editor, gutenberg, page
4
  Requires at least: 5.5
5
  Tested up to: 5.6
6
+ Stable tag: 3.28276
7
  Requires PHP: 5.6.20
8
  License: GPLv2 or later
9
  License URI: https://www.gnu.org/licenses/gpl-2.0.html