Full Site Editing - Version 0.7

Version Description

  • Change theme support to Maywood instead of Modern Business.
  • Improve style support and UX issues.
  • Remove featured image support for pages.
  • No longer load FSE editor if theme is unsupported.
  • Improve autosave support.
  • Add embed/shortcode support to header and footer.
  • Several other high priority fixes for the FSE editor.
Download this release

Release Info

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

Code changes from version 0.6.1 to 0.7

Files changed (42) hide show
  1. full-site-editing-plugin.php +126 -10
  2. full-site-editing/blocks/navigation-menu/edit.js +4 -4
  3. full-site-editing/blocks/navigation-menu/index.js +9 -1
  4. full-site-editing/blocks/navigation-menu/index.php +24 -9
  5. full-site-editing/blocks/navigation-menu/style.scss +1 -142
  6. full-site-editing/blocks/post-content/index.js +9 -0
  7. full-site-editing/blocks/post-content/style.scss +8 -0
  8. full-site-editing/blocks/site-description/edit.js +7 -2
  9. full-site-editing/blocks/site-description/index.js +8 -0
  10. full-site-editing/blocks/site-description/index.php +6 -0
  11. full-site-editing/blocks/site-description/style.scss +8 -18
  12. full-site-editing/blocks/site-title/edit.js +1 -1
  13. full-site-editing/blocks/site-title/index.js +8 -0
  14. full-site-editing/blocks/site-title/index.php +6 -0
  15. full-site-editing/blocks/site-title/style.scss +8 -23
  16. full-site-editing/blocks/template/edit.js +51 -42
  17. full-site-editing/blocks/template/index.js +1 -0
  18. full-site-editing/blocks/template/style.scss +66 -67
  19. full-site-editing/blocks/useSiteOptions.js +3 -2
  20. full-site-editing/class-full-site-editing.php +74 -25
  21. full-site-editing/dist/full-site-editing.css +1 -1
  22. full-site-editing/dist/full-site-editing.deps.json +1 -1
  23. full-site-editing/dist/full-site-editing.js +2 -2
  24. full-site-editing/dist/full-site-editing.rtl.css +1 -1
  25. full-site-editing/editor/index.js +3 -0
  26. full-site-editing/editor/remove-editor-panels/index.js +31 -0
  27. full-site-editing/editor/style.scss +14 -12
  28. full-site-editing/editor/suppress-draft-action/index.js +34 -0
  29. full-site-editing/editor/suppress-trash-action/index.js +22 -0
  30. full-site-editing/plugins/editor-template-classes/index.js +4 -7
  31. full-site-editing/sass/_mixins.scss +17 -0
  32. full-site-editing/templates/class-wp-template.php +35 -3
  33. posts-list-block/class-posts-list-block.php +21 -6
  34. posts-list-block/dist/posts-list-block.js +1 -1
  35. readme.txt +10 -1
  36. starter-page-templates/class-wp-rest-sideload-image-controller.php +294 -0
  37. starter-page-templates/dist/starter-page-templates.js +2 -2
  38. starter-page-templates/page-template-modal/components/block-template-preview.js +32 -0
  39. starter-page-templates/page-template-modal/components/preview-template-title.js +20 -0
  40. starter-page-templates/page-template-modal/components/template-selector-item.js +58 -0
  41. starter-page-templates/page-template-modal/components/template-selector-preview.js +111 -0
  42. starter-page-templates/page-template-modal/utils/ensure-assets.js +213 -0
full-site-editing-plugin.php CHANGED
@@ -2,7 +2,7 @@
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
@@ -20,20 +20,18 @@ namespace A8C\FSE;
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
- *
32
- * @since 0.2
33
- *
34
- * @param bool true if Full Site Editing should be disabled, false otherwise.
35
- */
36
- if ( apply_filters( 'a8c_disable_full_site_editing', false ) ) {
37
  return;
38
  }
39
 
@@ -52,6 +50,77 @@ function load_full_site_editing() {
52
  }
53
  add_action( 'plugins_loaded', __NAMESPACE__ . '\load_full_site_editing' );
54
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  /**
56
  * Load Posts List Block.
57
  */
@@ -115,3 +184,50 @@ function populate_wp_template_data() {
115
  $fse->insert_default_data();
116
  }
117
  register_activation_hook( __FILE__, __NAMESPACE__ . '\populate_wp_template_data' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  /**
3
  * Plugin Name: Full Site Editing
4
  * Description: Enhances your page creation workflow within the Block Editor.
5
+ * Version: 0.7
6
  * Author: Automattic
7
  * Author URI: https://automattic.com/wordpress-plugins/
8
  * License: GPLv2 or later
20
  *
21
  * @var string
22
  */
23
+ define( 'PLUGIN_VERSION', '0.7' );
24
+
25
+ // Themes which are supported by Full Site Editing (not the same as the SPT themes).
26
+ const SUPPORTED_THEMES = [ 'maywood' ];
27
 
28
  /**
29
  * Load Full Site Editing.
30
  */
31
  function load_full_site_editing() {
32
+ // Bail if FSE should not be active on the site. We do not
33
+ // want to load FSE functionality on non-supported sites!
34
+ if ( ! is_full_site_editing_active() ) {
 
 
 
 
 
35
  return;
36
  }
37
 
50
  }
51
  add_action( 'plugins_loaded', __NAMESPACE__ . '\load_full_site_editing' );
52
 
53
+ /**
54
+ * Whether or not FSE is active.
55
+ * If false, FSE functionality can be disabled.
56
+ *
57
+ * @returns bool True if FSE is active, false otherwise.
58
+ */
59
+ function is_full_site_editing_active() {
60
+ return is_site_eligible_for_full_site_editing() && is_theme_supported();
61
+ }
62
+
63
+ /**
64
+ * Returns normalized theme slug for the current theme.
65
+ *
66
+ * Normalize WP.com theme slugs that differ from those that we'll get on self hosted sites.
67
+ * For example, we will get 'modern-business-wpcom' when retrieving theme slug on self hosted sites,
68
+ * but due to WP.com setup, on Simple sites we'll get 'pub/modern-business' for the theme.
69
+ *
70
+ * @return string Normalized theme slug.
71
+ */
72
+ function get_theme_slug() {
73
+ /**
74
+ * Used to get the correct theme in certain contexts.
75
+ *
76
+ * For example, in the wpcom API context, the theme slug is a8c/public-api, so we need
77
+ * to grab the correct one with the filter.
78
+ *
79
+ * @since 0.7
80
+ *
81
+ * @param string current theme slug is the default if nothing overrides it.
82
+ */
83
+ $theme_slug = apply_filters( 'a8c_fse_get_theme_slug', get_stylesheet() );
84
+
85
+ // Normalize the theme slug.
86
+ if ( 'pub/' === substr( $theme_slug, 0, 4 ) ) {
87
+ $theme_slug = substr( $theme_slug, 4 );
88
+ }
89
+
90
+ if ( '-wpcom' === substr( $theme_slug, -6, 6 ) ) {
91
+ $theme_slug = substr( $theme_slug, 0, -6 );
92
+ }
93
+
94
+ return $theme_slug;
95
+ }
96
+
97
+ /**
98
+ * Whether or not the site is eligible for FSE.
99
+ * This is essentially a feature gate to disable FSE
100
+ * on some sites which could theoretically otherwise use it.
101
+ *
102
+ * @return bool True if current site is eligible for FSE, false otherwise.
103
+ */
104
+ function is_site_eligible_for_full_site_editing() {
105
+ /**
106
+ * Can be used to disable Full Site Editing functionality.
107
+ *
108
+ * @since 0.2
109
+ *
110
+ * @param bool true if Full Site Editing should be disabled, false otherwise.
111
+ */
112
+ return ! apply_filters( 'a8c_disable_full_site_editing', false );
113
+ }
114
+
115
+ /**
116
+ * Whether or not current theme is enabled for FSE.
117
+ *
118
+ * @return bool True if current theme supports FSE, false otherwise.
119
+ */
120
+ function is_theme_supported() {
121
+ return in_array( get_theme_slug(), SUPPORTED_THEMES, true );
122
+ }
123
+
124
  /**
125
  * Load Posts List Block.
126
  */
184
  $fse->insert_default_data();
185
  }
186
  register_activation_hook( __FILE__, __NAMESPACE__ . '\populate_wp_template_data' );
187
+
188
+ /**
189
+ * Add front-end CoBlocks gallery block scripts.
190
+ *
191
+ * This function performs the same enqueueing duties as `CoBlocks_Block_Assets::frontend_scripts`,
192
+ * but for our FSE header and footer content. `frontend_scripts` uses `has_block` to determine
193
+ * if gallery blocks are present, and `has_block` is not aware of content sections outside of
194
+ * post_content yet.
195
+ */
196
+ function enqueue_coblocks_gallery_scripts() {
197
+ if ( ! function_exists( 'CoBlocks' ) || ! is_full_site_editing_active() ) {
198
+ return;
199
+ }
200
+
201
+ $template = new WP_Template();
202
+ $header = $template->get_template_content( 'header' );
203
+ $footer = $template->get_template_content( 'footer' );
204
+
205
+ // Define where the asset is loaded from.
206
+ $dir = CoBlocks()->asset_source( 'js' );
207
+
208
+ // Define where the vendor asset is loaded from.
209
+ $vendors_dir = CoBlocks()->asset_source( 'js', 'vendors' );
210
+
211
+ // Masonry block.
212
+ if ( has_block( 'coblocks/gallery-masonry', $header . $footer ) ) {
213
+ wp_enqueue_script(
214
+ 'coblocks-masonry',
215
+ $dir . 'coblocks-masonry' . COBLOCKS_ASSET_SUFFIX . '.js',
216
+ array( 'jquery', 'masonry', 'imagesloaded' ),
217
+ COBLOCKS_VERSION,
218
+ true
219
+ );
220
+ }
221
+
222
+ // Carousel block.
223
+ if ( has_block( 'coblocks/gallery-carousel', $header . $footer ) ) {
224
+ wp_enqueue_script(
225
+ 'coblocks-flickity',
226
+ $vendors_dir . '/flickity' . COBLOCKS_ASSET_SUFFIX . '.js',
227
+ array( 'jquery' ),
228
+ COBLOCKS_VERSION,
229
+ true
230
+ );
231
+ }
232
+ }
233
+ add_action( 'wp_enqueue_scripts', __NAMESPACE__ . '\enqueue_coblocks_gallery_scripts' );
full-site-editing/blocks/navigation-menu/edit.js CHANGED
@@ -1,4 +1,4 @@
1
- /* eslint-disable wpcalypso/jsx-classname-namespace */
2
  /**
3
  * External dependencies
4
  */
@@ -6,17 +6,17 @@
6
  /**
7
  * WordPress dependencies
8
  */
9
- import { ServerSideRender } from '@wordpress/components';
10
  import { Fragment } from '@wordpress/element';
11
 
12
  /**
13
  * Internal dependencies
14
  */
15
 
16
- const NavigationMenuEdit = ( { attributes } ) => {
17
  return (
18
  <Fragment>
19
- <ServerSideRender attributes={ attributes } block="a8c/navigation-menu" />
20
  </Fragment>
21
  );
22
  };
1
+ /* eslint-disable import/no-extraneous-dependencies */
2
  /**
3
  * External dependencies
4
  */
6
  /**
7
  * WordPress dependencies
8
  */
9
+ import ServerSideRender from '@wordpress/server-side-render';
10
  import { Fragment } from '@wordpress/element';
11
 
12
  /**
13
  * Internal dependencies
14
  */
15
 
16
+ const NavigationMenuEdit = () => {
17
  return (
18
  <Fragment>
19
+ <ServerSideRender block="a8c/navigation-menu" />
20
  </Fragment>
21
  );
22
  };
full-site-editing/blocks/navigation-menu/index.js CHANGED
@@ -1,3 +1,4 @@
 
1
  /**
2
  * WordPress dependencies
3
  */
@@ -23,9 +24,16 @@ registerBlockType( 'a8c/navigation-menu', {
23
  icon,
24
  category: 'layout',
25
  supports: {
 
26
  html: false,
27
  reusable: false,
28
  },
 
 
 
 
 
 
29
  edit,
30
  save: () => null,
31
- } );
1
+ /* eslint-disable import/no-extraneous-dependencies */
2
  /**
3
  * WordPress dependencies
4
  */
24
  icon,
25
  category: 'layout',
26
  supports: {
27
+ align: [ 'wide', 'full' ],
28
  html: false,
29
  reusable: false,
30
  },
31
+ attributes: {
32
+ align: {
33
+ type: 'string',
34
+ default: 'wide',
35
+ },
36
+ },
37
  edit,
38
  save: () => null,
39
+ } );
full-site-editing/blocks/navigation-menu/index.php CHANGED
@@ -10,25 +10,38 @@ namespace A8C\FSE;
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
@@ -49,7 +62,7 @@ function get_fallback_navigation_menu() {
49
  'before' => false,
50
  'container' => 'ul',
51
  'echo' => false,
52
- 'menu_class' => 'main-menu default-menu',
53
  'sort_column' => 'post_date',
54
  ]
55
  );
@@ -62,5 +75,7 @@ function get_fallback_navigation_menu() {
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
  }
10
  /**
11
  * Render the navigation menu.
12
  *
13
+ * @param array $attributes Block attributes.
14
  * @return string
15
  */
16
+ function render_navigation_menu_block( $attributes ) {
17
  $menu = wp_nav_menu(
18
  [
19
  'echo' => false,
20
+ 'fallback_cb' => 'get_fallback_navigation_menu',
21
+ 'items_wrap' => '<ul id="%1$s" class="%2$s" aria-label="submenu">%3$s</ul>',
22
+ 'menu_class' => 'main-menu footer-menu',
23
  'theme_location' => 'menu-1',
24
  ]
25
  );
26
 
27
+ $align = ' alignwide';
28
+ if ( isset( $attributes['align'] ) ) {
29
+ $align = empty( $attributes['align'] ) ? '' : ' align' . $attributes['align'];
30
+ }
31
+
32
  ob_start();
33
  // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped
34
  ?>
35
+ <nav class="main-navigation wp-block-a8c-navigation-menu<?php echo esc_attr( $align ); ?>">
36
+ <input type="checkbox" role="button" aria-haspopup="true" id="toggle" class="hide-visually">
37
+ <label for="toggle" id="toggle-menu" class="button">
38
+ <?php esc_html_e( 'Menu', 'full-site-editing' ); ?>
39
+ <span class="dropdown-icon open">+</span>
40
+ <span class="dropdown-icon close">&times;</span>
41
+ <span class="hide-visually expanded-text"><?php esc_html_e( 'expanded', 'full-site-editing' ); ?></span>
42
+ <span class="hide-visually collapsed-text"><?php esc_html_e( 'collapsed', 'full-site-editing' ); ?></span>
43
+ </label>
44
+ <?php echo $menu ? $menu : get_fallback_navigation_menu(); ?>
45
  </nav>
46
  <!-- #site-navigation -->
47
  <?php
62
  'before' => false,
63
  'container' => 'ul',
64
  'echo' => false,
65
+ 'menu_class' => 'main-menu footer-menu',
66
  'sort_column' => 'post_date',
67
  ]
