From ad0e283a1e9c37aeaa9a4bbdeca75c6cd75c9c15 Mon Sep 17 00:00:00 2001 From: Tugdual de Kerviler Date: Thu, 2 May 2019 13:10:24 +0200 Subject: [PATCH] Squashed commit of the following: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 1dddab40b2ede5737e615390e6a41daaa27c4461 Author: Stefanos Togkoulidis Date: Wed May 1 00:00:50 2019 +0300 Have Aztec delete the detected Enter key for paragraphs Aztec-Android doesn't swallow the Enter key (like the list handling does) so, instruct Aztec to delete it for the paragraph block. commit 0936ca0fec43f631fc05c8e29389a071bc2a03c0 Author: Stefanos Togkoulidis Date: Tue Apr 30 20:58:36 2019 +0300 Just use onFormatChange which now defaults to "force" commit 6358de362a89ec97eda748c704edd8d2e20f8a06 Merge: a5282ce1d 5e4d62721 Author: Stefanos Togkoulidis Date: Tue Apr 30 20:23:57 2019 +0300 Merge branch 'master' into rnmobile/fix-list-handling-android commit 5e4d62721e47cc699a855f3f0ac8ca9c16555da0 Author: Pascal Birchler Date: Tue Apr 30 18:27:24 2019 +0200 Update to Babel 7.4 and core-js 3 (#15139) * Specify core-js version when using useBuiltIns * Update to Babel 7.4 and core-js 3 * setupFiles: fix path to async-iterator * Also update Babel packages in babel-preset-default * Update snapshot for babel-preset-default test * Manually include web.dom-collections.iterator in jest config * Regenerate package-lock.json file after latest changes applied * Upgrade ESLint related npm packages * Another cleanup in the package-lock.json file * Remove ESLint rules which throw error to fix linting * Add core-js/modules/web.dom.iterable to make e2e tests work * Update Babel packages to the latest version * Update ignore files in e2e tests config * Add changelog entries related to Babel and ESLint version bumps commit 1d959bad91e80a38d76e27fe5461128e3647ceff Author: Andrés Date: Tue Apr 30 17:14:35 2019 +0200 Remove not used state (#15224) commit d715e93b9802278a8c18cbca2132e9478a588206 Author: Jon Surrell Date: Tue Apr 30 16:29:09 2019 +0200 Babel plugin JSX: Implement Fragment handling (#15120) Add imports for `<>` JSX Fragments. commit 96cad996572a5aaa3ed3e339f19b6eb51c9bcb6d Author: Kelly Dwan Date: Tue Apr 30 09:18:54 2019 -0400 Fix incorrect ID in FocalPointPicker (#15255) commit c1ba13ef88b91c4176842e9fc742c07c2be22b95 Author: Jon Surrell Date: Tue Apr 30 13:44:50 2019 +0200 Update Fragment imports in READMEs (#15262) Some Fragment imports were incorrect. Fix them. commit 297c2f427490ed704507bb80fe31d5e90b1bd051 Author: etoledom Date: Tue Apr 30 13:19:34 2019 +0200 RNMobile: Fix autoscroll on ListBlock (#15048) * RNMobile: Add ability to send extra props (i.e. props needed just for mobile) to the list block. * Adding onCaretVerticalPositionChange to RichText via context * Passing onCaretVerticalPositionChange via context to RichText for all RichText based blocks This makes it not necessary to pass onCaretVerticalPositionChange as a prop directly to RichText from the block component. * Update jest snapshot for block-edit commit 447dd274129206a4e1a5b35b79256a549d0f9ace Author: Jorge Costa Date: Tue Apr 30 10:47:55 2019 +0100 Fix copy paste and delete error core paragraph with locking (#14712) * Fix: Copy / Paste error core/paragraph with locking * Add test case. * Update packages/block-library/src/paragraph/edit.js Co-Authored-By: jorgefilipecosta commit 0b2eb1c4fd5e9d25d8bde0e652eb8ede78f9295e Author: Jon Surrell Date: Tue Apr 30 09:39:29 2019 +0200 Dependency extraction webpack plugin: Change option name consistent with docs (#15260) In the docs, an option name was provided as `requestToHandle`, but the actual option in use was `requestToDependency`. Update the code and related tests to use `requestToHandle` as described in the documentation instead of `requestToDependency`. commit 506827ed2a5ab59990f650d113c4afe900db4d21 Author: Jon Surrell Date: Tue Apr 30 09:31:38 2019 +0200 Read script dependencies from generated files (#15124) * Rework script registration to use generated deps * Deprecate static list of dependencies * Rework translation without packages-dependencies.php * Include build/*/*.deps.json in plugin zip * Add script dependencies undetectable by build tools Some scripts have dependencies that are undetectable by the webpack plugin used to generate the dependency files. Add these dependencies to the generated dependencies. * Add `wp-polyfill` dependency via webpack plugin Enable `injectPolyfill` option in the webpack plugin instead of manually injecting the dependency via PHP on script registration. This will enable the polyfill for consumers of wp-scripts default webpack config. * Improve deprecated message * Remove obsolete lib/packages-dependencies.php commit c2c8276ac8e89af8382d5180ffa6a52f7fa3f98e Author: Daniel Richards Date: Tue Apr 30 13:36:49 2019 +0800 Use button block appender on group block (#14943) * Use button block appender on group block * Update group block e2e tests for the new button appender * Add additional margin to the appender when a group has a background color. * Use more opaque versions of the appender background color To ensure greater compatibility when layered on top of a block with a background color. * Block Library: Display ButtonBlockAppender only if selected or empty * Only render button appender when the group has no inner blocks commit 1e96ec74a43021c60dccfde95b47cd6c1f0a11cd Author: Andrew Duthie Date: Mon Apr 29 16:40:24 2019 -0400 Build Tooling: Pass individual files as arguments from watch to build script (#15219) commit cafb57b84fefb9194db2e43b2157909236c3d317 Author: Grzegorz (Greg) Ziółkowski Date: Mon Apr 29 22:12:08 2019 +0200 Blocks: Upgrade simple-html-tokenizer dependency (#15246) commit 5b3b3aba47049e025464d4942a3e3d742c7513cf Author: Andrew Duthie Date: Mon Apr 29 13:38:09 2019 -0400 Framework: Add REST API codeowners (#15215) commit 64c48fdea724843009b48c373649c6382957eb6f Author: Ian Dunn Date: Mon Apr 29 10:06:46 2019 -0700 Correct name of `date_i18n()` PHP function. (#15204) commit 8c288148c17e74dcabb80e674b23003d1f6ffff7 Author: Andrew Duthie Date: Mon Apr 29 13:05:10 2019 -0400 Framework: Remove TESTS.md (#15217) commit 0f1fb5797566a203be357aa3d1ae9f8951c931fc Author: Emmanuel Hesry Date: Mon Apr 29 17:34:22 2019 +0200 fix typo in withDispatch documentation (#15251) commit a5282ce1d8f2b6e0114a7ec1dd996e21e2cf5c67 Author: Stefanos Togkoulidis Date: Thu Apr 25 16:08:31 2019 +0300 Revert "Trivial change to trigger Travis" This reverts commit e22ffde2ef44bf376508e11669e2feb8b3addcca. commit e22ffde2ef44bf376508e11669e2feb8b3addcca Author: Stefanos Togkoulidis Date: Thu Apr 25 16:08:24 2019 +0300 Trivial change to trigger Travis commit 15a51f8c9ddbdedda0352f44ab41bfcc79aca6fa Author: Jorge Costa Date: Fri Apr 19 15:33:15 2019 +0100 chore: Fix: Lint error that makes unit tests (and CI tests) fail. (#15073) commit 2b11074b9c0245c39935b01fff30651ce578ca39 Author: Stefanos Togkoulidis Date: Thu Apr 25 12:42:55 2019 +0300 Fix lint issues commit 9c298c8b74d847dbdfcc39b3e79eff2f74ca0080 Author: Stefanos Togkoulidis Date: Thu Apr 25 12:01:46 2019 +0300 Need to specify firedAfterTextChanged on all Aztec events commit 46e086d58f7b4531e66e75e41050f1e5da496ef8 Author: Stefanos Togkoulidis Date: Thu Apr 25 03:59:59 2019 +0300 Force Aztec update if "Enter" fired before text change commit 724e2951d7410d851556477796c8b9e624ee2f15 Author: Stefanos Togkoulidis Date: Thu Apr 25 03:11:52 2019 +0300 Differentiate Android and iOS since assumptions diverged The iOS side still expects to just check against `this.lastContent` to force the change into Aztec. commit 52386fa6bf51bff16eb684110ec1e00497b1b18c Author: Stefanos Togkoulidis Date: Thu Apr 25 01:55:22 2019 +0300 Use a flag to signal Aztec-originated changes And assume that when that flag is false, component changes need to get sent/reflected down to Aztec. commit c7aa381c96d5da06fe6db09f18c8c1fec8374242 Author: Stefanos Togkoulidis Date: Tue Apr 23 17:30:45 2019 +0300 Able to not lose content commit 60c75b06abc3c2cbf3a2ad361a9625c9287b72fb Author: Stefanos Togkoulidis Date: Tue Apr 23 10:09:23 2019 +0300 If text already changed, don't modify it --- .../src/components/rich-text/index.native.js | 61 ++++++++++++------- .../src/paragraph/edit.native.js | 3 +- 2 files changed, 42 insertions(+), 22 deletions(-) diff --git a/packages/block-editor/src/components/rich-text/index.native.js b/packages/block-editor/src/components/rich-text/index.native.js index f23775a5a0864..80bc5d720ff3f 100644 --- a/packages/block-editor/src/components/rich-text/index.native.js +++ b/packages/block-editor/src/components/rich-text/index.native.js @@ -104,7 +104,6 @@ export class RichText extends Component { this.onFocus = this.onFocus.bind( this ); this.onBlur = this.onBlur.bind( this ); this.onContentSizeChange = this.onContentSizeChange.bind( this ); - this.onFormatChangeForceChild = this.onFormatChangeForceChild.bind( this ); this.onFormatChange = this.onFormatChange.bind( this ); // This prevents a bug in Aztec which triggers onSelectionChange twice on format change this.onSelectionChange = this.onSelectionChange.bind( this ); @@ -163,9 +162,9 @@ export class RichText extends Component { // value. This also provides an opportunity for the parent component to // determine whether the before/after value has changed using a trivial // strict equality operation. - if ( isEmpty( after ) ) { + if ( isEmpty( after ) && before.text.length === currentRecord.text.length ) { before = currentRecord; - } else if ( isEmpty( before ) ) { + } else if ( isEmpty( before ) && after.text.length === currentRecord.text.length ) { after = currentRecord; } @@ -211,11 +210,7 @@ export class RichText extends Component { } ).map( ( name ) => gutenbergFormatNamesToAztec[ name ] ).filter( Boolean ); } - onFormatChangeForceChild( record ) { - this.onFormatChange( record, true ); - } - - onFormatChange( record, doUpdateChild ) { + onFormatChange( record, doUpdateChild = true ) { let newContent; // valueToFormat might throw when converting the record to a tree structure // let's ignore the event for now and force a render update so we're still in sync @@ -230,7 +225,7 @@ export class RichText extends Component { } ); if ( newContent && newContent !== this.props.value ) { this.props.onChange( newContent ); - if ( record.needsSelectionUpdate && record.start && record.end ) { + if ( record.needsSelectionUpdate && record.start && record.end && doUpdateChild ) { this.forceSelectionUpdate( record.start, record.end ); } } else { @@ -274,6 +269,8 @@ export class RichText extends Component { this.lastEventCount = event.nativeEvent.eventCount; const contentWithoutRootTag = this.removeRootTagsProduceByAztec( unescapeSpaces( event.nativeEvent.text ) ); this.lastContent = contentWithoutRootTag; + this.comesFromAztec = true; + this.firedAfterTextChanged = true; // the onChange event always fires after the fact this.props.onChange( this.lastContent ); } @@ -289,6 +286,8 @@ export class RichText extends Component { // eslint-disable-next-line no-unused-vars onEnter( event ) { this.lastEventCount = event.nativeEvent.eventCount; + this.comesFromAztec = true; + this.firedAfterTextChanged = event.nativeEvent.firedAfterTextChanged; const currentRecord = this.createRecord( { ...event.nativeEvent, @@ -298,19 +297,19 @@ export class RichText extends Component { if ( this.multilineTag ) { if ( event.shiftKey ) { const insertedLineBreak = { needsSelectionUpdate: true, ...insert( currentRecord, '\n' ) }; - this.onFormatChangeForceChild( insertedLineBreak ); + this.onFormatChange( insertedLineBreak ); } else if ( this.onSplit && isEmptyLine( currentRecord ) ) { this.setState( { needsSelectionUpdate: false, } ); - this.onSplit( ...split( currentRecord ).map( this.valueToFormat ) ); + this.splitContent( currentRecord ); } else { const insertedLineSeparator = { needsSelectionUpdate: true, ...insertLineSeparator( currentRecord ) }; - this.onFormatChangeForceChild( insertedLineSeparator ); + this.onFormatChange( insertedLineSeparator, ! this.firedAfterTextChanged ); } } else if ( event.shiftKey || ! this.onSplit ) { const insertedLineBreak = { needsSelectionUpdate: true, ...insert( currentRecord, '\n' ) }; - this.onFormatChangeForceChild( insertedLineBreak ); + this.onFormatChange( insertedLineBreak ); } else { this.splitContent( currentRecord ); } @@ -393,7 +392,6 @@ export class RichText extends Component { }, } ); this.lastContent = this.valueToFormat( linkedRecord ); - this.lastEventCount = undefined; this.props.onChange( this.lastContent ); // Allows us to ask for this information when we get a report. @@ -425,7 +423,6 @@ export class RichText extends Component { const recordToInsert = create( { html: pastedContent } ); const insertedContent = insert( currentRecord, recordToInsert ); const newContent = this.valueToFormat( insertedContent ); - this.lastEventCount = undefined; this.lastContent = newContent; // explicitly set selection after inline paste @@ -488,6 +485,8 @@ export class RichText extends Component { // we don't want to refresh aztec native as no content can have changed from this event // let's update lastContent to prevent that in shouldComponentUpdate this.lastContent = newContent; + this.comesFromAztec = true; + this.firedAfterTextChanged = true; // Selection change event always fires after the fact this.props.onChange( this.lastContent ); } this.props.onSelectionChange(realStart, realEnd); @@ -574,7 +573,7 @@ export class RichText extends Component { // This logic will handle the selection when two blocks are merged or when block is split // into two blocks - if ( nextTextContent.startsWith( this.savedContent ) ) { + if ( nextTextContent.startsWith( this.savedContent ) && this.savedContent && this.savedContent.length > 0 ) { let length = this.savedContent.length; if ( length === 0 && nextTextContent !== this.props.value ) { length = this.props.value.length; @@ -593,7 +592,7 @@ export class RichText extends Component { } shouldComponentUpdate( nextProps ) { - if ( nextProps.tagName !== this.props.tagName || nextProps.isSelected !== this.props.isSelected ) { + if ( nextProps.tagName !== this.props.tagName ) { this.lastEventCount = undefined; this.lastContent = undefined; return true; @@ -603,13 +602,27 @@ export class RichText extends Component { // It was removed in https://github.com/WordPress/gutenberg/pull/12417 to fix undo/redo problem. // If the component is changed React side (undo/redo/merging/splitting/custom text actions) - // we need to make sure the native is updated as well + // we need to make sure the native is updated as well. + + const previousValueToCheck = Platform.OS === 'android' ? this.props.value : this.lastContent; + + // Also, don't trust the "this.lastContent" as on Android, incomplete text events arrive + // with only some of the text, while the virtual keyboard's suggestion system does its magic. + // ** compare with this.lastContent for optimizing performance by not forcing Aztec with text it already has + // , but compare with props.value to not lose "half word" text because of Android virtual keyb autosuggestion behavior if ( ( typeof nextProps.value !== 'undefined' ) && - ( typeof this.lastContent !== 'undefined' ) && - nextProps.value !== this.lastContent ) { + ( typeof this.props.value !== 'undefined' ) && + ( Platform.OS === 'ios' || ( Platform.OS === 'android' && ( ! this.comesFromAztec || ! this.firedAfterTextChanged ) ) ) && + nextProps.value !== previousValueToCheck ) { this.lastEventCount = undefined; // force a refresh on the native side } + if ( Platform.OS === 'android' && this.comesFromAztec === false ) { + if ( this.needsSelectionUpdate ) { + this.lastEventCount = undefined; // force a refresh on the native side + } + } + return true; } @@ -684,6 +697,11 @@ export class RichText extends Component { } } + if ( this.comesFromAztec ) { + this.comesFromAztec = false; + this.firedAfterTextChanged = false; + } + return ( { isSelected && this.multilineTag === 'li' && ( @@ -691,7 +709,7 @@ export class RichText extends Component { onTagNameChange={ onTagNameChange } tagName={ tagName } value={ record } - onChange={ this.onFormatChangeForceChild } + onChange={ this.onFormatChange } /> ) } { isSelected && ( @@ -714,6 +732,7 @@ export class RichText extends Component { text={ { text: html, eventCount: this.lastEventCount, selection } } placeholder={ this.props.placeholder } placeholderTextColor={ this.props.placeholderTextColor || styles[ 'block-editor-rich-text' ].textDecorationColor } + deleteEnter={ this.props.deleteEnter } onChange={ this.onChange } onFocus={ this.onFocus } onBlur={ this.onBlur } diff --git a/packages/block-library/src/paragraph/edit.native.js b/packages/block-library/src/paragraph/edit.native.js index 9ba8b498d7edf..1caba6062b451 100644 --- a/packages/block-library/src/paragraph/edit.native.js +++ b/packages/block-library/src/paragraph/edit.native.js @@ -125,7 +125,8 @@ class ParagraphEdit extends Component { value={ content } isSelected={ this.props.isSelected } onFocus={ this.props.onFocus } // always assign onFocus as a props - onBlur={ this.props.onBlur } // always assign onBlur as a props + onBlur={ this.props.onBlur } // always assign onBlur as a props= + deleteEnter={ true }= style={ style } onChange={ ( nextContent ) => { setAttributes( {