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

Footnotes: try with post meta #51201

Merged
merged 44 commits into from
Jun 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
01e319a
wip
ellatrix Apr 24, 2023
9a14fa9
wip
ellatrix Apr 25, 2023
bbb4f1c
wip
ellatrix Apr 27, 2023
23d1b1b
higher order reducer
ellatrix May 2, 2023
b942b11
Make links interactive
ellatrix May 2, 2023
f16cba5
min diff
ellatrix May 2, 2023
b454ff7
Add style
ellatrix May 2, 2023
d1d9560
wip
ellatrix May 9, 2023
7a924da
Lock apis
ellatrix May 11, 2023
e59aee9
Fix failing tests
ellatrix May 15, 2023
9bcf4df
Add fn block fixture
ellatrix May 15, 2023
910fbe0
Clean up hor
ellatrix May 15, 2023
94a370d
Fix unit test
ellatrix May 16, 2023
a2e9630
Don't save ce=false
ellatrix May 16, 2023
800f37f
Fix selection issues
ellatrix May 30, 2023
040e7f7
Remove editor style in bock json
ellatrix May 30, 2023
3310248
Footnotes: try with post meta
ellatrix Jun 2, 2023
947abe8
Clean up
ellatrix Jun 2, 2023
cc4c44e
Add server site render callback
ellatrix Jun 2, 2023
89f6f5b
Add fn block if not present
ellatrix Jun 2, 2023
42e08d5
Fix scroll into view
ellatrix Jun 2, 2023
3073634
Fix tests
ellatrix Jun 2, 2023
1d2ef9d
Fix PHP linting
ellatrix Jun 2, 2023
b27e97e
Guard for no meta
ellatrix Jun 3, 2023
bec0a07
clean up
ellatrix Jun 3, 2023
830ce85
Fix unit tests
ellatrix Jun 3, 2023
dfb6cfe
Fix package lock
ellatrix Jun 3, 2023
5b0890b
Temporarily use __unstable
ellatrix Jun 15, 2023
371df4f
Don't do anything if fn is not supported
ellatrix Jun 16, 2023
f4e4ebb
Add tests and comments
ellatrix Jun 16, 2023
7968772
Fix php lint
ellatrix Jun 16, 2023
1645470
Fix removal and test
ellatrix Jun 16, 2023
8a8b8bd
Writing flow: ignore ce false on mouse leave
ellatrix Jun 19, 2023
d0d9471
Insert footnote after selection instead of replacing it
ellatrix Jun 19, 2023
006b2a7
Somewhat fix copy/cut/paste
ellatrix Jun 19, 2023
85e2370
Keep old footnotes so they can be restored on paste
ellatrix Jun 19, 2023
a4f4940
Address feedback: flatMap
ellatrix Jun 19, 2023
86e8b20
Prefer BFS search over flattenBlocks
mcsf Jun 19, 2023
35b1ccf
Share RichText.Content with native
ellatrix Jun 20, 2023
44cfa2d
Try private api
ellatrix Jun 20, 2023
e3bcc5c
Try removing private api from native
ellatrix Jun 21, 2023
165a353
Try unlocking just in time
ellatrix Jun 21, 2023
9141d40
Skip JSON.parse for empty string
ellatrix Jun 22, 2023
3b89e82
Fix perf issue
ellatrix Jun 22, 2023
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
9 changes: 9 additions & 0 deletions docs/reference-guides/core-blocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,15 @@ Add a link to a downloadable file. ([Source](https://github.com/WordPress/gutenb
- **Supports:** align, anchor, color (background, gradients, link, ~~text~~)
- **Attributes:** displayPreview, downloadButtonText, fileId, fileName, href, id, previewHeight, showDownloadButton, textLinkHref, textLinkTarget

## Footnotes

([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/footnotes))

- **Name:** core/footnotes
- **Category:** text
- **Supports:** ~~html~~, ~~inserter~~, ~~multiple~~, ~~reusable~~
- **Attributes:**

## Classic

Use the classic WordPress editor. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/freeform))
Expand Down
2 changes: 2 additions & 0 deletions lib/blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ function gutenberg_reregister_core_block_types() {
'comments',
'details',
'group',
'footnotes',
'html',
'list',
'list-item',
Expand Down Expand Up @@ -65,6 +66,7 @@ function gutenberg_reregister_core_block_types() {
'comments-pagination-previous.php' => 'core/comments-pagination-previous',
'comments-title.php' => 'core/comments-title',
'comments.php' => 'core/comments',
'footnotes.php' => 'core/footnotes',
'file.php' => 'core/file',
'home-link.php' => 'core/home-link',
'image.php' => 'core/image',
Expand Down
5 changes: 4 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions packages/block-editor/src/components/copy-handler/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ export function useClipboardHandler() {

return useRefEffect( ( node ) => {
function handler( event ) {
if ( event.defaultPrevented ) {
// This was likely already handled in rich-text/use-paste-handler.js.
return;
}

const selectedBlockClientIds = getSelectedBlockClientIds();

if ( selectedBlockClientIds.length === 0 ) {
Expand Down Expand Up @@ -127,7 +132,6 @@ export function useClipboardHandler() {
return;
}

const eventDefaultPrevented = event.defaultPrevented;
event.preventDefault();

const isSelectionMergeable = __unstableIsSelectionMergeable();
Expand Down Expand Up @@ -197,10 +201,6 @@ export function useClipboardHandler() {
__unstableDeleteSelection();
}
} else if ( event.type === 'paste' ) {
if ( eventDefaultPrevented ) {
// This was likely already handled in rich-text/use-paste-handler.js.
return;
}
const {
__experimentalCanUserUseUnfilteredHTML:
canUserUseUnfilteredHTML,
Expand Down
85 changes: 85 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,85 @@
/**
* WordPress dependencies
*/
import { RawHTML } from '@wordpress/element';
import {
children as childrenSource,
getSaveElement,
__unstableGetBlockProps as getBlockProps,
} 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 = [] ) {
getBlockProps.skipFilters = true;
const values = findContent(
( Array.isArray( blocks ) ? blocks : [ blocks ] ).map( _getSaveElement )
);
getBlockProps.skipFilters = false;
return values;
}
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
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export default function useDragSelection() {
// child elements of the content editable wrapper are editable
// and return true for this property. We only want to start
// multi selecting when the mouse leaves the wrapper.
if ( ! target.getAttribute( 'contenteditable' ) ) {
if ( target.getAttribute( 'contenteditable' ) !== 'true' ) {
return;
}

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 @@ -23,6 +24,7 @@ export const privateApis = {};
lock( privateApis, {
...globalStyles,
ExperimentalBlockEditorProvider,
getRichTextValues,
PrivateInserter,
PrivateListView,
ResizableBoxPopover,
Expand Down
3 changes: 2 additions & 1 deletion packages/block-library/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@
"memize": "^2.1.0",
"micromodal": "^0.4.10",
"preact": "^10.13.2",
"remove-accents": "^0.4.2"
"remove-accents": "^0.4.2",
"uuid": "^8.3.0"
},
"peerDependencies": {
"react": "^18.0.0",
Expand Down
18 changes: 18 additions & 0 deletions packages/block-library/src/footnotes/block.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "core/footnotes",
"title": "Footnotes",
youknowriad marked this conversation as resolved.
Show resolved Hide resolved
"category": "text",
"description": "",
"keywords": [ "references" ],
"textdomain": "default",
"usesContext": [ "postId", "postType" ],
"supports": {
"html": false,
"multiple": false,
"inserter": false,
"reusable": false
},
"style": "wp-block-footnotes"
}
52 changes: 52 additions & 0 deletions packages/block-library/src/footnotes/edit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* WordPress dependencies
*/
import { RichText, useBlockProps } from '@wordpress/block-editor';
import { useEntityProp } from '@wordpress/core-data';

export default function FootnotesEdit( { context: { postType, postId } } ) {
const [ meta, updateMeta ] = useEntityProp(
'postType',
postType,
'meta',
postId
);
const footnotes = meta?.footnotes ? JSON.parse( meta.footnotes ) : [];
return (
<ol { ...useBlockProps() }>
{ footnotes.map( ( { id, content } ) => (
<li key={ id }>
<RichText
id={ id }
tagName="span"
value={ content }
identifier={ id }
// To do: figure out why the browser is not scrolling
// into view when it receives focus.
onFocus={ ( event ) => {
if ( ! event.target.textContent.trim() ) {
event.target.scrollIntoView();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really needed? I thought the browser scrolls when you focus something?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, see above comment, I don't know why this is happening yet

}
} }
onChange={ ( nextFootnote ) => {
updateMeta( {
...meta,
footnotes: JSON.stringify(
footnotes.map( ( footnote ) => {
return footnote.id === id
? {
content: nextFootnote,
id,
}
: footnote;
} )
),
} );
} }
/>{ ' ' }
<a href={ `#${ id }-link` }>↩︎</a>
</li>
) ) }
</ol>
);
}
Loading