68
  );
75
  $original_classes = [ 'children', 'page_item_has_sub-menu' ];
76
  $replacement_classes = [ 'sub-menu', 'menu-item-has-children' ];
77
 
78
+ return '<div class="menu-primary-container">'
79
+ . str_replace( $original_classes, $replacement_classes, $menu )
80
+ . '</div>';
81
  }
full-site-editing/blocks/navigation-menu/style.scss CHANGED
@@ -1,144 +1,3 @@
1
  .wp-block-a8c-navigation-menu.main-navigation {
2
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
3
- font-size: 1.125em;
4
- font-weight: 700;
5
- letter-spacing: -0.02em;
6
- line-height: 1.2;
7
- pointer-events: none;
8
- -webkit-font-smoothing: antialiased;
9
- }
10
-
11
- .wp-block-a8c-navigation-menu.main-navigation .main-menu {
12
- display: inline-block;
13
- margin: 0;
14
- padding: 0;
15
- }
16
-
17
- .wp-block-a8c-navigation-menu.main-navigation .main-menu > li {
18
- color: #0073aa;
19
- display: inline;
20
- position: relative;
21
- }
22
-
23
- .wp-block-a8c-navigation-menu.main-navigation .main-menu > li > a {
24
- font-weight: 700;
25
- color: #0073aa;
26
- margin-right: 0.5rem;
27
- }
28
-
29
- .wp-block-a8c-navigation-menu.main-navigation .main-menu > li:last-child > a, .main-navigation .main-menu > li:last-child.menu-item-has-children .submenu-expand {
30
- margin-right: 0;
31
- }
32
-
33
- .wp-block-a8c-navigation-menu.main-navigation .main-menu > li.menu-item-has-children > a {
34
- margin-right: 0.125rem;
35
- }
36
-
37
- .wp-block-a8c-navigation-menu.main-navigation .main-menu > li.menu-item-has-children {
38
- display: inline-block;
39
- position: inherit;
40
- }
41
-
42
- .wp-block-a8c-navigation-menu.main-navigation .main-menu > li.menu-item-has-children .submenu-expand {
43
- display: inline-block;
44
- margin-right: 0.25rem;
45
- }
46
-
47
- .wp-block-a8c-navigation-menu.main-navigation .main-menu > li.menu-item-has-children .submenu-expand svg {
48
- position: relative;
49
- top: 0.3rem;
50
- }
51
-
52
- .wp-block-a8c-navigation-menu.main-navigation .main-menu > li > a:hover, .main-navigation .main-menu > li > a:hover + svg {
53
- color: #005177;
54
- }
55
-
56
- .wp-block-a8c-navigation-menu.main-navigation .main-menu-more {
57
- display: none;
58
- }
59
-
60
- .wp-block-a8c-navigation-menu.main-navigation svg {
61
- transition: fill 120ms ease-in-out;
62
- fill: currentColor;
63
- }
64
-
65
- .wp-block-a8c-navigation-menu.main-navigation a {
66
- text-decoration: none;
67
- }
68
-
69
- .wp-block-a8c-navigation-menu.main-navigation button {
70
- display: inline-block;
71
- border: none;
72
- padding: 0;
73
- margin: 0;
74
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
75
- font-size: 0.88889em;
76
- font-weight: 700;
77
- line-height: 1.2;
78
- text-decoration: none;
79
- vertical-align: bottom;
80
- background: transparent;
81
- color: inherit;
82
- cursor: pointer;
83
- transition: background 250ms ease-in-out, transform 150ms ease;
84
- -webkit-appearance: none;
85
- -moz-appearance: none;
86
- }
87
-
88
- .wp-block-a8c-navigation-menu.main-menu-more {
89
- display: none;
90
- }
91
-
92
- .wp-block-a8c-navigation-menu.social-navigation {
93
- line-height: 1.25;
94
- margin-top: calc( 1rem / 2 );
95
- text-align: left;
96
- }
97
-
98
- .wp-block-a8c-navigation-menu.social-navigation ul.social-links-menu {
99
- content: '';
100
- display: inline-block;
101
- margin: 0;
102
- padding: 0;
103
- }
104
-
105
- .wp-block-a8c-navigation-menu.social-navigation ul.social-links-menu li {
106
- display: inline-block;
107
- vertical-align: bottom;
108
- vertical-align: -webkit-baseline-middle;
109
- list-style: none;
110
- }
111
-
112
- .wp-block-a8c-navigation-menu.social-navigation ul.social-links-menu li a svg {
113
- display: block;
114
- width: 32px;
115
- height: 32px;
116
- transform: translateZ( 0 );
117
- }
118
-
119
- .wp-block-a8c-navigation-menu.footer-navigation .footer-menu {
120
- display: inline;
121
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
122
- font-size: 0.71111em;
123
- padding-left: 0;
124
- }
125
-
126
- .wp-block-a8c-navigation-menu.footer-navigation .footer-menu li {
127
- display: inline;
128
- margin-right: 1rem;
129
- }
130
-
131
- .wp-block-a8c-navigation-menu.footer-navigation .footer-menu a {
132
- text-decoration: none;
133
- color: #767676;
134
- }
135
-
136
- .wp-block-a8c-navigation-menu.footer-navigation .footer-menu a:hover {
137
- text-decoration: none;
138
- color: #0073aa;
139
- }
140
-
141
- .editor-styles-wrapper .wp-block-a8c-navigation-menu-toolbar a,
142
- .editor-styles-wrapper .wp-block-a8c-navigation-menu-toolbar a:hover {
143
- color: #555d66;
144
  }
1
  .wp-block-a8c-navigation-menu.main-navigation {
2
+ pointer-events: none;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  }
full-site-editing/blocks/post-content/index.js CHANGED
@@ -1,3 +1,4 @@
 
1
  /**
2
  * External dependencies
3
  */
@@ -19,12 +20,20 @@ registerBlockType( 'a8c/post-content', {
19
  icon: 'layout',
20
  category: 'layout',
21
  supports: {
 
22
  anchor: false,
23
  customClassName: false,
24
  html: false,
 
25
  multiple: false,
26
  reusable: false,
27
  },
 
 
 
 
 
 
28
  edit,
29
  save,
30
  } );
1
+ /* eslint-disable import/no-extraneous-dependencies */
2
  /**
3
  * External dependencies
4
  */
20
  icon: 'layout',
21
  category: 'layout',
22
  supports: {
23
+ align: [ 'full' ],
24
  anchor: false,
25
  customClassName: false,
26
  html: false,
27
+ inserter: false,
28
  multiple: false,
29
  reusable: false,
30
  },
31
+ attributes: {
32
+ align: {
33
+ type: 'string',
34
+ default: 'full',
35
+ },
36
+ },
37
  edit,
38
  save,
39
  } );
full-site-editing/blocks/post-content/style.scss CHANGED
@@ -34,6 +34,14 @@
34
  }
35
  }
36
 
 
 
 
 
 
 
 
 
37
  /* Hide the content slot block UI */
38
  .block-editor-block-list__layout {
39
  .post-content__block {
34
  }
35
  }
36
 
37
+ // Fix the size and positioning full-width blocks inside the Post Content block
38
+ // TODO: Replace the magic numbers!
39
+ .post-content-block .block-editor-block-list__layout .block-editor-block-list__block[data-align=full] {
40
+ max-width: calc( 100vw - 81px );
41
+ margin-left: 3px;
42
+ margin-right: 3px;
43
+ }
44
+
45
  /* Hide the content slot block UI */
46
  .block-editor-block-list__layout {
47
  .post-content__block {
full-site-editing/blocks/site-description/edit.js CHANGED
@@ -1,6 +1,11 @@
1
  /**
2
  * External dependencies
3
  */
 
 
 
 
 
4
  import { PlainText } from '@wordpress/editor';
5
  import { compose } from '@wordpress/compose';
6
  import { withSelect, withDispatch } from '@wordpress/data';
@@ -48,11 +53,11 @@ function SiteDescriptionEdit( {
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
  />
58
  </Fragment>
1
  /**
2
  * External dependencies
3
  */
4
+ import classNames from 'classnames';
5
+
6
+ /**
7
+ * WordPress dependencies
8
+ */
9
  import { PlainText } from '@wordpress/editor';
10
  import { compose } from '@wordpress/compose';
11
  import { withSelect, withDispatch } from '@wordpress/data';
53
  return (
54
  <Fragment>
55
  <PlainText
56
+ className={ classNames( 'site-description', className ) }
57
  value={ option }
58
  onChange={ value => handleChange( value ) }
59
  onKeyDown={ onKeyDown }
60
+ placeholder={ __( 'Add a Site Description' ) }
61
  aria-label={ __( 'Site Description' ) }
62
  />
63
  </Fragment>
full-site-editing/blocks/site-description/index.js CHANGED
@@ -1,3 +1,4 @@
 
1
  /**
2
  * WordPress dependencies
3
  */
@@ -21,10 +22,17 @@ registerBlockType( 'a8c/site-description', {
21
  ),
22
  category: 'layout',
23
  supports: {
 
24
  html: false,
25
  multiple: false,
26
  reusable: false,
27
  },
 
 
 
 
 
 
28
  edit,
29
  save: () => null,
30
  } );
1
+ /* eslint-disable import/no-extraneous-dependencies */
2
  /**
3
  * WordPress dependencies
4
  */
22
  ),
23
  category: 'layout',
24
  supports: {
25
+ align: [ 'wide', 'full' ],
26
  html: false,
27
  multiple: false,
28
  reusable: false,
29
  },
30
+ attributes: {
31
+ align: {
32
+ type: 'string',
33
+ default: 'wide',
34
+ },
35
+ },
36
  edit,
37
  save: () => null,
38
  } );
full-site-editing/blocks/site-description/index.php CHANGED
@@ -21,6 +21,12 @@ function render_site_description_block( $attributes ) {
21
  $class .= ' ' . $attributes['className'];
22
  }
23
 
 
 
 
 
 
 
24
  ?>
25
  <p class="<?php echo esc_attr( $class ); ?>">
26
  <?php bloginfo( 'description' ); ?>
21
  $class .= ' ' . $attributes['className'];
22
  }
23
 
24
+ $align = ' alignwide';
25
+ if ( isset( $attributes['align'] ) ) {
26
+ $align = empty( $attributes['align'] ) ? '' : ' align' . $attributes['align'];
27
+ }
28
+ $class .= $align;
29
+
30
  ?>
31
  <p class="<?php echo esc_attr( $class ); ?>">
32
  <?php bloginfo( 'description' ); ?>
full-site-editing/blocks/site-description/style.scss CHANGED
@@ -1,22 +1,12 @@
 
 
1
  .block-editor {
2
- .wp-block-a8c-site-description {
3
- &,&:focus {
4
- display: inline;
5
- color: #767676;
6
- font-size: 1.125em;
7
- font-weight: normal;
8
- letter-spacing: -0.01em;
9
- margin: 0;
10
- box-shadow: none;
11
- background-color: transparent;
12
- }
13
  }
14
- .site-description__save-button {
15
- margin-left: auto;
16
- display: block;
17
- }
18
- .site-title:not( :empty ) + .site-description:not( :empty )::before {
19
- content: '\2014';
20
- margin: 0 0.2em;
21
  }
22
  }
1
+ @import '../../sass/mixins';
2
+
3
  .block-editor {
4
+ .wp-block-a8c-site-description:focus {
5
+ box-shadow: none;
6
+ background-color: transparent;
 
 
 
 
 
 
 
 
7
  }
8
+
9
+ .wp-block.is-selected .wp-block-a8c-site-description {
10
+ @include hide-input-placeholder;
 
 
 
 
11
  }
12
  }
full-site-editing/blocks/site-title/edit.js CHANGED
@@ -56,7 +56,7 @@ function SiteTitleEdit( {
56
  value={ option }
57
  onChange={ value => handleChange( value ) }
58
  onKeyDown={ onKeyDown }
59
- placeholder={ __( 'Site Title' ) }
60
  aria-label={ __( 'Site Title' ) }
61
  />
62
  </Fragment>
56
  value={ option }
57
  onChange={ value => handleChange( value ) }
58
  onKeyDown={ onKeyDown }
59
+ placeholder={ __( 'Add a Site Title' ) }
60
  aria-label={ __( 'Site Title' ) }
61
  />
62
  </Fragment>
full-site-editing/blocks/site-title/index.js CHANGED
@@ -1,3 +1,4 @@
 
1
  /**
2
  * WordPress dependencies
3
  */
@@ -16,10 +17,17 @@ registerBlockType( 'a8c/site-title', {
16
  icon: 'layout',
17
  category: 'layout',
18
  supports: {
 
19
  html: false,
20
  multiple: false,
21
  reusable: false,
22
  },
 
 
 
 
 
 
23
  edit,
24
  save: () => null,
25
  } );
1
+ /* eslint-disable import/no-extraneous-dependencies */
2
  /**
3
  * WordPress dependencies
4
  */
17
  icon: 'layout',
18
  category: 'layout',
19
  supports: {
20
+ align: [ 'wide', 'full' ],
21
  html: false,
22
  multiple: false,
23
  reusable: false,
24
  },
25
+ attributes: {
26
+ align: {
27
+ type: 'string',
28
+ default: 'wide',
29
+ },
30
+ },
31
  edit,
32
  save: () => null,
33
  } );
full-site-editing/blocks/site-title/index.php CHANGED
@@ -21,6 +21,12 @@ function render_site_title_block( $attributes ) {
21
  $class .= ' ' . $attributes['className'];
22
  }
23
 
 
 
 
 
 
 
24
  ?>
25
  <h1 class="<?php echo esc_attr( $class ); ?>">
26
  <a href="<?php echo esc_url( home_url( '/' ) ); ?>"><?php bloginfo( 'name' ); ?></a>
21
  $class .= ' ' . $attributes['className'];
22
  }
23
 
24
+ $align = ' alignwide';
25
+ if ( isset( $attributes['align'] ) ) {
26
+ $align = empty( $attributes['align'] ) ? '' : ' align' . $attributes['align'];
27
+ }
28
+ $class .= $align;
29
+
30
  ?>
31
  <h1 class="<?php echo esc_attr( $class ); ?>">
32
  <a href="<?php echo esc_url( home_url( '/' ) ); ?>"><?php bloginfo( 'name' ); ?></a>
