From 327852393a5c65610b800080de77fcb33af34c40 Mon Sep 17 00:00:00 2001 From: gziolo Date: Wed, 28 Jul 2021 10:06:59 +0000 Subject: [PATCH] Build: Split packages and blocks to their webpack configs It aligns with the changes proposed added in Gutenberg: https://github.com/WordPress/gutenberg/pull/33293. The idea here is to split the growing webpack config into two parts: blocks and packages. We need to add handling for JavaScript files that are going to be used with blocks on the frontend. They didn't work quite well with the current setup for entry points created for packages. As part of the effort, it adds support for `viewScript` in `block.json` metadata file that is later translated to `$view_script` in `WP_Block_Type` class and exposed as `view_script` from the REST API endpoint for block types. Props youknowriad, desrosj, aristath. Fixes #53690. Built from https://develop.svn.wordpress.org/trunk@51501 git-svn-id: http://core.svn.wordpress.org/trunk@51112 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/blocks.php | 29 ++- wp-includes/blocks/file/view.asset.php | 1 + wp-includes/blocks/file/view.js | 170 ++++++++++++++++++ wp-includes/blocks/file/view.min.asset.php | 1 + wp-includes/blocks/file/view.min.js | 1 + wp-includes/class-wp-block-type.php | 26 ++- wp-includes/class-wp-block.php | 4 + .../class-wp-rest-block-types-controller.php | 10 +- wp-includes/version.php | 2 +- 9 files changed, 228 insertions(+), 16 deletions(-) create mode 100644 wp-includes/blocks/file/view.asset.php create mode 100644 wp-includes/blocks/file/view.js create mode 100644 wp-includes/blocks/file/view.min.asset.php create mode 100644 wp-includes/blocks/file/view.min.js diff --git a/wp-includes/blocks.php b/wp-includes/blocks.php index bfd36b41c0..96b897aeec 100644 --- a/wp-includes/blocks.php +++ b/wp-includes/blocks.php @@ -42,12 +42,16 @@ function generate_block_asset_handle( $block_name, $field_name ) { if ( 0 === strpos( $field_name, 'editor' ) ) { $asset_handle .= '-editor'; } + if ( 0 === strpos( $field_name, 'view' ) ) { + $asset_handle .= '-view'; + } return $asset_handle; } $field_mappings = array( 'editorScript' => 'editor-script', 'script' => 'script', + 'viewScript' => 'view-script', 'editorStyle' => 'editor-style', 'style' => 'style', ); @@ -96,18 +100,23 @@ function register_block_script_handle( $metadata, $field_name ) { ); return false; } - $script_asset = require $script_asset_path; - $result = wp_register_script( + $is_core_block = isset( $metadata['file'] ) && 0 === strpos( $metadata['file'], ABSPATH . WPINC ); + $script_uri = $is_core_block ? + includes_url( str_replace( ABSPATH . WPINC, '', realpath( dirname( $metadata['file'] ) . '/' . $script_path ) ) ) : + plugins_url( $script_path, $metadata['file'] ); + $script_asset = require $script_asset_path; + $script_dependencies = isset( $script_asset['dependencies'] ) ? $script_asset['dependencies'] : array(); + $result = wp_register_script( $script_handle, - plugins_url( $script_path, $metadata['file'] ), - $script_asset['dependencies'], - $script_asset['version'] + $script_uri, + $script_dependencies, + isset( $script_asset['version'] ) ? $script_asset['version'] : false ); if ( ! $result ) { return false; } - if ( ! empty( $metadata['textdomain'] ) ) { + if ( ! empty( $metadata['textdomain'] ) && in_array( 'wp-i18n', $script_dependencies ) ) { wp_set_script_translations( $script_handle, $metadata['textdomain'] ); } @@ -182,6 +191,7 @@ function register_block_style_handle( $metadata, $field_name ) { * Registers a block type from the metadata stored in the `block.json` file. * * @since 5.5.0 + * @since 5.9.0 Added support for the `viewScript` field. * * @param string $file_or_folder Path to the JSON file with metadata definition for * the block or path to the folder where the `block.json` file is located. @@ -304,6 +314,13 @@ function register_block_type_from_metadata( $file_or_folder, $args = array() ) { ); } + if ( ! empty( $metadata['viewScript'] ) ) { + $settings['view_script'] = register_block_script_handle( + $metadata, + 'viewScript' + ); + } + if ( ! empty( $metadata['editorStyle'] ) ) { $settings['editor_style'] = register_block_style_handle( $metadata, diff --git a/wp-includes/blocks/file/view.asset.php b/wp-includes/blocks/file/view.asset.php new file mode 100644 index 0000000000..d3fd92c19d --- /dev/null +++ b/wp-includes/blocks/file/view.asset.php @@ -0,0 +1 @@ + array('wp-polyfill'), 'version' => '650904f3ca9fdeab18131aab66cea896'); \ No newline at end of file diff --git a/wp-includes/blocks/file/view.js b/wp-includes/blocks/file/view.js new file mode 100644 index 0000000000..479d33238e --- /dev/null +++ b/wp-includes/blocks/file/view.js @@ -0,0 +1,170 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); +/******/ } +/******/ }; +/******/ +/******/ // define __esModule on exports +/******/ __webpack_require__.r = function(exports) { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ +/******/ // create a fake namespace object +/******/ // mode & 1: value is a module id, require it +/******/ // mode & 2: merge all properties of value into the ns +/******/ // mode & 4: return value when already ns object +/******/ // mode & 8|1: behave like require +/******/ __webpack_require__.t = function(value, mode) { +/******/ if(mode & 1) value = __webpack_require__(value); +/******/ if(mode & 8) return value; +/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; +/******/ var ns = Object.create(null); +/******/ __webpack_require__.r(ns); +/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); +/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); +/******/ return ns; +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = "DP2F"); +/******/ }) +/************************************************************************/ +/******/ ({ + +/***/ "DP2F": +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +// ESM COMPAT FLAG +__webpack_require__.r(__webpack_exports__); + +// CONCATENATED MODULE: ./node_modules/@wordpress/block-library/build-module/file/utils.js +/** + * Uses a combination of user agent matching and feature detection to determine whether + * the current browser supports rendering PDFs inline. + * + * @return {boolean} Whether or not the browser supports inline PDFs. + */ +const browserSupportsPdfs = () => { + // Most mobile devices include "Mobi" in their UA. + if (window.navigator.userAgent.indexOf('Mobi') > -1) { + return false; + } // Android tablets are the noteable exception. + + + if (window.navigator.userAgent.indexOf('Android') > -1) { + return false; + } // iPad pretends to be a Mac. + + + if (window.navigator.userAgent.indexOf('Macintosh') > -1 && window.navigator.maxTouchPoints && window.navigator.maxTouchPoints > 2) { + return false; + } // IE only supports PDFs when there's an ActiveX object available for it. + + + if (!!(window.ActiveXObject || 'ActiveXObject' in window) && !(createActiveXObject('AcroPDF.PDF') || createActiveXObject('PDF.PdfCtrl'))) { + return false; + } + + return true; +}; +/** + * Helper function for creating ActiveX objects, catching any errors that are thrown + * when it's generated. + * + * @param {string} type The name of the ActiveX object to create. + * @return {window.ActiveXObject|undefined} The generated ActiveXObject, or null if it failed. + */ + +const createActiveXObject = type => { + let ax; + + try { + ax = new window.ActiveXObject(type); + } catch (e) { + ax = undefined; + } + + return ax; +}; +/** + * Hides all .wp-block-file__embed elements on the document. This function is only intended + * to be run on the front-end, it may have weird side effects running in the block editor. + */ + + +const hidePdfEmbedsOnUnsupportedBrowsers = () => { + if (!browserSupportsPdfs()) { + const embeds = document.getElementsByClassName('wp-block-file__embed'); + Array.from(embeds).forEach(embed => { + embed.style.display = 'none'; + }); + } +}; + +// CONCATENATED MODULE: ./node_modules/@wordpress/block-library/build-module/file/view.js +/** + * Internal dependencies + */ + +hidePdfEmbedsOnUnsupportedBrowsers(); + + +/***/ }) + +/******/ }); \ No newline at end of file diff --git a/wp-includes/blocks/file/view.min.asset.php b/wp-includes/blocks/file/view.min.asset.php new file mode 100644 index 0000000000..fb44b982ae --- /dev/null +++ b/wp-includes/blocks/file/view.min.asset.php @@ -0,0 +1 @@ + array('wp-polyfill'), 'version' => 'e8d668b8e69d9bf1c99dc250d92f2b72'); \ No newline at end of file diff --git a/wp-includes/blocks/file/view.min.js b/wp-includes/blocks/file/view.min.js new file mode 100644 index 0000000000..9d268a8bd8 --- /dev/null +++ b/wp-includes/blocks/file/view.min.js @@ -0,0 +1 @@ +!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s="DP2F")}({DP2F:function(e,t,n){"use strict";n.r(t);const r=e=>{let t;try{t=new window.ActiveXObject(e)}catch(e){t=void 0}return t};(()=>{if(window.navigator.userAgent.indexOf("Mobi")>-1||window.navigator.userAgent.indexOf("Android")>-1||window.navigator.userAgent.indexOf("Macintosh")>-1&&window.navigator.maxTouchPoints&&window.navigator.maxTouchPoints>2||(window.ActiveXObject||"ActiveXObject"in window)&&!r("AcroPDF.PDF")&&!r("PDF.PdfCtrl")){const e=document.getElementsByClassName("wp-block-file__embed");Array.from(e).forEach(e=>{e.style.display="none"})}})()}}); \ No newline at end of file diff --git a/wp-includes/class-wp-block-type.php b/wp-includes/class-wp-block-type.php index 84e956ec9a..10dbe42428 100644 --- a/wp-includes/class-wp-block-type.php +++ b/wp-includes/class-wp-block-type.php @@ -156,7 +156,7 @@ class WP_Block_Type { public $provides_context = null; /** - * Block type editor script handle. + * Block type editor only script handle. * * @since 5.0.0 * @var string|null @@ -164,7 +164,7 @@ class WP_Block_Type { public $editor_script = null; /** - * Block type front end script handle. + * Block type front end and editor script handle. * * @since 5.0.0 * @var string|null @@ -172,7 +172,15 @@ class WP_Block_Type { public $script = null; /** - * Block type editor style handle. + * Block type front end only script handle. + * + * @since 5.9.0 + * @var string|null + */ + public $view_script = null; + + /** + * Block type editor only style handle. * * @since 5.0.0 * @var string|null @@ -180,7 +188,7 @@ class WP_Block_Type { public $editor_style = null; /** - * Block type front end style handle. + * Block type front end and editor style handle. * * @since 5.0.0 * @var string|null @@ -198,6 +206,7 @@ class WP_Block_Type { * `uses_context`, and `provides_context` properties. * @since 5.6.0 Added the `api_version` property. * @since 5.8.0 Added the `variations` property. + * @since 5.9.0 Added the `view_script` property. * * @see register_block_type() * @@ -225,10 +234,11 @@ class WP_Block_Type { * @type array|null $attributes Block type attributes property schemas. * @type array $uses_context Context values inherited by blocks of this type. * @type array|null $provides_context Context provided by blocks of this type. - * @type string|null $editor_script Block type editor script handle. - * @type string|null $script Block type front end script handle. - * @type string|null $editor_style Block type editor style handle. - * @type string|null $style Block type front end style handle. + * @type string|null $editor_script Block type editor only script handle. + * @type string|null $script Block type front end and editor script handle. + * @type string|null $view_script Block type front end only script handle. + * @type string|null $editor_style Block type editor only style handle. + * @type string|null $style Block type front end and editor style handle. * } */ public function __construct( $block_type, $args = array() ) { diff --git a/wp-includes/class-wp-block.php b/wp-includes/class-wp-block.php index 93f6642440..a8ae6747c4 100644 --- a/wp-includes/class-wp-block.php +++ b/wp-includes/class-wp-block.php @@ -229,6 +229,10 @@ class WP_Block { wp_enqueue_script( $this->block_type->script ); } + if ( ! empty( $this->block_type->view_script ) && empty( $this->block_type->render_callback ) ) { + wp_enqueue_script( $this->block_type->view_script ); + } + if ( ! empty( $this->block_type->style ) ) { wp_enqueue_style( $this->block_type->style ); } diff --git a/wp-includes/rest-api/endpoints/class-wp-rest-block-types-controller.php b/wp-includes/rest-api/endpoints/class-wp-rest-block-types-controller.php index 3d8672325f..4a1c07764b 100644 --- a/wp-includes/rest-api/endpoints/class-wp-rest-block-types-controller.php +++ b/wp-includes/rest-api/endpoints/class-wp-rest-block-types-controller.php @@ -272,6 +272,7 @@ class WP_REST_Block_Types_Controller extends WP_REST_Controller { 'example', 'editor_script', 'script', + 'view_script', 'editor_style', 'style', 'variations', @@ -517,6 +518,13 @@ class WP_REST_Block_Types_Controller extends WP_REST_Controller { 'readonly' => true, ), 'script' => array( + 'description' => __( 'Public facing and editor script handle.' ), + 'type' => array( 'string', 'null' ), + 'default' => null, + 'context' => array( 'embed', 'view', 'edit' ), + 'readonly' => true, + ), + 'view_script' => array( 'description' => __( 'Public facing script handle.' ), 'type' => array( 'string', 'null' ), 'default' => null, @@ -531,7 +539,7 @@ class WP_REST_Block_Types_Controller extends WP_REST_Controller { 'readonly' => true, ), 'style' => array( - 'description' => __( 'Public facing style handle.' ), + 'description' => __( 'Public facing and editor style handle.' ), 'type' => array( 'string', 'null' ), 'default' => null, 'context' => array( 'embed', 'view', 'edit' ), diff --git a/wp-includes/version.php b/wp-includes/version.php index 5d6fbb1766..5c30ac7cae 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -13,7 +13,7 @@ * * @global string $wp_version */ -$wp_version = '5.9-alpha-51500'; +$wp_version = '5.9-alpha-51501'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.