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.