Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ignore: just doing some performance testing #51765

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions lib/client-assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -569,3 +569,25 @@ function gutenberg_register_vendor_scripts( $scripts ) {
// Enqueue stored styles.
add_action( 'wp_enqueue_scripts', 'gutenberg_enqueue_stored_styles' );
add_action( 'wp_footer', 'gutenberg_enqueue_stored_styles', 1 );

/**
* Registers the `core/footnotes` block on the server.
*/
function register_block_core_footnotes() {
register_post_meta(
'post',
'footnotes',
array(
'show_in_rest' => true,
'single' => true,
'type' => 'string',
)
);
register_block_type_from_metadata(
__DIR__ . '/footnotes',
array(
'render_callback' => 'render_block_core_footnotes',
)
);
}
add_action( 'init', 'register_block_core_footnotes' );
78 changes: 78 additions & 0 deletions packages/block-editor/src/components/rich-text/content.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/**
* WordPress dependencies
*/
import { RawHTML } from '@wordpress/element';
import { children as childrenSource, getSaveElement } from '@wordpress/blocks';
import deprecated from '@wordpress/deprecated';

/**
* Internal dependencies
*/
import { getMultilineTag } from './utils';

export const Content = ( { value, tagName: Tag, multiline, ...props } ) => {
// Handle deprecated `children` and `node` sources.
if ( Array.isArray( value ) ) {
deprecated( 'wp.blockEditor.RichText value prop as children type', {
since: '6.1',
version: '6.3',
alternative: 'value prop as string',
link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/',
} );

value = childrenSource.toHTML( value );
}

const MultilineTag = getMultilineTag( multiline );

if ( ! value && MultilineTag ) {
value = `<${ MultilineTag }></${ MultilineTag }>`;
}

const content = <RawHTML>{ value }</RawHTML>;

if ( Tag ) {
const { format, ...restProps } = props;
return <Tag { ...restProps }>{ content }</Tag>;
}

return content;
};

Content.__unstableIsRichTextContent = {};

function findContent( blocks, richTextValues = [] ) {
if ( ! Array.isArray( blocks ) ) {
blocks = [ blocks ];
}

for ( const block of blocks ) {
if (
block?.type?.__unstableIsRichTextContent ===
Content.__unstableIsRichTextContent
) {
richTextValues.push( block.props.value );
continue;
}

if ( block?.props?.children ) {
findContent( block.props.children, richTextValues );
}
}

return richTextValues;
}

function _getSaveElement( { name, attributes, innerBlocks } ) {
return getSaveElement(
name,
attributes,
innerBlocks.map( _getSaveElement )
);
}

export function getRichTextValues( blocks = [] ) {
return findContent(
( Array.isArray( blocks ) ? blocks : [ blocks ] ).map( _getSaveElement )
);
}
37 changes: 2 additions & 35 deletions packages/block-editor/src/components/rich-text/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import classnames from 'classnames';
* WordPress dependencies
*/
import {
RawHTML,
useRef,
useCallback,
forwardRef,
Expand Down Expand Up @@ -46,6 +45,7 @@ import { useInsertReplacementText } from './use-insert-replacement-text';
import { useFirefoxCompat } from './use-firefox-compat';
import FormatEdit from './format-edit';
import { getMultilineTag, getAllowedFormats } from './utils';
import { Content } from './content';

export const keyboardShortcutContext = createContext();
export const inputEventContext = createContext();
Expand Down Expand Up @@ -419,40 +419,7 @@ function RichTextWrapper(

const ForwardedRichTextContainer = forwardRef( RichTextWrapper );

ForwardedRichTextContainer.Content = ( {
value,
tagName: Tag,
multiline,
...props
} ) => {
// Handle deprecated `children` and `node` sources.
if ( Array.isArray( value ) ) {
deprecated( 'wp.blockEditor.RichText value prop as children type', {
since: '6.1',
version: '6.3',
alternative: 'value prop as string',
link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/',
} );

value = childrenSource.toHTML( value );
}

const MultilineTag = getMultilineTag( multiline );

if ( ! value && MultilineTag ) {
value = `<${ MultilineTag }></${ MultilineTag }>`;
}

const content = <RawHTML>{ value }</RawHTML>;

if ( Tag ) {
const { format, ...restProps } = props;
return <Tag { ...restProps }>{ content }</Tag>;
}

return content;
};

ForwardedRichTextContainer.Content = Content;
ForwardedRichTextContainer.isEmpty = ( value ) => {
return ! value || value.length === 0;
};
Expand Down
36 changes: 3 additions & 33 deletions packages/block-editor/src/components/rich-text/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,7 @@ import classnames from 'classnames';
/**
* WordPress dependencies
*/
import {
RawHTML,
Platform,
useRef,
useCallback,
forwardRef,
} from '@wordpress/element';
import { Platform, useRef, useCallback, forwardRef } from '@wordpress/element';
import { useDispatch, useSelect } from '@wordpress/data';
import {
pasteHandler,
Expand Down Expand Up @@ -55,6 +49,7 @@ import {
createLinkInParagraph,
} from './utils';
import EmbedHandlerPicker from './embed-handler-picker';
import { Content } from './content';

const classes = 'block-editor-rich-text__editable';

Expand Down Expand Up @@ -707,32 +702,7 @@ function RichTextWrapper(

const ForwardedRichTextContainer = forwardRef( RichTextWrapper );

ForwardedRichTextContainer.Content = ( {
value,
tagName: Tag,
multiline,
...props
} ) => {
// Handle deprecated `children` and `node` sources.
if ( Array.isArray( value ) ) {
value = childrenSource.toHTML( value );
}

const MultilineTag = getMultilineTag( multiline );

if ( ! value && MultilineTag ) {
value = `<${ MultilineTag }></${ MultilineTag }>`;
}

const content = <RawHTML>{ value }</RawHTML>;

if ( Tag ) {
const { format, ...restProps } = props;
return <Tag { ...restProps }>{ content }</Tag>;
}

return content;
};
ForwardedRichTextContainer.Content = Content;

ForwardedRichTextContainer.isEmpty = ( value ) => {
return ! value || value.length === 0;
Expand Down
2 changes: 2 additions & 0 deletions packages/block-editor/src/private-apis.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import * as globalStyles from './components/global-styles';
import { ExperimentalBlockEditorProvider } from './components/provider';
import { lock } from './lock-unlock';
import { getRichTextValues } from './components/rich-text/content';
import ResizableBoxPopover from './components/resizable-box-popover';
import { ComposedPrivateInserter as PrivateInserter } from './components/inserter';
import { PrivateListView } from './components/list-view';
Expand All @@ -22,6 +23,7 @@ export const privateApis = {};
lock( privateApis, {
...globalStyles,
ExperimentalBlockEditorProvider,
getRichTextValues,
PrivateInserter,
PrivateListView,
ResizableBoxPopover,
Expand Down
9 changes: 9 additions & 0 deletions packages/blocks/src/api/serializer.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@ export function getBlockProps( props = {} ) {
*/
export function getInnerBlocksProps( props = {} ) {
const { innerBlocks } = innerBlocksPropsProvider;
const [ firstBlock ] = innerBlocks ?? [];
if ( ! firstBlock ) return props;
// If the innerBlocks passed to `getSaveElement` are not blocks but already
// components, return the props as is. This is the case for
// `getRichTextValues`.
if ( ! firstBlock.clientId ) return { ...props, children: innerBlocks };
// Value is an array of blocks, so defer to block serializer.
const html = serialize( innerBlocks, { isInnerBlocks: true } );
// Use special-cased raw HTML tag to avoid default escaping.
Expand All @@ -120,6 +126,9 @@ export function getSaveElement(
innerBlocks = []
) {
const blockType = normalizeBlockType( blockTypeOrName );

if ( ! blockType?.save ) return null;

let { save } = blockType;

// Component classes are unsupported for save since serialization must
Expand Down
2 changes: 2 additions & 0 deletions packages/core-data/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"dependencies": {
"@babel/runtime": "^7.16.0",
"@wordpress/api-fetch": "file:../api-fetch",
"@wordpress/block-editor": "file:../block-editor",
"@wordpress/blocks": "file:../blocks",
"@wordpress/compose": "file:../compose",
"@wordpress/data": "file:../data",
Expand All @@ -40,6 +41,7 @@
"@wordpress/html-entities": "file:../html-entities",
"@wordpress/i18n": "file:../i18n",
"@wordpress/is-shallow-equal": "file:../is-shallow-equal",
"@wordpress/private-apis": "file:../private-apis",
"@wordpress/url": "file:../url",
"change-case": "^4.1.2",
"equivalent-key-map": "^0.2.2",
Expand Down
77 changes: 72 additions & 5 deletions packages/core-data/src/entity-provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,22 @@ import {
useCallback,
useEffect,
} from '@wordpress/element';
import { useSelect, useDispatch } from '@wordpress/data';
import { useSelect, useDispatch, useRegistry } from '@wordpress/data';
import { parse, __unstableSerializeAndClean } from '@wordpress/blocks';
import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor';

/**
* Internal dependencies
*/
import { STORE_NAME } from './name';
import { unlock } from './private-apis';

/** @typedef {import('@wordpress/blocks').WPBlock} WPBlock */

const EMPTY_ARRAY = [];

const oldFootnotes = {};

/**
* Internal dependencies
*/
Expand Down Expand Up @@ -150,6 +154,8 @@ export function useEntityProp( kind, name, prop, _id ) {
* @return {[WPBlock[], Function, Function]} The block array and setters.
*/
export function useEntityBlockEditor( kind, name, { id: _id } = {} ) {
const [ meta, updateMeta ] = useEntityProp( kind, name, 'meta', _id );
const registry = useRegistry();
const providerId = useEntityId( kind, name );
const id = _id ?? providerId;
const { content, blocks } = useSelect(
Expand Down Expand Up @@ -184,6 +190,61 @@ export function useEntityBlockEditor( kind, name, { id: _id } = {} ) {
}
}, [ content ] );

const updateFootnotes = useCallback(
( _blocks ) => {
if ( ! meta ) return;
// If meta.footnotes is empty, it means the meta is not registered.
if ( meta.footnotes === undefined ) return;

const { getRichTextValues } = unlock( blockEditorPrivateApis );
const _content = getRichTextValues( _blocks ).join( '' ) || '';
// const newOrder = [];

// // This can be avoided when
// // https://github.com/WordPress/gutenberg/pull/43204 lands. We can then
// // get the order directly from the rich text values.
// if ( _content.indexOf( 'data-fn' ) !== -1 ) {
// const regex = /data-fn="([^"]+)"/g;
// let match;
// while ( ( match = regex.exec( _content ) ) !== null ) {
// newOrder.push( match[ 1 ] );
// }
// }

// const footnotes = meta.footnotes
// ? JSON.parse( meta.footnotes )
// : [];
// const currentOrder = footnotes.map( ( fn ) => fn.id );

// if ( currentOrder.join( '' ) === newOrder.join( '' ) ) return;

// const newFootnotes = newOrder.map(
// ( fnId ) =>
// footnotes.find( ( fn ) => fn.id === fnId ) ||
// oldFootnotes[ fnId ] || {
// id: fnId,
// content: '',
// }
// );

// oldFootnotes = {
// ...oldFootnotes,
// ...footnotes.reduce( ( acc, fn ) => {
// if ( ! newOrder.includes( fn.id ) ) {
// acc[ fn.id ] = fn;
// }
// return acc;
// }, {} ),
// };

// updateMeta( {
// ...meta,
// footnotes: JSON.stringify( newFootnotes ),
// } );
},
[ meta, updateMeta ]
);

const onChange = useCallback(
( newBlocks, options ) => {
const { selection } = options;
Expand All @@ -200,18 +261,24 @@ export function useEntityBlockEditor( kind, name, { id: _id } = {} ) {
edits.content = ( { blocks: blocksForSerialization = [] } ) =>
__unstableSerializeAndClean( blocksForSerialization );

editEntityRecord( kind, name, id, edits );
registry.batch( () => {
updateFootnotes( edits.blocks );
editEntityRecord( kind, name, id, edits );
} );
},
[ kind, name, id, blocks ]
[ kind, name, id, blocks, updateFootnotes ]
);

const onInput = useCallback(
( newBlocks, options ) => {
const { selection } = options;
const edits = { blocks: newBlocks, selection };
editEntityRecord( kind, name, id, edits );
registry.batch( () => {
updateFootnotes( edits.blocks );
editEntityRecord( kind, name, id, edits );
} );
},
[ kind, name, id ]
[ kind, name, id, updateFootnotes ]
);

return [ blocks ?? EMPTY_ARRAY, onInput, onChange ];
Expand Down
Loading