full-site-editing/blocks/site-title/style.scss CHANGED
@@ -1,27 +1,12 @@
 
 
1
  .block-editor {
2
- .wp-block-a8c-site-title {
3
- &, &:focus {
4
- display: inline;
5
- color: #111111;
6
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu',
7
- 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
8
- font-size: 1.125em;
9
- font-weight: normal;
10
- letter-spacing: -0.02em;
11
- line-height: 1.2;
12
- margin: 0;
13
- box-shadow: none;
14
- background-color: transparent;
15
- }
16
  }
17
- .site-title__save-button {
18
- margin-left: auto;
19
- display: block;
20
- }
21
- .site-title a:link,
22
- .site-title a:visited {
23
- color: #111;
24
- text-decoration: none;
25
- font-weight: 400;
26
  }
27
  }
1
+ @import '../../sass/mixins';
2
+
3
  .block-editor {
4
+ .wp-block-a8c-site-title:focus {
5
+ box-shadow: none;
6
+ background-color: transparent;
 
 
 
 
 
 
 
 
 
 
 
7
  }
8
+
9
+ .wp-block.is-selected .wp-block-a8c-site-title {
10
+ @include hide-input-placeholder;
 
 
 
 
 
 
11
  }
12
  }
full-site-editing/blocks/template/edit.js CHANGED
@@ -24,11 +24,11 @@ import { addQueryArgs } from '@wordpress/url';
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();
@@ -37,6 +37,7 @@ const TemplateEdit = compose(
37
  post: templateId,
38
  fse_parent_post: currentPostId,
39
  } );
 
40
 
41
  return {
42
  currentPostId,
@@ -46,12 +47,12 @@ const TemplateEdit = compose(
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,
@@ -61,16 +62,12 @@ const TemplateEdit = compose(
61
  }
62
 
63
  const templateBlocks = parse( get( template, [ 'content', 'raw' ], '' ) );
64
- const templateBlock =
65
- templateBlocks.length === 1
66
- ? templateBlocks[ 0 ]
67
- : createBlock( 'core/template', {}, templateBlocks );
68
 
69
  receiveBlocks( [ templateBlock ] );
70
  setState( { templateClientId: templateBlock.clientId } );
71
  },
72
- closeGeneralSidebar,
73
- clearSelectedBlock,
74
  };
75
  } )
76
  )(
@@ -83,12 +80,9 @@ const TemplateEdit = compose(
83
  templateTitle,
84
  isDirty,
85
  savePost,
86
- isSelected,
87
  isEditorSidebarOpened,
88
- closeGeneralSidebar,
89
- clearSelectedBlock,
90
- shouldCloseSidebarOnSelect,
91
- setState,
92
  } ) => {
93
  if ( ! template ) {
94
  return (
@@ -111,55 +105,70 @@ const TemplateEdit = compose(
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
  >
144
  { templateBlock && (
145
  <Fragment>
146
  <Disabled>
147
- <BlockEdit
148
- attributes={ templateBlock.attributes }
149
- block={ templateBlock }
150
- clientId={ templateBlock.clientId }
151
- isSelected={ false }
152
- name={ templateBlock.name }
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>
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, isEditedPostDirty } = select( 'core/editor' );
31
+ const { getBlock, getSelectedBlock } = select( 'core/block-editor' );
32
  const { isEditorSidebarOpened } = select( 'core/edit-post' );
33
  const { templateId } = attributes;
34
  const currentPostId = getCurrentPostId();
37
  post: templateId,
38
  fse_parent_post: currentPostId,
39
  } );
40
+ const selectedBlock = getSelectedBlock();
41
 
42
  return {
43
  currentPostId,
47
  templateTitle: get( template, [ 'title', 'rendered' ], '' ),
48
  isDirty: isEditedPostDirty(),
49
  isEditorSidebarOpened: !! isEditorSidebarOpened(),
50
+ isAnyTemplateBlockSelected: selectedBlock && 'a8c/template' === selectedBlock.name,
51
  };
52
  } ),
53
  withDispatch( ( dispatch, ownProps ) => {
54
  const { receiveBlocks } = dispatch( 'core/block-editor' );
55
+ const { openGeneralSidebar } = dispatch( 'core/edit-post' );
 
56
  const { template, templateClientId, setState } = ownProps;
57
  return {
58
  savePost: dispatch( 'core/editor' ).savePost,
62
  }
63
 
64
  const templateBlocks = parse( get( template, [ 'content', 'raw' ], '' ) );
65
+ const templateBlock = createBlock( 'core/template', {}, templateBlocks );
 
 
 
66
 
67
  receiveBlocks( [ templateBlock ] );
68
  setState( { templateClientId: templateBlock.clientId } );
69
  },
70
+ openGeneralSidebar,
 
71
  };
72
  } )
