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

Upgrade React version to 16.13.1 #21289

Merged
merged 8 commits into from
Aug 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 14 additions & 0 deletions lib/client-assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,20 @@ function gutenberg_override_style( $styles, $handle, $src, $deps = array(), $ver
function gutenberg_register_vendor_scripts( $scripts ) {
$suffix = SCRIPT_DEBUG ? '' : '.min';

$react_suffix = ( SCRIPT_DEBUG ? '.development' : '.production' ) . $suffix;
gutenberg_register_vendor_script(
$scripts,
'react',
'https://unpkg.com/react@16.13.1/umd/react' . $react_suffix . '.js',
array( 'wp-polyfill' )
);
gutenberg_register_vendor_script(
$scripts,
'react-dom',
'https://unpkg.com/react-dom@16.13.1/umd/react-dom' . $react_suffix . '.js',
array( 'react' )
);

/*
* This script registration and the corresponding function should be removed
* once the plugin is updated to support WordPress 5.4.0 and newer.
Expand Down
55 changes: 38 additions & 17 deletions package-lock.json

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

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -182,10 +182,10 @@
"prettier": "npm:wp-prettier@2.0.5",
"progress": "2.0.3",
"puppeteer": "npm:puppeteer-core@3.0.0",
"react": "16.9.0",
"react-dom": "16.9.0",
"react": "16.13.1",
"react-dom": "16.13.1",
"react-native": "0.61.5",
"react-test-renderer": "16.9.0",
"react-test-renderer": "16.13.1",
"rimraf": "3.0.2",
"rtlcss": "2.4.0",
"sass-loader": "8.0.2",
Expand Down
2 changes: 1 addition & 1 deletion packages/components/src/tooltip/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ describe( 'Tooltip', () => {
target: wrapper.find( 'button > span' ).getDOMNode(),
} );

expect( originalMouseEnter ).toHaveBeenCalled();
expect( originalMouseEnter ).not.toHaveBeenCalled();

const popover = wrapper.find( 'Popover' );
wrapper.instance().delayedSetIsOver.flush();
Expand Down
40 changes: 35 additions & 5 deletions packages/components/src/unit-control/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import classnames from 'classnames';
/**
* WordPress dependencies
*/
import { forwardRef } from '@wordpress/element';
import { forwardRef, useRef } from '@wordpress/element';

/**
* Internal dependencies
Expand Down Expand Up @@ -48,14 +48,21 @@ function UnitControl(
initial: initialUnit,
} );

/*
* Storing parsed unit changes to be applied during the onChange callback
* cycle.
*/
const nextParsedUnitRef = useRef();

const classes = classnames( 'components-unit-control', className );

const handleOnChange = ( next, changeProps ) => {
if ( next === '' ) {
onChange( '', changeProps );
return;
}
/**

/*
* Customizing the onChange callback.
* This allows as to broadcast a combined value+unit to onChange.
*/
Expand All @@ -65,7 +72,22 @@ function UnitControl(
value,
unit
);
const nextValue = `${ parsedValue }${ parsedUnit }`;
const nextParsedUnit = nextParsedUnitRef.current;

/*
* If we've noticed a (parsed) unit change, which would have been
* stored in nextParsedUnitRef, we'll update our local unit set,
* as well as fire the onUnitChange callback.
*/
if ( nextParsedUnit ) {
onUnitChange( nextParsedUnit, changeProps );
setUnit( nextParsedUnit );
// We have to reset this ref value to properly track new changes.
nextParsedUnitRef.current = null;
}

const nextUnit = nextParsedUnit || parsedUnit;
const nextValue = `${ parsedValue }${ nextUnit }`;

onChange( nextValue, changeProps );
};
Expand Down Expand Up @@ -98,7 +120,7 @@ function UnitControl(
const { type, payload } = action;
const event = payload?.event;

/**
/*
* Customizes the commit interaction.
*
* This occurs when pressing ENTER to fire a change.
Expand All @@ -119,7 +141,15 @@ function UnitControl(

// Update unit if the incoming parsed unit is different.
if ( unit !== parsedUnit ) {
handleOnUnitChange( parsedUnit, { event } );
/*
* We start by storing the next parsedUnit value in our
* nextParsedUnitRef. We can't set the unit during this
* stateReducer callback as it cause state update
* conflicts within React's render cycle.
*
* https://github.com/facebook/react/issues/18178
*/
nextParsedUnitRef.current = parsedUnit;
}
}

Expand Down
84 changes: 63 additions & 21 deletions packages/data/src/namespace-store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import { createStore, applyMiddleware } from 'redux';
import { flowRight, get, mapValues } from 'lodash';
import combineReducers from 'turbo-combine-reducers';
import EquivalentKeyMap from 'equivalent-key-map';

/**
* WordPress dependencies
Expand All @@ -19,6 +20,34 @@ import metadataReducer from './metadata/reducer';
import * as metadataSelectors from './metadata/selectors';
import * as metadataActions from './metadata/actions';

/**
* Create a cache to track whether resolvers started running or not.
*
* @return {Object} Resolvers Cache.
*/
function createResolversCache() {
const cache = {};
return {
isRunning( selectorName, args ) {
return cache[ selectorName ] && cache[ selectorName ].get( args );
},

clear( selectorName, args ) {
if ( cache[ selectorName ] ) {
cache[ selectorName ].delete( args );
}
},

markAsRunning( selectorName, args ) {
if ( ! cache[ selectorName ] ) {
cache[ selectorName ] = new EquivalentKeyMap();
}

cache[ selectorName ].set( args, true );
},
};
}

/**
* @typedef {WPDataRegistry} WPDataRegistry
*/
Expand All @@ -37,6 +66,7 @@ import * as metadataActions from './metadata/actions';
export default function createNamespace( key, options, registry ) {
const reducer = options.reducer;
const store = createReduxStore( key, options, registry );
const resolversCache = createResolversCache();

let resolvers;
const actions = mapActions(
Expand Down Expand Up @@ -64,7 +94,12 @@ export default function createNamespace( key, options, registry ) {
store
);
if ( options.resolvers ) {
const result = mapResolvers( options.resolvers, selectors, store );
const result = mapResolvers(
options.resolvers,
selectors,
store,
resolversCache
);
resolvers = result.resolvers;
selectors = result.selectors;
}
Expand Down Expand Up @@ -166,7 +201,6 @@ function createReduxStore( key, options, registry ) {
* public facing API. Selectors will get passed the
* state as first argument.
* @param {Object} store The store to which the selectors should be mapped.
*
* @return {Object} Selectors mapped to the provided store.
*/
function mapSelectors( selectors, store ) {
Expand Down Expand Up @@ -215,12 +249,13 @@ function mapActions( actions, store ) {
* Resolvers are side effects invoked once per argument set of a given selector call,
* used in ensuring that the data needs for the selector are satisfied.
*
* @param {Object} resolvers Resolvers to register.
* @param {Object} selectors The current selectors to be modified.
* @param {Object} store The redux store to which the resolvers should be mapped.
* @return {Object} An object containing updated selectors and resolvers.
* @param {Object} resolvers Resolvers to register.
* @param {Object} selectors The current selectors to be modified.
* @param {Object} store The redux store to which the resolvers should be mapped.
* @param {Object} queue Resolvers async queue.
* @param {Object} resolversCache Resolvers Cache.
*/
function mapResolvers( resolvers, selectors, store ) {
function mapResolvers( resolvers, selectors, store, resolversCache ) {
const mappedResolvers = mapValues( resolvers, ( resolver ) => {
const { fulfill: resolverFulfill = resolver } = resolver;
return { ...resolver, fulfill: resolverFulfill };
Expand All @@ -237,13 +272,15 @@ function mapResolvers( resolvers, selectors, store ) {
async function fulfillSelector() {
const state = store.getState();
if (
typeof resolver.isFulfilled === 'function' &&
resolver.isFulfilled( state, ...args )
resolversCache.isRunning( selectorName, args ) ||
( typeof resolver.isFulfilled === 'function' &&
resolver.isFulfilled( state, ...args ) )
) {
return;
}

const { metadata } = store.__unstableOriginalGetState();

if (
metadataSelectors.hasStartedResolution(
metadata,
Expand All @@ -254,18 +291,23 @@ function mapResolvers( resolvers, selectors, store ) {
return;
}

store.dispatch(
metadataActions.startResolution( selectorName, args )
);
await fulfillResolver(
store,
mappedResolvers,
selectorName,
...args
);
store.dispatch(
metadataActions.finishResolution( selectorName, args )
);
resolversCache.markAsRunning( selectorName, args );

setTimeout( async () => {
resolversCache.clear( selectorName, args );
store.dispatch(
metadataActions.startResolution( selectorName, args )
);
await fulfillResolver(
store,
mappedResolvers,
selectorName,
...args
);
store.dispatch(
metadataActions.finishResolution( selectorName, args )
);
} );
}

fulfillSelector( ...args );
Expand Down
10 changes: 5 additions & 5 deletions packages/data/src/namespace-store/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import { createRegistry } from '../../registry';
import { createRegistryControl } from '../../factory';

jest.useFakeTimers();

describe( 'controls', () => {
let registry;

Expand Down Expand Up @@ -80,16 +82,14 @@ describe( 'controls', () => {
.select( 'store' )
.hasFinishedResolution( 'getItems' );
if ( isFinished ) {
expect( registry.select( 'store' ).getItems() ).toEqual( [
1,
2,
3,
] );
const items = registry.select( 'store' ).getItems();
expect( items ).toEqual( [ 1, 2, 3 ] );
}
resolve();
} );

registry.select( 'store' ).getItems();
jest.runAllTimers();
} );
} );
describe( 'selectors have expected value for the `hasResolver` property', () => {
Expand Down