Full Site Editing - Version 0.6.1

Version Description

  • Updates priority of filter so classnames are added properly to the template blocks.
Download this release

Release Info

Developer gwwar
Plugin Icon wp plugin Full Site Editing
Version 0.6.1
Comparing to
See all releases

Code changes from version 0.4 to 0.6.1

Files changed (44) hide show
  1. full-site-editing-plugin.php +32 -13
  2. full-site-editing/blocks/navigation-menu/index.php +37 -23
  3. full-site-editing/blocks/post-content/edit.js +4 -62
  4. full-site-editing/blocks/post-content/index.js +24 -3
  5. full-site-editing/blocks/post-content/index.php +3 -10
  6. full-site-editing/blocks/post-content/save.js +1 -4
  7. full-site-editing/blocks/post-content/style.scss +31 -0
  8. full-site-editing/blocks/site-description/edit.js +26 -4
  9. full-site-editing/blocks/site-description/index.php +3 -1
  10. full-site-editing/blocks/site-title/edit.js +26 -4
  11. full-site-editing/blocks/site-title/index.php +3 -1
  12. full-site-editing/blocks/template/edit.js +64 -22
  13. full-site-editing/blocks/template/index.js +30 -5
  14. full-site-editing/blocks/template/index.php +5 -3
  15. full-site-editing/blocks/template/site-logo.js +18 -0
  16. full-site-editing/blocks/template/style.scss +60 -8
  17. full-site-editing/class-full-site-editing.php +248 -350
  18. full-site-editing/dist/full-site-editing.css +1 -1
  19. full-site-editing/dist/full-site-editing.deps.json +1 -1
  20. full-site-editing/dist/full-site-editing.js +2 -2
  21. full-site-editing/dist/full-site-editing.rtl.css +1 -1
  22. full-site-editing/editor/image-block-keywords/index.js +23 -0
  23. full-site-editing/editor/index.js +2 -0
  24. full-site-editing/editor/style.scss +61 -0
  25. full-site-editing/editor/template-validity-override/index.js +0 -2
  26. full-site-editing/index.js +2 -3
  27. full-site-editing/plugins/close-button-override/index.js +22 -11
  28. full-site-editing/plugins/close-button-override/style.scss +13 -0
  29. full-site-editing/plugins/editor-template-classes/index.js +51 -0
  30. full-site-editing/plugins/template-update-notice/index.js +20 -0
  31. full-site-editing/serialize-block-fallback.php +70 -0
  32. full-site-editing/templates/class-rest-templates-controller.php +49 -0
  33. full-site-editing/templates/class-wp-template-inserter.php +388 -0
  34. full-site-editing/templates/class-wp-template.php +182 -0
  35. posts-list-block/class-posts-list-block.php +7 -5
  36. posts-list-block/dist/posts-list-block.deps.json +1 -1
  37. posts-list-block/dist/posts-list-block.js +1 -1
  38. posts-list-block/templates/no-posts.php +1 -1
  39. posts-list-block/templates/posts-list.php +1 -1
  40. posts-list-block/utils.php +33 -33
  41. readme.txt +11 -1
  42. starter-page-templates/class-starter-page-templates.php +5 -3
  43. starter-page-templates/dist/starter-page-templates.deps.json +1 -1
  44. starter-page-templates/dist/starter-page-templates.js +2 -2
full-site-editing-plugin.php CHANGED
@@ -2,15 +2,17 @@
2
  /**
3
  * Plugin Name: Full Site Editing
4
  * Description: Enhances your page creation workflow within the Block Editor.
5
- * Version: 0.4
6
  * Author: Automattic
7
  * Author URI: https://automattic.com/wordpress-plugins/
8
  * License: GPLv2 or later
9
  * Text Domain: full-site-editing
10
  *
11
- * @package full-site-editing
12
  */
13
 
 
 
14
  /**
15
  * Plugin version.
16
  *
@@ -18,12 +20,12 @@
18
  *
19
  * @var string
20
  */
21
- define( 'A8C_FSE_VERSION', '0.4' );
22
 
23
  /**
24
  * Load Full Site Editing.
25
  */