73
  )(
80
  templateTitle,
81
  isDirty,
82
  savePost,
 
83
  isEditorSidebarOpened,
84
+ openGeneralSidebar,
85
+ isAnyTemplateBlockSelected,
 
 
86
  } ) => {
87
  if ( ! template ) {
88
  return (
105
  } );
106
 
107
  useEffect( () => {
108
+ // Since the Block Sidebar (`edit-post/block`) is not available for the Template block,
109
+ // if the sidebar is open, we force toggle to the Document Sidebar, and hide the Block button.
110
+ const blockSidebarButton = document.querySelector(
111
+ '.edit-post-sidebar__panel-tabs ul li:last-child'
112
+ );
113
+ if ( isEditorSidebarOpened && blockSidebarButton ) {
114
+ if ( isAnyTemplateBlockSelected ) {
115
+ openGeneralSidebar( 'edit-post/document' );
116
+ blockSidebarButton.classList.add( 'hidden' );
117
+ return;
118
  }
119
+ blockSidebarButton.classList.remove( 'hidden' );
 
120
  }
121
+ }, [ isAnyTemplateBlockSelected, isEditorSidebarOpened, openGeneralSidebar ] );
122
 
123
  const { align, className } = attributes;
124
 
125
  const save = event => {
126
+ setNavigateToTemplate( true );
127
  if ( ! isDirty ) {
128
  return;
129
  }
130
  event.preventDefault();
 
131
  savePost();
132
  };
133
 
134
  return (
135
  <div
136
+ className={ classNames( 'template-block', {
137
  [ `align${ align }` ]: align,
138
+ 'is-navigating-to-template': navigateToTemplate,
139
  } ) }
140
  >
141
  { templateBlock && (
142
  <Fragment>
143
  <Disabled>
144
+ <div className={ className }>
145
+ <BlockEdit
146
+ attributes={ templateBlock.attributes }
147
+ block={ templateBlock }
148
+ clientId={ templateBlock.clientId }
149
+ isSelected={ false }
150
+ name={ templateBlock.name }
151
+ setAttributes={ noop }
152
+ />
153
+ </div>
154
  </Disabled>
155
+ <Placeholder className="template-block__overlay">
156
+ { navigateToTemplate && (
157
+ <div className="template-block__loading">
158
+ <Spinner /> { sprintf( __( 'Loading %s Editor' ), templateTitle ) }
159
+ </div>
160
+ ) }
161
+ <Button
162
+ className={ navigateToTemplate ? 'hidden' : null }
163
+ href={ editTemplateUrl }
164
+ onClick={ save }
165
+ isDefault
166
+ isLarge
167
+ ref={ navButton }
168
+ >
169
+ { sprintf( __( 'Edit %s' ), templateTitle ) }
170
+ </Button>
171
+ </Placeholder>
172
  </Fragment>
173
  ) }
174
  </div>
full-site-editing/blocks/template/index.js CHANGED
@@ -28,6 +28,7 @@ if ( 'wp_template' !== fullSiteEditing.editorPostType ) {
28
  anchor: false,
29
  customClassName: false,
30
  html: false,
 
31
  reusable: false,
32
  },
33
  edit,
28
  anchor: false,
29
  customClassName: false,
30
  html: false,
31
+ inserter: false,
32
  reusable: false,
33
  },
34
  edit,
full-site-editing/blocks/template/style.scss CHANGED
@@ -1,95 +1,94 @@
1
  .template-block {
2
  min-height: 200px;
3
-
4
- .components-button .components-spinner {
5
- margin-top: 4px;
6
- }
7
  }
8
 
9
- .template-block.alignfull {
10
- padding: 0 12px;
11
- }
 
12
 
13
- .template-block__selector {
14
- width: 300px;
15
- a {
16
- font-family: sans-serif;
17
- font-size: 13px;
18
- padding-left: 8px;
 
 
 
 
 
 
 
19
  }
20
- }
21
 
22
- .template-block__content {
23
- pointer-events: none;
24
- &::after {
25
- content: '';
26
- clear: both;
27
- display: table;
 
 
 
 
 
 
28
  }
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
- }
1
  .template-block {
2
  min-height: 200px;
3
+ // Prevent blur bleeding
4
+ overflow: hidden;
5
+ position: relative;
 
6
  }
7
 
8
+ .template__block-container {
9
+ &.is-hovered {
10
+ cursor: pointer;
11
+ }
12
 
13
+ &.is-hovered, &.is-selected, .is-navigating-to-template {
14
+ .components-disabled {
15
+ filter: blur( 2px );
16
+ transition: filter 0.2s linear 0.7s;
17
+ }
18
+ .template-block__overlay {
19
+ opacity: 1;
20
+ transition: opacity 0.2s linear;
21
+ .components-button {
22
+ opacity: 1;
23
+ transition: opacity 0.2s linear 0.7s;
24
+ }
25
+ }
26
  }
 
27
 
28
+ .components-disabled {
29
+ filter: blur( 0 );
30
+ transition: filter 0.2s linear 0s;
31
+ }
32
+
33
+ // Hide the block toolbar and border
34
+ .block-editor-block-contextual-toolbar,
35
+ .block-editor-block-list__block-mobile-toolbar,
36
+ .block-editor-block-list__insertion-point,
37
+ .block-editor-block-list__breadcrumb,
38
+ .block-editor-block-list__block-edit::before {
39
+ display: none;
40
  }
41
  }
42
 
43
  .template-block__overlay {
44
+ background: rgba( #ffffff, 0.8 );
45
+ border: 0 solid rgba( #7b86a2, 0.3 ); // Gutenberg $dark-opacity-light-600
46
+ bottom: 0;
47
+ left: 0;
48
+ margin: 0;
49
+ opacity: 0;
50
+ padding: 0;
51
  position: absolute;
52
+ right: 0;
53
+ transition: opacity 0.2s linear 0s;
54
  top: 0;
 
 
 
 
 
 
55
  z-index: 2;
 
56
 
57
+ .is-selected & {
58
+ border-color: rgba( #425863, 0.4 ); // Gutenberg $dark-opacity-light-800
59
+ }
 
 
 
 
 
 
 
60
 
61
+ .editor-block-list__block:first-child & {
62
+ border-bottom-width: 1px;
63
+ }
64
+ .editor-block-list__block:last-child & {
65
+ border-top-width: 1px;
66
+ }
67
 
68
+ @media only screen and ( min-width: 768px ) {
69
+ border-width: 1px;
70
+ }
 
71
 
72
+ .components-button {
73
+ opacity: 0;
74
+ transition: opacity 0.2s linear 0s;
75
+ &.hidden {
76
+ display: none;
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  }
78
  }
79
  }
80
 
81
+ .template-block__loading {
82
+ display: flex;
83
+ align-items: center;
84
+ color: #191e23;
85
+ }
86
+
87
+ // Hide the site logo description and buttons when not editing the Template
88
  .block-editor-page:not( .post-type-wp_template ) {
89
  .fse-site-logo {
90
  .components-placeholder__fieldset, .components-placeholder__instructions {
91
  display: none;
92
  }
93
  }
94
+ }
full-site-editing/blocks/useSiteOptions.js CHANGED
@@ -4,6 +4,7 @@
4
  import { __, sprintf } from '@wordpress/i18n';
5
  import { useState, useEffect } from '@wordpress/element';
6
  import apiFetch from '@wordpress/api-fetch';
 
7
 
8
  /**
9
  * Internal dependencies
@@ -41,8 +42,8 @@ export default function useSiteOptions(
41
  .then( result =>
42
  setSiteOptions( {
43
  ...siteOptions,
44
- option: result[ siteOption ],
45
- previousOption: result[ siteOption ],
46
  loaded: true,
47
  error: false,
48
  } )
4
  import { __, sprintf } from '@wordpress/i18n';
5
  import { useState, useEffect } from '@wordpress/element';
6
  import apiFetch from '@wordpress/api-fetch';
7
+ import { decodeEntities } from '@wordpress/html-entities';
8
 
9
  /**
10
  * Internal dependencies
42
  .then( result =>
43
  setSiteOptions( {
44
  ...siteOptions,
45
+ option: decodeEntities( result[ siteOption ] ),
46
+ previousOption: decodeEntities( result[ siteOption ] ),
47
  loaded: true,
48
  error: false,
49
  } )
full-site-editing/class-full-site-editing.php CHANGED
@@ -39,13 +39,6 @@ class Full_Site_Editing {
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
  */
@@ -63,9 +56,11 @@ class Full_Site_Editing {
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 );
@@ -87,12 +82,16 @@ class Full_Site_Editing {
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
  /**
@@ -102,8 +101,8 @@ class Full_Site_Editing {
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
 
@@ -120,7 +119,7 @@ class Full_Site_Editing {
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.
@@ -129,7 +128,11 @@ class Full_Site_Editing {
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;
@@ -336,13 +339,8 @@ class Full_Site_Editing {
336
  * @param \WP_Post $post Post instance.
337
  */
338
  public function merge_template_and_post( $post ) {
339
- // Bail if not a REST API Request.
340
- if ( defined( 'REST_REQUEST' ) && ! REST_REQUEST ) {
341
- return;
342
- }
343
-
344
- // Bail if the post is not a full site page.
345
- if ( ! $this->is_full_site_page() ) {
346
  return;
347
  }
348
 
@@ -357,6 +355,29 @@ class Full_Site_Editing {
357
  $post->post_content = preg_replace( '@(<!-- wp:a8c/post-content)(.*?)(/-->)@', "$1$2-->$post->post_content<!-- /wp:a8c/post-content -->", $template_content );
358
  }
359
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
360
  /**
361
  * This will extract the inner blocks of the post content and
362
  * serialize them back to HTML for saving.
@@ -431,10 +452,23 @@ class Full_Site_Editing {
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
  /**
@@ -476,7 +510,7 @@ class Full_Site_Editing {
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;
@@ -494,16 +528,31 @@ class Full_Site_Editing {
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
  *
39
  */
40
  public $wp_template_inserter;
41
 
 
 
 
 
 
 
 
42
  /**
43
  * Full_Site_Editing constructor.
44
  */
56
  add_filter( 'post_row_actions', [ $this, 'remove_trash_row_action_for_template_post_types' ], 10, 2 );
57
  add_filter( 'bulk_actions-edit-wp_template', [ $this, 'remove_trash_bulk_action_for_template_post_type' ] );
58
  add_action( 'wp_trash_post', [ $this, 'restrict_template_deletion' ] );
59
+ add_action( 'before_delete_post', [ $this, 'restrict_template_deletion' ] );
60
  add_filter( 'wp_template_type_row_actions', [ $this, 'remove_delete_row_action_for_template_taxonomy' ], 10, 2 );
61
  add_filter( 'bulk_actions-edit-wp_template_type', [ $this, 'remove_delete_bulk_action_for_template_taxonomy' ] );
62
  add_action( 'pre_delete_term', [ $this, 'restrict_template_taxonomy_deletion' ], 10, 2 );
63
+ add_action( 'transition_post_status', [ $this, 'restrict_template_drafting' ], 10, 3 );
64
 
65
  $this->theme_slug = $this->normalize_theme_slug( get_stylesheet() );
66
  $this->wp_template_inserter = new WP_Template_Inserter( $this->theme_slug );
82
  /**
83
  * Determines whether provided theme supports FSE.
84
  *
85
+ * @deprecated being replaced soon by an is_active static method - don't add new usages
86
  * @param string $theme_slug Theme slug to check support for.
87
  *
88
  * @return bool True if passed theme supports FSE, false otherwise.
89
  */
90
+ // phpcs:disable
91
+ public function is_supported_theme( $theme_slug = null ) {
92
+ // phpcs:enable
93
+ // now in reality is_current_theme_supported.
94
+ return current_theme_supports( 'full-site-editing' );
95
  }
96
 
97
  /**
101
  * It is hooked into after_switch_theme action.
102
  */
103
  public function insert_default_data() {
104
+ // Bail if current theme doesn't support FSE.
105
+ if ( ! $this->is_supported_theme() ) {
106
  return;
107
  }
108
 
119
  * Returns normalized theme slug for the current theme.
120
  *
121
  * Normalize WP.com theme slugs that differ from those that we'll get on self hosted sites.
122
+ * For example, we will get 'modern-business-wpcom' when retrieving theme slug on self hosted sites,
123
  * but due to WP.com setup, on Simple sites we'll get 'pub/modern-business' for the theme.
124
  *
125
  * @param string $theme_slug Theme slug to check support for.
128
  */
129
  public function normalize_theme_slug( $theme_slug ) {
130
  if ( 'pub/' === substr( $theme_slug, 0, 4 ) ) {
131
+ $theme_slug = substr( $theme_slug, 4 );
132
+ }
133
+
134
+ if ( '-wpcom' === substr( $theme_slug, -6, 6 ) ) {
135
+ $theme_slug = substr( $theme_slug, 0, -6 );
136
  }
137
 
138
  return $theme_slug;
339
  * @param \WP_Post $post Post instance.
340
  */
341
  public function merge_template_and_post( $post ) {
342
+ // Bail if not a REST API Request and not in the editor.
343
+ if ( ! $this->should_merge_template_and_post( $post ) ) {
 
 
 
 
 
344
  return;
345
  }
346
 
355
  $post->post_content = preg_replace( '@(<!-- wp:a8c/post-content)(.*?)(/-->)@', "$1$2-->$post->post_content<!-- /wp:a8c/post-content -->", $template_content );
356
  }
357
 
358
+ /**
359
+ * Detects if we are in a context where the template and post should be merged.
360
+ *
361
+ * Conditions:
362
+ * 1. Current theme supports it
363
+ * 2. AND in a REST API request (either flavour)
364
+ * 3. OR on a block editor screen (inlined requests using `rest_preload_api_request` )
365
+ * 4. AND editing a post_type that supports full site editing
366
+ *
367
+ * @param \WP_Post $post object for the check.
368
+ * @return bool
369
+ */
370
+ private function should_merge_template_and_post( $post ) {
371
+ $is_rest_api_wpcom = ( defined( 'REST_API_REQUEST' ) && REST_API_REQUEST );
372
+ $is_rest_api_core = ( defined( 'REST_REQUEST' ) && REST_REQUEST );
373
+ $is_block_editor_screen = ( function_exists( 'get_current_screen' ) && get_current_screen() && get_current_screen()->is_block_editor() );
374
+
375
+ if ( ! ( $is_block_editor_screen || $is_rest_api_core || $is_rest_api_wpcom ) ) {
376
+ return false;
377
+ }
378
+ return $this->is_full_site_page( $post );
379
+ }
380
+
381
  /**
382
  * This will extract the inner blocks of the post content and
383
  * serialize them back to HTML for saving.
452
  * Determine if the current edited post is a full site page.
453
  * So far we only support static pages.
454
  *
455
+ * @param object $post optional post object, if not passed in then current post is checked.
456
  * @return boolean
457
  */
458
+ public function is_full_site_page( $post = null ) {
459
+ $post_type = get_post_type( $post );
460
+ return 'page' === $post_type || ( 'revision' === $post_type && 'page' === get_post_type( $post->post_parent ) );
461
+ }
462
+
463
+ /**
464
+ * Determines whether given post belongs to FSE template CPTs.
465
+ *
466
+ * @param WP_Post $post Check if this post belongs to templates.
467
+ *
468
+ * @return boolean
469
+ */
470
+ public function is_template_post_type( $post ) {
471
+ return in_array( $post->post_type, $this->template_post_types, true );
472
  }
473
 
474
  /**
510
  * @return array
511
  */
512
  public function remove_trash_row_action_for_template_post_types( $actions, $post ) {
513
+ if ( $this->is_template_post_type( $post ) ) {
514
  unset( $actions['trash'] );
515
  }
516
  return $actions;
528
  }
529
 
530
  /**
531
+ * Prevents posts for the template post types to be deleted.
532
  *
533
  * @param integer $post_id The post id.
534
  */
535
  public function restrict_template_deletion( $post_id ) {
536
+ if ( $this->is_template_post_type( get_post( $post_id ) ) ) {
537
  wp_die( esc_html__( 'Templates cannot be deleted.' ) );
538
  }
539
  }
540
 
541
+ // phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
542
+ /**
543
+ * Prevents draftinig of template post types.
544
+ *
545
+ * @param string $new_status New post status.
546
+ * @param string $old_status Old post status.
547
+ * @param object $post Post object for which the status change is attempted.
548
+ */
549
+ public function restrict_template_drafting( $new_status, $old_status, $post ) {
550
+ if ( 'draft' === $new_status && $this->is_template_post_type( $post ) ) {
551
+ wp_die( esc_html__( 'Templates cannot be moved to drafts.' ) );
552
+ }
553
+ }
554
+ // phpcs:enable Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
555
+
556
  /**
557
  * Removes the Delete action from the quick actions for the template taxonomy.
558
  *
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}.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}
1
+ .wp-block-a8c-navigation-menu.main-navigation{pointer-events:none}.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}.post-content-block .block-editor-block-list__layout .block-editor-block-list__block[data-align=full]{max-width:calc(100vw - 81px);margin-left:3px;margin-right:3px}.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:focus{box-shadow:none;background-color:transparent}.block-editor .wp-block.is-selected .wp-block-a8c-site-description::-webkit-input-placeholder{color:transparent}.block-editor .wp-block.is-selected .wp-block-a8c-site-description:-moz-placeholder,.block-editor .wp-block.is-selected .wp-block-a8c-site-description::-moz-placeholder{color:transparent}.block-editor .wp-block.is-selected .wp-block-a8c-site-description:-ms-input-placeholder{color:transparent}.block-editor .wp-block-a8c-site-title:focus{box-shadow:none;background-color:transparent}.block-editor .wp-block.is-selected .wp-block-a8c-site-title::-webkit-input-placeholder{color:transparent}.block-editor .wp-block.is-selected .wp-block-a8c-site-title:-moz-placeholder,.block-editor .wp-block.is-selected .wp-block-a8c-site-title::-moz-placeholder{color:transparent}.block-editor .wp-block.is-selected .wp-block-a8c-site-title:-ms-input-placeholder{color:transparent}.template-block{min-height:200px;overflow:hidden;position:relative}.template__block-container.is-hovered{cursor:pointer}.template__block-container.is-hovered .components-disabled,.template__block-container .is-navigating-to-template .components-disabled,.template__block-container.is-selected .components-disabled{filter:blur(2px);transition:filter .2s linear .7s}.template__block-container.is-hovered .template-block__overlay,.template__block-container .is-navigating-to-template .template-block__overlay,.template__block-container.is-selected .template-block__overlay{opacity:1;transition:opacity .2s linear}.template__block-container.is-hovered .template-block__overlay .components-button,.template__block-container .is-navigating-to-template .template-block__overlay .components-button,.template__block-container.is-selected .template-block__overlay .components-button{opacity:1;transition:opacity .2s linear .7s}.template__block-container .components-disabled{filter:blur(0);transition:filter .2s linear 0s}.template__block-container .block-editor-block-contextual-toolbar,.template__block-container .block-editor-block-list__block-edit:before,.template__block-container .block-editor-block-list__block-mobile-toolbar,.template__block-container .block-editor-block-list__breadcrumb,.template__block-container .block-editor-block-list__insertion-point{display:none}.template-block__overlay{background:hsla(0,0%,100%,.8);border:0 solid rgba(123,134,162,.3);bottom:0;left:0;margin:0;opacity:0;padding:0;position:absolute;right:0;transition:opacity .2s linear 0s;top:0;z-index:2}.is-selected .template-block__overlay{border-color:rgba(66,88,99,.4)}.editor-block-list__block:first-child .template-block__overlay{border-bottom-width:1px}.editor-block-list__block:last-child .template-block__overlay{border-top-width:1px}@media only screen and (min-width:768px){.template-block__overlay{border-width:1px}}.template-block__overlay .components-button{opacity:0;transition:opacity .2s linear 0s}.template-block__overlay .components-button.hidden{display:none}.template-block__loading{display:flex;align-items:center;color:#191e23}.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 .edit-post-post-status,.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-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}}.post-type-page .editor-writing-flow__click-redirect,.post-type-wp_template .editor-writing-flow__click-redirect{display:none}.editor-styles-wrapper{background:#fff}.post-type-page .edit-post-visual-editor{padding-top:0}.post-type-page .block-editor-writing-flow{display:block}.post-type-page .wp-block.template__block-container [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-editor","wp-element","wp-hooks","wp-i18n","wp-keycodes","wp-plugins","wp-polyfill","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-html-entities","wp-i18n","wp-keycodes","wp-plugins","wp-polyfill","wp-server-side-render","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 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,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 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)}]));
1
+ !function(t,e){for(var n in e)t[n]=e[n]}(window,function(t){var e={};function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(r,o,function(e){return t[e]}.bind(null,o));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=43)}([function(t,e){!function(){t.exports=this.wp.element}()},function(t,e){!function(){t.exports=this.wp.i18n}()},function(t,e){!function(){t.exports=this.wp.data}()},function(t,e){!function(){t.exports=this.wp.compose}()},function(t,e){!function(){t.exports=this.wp.blocks}()},function(t,e){!function(){t.exports=this.wp.editor}()},function(t,e,n){var r=n(10);function o(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),n.push.apply(n,r)}return n}t.exports=function(t){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{};e%2?o(n,!0).forEach(function(e){r(t,e,n[e])}):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(n)):o(n).forEach(function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(n,e))})}return t}},function(t,e){!function(){t.exports=this.lodash}()},function(t,e,n){var r;
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 o(){for(var t=[],e=0;e<arguments.length;e++){var r=arguments[e];if(r){var i=typeof r;if("string"===i||"number"===i)t.push(r);else if(Array.isArray(r)&&r.length){var c=o.apply(null,r);c&&t.push(c)}else if("object"===i)for(var l in r)n.call(r,l)&&r[l]&&t.push(l)}}return t.join(" ")}t.exports?(o.default=o,t.exports=o):void 0===(r=function(){return o}.apply(e,[]))||(t.exports=r)}()},function(t,e){!function(){t.exports=this.wp.hooks}()},function(t,e){t.exports=function(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}},function(t,e){!function(){t.exports=this.wp.components}()},function(t,e){function n(){return t.exports=n=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(t[r]=n[r])}return t},n.apply(this,arguments)}t.exports=n},function(t,e){!function(){t.exports=this.wp.domReady}()},function(t,e){!function(){t.exports=this.wp.keycodes}()},function(t,e,n){var r=n(33),o=n(34),i=n(35);t.exports=function(t,e){return r(t)||o(t,e)||i()}},function(t,e){!function(){t.exports=this.wp.apiFetch}()},function(t,e){!function(){t.exports=this.wp.htmlEntities}()},function(t,e,n){},function(t,e){!function(){t.exports=this.wp.serverSideRender}()},function(t,e){t.exports=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}},function(t,e){function n(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}t.exports=function(t,e,r){return e&&n(t.prototype,e),r&&n(t,r),t}},function(t,e,n){var r=n(29),o=n(30);t.exports=function(t,e){return!e||"object"!==r(e)&&"function"!=typeof e?o(t):e}},function(t,e){function n(e){return t.exports=n=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)},n(e)}t.exports=n},function(t,e,n){var r=n(31);t.exports=function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&r(t,e)}},function(t,e){!function(){t.exports=this.wp.url}()},function(t,e,n){var r=n(39),o=n(40),i=n(41);t.exports=function(t){return r(t)||o(t)||i()}},function(t,e){!function(){t.exports=this.wp.plugins}()},function(t,e,n){},function(t,e){function n(t){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function r(e){return"function"==typeof Symbol&&"symbol"===n(Symbol.iterator)?t.exports=r=function(t){return n(t)}:t.exports=r=function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":n(t)},r(e)}t.exports=r},function(t,e){t.exports=function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}},function(t,e){function n(e,r){return t.exports=n=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t},n(e,r)}t.exports=n},function(t,e,n){},function(t,e){t.exports=function(t){if(Array.isArray(t))return t}},function(t,e){t.exports=function(t,e){var n=[],r=!0,o=!1,i=void 0;try{for(var c,l=t[Symbol.iterator]();!(r=(c=l.next()).done)&&(n.push(c.value),!e||n.length!==e);r=!0);}catch(a){o=!0,i=a}finally{try{r||null==l.return||l.return()}finally{if(o)throw i}}return n}},function(t,e){t.exports=function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}},function(t,e,n){},function(t,e,n){},function(t,e,n){},function(t,e){t.exports=function(t){if(Array.isArray(t)){for(var e=0,n=new Array(t.length);e<t.length;e++)n[e]=t[e];return n}}},function(t,e){t.exports=function(t){if(Symbol.iterator in Object(t)||"[object Arguments]"===Object.prototype.toString.call(t))return Array.from(t)}},function(t,e){t.exports=function(){throw new TypeError("Invalid attempt to spread non-iterable instance")}},function(t,e,n){},function(t,e,n){"use strict";n.r(e);var r=n(0),o=n(4),i=n(1),c=n(19),l=n.n(c),a=function(){return Object(r.createElement)(r.Fragment,null,Object(r.createElement)(l.a,{block:"a8c/navigation-menu"}))},s=(n(28),Object(r.createElement)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},Object(r.createElement)("path",{fill:"none",d:"M0 0h24v24H0V0z"}),Object(r.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(o.registerBlockType)("a8c/navigation-menu",{title:Object(i.__)("Navigation Menu"),description:Object(i.__)("Visual placeholder for site-wide navigation and menus."),icon:s,category:"layout",supports:{align:["wide","full"],html:!1,reusable:!1},attributes:{align:{type:"string",default:"wide"}},edit:a,save:function(){return null}});var u=n(12),p=n.n(u),d=n(3),f=n(9),b=n(10),m=n.n(b),O=n(20),g=n.n(O),v=n(21),h=n.n(v),y=n(22),j=n.n(y),w=n(23),E=n.n(w),S=n(24),k=n.n(S),_=n(8),P=n.n(_),x=n(2),T=n(5),I=function(t){function e(){return g()(this,e),j()(this,E()(e).apply(this,arguments))}return k()(e,t),h()(e,[{key:"toggleEditing",value:function(){var t=this.props,e=t.isEditing;(0,t.setState)({isEditing:!e})}},{key:"onSelectPost",value:function(t){var e=t.id,n=t.type;this.props.setState({isEditing:!1,selectedPostId:e,selectedPostType:n})}},{key:"render",value:function(){var t=this.props.attributes.align;return Object(r.createElement)(r.Fragment,null,Object(r.createElement)("div",{className:P()("post-content-block",m()({},"align".concat(t),t))},Object(r.createElement)(T.PostTitle,null),Object(r.createElement)(T.InnerBlocks,{templateLock:!1})))}}]),e}(r.Component),B=Object(d.compose)([Object(d.withState)({isEditing:!1,selectedPostId:void 0,selectedPostType:void 0}),Object(x.withSelect)(function(t,e){var n=e.selectedPostId,r=e.selectedPostType;return{selectedPost:(0,t("core").getEntityRecord)("postType",r,n)}})])(I);n(32);Object(o.registerBlockType)("a8c/post-content",{title:Object(i.__)("Content"),description:Object(i.__)("The page content."),icon:"layout",category:"layout",supports:{align:["full"],anchor:!1,customClassName:!1,html:!1,inserter:!1,multiple:!1,reusable:!1},attributes:{align:{type:"string",default:"full"}},edit:B,save:function(){return Object(r.createElement)(T.InnerBlocks.Content,null)}});var C=Object(d.createHigherOrderComponent)(function(t){return function(e){return"a8c/post-content"!==e.name?Object(r.createElement)(t,e):Object(r.createElement)(t,p()({},e,{className:"post-content__block"}))}},"addContentSlotClassname");Object(f.addFilter)("editor.BlockListBlock","full-site-editing/blocks/post-content",C,9);var D=n(14),N=n(6),L=n.n(N),A=n(15),M=n.n(A),F=n(16),R=n.n(F),U=n(17);function H(t){var e=Object(r.useRef)();return Object(r.useEffect)(function(){e.current=t},[t]),e.current}function z(t,e,n,o,c,l){var a=Object(r.useState)({option:e,previousOption:"",loaded:!1,error:!1}),s=M()(a,2),u=s[0],p=s[1],d=H(o),f=H(c);function b(){p(L()({},u,{option:u.previousOption,isSaving:!1}))}return Object(r.useEffect)(function(){u.loaded||u.error?function(){var e=u.option,r=u.previousOption,l=e&&e.trim()===r.trim(),a=!e||0===e.trim().length;!o&&d&&a&&b();if(!c||l)return;!f&&c&&function(e){p(L()({},u,{isSaving:!0})),R()({path:"/wp/v2/settings",method:"POST",data:m()({},t,e)}).then(function(){return function(t){p(L()({},u,{previousOption:t,isDirty:!1,isSaving:!1}))}(e)}).catch(function(){n(Object(i.sprintf)(Object(i.__)("Unable to save site %s"),t)),b()})}(e)}():R()({path:"/wp/v2/settings"}).then(function(e){return p(L()({},u,{option:Object(U.decodeEntities)(e[t]),previousOption:Object(U.decodeEntities)(e[t]),loaded:!0,error:!1}))}).catch(function(){n(Object(i.sprintf)(Object(i.__)("Unable to load site %s"),t)),p(L()({},u,{option:Object(i.sprintf)(Object(i.__)("Error loading site %s"),t),error:!0}))})}),{siteOptions:u,handleChange:function(t){l({updated:Date.now()}),p(L()({},u,{option:t}))}}}var q=Object(d.compose)([Object(x.withSelect)(function(t,e){var n=e.clientId,r=t("core/editor"),o=r.isSavingPost,i=r.isPublishingPost,c=r.isAutosavingPost,l=r.isCurrentPostPublished,a=t("core/block-editor"),s=a.getBlockIndex,u=a.getBlockRootClientId,p=a.getTemplateLock,d=u(n);return{blockIndex:s(n,d),isLocked:!!p(d),rootClientId:d,shouldUpdateSiteOption:(o()&&l()||i())&&!c()}}),Object(x.withDispatch)(function(t,e){var n=e.blockIndex,r=e.rootClientId;return{createErrorNotice:t("core/notices").createErrorNotice,insertDefaultBlock:function(){return t("core/block-editor").insertDefaultBlock({},r,n+1)}}})])(function(t){var e=t.className,n=t.createErrorNotice,o=t.shouldUpdateSiteOption,c=t.isSelected,l=t.setAttributes,a=t.isLocked,s=t.insertDefaultBlock,u=z("description",Object(i.__)("Site description loading…"),n,c,o,l),p=u.siteOptions,d=u.handleChange,f=p.option;return Object(r.createElement)(r.Fragment,null,Object(r.createElement)(T.PlainText,{className:P()("site-description",e),value:f,onChange:function(t){return d(t)},onKeyDown:function(t){t.keyCode===D.ENTER&&(t.preventDefault(),a||s())},placeholder:Object(i.__)("Add a Site Description"),"aria-label":Object(i.__)("Site Description")}))});n(36);Object(o.registerBlockType)("a8c/site-description",{title:Object(i.__)("Site Description"),description:Object(i.__)("Site description, also known as the tagline."),icon:Object(r.createElement)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24"},Object(r.createElement)("path",{fill:"none",d:"M0 0h24v24H0z"}),Object(r.createElement)("path",{d:"M4 9h16v2H4V9zm0 4h10v2H4v-2z"})),category:"layout",supports:{align:["wide","full"],html:!1,multiple:!1,reusable:!1},attributes:{align:{type:"string",default:"wide"}},edit:q,save:function(){return null}});var V=Object(d.compose)([Object(x.withSelect)(function(t,e){var n=e.clientId,r=t("core/editor"),o=r.isSavingPost,i=r.isPublishingPost,c=r.isAutosavingPost,l=r.isCurrentPostPublished,a=t("core/block-editor"),s=a.getBlockIndex,u=a.getBlockRootClientId,p=a.getTemplateLock,d=u(n);return{blockIndex:s(n,d),isLocked:!!p(d),rootClientId:d,shouldUpdateSiteOption:(o()&&l()||i())&&!c()}}),Object(x.withDispatch)(function(t,e){var n=e.blockIndex,r=e.rootClientId;return{createErrorNotice:t("core/notices").createErrorNotice,insertDefaultBlock:function(){return t("core/block-editor").insertDefaultBlock({},r,n+1)}}})])(function(t){var e=t.className,n=t.createErrorNotice,o=t.shouldUpdateSiteOption,c=t.isSelected,l=t.setAttributes,a=t.isLocked,s=t.insertDefaultBlock,u=z("title",Object(i.__)("Site title loading…"),n,c,o,l),p=u.siteOptions,d=u.handleChange,f=p.option;return Object(r.createElement)(r.Fragment,null,Object(r.createElement)(T.PlainText,{className:P()("site-title",e),value:f,onChange:function(t){return d(t)},onKeyDown:function(t){t.keyCode===D.ENTER&&(t.preventDefault(),a||s())},placeholder:Object(i.__)("Add a Site Title"),"aria-label":Object(i.__)("Site Title")}))});n(37);Object(o.registerBlockType)("a8c/site-title",{title:Object(i.__)("Site Title"),description:Object(i.__)("Your site title."),icon:"layout",category:"layout",supports:{align:["wide","full"],html:!1,multiple:!1,reusable:!1},attributes:{align:{type:"string",default:"wide"}},edit:V,save:function(){return null}});var G=n(7),W=n(11),K=n(25),Q=(n(18),Object(d.compose)(Object(d.withState)({templateClientId:null}),Object(x.withSelect)(function(t,e){var n=e.attributes,r=e.templateClientId,o=t("core").getEntityRecord,i=t("core/editor"),c=i.getCurrentPostId,l=i.isEditedPostDirty,a=t("core/block-editor"),s=a.getBlock,u=a.getSelectedBlock,p=t("core/edit-post").isEditorSidebarOpened,d=n.templateId,f=c(),b=d&&o("postType","wp_template",d),m=Object(K.addQueryArgs)(fullSiteEditing.editTemplateBaseUrl,{post:d,fse_parent_post:f}),O=u();return{currentPostId:f,editTemplateUrl:m,template:b,templateBlock:s(r),templateTitle:Object(G.get)(b,["title","rendered"],""),isDirty:l(),isEditorSidebarOpened:!!p(),isAnyTemplateBlockSelected:O&&"a8c/template"===O.name}}),Object(x.withDispatch)(function(t,e){var n=t("core/block-editor").receiveBlocks,r=t("core/edit-post").openGeneralSidebar,i=e.template,c=e.templateClientId,l=e.setState;return{savePost:t("core/editor").savePost,receiveTemplateBlocks:function(){if(i&&!c){var t=Object(o.parse)(Object(G.get)(i,["content","raw"],"")),e=Object(o.createBlock)("core/template",{},t);n([e]),l({templateClientId:e.clientId})}},openGeneralSidebar:r}}))(function(t){var e,n=t.attributes,o=t.editTemplateUrl,c=t.receiveTemplateBlocks,l=t.template,a=t.templateBlock,s=t.templateTitle,u=t.isDirty,p=t.savePost,d=t.isEditorSidebarOpened,f=t.openGeneralSidebar,b=t.isAnyTemplateBlockSelected;if(!l)return Object(r.createElement)(W.Placeholder,null,Object(r.createElement)(W.Spinner,null));var O=Object(r.createRef)(),g=Object(r.useState)(!1),v=M()(g,2),h=v[0],y=v[1];Object(r.useEffect)(function(){h&&!u&&O.current.click(),c()}),Object(r.useEffect)(function(){var t=document.querySelector(".edit-post-sidebar__panel-tabs ul li:last-child");if(d&&t){if(b)return f("edit-post/document"),void t.classList.add("hidden");t.classList.remove("hidden")}},[b,d,f]);var j=n.align,w=n.className;return Object(r.createElement)("div",{className:P()("template-block",(e={},m()(e,"align".concat(j),j),m()(e,"is-navigating-to-template",h),e))},a&&Object(r.createElement)(r.Fragment,null,Object(r.createElement)(W.Disabled,null,Object(r.createElement)("div",{className:w},Object(r.createElement)(T.BlockEdit,{attributes:a.attributes,block:a,clientId:a.clientId,isSelected:!1,name:a.name,setAttributes:G.noop}))),Object(r.createElement)(W.Placeholder,{className:"template-block__overlay"},h&&Object(r.createElement)("div",{className:"template-block__loading"},Object(r.createElement)(W.Spinner,null)," ",Object(i.sprintf)(Object(i.__)("Loading %s Editor"),s)),Object(r.createElement)(W.Button,{className:h?"hidden":null,href:o,onClick:function(t){y(!0),u&&(t.preventDefault(),p())},isDefault:!0,isLarge:!0,ref:O},Object(i.sprintf)(Object(i.__)("Edit %s"),s)))))})),Y=Object(d.createHigherOrderComponent)(function(t){return function(e){return"fse-site-logo"!==e.attributes.className?Object(r.createElement)(t,e):Object(r.createElement)(t,p()({},e,{className:"template__site-logo"}))}},"addFSESiteLogoClassname");Object(f.addFilter)("editor.BlockListBlock","full-site-editing/blocks/template",Y),"wp_template"!==fullSiteEditing.editorPostType&&Object(o.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,inserter:!1,reusable:!1},edit:Q,save:function(){return null},getEditWrapperProps:function(){return{"data-align":"full"}}});var J=Object(d.createHigherOrderComponent)(function(t){return function(e){return"a8c/template"!==e.name?Object(r.createElement)(t,e):Object(r.createElement)(t,p()({},e,{className:"template__block-container"}))}},"addFSETemplateClassname");Object(f.addFilter)("editor.BlockListBlock","full-site-editing/blocks/template",J,9);var X=n(13),Z=n.n(X);n(38);Z()(function(){var t=fullSiteEditing,e=t.closeButtonLabel,n=t.closeButtonUrl,r=t.editorPostType,o=setInterval(function(){var t=document.querySelector(".edit-post-fullscreen-mode-close__toolbar a");if(t)if(clearInterval(o),"wp_template"===r&&n){var i=document.createElement("a");i.href=n,i.innerHTML=e,i.className="components-button components-icon-button is-button is-default",i.setAttribute("aria-label",e),document.querySelector(".edit-post-fullscreen-mode-close__toolbar").replaceChild(i,t)}else t.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>',t.classList.add("a8c-close-button")})});var $=n(26),tt=n.n($),et=n(27),nt=Object(x.withSelect)(function(t){var e=t("core").getEntityRecord,n=t("core/editor").getEditedPostAttribute;return{templateClasses:Object(G.map)(n("template_types"),function(t){var n=Object(G.get)(e("taxonomy","wp_template_type",t),"name","");return Object(G.endsWith)(n,"-header")?"site-header site-branding":Object(G.endsWith)(n,"-footer")?"site-footer":void 0})}})(function(t){var e=t.templateClasses,n=setInterval(function(){var t=document.querySelector(".block-editor-writing-flow.editor-writing-flow > div");t&&(clearInterval(n),t.className=P.a.apply(void 0,["a8c-template-editor"].concat(tt()(e))))});return null});"wp_template"===fullSiteEditing.editorPostType&&Object(et.registerPlugin)("fse-editor-template-classes",{render:nt}),Z()(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 rt=Object(d.compose)(Object(x.withSelect)(function(t){var e=t("core/editor"),n=e.getBlocks,r=e.getEditorSettings,o=t("core/edit-post").getEditorMode,i=n().find(function(t){return"a8c/post-content"===t.name});return{rootClientId:i?i.clientId:"",showInserter:"visual"===o()&&r().richEditingEnabled}}))(function(t){var e=t.rootClientId,n=t.showInserter;return Object(r.createElement)(T.Inserter,{rootClientId:e,disabled:!n,position:"bottom right"})});Z()(function(){return function(){if("page"===fullSiteEditing.editorPostType)var t=setInterval(function(){var e=document.querySelector(".edit-post-header-toolbar");if(e){clearInterval(t);var n=document.createElement("div");n.classList.add("fse-post-content-block-inserter"),e.insertBefore(n,e.firstChild),Object(r.render)(Object(r.createElement)(rt,null),n)}})}()});var ot=Object(x.subscribe)(function(){if("page"!==fullSiteEditing.editorPostType)return ot();!1===Object(x.select)("core/editor").isValidTemplate()&&Object(x.dispatch)("core/editor").setTemplateValidity(!0)}),it=["logo","brand","emblem","hallmark"];Object(f.addFilter)("blocks.registerBlockType","full-site-editing/editor/image-block-keywords",function(t,e){return"core/image"!==e?t:t=Object(G.assign)({},t,{keywords:t.keywords.concat(it)})});n(42);Object(x.use)(function(t){return{dispatch:function(e){var n=L()({},t.dispatch(e)),r=fullSiteEditing.editorPostType;return"core/editor"===e&&n.trashPost&&"wp_template"===r&&(n.trashPost=function(){}),n}}}),Object(x.use)(function(t){return{dispatch:function(e){var n=L()({},t.dispatch(e)),r=fullSiteEditing.editorPostType;if("core/editor"===e&&n.editPost&&"wp_template"===r){var o=n.editPost;n.editPost=function(t){"draft"!==t.status&&o(t)}}return n}}});var ct=Object(x.subscribe)(function(){var t=Object(x.dispatch)("core/edit-post").removeEditorPanel;return"page"===fullSiteEditing.editorPostType&&t("featured-image"),"wp_template"===fullSiteEditing.editorPostType&&t("post-status"),ct()})}]));
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}.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}
1
+ .wp-block-a8c-navigation-menu.main-navigation{pointer-events:none}.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}.post-content-block .block-editor-block-list__layout .block-editor-block-list__block[data-align=full]{max-width:calc(100vw - 81px);margin-right:3px;margin-left:3px}.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:focus{box-shadow:none;background-color:transparent}.block-editor .wp-block.is-selected .wp-block-a8c-site-description::-webkit-input-placeholder{color:transparent}.block-editor .wp-block.is-selected .wp-block-a8c-site-description:-moz-placeholder,.block-editor .wp-block.is-selected .wp-block-a8c-site-description::-moz-placeholder{color:transparent}.block-editor .wp-block.is-selected .wp-block-a8c-site-description:-ms-input-placeholder{color:transparent}.block-editor .wp-block-a8c-site-title:focus{box-shadow:none;background-color:transparent}.block-editor .wp-block.is-selected .wp-block-a8c-site-title::-webkit-input-placeholder{color:transparent}.block-editor .wp-block.is-selected .wp-block-a8c-site-title:-moz-placeholder,.block-editor .wp-block.is-selected .wp-block-a8c-site-title::-moz-placeholder{color:transparent}.block-editor .wp-block.is-selected .wp-block-a8c-site-title:-ms-input-placeholder{color:transparent}.template-block{min-height:200px;overflow:hidden;position:relative}.template__block-container.is-hovered{cursor:pointer}.template__block-container.is-hovered .components-disabled,.template__block-container .is-navigating-to-template .components-disabled,.template__block-container.is-selected .components-disabled{filter:blur(2px);transition:filter .2s linear .7s}.template__block-container.is-hovered .template-block__overlay,.template__block-container .is-navigating-to-template .template-block__overlay,.template__block-container.is-selected .template-block__overlay{opacity:1;transition:opacity .2s linear}.template__block-container.is-hovered .template-block__overlay .components-button,.template__block-container .is-navigating-to-template .template-block__overlay .components-button,.template__block-container.is-selected .template-block__overlay .components-button{opacity:1;transition:opacity .2s linear .7s}.template__block-container .components-disabled{filter:blur(0);transition:filter .2s linear 0s}.template__block-container .block-editor-block-contextual-toolbar,.template__block-container .block-editor-block-list__block-edit:before,.template__block-container .block-editor-block-list__block-mobile-toolbar,.template__block-container .block-editor-block-list__breadcrumb,.template__block-container .block-editor-block-list__insertion-point{display:none}.template-block__overlay{background:hsla(0,0%,100%,.8);border:0 solid rgba(123,134,162,.3);bottom:0;right:0;margin:0;opacity:0;padding:0;position:absolute;left:0;transition:opacity .2s linear 0s;top:0;z-index:2}.is-selected .template-block__overlay{border-color:rgba(66,88,99,.4)}.editor-block-list__block:first-child .template-block__overlay{border-bottom-width:1px}.editor-block-list__block:last-child .template-block__overlay{border-top-width:1px}@media only screen and (min-width:768px){.template-block__overlay{border-width:1px}}.template-block__overlay .components-button{opacity:0;transition:opacity .2s linear 0s}.template-block__overlay .components-button.hidden{display:none}.template-block__loading{display:flex;align-items:center;color:#191e23}.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 .edit-post-post-status,.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-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}}.post-type-page .editor-writing-flow__click-redirect,.post-type-wp_template .editor-writing-flow__click-redirect{display:none}.editor-styles-wrapper{background:#fff}.post-type-page .edit-post-visual-editor{padding-top:0}.post-type-page .block-editor-writing-flow{display:block}.post-type-page .wp-block.template__block-container [data-block]{margin:0}
full-site-editing/editor/index.js CHANGED
@@ -5,3 +5,6 @@ import './block-inserter';
5
  import './template-validity-override';
6
  import './image-block-keywords';
7
  import './style.scss';
 
 
 
5
  import './template-validity-override';
6
  import './image-block-keywords';
7
  import './style.scss';
8
+ import './suppress-trash-action';
9
+ import './suppress-draft-action';
10
+ import './remove-editor-panels';
full-site-editing/editor/remove-editor-panels/index.js ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global fullSiteEditing */
2
+
3
+ /**
4
+ * External dependencies
5
+ */
6
+ import { dispatch, subscribe } from '@wordpress/data';
7
+
8
+ /**
9
+ * Disables specific sidebar editor panels in the FSE context.
10
+ *
11
+ * In particular, we remove the featured image panel for pages,
12
+ * and we remove the post status panel for templates.
13
+ *
14
+ * Note that we only need to remove the panel once as it is persisted
15
+ * in the redux state.
16
+ */
17
+ const unsubscribe = subscribe( () => {
18
+ const { removeEditorPanel } = dispatch( 'core/edit-post' );
19
+ if ( 'page' === fullSiteEditing.editorPostType ) {
20
+ removeEditorPanel( 'featured-image' );
21
+ }
22
+
23
+ // @TODO Since the post status component doesn't check to see if it is removed, the
24
+ // removeEditorPanel action won't have the desired effect. See:
25
+ // https://github.com/WordPress/gutenberg/pull/17117
26
+ // When support is added, we should remove the CSS hack at '../style.scss'
27
+ if ( 'wp_template' === fullSiteEditing.editorPostType ) {
28
+ removeEditorPanel( 'post-status' );
29
+ }
30
+ return unsubscribe();
31
+ } );
full-site-editing/editor/style.scss CHANGED
@@ -4,6 +4,12 @@
4
  display: none;
5
  }
6
 
 
 
 
 
 
 
7
  .edit-post-visual-editor {
8
  margin-top: 20px;
9
  padding-top: 0;
@@ -12,15 +18,6 @@
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 {
@@ -34,9 +31,14 @@
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
@@ -48,14 +50,14 @@
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
  }
4
  display: none;
5
  }
6
 
7
+ // @TODO: Remove this when Gutenberg support is added for
8
+ // removing the PostStatus panel:
9
+ .edit-post-post-status {
10
+ display: none;
11
+ }
12
+
13
  .edit-post-visual-editor {
14
  margin-top: 20px;
15
  padding-top: 0;
18
  .editor-post-switch-to-draft {
19
  display: none;
20
  }
 
 
 
 
 
 
 
 
 
21
  }
22
 
23
  .post-type-page, .post-type-wp_template {
31
  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 );
32
 
33
  @media ( max-width: 768px ) {
34
+ margin: 0;
35
  }
36
  }
37
+
38
+ // Remove the 50vh bottom padding that looks off with the FSE frame.
39
+ .editor-writing-flow__click-redirect {
40
+ display: none;
41
+ }
42
  }
43
 
44
  // We separate this from the other styles so that
50
 
51
  .post-type-page {
52
  .edit-post-visual-editor {
53
+ padding-top: 0;
54
  }
55
 
56
  .block-editor-writing-flow {
57
  display: block;
58
  }
59
 
60
+ .wp-block.template__block-container [data-block] {
61
  margin: 0;
62
  }
63
  }
full-site-editing/editor/suppress-draft-action/index.js ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global fullSiteEditing */
2
+
3
+ /**
4
+ * External dependencies
5
+ */
6
+ import { use } from '@wordpress/data';
7
+
8
+ // The purpose of this override is to prevent Switch to Draft action for template CPTs.
9
+ use( registry => {
10
+ return {
11
+ dispatch: namespace => {
12
+ const actions = { ...registry.dispatch( namespace ) };
13
+ const { editorPostType } = fullSiteEditing;
14
+
15
+ if ( namespace === 'core/editor' && actions.editPost && editorPostType === 'wp_template' ) {
16
+ const originalEditPost = actions.editPost;
17
+
18
+ actions.editPost = edits => {
19
+ const { status } = edits;
20
+
21
+ // Bail if editPost is attempting to set draft as status.
22
+ if ( status === 'draft' ) {
23
+ return;
24
+ }
25
+
26
+ // Proceed with the usual call otherwise.
27
+ originalEditPost( edits );
28
+ };
29
+ }
30
+
31
+ return actions;
32
+ },
33
+ };
34
+ } );
full-site-editing/editor/suppress-trash-action/index.js ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global fullSiteEditing */
2
+
3
+ /**
4
+ * External dependencies
5
+ */
6
+ import { use } from '@wordpress/data';
7
+
8
+ // The purpose of this override is to prevent trash action from deleting template CPTs.
9
+ use( registry => {
10
+ return {
11
+ dispatch: namespace => {
12
+ const actions = { ...registry.dispatch( namespace ) };
13
+ const { editorPostType } = fullSiteEditing;
14
+
15
+ if ( namespace === 'core/editor' && actions.trashPost && editorPostType === 'wp_template' ) {
16
+ actions.trashPost = () => {};
17
+ }
18
+
19
+ return actions;
20
+ },
21
+ };
22
+ } );
full-site-editing/plugins/editor-template-classes/index.js CHANGED
@@ -26,19 +26,16 @@ const EditorTemplateClasses = withSelect( select => {
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;
26
  return { templateClasses };
27
  } )( ( { templateClasses } ) => {
28
  const blockListInception = setInterval( () => {
29
+ const blockList = document.querySelector(
30
+ '.block-editor-writing-flow.editor-writing-flow > div'
31
+ );
32
 
33
  if ( ! blockList ) {
34
  return;
35
  }
36
  clearInterval( blockListInception );
37
 
38
+ blockList.className = classNames( 'a8c-template-editor', ...templateClasses );
 
 
 
 
 
39
  } );
40
 
41
  return null;
full-site-editing/sass/_mixins.scss ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @mixin hide-input-placeholder {
2
+ &::-webkit-input-placeholder {
3
+ color: transparent;
4
+ }
5
+
6
+ &:-moz-placeholder {
7
+ color: transparent;
8
+ }
9
+
10
+ &::-moz-placeholder {
11
+ color: transparent;
12
+ }
13
+
14
+ &:-ms-input-placeholder {
15
+ color: transparent;
16
+ }
17
+ }
full-site-editing/templates/class-wp-template.php CHANGED
@@ -50,7 +50,7 @@ class WP_Template {
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.
@@ -59,7 +59,11 @@ class WP_Template {
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;
@@ -148,6 +152,15 @@ class WP_Template {
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\"} /-->";
@@ -176,7 +189,26 @@ class WP_Template {
176
  return null;
177
  }
178
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
179
  // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped
180
- echo do_blocks( $this->get_template_content( $template_type ) );
181
  }
182
  }
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-wpcom' 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.
59
  */
60
  public function normalize_theme_slug( $theme_slug ) {
61
  if ( 'pub/' === substr( $theme_slug, 0, 4 ) ) {
62
+ $theme_slug = substr( $theme_slug, 4 );
63
+ }
64
+
65
+ if ( '-wpcom' === substr( $theme_slug, -6, 6 ) ) {
66
+ $theme_slug = substr( $theme_slug, 0, -6 );
67
  }
68
 
69
  return $theme_slug;
152
  $header_id = $this->get_template_id( self::HEADER );
153
  $footer_id = $this->get_template_id( self::FOOTER );
154
 
155
+ /*
156
+ * Bail if we are missing header or footer. Otherwise this would cause us to
157
+ * always return some page template content and show template parts (with empty IDs),
158
+ * even for themes that don't support FSE.
159
+ */
160
+ if ( ! $header_id || ! $footer_id ) {
161
+ return null;
162
+ }
163
+
164
  return "<!-- wp:a8c/template {\"templateId\":$header_id,\"className\":\"site-header site-branding\"} /-->" .
165
  '<!-- wp:a8c/post-content /-->' .
166
  "<!-- wp:a8c/template {\"templateId\":$footer_id,\"className\":\"site-footer\"} /-->";
189
  return null;
190
  }
191
 
192
+ // Things that follow are from wp-includes/default-filters.php
193
+ // not everything is appropriate for template content as opposed to post content.
194
+ global $wp_embed;
195
+ $content = $this->get_template_content( $template_type );
196
+
197
+ // 8 priority
198
+ $content = $wp_embed->run_shortcode( $content );
199
+ $content = $wp_embed->autoembed( $content );
200
+
201
+ // 9 priority
202
+ $content = do_blocks( $content );
203
+
204
+ // 10 priority
205
+ $content = wptexturize( $content );
206
+ // @todo maybe look at WPCOM_Responsive_Images for WPCom responsive image handling
207
+
208
+ // 11 priority
209
+ $content = do_shortcode( $content );
210
+
211
  // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped
212
+ echo $content;
213
  }
214
  }
posts-list-block/class-posts-list-block.php CHANGED
@@ -19,6 +19,13 @@ class Posts_List_Block {
19
  */
20
  private static $instance = null;
21
 
 
 
 
 
 
 
 
22
  /**
23
  * A8C_Post_List constructor.
24
  */
@@ -103,6 +110,7 @@ class Posts_List_Block {
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',
@@ -114,12 +122,19 @@ class Posts_List_Block {
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,
121
- )
122
- );
 
 
 
 
 
 
 
123
 
124
  remove_filter( 'excerpt_more', array( $this, 'custom_excerpt_read_more' ) );
125
 
19
  */
20
  private static $instance = null;
21
 
22
+ /**
23
+ * Whether we are in the process of rendering the block.
24
+ *
25
+ * @var bool
26
+ */
27
+ private $rendering_block = false;
28
+
29
  /**
30
  * A8C_Post_List constructor.
31
  */
110
  * @return string
111
  */
112
  public function render_a8c_post_list_block( $attributes, $content ) {
113
+
114
  $posts_list = new \WP_Query(
115
  array(
116
  'post_type' => 'post',
122
 
123
  add_filter( 'excerpt_more', array( $this, 'custom_excerpt_read_more' ) );
124
 
125
+ // Prevent situations when the block attempts rendering another a8c/posts-list block.
126
+ if ( $this->rendering_block !== true ) {
127
+ $this->rendering_block = true;
128
+
129
+ $content = render_template(
130
+ 'posts-list',
131
+ array(
132
+ 'posts_list' => $posts_list,
133
+ )
134
+ );
135
+
136
+ $this->rendering_block = false;
137
+ }
138
 
139
  remove_filter( 'excerpt_more', array( $this, 'custom_excerpt_read_more' ) );
140
 
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(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}})}]));
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=7)}([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}})}]));
readme.txt CHANGED
@@ -1,5 +1,5 @@
1
  === Full Site Editing ===
