Skip to content

Commit

Permalink
Merge branch 'trunk' of https://github.com/WordPress/gutenberg into f…
Browse files Browse the repository at this point in the history
…eat/tablist-sizing-and-overflow-improvements
  • Loading branch information
DaniGuardiola committed Sep 28, 2024
2 parents 9aa1d71 + 88d60e4 commit e73f1d5
Show file tree
Hide file tree
Showing 71 changed files with 2,982 additions and 3,119 deletions.
30 changes: 3 additions & 27 deletions docs/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -1098,33 +1098,9 @@
"parent": "components"
},
{
"title": "NavigatorBackButton",
"slug": "navigator-back-button",
"markdown_source": "../packages/components/src/navigator/navigator-back-button/README.md",
"parent": "components"
},
{
"title": "NavigatorButton",
"slug": "navigator-button",
"markdown_source": "../packages/components/src/navigator/navigator-button/README.md",
"parent": "components"
},
{
"title": "NavigatorProvider",
"slug": "navigator-provider",
"markdown_source": "../packages/components/src/navigator/navigator-provider/README.md",
"parent": "components"
},
{
"title": "NavigatorScreen",
"slug": "navigator-screen",
"markdown_source": "../packages/components/src/navigator/navigator-screen/README.md",
"parent": "components"
},
{
"title": "NavigatorToParentButton",
"slug": "navigator-to-parent-button",
"markdown_source": "../packages/components/src/navigator/navigator-to-parent-button/README.md",
"title": "Navigator",
"slug": "navigator",
"markdown_source": "../packages/components/src/navigator/README.md",
"parent": "components"
},
{
Expand Down
31 changes: 22 additions & 9 deletions lib/experimental/media/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,24 @@ function gutenberg_rest_get_attachment_filesize( array $post ): ?int {
return null;
}

/**
* Filters the list of rewrite rules formatted for output to an .htaccess file.
*
* Adds support for serving wasm-vips locally.
*
* @param string $rules mod_rewrite Rewrite rules formatted for .htaccess.
* @return string Filtered rewrite rules.
*/
function gutenberg_filter_mod_rewrite_rules( string $rules ): string {
$rules .= "\n# BEGIN Gutenberg client-side media processing experiment\n" .
"AddType application/wasm wasm\n" .
"# END Gutenberg client-side media processing experiment\n";

return $rules;
}

add_filter( 'mod_rewrite_rules', 'gutenberg_filter_mod_rewrite_rules' );

/**
* Enables cross-origin isolation in the block editor.
*
Expand Down Expand Up @@ -236,16 +254,11 @@ function gutenberg_start_cross_origin_isolation_output_buffer(): void {
$coep = $is_safari ? 'require-corp' : 'credentialless';

ob_start(
function ( string $output, ?int $phase ) use ( $coep ): string {
// Only send the header when the buffer is not being cleaned.
if ( ( $phase & PHP_OUTPUT_HANDLER_CLEAN ) === 0 ) {
header( 'Cross-Origin-Opener-Policy: same-origin' );
header( "Cross-Origin-Embedder-Policy: $coep" );

$output = gutenberg_add_crossorigin_attributes( $output );
}
function ( string $output ) use ( $coep ): string {
header( 'Cross-Origin-Opener-Policy: same-origin' );
header( "Cross-Origin-Embedder-Policy: $coep" );

return $output;
return gutenberg_add_crossorigin_attributes( $output );
}
);
}
Expand Down
58 changes: 47 additions & 11 deletions packages/block-editor/src/components/block-list/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
getBlockDefaultClassName,
hasBlockSupport,
store as blocksStore,
privateApis as blocksPrivateApis,
} from '@wordpress/blocks';
import { withFilters } from '@wordpress/components';
import { withDispatch, useDispatch, useSelect } from '@wordpress/data';
Expand All @@ -46,6 +47,8 @@ import { PrivateBlockContext } from './private-block-context';

import { unlock } from '../../lock-unlock';

const { isUnmodifiedBlockContent } = unlock( blocksPrivateApis );

/**
* Merges wrapper props with special handling for classNames and styles.
*
Expand Down Expand Up @@ -350,34 +353,66 @@ const applyWithDispatch = withDispatch( ( dispatch, ownProps, registry ) => {
removeBlock( _clientId );
} else {
registry.batch( () => {
const firstBlock = getBlock( firstClientId );
const isFirstBlockContentUnmodified =
isUnmodifiedBlockContent( firstBlock );
const defaultBlockName = getDefaultBlockName();
const replacement = switchToBlockType(
firstBlock,
defaultBlockName
);
const canTransformToDefaultBlock =
!! replacement?.length &&
replacement.every( ( block ) =>
canInsertBlockType( block.name, _clientId )
);

if (
isFirstBlockContentUnmodified &&
canTransformToDefaultBlock
) {
// Step 1: If the block is empty and can be transformed to the default block type.
replaceBlocks(
firstClientId,
replacement,
changeSelection
);
} else if (
isFirstBlockContentUnmodified &&
firstBlock.name === defaultBlockName
) {
// Step 2: If the block is empty and is already the default block type.
removeBlock( firstClientId );
const nextBlockClientId =
getNextBlockClientId( clientId );
if ( nextBlockClientId ) {
selectBlock( nextBlockClientId );
}
} else if (
canInsertBlockType(
getBlockName( firstClientId ),
firstBlock.name,
targetRootClientId
)
) {
// Step 3: If the block can be moved up.
moveBlocksToPosition(
[ firstClientId ],
_clientId,
targetRootClientId,
getBlockIndex( _clientId )
);
} else {
const replacement = switchToBlockType(
getBlock( firstClientId ),
getDefaultBlockName()
);

if (
replacement &&
replacement.length &&
const canLiftAndTransformToDefaultBlock =
!! replacement?.length &&
replacement.every( ( block ) =>
canInsertBlockType(
block.name,
targetRootClientId
)
)
) {
);

if ( canLiftAndTransformToDefaultBlock ) {
// Step 4: If the block can be transformed to the default block type and moved up.
insertBlocks(
replacement,
getBlockIndex( _clientId ),
Expand All @@ -386,6 +421,7 @@ const applyWithDispatch = withDispatch( ( dispatch, ownProps, registry ) => {
);
removeBlock( firstClientId, false );
} else {
// Step 5: Continue the default behavior.
switchToDefaultOrRemove();
}
}
Expand Down
12 changes: 12 additions & 0 deletions packages/block-editor/src/components/block-list/content.scss
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,18 @@ _::-webkit-full-page-media, _:future, :root .has-multi-selection .block-editor-b
margin-left: -1px;
margin-right: -1px;
transition: background-color 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
font-size: $default-font-size;
font-family: $default-font;
color: $black;
font-weight: normal;

.is-zoomed-out & {
// Scale the font size based on the zoom level.
font-size: calc(#{$default-font-size} * ( 2 - var(--wp-block-editor-iframe-zoom-out-scale) ));
}

&.is-dragged-over {
background: $gray-400;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
import { useReducedMotion } from '@wordpress/compose';
import { useSelect } from '@wordpress/data';
import { useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
Expand Down Expand Up @@ -119,7 +120,19 @@ export function ZoomOutSeparator( {
data-is-insertion-point="true"
onDragOver={ () => setIsDraggedOver( true ) }
onDragLeave={ () => setIsDraggedOver( false ) }
></motion.div>
>
<motion.div
initial={ { opacity: 0 } }
animate={ { opacity: 1 } }
exit={ { opacity: 0 } }
transition={ {
type: 'tween',
duration: 0.1,
} }
>
{ __( 'Drop pattern.' ) }
</motion.div>
</motion.div>
) }
</AnimatePresence>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { moreVertical, external } from '@wordpress/icons';
import { useSelect, useDispatch } from '@wordpress/data';
import { store as noticesStore } from '@wordpress/notices';
import { isBlobURL } from '@wordpress/blob';
import { getFilename } from '@wordpress/url';

/**
* Internal dependencies
Expand Down Expand Up @@ -167,8 +168,13 @@ export function MediaPreview( { media, onClick, category } ) {
.fetch( url )
.then( ( response ) => response.blob() )
.then( ( blob ) => {
const fileName = getFilename( url ) || 'image.jpg';
const file = new File( [ blob ], fileName, {
type: blob.type,
} );

settings.mediaUpload( {
filesList: [ blob ],
filesList: [ file ],
additionalData: { caption },
onFileChange( [ img ] ) {
if ( isBlobURL( img.url ) ) {
Expand Down
1 change: 1 addition & 0 deletions packages/block-library/src/site-logo/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,7 @@ export default function LogoEdit( {
iconId={ siteIconId }
canUserEdit={ canUserEdit }
/>
{ canUserEdit && <DropZone onFilesDrop={ onFilesDrop } /> }
</>
);
}
Expand Down
2 changes: 2 additions & 0 deletions packages/blocks/src/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
getBlockBindingsSource,
getBlockBindingsSources,
} from './registration';
import { isUnmodifiedBlockContent } from './utils';

// The blocktype is the most important concept within the block API. It defines
// all aspects of the block configuration and its interfaces, including `edit`
Expand Down Expand Up @@ -183,4 +184,5 @@ lock( privateApis, {
unregisterBlockBindingsSource,
getBlockBindingsSource,
getBlockBindingsSources,
isUnmodifiedBlockContent,
} );
68 changes: 54 additions & 14 deletions packages/blocks/src/api/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,30 @@ extend( [ namesPlugin, a11yPlugin ] );
*/
const ICON_COLORS = [ '#191e23', '#f8f9f9' ];

/**
* Determines whether the block's attribute is equal to the default attribute
* which means the attribute is unmodified.
* @param {Object} attributeDefinition The attribute's definition of the block type.
* @param {*} value The attribute's value.
* @return {boolean} Whether the attribute is unmodified.
*/
function isUnmodifiedAttribute( attributeDefinition, value ) {
// Every attribute that has a default must match the default.
if ( attributeDefinition.hasOwnProperty( 'default' ) ) {
return value === attributeDefinition.default;
}

// The rich text type is a bit different from the rest because it
// has an implicit default value of an empty RichTextData instance,
// so check the length of the value.
if ( attributeDefinition.type === 'rich-text' ) {
return ! value?.length;
}

// Every attribute that doesn't have a default should be undefined.
return value === undefined;
}

/**
* Determines whether the block's attributes are equal to the default attributes
* which means the block is unmodified.
Expand All @@ -43,20 +67,7 @@ export function isUnmodifiedBlock( block ) {
( [ key, definition ] ) => {
const value = block.attributes[ key ];

// Every attribute that has a default must match the default.
if ( definition.hasOwnProperty( 'default' ) ) {
return value === definition.default;
}

// The rich text type is a bit different from the rest because it
// has an implicit default value of an empty RichTextData instance,
// so check the length of the value.
if ( definition.type === 'rich-text' ) {
return ! value?.length;
}

// Every attribute that doesn't have a default should be undefined.
return value === undefined;
return isUnmodifiedAttribute( definition, value );
}
);
}
Expand All @@ -73,6 +84,35 @@ export function isUnmodifiedDefaultBlock( block ) {
return block.name === getDefaultBlockName() && isUnmodifiedBlock( block );
}

/**
* Determines whether the block content is unmodified. A block content is
* considered unmodified if all the attributes that have a role of 'content'
* are equal to the default attributes (or undefined).
* If the block does not have any attributes with a role of 'content', it
* will be considered unmodified if all the attributes are equal to the default
* attributes (or undefined).
*
* @param {WPBlock} block Block Object
* @return {boolean} Whether the block content is unmodified.
*/
export function isUnmodifiedBlockContent( block ) {
const contentAttributes = getBlockAttributesNamesByRole(
block.name,
'content'
);

if ( contentAttributes.length === 0 ) {
return isUnmodifiedBlock( block );
}

return contentAttributes.every( ( key ) => {
const definition = getBlockType( block.name )?.attributes[ key ];
const value = block.attributes[ key ];

return isUnmodifiedAttribute( definition, value );
} );
}

/**
* Function that checks if the parameter is a valid icon.
*
Expand Down
7 changes: 7 additions & 0 deletions packages/components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@
### Enhancements

- `Tabs`: handle horizontal overflow and large tab lists gracefully ([#64371](https://github.com/WordPress/gutenberg/pull/64371)).
- `BorderBoxControl`: promote to stable ([#65586](https://github.com/WordPress/gutenberg/pull/65586)).
- `MenuGroup`: Simplify the MenuGroup styles within dropdown menus. ([#65561](https://github.com/WordPress/gutenberg/pull/65561)).
- `DatePicker`: Use compact button size. ([#65653](https://github.com/WordPress/gutenberg/pull/65653)).
- `Navigator`: add support for exit animation ([#64777](https://github.com/WordPress/gutenberg/pull/64777)).
- `Guide`: Update finish button to use the new default size ([#65680](https://github.com/WordPress/gutenberg/pull/65680)).
- `BorderControl`: Use `__next40pxDefaultSize` prop for Reset button ([#65682](https://github.com/WordPress/gutenberg/pull/65682)).
- `Navigator`: stabilize APIs ([#64613](https://github.com/WordPress/gutenberg/pull/64613)).

## 28.8.0 (2024-09-19)

Expand Down
1 change: 1 addition & 0 deletions packages/components/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ export {
NavigatorToParentButton as __experimentalNavigatorToParentButton,
useNavigator as __experimentalUseNavigator,
} from './navigator/legacy';
export { Navigator, useNavigator } from './navigator';
export { default as Notice } from './notice';
export { default as __experimentalNumberControl } from './number-control';
export { default as NoticeList } from './notice/list';
Expand Down
Loading

0 comments on commit e73f1d5

Please sign in to comment.