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

Refactor: move core/edit-post INIT effect to use action-generators and controls #14740

Merged
merged 14 commits into from
May 2, 2019
6 changes: 5 additions & 1 deletion packages/edit-post/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
## V.V.V (Unreleased)
## Master

### New Features

- Implement the `addToGallery` option in the `MediaUpload` hook. The option allows users to open the media modal in the `gallery-library`instead of `gallery-edit` state.

### Refactor

- convert `INIT` effect to controls & actions [#14740](https://github.com/WordPress/gutenberg/pull/14740)


## 3.2.0 (2019-03-06)

Expand Down
1 change: 1 addition & 0 deletions packages/edit-post/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ export function initializeEditor( id, postType, postId, settings, initialEdits )
console.warn( "Your browser is using Quirks Mode. \nThis can cause rendering issues such as blocks overlaying meta boxes in the editor. Quirks Mode can be triggered by PHP errors or HTML code appearing before the opening <!DOCTYPE html>. Try checking the raw page source or your site's PHP error log and resolving errors there, removing any HTML before the doctype, or disabling plugins." );
}

dispatch( 'core/edit-post' ).__unstableInitialize();
dispatch( 'core/nux' ).triggerGuide( [
'core/editor.inserter',
'core/editor.settings',
Expand Down
78 changes: 78 additions & 0 deletions packages/edit-post/src/store/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
*/
import { castArray } from 'lodash';

/**
* Internal dependencies
*/
import { __unstableSubscribe } from './controls';
import { onChangeListener } from './utils';
import { STORE_KEY, VIEW_AS_LINK_SELECTOR } from './constants';

/**
* Returns an action object used in signalling that the user opened an editor sidebar.
*
Expand Down Expand Up @@ -232,3 +239,74 @@ export function metaBoxUpdatesSuccess() {
};
}

/**
* Returns an action generator used to initialize some subscriptions for the
* post editor:
*
* - subscription for toggling the `edit-post/block` general sidebar when a
* block is selected.
* - subscription for hiding/showing the sidebar depending on size of viewport.
* - subscription for updating the "View Post" link in the admin bar when
* permalink is updated.
*/
export function* __unstableInitialize() {
// Select the block settings tab when the selected block changes
yield __unstableSubscribe( ( registry ) => onChangeListener(
() => !! registry.select( 'core/block-editor' )
.getBlockSelectionStart(),
( hasBlockSelection ) => {
if ( ! registry.select( 'core/edit-post' ).isEditorSidebarOpened() ) {
return;
}
if ( hasBlockSelection ) {
registry.dispatch( STORE_KEY )
.openGeneralSidebar( 'edit-post/block' );
} else {
registry.dispatch( STORE_KEY )
.openGeneralSidebar( 'edit-post/document' );
}
}
) );
// hide/show the sidebar depending on size of viewport.
yield __unstableSubscribe( ( registry ) => onChangeListener(
() => registry.select( 'core/viewport' )
.isViewportMatch( '< medium' ),
( () => {
let sidebarToReOpenOnExpand = null;
return ( isSmall ) => {
const { getActiveGeneralSidebarName } = registry.select( STORE_KEY );
const {
closeGeneralSidebar: closeSidebar,
openGeneralSidebar: openSidebar,
} = registry.dispatch( STORE_KEY );
if ( isSmall ) {
sidebarToReOpenOnExpand = getActiveGeneralSidebarName();
if ( sidebarToReOpenOnExpand ) {
closeSidebar();
}
} else if (
sidebarToReOpenOnExpand &&
! getActiveGeneralSidebarName()
) {
openSidebar( sidebarToReOpenOnExpand );
}
};
} )(),
true
) );
// Update View Post link in the admin bar when permalink is updated.
yield __unstableSubscribe( ( registry ) => onChangeListener(
() => registry.select( 'core/editor' ).getCurrentPost().link,
( newPermalink ) => {
if ( ! newPermalink ) {
return;
}
const nodeToUpdate = document.querySelector( VIEW_AS_LINK_SELECTOR );
if ( ! nodeToUpdate ) {
return;
}
nodeToUpdate.setAttribute( 'href', newPermalink );
}
) );
}

11 changes: 11 additions & 0 deletions packages/edit-post/src/store/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* The identifier for the data store.
* @type {string}
*/
export const STORE_KEY = 'core/edit-post';

/**
* CSS selector string for the admin bar view post link anchor tag.
* @type {string}
*/
export const VIEW_AS_LINK_SELECTOR = '#wp-admin-bar-view a';
Copy link
Member

Choose a reason for hiding this comment

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

I'd recommend some JSDoc for the constants.

Copy link
Member

Choose a reason for hiding this comment

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

Aside: It wasn't introduced here, but "View" shows for draft posts with a different ID wp-admin-bar-preview (view vs. preview) and thus wouldn't be updated.

Copy link
Member

Choose a reason for hiding this comment

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

Aside: It wasn't introduced here, but "View" shows for draft posts with a different ID wp-admin-bar-preview (view vs. preview) and thus wouldn't be updated.

Follow-up issue: #15402

48 changes: 48 additions & 0 deletions packages/edit-post/src/store/controls.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* WordPress dependencies
*/
import { createRegistryControl } from '@wordpress/data';

/**
* Calls a selector using the current state.
*
* @param {string} storeName Store name.
* @param {string} selectorName Selector name.
* @param {Array} args Selector arguments.
*
* @return {Object} control descriptor.
*/
export function select( storeName, selectorName, ...args ) {
return {
type: 'SELECT',
storeName,
selectorName,
args,
};
}

/**
* Calls a subscriber using the current state.
*
* @param {function} listenerCallback A callback for the subscriber that
* receives the registry.
* @return {Object} control descriptor.
*/
export function __unstableSubscribe( listenerCallback ) {
Copy link
Member

Choose a reason for hiding this comment

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

Since it's not exposed on a public API, I suppose it doesn't strictly need the prefix. But could be a good indicator for internal use as well.

return { type: 'SUBSCRIBE', listenerCallback };
}

const controls = {
SELECT: createRegistryControl(
( registry ) => ( { storeName, selectorName, args } ) => {
return registry.select( storeName )[ selectorName ]( ...args );
}
),
SUBSCRIBE: createRegistryControl(
( registry ) => ( { listenerCallback } ) => {
return registry.subscribe( listenerCallback( registry ) );
}
),
};

export default controls;
75 changes: 2 additions & 73 deletions packages/edit-post/src/store/effects.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,9 @@ import apiFetch from '@wordpress/api-fetch';
/**
* Internal dependencies
*/
import {
metaBoxUpdatesSuccess,
requestMetaBoxUpdates,
openGeneralSidebar,
closeGeneralSidebar,
} from './actions';
import {
getActiveMetaBoxLocations,
getActiveGeneralSidebarName,
} from './selectors';
import { metaBoxUpdatesSuccess, requestMetaBoxUpdates } from './actions';
import { getActiveMetaBoxLocations } from './selectors';
import { getMetaBoxContainer } from '../utils/meta-boxes';
import { onChangeListener } from './utils';

const VIEW_AS_LINK_SELECTOR = '#wp-admin-bar-view a';

const effects = {
SET_META_BOXES_PER_LOCATIONS( action, store ) {
Expand Down Expand Up @@ -126,66 +115,6 @@ const effects = {
const message = action.mode === 'visual' ? __( 'Visual editor selected' ) : __( 'Code editor selected' );
speak( message, 'assertive' );
},
INIT( _, store ) {
// Select the block settings tab when the selected block changes
subscribe( onChangeListener(
() => !! select( 'core/block-editor' ).getBlockSelectionStart(),
( hasBlockSelection ) => {
if ( ! select( 'core/edit-post' ).isEditorSidebarOpened() ) {
return;
}
if ( hasBlockSelection ) {
store.dispatch( openGeneralSidebar( 'edit-post/block' ) );
} else {
store.dispatch( openGeneralSidebar( 'edit-post/document' ) );
}
} )
);

const isMobileViewPort = () => select( 'core/viewport' ).isViewportMatch( '< medium' );
const adjustSidebar = ( () => {
// contains the sidebar we close when going to viewport sizes lower than medium.
// This allows to reopen it when going again to viewport sizes greater than medium.
let sidebarToReOpenOnExpand = null;
return ( isSmall ) => {
if ( isSmall ) {
sidebarToReOpenOnExpand = getActiveGeneralSidebarName( store.getState() );
if ( sidebarToReOpenOnExpand ) {
store.dispatch( closeGeneralSidebar() );
}
} else if ( sidebarToReOpenOnExpand && ! getActiveGeneralSidebarName( store.getState() ) ) {
store.dispatch( openGeneralSidebar( sidebarToReOpenOnExpand ) );
}
};
} )();

adjustSidebar( isMobileViewPort() );

// Collapse sidebar when viewport shrinks.
// Reopen sidebar it if viewport expands and it was closed because of a previous shrink.
subscribe( onChangeListener( isMobileViewPort, adjustSidebar ) );

// Update View as link when currentPost link changes
const updateViewAsLink = ( newPermalink ) => {
if ( ! newPermalink ) {
return;
}

const nodeToUpdate = document.querySelector(
VIEW_AS_LINK_SELECTOR
);
if ( ! nodeToUpdate ) {
return;
}
nodeToUpdate.setAttribute( 'href', newPermalink );
};

subscribe( onChangeListener(
() => select( 'core/editor' ).getCurrentPost().link,
updateViewAsLink
) );
},

};

export default effects;
6 changes: 4 additions & 2 deletions packages/edit-post/src/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,17 @@ import reducer from './reducer';
import applyMiddlewares from './middlewares';
import * as actions from './actions';
import * as selectors from './selectors';
import controls from './controls';
import { STORE_KEY } from './constants';

const store = registerStore( 'core/edit-post', {
const store = registerStore( STORE_KEY, {
reducer,
actions,
selectors,
controls,
persist: [ 'preferences' ],
} );

applyMiddlewares( store );
store.dispatch( { type: 'INIT' } );

export default store;
3 changes: 2 additions & 1 deletion packages/edit-post/src/store/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ import reducer from './reducer';
import applyMiddlewares from './middlewares';
import * as actions from './actions';
import * as selectors from './selectors';
import { STORE_KEY } from './constants';

const store = registerStore( 'core/edit-post', {
const store = registerStore( STORE_KEY, {
reducer,
actions,
selectors,
Expand Down
Loading