2
- Contributors: alexislloyd, allancole, automattic, codebykat, copons, dmsnell, get_dave, glendaviesnz, gwwar, iamtakashi, Joen, kwight, marekhrabe, mattwiebe, mmtr86, mppfeiffer, nrqsnchz, obenland, okenobi, vindl
3
  Tags: block, blocks, editor, gutenberg, page
4
  Requires at least: 5.0
5
  Tested up to: 5.2
@@ -40,6 +40,15 @@ This plugin is experimental, so we don't provide any support for it outside of w
40
 
41
  == Changelog ==
42
 
 
 
 
 
 
 
 
 
 
43
  = 0.6.1 =
44
  * Updates priority of filter so classnames are added properly to the template blocks.
45
 
1
  === Full Site Editing ===
2
+ Contributors: alexislloyd, allancole, automattic, codebykat, copons, dmsnell, get_dave, glendaviesnz, gwwar, iamtakashi, Joen, kwight, marekhrabe, mattwiebe, mmtr86, mppfeiffer, nrqsnchz, obenland, okenobi, vindl, noahtallen, owolski
3
  Tags: block, blocks, editor, gutenberg, page
4
  Requires at least: 5.0
5
  Tested up to: 5.2
40
 
41
  == Changelog ==
42
 
43
+ = 0.7 =
44
+ * Change theme support to Maywood instead of Modern Business.
45
+ * Improve style support and UX issues.
46
+ * Remove featured image support for pages.
47
+ * No longer load FSE editor if theme is unsupported.
48
+ * Improve autosave support.
49
+ * Add embed/shortcode support to header and footer.
50
+ * Several other high priority fixes for the FSE editor.
51
+
52
  = 0.6.1 =