26
- function a8c_load_full_site_editing() {
27
  /**
28
  * Can be used to disable Full Site Editing functionality.
29
  *
@@ -35,25 +37,25 @@ function a8c_load_full_site_editing() {
35
  return;
36
  }
37
 
38
- require_once __DIR__ . '/lib/feature-flags/class-a8c-full-site-editing-feature-flags.php';
39
  require_once __DIR__ . '/full-site-editing/blocks/navigation-menu/index.php';
40
  require_once __DIR__ . '/full-site-editing/blocks/post-content/index.php';
41
  require_once __DIR__ . '/full-site-editing/blocks/site-description/index.php';
42
  require_once __DIR__ . '/full-site-editing/blocks/site-title/index.php';
43
  require_once __DIR__ . '/full-site-editing/blocks/template/index.php';
44
- require_once __DIR__ . '/full-site-editing/blocks/site-logo/index.php';
45
- require_once __DIR__ . '/full-site-editing/class-a8c-rest-templates-controller.php';
46
  require_once __DIR__ . '/full-site-editing/class-full-site-editing.php';
47
- require_once __DIR__ . '/full-site-editing/utils/class-a8c-wp-template.php';
 
 
 
48
 
49
  Full_Site_Editing::get_instance();
50
  }
51
- add_action( 'plugins_loaded', 'a8c_load_full_site_editing' );
52
 
53
  /**
54
  * Load Posts List Block.
55
  */
56
- function a8c_load_posts_list_block() {
57
  if ( class_exists( 'Posts_List_Block' ) ) {
58
  return;
59
  }
@@ -74,12 +76,12 @@ function a8c_load_posts_list_block() {
74
 
75
  Posts_List_Block::get_instance();
76
  }
77
- add_action( 'plugins_loaded', 'a8c_load_posts_list_block' );
78
 
79
  /**
80
  * Load Starter_Page_Templates.
81
  */
82
- function a8c_load_starter_page_templates() {
83
  /**
84
  * Can be used to disable the Starter Page Templates.
85
  *
@@ -95,4 +97,21 @@ function a8c_load_starter_page_templates() {
95
 
96
  Starter_Page_Templates::get_instance();
97
  }
98
- add_action( 'plugins_loaded', 'a8c_load_starter_page_templates' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  /**
3
  * Plugin Name: Full Site Editing
4
  * Description: Enhances your page creation workflow within the Block Editor.
5
+ * Version: 0.6.1
6
  * Author: Automattic
7
  * Author URI: https://automattic.com/wordpress-plugins/
8
  * License: GPLv2 or later
9
  * Text Domain: full-site-editing
10
  *
11
+ * @package A8C\FSE
12
  */
13
 
14
+ namespace A8C\FSE;
15
+
16
  /**
17
  * Plugin version.
18
  *
20
  *
21
  * @var string
22
  */
23
+ define( 'PLUGIN_VERSION', '0.6.1' );
24
 
25
  /**
26
  * Load Full Site Editing.
27
  */
28
+ function load_full_site_editing() {
29
  /**
30
  * Can be used to disable Full Site Editing functionality.
31
  *
37
  return;
38
  }
39
 
 
40
  require_once __DIR__ . '/full-site-editing/blocks/navigation-menu/index.php';
41
  require_once __DIR__ . '/full-site-editing/blocks/post-content/index.php';
42
  require_once __DIR__ . '/full-site-editing/blocks/site-description/index.php';
43
  require_once __DIR__ . '/full-site-editing/blocks/site-title/index.php';
44
  require_once __DIR__ . '/full-site-editing/blocks/template/index.php';
 
 
45
  require_once __DIR__ . '/full-site-editing/class-full-site-editing.php';
46
+ require_once __DIR__ . '/full-site-editing/templates/class-rest-templates-controller.php';
47
+ require_once __DIR__ . '/full-site-editing/templates/class-wp-template.php';
48
+ require_once __DIR__ . '/full-site-editing/templates/class-wp-template-inserter.php';
49
+ require_once __DIR__ . '/full-site-editing/serialize-block-fallback.php';
50
 
51
  Full_Site_Editing::get_instance();
52
  }
53
+ add_action( 'plugins_loaded', __NAMESPACE__ . '\load_full_site_editing' );
54
 
55
  /**
56
  * Load Posts List Block.
57
  */
58
+ function load_posts_list_block() {
59
  if ( class_exists( 'Posts_List_Block' ) ) {
60
  return;
61
  }
76
 
77
  Posts_List_Block::get_instance();
78
  }
79
+ add_action( 'plugins_loaded', __NAMESPACE__ . '\load_posts_list_block' );
80
 
81
  /**
82
  * Load Starter_Page_Templates.
83
  */
84
+ function load_starter_page_templates() {
85
  /**
86
  * Can be used to disable the Starter Page Templates.
87
  *
97
 
98
  Starter_Page_Templates::get_instance();
99
  }
100
+ add_action( 'plugins_loaded', __NAMESPACE__ . '\load_starter_page_templates' );
101
+
102
+ /**
103
+ * Inserts default full site editing data for current theme during plugin activation.
104
+ *
105
+ * We usually perform this on theme activation hook, but this is needed to handle
106
+ * the cases in which FSE supported theme was activated prior to the plugin. This will
107
+ * populate the default header and footer for current theme, and create About and Contact
108
+ * pages provided that they don't already exist.
109
+ */
110
+ function populate_wp_template_data() {
111
+ require_once __DIR__ . '/full-site-editing/class-full-site-editing.php';
112
+ require_once __DIR__ . '/full-site-editing/templates/class-wp-template-inserter.php';
113
+
114
+ $fse = Full_Site_Editing::get_instance();
115
+ $fse->insert_default_data();
116
+ }
117
+ register_activation_hook( __FILE__, __NAMESPACE__ . '\populate_wp_template_data' );
full-site-editing/blocks/navigation-menu/index.php CHANGED
@@ -1,26 +1,38 @@
1
  <?php
2
  /**
3
- * Render navigation menus.
4
  *
5
- * @package full-site-editing
6
  */
7
- function a8c_fse_render_navigation_menu_block( $attributes ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  ob_start();
9
- // phpcs:disable WordPress.WP.I18n.NonSingularStringLiteralText
10
  ?>
11
  <nav class="main-navigation wp-block-a8c-navigation-menu">
12
  <div class="menu-nav-container">
13
- <?php
14
- echo wp_nav_menu([
15
- 'theme_location' => 'menu-1',
16
- 'menu_class' => 'main-menu',
17
- 'fallback_cb' => 'a8c_fse_get_fallback_navigation_menu'
18
- ]);
19
- ?>
20
  </div>
21
  </nav>
22
  <!-- #site-navigation -->
23
  <?php
 
24
  return ob_get_clean();
25
  }
26
 
@@ -28,25 +40,27 @@ function a8c_fse_render_navigation_menu_block( $attributes ) {
28
  * Render a list of all site pages as a fallback
29
  * for when a menu does not exist.
30
  *
31
- * @package full-site-editing
32
  */
33
- function a8c_fse_get_fallback_navigation_menu() {
34
- $menu = wp_page_menu([
35
- 'echo' => 0,
36
- 'sort_column' => 'post_date',
37
- 'container' => 'ul',
38
- 'menu_class' => 'main-menu default-menu',
39
- 'before' => false,
40
- 'after' => false
41
- ]);
 
 
42
 
43
  /**
44
  * Filter the fallback page menu to use the same
45
  * CSS class structure as a regularly built menu
46
  * so we don't have to duplicate CSS selectors everywhere.
47
  */
48
- $original_classes = [ 'children', 'page_item_has_sub-menu' ];
49
  $replacement_classes = [ 'sub-menu', 'menu-item-has-children' ];
50
 
51
  return str_replace( $original_classes, $replacement_classes, $menu );
52
- }
1
  <?php
2
  /**
3
+ * Render navigation menu block file.
4
  *
5
+ * @package A8C\FSE
6
  */
7
+
8
+ namespace A8C\FSE;
9
+
10
+ /**
11
+ * Render the navigation menu.
12
+ *
13
+ * @return string
14
+ */
15
+ function render_navigation_menu_block() {
16
+ $menu = wp_nav_menu(
17
+ [
18
+ 'echo' => false,
19
+ 'menu_class' => 'main-menu',
20
+ 'fallback_cb' => 'a8c_fse_get_fallback_navigation_menu',
21
+ 'theme_location' => 'menu-1',
22
+ ]
23
+ );
24
+
25
  ob_start();
26
+ // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped
27
  ?>
28
  <nav class="main-navigation wp-block-a8c-navigation-menu">
29
  <div class="menu-nav-container">
30
+ <?php echo $menu ? $menu : get_fallback_navigation_menu(); ?>
 
 
 
 
 
 
31
  </div>
32
  </nav>
33
  <!-- #site-navigation -->
34
  <?php
35
+ // phpcs:enable WordPress.Security.EscapeOutput.OutputNotEscaped
36
  return ob_get_clean();
37
  }
38
 
40
  * Render a list of all site pages as a fallback
41
  * for when a menu does not exist.
42
  *
43
+ * @return string
44
  */
45
+ function get_fallback_navigation_menu() {
46
+ $menu = wp_page_menu(
47
+ [
48
+ 'after' => false,
49
+ 'before' => false,
50
+ 'container' => 'ul',
51
+ 'echo' => false,
52
+ 'menu_class' => 'main-menu default-menu',
53
+ 'sort_column' => 'post_date',
54
+ ]
55
+ );
56
 
57
  /**
58
  * Filter the fallback page menu to use the same
59
  * CSS class structure as a regularly built menu
60
  * so we don't have to duplicate CSS selectors everywhere.
61
  */
62
+ $original_classes = [ 'children', 'page_item_has_sub-menu' ];
63
  $replacement_classes = [ 'sub-menu', 'menu-item-has-children' ];
64
 
65
  return str_replace( $original_classes, $replacement_classes, $menu );
66
+ }
full-site-editing/blocks/post-content/edit.js CHANGED
@@ -1,26 +1,17 @@
1
  /* eslint-disable wpcalypso/jsx-classname-namespace */
2
- /* global fullSiteEditing */
3
 
4
  /**
5
  * External dependencies
6
  */
7
  import classNames from 'classnames';
8
- import { get } from 'lodash';
9
 
10
  /**
11
  * WordPress dependencies
12
  */
13
- import { IconButton, Placeholder, Toolbar } from '@wordpress/components';
14
  import { compose, withState } from '@wordpress/compose';
15
  import { withSelect } from '@wordpress/data';
16
- import { BlockControls, InnerBlocks, PostTitle } from '@wordpress/editor';
17
- import { Component, Fragment, RawHTML } from '@wordpress/element';
18
- import { __, sprintf } from '@wordpress/i18n';
19
-
20
- /**
21
- * Internal dependencies
22
- */
23
- import PostAutocomplete from '../../components/post-autocomplete';
24
 
25
  class PostContentEdit extends Component {
26
  toggleEditing() {
@@ -37,67 +28,18 @@ class PostContentEdit extends Component {
37
  }
38
 
39
  render() {
40
- const { attributes, isEditing, selectedPost } = this.props;
41
  const { align } = attributes;
42
 
43
- const isTemplatePostType = 'wp_template' === fullSiteEditing.editorPostType;
44
- const showToggleButton = isTemplatePostType && ( ! isEditing || !! selectedPost );
45
- const showPlaceholder = isTemplatePostType && ( isEditing || ! selectedPost );
46
- const showPreview = isTemplatePostType && ! isEditing && !! selectedPost;
47
- const showInnerBlocks = ! isTemplatePostType;
48
-
49
  return (
50
  <Fragment>
51
- { showToggleButton && (
52
- <BlockControls>
53
- <Toolbar>
54
- <IconButton
55
- className={ classNames( 'components-icon-button components-toolbar__control', {
56
- 'is-active': isEditing,
57
- } ) }
58
- label={ __( 'Change Preview' ) }
59
- onClick={ this.toggleEditing }
60
- icon="edit"
61
- />
62
- </Toolbar>
63
- </BlockControls>
64
- ) }
65
  <div
66
  className={ classNames( 'post-content-block', {
67
  [ `align${ align }` ]: align,
68
  } ) }
69
  >
70
  <PostTitle />
71
- { showInnerBlocks && <InnerBlocks templateLock={ false } /> }
72
- { showPlaceholder && (
73
- <Placeholder
74
- icon="layout"
75
- label={ __( 'Content Slot' ) }
76
- instructions={ __( 'Placeholder for a post or a page.' ) }
77
- >
78
- <div className="post-content-block__selector">
79
- <div>{ __( 'Select something to preview:' ) }</div>
80
- <PostAutocomplete
81
- initialValue={ get( selectedPost, [ 'title', 'rendered' ] ) }
82
- onSelectPost={ this.onSelectPost }
83
- postType={ [ 'page', 'post' ] }
84
- />
85
- { !! selectedPost && (
86
- <a href={ `?post=${ selectedPost.id }&action=edit` }>
87
- { sprintf(
88
- __( 'Edit "%s"' ),
89
- get( selectedPost, [ 'title', 'rendered' ], '' )
90
- ) }
91
- </a>
92
- ) }
93
- </div>
94
- </Placeholder>
95
- ) }
96
- { showPreview && (
97
- <RawHTML className="post-content-block__preview">
98
- { get( selectedPost, [ 'content', 'rendered' ] ) }
99
- </RawHTML>
100
- ) }
101
  </div>
102
  </Fragment>
103
  );
1
  /* eslint-disable wpcalypso/jsx-classname-namespace */
 
2
 
3
  /**
4
  * External dependencies
5
  */
6
  import classNames from 'classnames';
 
7
 
8
  /**
9
  * WordPress dependencies
10
  */
 
11
  import { compose, withState } from '@wordpress/compose';
12
  import { withSelect } from '@wordpress/data';
13
+ import { InnerBlocks, PostTitle } from '@wordpress/editor';
14
+ import { Component, Fragment } from '@wordpress/element';
 
 
 
 
 
 
15
 
16
  class PostContentEdit extends Component {
17
  toggleEditing() {
28
  }
29
 
30
  render() {
31
+ const { attributes } = this.props;
32
  const { align } = attributes;
33
 
 
 
 
 
 
 
34
  return (
35
  <Fragment>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  <div
37
  className={ classNames( 'post-content-block', {
38
  [ `align${ align }` ]: align,
39
  } ) }
40
  >
41
  <PostTitle />
42
+ <InnerBlocks templateLock={ false } />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  </div>
44
  </Fragment>
45
  );
full-site-editing/blocks/post-content/index.js CHANGED
@@ -1,8 +1,10 @@
1
  /**
2
  * External dependencies
3
  */
 
4
  import { registerBlockType } from '@wordpress/blocks';
5
  import { __ } from '@wordpress/i18n';
 
6
 
7
  /**
8
  * Internal dependencies
@@ -12,12 +14,13 @@ import save from './save';
12
  import './style.scss';
13
 
14
  registerBlockType( 'a8c/post-content', {
15
- title: __( 'Content Slot' ),
16
- description: __( 'Placeholder for a post or a page.' ),
17
  icon: 'layout',
18
  category: 'layout',
19
  supports: {
20
- anchor: true,
 
21
  html: false,
22
  multiple: false,
23
  reusable: false,
@@ -25,3 +28,21 @@ registerBlockType( 'a8c/post-content', {
25
  edit,
26
  save,
27
  } );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  /**
2
  * External dependencies
3
  */
4
+ import { createHigherOrderComponent } from '@wordpress/compose';
5
  import { registerBlockType } from '@wordpress/blocks';
6
  import { __ } from '@wordpress/i18n';
7
+ import { addFilter } from '@wordpress/hooks';
8
 
9
  /**
10
  * Internal dependencies
14
  import './style.scss';
15
 
16
  registerBlockType( 'a8c/post-content', {
17
+ title: __( 'Content' ),
18
+ description: __( 'The page content.' ),
19
  icon: 'layout',
20
  category: 'layout',
21
  supports: {
22
+ anchor: false,
23
+ customClassName: false,
24
  html: false,
25
  multiple: false,
26
  reusable: false,
28
  edit,
29
  save,
30
  } );
31
+
32
+ const addContentSlotClassname = createHigherOrderComponent( BlockListBlock => {
33
+ return props => {
34
+ if ( props.name !== 'a8c/post-content' ) {
35
+ return <BlockListBlock { ...props } />;
36
+ }
37
+
38
+ return <BlockListBlock { ...props } className={ 'post-content__block' } />;
39
+ };
40
+ }, 'addContentSlotClassname' );
41
+
42
+ // Must be 9 or this breaks on Simple Sites
43
+ addFilter(
44
+ 'editor.BlockListBlock',
45
+ 'full-site-editing/blocks/post-content',
46
+ addContentSlotClassname,
47
+ 9
48
+ );
full-site-editing/blocks/post-content/index.php CHANGED
@@ -2,9 +2,11 @@
2
  /**
3
  * Render post content block file.
4
  *
5
- * @package full-site-editing
6
  */
7
 
 
 
8
  /**
9
  * Renders post content.
10
  *
@@ -18,15 +20,6 @@ function render_post_content_block( $attributes, $content ) {
18
  return $content;
19
  }
20
 
21
- $post_id = get_the_ID();
22
- $post_type = get_post_type();
23
- $template_id = get_post_meta( $post_id, '_wp_template_id', true );
24
-
25
- // Early return to avoid the infinite loop of a template rendering itself.
26
- if ( 'wp_template' === $post_type || $template_id === $post_id ) {
27
- return $content;
28
- }
29
-
30
  $align = isset( $attributes['align'] ) ? ' align' . $attributes['align'] : '';
31
 
32
  ob_start();
2
  /**
3
  * Render post content block file.
4
  *
5
+ * @package A8C\FSE
6
  */
7
 
8
+ namespace A8C\FSE;
9
+
10
  /**
11
  * Renders post content.
12
  *
20
  return $content;
21
  }
22
 
 
 
 
 
 
 
 
 
 
23
  $align = isset( $attributes['align'] ) ? ' align' . $attributes['align'] : '';
24
 
25
  ob_start();
full-site-editing/blocks/post-content/save.js CHANGED
@@ -1,9 +1,6 @@
1
- /* global fullSiteEditing */
2
-
3
  /**
4
  * External dependencies
5
  */
6
  import { InnerBlocks } from '@wordpress/editor';
7
 
8
- const isTemplatePostType = 'wp_template' === fullSiteEditing.editorPostType;
9
- export default ( isTemplatePostType ? () => null : () => <InnerBlocks.Content /> );
 
 
1
  /**
2
  * External dependencies
3
  */
4
  import { InnerBlocks } from '@wordpress/editor';
5
 
6
+ export default () => <InnerBlocks.Content />;
 
full-site-editing/blocks/post-content/style.scss CHANGED
@@ -33,3 +33,34 @@
33
  display: block;
34
  }
35
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  display: block;
34
  }
35
  }
36
+
37
+ /* Hide the content slot block UI */
38
+ .block-editor-block-list__layout {
39
+ .post-content__block {
40
+ &.is-selected {
41
+ .block-editor-block-contextual-toolbar {
42
+ display: none;
43
+ }
44
+ }
45
+
46
+ &.block-editor-block-list__block {
47
+ // Need to get super specific to override the core css selectors:
48
+ &,
49
+ &.has-child-selected,
50
+ &.is-navigate-mode,
51
+ &.is-hovered {
52
+ > .block-editor-block-list__block-edit {
53
+ &::before {
54
+ transition: none;
55
+ border: none;
56
+ outline: none;
57
+ box-shadow: none;
58
+ }
59
+ > .block-editor-block-list__breadcrumb {
60
+ display: none;
61
+ }
62
+ }
63
+ }
64
+ }
65
+ }
66
+ }
full-site-editing/blocks/site-description/edit.js CHANGED
@@ -6,6 +6,7 @@ import { compose } from '@wordpress/compose';
6
  import { withSelect, withDispatch } from '@wordpress/data';
7
  import { Fragment } from '@wordpress/element';
8
  import { __ } from '@wordpress/i18n';
 
9
 
10
  /**
11
  * Internal dependencies
@@ -18,6 +19,8 @@ function SiteDescriptionEdit( {
18
  shouldUpdateSiteOption,
19
  isSelected,
20
  setAttributes,
 
 
21
  } ) {
22
  const inititalDescription = __( 'Site description loading…' );
23
 
@@ -32,12 +35,23 @@ function SiteDescriptionEdit( {
32
 
33
  const { option } = siteOptions;
34
 
 
 
 
 
 
 
 
 
 
 
35
  return (
36
  <Fragment>
37
  <PlainText
38
  className={ className }
39
  value={ option }
40
  onChange={ value => handleChange( value ) }
 
41
  placeholder={ __( 'Site Description' ) }
42
  aria-label={ __( 'Site Description' ) }
43
  />
@@ -46,17 +60,25 @@ function SiteDescriptionEdit( {
46
  }
47
 
48
  export default compose( [
49
- withDispatch( dispatch => ( {
50
- createErrorNotice: dispatch( 'core/notices' ).createErrorNotice,
51
- } ) ),
52
- withSelect( select => {
53
  const { isSavingPost, isPublishingPost, isAutosavingPost, isCurrentPostPublished } = select(
54
  'core/editor'
55
  );
 
 
 
56
  return {
 
 
 
57
  shouldUpdateSiteOption:
58
  ( ( isSavingPost() && isCurrentPostPublished() ) || isPublishingPost() ) &&
59
  ! isAutosavingPost(),
60
  };
61
  } ),
 
 
 
 
 
62
  ] )( SiteDescriptionEdit );
6
  import { withSelect, withDispatch } from '@wordpress/data';
7
  import { Fragment } from '@wordpress/element';
8
  import { __ } from '@wordpress/i18n';
9
+ import { ENTER } from '@wordpress/keycodes';
10
 
11
  /**
12
  * Internal dependencies
19
  shouldUpdateSiteOption,
20
  isSelected,
21
  setAttributes,
22
+ isLocked,
23
+ insertDefaultBlock,
24
  } ) {
25
  const inititalDescription = __( 'Site description loading…' );
26
 
35
 
36
  const { option } = siteOptions;
37
 
38
+ const onKeyDown = event => {
39
+ if ( event.keyCode !== ENTER ) {
40
+ return;
41
+ }
42
+ event.preventDefault();
43
+ if ( ! isLocked ) {
44
+ insertDefaultBlock();
45
+ }
46
+ };
47
+
48
  return (
49
  <Fragment>
50
  <PlainText
51
  className={ className }
52
  value={ option }
53
  onChange={ value => handleChange( value ) }
54
+ onKeyDown={ onKeyDown }
55
  placeholder={ __( 'Site Description' ) }
56
  aria-label={ __( 'Site Description' ) }
57
  />
60
  }
61
 
62
  export default compose( [
63
+ withSelect( ( select, { clientId } ) => {
 
 
 
64
  const { isSavingPost, isPublishingPost, isAutosavingPost, isCurrentPostPublished } = select(
65
  'core/editor'
66
  );
67
+ const { getBlockIndex, getBlockRootClientId, getTemplateLock } = select( 'core/block-editor' );
68
+ const rootClientId = getBlockRootClientId( clientId );
69
+
70
  return {
71
+ blockIndex: getBlockIndex( clientId, rootClientId ),
72
+ isLocked: !! getTemplateLock( rootClientId ),
73
+ rootClientId,
74
  shouldUpdateSiteOption:
75
  ( ( isSavingPost() && isCurrentPostPublished() ) || isPublishingPost() ) &&
76
  ! isAutosavingPost(),
77
  };
78
  } ),
79
+ withDispatch( ( dispatch, { blockIndex, rootClientId } ) => ( {
80
+ createErrorNotice: dispatch( 'core/notices' ).createErrorNotice,
81
+ insertDefaultBlock: () =>
82
+ dispatch( 'core/block-editor' ).insertDefaultBlock( {}, rootClientId, blockIndex + 1 ),
83
+ } ) ),
84
  ] )( SiteDescriptionEdit );
full-site-editing/blocks/site-description/index.php CHANGED
@@ -2,9 +2,11 @@
2
  /**
3
  * Render site description file.
4
  *
5
- * @package full-site-editing
6
  */
7
 
 
 
8
  /**
9
  * Renders the site description (tagline) block.
10
  *
2
  /**
3
  * Render site description file.
4
  *
5
+ * @package A8C\FSE
6
  */
7
 
8
+ namespace A8C\FSE;
9
+
10
  /**
11
  * Renders the site description (tagline) block.
12
  *
full-site-editing/blocks/site-title/edit.js CHANGED
@@ -11,6 +11,7 @@ import { PlainText } from '@wordpress/editor';
11
  import { withSelect, withDispatch } from '@wordpress/data';
12
  import { compose } from '@wordpress/compose';
13
  import { Fragment } from '@wordpress/element';
 
14
 
15
  /**
16
  * Internal dependencies
@@ -23,6 +24,8 @@ function SiteTitleEdit( {
23
  shouldUpdateSiteOption,
24
  isSelected,
25
  setAttributes,
 
 
26
  } ) {
27
  const inititalTitle = __( 'Site title loading…' );
28
  const { siteOptions, handleChange } = useSiteOptions(
@@ -36,12 +39,23 @@ function SiteTitleEdit( {
36
 
37
  const { option } = siteOptions;
38
 
 
 
 
 
 
 
 
 
 
 
39
  return (
40
  <Fragment>
41
  <PlainText
42
  className={ classNames( 'site-title', className ) }
43
  value={ option }
44
  onChange={ value => handleChange( value ) }
 
45
  placeholder={ __( 'Site Title' ) }
46
  aria-label={ __( 'Site Title' ) }
47
  />
@@ -50,17 +64,25 @@ function SiteTitleEdit( {
50
  }
51
 
52
  export default compose( [
53
- withDispatch( dispatch => ( {
54
- createErrorNotice: dispatch( 'core/notices' ).createErrorNotice,
55
- } ) ),
56
- withSelect( select => {
57
  const { isSavingPost, isPublishingPost, isAutosavingPost, isCurrentPostPublished } = select(
58
  'core/editor'
59
  );
 
 
 
60
  return {
 
 
 
61
  shouldUpdateSiteOption:
62
  ( ( isSavingPost() && isCurrentPostPublished() ) || isPublishingPost() ) &&
63
  ! isAutosavingPost(),
64
  };
65
  } ),
 
 
 
 
 
66
  ] )( SiteTitleEdit );
11
  import { withSelect, withDispatch } from '@wordpress/data';
12
  import { compose } from '@wordpress/compose';
13
  import { Fragment } from '@wordpress/element';
14
+ import { ENTER } from '@wordpress/keycodes';
15
 
16
  /**
17
  * Internal dependencies
24
  shouldUpdateSiteOption,
25
  isSelected,
26
  setAttributes,
27
+ isLocked,
28
+ insertDefaultBlock,
29
  } ) {
30
  const inititalTitle = __( 'Site title loading…' );
31
  const { siteOptions, handleChange } = useSiteOptions(
39
 
40
  const { option } = siteOptions;
41
 
42
+ const onKeyDown = event => {
43
+ if ( event.keyCode !== ENTER ) {
44
+ return;
45
+ }
46
+ event.preventDefault();
47
+ if ( ! isLocked ) {
48
+ insertDefaultBlock();
49
+ }
50
+ };
51
+
52
  return (
53
  <Fragment>
54
  <PlainText
55
  className={ classNames( 'site-title', className ) }
56
  value={ option }
57
  onChange={ value => handleChange( value ) }
58
+ onKeyDown={ onKeyDown }
59
  placeholder={ __( 'Site Title' ) }
60
  aria-label={ __( 'Site Title' ) }
61
  />
64
  }
65
 
66
  export default compose( [
67
+ withSelect( ( select, { clientId } ) => {
 
 
 
68
  const { isSavingPost, isPublishingPost, isAutosavingPost, isCurrentPostPublished } = select(
69
  'core/editor'
70
  );
71
+ const { getBlockIndex, getBlockRootClientId, getTemplateLock } = select( 'core/block-editor' );
72
+ const rootClientId = getBlockRootClientId( clientId );
73
+
74
  return {
75
+ blockIndex: getBlockIndex( clientId, rootClientId ),
76
+ isLocked: !! getTemplateLock( rootClientId ),
77
+ rootClientId,
78
  shouldUpdateSiteOption:
79
  ( ( isSavingPost() && isCurrentPostPublished() ) || isPublishingPost() ) &&
80
  ! isAutosavingPost(),
81
  };
82
  } ),
83
+ withDispatch( ( dispatch, { blockIndex, rootClientId } ) => ( {
84
+ createErrorNotice: dispatch( 'core/notices' ).createErrorNotice,
85
+ insertDefaultBlock: () =>
86
+ dispatch( 'core/block-editor' ).insertDefaultBlock( {}, rootClientId, blockIndex + 1 ),
87
+ } ) ),
88
  ] )( SiteTitleEdit );
full-site-editing/blocks/site-title/index.php CHANGED
@@ -2,9 +2,11 @@
2
  /**
3
  * Render site title block.
4
  *
5
- * @package full-site-editing
6
  */
7
 
 
 
8
  /**
9
  * Renders the site title and allows for editing in the full site editor.
10
  *
2
  /**
3
  * Render site title block.
4
  *
5
+ * @package A8C\FSE
6
  */
7
 
8
+ namespace A8C\FSE;
9
+
10
  /**
11
  * Renders the site title and allows for editing in the full site editor.
12
  *
full-site-editing/blocks/template/edit.js CHANGED
@@ -14,7 +14,7 @@ import { BlockEdit } from '@wordpress/editor';
14
  import { Button, Placeholder, Spinner, Disabled } from '@wordpress/components';
15
  import { compose, withState } from '@wordpress/compose';
16
  import { withDispatch, withSelect } from '@wordpress/data';
17
- import { Fragment, useEffect } from '@wordpress/element';
18
  import { __, sprintf } from '@wordpress/i18n';
19
  import { addQueryArgs } from '@wordpress/url';
20
 
@@ -24,33 +24,37 @@ import { addQueryArgs } from '@wordpress/url';
24
  import './style.scss';
25
 
26
  const TemplateEdit = compose(
27
- withState( { templateClientId: null } ),
28
  withSelect( ( select, { attributes, templateClientId } ) => {
29
  const { getEntityRecord } = select( 'core' );
30
- const { getCurrentPostId } = select( 'core/editor' );
31
  const { getBlock } = select( 'core/block-editor' );
32
-
33
  const { templateId } = attributes;
34
  const currentPostId = getCurrentPostId();
35
- const template = templateId && getEntityRecord( 'postType', 'wp_template_part', templateId );
36
- const editTemplatePartUrl = addQueryArgs( fullSiteEditing.editTemplatePartBaseUrl, {
37
  post: templateId,
38
  fse_parent_post: currentPostId,
39
  } );
40
 
41
  return {
42
  currentPostId,
43
- editTemplatePartUrl,
44
  template,
45
  templateBlock: getBlock( templateClientId ),
46
  templateTitle: get( template, [ 'title', 'rendered' ], '' ),
 
 
47
  };
48
  } ),
49
  withDispatch( ( dispatch, ownProps ) => {
50
  const { receiveBlocks } = dispatch( 'core/block-editor' );
 
 
51
  const { template, templateClientId, setState } = ownProps;
52
-
53
  return {
 
54
  receiveTemplateBlocks: () => {
55
  if ( ! template || templateClientId ) {
56
  return;
@@ -65,16 +69,26 @@ const TemplateEdit = compose(
65
  receiveBlocks( [ templateBlock ] );
66
  setState( { templateClientId: templateBlock.clientId } );
67
  },
 
 
68
  };
69
  } )
70
  )(
71
  ( {
72
  attributes,
73
- editTemplatePartUrl,
74
  receiveTemplateBlocks,
75
  template,
76
  templateBlock,
77
  templateTitle,
 
 
 
 
 
 
 
 
78
  } ) => {
79
  if ( ! template ) {
80
  return (
@@ -83,16 +97,47 @@ const TemplateEdit = compose(
83
  </Placeholder>
84
  );
85
  }
86
-
 
87
  useEffect( () => {
 
 
 
 
 
 
 
88
  receiveTemplateBlocks();
89
  } );
90
 
91
- const { align } = attributes;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
 
93
  return (
94
  <div
95
- className={ classNames( 'template-block', {
96
  [ `align${ align }` ]: align,
97
  } ) }
98
  >
@@ -108,16 +153,13 @@ const TemplateEdit = compose(
108
  setAttributes={ noop }
109
  />
110
  </Disabled>
111
- <Placeholder
112
- className="template-block__overlay"
113
- instructions={ __(
114
- 'This block is part of your site template and may appear on multiple pages.'
115
- ) }
116
- >
117
- <Button href={ editTemplatePartUrl } isDefault>
118
- { sprintf( __( 'Edit %s' ), templateTitle ) }
119
- </Button>
120
- </Placeholder>
121
  </Fragment>
122
  ) }
123
  </div>
14
  import { Button, Placeholder, Spinner, Disabled } from '@wordpress/components';
15
  import { compose, withState } from '@wordpress/compose';
16
  import { withDispatch, withSelect } from '@wordpress/data';
17
+ import { Fragment, useEffect, useState, createRef } from '@wordpress/element';
18
  import { __, sprintf } from '@wordpress/i18n';
19
  import { addQueryArgs } from '@wordpress/url';
20
 
24
  import './style.scss';
25
 
26
  const TemplateEdit = compose(
27
+ withState( { templateClientId: null, shouldCloseSidebarOnSelect: true } ),
28
  withSelect( ( select, { attributes, templateClientId } ) => {
29
  const { getEntityRecord } = select( 'core' );
30
+ const { getCurrentPostId, isEditedPostDirty } = select( 'core/editor' );
31
  const { getBlock } = select( 'core/block-editor' );
32
+ const { isEditorSidebarOpened } = select( 'core/edit-post' );
33
  const { templateId } = attributes;
34
  const currentPostId = getCurrentPostId();
35
+ const template = templateId && getEntityRecord( 'postType', 'wp_template', templateId );
36
+ const editTemplateUrl = addQueryArgs( fullSiteEditing.editTemplateBaseUrl, {
37
  post: templateId,
38
  fse_parent_post: currentPostId,
39
  } );
40
 
41
  return {
42
  currentPostId,
43
+ editTemplateUrl,
44
  template,
45
  templateBlock: getBlock( templateClientId ),
46
  templateTitle: get( template, [ 'title', 'rendered' ], '' ),
47
+ isDirty: isEditedPostDirty(),
48
+ isEditorSidebarOpened: !! isEditorSidebarOpened(),
49
  };
50
  } ),
51
  withDispatch( ( dispatch, ownProps ) => {
52
  const { receiveBlocks } = dispatch( 'core/block-editor' );
53
+ const { closeGeneralSidebar } = dispatch( 'core/edit-post' );
54
+ const { clearSelectedBlock } = dispatch( 'core/editor' );
55
  const { template, templateClientId, setState } = ownProps;
 
56
  return {
57
+ savePost: dispatch( 'core/editor' ).savePost,
58
  receiveTemplateBlocks: () => {
59
  if ( ! template || templateClientId ) {
60
  return;
69
  receiveBlocks( [ templateBlock ] );
70
  setState( { templateClientId: templateBlock.clientId } );
71
  },
72
+ closeGeneralSidebar,
73
+ clearSelectedBlock,
74
  };
75
  } )
76
  )(
77
  ( {
78
  attributes,
79
+ editTemplateUrl,
80
  receiveTemplateBlocks,
81
  template,
82
  templateBlock,
83
  templateTitle,
84
+ isDirty,
85
+ savePost,
86
+ isSelected,
87
+ isEditorSidebarOpened,
88
+ closeGeneralSidebar,
89
+ clearSelectedBlock,
90
+ shouldCloseSidebarOnSelect,
91
+ setState,
92
  } ) => {
93
  if ( ! template ) {
94
  return (
97
  </Placeholder>
98
  );
99
  }
100
+ const navButton = createRef();
101
+ const [ navigateToTemplate, setNavigateToTemplate ] = useState( false );
102
  useEffect( () => {
103
+ if ( navigateToTemplate && ! isDirty ) {
104
+ // Since we cancelled the click event to save the post
105
+ // we trigger it again here. We do this instead of setting
106
+ // window.location.href because in WordPress.com, the navigation
107
+ // scheme is different and not available to us here.
108
+ navButton.current.click();
109
+ }
110
  receiveTemplateBlocks();
111
  } );
112
 
113
+ useEffect( () => {
114
+ if ( isSelected ) {
115
+ if ( ! isEditorSidebarOpened ) {
116
+ setState( { shouldCloseSidebarOnSelect: false } );
117
+ } else if ( shouldCloseSidebarOnSelect ) {
118
+ closeGeneralSidebar();
119
+ } else {
120
+ clearSelectedBlock();
121
+ }
122
+ } else {
123
+ setState( { shouldCloseSidebarOnSelect: true } );
124
+ }
125
+ } );
126
+
127
+ const { align, className } = attributes;
128
+
129
+ const save = event => {
130
+ if ( ! isDirty ) {
131
+ return;
132
+ }
133
+ event.preventDefault();
134
+ setNavigateToTemplate( true );
135
+ savePost();
136
+ };
137
 
138
  return (
139
  <div
140
+ className={ classNames( 'template-block', className, {
141
  [ `align${ align }` ]: align,
142
  } ) }
143
  >
153
  setAttributes={ noop }
154
  />
155
  </Disabled>
156
+ { isSelected && (
157
+ <Placeholder className="template-block__overlay">
158
+ <Button href={ editTemplateUrl } onClick={ save } isDefault ref={ navButton }>
159
+ { navigateToTemplate ? <Spinner /> : sprintf( __( 'Edit %s' ), templateTitle ) }
160
+ </Button>
161
+ </Placeholder>
162
+ ) }
 
 
 
163
  </Fragment>
164
  ) }
165
  </div>
full-site-editing/blocks/template/index.js CHANGED
@@ -4,22 +4,29 @@
4
  */
5
  import { registerBlockType } from '@wordpress/blocks';
6
  import { __ } from '@wordpress/i18n';
 
 
7
 
8
  /**
9
  * Internal dependencies
10
  */
11
  import edit from './edit';
12
  import './style.scss';
 
13
 
14
- if ( 'wp_template_part' !== fullSiteEditing.editorPostType ) {
15
  registerBlockType( 'a8c/template', {
16
- title: __( 'Template Part' ),
17
- description: __( 'Display a template part.' ),
18
  icon: 'layout',
19
  category: 'layout',
20
- attributes: { templateId: { type: 'number' } },
 
 
 
21
  supports: {
22
- anchor: true,
 
23
  html: false,
24
  reusable: false,
25
  },
@@ -30,3 +37,21 @@ if ( 'wp_template_part' !== fullSiteEditing.editorPostType ) {
30
  },
31
  } );
32
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  */
5
  import { registerBlockType } from '@wordpress/blocks';
6
  import { __ } from '@wordpress/i18n';
7
+ import { createHigherOrderComponent } from '@wordpress/compose';
8
+ import { addFilter } from '@wordpress/hooks';
9
 
10
  /**
11
  * Internal dependencies
12
  */
13
  import edit from './edit';
14
  import './style.scss';
15
+ import './site-logo';
16
 
17
+ if ( 'wp_template' !== fullSiteEditing.editorPostType ) {
18
  registerBlockType( 'a8c/template', {
19
+ title: __( 'Template' ),
20
+ description: __( 'Display a template.' ),
21
  icon: 'layout',
22
  category: 'layout',
23
+ attributes: {
24
+ templateId: { type: 'number' },
25
+ className: { type: 'string' },
26
+ },
27
  supports: {
28
+ anchor: false,
29
+ customClassName: false,
30
  html: false,
31
  reusable: false,
32
  },
37
  },
38
  } );
39
  }
40
+
41
+ const addFSETemplateClassname = createHigherOrderComponent( BlockListBlock => {
42
+ return props => {
43
+ if ( props.name !== 'a8c/template' ) {
44
+ return <BlockListBlock { ...props } />;
45
+ }
46
+
47
+ return <BlockListBlock { ...props } className="template__block-container" />;
48
+ };
49
+ }, 'addFSETemplateClassname' );
50
+
51
+ // Must be 9 or this breaks on Simple Sites
52
+ addFilter(
53
+ 'editor.BlockListBlock',
54
+ 'full-site-editing/blocks/template',
55
+ addFSETemplateClassname,
56
+ 9
57
+ );
full-site-editing/blocks/template/index.php CHANGED
@@ -2,9 +2,11 @@
2
  /**
3
  * Render template block file.
4
  *
5
- * @package full-site-editing
6
  */
7
 
 
 
8
  /**
9
  * Renders template.
10
  *
@@ -24,12 +26,12 @@ function render_template_block( $attributes ) {
24
  ob_start();
25
  ?>
26
 
27
- <div class="template-part<?php echo esc_attr( $align ); ?>">
28
  <?php
29
  // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
30
  echo apply_filters( 'the_content', get_the_content() );
31
  ?>
32
- </div><!-- .template-part -->
33
 
34
  <?php
35
  $content = ob_get_clean();
2
  /**
3
  * Render template block file.
4
  *
5
+ * @package A8C\FSE
6
  */
7
 
8
+ namespace A8C\FSE;
9
+
10
  /**
11
  * Renders template.
12
  *
26
  ob_start();
27
  ?>
28
 
29
+ <div class="template<?php echo esc_attr( $align ); ?>">
30
  <?php
31
  // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
32
  echo apply_filters( 'the_content', get_the_content() );
33
  ?>
34
+ </div><!-- .template -->
35
 
36
  <?php
37
  $content = ob_get_clean();
full-site-editing/blocks/template/site-logo.js ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* eslint-disable wpcalypso/import-docblock */
2
+ /**
3
+ * WordPress dependencies
4
+ */
5
+ import { createHigherOrderComponent } from '@wordpress/compose';
6
+ import { addFilter } from '@wordpress/hooks';
7
+
8
+ const addFSESiteLogoClassname = createHigherOrderComponent( BlockListBlock => {
9
+ return props => {
10
+ if ( props.attributes.className !== 'fse-site-logo' ) {
11
+ return <BlockListBlock { ...props } />;
12
+ }
13
+
14
+ return <BlockListBlock { ...props } className="template__site-logo" />;
15
+ };
16
+ }, 'addFSESiteLogoClassname' );
17
+
18
+ addFilter( 'editor.BlockListBlock', 'full-site-editing/blocks/template', addFSESiteLogoClassname );
full-site-editing/blocks/template/style.scss CHANGED
@@ -1,8 +1,8 @@
1
  .template-block {
2
  min-height: 200px;
3
-
4
- &:hover .template-block__overlay {
5
- display: flex;
6
  }
7
  }
8
 
@@ -29,15 +29,67 @@
29
  }
30
 
31
  .template-block__overlay {
32
- display: none;
33
  position: absolute;
34
  top: 0;
35
- left: 0;
36
  width: 100%;
37
  height: 100%;
38
- background: rgba( #000000, 0.75 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
- .components-placeholder__instructions {
41
- color: white;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  }
43
  }
 
 
 
 
 
 
 
 
 
1
  .template-block {
2
  min-height: 200px;
3
+
4
+ .components-button .components-spinner {
5
+ margin-top: 4px;
6
  }
7
  }
8
 
29
  }
30
 
31
  .template-block__overlay {
32
+ display: flex;
33
  position: absolute;
34
  top: 0;
35
+ left: 2px;
36
  width: 100%;
37
  height: 100%;
38
+ justify-content: center;
39
+ align-items: center;
40
+ background: rgba( #f5f5f5, 0.8 );
41
+ z-index: 2;
42
+ }
43
+
44
+ .block-editor-block-list__layout {
45
+ .template__block-container {
46
+ .wp-block {
47
+ margin-top: 15px;
48
+ margin-bottom: 15px;
49
+ }
50
+
51
+ &.is-hovered {
52
+ cursor: pointer;
53
+ }
54
 
55
+ &.is-selected {
56
+ // Hide the toolbar for this block
57
+ .block-editor-block-contextual-toolbar {
58
+ display: none;
59
+ }
60
+
61
+ .components-disabled {
62
+ filter: blur( 2px );
63
+ }
64
+ }
65
+
66
+ &.block-editor-block-list__block {
67
+ // Need to get super specific to override the core css selectors:
68
+ &,
69
+ &.has-child-selected,
70
+ &.is-hovered,
71
+ &.is-navigate-mode {
72
+ > .block-editor-block-list__block-edit {
73
+ &::before {
74
+ transition: none;
75
+ border: none;
76
+ outline: none;
77
+ box-shadow: none;
78
+ }
79
+ > .block-editor-block-list__breadcrumb {
80
+ display: none;
81
+ }
82
+ }
83
+ }
84
+ }
85
  }
86
  }
87
+
88
+ // don't display the site logo action buttons if not editing the template
89
+ .block-editor-page:not( .post-type-wp_template ) {
90
+ .fse-site-logo {
91
+ .components-placeholder__fieldset, .components-placeholder__instructions {
92
+ display: none;
93
+ }
94
+ }
95
+ }
full-site-editing/class-full-site-editing.php CHANGED
@@ -2,9 +2,11 @@
2
  /**
3
  * Full site editing file.
4
  *
5
- * @package full-site-editing
6
  */
7
 
 
 
8
  /**
9
  * Class Full_Site_Editing
10
  */
@@ -12,36 +14,67 @@ class Full_Site_Editing {
12
  /**
13
  * Class instance.
14
  *
15
- * @var Full_Site_Editing
16
  */
17
  private static $instance = null;
18
 
19
  /**
20
  * Custom post types.
21
  *
22
- * @var Full_Site_Editing
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  */
24
- private $template_post_types = array( 'wp_template', 'wp_template_part' );
 
 
 
 
 
 
 
25
 
26
  /**
27
  * Full_Site_Editing constructor.
28
  */
29
  private function __construct() {
30
- add_action( 'init', array( $this, 'register_blocks' ), 100 );
31
- add_action( 'init', array( $this, 'register_template_post_types' ) );
32
- add_action( 'init', array( $this, 'register_meta_template_id' ) );
33
- add_action( 'rest_api_init', array( $this, 'allow_searching_for_templates' ) );
34
- add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_script_and_style' ), 100 );
35
- add_action( 'the_post', array( $this, 'merge_template_and_post' ) );
36
- add_filter( 'wp_insert_post_data', array( $this, 'remove_template_components' ), 10, 2 );
37
- add_filter( 'admin_body_class', array( $this, 'toggle_editor_post_title_visibility' ) );
38
- add_filter( 'block_editor_settings', array( $this, 'set_block_template' ) );
 
 
 
 
 
 
 
 
 
 
39
  }
40
 
41
  /**
42
  * Creates instance.
43
  *
44
- * @return \Full_Site_Editing
45
  */
46
  public static function get_instance() {
47
  if ( null === self::$instance ) {
@@ -52,216 +85,61 @@ class Full_Site_Editing {
52
  }
53
 
54
  /**
55
- * Register post types.
 
 
 
 
56
  */
57
- public function register_template_post_types() {
58
- register_post_type(
59
- 'wp_template',
60
- array(
61
- 'labels' => array(
62
- 'name' => _x( 'Templates', 'post type general name', 'full-site-editing' ),
63
- 'singular_name' => _x( 'Template', 'post type singular name', 'full-site-editing' ),
64
- 'menu_name' => _x( 'Templates', 'admin menu', 'full-site-editing' ),
65
- 'name_admin_bar' => _x( 'Template', 'add new on admin bar', 'full-site-editing' ),
66
- 'add_new' => _x( 'Add New', 'Template', 'full-site-editing' ),
67
- 'add_new_item' => __( 'Add New Template', 'full-site-editing' ),
68
- 'new_item' => __( 'New Template', 'full-site-editing' ),
69
- 'edit_item' => __( 'Edit Template', 'full-site-editing' ),
70
- 'view_item' => __( 'View Template', 'full-site-editing' ),
71
- 'all_items' => __( 'All Templates', 'full-site-editing' ),
72
- 'search_items' => __( 'Search Templates', 'full-site-editing' ),
73
- 'not_found' => __( 'No templates found.', 'full-site-editing' ),
74
- 'not_found_in_trash' => __( 'No templates found in Trash.', 'full-site-editing' ),
75
- 'filter_items_list' => __( 'Filter templates list', 'full-site-editing' ),
76
- 'items_list_navigation' => __( 'Templates list navigation', 'full-site-editing' ),
77
- 'items_list' => __( 'Templates list', 'full-site-editing' ),
78
- 'item_published' => __( 'Template published.', 'full-site-editing' ),
79
- 'item_published_privately' => __( 'Template published privately.', 'full-site-editing' ),
80
- 'item_reverted_to_draft' => __( 'Template reverted to draft.', 'full-site-editing' ),
81
- 'item_scheduled' => __( 'Template scheduled.', 'full-site-editing' ),
82
- 'item_updated' => __( 'Template updated.', 'full-site-editing' ),
83
- ),
84
- 'menu_icon' => 'dashicons-layout',
85
- 'public' => false,
86
- 'show_ui' => true,
87
- 'show_in_menu' => true,
88
- 'rewrite' => false,
89
- 'show_in_rest' => true,
90
- 'rest_base' => 'templates',
91
- 'rest_controller_class' => 'A8C_REST_Templates_Controller',
92
- 'capability_type' => 'template',
93
- 'capabilities' => array(
94
- // You need to be able to edit posts, in order to read templates in their raw form.
95
- 'read' => 'edit_posts',
96
- // You need to be able to customize, in order to create templates.
97
- 'create_posts' => 'edit_theme_options',
98
- 'edit_posts' => 'edit_theme_options',
99
- 'delete_posts' => 'edit_theme_options',
100
- 'edit_published_posts' => 'edit_theme_options',
101
- 'delete_published_posts' => 'edit_theme_options',
102
- 'edit_others_posts' => 'edit_theme_options',
103
- 'delete_others_posts' => 'edit_theme_options',
104
- 'publish_posts' => 'edit_theme_options',
105
- ),
106
- 'map_meta_cap' => true,
107
- 'supports' => array(
108
- 'title',
109
- 'editor',
110
- ),
111
- )
112
- );
113
 
114
- register_post_type(
115
- 'wp_template_part',
116
- array(
117
- 'labels' => array(
118
- 'name' => _x( 'Template Parts', 'post type general name', 'full-site-editing' ),
119
- 'singular_name' => _x( 'Template Part', 'post type singular name', 'full-site-editing' ),
120
- 'menu_name' => _x( 'Template Parts', 'admin menu', 'full-site-editing' ),
121
- 'name_admin_bar' => _x( 'Template Part', 'add new on admin bar', 'full-site-editing' ),
122
- 'add_new' => _x( 'Add New', 'Template Part', 'full-site-editing' ),
123
- 'add_new_item' => __( 'Add New Template Part', 'full-site-editing' ),
124
- 'new_item' => __( 'New Template Part', 'full-site-editing' ),
125
- 'edit_item' => __( 'Edit Template Part', 'full-site-editing' ),
126
- 'view_item' => __( 'View Template Part', 'full-site-editing' ),
127
- 'all_items' => __( 'All Template Parts', 'full-site-editing' ),
128
- 'search_items' => __( 'Search Template Parts', 'full-site-editing' ),
129
- 'not_found' => __( 'No template parts found.', 'full-site-editing' ),
130
- 'not_found_in_trash' => __( 'No template parts found in Trash.', 'full-site-editing' ),
131
- 'filter_items_list' => __( 'Filter template parts list', 'full-site-editing' ),
132
- 'items_list_navigation' => __( 'Template parts list navigation', 'full-site-editing' ),
133
- 'items_list' => __( 'Template parts list', 'full-site-editing' ),
134
- 'item_published' => __( 'Template part published.', 'full-site-editing' ),
135
- 'item_published_privately' => __( 'Template part published privately.', 'full-site-editing' ),
136
- 'item_reverted_to_draft' => __( 'Template part reverted to draft.', 'full-site-editing' ),
137
- 'item_scheduled' => __( 'Template part scheduled.', 'full-site-editing' ),
138
- 'item_updated' => __( 'Template part updated.', 'full-site-editing' ),
139
- ),
140
- 'menu_icon' => 'dashicons-layout',
141
- 'public' => false,
142
- 'show_ui' => true,
143
- 'show_in_menu' => true,
144
- 'rewrite' => false,
145
- 'show_in_rest' => true,
146
- 'rest_base' => 'template_parts',
147
- 'rest_controller_class' => 'A8C_REST_Templates_Controller',
148
- 'capability_type' => 'template_part',
149
- 'capabilities' => array(
150
- // You need to be able to edit posts, in order to read templates in their raw form.
151
- 'read' => 'edit_posts',
152
- // You need to be able to customize, in order to create templates.
153
- 'create_posts' => 'edit_theme_options',
154
- 'edit_posts' => 'edit_theme_options',
155
- 'delete_posts' => 'edit_theme_options',
156
- 'edit_published_posts' => 'edit_theme_options',
157
- 'delete_published_posts' => 'edit_theme_options',
158
- 'edit_others_posts' => 'edit_theme_options',
159
- 'delete_others_posts' => 'edit_theme_options',
160
- 'publish_posts' => 'edit_theme_options',
161
- ),
162
- 'map_meta_cap' => true,
163
- 'supports' => array(
164
- 'title',
165
- 'editor',
166
- ),
167
- )
168
- );
169
 
170
- register_taxonomy(
171
- 'wp_template_type',
172
- 'wp_template',
173
- array(
174
- 'labels' => array(
175
- 'name' => _x( 'Template Types', 'taxonomy general name', 'full-site-editing' ),
176
- 'singular_name' => _x( 'Template Type', 'taxonomy singular name', 'full-site-editing' ),
177
- 'menu_name' => _x( 'Template Types', 'admin menu', 'full-site-editing' ),
178
- 'all_items' => __( 'All Template Types', 'full-site-editing' ),
179
- 'edit_item' => __( 'Edit Template Type', 'full-site-editing' ),
180
- 'view_item' => __( 'View Template Type', 'full-site-editing' ),
181
- 'update_item' => __( 'Update Template Type', 'full-site-editing' ),
182
- 'add_new_item' => __( 'Add New Template Type', 'full-site-editing' ),
183
- 'new_item_name' => __( 'New Template Type', 'full-site-editing' ),
184
- 'parent_item' => __( 'Parent Template Type', 'full-site-editing' ),
185
- 'parent_item_colon' => __( 'Parent Template Type:', 'full-site-editing' ),
186
- 'search_items' => __( 'Search Template Types', 'full-site-editing' ),
187
- 'not_found' => __( 'No template types found.', 'full-site-editing' ),
188
- 'back_to_items' => __( 'Back to template types', 'full-site-editing' ),
189
- ),
190
- 'public' => false,
191
- 'publicly_queryable' => true,
192
- 'show_ui' => true,
193
- 'show_in_menu' => false,
194
- 'show_in_nav_menu' => false,
195
- 'show_in_rest' => true,
196
- 'rest_base' => 'template_types',
197
- 'show_tagcloud' => false,
198
- 'show_admin_column' => true,
199
- 'hierarchical' => true,
200
- 'rewrite' => false,
201
- 'capabilities' => array(
202
- 'manage_terms' => 'edit_theme_options',
203
- 'edit_terms' => 'edit_theme_options',
204
- 'delete_terms' => 'edit_theme_options',
205
- 'assign_terms' => 'edit_theme_options',
206
- ),
207
- )
208
- );
209
 
210
- register_taxonomy(
211
- 'wp_template_part_type',
212
- 'wp_template_part',
213
- array(
214
- 'labels' => array(
215
- 'name' => _x( 'Template Part Types', 'taxonomy general name', 'full-site-editing' ),
216
- 'singular_name' => _x( 'Template Part Type', 'taxonomy singular name', 'full-site-editing' ),
217
- 'menu_name' => _x( 'Template Part Types', 'admin menu', 'full-site-editing' ),
218
- 'all_items' => __( 'All Template Part Types', 'full-site-editing' ),
219
- 'edit_item' => __( 'Edit Template Part Type', 'full-site-editing' ),
220
- 'view_item' => __( 'View Template Part Type', 'full-site-editing' ),
221
- 'update_item' => __( 'Update Template Part Type', 'full-site-editing' ),
222
- 'add_new_item' => __( 'Add New Template Part Type', 'full-site-editing' ),
223
- 'new_item_name' => __( 'New Template Part Type', 'full-site-editing' ),
224
- 'parent_item' => __( 'Parent Template Part Type', 'full-site-editing' ),
225
- 'parent_item_colon' => __( 'Parent Template Part Type:', 'full-site-editing' ),
226
- 'search_items' => __( 'Search Template Part Types', 'full-site-editing' ),
227
- 'not_found' => __( 'No template part types found.', 'full-site-editing' ),
228
- 'back_to_items' => __( 'Back to template part types', 'full-site-editing' ),
229
- ),
230
- 'public' => false,
231
- 'publicly_queryable' => true,
232
- 'show_ui' => true,
233
- 'show_in_menu' => false,
234
- 'show_in_nav_menu' => false,
235
- 'show_in_rest' => true,
236
- 'rest_base' => 'template_part_types',
237
- 'show_tagcloud' => false,
238
- 'show_admin_column' => true,
239
- 'hierarchical' => true,
240
- 'rewrite' => false,
241
- 'capabilities' => array(
242
- 'manage_terms' => 'edit_theme_options',
243
- 'edit_terms' => 'edit_theme_options',
244
- 'delete_terms' => 'edit_theme_options',
245
- 'assign_terms' => 'edit_theme_options',
246
- ),
247
- )
248
- );
249
  }
250
 
251
  /**
252
- * Register post meta.
 
 
 
 
 
 
 
 
253
  */
254
- public function register_meta_template_id() {
255
- register_post_meta(
256
- '',
257
- '_wp_template_id',
258
- array(
259
- 'auth_callback' => array( $this, 'meta_template_id_auth_callback' ),
260
- 'show_in_rest' => true,
261
- 'single' => true,
262
- 'type' => 'integer',
263
- )
264
- );
 
 
265
  }
266
 
267
  /**
@@ -291,16 +169,14 @@ class Full_Site_Editing {
291
  true
292
  );
293
 
294
- $feature_flags = A8C_Full_Site_Editing_Feature_Flags::get_instance();
295
-
296
  wp_localize_script(
297
  'a8c-full-site-editing-script',
298
  'fullSiteEditing',
299
  array(
300
- 'editorPostType' => get_current_screen()->post_type,
301
- 'featureFlags' => $feature_flags->get_flags(),
302
- 'closeButtonUrl' => esc_url( $this->get_close_button_url() ),
303
- 'editTemplatePartBaseUrl' => esc_url( $this->get_edit_template_part_base_url() ),
304
  )
305
  );
306
 
@@ -323,77 +199,87 @@ class Full_Site_Editing {
323
  'a8c/navigation-menu',
324
  array(
325
  'attributes' => [
326
- 'className' => [
327
  'default' => '',
328
  'type' => 'string',
329
  ],
330
  ],
331
- 'render_callback' => 'a8c_fse_render_navigation_menu_block',
332
  )
333
  );
334
 
335
  register_block_type(
336
  'a8c/post-content',
337
  array(
338
- 'render_callback' => 'render_post_content_block',
339
  )
340
  );
341
 
342
  register_block_type(
343
  'a8c/site-description',
344
  array(
345
- 'render_callback' => 'render_site_description_block',
346
  )
347
  );
348
 
349
  register_block_type(
350
  'a8c/template',
351
  array(
352
- 'render_callback' => 'render_template_block',
353
- )
354
- );
355
-
356
- register_block_type(
357
- 'a8c/site-logo',
358
- array(
359
- 'attributes' => array(
360
- 'editorPreview' => array(
361
- 'type' => 'boolean',
362
- 'default' => false,
363
- ),
364
- ),
365
- 'render_callback' => 'render_site_logo',
366
  )
367
  );
368
 
369
  register_block_type(
370
  'a8c/site-title',
371
  array(
372
- 'render_callback' => 'render_site_title_block',
373
  )
374
  );
375
  }
376
 
377
  /**
378
- * This will set the `wp_template` and `wp_template_part` post types to `public` to support
379
- * the core search endpoint, which looks for it.
 
 
380
  */
381
- public function allow_searching_for_templates() {
382
- $post_type = get_post_type_object( 'wp_template' );
383
- if ( ! ( $post_type instanceof WP_Post_Type ) ) {
384
- return;
385
  }
386
 
387
- // Setting this to `public` will allow it to be found in the search endpoint.
388
- $post_type->public = true;
389
 
390
- $post_type = get_post_type_object( 'wp_template_part' );
391
- if ( ! ( $post_type instanceof WP_Post_Type ) ) {
392
- return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
393
  }
394
 
395
- // Setting this to `public` will allow it to be found in the search endpoint.
396
- $post_type->public = true;
 
 
 
397
  }
398
 
399
  /**
@@ -401,27 +287,21 @@ class Full_Site_Editing {
401
  *
402
  * In some cases we want to override the default value which would take us to post listing
403
  * for a given post type. For example, when navigating back from Header, we want to show the
404
- * parent page editing view, and not the Template Part CPT list.
405
  *
406
  * @return null|string Override URL string if it should be inserted, or null otherwise.
407
  */
408
  public function get_close_button_url() {
409
- // phpcs:disable WordPress.Security.NonceVerification.Recommended
410
- if ( ! isset( $_GET['fse_parent_post'] ) ) {
411
- return null;
412
- }
413
 
414
- $parent_post_id = absint( $_GET['fse_parent_post'] );
415
- // phpcs:enable WordPress.Security.NonceVerification.Recommended
416
-
417
- if ( empty( $parent_post_id ) ) {
418
  return null;
419
  }
420
 
421
  $close_button_url = get_edit_post_link( $parent_post_id );
422
 
423
  /**
424
- * Filter the Gutenberg's close button URL when editing Template Part CPTs.
425
  *
426
  * @since 0.1
427
  *
@@ -431,29 +311,29 @@ class Full_Site_Editing {
431
  }
432
 
433
  /**
434
- * Returns the base URL for the Edit Template Part button. The URL does not contain neither
435
- * the post ID nor the template part ID. Those query arguments should be provided by
436
- * the Template Part on the Block.
437
  *
438
  * @return string edit link without post ID
439
  */
440
- public function get_edit_template_part_base_url() {
441
  $edit_post_link = remove_query_arg( 'post', get_edit_post_link( 0, 'edit' ) );
442
 
443
  /**
444
- * Filter the Gutenberg's edit template part button base URL
445
  * when editing pages or posts.
446
  *
447
  * @since 0.2
448
  *
449
  * @param string Current edit button URL.
450
  */
451
- return apply_filters( 'a8c_fse_edit_template_part_base_url', $edit_post_link );
452
  }
453
 
454
  /** This will merge the post content with the post template, modifiying the $post parameter.
455
  *
456
- * @param WP_Post $post Post instance.
457
  */
458
  public function merge_template_and_post( $post ) {
459
  // Bail if not a REST API Request.
@@ -466,8 +346,8 @@ class Full_Site_Editing {
466
  return;
467
  }
468
 
469
- $template = new A8C_WP_Template( $post->ID );
470
- $template_content = $template->get_template_content();
471
 
472
  // Bail if the template has no post content block.
473
  if ( ! has_block( 'a8c/post-content', $template_content ) ) {
@@ -510,18 +390,6 @@ class Full_Site_Editing {
510
  return $data;
511
  }
512
 
513
- /**
514
- * Determine if the current edited post is a full site page.
515
- * If it's a page being loaded that has a `wp_template`, it's a page that our FSE plugin should handle.
516
- *
517
- * @return boolean
518
- */
519
- public function is_full_site_page() {
520
- $fse_template = new A8C_WP_Template();
521
-
522
- return 'page' === get_post_type() && $fse_template->get_template_id();
523
- }
524
-
525
  /**
526
  * Return an extra class that will be assigned to the body element if a full site page is being edited.
527
  *
@@ -546,100 +414,130 @@ class Full_Site_Editing {
546
  */
547
  public function set_block_template( $editor_settings ) {
548
  if ( $this->is_full_site_page() ) {
549
- $fse_template = new A8C_WP_Template();
550
  $template_blocks = $fse_template->get_template_blocks();
551
 
552
  $template = array();
553
  foreach ( $template_blocks as $block ) {
554
- $template[] = fse_map_block_to_editor_template_setting( $block );
555
  }
556
  $editor_settings['template'] = $template;
557
  $editor_settings['templateLock'] = 'all';
558
  }
559
  return $editor_settings;
560
  }
561
- }
562
 
563
- /**
564
- * Returns an array with the expected format of the block template setting syntax.
565
- *
566
- * @see https://github.com/WordPress/gutenberg/blob/1414cf0ad1ec3d0f3e86a40815513c15938bb522/docs/designers-developers/developers/block-api/block-templates.md
567
- *
568
- * @param array $block Block to convert.
569
- * @return array
570
- */
571
- function fse_map_block_to_editor_template_setting( $block ) {
572
- $block_name = $block['blockName'];
573
- $attrs = $block['attrs'];
574
- $inner_blocks = $block['innerBlocks'];
575
-
576
- $inner_blocks_template = array();
577
- foreach ( $inner_blocks as $inner_block ) {
578
- $inner_blocks[] = fse_map_block_to_editor_template_setting( $inner_block );
 
 
 
579
  }
580
- return array( $block_name, $attrs, $inner_blocks_template );
581
- }
582
 
583
- if ( ! function_exists( 'serialize_block' ) ) {
584
  /**
585
- * Renders an HTML-serialized form of a block object
586
- * from https://core.trac.wordpress.org/ticket/47375
587
  *
588
- * Should be available since WordPress 5.3.0.
589
  *
590
- * @param array $block The block being rendered.
591
- * @return string The HTML-serialized form of the block
592
  */
593
- function serialize_block( $block ) {
594
- // Non-block content has no block name.
595
- if ( null === $block['blockName'] ) {
596
- return $block['innerHTML'];
 
 
 
 
597
  }
 
 
598
 
599
- $unwanted = array( '--', '<', '>', '&', '\"' );
600
- $wanted = array( '\u002d\u002d', '\u003c', '\u003e', '\u0026', '\u0022' );
601
-
602
- $name = 0 === strpos( $block['blockName'], 'core/' ) ? substr( $block['blockName'], 5 ) : $block['blockName'];
603
- $has_attrs = ! empty( $block['attrs'] );
604
- $attrs = $has_attrs ? str_replace( $unwanted, $wanted, wp_json_encode( $block['attrs'] ) ) : '';
605
-
606
- // Early abort for void blocks holding no content.
607
- if ( empty( $block['innerContent'] ) ) {
608
- return $has_attrs
609
- ? "<!-- wp:{$name} {$attrs} /-->"
610
- : "<!-- wp:{$name} /-->";
611
  }
 
 
612
 
613
- $output = $has_attrs
614
- ? "<!-- wp:{$name} {$attrs} -->\n"
615
- : "<!-- wp:{$name} -->\n";
616
-
617
- $inner_block_index = 0;
618
- foreach ( $block['innerContent'] as $chunk ) {
619
- $output .= null === $chunk
620
- ? serialize_block( $block['innerBlocks'][ $inner_block_index++ ] )
621
- : $chunk;
 
622
 
623
- $output .= "\n";
 
 
 
 
 
 
 
624
  }
 
625
 
626
- $output .= "<!-- /wp:{$name} -->";
627
-
628
- return $output;
 
 
 
 
 
 
 
 
 
629
  }
630
- }
631
 
632
- if ( ! function_exists( 'serialize_blocks' ) ) {
633
  /**
634
- * Renders an HTML-serialized form of a list of block objects
635
- * from https://core.trac.wordpress.org/ticket/47375
636
  *
637
- * Should be available since WordPress 5.3.0.
 
 
 
 
 
 
 
 
 
638
  *
639
- * @param array $blocks The list of parsed block objects.
640
- * @return string The HTML-serialized form of the list of blocks.
641
  */
642
- function serialize_blocks( $blocks ) {
643
- return implode( "\n\n", array_map( 'serialize_block', $blocks ) );
 
 
644
  }
645
  }
2
  /**
3
  * Full site editing file.
4
  *
5
+ * @package A8C\FSE
6
  */
7
 
8
+ namespace A8C\FSE;
9
+
10
  /**
11
  * Class Full_Site_Editing
12
  */
14
  /**
15
  * Class instance.
16
  *
17
+ * @var \A8C\FSE\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 = [ 'wp_template' ];
27
+
28
+ /**
29
+ * Current theme slug.
30
+ *
31
+ * @var string
32
+ */
33
+ private $theme_slug = '';
34
+
35
+ /**
36
+ * Instance of WP_Template_Inserter class.
37
+ *
38
+ * @var WP_Template_Inserter
39
  */
40
+ public $wp_template_inserter;
41
+
42
+ /**
43
+ * List of FSE supported themes.
44
+ *
45
+ * @var array
46
+ */
47
+ const SUPPORTED_THEMES = [ 'modern-business' ];
48
 
49
  /**
50
  * Full_Site_Editing constructor.
51
  */
52
  private function __construct() {
53
+ add_action( 'init', [ $this, 'register_blocks' ], 100 );
54
+ add_action( 'init', [ $this, 'register_template_post_types' ] );
55
+ add_action( 'enqueue_block_editor_assets', [ $this, 'enqueue_script_and_style' ], 100 );
56
+ add_action( 'the_post', [ $this, 'merge_template_and_post' ] );
57
+ add_filter( 'wp_insert_post_data', [ $this, 'remove_template_components' ], 10, 2 );
58
+ add_filter( 'admin_body_class', [ $this, 'toggle_editor_post_title_visibility' ] );
59
+ add_filter( 'block_editor_settings', [ $this, 'set_block_template' ] );
60
+ add_action( 'after_switch_theme', [ $this, 'insert_default_data' ] );
61
+ add_filter( 'body_class', array( $this, 'add_fse_body_class' ) );
62
+
63
+ add_filter( 'post_row_actions', [ $this, 'remove_trash_row_action_for_template_post_types' ], 10, 2 );
64
+ add_filter( 'bulk_actions-edit-wp_template', [ $this, 'remove_trash_bulk_action_for_template_post_type' ] );
65
+ add_action( 'wp_trash_post', [ $this, 'restrict_template_deletion' ] );
66
+ add_filter( 'wp_template_type_row_actions', [ $this, 'remove_delete_row_action_for_template_taxonomy' ], 10, 2 );
67
+ add_filter( 'bulk_actions-edit-wp_template_type', [ $this, 'remove_delete_bulk_action_for_template_taxonomy' ] );
68
+ add_action( 'pre_delete_term', [ $this, 'restrict_template_taxonomy_deletion' ], 10, 2 );
69
+
70
+ $this->theme_slug = $this->normalize_theme_slug( get_stylesheet() );
71
+ $this->wp_template_inserter = new WP_Template_Inserter( $this->theme_slug );
72
  }
73
 
74
  /**
75
  * Creates instance.
76
  *
77
+ * @return \A8C\FSE\Full_Site_Editing
78
  */
79
  public static function get_instance() {
80
  if ( null === self::$instance ) {
85
  }
86
 
87
  /**
88
+ * Determines whether provided theme supports FSE.
89
+ *
90
+ * @param string $theme_slug Theme slug to check support for.
91
+ *
92
+ * @return bool True if passed theme supports FSE, false otherwise.
93
  */
94
+ public function is_supported_theme( $theme_slug ) {
95
+ return in_array( $theme_slug, self::SUPPORTED_THEMES, true );
96
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
 
98
+ /**
99
+ * Inserts template data for the theme we are currently switching to.
100
+ *
101
+ * This insertion will only happen if theme supports FSE.
102
+ * It is hooked into after_switch_theme action.
103
+ */
104
+ public function insert_default_data() {
105
+ // Bail if theme doesn't support FSE.
106
+ if ( ! $this->is_supported_theme( $this->theme_slug ) ) {
107
+ return;
108
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
 
110
+ if ( ! $this->wp_template_inserter->is_template_data_inserted() ) {
111
+ $this->wp_template_inserter->insert_default_template_data();
112
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
 
114
+ if ( ! $this->wp_template_inserter->is_pages_data_inserted() ) {
115
+ $this->wp_template_inserter->insert_default_pages();
116
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
  }
118
 
119
  /**
120
+ * Returns normalized theme slug for the current theme.
121
+ *
122
+ * Normalize WP.com theme slugs that differ from those that we'll get on self hosted sites.
123
+ * For example, we will get 'modern-business' when retrieving theme slug on self hosted sites,
124
+ * but due to WP.com setup, on Simple sites we'll get 'pub/modern-business' for the theme.
125
+ *
126
+ * @param string $theme_slug Theme slug to check support for.
127
+ *
128
+ * @return string Normalized theme slug.
129
  */
130
+ public function normalize_theme_slug( $theme_slug ) {
131
+ if ( 'pub/' === substr( $theme_slug, 0, 4 ) ) {
132
+ $theme_slug = str_replace( 'pub/', '', $theme_slug );
133
+ }
134
+
135
+ return $theme_slug;
136
+ }
137
+
138
+ /**
139
+ * Register post types.
140
+ */
141
+ public function register_template_post_types() {
142
+ $this->wp_template_inserter->register_template_post_types();
143
  }
144
 
145
  /**
169
  true
170
  );
171
 
 
 
172
  wp_localize_script(
173
  'a8c-full-site-editing-script',
174
  'fullSiteEditing',
175
  array(
176
+ 'editorPostType' => get_current_screen()->post_type,
177
+ 'closeButtonLabel' => $this->get_close_button_label(),
178
+ 'closeButtonUrl' => esc_url( $this->get_close_button_url() ),
179
+ 'editTemplateBaseUrl' => esc_url( $this->get_edit_template_base_url() ),
180
  )
181
  );
182
 
199
  'a8c/navigation-menu',
200
  array(
201
  'attributes' => [
202
+ 'className' => [
203
  'default' => '',
204
  'type' => 'string',
205
  ],
206
  ],
207
+ 'render_callback' => __NAMESPACE__ . '\render_navigation_menu_block',
208
  )
209
  );
210
 
211
  register_block_type(
212
  'a8c/post-content',
213
  array(
214
+ 'render_callback' => __NAMESPACE__ . '\render_post_content_block',
215
  )
216
  );
217
 
218
  register_block_type(
219
  'a8c/site-description',
220
  array(
221
+ 'render_callback' => __NAMESPACE__ . '\render_site_description_block',
222
  )
223
  );
224
 
225
  register_block_type(
226
  'a8c/template',
227
  array(
228
+ 'render_callback' => __NAMESPACE__ . '\render_template_block',
 
 
 
 
 
 
 
 
 
 
 
 
 
229
  )
230
  );
231
 
232
  register_block_type(
233
  'a8c/site-title',
234
  array(
235
+ 'render_callback' => __NAMESPACE__ . '\render_site_title_block',
236
  )
237
  );
238
  }
239
 
240
  /**
241
+ * Returns the parent post ID if sent as query param when editing a Template from a
242
+ * Post/Page or a Template.
243
+ *
244
+ * @return null|string The parent post ID, or null if not set.
245
  */
246
+ public function get_parent_post_id() {
247
+ // phpcs:disable WordPress.Security.NonceVerification
248
+ if ( ! isset( $_GET['fse_parent_post'] ) ) {
249
+ return null;
250
  }
251
 
252
+ $parent_post_id = absint( $_GET['fse_parent_post'] );
253
+ // phpcs:enable WordPress.Security.NonceVerification
254
 
255
+ if ( empty( $parent_post_id ) ) {
256
+ return null;
257
+ }
258
+
259
+ return $parent_post_id;
260
+ }
261
+
262
+ /**
263
+ * Returns the label for the Gutenberg close button.
264
+ *
265
+ * When we edit a Template from a Post/Page or a Template, we want to replace the close
266
+ * icon with a "Back to" button, to clarify that it will take us back to the previous editing
267
+ * view, and not the Template CPT list.
268
+ *
269
+ * @return null|string Override label string if it should be inserted, or null otherwise.
270
+ */
271
+ public function get_close_button_label() {
272
+ $parent_post_id = $this->get_parent_post_id();
273
+
274
+ if ( ! $parent_post_id ) {
275
+ return null;
276
  }
277
 
278
+ $parent_post_type = get_post_type( $parent_post_id );
279
+ $parent_post_type_object = get_post_type_object( $parent_post_type );
280
+
281
+ /* translators: %s: "Back to Post", "Back to Page", "Back to Template", etc. */
282
+ return sprintf( __( 'Back to %s', 'full-site-editing' ), $parent_post_type_object->labels->singular_name );
283
  }
284
 
285
  /**
287
  *
288
  * In some cases we want to override the default value which would take us to post listing
289
  * for a given post type. For example, when navigating back from Header, we want to show the
290
+ * parent page editing view, and not the Template CPT list.
291
  *
292
  * @return null|string Override URL string if it should be inserted, or null otherwise.
293
  */
294
  public function get_close_button_url() {
295
+ $parent_post_id = $this->get_parent_post_id();
 
 
 
296
 
297
+ if ( ! $parent_post_id ) {
 
 
 
298
  return null;
299
  }
300
 
301
  $close_button_url = get_edit_post_link( $parent_post_id );
302
 
303
  /**
304
+ * Filter the Gutenberg's close button URL when editing Template CPTs.
305
  *
306
  * @since 0.1
307
  *
311
  }
312
 
313
  /**
314
+ * Returns the base URL for the Edit Template button. The URL does not contain neither
315
+ * the post ID nor the template ID. Those query arguments should be provided by
316
+ * the Template on the Block.
317
  *
318
  * @return string edit link without post ID
319
  */
320
+ public function get_edit_template_base_url() {
321
  $edit_post_link = remove_query_arg( 'post', get_edit_post_link( 0, 'edit' ) );
322
 
323
  /**
324
+ * Filter the Gutenberg's edit template button base URL
325
  * when editing pages or posts.
326
  *
327
  * @since 0.2
328
  *
329
  * @param string Current edit button URL.
330
  */
331
+ return apply_filters( 'a8c_fse_edit_template_base_url', $edit_post_link );
332
  }
333
 
334
  /** This will merge the post content with the post template, modifiying the $post parameter.
335
  *
336
+ * @param \WP_Post $post Post instance.
337
  */
338
  public function merge_template_and_post( $post ) {
339
  // Bail if not a REST API Request.
346
  return;
347
  }
348
 
349
+ $template = new WP_Template();
350
+ $template_content = $template->get_page_template_content();
351
 
352
  // Bail if the template has no post content block.
353
  if ( ! has_block( 'a8c/post-content', $template_content ) ) {
390
  return $data;
391
  }
392
 
 
 
 
 
 
 
 
 
 
 
 
 
393
  /**
394
  * Return an extra class that will be assigned to the body element if a full site page is being edited.
395
  *
414
  */
415
  public function set_block_template( $editor_settings ) {
416
  if ( $this->is_full_site_page() ) {
417
+ $fse_template = new WP_Template();
418
  $template_blocks = $fse_template->get_template_blocks();
419
 
420
  $template = array();
421
  foreach ( $template_blocks as $block ) {
422
+ $template[] = $this->fse_map_block_to_editor_template_setting( $block );
423
  }
424
  $editor_settings['template'] = $template;
425
  $editor_settings['templateLock'] = 'all';
426
  }
427
  return $editor_settings;
428
  }
 
429
 
430
+ /**
431
+ * Determine if the current edited post is a full site page.
432
+ * So far we only support static pages.
433
+ *
434
+ * @return boolean
435
+ */
436
+ public function is_full_site_page() {
437
+ return 'page' === get_post_type();
438
+ }
439
+
440
+ /**
441
+ * Add fse-enabled class to body so we can target css only if plugin enabled.
442
+ *
443
+ * @param array $classes classes to be applied to body.
444
+ * @return array classes to be applied to body.
445
+ */
446
+ public function add_fse_body_class( $classes ) {
447
+ $classes[] = 'fse-enabled';
448
+ return $classes;
449
  }
 
 
450
 
 
451
  /**
452
+ * Returns an array with the expected format of the block template setting syntax.
 
453
  *
454
+ * @see https://github.com/WordPress/gutenberg/blob/1414cf0ad1ec3d0f3e86a40815513c15938bb522/docs/designers-developers/developers/block-api/block-templates.md
455
  *
456
+ * @param array $block Block to convert.
457
+ * @return array
458
  */
459
+ private function fse_map_block_to_editor_template_setting( $block ) {
460
+ $block_name = $block['blockName'];
461
+ $attrs = $block['attrs'];
462
+ $inner_blocks = $block['innerBlocks'];
463
+
464
+ $inner_blocks_template = array();
465
+ foreach ( $inner_blocks as $inner_block ) {
466
+ $inner_blocks[] = fse_map_block_to_editor_template_setting( $inner_block );
467
  }
468
+ return array( $block_name, $attrs, $inner_blocks_template );
469
+ }
470
 
471
+ /**
472
+ * Removes the Trash action from the quick actions on the Templates list
473
+ *
474
+ * @param array $actions Array of row action links.
475
+ * @param WP_Post $post The post object.
476
+ * @return array
477
+ */
478
+ public function remove_trash_row_action_for_template_post_types( $actions, $post ) {
479
+ if ( in_array( $post->post_type, $this->template_post_types, true ) ) {
480
+ unset( $actions['trash'] );
 
 
481
  }
482
+ return $actions;
483
+ }
484
 
485
+ /**
486
+ * Removes the Trash bulk action from the Template List page.
487
+ *
488
+ * @param array $bulk_actions Array of bulk actions.
489
+ * @return array;
490
+ */
491
+ public function remove_trash_bulk_action_for_template_post_type( $bulk_actions ) {
492
+ unset( $bulk_actions['trash'] );
493
+ return $bulk_actions;
494
+ }
495
 
496
+ /**
497
+ * Prevents posts for the template post types to be deleted
498
+ *
499
+ * @param integer $post_id The post id.
500
+ */
501
+ public function restrict_template_deletion( $post_id ) {
502
+ if ( in_array( get_post_type( $post_id ), $this->template_post_types, true ) ) {
503
+ wp_die( esc_html__( 'Templates cannot be deleted.' ) );
504
  }
505
+ }
506
 
507
+ /**
508
+ * Removes the Delete action from the quick actions for the template taxonomy.
509
+ *
510
+ * @param array $actions Array of row action links.
511
+ * @param WP_Term $term The Term object.
512
+ * @return array
513
+ */
514
+ public function remove_delete_row_action_for_template_taxonomy( $actions, $term ) {
515
+ if ( 'wp_template_type' === $term->taxonomy ) {
516
+ unset( $actions['delete'] );
517
+ }
518
+ return $actions;
519
  }
 
520
 
 
521
  /**
522
+ * Removes the Delete bulk action from the Template Taxonomy list.
 
523
  *
524
+ * @param array $bulk_actions Array of bulk actions.
525
+ * @return array
526
+ */
527
+ public function remove_delete_bulk_action_for_template_taxonomy( $bulk_actions ) {
528
+ unset( $bulk_actions['delete'] );
529
+ return $bulk_actions;
530
+ }
531
+
532
+ /**
533
+ * Prevents template types to be deleted.
534
  *
535
+ * @param integer $term The Term Id.
536
+ * @param string $taxonomy Taxonomy name.
537
  */
538
+ public function restrict_template_taxonomy_deletion( $term, $taxonomy ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
539
+ if ( 'wp_template_type' === $taxonomy ) {
540
+ wp_die( esc_html__( 'Template Types cannon be deleted.' ) );
541
+ }
542
  }
543
  }
full-site-editing/dist/full-site-editing.css CHANGED
@@ -1 +1 @@
1
- .wp-block-a8c-navigation-menu.main-navigation{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;font-size:1.125em;font-weight:700;letter-spacing:-.02em;line-height:1.2;pointer-events:none;-webkit-font-smoothing:antialiased}.wp-block-a8c-navigation-menu.main-navigation .main-menu{display:inline-block;margin:0;padding:0}.wp-block-a8c-navigation-menu.main-navigation .main-menu>li{color:#0073aa;display:inline;position:relative}.wp-block-a8c-navigation-menu.main-navigation .main-menu>li>a{font-weight:700;color:#0073aa;margin-right:.5rem}.main-navigation .main-menu>li:last-child.menu-item-has-children .submenu-expand,.wp-block-a8c-navigation-menu.main-navigation .main-menu>li:last-child>a{margin-right:0}.wp-block-a8c-navigation-menu.main-navigation .main-menu>li.menu-item-has-children>a{margin-right:.125rem}.wp-block-a8c-navigation-menu.main-navigation .main-menu>li.menu-item-has-children{display:inline-block;position:inherit}.wp-block-a8c-navigation-menu.main-navigation .main-menu>li.menu-item-has-children .submenu-expand{display:inline-block;margin-right:.25rem}.wp-block-a8c-navigation-menu.main-navigation .main-menu>li.menu-item-has-children .submenu-expand svg{position:relative;top:.3rem}.main-navigation .main-menu>li>a:hover+svg,.wp-block-a8c-navigation-menu.main-navigation .main-menu>li>a:hover{color:#005177}.wp-block-a8c-navigation-menu.main-navigation .main-menu-more{display:none}.wp-block-a8c-navigation-menu.main-navigation svg{transition:fill .12s ease-in-out;fill:currentColor}.wp-block-a8c-navigation-menu.main-navigation a{text-decoration:none}.wp-block-a8c-navigation-menu.main-navigation button{display:inline-block;border:none;padding:0;margin:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;font-size:.88889em;font-weight:700;line-height:1.2;text-decoration:none;vertical-align:bottom;background:transparent;color:inherit;cursor:pointer;transition:background .25s ease-in-out,transform .15s ease;-webkit-appearance:none;-moz-appearance:none}.wp-block-a8c-navigation-menu.main-menu-more{display:none}.wp-block-a8c-navigation-menu.social-navigation{line-height:1.25;margin-top:.5rem;text-align:left}.wp-block-a8c-navigation-menu.social-navigation ul.social-links-menu{content:"";display:inline-block;margin:0;padding:0}.wp-block-a8c-navigation-menu.social-navigation ul.social-links-menu li{display:inline-block;vertical-align:bottom;vertical-align:-webkit-baseline-middle;list-style:none}.wp-block-a8c-navigation-menu.social-navigation ul.social-links-menu li a svg{display:block;width:32px;height:32px;transform:translateZ(0)}.wp-block-a8c-navigation-menu.footer-navigation .footer-menu{display:inline;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;font-size:.71111em;padding-left:0}.wp-block-a8c-navigation-menu.footer-navigation .footer-menu li{display:inline;margin-right:1rem}.wp-block-a8c-navigation-menu.footer-navigation .footer-menu a{text-decoration:none;color:#767676}.wp-block-a8c-navigation-menu.footer-navigation .footer-menu a:hover{text-decoration:none;color:#0073aa}.editor-styles-wrapper .wp-block-a8c-navigation-menu-toolbar a,.editor-styles-wrapper .wp-block-a8c-navigation-menu-toolbar a:hover{color:#555d66}.a8c-post-autocomplete{position:relative}.a8c-post-autocomplete .components-spinner{bottom:7px;position:absolute;right:-5px}.a8c-post-autocomplete__suggestions{max-height:200px;overflow-y:auto;width:302px}.a8c-post-autocomplete__suggestions .components-button{display:block;height:auto;min-height:30px;white-space:normal;width:100%;word-wrap:break-word}.post-content-block.alignfull{padding:0 12px}.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{content:"";clear:both;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 .wp-block-a8c-site-description,.block-editor .wp-block-a8c-site-description:focus{display:inline;color:#767676;font-size:1.125em;font-weight:400;letter-spacing:-.01em;margin:0;box-shadow:none;background-color:transparent}.block-editor .site-description__save-button{margin-left:auto;display:block}.block-editor .site-title:not(:empty)+.site-description:not(:empty):before{content:"\2014";margin:0 .2em}.block-editor .wp-block-a8c-site-title,.block-editor .wp-block-a8c-site-title:focus{display:inline;color:#111;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;font-size:1.125em;font-weight:400;letter-spacing:-.02em;line-height:1.2;margin:0;box-shadow:none;background-color:transparent}.block-editor .site-title__save-button{margin-left:auto;display:block}.block-editor .site-title a:link,.block-editor .site-title a:visited{color:#111;text-decoration:none;font-weight:400}.template-block{min-height:200px}.template-block:hover .template-block__overlay{display:flex}.template-block.alignfull{padding:0 12px}.template-block__selector{width:300px}.template-block__selector a{font-family:sans-serif;font-size:13px;padding-left:8px}.template-block__content{pointer-events:none}.template-block__content:after{content:"";clear:both;display:table}.template-block__overlay{display:none;position:absolute;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.75)}.template-block__overlay .components-placeholder__instructions{color:#fff}.wp-block-a8c-site-logo{pointer-events:none}
1
+ .wp-block-a8c-navigation-menu.main-navigation{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;font-size:1.125em;font-weight:700;letter-spacing:-.02em;line-height:1.2;pointer-events:none;-webkit-font-smoothing:antialiased}.wp-block-a8c-navigation-menu.main-navigation .main-menu{display:inline-block;margin:0;padding:0}.wp-block-a8c-navigation-menu.main-navigation .main-menu>li{color:#0073aa;display:inline;position:relative}.wp-block-a8c-navigation-menu.main-navigation .main-menu>li>a{font-weight:700;color:#0073aa;margin-right:.5rem}.main-navigation .main-menu>li:last-child.menu-item-has-children .submenu-expand,.wp-block-a8c-navigation-menu.main-navigation .main-menu>li:last-child>a{margin-right:0}.wp-block-a8c-navigation-menu.main-navigation .main-menu>li.menu-item-has-children>a{margin-right:.125rem}.wp-block-a8c-navigation-menu.main-navigation .main-menu>li.menu-item-has-children{display:inline-block;position:inherit}.wp-block-a8c-navigation-menu.main-navigation .main-menu>li.menu-item-has-children .submenu-expand{display:inline-block;margin-right:.25rem}.wp-block-a8c-navigation-menu.main-navigation .main-menu>li.menu-item-has-children .submenu-expand svg{position:relative;top:.3rem}.main-navigation .main-menu>li>a:hover+svg,.wp-block-a8c-navigation-menu.main-navigation .main-menu>li>a:hover{color:#005177}.wp-block-a8c-navigation-menu.main-navigation .main-menu-more{display:none}.wp-block-a8c-navigation-menu.main-navigation svg{transition:fill .12s ease-in-out;fill:currentColor}.wp-block-a8c-navigation-menu.main-navigation a{text-decoration:none}.wp-block-a8c-navigation-menu.main-navigation button{display:inline-block;border:none;padding:0;margin:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;font-size:.88889em;font-weight:700;line-height:1.2;text-decoration:none;vertical-align:bottom;background:transparent;color:inherit;cursor:pointer;transition:background .25s ease-in-out,transform .15s ease;-webkit-appearance:none;-moz-appearance:none}.wp-block-a8c-navigation-menu.main-menu-more{display:none}.wp-block-a8c-navigation-menu.social-navigation{line-height:1.25;margin-top:.5rem;text-align:left}.wp-block-a8c-navigation-menu.social-navigation ul.social-links-menu{content:"";display:inline-block;margin:0;padding:0}.wp-block-a8c-navigation-menu.social-navigation ul.social-links-menu li{display:inline-block;vertical-align:bottom;vertical-align:-webkit-baseline-middle;list-style:none}.wp-block-a8c-navigation-menu.social-navigation ul.social-links-menu li a svg{display:block;width:32px;height:32px;transform:translateZ(0)}.wp-block-a8c-navigation-menu.footer-navigation .footer-menu{display:inline;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;font-size:.71111em;padding-left:0}.wp-block-a8c-navigation-menu.footer-navigation .footer-menu li{display:inline;margin-right:1rem}.wp-block-a8c-navigation-menu.footer-navigation .footer-menu a{text-decoration:none;color:#767676}.wp-block-a8c-navigation-menu.footer-navigation .footer-menu a:hover{text-decoration:none;color:#0073aa}.editor-styles-wrapper .wp-block-a8c-navigation-menu-toolbar a,.editor-styles-wrapper .wp-block-a8c-navigation-menu-toolbar a:hover{color:#555d66}.post-content-block.alignfull{padding:0 12px}.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{content:"";clear:both;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{transition:none;border:none;outline:none;box-shadow: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}.block-editor .wp-block-a8c-site-description,.block-editor .wp-block-a8c-site-description:focus{display:inline;color:#767676;font-size:1.125em;font-weight:400;letter-spacing:-.01em;margin:0;box-shadow:none;background-color:transparent}.block-editor .site-description__save-button{margin-left:auto;display:block}.block-editor .site-title:not(:empty)+.site-description:not(:empty):before{content:"\2014";margin:0 .2em}.block-editor .wp-block-a8c-site-title,.block-editor .wp-block-a8c-site-title:focus{display:inline;color:#111;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;font-size:1.125em;font-weight:400;letter-spacing:-.02em;line-height:1.2;margin:0;box-shadow:none;background-color:transparent}.block-editor .site-title__save-button{margin-left:auto;display:block}.block-editor .site-title a:link,.block-editor .site-title a:visited{color:#111;text-decoration:none;font-weight:400}.template-block{min-height:200px}.template-block .components-button .components-spinner{margin-top:4px}.template-block.alignfull{padding:0 12px}.template-block__selector{width:300px}.template-block__selector a{font-family:sans-serif;font-size:13px;padding-left:8px}.template-block__content{pointer-events:none}.template-block__content:after{content:"";clear:both;display:table}.template-block__overlay{display:flex;position:absolute;top:0;left:2px;width:100%;height:100%;justify-content:center;align-items:center;background:hsla(0,0%,96.1%,.8);z-index:2}.block-editor-block-list__layout .template__block-container .wp-block{margin-top:15px;margin-bottom:15px}.block-editor-block-list__layout .template__block-container.is-hovered{cursor:pointer}.block-editor-block-list__layout .template__block-container.is-selected .block-editor-block-contextual-toolbar{display:none}.block-editor-block-list__layout .template__block-container.is-selected .components-disabled{filter:blur(2px)}.block-editor-block-list__layout .template__block-container.block-editor-block-list__block.has-child-selected>.block-editor-block-list__block-edit:before,.block-editor-block-list__layout .template__block-container.block-editor-block-list__block.is-hovered>.block-editor-block-list__block-edit:before,.block-editor-block-list__layout .template__block-container.block-editor-block-list__block.is-navigate-mode>.block-editor-block-list__block-edit:before,.block-editor-block-list__layout .template__block-container.block-editor-block-list__block>.block-editor-block-list__block-edit:before{transition:none;border:none;outline:none;box-shadow:none}.block-editor-block-list__layout .template__block-container.block-editor-block-list__block.has-child-selected>.block-editor-block-list__block-edit>.block-editor-block-list__breadcrumb,.block-editor-block-list__layout .template__block-container.block-editor-block-list__block.is-hovered>.block-editor-block-list__block-edit>.block-editor-block-list__breadcrumb,.block-editor-block-list__layout .template__block-container.block-editor-block-list__block.is-navigate-mode>.block-editor-block-list__block-edit>.block-editor-block-list__breadcrumb,.block-editor-block-list__layout .template__block-container.block-editor-block-list__block>.block-editor-block-list__block-edit>.block-editor-block-list__breadcrumb,.block-editor-page:not(.post-type-wp_template) .fse-site-logo .components-placeholder__fieldset,.block-editor-page:not(.post-type-wp_template) .fse-site-logo .components-placeholder__instructions{display:none}.edit-post-fullscreen-mode-close__toolbar a.is-button.is-default{height:auto}.edit-post-fullscreen-mode-close__toolbar a.is-button.is-default span{display:none}.edit-post-fullscreen-mode-close__toolbar a.a8c-close-button{padding:4px}.post-type-wp_template .editor-post-title,.post-type-wp_template .editor-post-trash{display:none}.post-type-wp_template .edit-post-visual-editor{margin-top:20px;padding-top:0}.post-type-wp_template .editor-post-switch-to-draft{display:none}.post-type-wp_template .editor-block-list__layout{padding-top:28px}.post-type-wp_template .editor-styles-wrapper [data-block]{margin-top:15px;margin-bottom:15px}.post-type-page .edit-post-layout__content,.post-type-wp_template .edit-post-layout__content{background:#eee}.post-type-page .edit-post-layout__content .edit-post-visual-editor,.post-type-wp_template .edit-post-layout__content .edit-post-visual-editor{flex:none;margin:36px 32px;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)}@media (max-width:768px){.post-type-page .edit-post-layout__content .edit-post-visual-editor,.post-type-wp_template .edit-post-layout__content .edit-post-visual-editor{margin:0}}.editor-styles-wrapper{background:#fff}.post-type-page .edit-post-visual-editor{padding:0 0 4px}.post-type-page .block-editor-writing-flow{display:block}.post-type-page .wp-block[data-type="a8c/template"] [data-block]{margin:0}
full-site-editing/dist/full-site-editing.deps.json CHANGED
@@ -1 +1 @@
1
- ["lodash","wp-api-fetch","wp-blocks","wp-components","wp-compose","wp-data","wp-dom-ready","wp-edit-post","wp-editor","wp-element","wp-i18n","wp-plugins","wp-url"]
1
+ ["lodash","wp-api-fetch","wp-blocks","wp-components","wp-compose","wp-data","wp-dom-ready","wp-editor","wp-element","wp-hooks","wp-i18n","wp-keycodes","wp-plugins","wp-polyfill","wp-url"]
full-site-editing/dist/full-site-editing.js CHANGED
@@ -1,4 +1,4 @@
1
- !function(e,t){for(var n in t)e[n]=t[n]}(window,function(e){var t={};function n(o){if(t[o])return t[o].exports;var i=t[o]={i:o,l:!1,exports:{}};return e[o].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(o,i,function(t){return e[t]}.bind(null,i));return o},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=43)}([function(e,t){e.exports=wp.element},function(e,t){e.exports=wp.i18n},function(e,t){e.exports=wp.components},function(e,t){e.exports=wp.data},function(e,t){e.exports=wp.compose},function(e,t){e.exports=lodash},function(e,t){e.exports=wp.editor},function(e,t){e.exports=wp.blocks},function(e,t){e.exports=function(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}},function(e,t,n){var o=n(8);e.exports=function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{},i=Object.keys(n);"function"==typeof Object.getOwnPropertySymbols&&(i=i.concat(Object.getOwnPropertySymbols(n).filter(function(e){return Object.getOwnPropertyDescriptor(n,e).enumerable}))),i.forEach(function(t){o(e,t,n[t])})}return e}},function(e,t,n){var o;
2
  /*!
3
  Copyright (c) 2017 Jed Watson.
4
  Licensed under the MIT License (MIT), see
@@ -9,4 +9,4 @@
9
  Licensed under the MIT License (MIT), see
10
  http://jedwatson.github.io/classnames
11
  */
12
- !function(){"use strict";var n={}.hasOwnProperty;function i(){for(var e=[],t=0;t<arguments.length;t++){var o=arguments[t];if(o){var r=typeof o;if("string"===r||"number"===r)e.push(o);else if(Array.isArray(o)&&o.length){var c=i.apply(null,o);c&&e.push(c)}else if("object"===r)for(var l in o)n.call(o,l)&&o[l]&&e.push(l)}}return e.join(" ")}e.exports?(i.default=i,e.exports=i):void 0===(o=function(){return i}.apply(t,[]))||(e.exports=o)}()},function(e,t){e.exports=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}},function(e,t){function n(e,t){for(var n=0;n<t.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}e.exports=function(e,t,o){return t&&n(e.prototype,t),o&&n(e,o),e}},function(e,t,n){var o=n(27),i=n(19);e.exports=function(e,t){return!t||"object"!==o(t)&&"function"!=typeof t?i(e):t}},function(e,t){function n(t){return e.exports=n=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},n(t)}e.exports=n},function(e,t,n){var o=n(28);e.exports=function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&o(e,t)}},function(e,t){e.exports=wp.url},function(e,t){e.exports=wp.domReady},function(e,t){e.exports=wp.apiFetch},function(e,t){e.exports=function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}},function(e,t,n){var o=n(29),i=n(30),r=n(31);e.exports=function(e,t){return o(e)||i(e,t)||r()}},function(e,t){e.exports=wp.editPost},function(e,t,n){},function(e,t){function n(e,t,n,o,i,r,c){try{var l=e[r](c),a=l.value}catch(s){return void n(s)}l.done?t(a):Promise.resolve(a).then(o,i)}e.exports=function(e){return function(){var t=this,o=arguments;return new Promise(function(i,r){var c=e.apply(t,o);function l(e){n(c,i,r,l,a,"next",e)}function a(e){n(c,i,r,l,a,"throw",e)}l(void 0)})}}},function(e,t){e.exports=wp.plugins},function(e,t,n){},,function(e,t){function n(e){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function o(t){return"function"==typeof Symbol&&"symbol"===n(Symbol.iterator)?e.exports=o=function(e){return n(e)}:e.exports=o=function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":n(e)},o(t)}e.exports=o},function(e,t){function n(t,o){return e.exports=n=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},n(t,o)}e.exports=n},function(e,t){e.exports=function(e){if(Array.isArray(e))return e}},function(e,t){e.exports=function(e,t){var n=[],o=!0,i=!1,r=void 0;try{for(var c,l=e[Symbol.iterator]();!(o=(c=l.next()).done)&&(n.push(c.value),!t||n.length!==t);o=!0);}catch(a){i=!0,r=a}finally{try{o||null==l.return||l.return()}finally{if(i)throw r}}return n}},function(e,t){e.exports=function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}},function(e,t,n){},,function(e,t,n){},,function(e,t,n){},,function(e,t,n){},,,function(e,t,n){},,function(e,t,n){"use strict";n.r(t);var o=n(0),i=n(7),r=n(1),c=n(2),l=function(e){var t=e.attributes;return Object(o.createElement)(o.Fragment,null,Object(o.createElement)(c.ServerSideRender,{attributes:t,block:"a8c/navigation-menu"}))},a=(n(25),Object(o.createElement)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},Object(o.createElement)("path",{fill:"none",d:"M0 0h24v24H0V0z"}),Object(o.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"})));Object(i.registerBlockType)("a8c/navigation-menu",{title:Object(r.__)("Navigation Menu"),description:Object(r.__)("Visual placeholder for site-wide navigation and menus."),icon:a,category:"layout",supports:{html:!1,reusable:!1},edit:l,save:function(){return null}});var s=n(8),u=n.n(s),p=n(11),d=n.n(p),b=n(12),f=n.n(b),m=n(13),g=n.n(m),O=n(14),h=n.n(O),v=n(15),j=n.n(v),y=n(10),_=n.n(y),S=n(5),E=n(4),P=n(3),w=n(6),k=n(20),x=n.n(k),T=n(9),C=n.n(T),B=n(23),I=n.n(B),N=n(18),R=n.n(N),U=n(16),L=(n(32),Object(S.debounce)(function(){var e=I()(regeneratorRuntime.mark(function e(t,n,o){var i;return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return o({loading:!0,showSuggestions:!0,suggestions:[]}),e.next=3,R()({path:Object(U.addQueryArgs)("/wp/v2/search",C()({context:"embed",per_page:20,search:t},!!n&&{subtype:n}))});case 3:i=e.sent,o({loading:!1,showSuggestions:!0,suggestions:i});case 5:case"end":return e.stop()}},e)}));return function(t,n,o){return e.apply(this,arguments)}}(),200)),A=Object(E.withState)({loading:!1,showSuggestions:!1,suggestions:[]})(function(e){var t=e.initialValue,n=e.loading,i=e.onSelectPost,l=e.postType,a=e.setState,s=e.showSuggestions,u=e.suggestions,p=Object(o.useState)(t),d=x()(p,2),b=d[0],f=d[1],m=function(e){return function(){var t=function(e,t,n){var o=e.id,i=e.title,r=e.subtype;return t({loading:!1,showSuggestions:!1,suggestions:[]}),n(i),{id:o,type:r}}(e,a,f);i(t)}};return Object(o.createElement)("div",{className:"a8c-post-autocomplete"},Object(o.createElement)(c.TextControl,{autoComplete:"off",onChange:function(e){f(e),e.length<2?a({loading:!1,showSuggestions:!1}):L(e,l,a)},placeholder:Object(r.__)("Type to search"),type:"search",value:b}),n&&Object(o.createElement)(c.Spinner,null),s&&!!u.length&&Object(o.createElement)(c.Popover,{focusOnMount:!1,noArrow:!0,position:"bottom"},Object(o.createElement)("div",{className:"a8c-post-autocomplete__suggestions"},Object(S.map)(u,function(e){return Object(o.createElement)(c.Button,{isLarge:!0,isLink:!0,key:e.id,onClick:m(e)},e.title)}))))}),M=function(e){function t(){return d()(this,t),g()(this,h()(t).apply(this,arguments))}return j()(t,e),f()(t,[{key:"toggleEditing",value:function(){var e=this.props,t=e.isEditing;(0,e.setState)({isEditing:!t})}},{key:"onSelectPost",value:function(e){var t=e.id,n=e.type;this.props.setState({isEditing:!1,selectedPostId:t,selectedPostType:n})}},{key:"render",value:function(){var e=this.props,t=e.attributes,n=e.isEditing,i=e.selectedPost,l=t.align,a="wp_template"===fullSiteEditing.editorPostType,s=a&&(!n||!!i),p=a&&(n||!i),d=a&&!n&&!!i,b=!a;return Object(o.createElement)(o.Fragment,null,s&&Object(o.createElement)(w.BlockControls,null,Object(o.createElement)(c.Toolbar,null,Object(o.createElement)(c.IconButton,{className:_()("components-icon-button components-toolbar__control",{"is-active":n}),label:Object(r.__)("Change Preview"),onClick:this.toggleEditing,icon:"edit"}))),Object(o.createElement)("div",{className:_()("post-content-block",u()({},"align".concat(l),l))},Object(o.createElement)(w.PostTitle,null),b&&Object(o.createElement)(w.InnerBlocks,{templateLock:!1}),p&&Object(o.createElement)(c.Placeholder,{icon:"layout",label:Object(r.__)("Content Slot"),instructions:Object(r.__)("Placeholder for a post or a page.")},Object(o.createElement)("div",{className:"post-content-block__selector"},Object(o.createElement)("div",null,Object(r.__)("Select something to preview:")),Object(o.createElement)(A,{initialValue:Object(S.get)(i,["title","rendered"]),onSelectPost:this.onSelectPost,postType:["page","post"]}),!!i&&Object(o.createElement)("a",{href:"?post=".concat(i.id,"&action=edit")},Object(r.sprintf)(Object(r.__)('Edit "%s"'),Object(S.get)(i,["title","rendered"],""))))),d&&Object(o.createElement)(o.RawHTML,{className:"post-content-block__preview"},Object(S.get)(i,["content","rendered"]))))}}]),t}(o.Component),z=Object(E.compose)([Object(E.withState)({isEditing:!1,selectedPostId:void 0,selectedPostType:void 0}),Object(P.withSelect)(function(e,t){var n=t.selectedPostId,o=t.selectedPostType;return{selectedPost:(0,e("core").getEntityRecord)("postType",o,n)}})])(M),D="wp_template"===fullSiteEditing.editorPostType?function(){return null}:function(){return Object(o.createElement)(w.InnerBlocks.Content,null)};n(34);function F(e){var t=Object(o.useRef)();return Object(o.useEffect)(function(){t.current=e},[e]),t.current}function V(e,t,n,i,c,l){var a=Object(o.useState)({option:t,previousOption:"",loaded:!1,error:!1}),s=x()(a,2),p=s[0],d=s[1],b=F(i),f=F(c);function m(){d(C()({},p,{option:p.previousOption,isSaving:!1}))}return Object(o.useEffect)(function(){p.loaded||p.error?function(){var t=p.option,o=p.previousOption,l=t&&t.trim()===o.trim(),a=!t||0===t.trim().length;!i&&b&&a&&m();if(!c||l)return;!f&&c&&function(t){d(C()({},p,{isSaving:!0})),R()({path:"/wp/v2/settings",method:"POST",data:u()({},e,t)}).then(function(){return function(e){d(C()({},p,{previousOption:e,isDirty:!1,isSaving:!1}))}(t)}).catch(function(){n(Object(r.sprintf)(Object(r.__)("Unable to save site %s"),e)),m()})}(t)}():R()({path:"/wp/v2/settings"}).then(function(t){return d(C()({},p,{option:t[e],previousOption:t[e],loaded:!0,error:!1}))}).catch(function(){n(Object(r.sprintf)(Object(r.__)("Unable to load site %s"),e)),d(C()({},p,{option:Object(r.sprintf)(Object(r.__)("Error loading site %s"),e),error:!0}))})}),{siteOptions:p,handleChange:function(e){l({updated:Date.now()}),d(C()({},p,{option:e}))}}}Object(i.registerBlockType)("a8c/post-content",{title:Object(r.__)("Content Slot"),description:Object(r.__)("Placeholder for a post or a page."),icon:"layout",category:"layout",supports:{anchor:!0,html:!1,multiple:!1,reusable:!1},edit:z,save:D});var H=Object(E.compose)([Object(P.withDispatch)(function(e){return{createErrorNotice:e("core/notices").createErrorNotice}}),Object(P.withSelect)(function(e){var t=e("core/editor"),n=t.isSavingPost,o=t.isPublishingPost,i=t.isAutosavingPost,r=t.isCurrentPostPublished;return{shouldUpdateSiteOption:(n()&&r()||o())&&!i()}})])(function(e){var t=e.className,n=e.createErrorNotice,i=e.shouldUpdateSiteOption,c=e.isSelected,l=e.setAttributes,a=V("description",Object(r.__)("Site description loading…"),n,c,i,l),s=a.siteOptions,u=a.handleChange,p=s.option;return Object(o.createElement)(o.Fragment,null,Object(o.createElement)(w.PlainText,{className:t,value:p,onChange:function(e){return u(e)},placeholder:Object(r.__)("Site Description"),"aria-label":Object(r.__)("Site Description")}))});n(36);Object(i.registerBlockType)("a8c/site-description",{title:Object(r.__)("Site Description"),description:Object(r.__)("Site description, also known as the tagline."),icon:Object(o.createElement)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24"},Object(o.createElement)("path",{fill:"none",d:"M0 0h24v24H0z"}),Object(o.createElement)("path",{d:"M4 9h16v2H4V9zm0 4h10v2H4v-2z"})),category:"layout",supports:{html:!1,multiple:!1,reusable:!1},edit:H,save:function(){return null}});var q=Object(E.compose)([Object(P.withDispatch)(function(e){return{createErrorNotice:e("core/notices").createErrorNotice}}),Object(P.withSelect)(function(e){var t=e("core/editor"),n=t.isSavingPost,o=t.isPublishingPost,i=t.isAutosavingPost,r=t.isCurrentPostPublished;return{shouldUpdateSiteOption:(n()&&r()||o())&&!i()}})])(function(e){var t=e.className,n=e.createErrorNotice,i=e.shouldUpdateSiteOption,c=e.isSelected,l=e.setAttributes,a=V("title",Object(r.__)("Site title loading…"),n,c,i,l),s=a.siteOptions,u=a.handleChange,p=s.option;return Object(o.createElement)(o.Fragment,null,Object(o.createElement)(w.PlainText,{className:_()("site-title",t),value:p,onChange:function(e){return u(e)},placeholder:Object(r.__)("Site Title"),"aria-label":Object(r.__)("Site Title")}))});n(38);Object(i.registerBlockType)("a8c/site-title",{title:Object(r.__)("Site Title"),description:Object(r.__)("Your site title."),icon:"layout",category:"layout",supports:{html:!1,multiple:!1,reusable:!1},edit:q,save:function(){return null}});n(22);var Q=Object(E.compose)(Object(E.withState)({templateClientId:null}),Object(P.withSelect)(function(e,t){var n=t.attributes,o=t.templateClientId,i=e("core").getEntityRecord,r=e("core/editor").getCurrentPostId,c=e("core/block-editor").getBlock,l=n.templateId,a=r(),s=l&&i("postType","wp_template_part",l);return{currentPostId:a,editTemplatePartUrl:Object(U.addQueryArgs)(fullSiteEditing.editTemplatePartBaseUrl,{post:l,fse_parent_post:a}),template:s,templateBlock:c(o),templateTitle:Object(S.get)(s,["title","rendered"],"")}}),Object(P.withDispatch)(function(e,t){var n=e("core/block-editor").receiveBlocks,o=t.template,r=t.templateClientId,c=t.setState;return{receiveTemplateBlocks:function(){if(o&&!r){var e=Object(i.parse)(Object(S.get)(o,["content","raw"],"")),t=1===e.length?e[0]:Object(i.createBlock)("core/template",{},e);n([t]),c({templateClientId:t.clientId})}}}}))(function(e){var t=e.attributes,n=e.editTemplatePartUrl,i=e.receiveTemplateBlocks,l=e.template,a=e.templateBlock,s=e.templateTitle;if(!l)return Object(o.createElement)(c.Placeholder,null,Object(o.createElement)(c.Spinner,null));Object(o.useEffect)(function(){i()});var p=t.align;return Object(o.createElement)("div",{className:_()("template-block",u()({},"align".concat(p),p))},a&&Object(o.createElement)(o.Fragment,null,Object(o.createElement)(c.Disabled,null,Object(o.createElement)(w.BlockEdit,{attributes:a.attributes,block:a,clientId:a.clientId,isSelected:!1,name:a.name,setAttributes:S.noop})),Object(o.createElement)(c.Placeholder,{className:"template-block__overlay",instructions:Object(r.__)("This block is part of your site template and may appear on multiple pages.")},Object(o.createElement)(c.Button,{href:n,isDefault:!0},Object(r.sprintf)(Object(r.__)("Edit %s"),s)))))});"wp_template_part"!==fullSiteEditing.editorPostType&&Object(i.registerBlockType)("a8c/template",{title:Object(r.__)("Template Part"),description:Object(r.__)("Display a template part."),icon:"layout",category:"layout",attributes:{templateId:{type:"number"}},supports:{anchor:!0,html:!1,reusable:!1},edit:Q,save:function(){return null},getEditWrapperProps:function(){return{"data-align":"full"}}});var G=function(e){var t=e.className;return Object(o.createElement)(o.Fragment,null,Object(o.createElement)(w.BlockControls,null,Object(o.createElement)(c.Toolbar,null,Object(o.createElement)(c.IconButton,{className:"components-toolbar__control",icon:"edit",label:Object(r.__)("Edit Site Logo"),onClick:function(){var e=Object(U.addQueryArgs)("customize.php",{"autofocus[section]":"title_tagline",return:window.location.href});window.location.href=e}}))),Object(o.createElement)(c.ServerSideRender,{className:t,block:"a8c/site-logo",attributes:{editorPreview:!0}}))};n(41);Object(i.registerBlockType)("a8c/site-logo",{title:Object(r.__)("Site Logo"),description:Object(r.__)("Site Logo"),icon:"format-image",category:"layout",keywords:[Object(r.__)("logo"),Object(r.__)("icon"),Object(r.__)("site")],edit:G,save:function(){return null}});var W=n(21),Y=n(24),J=Object(E.compose)(Object(P.withDispatch)(function(e){return{setTemplateId:function(t){return e("core/editor").editPost({meta:{_wp_template_id:t}})}}}),Object(P.withSelect)(function(e){var t=e("core"),n=t.canUser,o=t.getEntityRecord,i=Object(S.get)(e("core/editor").getEditedPostAttribute("meta"),"_wp_template_id");return{canUserUpdateSettings:n("update","settings"),selectedTemplate:i&&o("postType","wp_template",i)}}))(function(e){var t=e.canUserUpdateSettings,n=e.setTemplateId,i=e.selectedTemplate;if(!t)return null;return Object(o.createElement)(o.Fragment,null,Object(o.createElement)(W.PluginSidebarMoreMenuItem,{target:"fse-template-sidebar",icon:"layout"},Object(r.__)("Template")),Object(o.createElement)(W.PluginSidebar,{icon:"layout",name:"fse-template-sidebar",title:Object(r.__)("Template")},Object(o.createElement)(c.PanelBody,null,Object(r.__)("Select a template"),Object(o.createElement)(A,{initialValue:Object(S.get)(i,["title","rendered"]),onSelectPost:function(e){var t=e.id;n(parseInt(t,10))},postType:"wp_template"}))))});"page"===fullSiteEditing.editorPostType&&Object(Y.registerPlugin)("fse-template-selector-sidebar",{render:J});var K=n(17),X=n.n(K);X()(function(){if("wp_template_part"===fullSiteEditing.editorPostType&&fullSiteEditing.closeButtonUrl)var e=setInterval(function(){var t=document.querySelector(".edit-post-fullscreen-mode-close__toolbar a");t&&(clearInterval(e),fullSiteEditing.closeButtonUrl&&(t.href=fullSiteEditing.closeButtonUrl))})});var Z=n(19),$=n.n(Z),ee=function(e){function t(){return d()(this,t),g()(this,h()(t).apply(this,arguments))}return j()(t,e),f()(t,[{key:"render",value:function(){var e=this.props,t=e.onSave,n=e.onClose,i=e.isBusy,l=e.disabled;return Object(o.createElement)("div",{className:"edit-post-layout"},Object(o.createElement)("div",{className:"editor-post-publish-panel"},Object(o.createElement)("div",{className:"editor-post-publish-panel__header"},Object(o.createElement)("div",{className:"editor-post-publish-panel__header-publish-button"},Object(o.createElement)(c.Button,{isPrimary:!0,isLarge:!0,isBusy:i,onClick:t,disabled:l},Object(r.__)("Publish")),Object(o.createElement)("span",{className:"editor-post-publish-panel__spacer"})),Object(o.createElement)(c.IconButton,{"aria-expanded":!0,onClick:n,icon:"no-alt",label:Object(r.__)("Close panel")})),Object(o.createElement)("div",{className:"editor-post-publish-panel__prepublish"},Object(o.createElement)("p",null,Object(o.createElement)("strong",null,Object(r.__)("Are you ready to publish?"))),Object(o.createElement)("p",null,Object(r.__)("Changes you publish will update all pages with this template part.")))))}}]),t}(o.Component),te={buttonStyle:{visibility:"hidden"},isPanelOpen:!1},ne=function(e){function t(e){var n;return d()(this,t),n=g()(this,h()(t).call(this,e)),u()($()(n),"onPublish",function(){n.togglePanel(),n.getOriginalButton().click()}),u()($()(n),"togglePanel",function(){n.setState({isPanelOpen:!n.state.isPanelOpen})}),n.onResize=Object(S.debounce)(n.onResize,100),n.state=te,n.onResize(),n}return j()(t,e),f()(t,[{key:"componentDidUpdate",value:function(e,t){var n=this;e.isFullScreen!==t.isFullScreen&&setTimeout(function(){return n.onResize()},1)}},{key:"getOriginalButton",value:function(){return document.querySelector(".edit-post-header .editor-post-publish-button")}},{key:"onResize",value:function(){var e=this.getOriginalButton(),t=te.buttonStyle;if(Object(S.isNil)(e)||!("getBoundingClientRect"in e))return this.setState({buttonStyle:t});var n=e.getBoundingClientRect();t={height:"33px",position:"fixed",zIndex:"10001",top:n.top,left:n.x},window.matchMedia("(min-width: 600px)").matches||(t.paddingLeft="5px",t.paddingRight="5px"),this.setState({buttonStyle:t})}},{key:"getHidingCss",value:function(){return".edit-post-header .editor-post-publish-button {\n\t\t\tvisibility: hidden !important;\n\t\t}"}},{key:"render",value:function(){if(!this.shouldRender())return null;var e=this.props,t=e.isSaving,n=e.isSaveable,i=e.isPostSavingLocked,l=e.isPublishable,a=t||!n||i||!l;return Object(o.createElement)(o.Fragment,null,Object(o.createElement)(c.Button,{onClick:this.togglePanel,isPrimary:!0,isLarge:!0,style:this.state.buttonStyle,disabled:a,isBusy:this.isSaving},Object(r.__)("Update")),this.state.isPanelOpen&&Object(o.createElement)(ee,{isBusy:this.isSaving,onClose:this.togglePanel,onSave:this.onPublish,disabled:a}),Object(o.createElement)("style",null,this.getHidingCss()))}},{key:"shouldRender",value:function(){var e=this.props,t=e.isPublished,n=e.isPublishable,o=e.isSaveable;return!!(t&&n&&o)}}]),t}(o.Component),oe=Object(E.compose)([Object(P.withSelect)(function(e){var t=e("core/editor"),n=t.isSavingPost,o=t.isCurrentPostPublished,i=t.isEditedPostSaveable,r=t.isEditedPostPublishable,c=t.isPostSavingLocked,l=t.getCurrentPost;return{isSaving:n(),isSaveable:i(),isPostSavingLocked:c(),isPublishable:r(),isPublished:o(),hasPublishAction:Object(S.get)(l(),["_links","wp:action-publish"],!1),isFullScreen:e("core/edit-post").isFeatureActive("fullscreenMode")}}),Object(E.withGlobalEvents)({resize:"onResize"})])(ne);X()(function(){if("wp_template_part"===fullSiteEditing.editorPostType){var e=document.createElement("div");e.id="template-update-confirmation",document.getElementById("wpcontent").appendChild(e),Object(o.render)(Object(o.createElement)(oe,null),e)}});var ie=Object(E.compose)(Object(P.withSelect)(function(e){var t=e("core/editor"),n=t.getBlocks,o=t.getEditorSettings,i=e("core/edit-post").getEditorMode,r=n().find(function(e){return"a8c/post-content"===e.name});return{rootClientId:r?r.clientId:"",showInserter:"visual"===i()&&o().richEditingEnabled}}))(function(e){var t=e.rootClientId,n=e.showInserter;return Object(o.createElement)(w.Inserter,{rootClientId:t,disabled:!n,position:"bottom right"})});X()(function(){return function(){if("page"===fullSiteEditing.editorPostType)var e=setInterval(function(){var t=document.querySelector(".edit-post-header-toolbar");if(t){clearInterval(e);var n=document.createElement("div");n.classList.add("fse-post-content-block-inserter"),t.insertBefore(n,t.firstChild),Object(o.render)(Object(o.createElement)(ie,null),n)}})}()});var re=Object(P.subscribe)(function(){if("page"!==fullSiteEditing.editorPostType)return re();!1===Object(P.select)("core/editor").isValidTemplate()&&(Object(P.dispatch)("core/editor").setTemplateValidity(!0),re())})}]));
1
+ !function(e,t){for(var n in t)e[n]=t[n]}(window,function(e){var t={};function n(o){if(t[o])return t[o].exports;var r=t[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(o,r,function(t){return e[t]}.bind(null,r));return o},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=48)}([function(e,t){!function(){e.exports=this.wp.element}()},function(e,t){!function(){e.exports=this.wp.i18n}()},function(e,t){!function(){e.exports=this.wp.data}()},function(e,t){!function(){e.exports=this.wp.compose}()},function(e,t){!function(){e.exports=this.wp.blocks}()},function(e,t){!function(){e.exports=this.wp.editor}()},function(e,t){!function(){e.exports=this.lodash}()},function(e,t){!function(){e.exports=this.wp.components}()},function(e,t){!function(){e.exports=this.wp.hooks}()},function(e,t,n){var o;
2
  /*!
3
  Copyright (c) 2017 Jed Watson.
4
  Licensed under the MIT License (MIT), see
9
  Licensed under the MIT License (MIT), see
10
  http://jedwatson.github.io/classnames
11
  */
12
+ !function(){"use strict";var n={}.hasOwnProperty;function r(){for(var e=[],t=0;t<arguments.length;t++){var o=arguments[t];if(o){var i=typeof o;if("string"===i||"number"===i)e.push(o);else if(Array.isArray(o)&&o.length){var c=r.apply(null,o);c&&e.push(c)}else if("object"===i)for(var l in o)n.call(o,l)&&o[l]&&e.push(l)}}return e.join(" ")}e.exports?(r.default=r,e.exports=r):void 0===(o=function(){return r}.apply(t,[]))||(e.exports=o)}()},function(e,t){e.exports=function(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}},function(e,t,n){var o=n(10);function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,o)}return n}e.exports=function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?r(n,!0).forEach(function(t){o(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):r(n).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}},function(e,t){function n(){return e.exports=n=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var o in n)Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o])}return e},n.apply(this,arguments)}e.exports=n},function(e,t){!function(){e.exports=this.wp.domReady}()},function(e,t){!function(){e.exports=this.wp.keycodes}()},function(e,t,n){var o=n(33),r=n(34),i=n(35);e.exports=function(e,t){return o(e)||r(e,t)||i()}},function(e,t){!function(){e.exports=this.wp.apiFetch}()},function(e,t,n){},function(e,t){e.exports=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}},function(e,t){function n(e,t){for(var n=0;n<t.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}e.exports=function(e,t,o){return t&&n(e.prototype,t),o&&n(e,o),e}},function(e,t,n){var o=n(28),r=n(29);e.exports=function(e,t){return!t||"object"!==o(t)&&"function"!=typeof t?r(e):t}},function(e,t){function n(t){return e.exports=n=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},n(t)}e.exports=n},function(e,t,n){var o=n(30);e.exports=function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&o(e,t)}},function(e,t){!function(){e.exports=this.wp.url}()},function(e,t,n){var o=n(43),r=n(44),i=n(45);e.exports=function(e){return o(e)||r(e)||i()}},function(e,t){!function(){e.exports=this.wp.plugins}()},function(e,t,n){},,function(e,t){function n(e){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function o(t){return"function"==typeof Symbol&&"symbol"===n(Symbol.iterator)?e.exports=o=function(e){return n(e)}:e.exports=o=function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":n(e)},o(t)}e.exports=o},function(e,t){e.exports=function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}},function(e,t){function n(t,o){return e.exports=n=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},n(t,o)}e.exports=n},function(e,t,n){},,function(e,t){e.exports=function(e){if(Array.isArray(e))return e}},function(e,t){e.exports=function(e,t){var n=[],o=!0,r=!1,i=void 0;try{for(var c,l=e[Symbol.iterator]();!(o=(c=l.next()).done)&&(n.push(c.value),!t||n.length!==t);o=!0);}catch(a){r=!0,i=a}finally{try{o||null==l.return||l.return()}finally{if(r)throw i}}return n}},function(e,t){e.exports=function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}},function(e,t,n){},,function(e,t,n){},,,function(e,t,n){},,function(e,t){e.exports=function(e){if(Array.isArray(e)){for(var t=0,n=new Array(e.length);t<e.length;t++)n[t]=e[t];return n}}},function(e,t){e.exports=function(e){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e))return Array.from(e)}},function(e,t){e.exports=function(){throw new TypeError("Invalid attempt to spread non-iterable instance")}},function(e,t,n){},,function(e,t,n){"use strict";n.r(t);var o=n(0),r=n(4),i=n(1),c=n(7),l=function(e){var t=e.attributes;return Object(o.createElement)(o.Fragment,null,Object(o.createElement)(c.ServerSideRender,{attributes:t,block:"a8c/navigation-menu"}))},a=(n(26),Object(o.createElement)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},Object(o.createElement)("path",{fill:"none",d:"M0 0h24v24H0V0z"}),Object(o.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"})));Object(r.registerBlockType)("a8c/navigation-menu",{title:Object(i.__)("Navigation Menu"),description:Object(i.__)("Visual placeholder for site-wide navigation and menus."),icon:a,category:"layout",supports:{html:!1,reusable:!1},edit:l,save:function(){return null}});var s=n(12),u=n.n(s),p=n(3),f=n(8),d=n(10),b=n.n(d),m=n(18),O=n.n(m),g=n(19),v=n.n(g),h=n(20),y=n.n(h),j=n(21),w=n.n(j),S=n(22),k=n.n(S),E=n(9),_=n.n(E),x=n(2),P=n(5),T=function(e){function t(){return O()(this,t),y()(this,w()(t).apply(this,arguments))}return k()(t,e),v()(t,[{key:"toggleEditing",value:function(){var e=this.props,t=e.isEditing;(0,e.setState)({isEditing:!t})}},{key:"onSelectPost",value:function(e){var t=e.id,n=e.type;this.props.setState({isEditing:!1,selectedPostId:t,selectedPostType:n})}},{key:"render",value:function(){var e=this.props.attributes.align;return Object(o.createElement)(o.Fragment,null,Object(o.createElement)("div",{className:_()("post-content-block",b()({},"align".concat(e),e))},Object(o.createElement)(P.PostTitle,null),Object(o.createElement)(P.InnerBlocks,{templateLock:!1})))}}]),t}(o.Component),C=Object(p.compose)([Object(p.withState)({isEditing:!1,selectedPostId:void 0,selectedPostType:void 0}),Object(x.withSelect)(function(e,t){var n=t.selectedPostId,o=t.selectedPostType;return{selectedPost:(0,e("core").getEntityRecord)("postType",o,n)}})])(T);n(31);Object(r.registerBlockType)("a8c/post-content",{title:Object(i.__)("Content"),description:Object(i.__)("The page content."),icon:"layout",category:"layout",supports:{anchor:!1,customClassName:!1,html:!1,multiple:!1,reusable:!1},edit:C,save:function(){return Object(o.createElement)(P.InnerBlocks.Content,null)}});var I=Object(p.createHigherOrderComponent)(function(e){return function(t){return"a8c/post-content"!==t.name?Object(o.createElement)(e,t):Object(o.createElement)(e,u()({},t,{className:"post-content__block"}))}},"addContentSlotClassname");Object(f.addFilter)("editor.BlockListBlock","full-site-editing/blocks/post-content",I,9);var B=n(14),D=n(11),N=n.n(D),L=n(15),A=n.n(L),M=n(16),F=n.n(M);function R(e){var t=Object(o.useRef)();return Object(o.useEffect)(function(){t.current=e},[e]),t.current}function U(e,t,n,r,c,l){var a=Object(o.useState)({option:t,previousOption:"",loaded:!1,error:!1}),s=A()(a,2),u=s[0],p=s[1],f=R(r),d=R(c);function m(){p(N()({},u,{option:u.previousOption,isSaving:!1}))}return Object(o.useEffect)(function(){u.loaded||u.error?function(){var t=u.option,o=u.previousOption,l=t&&t.trim()===o.trim(),a=!t||0===t.trim().length;!r&&f&&a&&m();if(!c||l)return;!d&&c&&function(t){p(N()({},u,{isSaving:!0})),F()({path:"/wp/v2/settings",method:"POST",data:b()({},e,t)}).then(function(){return function(e){p(N()({},u,{previousOption:e,isDirty:!1,isSaving:!1}))}(t)}).catch(function(){n(Object(i.sprintf)(Object(i.__)("Unable to save site %s"),e)),m()})}(t)}():F()({path:"/wp/v2/settings"}).then(function(t){return p(N()({},u,{option:t[e],previousOption:t[e],loaded:!0,error:!1}))}).catch(function(){n(Object(i.sprintf)(Object(i.__)("Unable to load site %s"),e)),p(N()({},u,{option:Object(i.sprintf)(Object(i.__)("Error loading site %s"),e),error:!0}))})}),{siteOptions:u,handleChange:function(e){l({updated:Date.now()}),p(N()({},u,{option:e}))}}}var H=Object(p.compose)([Object(x.withSelect)(function(e,t){var n=t.clientId,o=e("core/editor"),r=o.isSavingPost,i=o.isPublishingPost,c=o.isAutosavingPost,l=o.isCurrentPostPublished,a=e("core/block-editor"),s=a.getBlockIndex,u=a.getBlockRootClientId,p=a.getTemplateLock,f=u(n);return{blockIndex:s(n,f),isLocked:!!p(f),rootClientId:f,shouldUpdateSiteOption:(r()&&l()||i())&&!c()}}),Object(x.withDispatch)(function(e,t){var n=t.blockIndex,o=t.rootClientId;return{createErrorNotice:e("core/notices").createErrorNotice,insertDefaultBlock:function(){return e("core/block-editor").insertDefaultBlock({},o,n+1)}}})])(function(e){var t=e.className,n=e.createErrorNotice,r=e.shouldUpdateSiteOption,c=e.isSelected,l=e.setAttributes,a=e.isLocked,s=e.insertDefaultBlock,u=U("description",Object(i.__)("Site description loading…"),n,c,r,l),p=u.siteOptions,f=u.handleChange,d=p.option;return Object(o.createElement)(o.Fragment,null,Object(o.createElement)(P.PlainText,{className:t,value:d,onChange:function(e){return f(e)},onKeyDown:function(e){e.keyCode===B.ENTER&&(e.preventDefault(),a||s())},placeholder:Object(i.__)("Site Description"),"aria-label":Object(i.__)("Site Description")}))});n(36);Object(r.registerBlockType)("a8c/site-description",{title:Object(i.__)("Site Description"),description:Object(i.__)("Site description, also known as the tagline."),icon:Object(o.createElement)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24"},Object(o.createElement)("path",{fill:"none",d:"M0 0h24v24H0z"}),Object(o.createElement)("path",{d:"M4 9h16v2H4V9zm0 4h10v2H4v-2z"})),category:"layout",supports:{html:!1,multiple:!1,reusable:!1},edit:H,save:function(){return null}});var z=Object(p.compose)([Object(x.withSelect)(function(e,t){var n=t.clientId,o=e("core/editor"),r=o.isSavingPost,i=o.isPublishingPost,c=o.isAutosavingPost,l=o.isCurrentPostPublished,a=e("core/block-editor"),s=a.getBlockIndex,u=a.getBlockRootClientId,p=a.getTemplateLock,f=u(n);return{blockIndex:s(n,f),isLocked:!!p(f),rootClientId:f,shouldUpdateSiteOption:(r()&&l()||i())&&!c()}}),Object(x.withDispatch)(function(e,t){var n=t.blockIndex,o=t.rootClientId;return{createErrorNotice:e("core/notices").createErrorNotice,insertDefaultBlock:function(){return e("core/block-editor").insertDefaultBlock({},o,n+1)}}})])(function(e){var t=e.className,n=e.createErrorNotice,r=e.shouldUpdateSiteOption,c=e.isSelected,l=e.setAttributes,a=e.isLocked,s=e.insertDefaultBlock,u=U("title",Object(i.__)("Site title loading…"),n,c,r,l),p=u.siteOptions,f=u.handleChange,d=p.option;return Object(o.createElement)(o.Fragment,null,Object(o.createElement)(P.PlainText,{className:_()("site-title",t),value:d,onChange:function(e){return f(e)},onKeyDown:function(e){e.keyCode===B.ENTER&&(e.preventDefault(),a||s())},placeholder:Object(i.__)("Site Title"),"aria-label":Object(i.__)("Site Title")}))});n(38);Object(r.registerBlockType)("a8c/site-title",{title:Object(i.__)("Site Title"),description:Object(i.__)("Your site title."),icon:"layout",category:"layout",supports:{html:!1,multiple:!1,reusable:!1},edit:z,save:function(){return null}});var V=n(6),q=n(23),G=(n(17),Object(p.compose)(Object(p.withState)({templateClientId:null,shouldCloseSidebarOnSelect:!0}),Object(x.withSelect)(function(e,t){var n=t.attributes,o=t.templateClientId,r=e("core").getEntityRecord,i=e("core/editor"),c=i.getCurrentPostId,l=i.isEditedPostDirty,a=e("core/block-editor").getBlock,s=e("core/edit-post").isEditorSidebarOpened,u=n.templateId,p=c(),f=u&&r("postType","wp_template",u);return{currentPostId:p,editTemplateUrl:Object(q.addQueryArgs)(fullSiteEditing.editTemplateBaseUrl,{post:u,fse_parent_post:p}),template:f,templateBlock:a(o),templateTitle:Object(V.get)(f,["title","rendered"],""),isDirty:l(),isEditorSidebarOpened:!!s()}}),Object(x.withDispatch)(function(e,t){var n=e("core/block-editor").receiveBlocks,o=e("core/edit-post").closeGeneralSidebar,i=e("core/editor").clearSelectedBlock,c=t.template,l=t.templateClientId,a=t.setState;return{savePost:e("core/editor").savePost,receiveTemplateBlocks:function(){if(c&&!l){var e=Object(r.parse)(Object(V.get)(c,["content","raw"],"")),t=1===e.length?e[0]:Object(r.createBlock)("core/template",{},e);n([t]),a({templateClientId:t.clientId})}},closeGeneralSidebar:o,clearSelectedBlock:i}}))(function(e){var t=e.attributes,n=e.editTemplateUrl,r=e.receiveTemplateBlocks,l=e.template,a=e.templateBlock,s=e.templateTitle,u=e.isDirty,p=e.savePost,f=e.isSelected,d=e.isEditorSidebarOpened,m=e.closeGeneralSidebar,O=e.clearSelectedBlock,g=e.shouldCloseSidebarOnSelect,v=e.setState;if(!l)return Object(o.createElement)(c.Placeholder,null,Object(o.createElement)(c.Spinner,null));var h=Object(o.createRef)(),y=Object(o.useState)(!1),j=A()(y,2),w=j[0],S=j[1];Object(o.useEffect)(function(){w&&!u&&h.current.click(),r()}),Object(o.useEffect)(function(){f?d?g?m():O():v({shouldCloseSidebarOnSelect:!1}):v({shouldCloseSidebarOnSelect:!0})});var k=t.align,E=t.className;return Object(o.createElement)("div",{className:_()("template-block",E,b()({},"align".concat(k),k))},a&&Object(o.createElement)(o.Fragment,null,Object(o.createElement)(c.Disabled,null,Object(o.createElement)(P.BlockEdit,{attributes:a.attributes,block:a,clientId:a.clientId,isSelected:!1,name:a.name,setAttributes:V.noop})),f&&Object(o.createElement)(c.Placeholder,{className:"template-block__overlay"},Object(o.createElement)(c.Button,{href:n,onClick:function(e){u&&(e.preventDefault(),S(!0),p())},isDefault:!0,ref:h},w?Object(o.createElement)(c.Spinner,null):Object(i.sprintf)(Object(i.__)("Edit %s"),s)))))})),W=Object(p.createHigherOrderComponent)(function(e){return function(t){return"fse-site-logo"!==t.attributes.className?Object(o.createElement)(e,t):Object(o.createElement)(e,u()({},t,{className:"template__site-logo"}))}},"addFSESiteLogoClassname");Object(f.addFilter)("editor.BlockListBlock","full-site-editing/blocks/template",W),"wp_template"!==fullSiteEditing.editorPostType&&Object(r.registerBlockType)("a8c/template",{title:Object(i.__)("Template"),description:Object(i.__)("Display a template."),icon:"layout",category:"layout",attributes:{templateId:{type:"number"},className:{type:"string"}},supports:{anchor:!1,customClassName:!1,html:!1,reusable:!1},edit:G,save:function(){return null},getEditWrapperProps:function(){return{"data-align":"full"}}});var K=Object(p.createHigherOrderComponent)(function(e){return function(t){return"a8c/template"!==t.name?Object(o.createElement)(e,t):Object(o.createElement)(e,u()({},t,{className:"template__block-container"}))}},"addFSETemplateClassname");Object(f.addFilter)("editor.BlockListBlock","full-site-editing/blocks/template",K,9);var Q=n(13),Y=n.n(Q);n(41);Y()(function(){var e=fullSiteEditing,t=e.closeButtonLabel,n=e.closeButtonUrl,o=e.editorPostType,r=setInterval(function(){var e=document.querySelector(".edit-post-fullscreen-mode-close__toolbar a");if(e)if(clearInterval(r),"wp_template"===o&&n){var i=document.createElement("a");i.href=n,i.innerHTML=t,i.className="components-button components-icon-button is-button is-default",i.setAttribute("aria-label",t),document.querySelector(".edit-post-fullscreen-mode-close__toolbar").replaceChild(i,e)}else e.innerHTML='<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="28" height="28" viewBox="0 0 20 20"><path d="M14.95 6.46l-3.54 3.54 3.54 3.54-1.41 1.41-3.54-3.53-3.53 3.53-1.42-1.42 3.53-3.53-3.53-3.53 1.42-1.42 3.53 3.53 3.54-3.53z"></path></svg>',e.classList.add("a8c-close-button")})});var J=n(24),X=n.n(J),Z=n(25),$=Object(x.withSelect)(function(e){var t=e("core").getEntityRecord,n=e("core/editor").getEditedPostAttribute;return{templateClasses:Object(V.map)(n("template_types"),function(e){var n=Object(V.get)(t("taxonomy","wp_template_type",e),"name","");return Object(V.endsWith)(n,"-header")?"site-header site-branding":Object(V.endsWith)(n,"-footer")?"site-footer":void 0})}})(function(e){var t=e.templateClasses,n=setInterval(function(){var e=document.querySelector(".block-editor-writing-flow.editor-writing-flow");e&&(clearInterval(n),e.className=_.a.apply(void 0,["block-editor-writing-flow","editor-writing-flow"].concat(X()(t))),e.style.padding=0)});return null});"wp_template"===fullSiteEditing.editorPostType&&Object(Z.registerPlugin)("fse-editor-template-classes",{render:$}),Y()(function(){"wp_template"===fullSiteEditing.editorPostType&&Object(x.dispatch)("core/notices").createNotice("info",Object(i.__)("Updates to this template will affect all pages on your site."),{isDismissible:!1})});var ee=Object(p.compose)(Object(x.withSelect)(function(e){var t=e("core/editor"),n=t.getBlocks,o=t.getEditorSettings,r=e("core/edit-post").getEditorMode,i=n().find(function(e){return"a8c/post-content"===e.name});return{rootClientId:i?i.clientId:"",showInserter:"visual"===r()&&o().richEditingEnabled}}))(function(e){var t=e.rootClientId,n=e.showInserter;return Object(o.createElement)(P.Inserter,{rootClientId:t,disabled:!n,position:"bottom right"})});Y()(function(){return function(){if("page"===fullSiteEditing.editorPostType)var e=setInterval(function(){var t=document.querySelector(".edit-post-header-toolbar");if(t){clearInterval(e);var n=document.createElement("div");n.classList.add("fse-post-content-block-inserter"),t.insertBefore(n,t.firstChild),Object(o.render)(Object(o.createElement)(ee,null),n)}})}()});var te=Object(x.subscribe)(function(){if("page"!==fullSiteEditing.editorPostType)return te();!1===Object(x.select)("core/editor").isValidTemplate()&&Object(x.dispatch)("core/editor").setTemplateValidity(!0)}),ne=["logo","brand","emblem","hallmark"];Object(f.addFilter)("blocks.registerBlockType","full-site-editing/editor/image-block-keywords",function(e,t){return"core/image"!==t?e:e=Object(V.assign)({},e,{keywords:e.keywords.concat(ne)})});n(46)}]));
full-site-editing/dist/full-site-editing.rtl.css CHANGED
@@ -1 +1 @@
1
- .wp-block-a8c-navigation-menu.main-navigation{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;font-size:1.125em;font-weight:700;letter-spacing:-.02em;line-height:1.2;pointer-events:none;-webkit-font-smoothing:antialiased}.wp-block-a8c-navigation-menu.main-navigation .main-menu{display:inline-block;margin:0;padding:0}.wp-block-a8c-navigation-menu.main-navigation .main-menu>li{color:#0073aa;display:inline;position:relative}.wp-block-a8c-navigation-menu.main-navigation .main-menu>li>a{font-weight:700;color:#0073aa;margin-left:.5rem}.main-navigation .main-menu>li:last-child.menu-item-has-children .submenu-expand,.wp-block-a8c-navigation-menu.main-navigation .main-menu>li:last-child>a{margin-left:0}.wp-block-a8c-navigation-menu.main-navigation .main-menu>li.menu-item-has-children>a{margin-left:.125rem}.wp-block-a8c-navigation-menu.main-navigation .main-menu>li.menu-item-has-children{display:inline-block;position:inherit}.wp-block-a8c-navigation-menu.main-navigation .main-menu>li.menu-item-has-children .submenu-expand{display:inline-block;margin-left:.25rem}.wp-block-a8c-navigation-menu.main-navigation .main-menu>li.menu-item-has-children .submenu-expand svg{position:relative;top:.3rem}.main-navigation .main-menu>li>a:hover+svg,.wp-block-a8c-navigation-menu.main-navigation .main-menu>li>a:hover{color:#005177}.wp-block-a8c-navigation-menu.main-navigation .main-menu-more{display:none}.wp-block-a8c-navigation-menu.main-navigation svg{transition:fill .12s ease-in-out;fill:currentColor}.wp-block-a8c-navigation-menu.main-navigation a{text-decoration:none}.wp-block-a8c-navigation-menu.main-navigation button{display:inline-block;border:none;padding:0;margin:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;font-size:.88889em;font-weight:700;line-height:1.2;text-decoration:none;vertical-align:bottom;background:transparent;color:inherit;cursor:pointer;transition:background .25s ease-in-out,transform .15s ease;-webkit-appearance:none;-moz-appearance:none}.wp-block-a8c-navigation-menu.main-menu-more{display:none}.wp-block-a8c-navigation-menu.social-navigation{line-height:1.25;margin-top:.5rem;text-align:right}.wp-block-a8c-navigation-menu.social-navigation ul.social-links-menu{content:"";display:inline-block;margin:0;padding:0}.wp-block-a8c-navigation-menu.social-navigation ul.social-links-menu li{display:inline-block;vertical-align:bottom;vertical-align:-webkit-baseline-middle;list-style:none}.wp-block-a8c-navigation-menu.social-navigation ul.social-links-menu li a svg{display:block;width:32px;height:32px;transform:translateZ(0)}.wp-block-a8c-navigation-menu.footer-navigation .footer-menu{display:inline;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;font-size:.71111em;padding-right:0}.wp-block-a8c-navigation-menu.footer-navigation .footer-menu li{display:inline;margin-left:1rem}.wp-block-a8c-navigation-menu.footer-navigation .footer-menu a{text-decoration:none;color:#767676}.wp-block-a8c-navigation-menu.footer-navigation .footer-menu a:hover{text-decoration:none;color:#0073aa}.editor-styles-wrapper .wp-block-a8c-navigation-menu-toolbar a,.editor-styles-wrapper .wp-block-a8c-navigation-menu-toolbar a:hover{color:#555d66}.a8c-post-autocomplete{position:relative}.a8c-post-autocomplete .components-spinner{bottom:7px;position:absolute;left:-5px}.a8c-post-autocomplete__suggestions{max-height:200px;overflow-y:auto;width:302px}.a8c-post-autocomplete__suggestions .components-button{display:block;height:auto;min-height:30px;white-space:normal;width:100%;word-wrap:break-word}.post-content-block.alignfull{padding:0 12px}.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{content:"";clear:both;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 .wp-block-a8c-site-description,.block-editor .wp-block-a8c-site-description:focus{display:inline;color:#767676;font-size:1.125em;font-weight:400;letter-spacing:-.01em;margin:0;box-shadow:none;background-color:transparent}.block-editor .site-description__save-button{margin-right:auto;display:block}.block-editor .site-title:not(:empty)+.site-description:not(:empty):before{content:"\2014";margin:0 .2em}.block-editor .wp-block-a8c-site-title,.block-editor .wp-block-a8c-site-title:focus{display:inline;color:#111;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;font-size:1.125em;font-weight:400;letter-spacing:-.02em;line-height:1.2;margin:0;box-shadow:none;background-color:transparent}.block-editor .site-title__save-button{margin-right:auto;display:block}.block-editor .site-title a:link,.block-editor .site-title a:visited{color:#111;text-decoration:none;font-weight:400}.template-block{min-height:200px}.template-block:hover .template-block__overlay{display:flex}.template-block.alignfull{padding:0 12px}.template-block__selector{width:300px}.template-block__selector a{font-family:sans-serif;font-size:13px;padding-right:8px}.template-block__content{pointer-events:none}.template-block__content:after{content:"";clear:both;display:table}.template-block__overlay{display:none;position:absolute;top:0;right:0;width:100%;height:100%;background:rgba(0,0,0,.75)}.template-block__overlay .components-placeholder__instructions{color:#fff}.wp-block-a8c-site-logo{pointer-events:none}
1
+ .wp-block-a8c-navigation-menu.main-navigation{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;font-size:1.125em;font-weight:700;letter-spacing:-.02em;line-height:1.2;pointer-events:none;-webkit-font-smoothing:antialiased}.wp-block-a8c-navigation-menu.main-navigation .main-menu{display:inline-block;margin:0;padding:0}.wp-block-a8c-navigation-menu.main-navigation .main-menu>li{color:#0073aa;display:inline;position:relative}.wp-block-a8c-navigation-menu.main-navigation .main-menu>li>a{font-weight:700;color:#0073aa;margin-left:.5rem}.main-navigation .main-menu>li:last-child.menu-item-has-children .submenu-expand,.wp-block-a8c-navigation-menu.main-navigation .main-menu>li:last-child>a{margin-left:0}.wp-block-a8c-navigation-menu.main-navigation .main-menu>li.menu-item-has-children>a{margin-left:.125rem}.wp-block-a8c-navigation-menu.main-navigation .main-menu>li.menu-item-has-children{display:inline-block;position:inherit}.wp-block-a8c-navigation-menu.main-navigation .main-menu>li.menu-item-has-children .submenu-expand{display:inline-block;margin-left:.25rem}.wp-block-a8c-navigation-menu.main-navigation .main-menu>li.menu-item-has-children .submenu-expand svg{position:relative;top:.3rem}.main-navigation .main-menu>li>a:hover+svg,.wp-block-a8c-navigation-menu.main-navigation .main-menu>li>a:hover{color:#005177}.wp-block-a8c-navigation-menu.main-navigation .main-menu-more{display:none}.wp-block-a8c-navigation-menu.main-navigation svg{transition:fill .12s ease-in-out;fill:currentColor}.wp-block-a8c-navigation-menu.main-navigation a{text-decoration:none}.wp-block-a8c-navigation-menu.main-navigation button{display:inline-block;border:none;padding:0;margin:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;font-size:.88889em;font-weight:700;line-height:1.2;text-decoration:none;vertical-align:bottom;background:transparent;color:inherit;cursor:pointer;transition:background .25s ease-in-out,transform .15s ease;-webkit-appearance:none;-moz-appearance:none}.wp-block-a8c-navigation-menu.main-menu-more{display:none}.wp-block-a8c-navigation-menu.social-navigation{line-height:1.25;margin-top:.5rem;text-align:right}.wp-block-a8c-navigation-menu.social-navigation ul.social-links-menu{content:"";display:inline-block;margin:0;padding:0}.wp-block-a8c-navigation-menu.social-navigation ul.social-links-menu li{display:inline-block;vertical-align:bottom;vertical-align:-webkit-baseline-middle;list-style:none}.wp-block-a8c-navigation-menu.social-navigation ul.social-links-menu li a svg{display:block;width:32px;height:32px;transform:translateZ(0)}.wp-block-a8c-navigation-menu.footer-navigation .footer-menu{display:inline;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;font-size:.71111em;padding-right:0}.wp-block-a8c-navigation-menu.footer-navigation .footer-menu li{display:inline;margin-left:1rem}.wp-block-a8c-navigation-menu.footer-navigation .footer-menu a{text-decoration:none;color:#767676}.wp-block-a8c-navigation-menu.footer-navigation .footer-menu a:hover{text-decoration:none;color:#0073aa}.editor-styles-wrapper .wp-block-a8c-navigation-menu-toolbar a,.editor-styles-wrapper .wp-block-a8c-navigation-menu-toolbar a:hover{color:#555d66}.post-content-block.alignfull{padding:0 12px}.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{content:"";clear:both;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{transition:none;border:none;outline:none;box-shadow: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}.block-editor .wp-block-a8c-site-description,.block-editor .wp-block-a8c-site-description:focus{display:inline;color:#767676;font-size:1.125em;font-weight:400;letter-spacing:-.01em;margin:0;box-shadow:none;background-color:transparent}.block-editor .site-description__save-button{margin-right:auto;display:block}.block-editor .site-title:not(:empty)+.site-description:not(:empty):before{content:"\2014";margin:0 .2em}.block-editor .wp-block-a8c-site-title,.block-editor .wp-block-a8c-site-title:focus{display:inline;color:#111;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;font-size:1.125em;font-weight:400;letter-spacing:-.02em;line-height:1.2;margin:0;box-shadow:none;background-color:transparent}.block-editor .site-title__save-button{margin-right:auto;display:block}.block-editor .site-title a:link,.block-editor .site-title a:visited{color:#111;text-decoration:none;font-weight:400}.template-block{min-height:200px}.template-block .components-button .components-spinner{margin-top:4px}.template-block.alignfull{padding:0 12px}.template-block__selector{width:300px}.template-block__selector a{font-family:sans-serif;font-size:13px;padding-right:8px}.template-block__content{pointer-events:none}.template-block__content:after{content:"";clear:both;display:table}.template-block__overlay{display:flex;position:absolute;top:0;right:2px;width:100%;height:100%;justify-content:center;align-items:center;background:hsla(0,0%,96.1%,.8);z-index:2}.block-editor-block-list__layout .template__block-container .wp-block{margin-top:15px;margin-bottom:15px}.block-editor-block-list__layout .template__block-container.is-hovered{cursor:pointer}.block-editor-block-list__layout .template__block-container.is-selected .block-editor-block-contextual-toolbar{display:none}.block-editor-block-list__layout .template__block-container.is-selected .components-disabled{filter:blur(2px)}.block-editor-block-list__layout .template__block-container.block-editor-block-list__block.has-child-selected>.block-editor-block-list__block-edit:before,.block-editor-block-list__layout .template__block-container.block-editor-block-list__block.is-hovered>.block-editor-block-list__block-edit:before,.block-editor-block-list__layout .template__block-container.block-editor-block-list__block.is-navigate-mode>.block-editor-block-list__block-edit:before,.block-editor-block-list__layout .template__block-container.block-editor-block-list__block>.block-editor-block-list__block-edit:before{transition:none;border:none;outline:none;box-shadow:none}.block-editor-block-list__layout .template__block-container.block-editor-block-list__block.has-child-selected>.block-editor-block-list__block-edit>.block-editor-block-list__breadcrumb,.block-editor-block-list__layout .template__block-container.block-editor-block-list__block.is-hovered>.block-editor-block-list__block-edit>.block-editor-block-list__breadcrumb,.block-editor-block-list__layout .template__block-container.block-editor-block-list__block.is-navigate-mode>.block-editor-block-list__block-edit>.block-editor-block-list__breadcrumb,.block-editor-block-list__layout .template__block-container.block-editor-block-list__block>.block-editor-block-list__block-edit>.block-editor-block-list__breadcrumb,.block-editor-page:not(.post-type-wp_template) .fse-site-logo .components-placeholder__fieldset,.block-editor-page:not(.post-type-wp_template) .fse-site-logo .components-placeholder__instructions{display:none}.edit-post-fullscreen-mode-close__toolbar a.is-button.is-default{height:auto}.edit-post-fullscreen-mode-close__toolbar a.is-button.is-default span{display:none}.edit-post-fullscreen-mode-close__toolbar a.a8c-close-button{padding:4px}.post-type-wp_template .editor-post-title,.post-type-wp_template .editor-post-trash{display:none}.post-type-wp_template .edit-post-visual-editor{margin-top:20px;padding-top:0}.post-type-wp_template .editor-post-switch-to-draft{display:none}.post-type-wp_template .editor-block-list__layout{padding-top:28px}.post-type-wp_template .editor-styles-wrapper [data-block]{margin-top:15px;margin-bottom:15px}.post-type-page .edit-post-layout__content,.post-type-wp_template .edit-post-layout__content{background:#eee}.post-type-page .edit-post-layout__content .edit-post-visual-editor,.post-type-wp_template .edit-post-layout__content .edit-post-visual-editor{flex:none;margin:36px 32px;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)}@media (max-width:768px){.post-type-page .edit-post-layout__content .edit-post-visual-editor,.post-type-wp_template .edit-post-layout__content .edit-post-visual-editor{margin:0}}.editor-styles-wrapper{background:#fff}.post-type-page .edit-post-visual-editor{padding:0 0 4px}.post-type-page .block-editor-writing-flow{display:block}.post-type-page .wp-block[data-type="a8c/template"] [data-block]{margin:0}
full-site-editing/editor/image-block-keywords/index.js ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { assign } from 'lodash';
5
+ import { addFilter } from '@wordpress/hooks';
6
+
7
+ const additionalKeywords = [ 'logo', 'brand', 'emblem', 'hallmark' ];
8
+
9
+ addFilter(
10
+ 'blocks.registerBlockType',
11
+ 'full-site-editing/editor/image-block-keywords',
12
+ ( settings, name ) => {
13
+ if ( name !== 'core/image' ) {
14
+ return settings;
15
+ }
16
+
17
+ settings = assign( {}, settings, {
18
+ keywords: settings.keywords.concat( additionalKeywords ),
19
+ } );
20
+
21
+ return settings;
22
+ }
23
+ );
full-site-editing/editor/index.js CHANGED
@@ -3,3 +3,5 @@
3
  */
4
  import './block-inserter';
5
  import './template-validity-override';
 
 
3
  */
4
  import './block-inserter';
5
  import './template-validity-override';
6
+ import './image-block-keywords';
7
+ import './style.scss';
full-site-editing/editor/style.scss ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .post-type-wp_template {
2
+ .editor-post-title,
3
+ .editor-post-trash {
4
+ display: none;
5
+ }
6
+
7
+ .edit-post-visual-editor {
8
+ margin-top: 20px;
9
+ padding-top: 0;
10
+ }
11
+
12
+ .editor-post-switch-to-draft {
13
+ display: none;
14
+ }
15
+
16
+ .editor-block-list__layout {
17
+ padding-top: 28px;
18
+ }
19
+
20
+ .editor-styles-wrapper [data-block] {
21
+ margin-top: 15px;
22
+ margin-bottom: 15px;
23
+ }
24
+ }
25
+
26
+ .post-type-page, .post-type-wp_template {
27
+ .edit-post-layout__content {
28
+ background: #eee;
29
+ }
30
+
31
+ .edit-post-layout__content .edit-post-visual-editor {
32
+ flex: none;
33
+ margin: 36px 32px;
34
+ box-shadow: 0 2px 2px 0 rgba( 0, 0, 0, 0.14 ), 0 3px 1px -2px rgba( 0, 0, 0, 0.12 ), 0 1px 5px 0 rgba( 0, 0, 0, 0.2 );
35
+
36
+ @media ( max-width: 768px ) {
37
+ margin: 0;
38
+ }
39
+ }
40
+ }
41
+
42
+ // We separate this from the other styles so that
43
+ // the theme style can override this class without
44
+ // having to get as specific.
45
+ .editor-styles-wrapper {
46
+ background: #fff;
47
+ }
48
+
49
+ .post-type-page {
50
+ .edit-post-visual-editor {
51
+ padding: 0 0 4px;
52
+ }
53
+
54
+ .block-editor-writing-flow {
55
+ display: block;
56
+ }
57
+
58
+ .wp-block[data-type='a8c/template'] [data-block] {
59
+ margin: 0;
60
+ }
61
+ }
full-site-editing/editor/template-validity-override/index.js CHANGED
@@ -19,7 +19,5 @@ const unsubscribe = subscribe( () => {
19
  }
20
  if ( select( 'core/editor' ).isValidTemplate() === false ) {
21
  dispatch( 'core/editor' ).setTemplateValidity( true );
22
- // should only need to do this once
23
- unsubscribe();
24
  }
25
  } );
19
  }
20
  if ( select( 'core/editor' ).isValidTemplate() === false ) {
21
  dispatch( 'core/editor' ).setTemplateValidity( true );
 
 
22
  }
23
  } );
full-site-editing/index.js CHANGED
@@ -6,8 +6,7 @@ import './blocks/post-content';
6
  import './blocks/site-description';
7
  import './blocks/site-title';
8
  import './blocks/template';
9
- import './blocks/site-logo';
10
- import './plugins/template-selector-sidebar';
11
  import './plugins/close-button-override';
12
- import './plugins/template-update-confirmation';
 
13
  import './editor';
6
  import './blocks/site-description';
7
  import './blocks/site-title';
8
  import './blocks/template';
 
 
9
  import './plugins/close-button-override';
10
+ import './plugins/editor-template-classes';
11
+ import './plugins/template-update-notice';
12
  import './editor';
full-site-editing/plugins/close-button-override/index.js CHANGED
@@ -5,16 +5,13 @@
5
  */
6
  import domReady from '@wordpress/dom-ready';
7
 
8
- domReady( () => {
9
- // We only want this override when closing Template Part CPT (e.g. header) to navigate back to parent page.
10
- if ( 'wp_template_part' !== fullSiteEditing.editorPostType ) {
11
- return;
12
- }
13
 
14
- // Keep the default URL if the override hasn't been provided by the plugin.
15
- if ( ! fullSiteEditing.closeButtonUrl ) {
16
- return;
17
- }
18
 
19
  const editPostHeaderInception = setInterval( () => {
20
  const closeButton = document.querySelector( '.edit-post-fullscreen-mode-close__toolbar a' );
@@ -24,8 +21,22 @@ domReady( () => {
24
  }
25
  clearInterval( editPostHeaderInception );
26
 
27
- if ( fullSiteEditing.closeButtonUrl ) {
28
- closeButton.href = fullSiteEditing.closeButtonUrl;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  }
30
  } );
31
  } );
5
  */
6
  import domReady from '@wordpress/dom-ready';
7
 
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import './style.scss';
 
12
 
13
+ domReady( () => {
14
+ const { closeButtonLabel, closeButtonUrl, editorPostType } = fullSiteEditing;
 
 
15
 
16
  const editPostHeaderInception = setInterval( () => {
17
  const closeButton = document.querySelector( '.edit-post-fullscreen-mode-close__toolbar a' );
21
  }
22
  clearInterval( editPostHeaderInception );
23
 
24
+ // When closing Template CPT (e.g. header) to navigate back to parent page.
25
+ if ( 'wp_template' === editorPostType && closeButtonUrl ) {
26
+ const newCloseButton = document.createElement( 'a' );
27
+ newCloseButton.href = closeButtonUrl;
28
+ newCloseButton.innerHTML = closeButtonLabel;
29
+ newCloseButton.className = 'components-button components-icon-button is-button is-default';
30
+ newCloseButton.setAttribute( 'aria-label', closeButtonLabel );
31
+
32
+ const parentContainer = document.querySelector( '.edit-post-fullscreen-mode-close__toolbar' );
33
+ parentContainer.replaceChild( newCloseButton, closeButton );
34
+ } else {
35
+ // Otherwise just replace the left caret with an X icon.
36
+ // The size is 28 instead of 20 because `dashicons-no-alt` looks smaller than `dashicons-arrow-left-alt2`.
37
+ closeButton.innerHTML =
38
+ '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="28" height="28" viewBox="0 0 20 20"><path d="M14.95 6.46l-3.54 3.54 3.54 3.54-1.41 1.41-3.54-3.53-3.53 3.53-1.42-1.42 3.53-3.53-3.53-3.53 1.42-1.42 3.53 3.53 3.54-3.53z"></path></svg>';
39
+ closeButton.classList.add( 'a8c-close-button' );
40
  }
41
  } );
42
  } );
full-site-editing/plugins/close-button-override/style.scss ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .edit-post-fullscreen-mode-close__toolbar a {
2
+ &.is-button.is-default {
3
+ height: auto;
4
+ span {
5
+ display: none;
6
+ }
7
+ }
8
+
9
+ &.a8c-close-button {
10
+ // Adjust the button padding to accommodate the bigger icon size.
11
+ padding: 4px;
12
+ }
13
+ }
full-site-editing/plugins/editor-template-classes/index.js ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global fullSiteEditing */
2
+ /**
3
+ * External dependencies
4
+ */
5
+ import classNames from 'classnames';
6
+ import { endsWith, get, map } from 'lodash';
7
+
8
+ /**
9
+ * WordPress dependencies
10
+ */
11
+ import { withSelect } from '@wordpress/data';
12
+ import { registerPlugin } from '@wordpress/plugins';
13
+
14
+ const EditorTemplateClasses = withSelect( select => {
15
+ const { getEntityRecord } = select( 'core' );
16
+ const { getEditedPostAttribute } = select( 'core/editor' );
17
+ const templateClasses = map( getEditedPostAttribute( 'template_types' ), typeId => {
18
+ const typeName = get( getEntityRecord( 'taxonomy', 'wp_template_type', typeId ), 'name', '' );
19
+ if ( endsWith( typeName, '-header' ) ) {
20
+ return 'site-header site-branding';
21
+ }
22
+ if ( endsWith( typeName, '-footer' ) ) {
23
+ return 'site-footer';
24
+ }
25
+ } );
26
+ return { templateClasses };
27
+ } )( ( { templateClasses } ) => {
28
+ const blockListInception = setInterval( () => {
29
+ const blockList = document.querySelector( '.block-editor-writing-flow.editor-writing-flow' );
30
+
31
+ if ( ! blockList ) {
32
+ return;
33
+ }
34
+ clearInterval( blockListInception );
35
+
36
+ blockList.className = classNames(
37
+ 'block-editor-writing-flow',
38
+ 'editor-writing-flow',
39
+ ...templateClasses
40
+ );
41
+ blockList.style.padding = 0;
42
+ } );
43
+
44
+ return null;
45
+ } );
46
+
47
+ if ( 'wp_template' === fullSiteEditing.editorPostType ) {
48
+ registerPlugin( 'fse-editor-template-classes', {
49
+ render: EditorTemplateClasses,
50
+ } );
51
+ }
full-site-editing/plugins/template-update-notice/index.js ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global fullSiteEditing */
2
+ /**
3
+ * External dependencies
4
+ */
5
+ import domReady from '@wordpress/dom-ready';
6
+ import { dispatch } from '@wordpress/data';
7
+ import { __ } from '@wordpress/i18n';
8
+
9
+ domReady( () => {
10
+ if ( 'wp_template' !== fullSiteEditing.editorPostType ) {
11
+ return;
12
+ }
13
+ dispatch( 'core/notices' ).createNotice(
14
+ 'info',
15
+ __( 'Updates to this template will affect all pages on your site.' ),
16
+ {
17
+ isDismissible: false,
18
+ }
19
+ );
20
+ } );
full-site-editing/serialize-block-fallback.php ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ }
full-site-editing/templates/class-rest-templates-controller.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ /**
16
+ * Checks if a template can be read.
17
+ *
18
+ * @param object $post Post object that backs the template.
19
+ * @return bool Whether the template can be read.
20
+ */
21
+ public function check_read_permission( $post ) {
22
+ // Ensure that the user is logged in and has the edit_posts capability.
23
+ $post_type = get_post_type_object( $post->post_type );
24
+ if ( ! current_user_can( $post_type->cap->read_post, $post->ID ) ) {
25
+ return false;
26
+ }
27
+
28
+ return parent::check_read_permission( $post );
29
+ }
30
+
31
+ /**
32
+ * Retrieves the template's schema, conforming to JSON Schema.
33
+ *
34
+ * @return array Item schema data.
35
+ */
36
+ public function get_item_schema() {
37
+ $schema = parent::get_item_schema();
38
+
39
+ /*
40
+ * Allow all contexts to access `title.raw` and `content.raw`. Clients always
41
+ * need the raw markup of a reusable template to do anything useful, e.g. parse
42
+ * it or display it in an editor.
43
+ */
44
+ $schema['properties']['title']['properties']['raw']['context'] = array( 'view', 'edit' );
45
+ $schema['properties']['content']['properties']['raw']['context'] = array( 'view', 'edit' );
46
+
47
+ return $schema;
48
+ }
49
+ }
full-site-editing/templates/class-wp-template-inserter.php ADDED
@@ -0,0 +1,388 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Full site editing file.
4
+ *
5
+ * @package A8C\FSE
6
+ */
7
+
8
+ namespace A8C\FSE;
9
+
10
+ /**
11
+ * Class WP_Template_Inserter
12
+ */
13
+ class WP_Template_Inserter {
14
+ /**
15
+ * Template header content.
16
+ *
17
+ * @var string $header_content
18
+ */
19
+ private $header_content;
20
+
21
+ /**
22
+ * Template footer content.
23
+ *
24
+ * @var string $footer_content
25
+ */
26
+ private $footer_content;
27
+
28
+ /**
29
+ * Current theme slug.
30
+ *
31
+ * @var string $theme_slug
32
+ */
33
+ private $theme_slug;
34
+
35
+ /**
36
+ * This site option will be used to indicate that template data has already been
37
+ * inserted for this theme, in order to prevent this functionality from running
38
+ * more than once.
39
+ *
40
+ * @var string $fse_template_data_option
41
+ */
42
+ private $fse_template_data_option;
43
+
44
+ /**
45
+ * This site option will be used to indicate that default page data has already been
46
+ * inserted for this theme, in order to prevent this functionality from running
47
+ * more than once.
48
+ *
49
+ * @var string $fse_page_data_option
50
+ */
51
+ private $fse_page_data_option = 'fse-page-data-v1';
52
+
53
+ /**
54
+ * WP_Template_Inserter constructor.
55
+ *
56
+ * @param string $theme_slug Current theme slug.
57
+ */
58
+ public function __construct( $theme_slug ) {
59
+ $this->theme_slug = $theme_slug;
60
+ $this->header_content = '';
61
+ $this->footer_content = '';
62
+
63
+ /*
64
+ * Previously the option suffix was '-fse-template-data'. Bumping this to '-fse-template-data-v1'
65
+ * to differentiate it from the old data that was not provided by the API. Note that we don't want
66
+ * to tie this to plugin version constant, because that would trigger the insertion on each plugin
67
+ * update, even when it's not necessary (it would duplicate existing data).
68
+ */
69
+ $this->fse_template_data_option = $this->theme_slug . '-fse-template-data-v1';
70
+ }
71
+
72
+ /**
73
+ * Retrieves template parts content from WP.com API.
74
+ */
75
+ public function fetch_template_parts() {
76
+ $request_url = 'https://public-api.wordpress.com/wpcom/v2/full-site-editing/templates';
77
+
78
+ $request_args = [
79
+ 'body' => [ 'theme_slug' => $this->theme_slug ],
80
+ ];
81
+
82
+ $response = $this->fetch_retry( $request_url, $request_args );
83
+
84
+ if ( ! $response ) {
85
+ return;
86
+ }
87
+
88
+ $api_response = json_decode( wp_remote_retrieve_body( $response ), true );
89
+
90
+ // Default to first returned header for now. Support for multiple headers will be added in future iterations.
91
+ if ( ! empty( $api_response['headers'] ) ) {
92
+ $this->header_content = $api_response['headers'][0];
93
+ }
94
+
95
+ // Default to first returned footer for now. Support for multiple footers will be added in future iterations.
96
+ if ( ! empty( $api_response['footers'] ) ) {
97
+ $this->footer_content = $api_response['footers'][0];
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Retries a call to wp_remote_get on error.
103
+ *
104
+ * @param string $request_url Url of the api call to make.
105
+ * @param string $request_args Addtional arguments for the api call.
106
+ * @param int $attempt The number of the attempt being made.
107
+ * @return array wp_remote_get reponse array
108
+ */
109
+ private function fetch_retry( $request_url, $request_args = null, $attempt = 1 ) {
110
+ $max_retries = 3;
111
+
112
+ $response = wp_remote_get( $request_url, $request_args );
113
+
114
+ if ( ! is_wp_error( $response ) ) {
115
+ return $response;
116
+ }
117
+
118
+ if ( $attempt > $max_retries ) {
119
+ return;
120
+ }
121
+
122
+ sleep( pow( 2, $attempt ) );
123
+ $attempt++;
124
+ $this->fetch_retry( $request_url, $request_args, $attempt );
125
+ }
126
+
127
+ /**
128
+ * Determines whether FSE data has already been inserted.
129
+ *
130
+ * @return bool True if FSE data has already been inserted, false otherwise.
131
+ */
132
+ public function is_template_data_inserted() {
133
+ return get_option( $this->fse_template_data_option ) ? true : false;
134
+ }
135
+
136
+ /**
137
+ * This function will be called on plugin activation hook.
138
+ */
139
+ public function insert_default_template_data() {
140
+ if ( $this->is_template_data_inserted() ) {
141
+ /*
142
+ * Bail here to prevent inserting the FSE data twice for any given theme.
143
+ * Multiple themes will still be able to insert different templates.
144
+ */
145
+ return;
146
+ }
147
+
148
+ // Set header and footer content based on data fetched from the WP.com API.
149
+ $this->fetch_template_parts();
150
+
151
+ // Avoid creating template parts if data hasn't been fetched properly.
152
+ if ( empty( $this->header_content ) || empty( $this->footer_content ) ) {
153
+ return;
154
+ }
155
+
156
+ $this->register_template_post_types();
157
+
158
+ $header_id = wp_insert_post(
159
+ [
160
+ 'post_title' => 'Header',
161
+ 'post_content' => $this->header_content,
162
+ 'post_status' => 'publish',
163
+ 'post_type' => 'wp_template',
164
+ 'comment_status' => 'closed',
165
+ 'ping_status' => 'closed',
166
+ ]
167
+ );
168
+
169
+ if ( ! term_exists( "$this->theme_slug-header", 'wp_template_type' ) ) {
170
+ wp_insert_term( "$this->theme_slug-header", 'wp_template_type' );
171
+ }
172
+
173
+ wp_set_object_terms( $header_id, "$this->theme_slug-header", 'wp_template_type' );
174
+
175
+ $footer_id = wp_insert_post(
176
+ [
177
+ 'post_title' => 'Footer',
178
+ 'post_content' => $this->footer_content,
179
+ 'post_status' => 'publish',
180
+ 'post_type' => 'wp_template',
181
+ 'comment_status' => 'closed',
182
+ 'ping_status' => 'closed',
183
+ ]
184
+ );
185
+
186
+ if ( ! term_exists( "$this->theme_slug-footer", 'wp_template_type' ) ) {
187
+ wp_insert_term( "$this->theme_slug-footer", 'wp_template_type' );
188
+ }
189
+
190
+ wp_set_object_terms( $footer_id, "$this->theme_slug-footer", 'wp_template_type' );
191
+
192
+ add_option( $this->fse_template_data_option, true );
193
+ }
194
+
195
+ /**
196
+ * Determines whether default pages have already been created.
197
+ *
198
+ * @return bool True if default pages have already been created, false otherwise.
199
+ */
200
+ public function is_pages_data_inserted() {
201
+ return get_option( $this->fse_page_data_option ) ? true : false;
202
+ }
203
+
204
+ /**
205
+ * Inserts default About and Contact pages based on Starter Page Templates content.
206
+ *
207
+ * The insertion will not happen if this data has been already inserted or if pages
208
+ * with 'About' and 'Contact' titles already exist.
209
+ */
210
+ public function insert_default_pages() {
211
+ // Bail if this data has already been inserted.
212
+ if ( $this->is_pages_data_inserted() ) {
213
+ return;
214
+ }
215
+
216
+ $request_url = add_query_arg(
217
+ [
218
+ '_locale' => $this->get_iso_639_locale(),
219
+ ],
220
+ 'https://public-api.wordpress.com/wpcom/v2/verticals/m1/templates'
221
+ );
222
+
223
+ $response = $this->fetch_retry( $request_url );
224
+
225
+ if ( ! $response ) {
226
+ return;
227
+ }
228
+
229
+ $api_response = json_decode( wp_remote_retrieve_body( $response ), true );
230
+
231
+ $about_page_content = '';
232
+ $contact_page_content = '';
233
+
234
+ /*
235
+ * Array of returned templates is not keyed by name, so we have to access it directly like this.
236
+ * About page is at position 6 in the array, and Contact page at 1.
237
+ */
238
+ if ( ! empty( $api_response['templates'][6]['content'] ) ) {
239
+ $about_page_content = $api_response['templates'][6]['content'];
240
+ }
241
+
242
+ if ( ! empty( $api_response['templates'][1]['content'] ) ) {
243
+ $contact_page_content = $api_response['templates'][1]['content'];
244
+ }
245
+
246
+ if ( empty( get_page_by_title( 'About' ) ) ) {
247
+ wp_insert_post(
248
+ [
249
+ 'post_title' => _x( 'About', 'Default page title', 'full-site-editing' ),
250
+ 'post_content' => $about_page_content,
251
+ 'post_status' => 'publish',
252
+ 'post_type' => 'page',
253
+ ]
254
+ );
255
+ }
256
+
257
+ if ( empty( get_page_by_title( 'Contact' ) ) ) {
258
+ wp_insert_post(
259
+ [
260
+ 'post_title' => _x( 'Contact', 'Default page title', 'full-site-editing' ),
261
+ 'post_content' => $contact_page_content,
262
+ 'post_status' => 'publish',
263
+ 'post_type' => 'page',
264
+ ]
265
+ );
266
+ }
267
+
268
+ update_option( $this->fse_page_data_option, true );
269
+ }
270
+
271
+ /**
272
+ * Returns ISO 639 conforming locale string.
273
+ *
274
+ * @return string ISO 639 locale string
275
+ */
276
+ public function get_iso_639_locale() {
277
+ $language = strtolower( get_locale() );
278
+
279
+ if ( in_array( $language, [ 'zh_tw', 'zh-tw', 'zh_cn', 'zh-cn' ], true ) ) {
280
+ $language = str_replace( '_', '-', $language );
281
+ } else {
282
+ $language = preg_replace( '/([-_].*)$/i', '', $language );
283
+ }
284
+
285
+ return $language;
286
+ }
287
+
288
+ /**
289
+ * Register post types.
290
+ */
291
+ public function register_template_post_types() {
292
+ register_post_type(
293
+ 'wp_template',
294
+ array(
295
+ 'labels' => array(
296
+ 'name' => _x( 'Templates', 'post type general name', 'full-site-editing' ),
297
+ 'singular_name' => _x( 'Template', 'post type singular name', 'full-site-editing' ),
298
+ 'menu_name' => _x( 'Templates', 'admin menu', 'full-site-editing' ),
299
+ 'name_admin_bar' => _x( 'Template', 'add new on admin bar', 'full-site-editing' ),
300
+ 'add_new' => _x( 'Add New', 'Template', 'full-site-editing' ),
301
+ 'add_new_item' => __( 'Add New Template', 'full-site-editing' ),
302
+ 'new_item' => __( 'New Template', 'full-site-editing' ),
303
+ 'edit_item' => __( 'Edit Template', 'full-site-editing' ),
304
+ 'view_item' => __( 'View Template', 'full-site-editing' ),
305
+ 'all_items' => __( 'All Templates', 'full-site-editing' ),
306
+ 'search_items' => __( 'Search Templates', 'full-site-editing' ),
307
+ 'not_found' => __( 'No templates found.', 'full-site-editing' ),
308
+ 'not_found_in_trash' => __( 'No templates found in Trash.', 'full-site-editing' ),
309
+ 'filter_items_list' => __( 'Filter templates list', 'full-site-editing' ),
310
+ 'items_list_navigation' => __( 'Templates list navigation', 'full-site-editing' ),
311
+ 'items_list' => __( 'Templates list', 'full-site-editing' ),
312
+ 'item_published' => __( 'Template published.', 'full-site-editing' ),
313
+ 'item_published_privately' => __( 'Template published privately.', 'full-site-editing' ),
314
+ 'item_reverted_to_draft' => __( 'Template reverted to draft.', 'full-site-editing' ),
315
+ 'item_scheduled' => __( 'Template scheduled.', 'full-site-editing' ),
316
+ 'item_updated' => __( 'Template updated.', 'full-site-editing' ),
317
+ ),
318
+ 'menu_icon' => 'dashicons-layout',
319
+ 'public' => false,
320
+ 'show_ui' => true, // Otherwise we'd get permission error when trying to edit them.
321
+ 'show_in_menu' => false,
322
+ 'rewrite' => false,
323
+ 'show_in_rest' => true, // Otherwise previews won't be generated in full page view.
324
+ 'rest_base' => 'templates',
325
+ 'rest_controller_class' => __NAMESPACE__ . '\REST_Templates_Controller',
326
+ 'capability_type' => 'template',
327
+ 'capabilities' => array(
328
+ // You need to be able to edit posts, in order to read templates in their raw form.
329
+ 'read' => 'edit_posts',
330
+ // You need to be able to customize, in order to create templates.
331
+ 'create_posts' => 'edit_theme_options',
332
+ 'edit_posts' => 'edit_theme_options',
333
+ 'delete_posts' => 'edit_theme_options',
334
+ 'edit_published_posts' => 'edit_theme_options',
335
+ 'delete_published_posts' => 'edit_theme_options',
336
+ 'edit_others_posts' => 'edit_theme_options',
337
+ 'delete_others_posts' => 'edit_theme_options',
338
+ 'publish_posts' => 'edit_theme_options',
339
+ ),
340
+ 'map_meta_cap' => true,
341
+ 'supports' => array(
342
+ 'title',
343
+ 'editor',
344
+ 'revisions',
345
+ ),
346
+ )
347
+ );
348
+
349
+ register_taxonomy(
350
+ 'wp_template_type',
351
+ 'wp_template',
352
+ array(
353
+ 'labels' => array(
354
+ 'name' => _x( 'Template Types', 'taxonomy general name', 'full-site-editing' ),
355
+ 'singular_name' => _x( 'Template Type', 'taxonomy singular name', 'full-site-editing' ),
356
+ 'menu_name' => _x( 'Template Types', 'admin menu', 'full-site-editing' ),
357
+ 'all_items' => __( 'All Template Types', 'full-site-editing' ),
358
+ 'edit_item' => __( 'Edit Template Type', 'full-site-editing' ),
359
+ 'view_item' => __( 'View Template Type', 'full-site-editing' ),
360
+ 'update_item' => __( 'Update Template Type', 'full-site-editing' ),
361
+ 'add_new_item' => __( 'Add New Template Type', 'full-site-editing' ),
362
+ 'new_item_name' => __( 'New Template Type', 'full-site-editing' ),
363
+ 'parent_item' => __( 'Parent Template Type', 'full-site-editing' ),
364
+ 'parent_item_colon' => __( 'Parent Template Type:', 'full-site-editing' ),
365
+ 'search_items' => __( 'Search Template Types', 'full-site-editing' ),
366
+ 'not_found' => __( 'No template types found.', 'full-site-editing' ),
367
+ 'back_to_items' => __( 'Back to template types', 'full-site-editing' ),
368
+ ),
369
+ 'public' => false,
370
+ 'publicly_queryable' => false,
371
+ 'show_ui' => false,
372
+ 'show_in_menu' => false,
373
+ 'show_in_nav_menu' => false,
374
+ 'show_in_rest' => true,
375
+ 'rest_base' => 'template_types',
376
+ 'show_tagcloud' => false,
377
+ 'hierarchical' => true,
378
+ 'rewrite' => false,
379
+ 'capabilities' => array(
380
+ 'manage_terms' => 'edit_theme_options',
381
+ 'edit_terms' => 'edit_theme_options',
382
+ 'delete_terms' => 'edit_theme_options',
383
+ 'assign_terms' => 'edit_theme_options',
384
+ ),
385
+ )
386
+ );
387
+ }
388
+ }
full-site-editing/templates/class-wp-template.php ADDED
@@ -0,0 +1,182 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * WP Template file.
4
+ *
5
+ * @package A8C\FSE
6
+ */
7
+
8
+ namespace A8C\FSE;
9
+
10
+ /**
11
+ * Class WP_Template
12
+ */
13
+ class WP_Template {
14
+ /**
15
+ * Header template type constant.
16
+ *
17
+ * @var string HEADER
18
+ */
19
+ const HEADER = 'header';
20
+
21
+ /**
22
+ * Footer template type constant
23
+ *
24
+ * @var string FOOTER
25
+ */
26
+ const FOOTER = 'footer';
27
+
28
+ /**
29
+ * Name of the currently active theme that is used to reference its template CPTs.
30
+ *
31
+ * @var string $current_theme_name Name of currently active theme on the site.
32
+ */
33
+ private $current_theme_name;
34
+
35
+ /**
36
+ * List of template types that FSE is currently supporting.
37
+ *
38
+ * @var array $supported_template_types Array of strings containing supported template types.
39
+ */
40
+ public $supported_template_types = [ self::HEADER, self::FOOTER ];
41
+
42
+ /**
43
+ * A8C_WP_Template constructor.
44
+ */
45
+ public function __construct() {
46
+ $this->current_theme_name = $this->normalize_theme_slug( get_stylesheet() );
47
+ }
48
+
49
+ /**
50
+ * Returns normalized theme slug for the current theme.
51
+ *
52
+ * Normalize WP.com theme slugs that differ from those that we'll get on self hosted sites.
53
+ * For example, we will get 'modern-business' when retrieving theme slug on self hosted sites,
54
+ * but due to WP.com setup, on Simple sites we'll get 'pub/modern-business' for the theme.
55
+ *
56
+ * @param string $theme_slug Theme slug to check support for.
57
+ *
58
+ * @return string Normalized theme slug.
59
+ */
60
+ public function normalize_theme_slug( $theme_slug ) {
61
+ if ( 'pub/' === substr( $theme_slug, 0, 4 ) ) {
62
+ $theme_slug = str_replace( 'pub/', '', $theme_slug );
63
+ }
64
+
65
+ return $theme_slug;
66
+ }
67
+
68
+
69
+ /**
70
+ * Checks whether the provided template type is supported in FSE.
71
+ *
72
+ * @param string $template_type String representing the template type.
73
+ *
74
+ * @return bool True if provided template type is supported in FSE, false otherwise.
75
+ */
76
+ public function is_supported_template_type( $template_type ) {
77
+ return in_array( $template_type, $this->supported_template_types, true );
78
+ }
79
+
80
+ /**
81
+ * Returns the post ID of the default template CPT for a given template type.
82
+ *
83
+ * @param string $template_type String representing the template type.
84
+ *
85
+ * @return null|int Template ID if it exists or null otherwise.
86
+ */
87
+ public function get_template_id( $template_type ) {
88
+ if ( ! $this->is_supported_template_type( $template_type ) ) {
89
+ return null;
90
+ }
91
+
92
+ $term = get_term_by( 'name', "$this->current_theme_name-$template_type", 'wp_template_type', ARRAY_A );
93
+
94
+ // Bail if current site doesn't have this term registered.
95
+ if ( ! isset( $term['term_id'] ) ) {
96
+ return null;
97
+ }
98
+
99
+ $template_ids = get_objects_in_term( $term['term_id'], $term['taxonomy'], [ 'order' => 'DESC' ] );
100
+
101
+ // Bail if we haven't found any post instances for this template type.
102
+ if ( empty( $template_ids ) ) {
103
+ return null;
104
+ }
105
+
106
+ /*
107
+ * Assuming that we'll have just one default template for now.
108
+ * We'll add support for multiple header and footer variations in future iterations.
109
+ */
110
+ return $template_ids[0];
111
+ }
112
+
113
+ /**
114
+ * Returns template content for given template type.
115
+ *
116
+ * @param string $template_type String representing the template type.
117
+ *
118
+ * @return null|string Template content if it exists or null otherwise.
119
+ */
120
+ public function get_template_content( $template_type ) {
121
+ if ( ! $this->is_supported_template_type( $template_type ) ) {
122
+ return null;
123
+ }
124
+
125
+ $template_id = $this->get_template_id( $template_type );
126
+
127
+ if ( null === $template_id ) {
128
+ return null;
129
+ }
130
+
131
+ $template_post = get_post( $template_id );
132
+
133
+ if ( null === $template_post ) {
134
+ return;
135
+ }
136
+
137
+ return $template_post->post_content;
138
+ }
139
+
140
+ /**
141
+ * Returns full page template content.
142
+ *
143
+ * We only support one page template for now with header at the top and footer at the bottom.
144
+ *
145
+ * @return null|string
146
+ */
147
+ public function get_page_template_content() {
148
+ $header_id = $this->get_template_id( self::HEADER );
149
+ $footer_id = $this->get_template_id( self::FOOTER );
150
+
151
+ return "<!-- wp:a8c/template {\"templateId\":$header_id,\"className\":\"site-header site-branding\"} /-->" .
152
+ '<!-- wp:a8c/post-content /-->' .
153
+ "<!-- wp:a8c/template {\"templateId\":$footer_id,\"className\":\"site-footer\"} /-->";
154
+ }
155
+
156
+ /**
157
+ * Returns array of blocks that represent the template.
158
+ *
159
+ * @return array
160
+ */
161
+ public function get_template_blocks() {
162
+ $template_content = $this->get_page_template_content();
163
+ $template_blocks = parse_blocks( $template_content );
164
+ return is_array( $template_blocks ) ? $template_blocks : [];
165
+ }
166
+
167
+ /**
168
+ * Output FSE template markup.
169
+ *
170
+ * @param string $template_type String representing the template type.
171
+ *
172
+ * @return null|void Null if unsupported template type is passed, outputs content otherwise.
173
+ */
174
+ public function output_template_content( $template_type ) {
175
+ if ( ! $this->is_supported_template_type( $template_type ) ) {
176
+ return null;
177
+ }
178
+
179
+ // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped
180
+ echo do_blocks( $this->get_template_content( $template_type ) );
181
+ }
182
+ }
posts-list-block/class-posts-list-block.php CHANGED
@@ -2,9 +2,11 @@
2
  /**
3
  * Posts list block file.
4
  *
5
- * @package full-site-editing
6
  */
7
 
 
 
8
  /**
9
  * Class Post_List_Block
10
  */
@@ -13,7 +15,7 @@ class Posts_List_Block {
13
  /**
14
  * Class instance.
15
  *
16
- * @var Posts_List_Block
17
  */
18
  private static $instance = null;
19
 
@@ -29,7 +31,7 @@ class Posts_List_Block {
29
  /**
30
  * Creates instance.
31
  *
32
- * @return \Posts_List_Block
33
  */
34
  public static function get_instance() {
35
  if ( null === self::$instance ) {
@@ -101,7 +103,7 @@ class Posts_List_Block {
101
  * @return string
102
  */
103
  public function render_a8c_post_list_block( $attributes, $content ) {
104
- $posts_list = new WP_Query(
105
  array(
106
  'post_type' => 'post',
107
  'posts_per_page' => $attributes['postsPerPage'],
@@ -112,7 +114,7 @@ class Posts_List_Block {
112
 
113
  add_filter( 'excerpt_more', array( $this, 'custom_excerpt_read_more' ) );
114
 
115
- $content = a8c_pl_render_template(
116
  'posts-list',
117
  array(
118
  'posts_list' => $posts_list,
2
  /**
3
  * Posts list block file.
4
  *
5
+ * @package A8C\FSE
6
  */
7
 
8
+ namespace A8C\FSE;
9
+
10
  /**
11
  * Class Post_List_Block
12
  */
15
  /**
16
  * Class instance.
17
  *
18
+ * @var \A8C\FSE\Posts_List_Block
19
  */
20
  private static $instance = null;
21
 
31
  /**
32
  * Creates instance.
33
  *
34
+ * @return \A8C\FSE\Posts_List_Block
35
  */
36
  public static function get_instance() {
37
  if ( null === self::$instance ) {
103
  * @return string
104
  */
105
  public function render_a8c_post_list_block( $attributes, $content ) {
106
+ $posts_list = new \WP_Query(
107
  array(
108
  'post_type' => 'post',
109
  'posts_per_page' => $attributes['postsPerPage'],
114
 
115
  add_filter( 'excerpt_more', array( $this, 'custom_excerpt_read_more' ) );
116
 
117
+ $content = render_template(
118
  'posts-list',
119
  array(
120
  'posts_list' => $posts_list,
posts-list-block/dist/posts-list-block.deps.json CHANGED
@@ -1 +1 @@
1
- ["wp-blocks","wp-components","wp-editor","wp-element","wp-i18n"]
1
+ ["wp-blocks","wp-components","wp-editor","wp-element","wp-i18n","wp-polyfill"]
posts-list-block/dist/posts-list-block.js CHANGED
@@ -1 +1 @@
1
- !function(e,t){for(var n in t)e[n]=t[n]}(window,function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=8)}([function(e,t){e.exports=wp.element},function(e,t){e.exports=wp.i18n},function(e,t){e.exports=wp.components},function(e){e.exports={b:"a8c/posts-list",a:{postsPerPage:{type:"number",default:10}}}},function(e,t){e.exports=wp.blocks},function(e,t){e.exports=wp.editor},function(e,t,n){},,function(e,t,n){"use strict";n.r(t);var r=n(0),o=n(4),l=n(1),i=n(2),u=n(5),c=n(3),s=(n(6),Object(r.createElement)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},Object(r.createElement)("path",{opacity:".87",fill:"none",d:"M0 0h24v24H0V0z"}),Object(r.createElement)("path",{d:"M3 5v14h17V5H3zm4 2v2H5V7h2zm-2 6v-2h2v2H5zm0 2h2v2H5v-2zm13 2H9v-2h9v2zm0-4H9v-2h9v2zm0-4H9V7h9v2z"})));Object(o.registerBlockType)(c.b,{title:Object(l.__)("Blog Posts Listing","full-site-editing"),description:Object(l.__)("Displays your latest Blog Posts.","full-site-editing"),icon:s,category:"layout",supports:{html:!1,multiple:!1,reusable:!1},attributes:c.a,edit:function(e){var t=e.attributes,n=e.setAttributes,o=e.isSelected;return Object(r.createElement)(r.Fragment,null,Object(r.createElement)(i.Placeholder,{icon:s,label:Object(l.__)("Your recent blog posts will be displayed here.","full-site-editing")},o?Object(r.createElement)(i.RangeControl,{label:Object(l.__)("Number of posts to show","full-site-editing"),value:t.postsPerPage,onChange:function(e){return n({postsPerPage:e})},min:1,max:50}):null),Object(r.createElement)(u.InspectorControls,null,Object(r.createElement)(i.PanelBody,null,Object(r.createElement)(i.RangeControl,{label:Object(l.__)("Number of posts","full-site-editing"),value:t.postsPerPage,onChange:function(e){return n({postsPerPage:e})},min:1,max:50}))))},save:function(){return null}})}]));
1
+ !function(e,t){for(var n in t)e[n]=t[n]}(window,function(e){var t={};function n(o){if(t[o])return t[o].exports;var r=t[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(o,r,function(t){return e[t]}.bind(null,r));return o},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=8)}([function(e,t){!function(){e.exports=this.wp.element}()},function(e,t){!function(){e.exports=this.wp.i18n}()},function(e,t){!function(){e.exports=this.wp.components}()},function(e){e.exports={b:"a8c/posts-list",a:{postsPerPage:{type:"number",default:10}}}},function(e,t){!function(){e.exports=this.wp.blocks}()},function(e,t){!function(){e.exports=this.wp.editor}()},function(e,t,n){},,function(e,t,n){"use strict";n.r(t);var o=n(0),r=n(4),i=n(1),l=n(2),u=n(5),c=n(3),s=(n(6),Object(o.createElement)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},Object(o.createElement)("path",{opacity:".87",fill:"none",d:"M0 0h24v24H0V0z"}),Object(o.createElement)("path",{d:"M3 5v14h17V5H3zm4 2v2H5V7h2zm-2 6v-2h2v2H5zm0 2h2v2H5v-2zm13 2H9v-2h9v2zm0-4H9v-2h9v2zm0-4H9V7h9v2z"})));Object(r.registerBlockType)(c.b,{title:Object(i.__)("Blog Posts Listing","full-site-editing"),description:Object(i.__)("Displays your latest Blog Posts.","full-site-editing"),icon:s,category:"layout",supports:{html:!1,multiple:!1,reusable:!1},attributes:c.a,edit:function(e){var t=e.attributes,n=e.setAttributes,r=e.isSelected;return Object(o.createElement)(o.Fragment,null,Object(o.createElement)(l.Placeholder,{icon:s,label:Object(i.__)("Your recent blog posts will be displayed here.","full-site-editing")},r?Object(o.createElement)(l.RangeControl,{label:Object(i.__)("Number of posts to show","full-site-editing"),value:t.postsPerPage,onChange:function(e){return n({postsPerPage:e})},min:1,max:50}):null),Object(o.createElement)(u.InspectorControls,null,Object(o.createElement)(l.PanelBody,null,Object(o.createElement)(l.RangeControl,{label:Object(i.__)("Number of posts","full-site-editing"),value:t.postsPerPage,onChange:function(e){return n({postsPerPage:e})},min:1,max:50}))))},save:function(){return null}})}]));
posts-list-block/templates/no-posts.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
  /**
3
- * Template part for displaying a message that posts cannot be found.
4
  *
5
  * @package full-site-editing
6
  * @link https://developer.wordpress.org/themes/basics/template-hierarchy/
1
  <?php
2
  /**
3
+ * Template for displaying a message that posts cannot be found.
4
  *
5
  * @package full-site-editing
6
  * @link https://developer.wordpress.org/themes/basics/template-hierarchy/
posts-list-block/templates/posts-list.php CHANGED
@@ -33,7 +33,7 @@ if ( $posts_list instanceof WP_Query && $posts_list->have_posts() ) :
33
  <?php
34
  else :
35
  // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
36
- echo a8c_pl_render_template( 'no-posts' );
37
  endif;
38
 
39
 
33
  <?php
34
  else :
35
  // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
36
+ echo A8C\FSE\render_template( 'no-posts' );
37
  endif;
38
 
39
 
posts-list-block/utils.php CHANGED
@@ -2,45 +2,45 @@
2
  /**
3
  * Template functions.
4
  *
5
- * @package full-site-editing
6
  */
7
 
8
- if ( ! function_exists( 'a8c_pl_render_template' ) ) {
9
- /**
10
- * OUTPUT BUFFERED LOAD TEMPLATE PART.
11
- *
12
- * Loads a given template using output buffering.
13
- * Optionally including $data to be passed into template.
14
- *
15
- * @param string $template_name Name of the template to be located.
16
- * @param array $data Optional. Associative array of data to be passed into the template. Default empty array.
17
- * @return string
18
- */
19
- function a8c_pl_render_template( $template_name, $data = array() ) {
20
-
21
- if ( ! strpos( $template_name, '.php' ) ) {
22
- $template_name = $template_name . '.php';
23
- }
24
 
25
- $template_file = __DIR__ . '/templates/' . $template_name;
 
 
 
 
 
 
 
 
 
 
26
 
27
- if ( ! file_exists( $template_file ) ) {
28
- return '';
29
- }
30
 
31
- // Optionally provided an assoc array of data to pass to template
32
- // and it will be extracted into variables.
33
- if ( is_array( $data ) ) {
34
- foreach ( $data as $name => $value ) {
35
- $GLOBALS[ $name ] = $value;
36
- }
37
- }
38
 
39
- ob_start();
40
- require_once $template_file;
41
- $content = ob_get_contents();
42
- ob_end_clean();
43
 
44
- return $content;
 
 
 
 
 
45
  }
 
 
 
 
 
 
 
46
  }
2
  /**
3
  * Template functions.
4
  *
5
+ * @package A8C\FSE
6
  */
7
 
8
+ namespace A8C\FSE;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
 
10
+ /**
11
+ * OUTPUT BUFFERED LOAD TEMPLATE PART.
12
+ *
13
+ * Loads a given template using output buffering.
14
+ * Optionally including $data to be passed into template.
15
+ *
16
+ * @param string $template_name Name of the template to be located.
17
+ * @param array $data Optional. Associative array of data to be passed into the template. Default empty array.
18
+ * @return string
19
+ */
20
+ function render_template( $template_name, $data = array() ) {
21
 
22
+ if ( ! strpos( $template_name, '.php' ) ) {
23
+ $template_name = $template_name . '.php';
24
+ }
25
 
26
+ $template_file = __DIR__ . '/templates/' . $template_name;
 
 
 
 
 
 
27
 
28
+ if ( ! file_exists( $template_file ) ) {
29
+ return '';
30
+ }
 
31
 
32
+ // Optionally provided an assoc array of data to pass to template
33
+ // and it will be extracted into variables.
34
+ if ( is_array( $data ) ) {
35
+ foreach ( $data as $name => $value ) {
36
+ $GLOBALS[ $name ] = $value;
37
+ }
38
  }
39
+
40
+ ob_start();
41
+ require_once $template_file;
42
+ $content = ob_get_contents();
43
+ ob_end_clean();
44
+
45
+ return $content;
46
  }
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: alexislloyd, allancole, automattic, codebykat, copons, dmsnell, ge
3
  Tags: block, blocks, editor, gutenberg, page
4
  Requires at least: 5.0
5
  Tested up to: 5.2
6
- Stable tag: 0.4
7
  Requires PHP: 5.6.20
8
  License: GPLv2 or later
9
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
@@ -40,6 +40,16 @@ This plugin is experimental, so we don't provide any support for it outside of w
40
 
41
  == Changelog ==
42
 
 
 
 
 
 
 
 
 
 
 
43
  = 0.4 =
44
  * Move template data initialization out of the plugin and delegate it to themes.
45
 
3
  Tags: block, blocks, editor, gutenberg, page
4
  Requires at least: 5.0
5
  Tested up to: 5.2
6
+ Stable tag: 0.6
7
  Requires PHP: 5.6.20
8
  License: GPLv2 or later
9
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
40
 
41
  == Changelog ==
42
 
43
+ = 0.6.1 =
44
+ * Updates priority of filter so classnames are added properly to the template blocks.
45
+
46
+ = 0.6 =
47
+ * Fix issues with Edit template and Back to Page functionality.
48
+
49
+ = 0.5 =
50
+ * Fetch templates data from the API.
51
+ * Improve UX flows and fix styling issues.
52
+
53
  = 0.4 =
54
  * Move template data initialization out of the plugin and delegate it to themes.
55
 
starter-page-templates/class-starter-page-templates.php CHANGED
@@ -2,9 +2,11 @@
2
  /**
3
  * Starter page templates file.
4
  *
5
- * @package full-site-editing
6
  */
7
 
 
 
8
  /**
9
  * Class Starter_Page_Templates
10
  */
@@ -29,7 +31,7 @@ class Starter_Page_Templates {
29
  /**
30
  * Creates instance.
31
  *
32
- * @return \Starter_Page_Templates
33
  */
34
  public static function get_instance() {
35
  if ( null === self::$instance ) {
@@ -169,7 +171,7 @@ class Starter_Page_Templates {
169
  */
170
  public function fetch_vertical_data() {
171
  $vertical_id = get_option( 'site_vertical', 'default' );
172
- $transient_key = implode( '_', [ 'starter_page_templates', A8C_FSE_VERSION, $vertical_id, get_locale() ] );
173
  $vertical_templates = get_transient( $transient_key );
174
 
175
  // Load fresh data if we don't have any or vertical_id doesn't match.
2
  /**
3
  * Starter page templates file.
4
  *
5
+ * @package A8C\FSE
6
  */
7
 
8
+ namespace A8C\FSE;
9
+
10
  /**
11
  * Class Starter_Page_Templates
12
  */
31
  /**
32
  * Creates instance.
33
  *
34
+ * @return \A8C\FSE\Starter_Page_Templates
35
  */
36
  public static function get_instance() {
37
  if ( null === self::$instance ) {
171
  */
172
  public function fetch_vertical_data() {
173
  $vertical_id = get_option( 'site_vertical', 'default' );
174
+ $transient_key = implode( '_', [ 'starter_page_templates', PLUGIN_VERSION, $vertical_id, get_locale() ] );
175
  $vertical_templates = get_transient( $transient_key );
176
 
177
  // Load fresh data if we don't have any or vertical_id doesn't match.
starter-page-templates/dist/starter-page-templates.deps.json CHANGED
@@ -1 +1 @@
1
- ["lodash","wp-blocks","wp-components","wp-compose","wp-data","wp-element","wp-i18n","wp-nux","wp-plugins"]
1
+ ["lodash","wp-blocks","wp-components","wp-compose","wp-data","wp-element","wp-i18n","wp-nux","wp-plugins","wp-polyfill"]
starter-page-templates/dist/starter-page-templates.js CHANGED
@@ -1,4 +1,4 @@
1
- !function(e,t){for(var n in t)e[n]=t[n]}(window,function(e){var t={};function n(o){if(t[o])return t[o].exports;var r=t[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(o,r,function(t){return e[t]}.bind(null,r));return o},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=22)}([function(e,t){e.exports=wp.element},function(e,t){e.exports=wp.i18n},function(e,t){e.exports=lodash},function(e,t){e.exports=function(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}},function(e,t){e.exports=function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}},function(e,t){e.exports=wp.compose},function(e,t){e.exports=wp.components},function(e,t,n){var o=n(3);e.exports=function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{},r=Object.keys(n);"function"==typeof Object.getOwnPropertySymbols&&(r=r.concat(Object.getOwnPropertySymbols(n).filter(function(e){return Object.getOwnPropertyDescriptor(n,e).enumerable}))),r.forEach(function(t){o(e,t,n[t])})}return e}},function(e,t){e.exports=wp.data},function(e,t){e.exports=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}},function(e,t){function n(e,t){for(var n=0;n<t.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}e.exports=function(e,t,o){return t&&n(e.prototype,t),o&&n(e,o),e}},function(e,t,n){var o=n(17),r=n(4);e.exports=function(e,t){return!t||"object"!==o(t)&&"function"!=typeof t?r(e):t}},function(e,t){function n(t){return e.exports=n=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},n(t)}e.exports=n},function(e,t,n){var o=n(18);e.exports=function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&o(e,t)}},function(e,t){e.exports=wp.plugins},function(e,t){e.exports=wp.blocks},function(e,t,n){var o;
2
  /*!
3
  Copyright (c) 2017 Jed Watson.
4
  Licensed under the MIT License (MIT), see
@@ -9,4 +9,4 @@
9
  Licensed under the MIT License (MIT), see
10
  http://jedwatson.github.io/classnames
11
  */
12
- !function(){"use strict";var n={}.hasOwnProperty;function r(){for(var e=[],t=0;t<arguments.length;t++){var o=arguments[t];if(o){var i=typeof o;if("string"===i||"number"===i)e.push(o);else if(Array.isArray(o)&&o.length){var l=r.apply(null,o);l&&e.push(l)}else if("object"===i)for(var c in o)n.call(o,c)&&o[c]&&e.push(c)}}return e.join(" ")}e.exports?(r.default=r,e.exports=r):void 0===(o=function(){return r}.apply(t,[]))||(e.exports=o)}()},function(e,t){function n(e){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function o(t){return"function"==typeof Symbol&&"symbol"===n(Symbol.iterator)?e.exports=o=function(e){return n(e)}:e.exports=o=function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":n(e)},o(t)}e.exports=o},function(e,t){function n(t,o){return e.exports=n=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},n(t,o)}e.exports=n},function(e,t){e.exports=wp.nux},function(e,t,n){},,function(e,t,n){"use strict";n.r(t);var o=n(7),r=n.n(o),i=n(9),l=n.n(i),c=n(10),a=n.n(c),s=n(11),u=n.n(s),p=n(12),f=n.n(p),m=n(4),d=n.n(m),b=n(13),v=n.n(b),y=n(3),_=n.n(y),g=n(0),O=n(2),j=n(1),w=n(5),h=n(6),x=n(14),P=n(8),S=n(15),E=(n(19),{Address:Object(j._x)("123 Main St","default address","full-site-editing"),Phone:Object(j._x)("555-555-5555","default phone number","full-site-editing"),CompanyName:Object(j._x)("Your Company Name","default company name","full-site-editing"),Vertical:Object(j._x)("Business","default vertical name","full-site-editing")}),k={CompanyName:"title",Address:"address",Phone:"phone",Vertical:"vertical"},C=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return e.replace(/{{(\w+)}}/g,function(e,n){var o=E[n];return t[k[n]]||o||n})},N=(n(20),n(16)),T=n.n(N);var M=Object(w.withInstanceId)(function(e){var t=e.label,n=e.className,o=e.help,r=e.instanceId,i=e.onClick,l=e.templates,c=void 0===l?[]:l,a="template-selector-control-".concat(r),s=function(e){return i(e.target.value)};return Object(O.isEmpty)(c)?null:Object(g.createElement)(h.BaseControl,{label:t,id:a,help:o,className:T()(n,"template-selector-control")},Object(g.createElement)("ul",{className:"template-selector-control__options"},c.map(function(e,t){return Object(g.createElement)("li",{key:"".concat(a,"-").concat(t),className:"template-selector-control__option"},Object(g.createElement)("button",{type:"button",id:"".concat(a,"-").concat(t),className:"template-selector-control__label",value:e.value,onClick:s,"aria-describedby":o?"".concat(a,"__help"):void 0},Object(g.createElement)("div",{className:"template-selector-control__media-wrap"},e.preview&&Object(g.createElement)("img",{className:"template-selector-control__media",src:e.preview,alt:e.previewAlt||""})),e.label))})))});window._tkq=window._tkq||[];var I,q=null,A=function(e,t){q&&window._tkq.push(["recordEvent","a8c_full_site_editing_template_selector_dismiss",{blog_id:q.blogid,segment_id:e,vertical_id:t}])},B=function(e,t,n){q&&window._tkq.push(["recordEvent","a8c_full_site_editing_template_selector_template_selected",{blog_id:q.blogid,segment_id:e,vertical_id:t,template:n}])},D=function(e){function t(e){var n;return l()(this,t),n=u()(this,f()(t).call(this)),_()(d()(n),"state",{isLoading:!1}),_()(d()(n),"selectTemplate",function(e){n.setState({isOpen:!1}),B(n.props.segment.id,n.props.vertical.id,e);var t=n.props.templates[e];if(n.props.saveTemplateChoice(t),Object(O.has)(t,"content")){var o=r()({},t,{title:C(t.title,n.props.siteInformation),content:C(t.content,n.props.siteInformation)});n.props.insertTemplate(o)}}),_()(d()(n),"closeModal",function(){n.setState({isOpen:!1}),A(n.props.segment.id,n.props.vertical.id)}),n.state.isOpen=!Object(O.isEmpty)(e.templates),n}return v()(t,e),a()(t,[{key:"componentDidMount",value:function(){var e,t;this.state.isOpen&&(e=this.props.segment.id,t=this.props.vertical.id,q&&window._tkq.push(["recordEvent","a8c_full_site_editing_template_selector_view",{blog_id:q.blogid,segment_id:e,vertical_id:t}]))}},{key:"render",value:function(){var e=this;return this.state.isOpen?Object(g.createElement)(h.Modal,{title:Object(j.__)("Select Page Template","full-site-editing"),onRequestClose:this.closeModal,className:"page-template-modal",overlayClassName:"page-template-modal-screen-overlay"},Object(g.createElement)("div",{className:"page-template-modal__inner"},Object(g.createElement)("form",{className:"page-template-modal__form"},Object(g.createElement)("fieldset",{className:"page-template-modal__list"},Object(g.createElement)(M,{label:Object(j.__)("Template","full-site-editing"),templates:Object(O.map)(this.props.templates,function(e){return{label:e.title,value:e.slug,preview:e.preview,previewAlt:e.description}}),onClick:function(t){return e.selectTemplate(t)}}))))):null}}]),t}(g.Component),R=Object(w.compose)(Object(P.withSelect)(function(e){return{getMeta:function(){return e("core/editor").getEditedPostAttribute("meta")},postContentBlock:e("core/editor").getBlocks().find(function(e){return"a8c/post-content"===e.name})}}),Object(P.withDispatch)(function(e,t){e("core/nux").disableTips();var n=e("core/editor");return{saveTemplateChoice:function(e){var o=t.getMeta();n.editPost({meta:r()({},o,{_starter_page_template:e.slug})})},insertTemplate:function(e){n.editPost({title:e.title});var o=t.postContentBlock,r=Object(S.parse)(e.content);n.insertBlocks(r,0,o?o.clientId:"",!1)}}}))(D),U=window.starterPageTemplatesConfig,V=U.siteInformation,L=void 0===V?{}:V,Y=U.templates,z=void 0===Y?[]:Y,F=U.vertical,G=U.segment,H=U.tracksUserData;H&&(q=I=H,window._tkq.push(["identifyUser",I.userid,I.username])),Object(x.registerPlugin)("page-templates",{render:function(){return Object(g.createElement)(R,{templates:Object(O.keyBy)(z,"slug"),vertical:F,segment:G,siteInformation:L})}})}]));
1
+ !function(e,t){for(var n in t)e[n]=t[n]}(window,function(e){var t={};function n(o){if(t[o])return t[o].exports;var r=t[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(o,r,function(t){return e[t]}.bind(null,r));return o},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=22)}([function(e,t){!function(){e.exports=this.wp.element}()},function(e,t){!function(){e.exports=this.wp.i18n}()},function(e,t){!function(){e.exports=this.lodash}()},function(e,t){e.exports=function(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}},function(e,t){e.exports=function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}},function(e,t){!function(){e.exports=this.wp.compose}()},function(e,t){!function(){e.exports=this.wp.components}()},function(e,t,n){var o=n(3);function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,o)}return n}e.exports=function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?r(n,!0).forEach(function(t){o(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):r(n).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}},function(e,t){!function(){e.exports=this.wp.data}()},function(e,t){e.exports=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}},function(e,t){function n(e,t){for(var n=0;n<t.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}e.exports=function(e,t,o){return t&&n(e.prototype,t),o&&n(e,o),e}},function(e,t,n){var o=n(17),r=n(4);e.exports=function(e,t){return!t||"object"!==o(t)&&"function"!=typeof t?r(e):t}},function(e,t){function n(t){return e.exports=n=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},n(t)}e.exports=n},function(e,t,n){var o=n(18);e.exports=function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&o(e,t)}},function(e,t){!function(){e.exports=this.wp.plugins}()},function(e,t){!function(){e.exports=this.wp.blocks}()},function(e,t,n){var o;
2
  /*!
3
  Copyright (c) 2017 Jed Watson.
4
  Licensed under the MIT License (MIT), see
9
  Licensed under the MIT License (MIT), see
10
  http://jedwatson.github.io/classnames
11
  */
12
+ !function(){"use strict";var n={}.hasOwnProperty;function r(){for(var e=[],t=0;t<arguments.length;t++){var o=arguments[t];if(o){var i=typeof o;if("string"===i||"number"===i)e.push(o);else if(Array.isArray(o)&&o.length){var c=r.apply(null,o);c&&e.push(c)}else if("object"===i)for(var l in o)n.call(o,l)&&o[l]&&e.push(l)}}return e.join(" ")}e.exports?(r.default=r,e.exports=r):void 0===(o=function(){return r}.apply(t,[]))||(e.exports=o)}()},function(e,t){function n(e){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function o(t){return"function"==typeof Symbol&&"symbol"===n(Symbol.iterator)?e.exports=o=function(e){return n(e)}:e.exports=o=function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":n(e)},o(t)}e.exports=o},function(e,t){function n(t,o){return e.exports=n=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},n(t,o)}e.exports=n},function(e,t){!function(){e.exports=this.wp.nux}()},function(e,t,n){},,function(e,t,n){"use strict";n.r(t);var o=n(7),r=n.n(o),i=n(9),c=n.n(i),l=n(10),a=n.n(l),s=n(11),u=n.n(s),p=n(12),f=n.n(p),m=n(4),d=n.n(m),b=n(13),y=n.n(b),v=n(3),_=n.n(v),g=n(0),O=n(2),h=n(1),j=n(5),w=n(6),x=n(14),P=n(8),E=n(15),S=(n(19),{Address:Object(h._x)("123 Main St","default address","full-site-editing"),Phone:Object(h._x)("555-555-5555","default phone number","full-site-editing"),CompanyName:Object(h._x)("Your Company Name","default company name","full-site-editing"),Vertical:Object(h._x)("Business","default vertical name","full-site-editing")}),k={CompanyName:"title",Address:"address",Phone:"phone",Vertical:"vertical"},C=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return e.replace(/{{(\w+)}}/g,function(e,n){var o=S[n];return t[k[n]]||o||n})},N=(n(20),n(16)),T=n.n(N);var M=Object(j.withInstanceId)(function(e){var t=e.label,n=e.className,o=e.help,r=e.instanceId,i=e.onClick,c=e.templates,l=void 0===c?[]:c,a="template-selector-control-".concat(r),s=function(e){return i(e.target.value)};return Object(O.isEmpty)(l)?null:Object(g.createElement)(w.BaseControl,{label:t,id:a,help:o,className:T()(n,"template-selector-control")},Object(g.createElement)("ul",{className:"template-selector-control__options"},l.map(function(e,t){return Object(g.createElement)("li",{key:"".concat(a,"-").concat(t),className:"template-selector-control__option"},Object(g.createElement)("button",{type:"button",id:"".concat(a,"-").concat(t),className:"template-selector-control__label",value:e.value,onClick:s,"aria-describedby":o?"".concat(a,"__help"):void 0},Object(g.createElement)("div",{className:"template-selector-control__media-wrap"},e.preview&&Object(g.createElement)("img",{className:"template-selector-control__media",src:e.preview,alt:e.previewAlt||""})),e.label))})))});window._tkq=window._tkq||[];var I,q=null,A=function(e,t){q&&window._tkq.push(["recordEvent","a8c_full_site_editing_template_selector_dismiss",{blog_id:q.blogid,segment_id:e,vertical_id:t}])},B=function(e,t,n){q&&window._tkq.push(["recordEvent","a8c_full_site_editing_template_selector_template_selected",{blog_id:q.blogid,segment_id:e,vertical_id:t,template:n}])},D=function(e){function t(e){var n;return c()(this,t),n=u()(this,f()(t).call(this)),_()(d()(n),"state",{isLoading:!1}),_()(d()(n),"selectTemplate",function(e){n.setState({isOpen:!1}),B(n.props.segment.id,n.props.vertical.id,e);var t=n.props.templates[e];if(n.props.saveTemplateChoice(t),Object(O.has)(t,"content")){var o=r()({},t,{title:C(t.title,n.props.siteInformation),content:C(t.content,n.props.siteInformation)});n.props.insertTemplate(o)}}),_()(d()(n),"closeModal",function(){n.setState({isOpen:!1}),A(n.props.segment.id,n.props.vertical.id)}),n.state.isOpen=!Object(O.isEmpty)(e.templates),n}return y()(t,e),a()(t,[{key:"componentDidMount",value:function(){var e,t;this.state.isOpen&&(e=this.props.segment.id,t=this.props.vertical.id,q&&window._tkq.push(["recordEvent","a8c_full_site_editing_template_selector_view",{blog_id:q.blogid,segment_id:e,vertical_id:t}]))}},{key:"render",value:function(){var e=this;return this.state.isOpen?Object(g.createElement)(w.Modal,{title:Object(h.__)("Select Page Template","full-site-editing"),onRequestClose:this.closeModal,className:"page-template-modal",overlayClassName:"page-template-modal-screen-overlay"},Object(g.createElement)("div",{className:"page-template-modal__inner"},Object(g.createElement)("form",{className:"page-template-modal__form"},Object(g.createElement)("fieldset",{className:"page-template-modal__list"},Object(g.createElement)(M,{label:Object(h.__)("Template","full-site-editing"),templates:Object(O.map)(this.props.templates,function(e){return{label:e.title,value:e.slug,preview:e.preview,previewAlt:e.description}}),onClick:function(t){return e.selectTemplate(t)}}))))):null}}]),t}(g.Component),R=Object(j.compose)(Object(P.withSelect)(function(e){return{getMeta:function(){return e("core/editor").getEditedPostAttribute("meta")},postContentBlock:e("core/editor").getBlocks().find(function(e){return"a8c/post-content"===e.name})}}),Object(P.withDispatch)(function(e,t){e("core/nux").disableTips();var n=e("core/editor");return{saveTemplateChoice:function(e){var o=t.getMeta();n.editPost({meta:r()({},o,{_starter_page_template:e.slug})})},insertTemplate:function(e){n.editPost({title:e.title});var o=t.postContentBlock,r=Object(E.parse)(e.content);n.insertBlocks(r,0,o?o.clientId:"",!1)}}}))(D),U=window.starterPageTemplatesConfig,V=U.siteInformation,L=void 0===V?{}:V,Y=U.templates,z=void 0===Y?[]:Y,F=U.vertical,G=U.segment,H=U.tracksUserData;H&&(q=I=H,window._tkq.push(["identifyUser",I.userid,I.username])),Object(x.registerPlugin)("page-templates",{render:function(){return Object(g.createElement)(R,{templates:Object(O.keyBy)(z,"slug"),vertical:F,segment:G,siteInformation:L})}})}]));