53
  * Updates priority of filter so classnames are added properly to the template blocks.
54
 
starter-page-templates/class-wp-rest-sideload-image-controller.php ADDED
@@ -0,0 +1,294 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * WP_REST_Sideload_Image_Controller file.
4
+ *
5
+ * @package A8C\FSE
6
+ */
7
+
8
+ namespace A8C\FSE;
9
+
10
+ /**
11
+ * Class WP_REST_Sideload_Image_Controller.
12
+ */
13
+ class WP_REST_Sideload_Image_Controller extends \WP_REST_Attachments_Controller {
14
+
15
+ /**
16
+ * WP_REST_Sideload_Image_Controller constructor.
17
+ */
18
+ public function __construct() {
19
+ parent::__construct( 'attachment' );
20
+
21
+ $this->namespace = 'fse/v1';
22
+ $this->rest_base = 'sideload/image';
23
+ }
24
+
25
+ /**
26
+ * Register available routes.
27
+ */
28
+ public function register_routes() {
29
+ register_rest_route(
30
+ $this->namespace,
31
+ '/' . $this->rest_base,
32
+ [
33
+ [
34
+ 'methods' => \WP_REST_Server::CREATABLE,
35
+ 'callback' => [ $this, 'create_item' ],
36
+ 'permission_callback' => [ $this, 'create_item_permissions_check' ],
37
+ 'show_in_index' => false,
38
+ 'args' => $this->get_collection_params(),
39
+ ],
40
+ 'schema' => [ $this, 'get_item_schema' ],
41
+ ]
42
+ );
43
+
44
+ register_rest_route(
45
+ $this->namespace,
46
+ '/' . $this->rest_base . '/batch',
47
+ [
48
+ [
49
+ 'methods' => \WP_REST_Server::CREATABLE,
50
+ 'callback' => [ $this, 'create_items' ],
51
+ 'show_in_index' => false,
52
+ 'args' => [
53
+ 'resources' => [
54
+ 'description' => 'URL to the image to be side-loaded.',
55
+ 'type' => 'array',
56
+ 'required' => true,
57
+ 'items' => [
58
+ 'type' => 'object',
59
+ 'properties' => $this->get_collection_params(),
60
+ ],
61
+ ],
62
+ ],
63
+ ],
64
+ ]
65
+ );
66
+ }
67
+
68
+ /**
69
+ * Creates a single attachment.
70
+ *
71
+ * @param \WP_REST_Request $request Full details about the request.
72
+ * @return \WP_Error|\WP_REST_Response Response object on success, WP_Error object on failure.
73
+ */
74
+ public function create_item( $request ) {
75
+ if ( ! empty( $request['post_id'] ) && in_array( get_post_type( $request['post_id'] ), [ 'revision', 'attachment' ], true ) ) {
76
+ return new \WP_Error( 'rest_invalid_param', __( 'Invalid parent type.' ), [ 'status' => 400 ] );
77
+ }
78
+
79
+ $inserted = false;
80
+ $attachment = $this->get_attachment( $request->get_param( 'url' ) );
81
+ if ( ! $attachment ) {
82
+ // Include image functions to get access to wp_read_image_metadata().
83
+ require_once ABSPATH . 'wp-admin/includes/file.php';
84
+ require_once ABSPATH . 'wp-admin/includes/image.php';
85
+ require_once ABSPATH . 'wp-admin/includes/media.php';
86
+
87
+ // The post ID on success, WP_Error on failure.
88
+ $id = media_sideload_image(
89
+ $request->get_param( 'url' ),
90
+ $request->get_param( 'post_id' ),
91
+ null,
92
+ 'id'
93
+ );
94
+
95
+ if ( is_wp_error( $id ) ) {
96
+ if ( 'db_update_error' === $id->get_error_code() ) {
97
+ $id->add_data( [ 'status' => 500 ] );
98
+ } else {
99
+ $id->add_data( [ 'status' => 400 ] );
100
+ }
101
+
102
+ return rest_ensure_response( $id ); // Return error.
103
+ }
104
+
105
+ $attachment = get_post( $id );
106
+
107
+ /**
108
+ * Fires after a single attachment is created or updated via the REST API.
109
+ *
110
+ * @param WP_Post $attachment Inserted or updated attachment object.
111
+ * @param WP_REST_Request $request The request sent to the API.
112
+ * @param bool $creating True when creating an attachment, false when updating.
113
+ */
114
+ do_action( 'rest_insert_attachment', $attachment, $request, true );
115
+
116
+ if ( isset( $request['alt_text'] ) ) {
117
+ update_post_meta( $id, '_wp_attachment_image_alt', sanitize_text_field( $request['alt_text'] ) );
118
+ }
119
+
120
+ update_post_meta( $id, '_sideloaded_url', $request->get_param( 'url' ) );
121
+
122
+ $fields_update = $this->update_additional_fields_for_object( $attachment, $request );
123
+
124
+ if ( is_wp_error( $fields_update ) ) {
125
+ return $fields_update;
126
+ }
127
+
128
+ $inserted = true;
129
+ $request->set_param( 'context', 'edit' );
130
+
131
+ /**
132
+ * Fires after a single attachment is completely created or updated via the REST API.
133
+ *
134
+ * @param WP_Post $attachment Inserted or updated attachment object.
135
+ * @param WP_REST_Request $request Request object.
136
+ * @param bool $creating True when creating an attachment, false when updating.
137
+ */
138
+ do_action( 'rest_after_insert_attachment', $attachment, $request, true );
139
+ }
140
+
141
+ $response = $this->prepare_item_for_response( $attachment, $request );
142
+ $response = rest_ensure_response( $response );
143
+ $response->header( 'Location', rest_url( sprintf( '%s/%s/%d', 'wp/v2', 'media', $attachment->ID ) ) );
144
+
145
+ if ( $inserted ) {
146
+ $response->set_status( 201 );
147
+ }
148
+
149
+ return $response;
150
+ }
151
+
152
+ /**
153
+ * Creates a batch of attachments.
154
+ *
155
+ * @param \WP_REST_Request $request Full details about the request.
156
+ * @return \WP_Error|\WP_REST_Response Response object on success, WP_Error object on failure.
157
+ */
158
+ public function create_items( $request ) {
159
+ $data = [];
160
+
161
+ // Foreach request specified in the requests param, run the endpoint.
162
+ foreach ( $request['resources'] as $resource ) {
163
+ $request = new \WP_REST_Request( 'POST', $this->get_item_route() );
164
+
165
+ // Add specified request parameters into the request.
166
+ foreach ( $resource as $param_name => $param_value ) {
167
+ $request->set_param( $param_name, $param_value );
168
+ }
169
+
170
+ $response = rest_do_request( $request );
171
+ $data[] = $this->prepare_for_collection( $response );
172
+ }
173
+
174
+ return rest_ensure_response( $data );
175
+ }
176
+
177
+ /**
178
+ * Prepare a response for inserting into a collection of responses.
179
+ *
180
+ * @param \WP_REST_Response $response Response object.
181
+ * @return array|\WP_REST_Response Response data, ready for insertion into collection data.
182
+ */
183
+ public function prepare_for_collection( $response ) {
184
+ if ( ! ( $response instanceof \WP_REST_Response ) ) {
185
+ return $response;
186
+ }
187
+
188
+ $data = (array) $response->get_data();
189
+ $server = rest_get_server();
190
+
191
+ if ( method_exists( $server, 'get_compact_response_links' ) ) {
192
+ $links = call_user_func( [ $server, 'get_compact_response_links' ], $response );
193
+ } else {
194
+ $links = call_user_func( [ $server, 'get_response_links' ], $response );
195
+ }
196
+
197
+ if ( ! empty( $links ) ) {
198
+ $data['_links'] = $links;
199
+ }
200
+
201
+ return $data;
202
+ }
203
+
204
+ /**
205
+ * Prepares a single attachment output for response.
206
+ *
207
+ * @param \WP_Post $post Attachment object.
208
+ * @param \WP_REST_Request $request Request object.
209
+ * @return \WP_REST_Response Response object.
210
+ */
211
+ public function prepare_item_for_response( $post, $request ) {
212
+ $response = parent::prepare_item_for_response( $post, $request );
213
+ $base = 'wp/v2/media';
214
+
215
+ foreach ( [ 'self', 'collection', 'about' ] as $link ) {
216
+ $response->remove_link( $link );
217
+
218
+ }
219
+
220
+ $response->add_link( 'self', rest_url( trailingslashit( $base ) . $post->ID ) );
221
+ $response->add_link( 'collection', rest_url( $base ) );
222
+ $response->add_link( 'about', rest_url( 'wp/v2/types/' . $post->post_type ) );
223
+
224
+ return $response;
225
+ }
226
+
227
+ /**
228
+ * Gets the attachment if an image has been sideloaded previously.
229
+ *
230
+ * @param string $url URL of the image to sideload.
231
+ * @return object|bool Attachment object on success, false on failure.
232
+ */
233
+ public function get_attachment( $url ) {
234
+ $cache_key = 'fse_sideloaded_image_' . hash( 'crc32b', $url );
235
+ $attachment = get_transient( $cache_key );
236
+
237
+ if ( false === $attachment ) {
238
+ $attachments = new \WP_Query(
239
+ [
240
+ 'no_found_rows' => true,
241
+ 'posts_per_page' => 1,
242
+ 'post_status' => 'inherit',
243
+ 'post_type' => 'attachment',
244
+ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
245
+ 'meta_query' => [
246
+ [
247
+ 'key' => '_sideloaded_url',
248
+ 'value' => $url,
249
+ ],
250
+ ],
251
+ ]
252
+ );
253
+
254
+ if ( $attachments->have_posts() ) {
255
+ set_transient( $cache_key, $attachments->post );
256
+ }
257
+ }
258
+
259
+ return $attachment;
260
+ }
261
+
262
+ /**
263
+ * Returns the endpoints request parameters.
264
+ *
265
+ * @return array Request parameters.
266
+ */
267
+ public function get_collection_params() {
268
+ return [
269
+ 'url' => [
270
+ 'description' => 'URL to the image to be side-loaded.',
271
+ 'type' => 'string',
272
+ 'required' => true,
273
+ 'format' => 'uri',
274
+ 'sanitize_callback' => function( $url ) {
275
+ return esc_url_raw( strtok( $url, '?' ) );
276
+ },
277
+ ],
278
+ 'post_id' => [
279
+ 'description' => 'ID of the post to associate the image with',
280
+ 'type' => 'integer',
281
+ 'default' => 0,
282
+ ],
283
+ ];
284
+ }
285
+
286
+ /**
287
+ * Returns the route to sideload a single image.
288
+ *
289
+ * @return string
290
+ */
291
+ public function get_item_route() {
292
+ return "/{$this->namespace}/{$this->rest_base}";
293
+ }
294
+ }
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){!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,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 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})}})}]));
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=21)}([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})}})}]));
starter-page-templates/page-template-modal/components/block-template-preview.js ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+
5
+ /**
6
+ * Internal dependencies
7
+ */
8
+
9
+ /**
10
+ * WordPress dependencies
11
+ */
12
+ import { BlockPreview } from '@wordpress/block-editor';
13
+
14
+ const BlockTemplatePreview = ( { blocks, viewportWidth } ) => {
15
+ if ( ! blocks || ! blocks.length ) {
16
+ return null;
17
+ }
18
+
19
+ return (
20
+ /* eslint-disable wpcalypso/jsx-classname-namespace */
21
+ <div className="edit-post-visual-editor">
22
+ <div className="editor-styles-wrapper">
23
+ <div className="editor-writing-flow">
24
+ { blocks && <BlockPreview blocks={ blocks } viewportWidth={ viewportWidth } /> }
25
+ </div>
26
+ </div>
27
+ </div>
28
+ /* eslint-enable wpcalypso/jsx-classname-namespace */
29
+ );
30
+ };
31
+
32
+ export default BlockTemplatePreview;
starter-page-templates/page-template-modal/components/preview-template-title.js ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Return a component which acts as a PostTitle,
3
+ * applying the css classes needed to follow the styles
4
+ * inherited from the Editor.
5
+ *
6
+ * @param {string} title Template title - transform css rule.
7
+ * @return {*} Component
8
+ */
9
+
10
+ const PreviewTemplateTitle = ( { title, transform } ) => (
11
+ /* eslint-disable wpcalypso/jsx-classname-namespace */
12
+ <div className="editor-post-title" style={ { transform } }>
13
+ <div className="editor-post-title__block">
14
+ <textarea className="editor-post-title__input" value={ title } />
15
+ </div>
16
+ </div>
17
+ /* eslint-enable wpcalypso/jsx-classname-namespace */
18
+ );
19
+
20
+ export default PreviewTemplateTitle;
starter-page-templates/page-template-modal/components/template-selector-item.js ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+
5
+ /**
6
+ * Internal dependencies
7
+ */
8
+
9
+ /**
10
+ * WordPress dependencies
11
+ */
12
+ import BlockPreview from './block-template-preview';
13
+ import { Disabled } from '@wordpress/components';
14
+
15
+ const TemplateSelectorItem = props => {
16
+ const {
17
+ id,
18
+ value,
19
+ help,
20
+ onFocus,
21
+ onSelect,
22
+ label,
23
+ useDynamicPreview = false,
24
+ staticPreviewImg,
25
+ staticPreviewImgAlt = '',
26
+ blocks = [],
27
+ } = props;
28
+
29
+ // Define static or dynamic preview.
30
+ const innerPreview = useDynamicPreview ? (
31
+ <Disabled>
32
+ <BlockPreview blocks={ blocks } viewportWidth={ 960 } />
33
+ </Disabled>
34
+ ) : (
35
+ <img
36
+ className="template-selector-item__media"
37
+ src={ staticPreviewImg }
38
+ alt={ staticPreviewImgAlt }
39
+ />
40
+ );
41
+
42
+ return (
43
+ <button
44
+ type="button"
45
+ id={ `${ id }-${ value }` }
46
+ className="template-selector-item__label"
47
+ value={ value }
48
+ onMouseEnter={ () => onFocus( value, label ) }
49
+ onClick={ () => onSelect( value, label ) }
50
+ aria-describedby={ help ? `${ id }__help` : undefined }
51
+ >
52
+ <div className="template-selector-item__preview-wrap">{ innerPreview }</div>
53
+ { label }
54
+ </button>
55
+ );
56
+ };
57
+
58
+ export default TemplateSelectorItem;
starter-page-templates/page-template-modal/components/template-selector-preview.js ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import classnames from 'classnames';
5
+ import { isEmpty, debounce } from 'lodash';
6
+
7
+ /**
8
+ * WordPress dependencies
9
+ */
10
+ import { __ } from '@wordpress/i18n';
11
+ import { BlockPreview } from '@wordpress/block-editor';
12
+ import { Disabled } from '@wordpress/components';
13
+ import { useState, useEffect, useLayoutEffect, useRef, useReducer } from '@wordpress/element';
14
+
15
+ /**
16
+ * Internal dependencies
17
+ */
18
+ import PreviewTemplateTitle from './preview-template-title';
19
+
20
+ const TemplateSelectorPreview = ( { blocks, viewportWidth, title } ) => {
21
+ const THRESHOLD_RESIZE = 300;
22
+
23
+ const previewElClasses = classnames( 'template-selector-preview', 'editor-styles-wrapper' );
24
+ const [ transform, setTransform ] = useState( 'none' );
25
+ const [ visibility, setVisibility ] = useState( 'hidden' );
26
+ const ref = useRef( null );
27
+
28
+ const [ recompute, triggerRecompute ] = useReducer( state => state + 1, 0 );
29
+
30
+ // TODO: we should remove this approach and use the onReady callback.
31
+ // There is Gutenberg PR which adds the onReady callback
32
+ // as a component property.
33
+ // The following approach can be easily replace calling this callback
34
+ // once the PR ships (finger-crossed)
35
+ // https://github.com/WordPress/gutenberg/pull/17242
36
+
37
+ const updateTemplateTitle = () => {
38
+ // Get DOM reference.
39
+ setTimeout( () => {
40
+ if ( ! ref || ! ref.current ) {
41
+ return;
42
+ }
43
+
44
+ // Try to get the preview content element.
45
+ const previewContainerEl = ref.current.querySelector( '.block-editor-block-preview__content' );
46
+ if ( ! previewContainerEl ) {
47
+ return;
48
+ }
49
+
50
+ // Try to get the `transform` css rule from the preview container element.
51
+ const elStyles = window.getComputedStyle( previewContainerEl );
52
+ if ( elStyles && elStyles.transform ) {
53
+ setTransform( elStyles.transform ); // apply the same transform css rule to template title.
54
+ }
55
+
56
+ setVisibility( 'visible' );
57
+ }, 300 );
58
+ };
59
+
60
+ useLayoutEffect( () => {
61
+ setVisibility( 'hidden' );
62
+ updateTemplateTitle();
63
+ }, [ blocks ] );
64
+
65
+ useEffect( () => {
66
+ if ( ! blocks.length ) {
67
+ return;
68
+ }
69
+
70
+ const rePreviewTemplate = () => {
71
+ updateTemplateTitle();
72
+ triggerRecompute();
73
+ };
74
+
75
+ const refreshPreview = debounce( rePreviewTemplate, THRESHOLD_RESIZE );
76
+ window.addEventListener( 'resize', refreshPreview );
77
+
78
+ return () => {
79
+ window.removeEventListener( 'resize', refreshPreview );
80
+ };
81
+ }, [ blocks ] );
82
+
83
+ if ( isEmpty( blocks ) ) {
84
+ return (
85
+ <div className={ previewElClasses }>
86
+ <div className="template-selector-preview__placeholder">
87
+ { __( 'Select a page template to preview.', 'full-site-editing' ) }
88
+ </div>
89
+ </div>
90
+ );
91
+ }
92
+
93
+ return (
94
+ /* eslint-disable wpcalypso/jsx-classname-namespace */
95
+ <div className={ previewElClasses }>
96
+ <Disabled>
97
+ <div ref={ ref } className="edit-post-visual-editor">
98
+ <div className="editor-styles-wrapper" style={ { visibility } }>
99
+ <div className="editor-writing-flow">
100
+ <PreviewTemplateTitle title={ title } transform={ transform } />
101
+ <BlockPreview key={ recompute } blocks={ blocks } viewportWidth={ viewportWidth } />
102
+ </div>
103
+ </div>
104
+ </div>
105
+ </Disabled>
106
+ </div>
107
+ /* eslint-enable wpcalypso/jsx-classname-namespace */
108
+ );
109
+ };
110
+
111
+ export default TemplateSelectorPreview;
starter-page-templates/page-template-modal/utils/ensure-assets.js ADDED
@@ -0,0 +1,213 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { reduce, isEmpty, forEach, set, map } from 'lodash';
5
+
6
+ /**
7
+ * WordPress dependencies
8
+ */
9
+ import apiFetch from '@wordpress/api-fetch';
10
+ import { removeQueryArgs } from '@wordpress/url';
11
+
12
+ /**
13
+ * A full asset URL.
14
+ * @typedef {String} URL
15
+ */
16
+
17
+ /**
18
+ * Gutenberg Block.
19
+ * @typedef {Object} GutenbergBlock
20
+ * @property {String} clientId A unique id of the block.
21
+ * @property {String} name A block name, like "core/paragraph".
22
+ * @property {Array<GutenbergBlock>} innerBlocks Nested blocks.
23
+ * @property {Object} attributes An object with attributes, different for each block type.
24
+ */
25
+
26
+ /**
27
+ * Usage object contains an info that certain property is used inside another object.
28
+ * @typedef {Object} Usage
29
+ * @property {String} prop Name of the property.
30
+ * @property {Array<String|Number>} path A path inside an object where prop is, defined as list of keys.
31
+ */
32
+
33
+ /**
34
+ * An asset file that is referenced in blocks.
35
+ * @typedef {Object} Asset
36
+ * @property {URL} url A full URL of the asset.
37
+ * @property {Array<Usage>} usages A list of {@link Usage} objects.
38
+ */
39
+
40
+ /**
41
+ * A collection of {@link Asset} objects, keyed by their URLs.
42
+ * @typedef {Object.<String, Asset>} Assets URLs as keys, {@link Asset}.as a values.
43
+ */
44
+
45
+ /**
46
+ * FetchSession describes a set of blocks and their assets.
47
+ * @typedef {Object} FetchSession
48
+ * @property {Array<GutenbergBlock>} blocks List of Gutenberg blocks.
49
+ * @property {Object<String, GutenbergBlock>} blocksByClientId Blocks, keyed by their `clientId`
50
+ * @property {Assets} assets A list of assets detected in blocks.
51
+ */
52
+
53
+ /**
54
+ * Extends an {@link Assets} object with a new asset and updates its usages.
55
+ *
56
+ * @param {Assets} assets Object containing assets.
57
+ * @param {URL} url A full URL of the asset.
58
+ * @param {Array<Usage>} usages A list of {@link Usage} objects.
59
+ * @returns {Assets} assets object with the new {@link Asset} included
60
+ */
61
+ const addAssetToLoad = ( assets, url, usages ) => {
62
+ // Remove resizing query arguments from the URL.
63
+ url = removeQueryArgs( url, 'w', 's' );
64
+
65
+ // Use an existing asset for the URL or make a new one.
66
+ const asset = assets[ url ] || {
67
+ url,
68
+ usages: [],
69
+ };
70
+
71
+ // Return new result object, extended with the new/updated asset.
72
+ return {
73
+ ...assets,
74
+ [ url ]: {
75
+ ...asset,
76
+ // Store where exactly block uses id/url so we can update it later.
77
+ usages: [ ...asset.usages, ...usages ],
78
+ },
79
+ };
80
+ };
81
+
82
+ /**
83
+ * This function is used as a reducer iteratee. It checks if the block
84
+ * contains any image and if so, enqueues it to be downloaded later.
85
+ *
86
+ * @param {FetchSession} session Session object.
87
+ * @param {GutenbergBlock} block Gutenberg Block object.
88
+ * @returns {FetchSession} Updated session object
89
+ */
90
+ const findAssetsInBlock = ( session, block ) => {
91
+ // Save a reference for the block so we can later easily
92
+ // find it without any loops and recursion.
93
+ session.blocksByClientId[ block.clientId ] = block;
94
+
95
+ // Identify assets in blocks where we expect them.
96
+ switch ( block.name ) {
97
+ // Both of these blocks use same attribute names for image id and url
98
+ // and thus we can share the implementation.
99
+ case 'core/cover':
100
+ case 'core/image': {
101
+ const url = block.attributes.url;
102
+ if ( url ) {
103
+ session.assets = addAssetToLoad( session.assets, url, [
104
+ { prop: 'url', path: [ block.clientId, 'attributes', 'url' ] },
105
+ { prop: 'id', path: [ block.clientId, 'attributes', 'id' ] },
106
+ ] );
107
+ }
108
+ }
109
+ case 'core/media-text': {
110
+ const url = block.attributes.mediaUrl;
111
+ if ( url && block.attributes.mediaType === 'image' ) {
112
+ session.assets = addAssetToLoad( session.assets, url, [
113
+ { prop: 'url', path: [ block.clientId, 'attributes', 'mediaUrl' ] },
114
+ { prop: 'id', path: [ block.clientId, 'attributes', 'mediaId' ] },
115
+ ] );
116
+ }
117
+ }
118
+ case 'core/gallery': {
119
+ forEach( block.attributes.images, ( image, i ) => {
120
+ session.assets = addAssetToLoad( session.assets, image.url, [
121
+ { prop: 'url', path: [ block.clientId, 'attributes', 'images', i, 'url' ] },
122
+ { prop: 'url', path: [ block.clientId, 'attributes', 'images', i, 'link' ] },
123
+ { prop: 'id', path: [ block.clientId, 'attributes', 'images', i, 'id' ] },
124
+ { prop: 'id', path: [ block.clientId, 'attributes', 'ids', i ] },
125
+ ] );
126
+ } );
127
+ }
128
+ }
129
+
130
+ // Recursively process all inner blocks.
131
+ if ( ! isEmpty( block.innerBlocks ) ) {
132
+ return reduce( block.innerBlocks, findAssetsInBlock, session );
133
+ }
134
+
135
+ return session;
136
+ };
137
+
138
+ /**
139
+ * Calls an API that fetches assets and saves the result into the DetectedAssets object.
140
+ *
141
+ * @param {Assets} assets Assets that were detected from blocks.
142
+ * @returns {Promise} Promise that resoves into an object with URLs as keys and fetch results as values.
143
+ */
144
+ const fetchAssets = async assets => {
145
+ return await apiFetch( {
146
+ method: 'POST',
147
+ path: '/fse/v1/sideload/image/batch',
148
+ data: { resources: map( assets ) },
149
+ } ).then( response =>
150
+ reduce(
151
+ assets,
152
+ ( fetched, asset ) => {
153
+ const { id, source_url } = response.shift();
154
+ return {
155
+ ...fetched,
156
+ [ asset.url ]: { id, url: source_url },
157
+ };
158
+ },
159
+ {}
160
+ )
161
+ );
162
+ };
163
+
164
+ /**
165
+ * Takes fetched assets and makes sure all their usages will be changed into
166
+ * their new local copies.
167
+ *
168
+ * @param {FetchSession} session A current session.
169
+ * @param {Object<String,Object>} fetchedAssets Fetched assets.
170
+ * @returns {Array<GutenbergBlock>} A promise resolving into an array of blocks.
171
+ */
172
+ const getBlocksWithAppliedAssets = ( session, fetchedAssets ) => {
173
+ forEach( session.assets, asset => {
174
+ const newAsset = fetchedAssets[ asset.url ];
175
+ if ( ! newAsset ) {
176
+ return;
177
+ }
178
+ forEach( asset.usages, usage => {
179
+ set( session.blocksByClientId, usage.path, newAsset[ usage.prop ] );
180
+ } );
181
+ } );
182
+
183
+ return session.blocks;
184
+ };
185
+
186
+ /**
187
+ * Analyzes blocks and if they use any external assets, ensures they are
188
+ * copied into a local site and are used in blocks instead of the remote ones.
189
+ *
190
+ * @param {Array<GutenbergBlock>} blocks Blocks, as returned by `wp.block.parse`
191
+ * @returns {Promise} A promise that resolves into an array of {@link GutenbergBlock} with updated assets
192
+ */
193
+ const ensureAssetsInBlocks = async blocks => {
194
+ // Create a FetchSession object by reducing blocks.
195
+ const session = reduce( blocks, findAssetsInBlock, {
196
+ assets: {},
197
+ blocksByClientId: {},
198
+ blocks,
199
+ } );
200
+
201
+ // No assets found. Proceed with insertion right away.
202
+ if ( isEmpty( session.assets ) ) {
203
+ return blocks;
204
+ }
205
+
206
+ // Ensure assets are available on the site and replace originals
207
+ // with local copies before inserting the template.
208
+ return fetchAssets( session.assets ).then( fetchedAssets => {
209
+ return getBlocksWithAppliedAssets( session, fetchedAssets );
210
+ } );
211
+ };
212
+
213
+ export default ensureAssetsInBlocks;