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

Fix meta save causing autosave deletion, resulting in preview not displaying unsaved changes #13718

Closed
wants to merge 8 commits into from
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,10 @@ what Meta boxes are available in which location.

Returns an action object used to request meta box update.

### metaBoxUpdatesStart

Returns an action object used signal meta box updates have begun.

### metaBoxUpdatesSuccess

Returns an action object used signal a successful meta box update.
18 changes: 18 additions & 0 deletions docs/designers-developers/developers/filters/editor-filters.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,21 @@ var customPreviewMessage = function() {
wp.hooks.addFilter( 'editor.PostPreview.interstitialMarkup', 'my-plugin/custom-preview-message', customPreviewMessage );
```

## `editor.updatePost`

Used to perform other steps before, during or after the post update process.

The filter recieves a function `updatePost` that when called triggers the post update. It should return a function that wraps `updatePost` (or returns `updatePost` itself if no actions need to be performed).

_Example:_

```js
var updatePostFilter = function( updatePost ) {
return function() {
// make an API request prior to updating the post.
myApiRequest().then( updatePost );
};
};

wp.hooks.addFilter( 'editor.updatePost', 'my-plugin/update-post-filter', updatePostFilter );
```
148 changes: 114 additions & 34 deletions packages/e2e-tests/specs/preview.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,47 +12,75 @@ import {
createURL,
publishPost,
saveDraft,
clickOnMoreMenuItem,
pressKeyWithModifier,
} from '@wordpress/e2e-test-utils';

describe( 'Preview', () => {
beforeEach( async () => {
await createNewPost();
} );
async function openPreviewPage( editorPage ) {
let openTabs = await browser.pages();
const expectedTabsCount = openTabs.length + 1;
await editorPage.click( '.editor-post-preview' );

async function openPreviewPage( editorPage ) {
let openTabs = await browser.pages();
const expectedTabsCount = openTabs.length + 1;
await editorPage.click( '.editor-post-preview' );

// Wait for the new tab to open.
while ( openTabs.length < expectedTabsCount ) {
await editorPage.waitFor( 1 );
openTabs = await browser.pages();
}

const previewPage = last( openTabs );
// Wait for the preview to load. We can't do interstitial detection here,
// because it might load too quickly for us to pick up, so we wait for
// the preview to load by waiting for the title to appear.
await previewPage.waitForSelector( '.entry-title' );
return previewPage;
// Wait for the new tab to open.
while ( openTabs.length < expectedTabsCount ) {
await editorPage.waitFor( 1 );
openTabs = await browser.pages();
}

/**
* Given a Puppeteer Page instance for a preview window, clicks Preview, and
* awaits the window navigation.
*
* @param {puppeteer.Page} previewPage Page on which to await navigation.
*
* @return {Promise} Promise resolving once navigation completes.
*/
async function waitForPreviewNavigation( previewPage ) {
const navigationCompleted = previewPage.waitForNavigation();
await page.click( '.editor-post-preview' );
const previewPage = last( openTabs );
// Wait for the preview to load. We can't do interstitial detection here,
// because it might load too quickly for us to pick up, so we wait for
// the preview to load by waiting for the title to appear.
await previewPage.waitForSelector( '.entry-title' );
return previewPage;
}

/**
* Given a Puppeteer Page instance for a preview window, clicks Preview, and
* awaits the window navigation.
*
* @param {puppeteer.Page} previewPage Page on which to await navigation.
*
* @return {Promise} Promise resolving once navigation completes.
*/
async function waitForPreviewNavigation( previewPage ) {
const navigationCompleted = previewPage.waitForNavigation();
await page.click( '.editor-post-preview' );
return navigationCompleted;
}

/**
* Enables or disables the custom fields option.
*
* Note that this is implemented separately from the `toggleScreenOptions`
* utility, since the custom fields option triggers a page reload and requires
* extra async logic to wait for navigation to complete.
*
* @param {boolean} shouldBeChecked If true, turns the option on. If false, off.
*/
async function toggleCustomFieldsOption( shouldBeChecked ) {
await clickOnMoreMenuItem( 'Options' );
const [ handle ] = await page.$x( `//label[contains(text(), "Custom Fields")]` );

const isChecked = await page.evaluate(
( element ) => element.control.checked,
handle
);
if ( isChecked !== shouldBeChecked ) {
const navigationCompleted = page.waitForNavigation();
await handle.click();
return navigationCompleted;
}

it( 'Should open a preview window for a new post', async () => {
await page.click( 'button[aria-label="Close dialog"]' );
}

describe( 'Preview', () => {
beforeEach( async () => {
await createNewPost();
} );

it( 'should open a preview window for a new post', async () => {
const editorPage = page;

// Disabled until content present.
Expand Down Expand Up @@ -129,7 +157,7 @@ describe( 'Preview', () => {
await previewPage.close();
} );

it( 'Should not revert title during a preview right after a save draft', async () => {
it( 'should not revert title during a preview right after a save draft', async () => {
const editorPage = page;

// Type aaaaa in the title filed.
Expand Down Expand Up @@ -166,3 +194,55 @@ describe( 'Preview', () => {
await previewPage.close();
} );
} );

describe( 'Preview + Custom Fields', async () => {
beforeEach( async () => {
await createNewPost();
await toggleCustomFieldsOption( true );
} );

afterEach( async () => {
await toggleCustomFieldsOption( false );
} );

it( 'displays edits to the post title and content in the preview', async () => {
const editorPage = page;

// Add an initial title and content.
await editorPage.type( '.editor-post-title__input', 'title 1' );
await editorPage.keyboard.press( 'Tab' );
await editorPage.keyboard.type( 'content 1' );

// Open the preview page.
const previewPage = await openPreviewPage( editorPage );

// Check the title and preview match.
let previewTitle = await previewPage.$eval( '.entry-title', ( node ) => node.textContent );
expect( previewTitle ).toBe( 'title 1' );
let previewContent = await previewPage.$eval( '.entry-content p', ( node ) => node.textContent );
expect( previewContent ).toBe( 'content 1' );

// Return to editor and modify the title and content.
await editorPage.bringToFront();
await editorPage.click( '.editor-post-title__input' );
await pressKeyWithModifier( 'shift', 'Home' );
await editorPage.keyboard.press( 'Delete' );
await editorPage.keyboard.type( 'title 2' );
await editorPage.keyboard.press( 'Tab' );
await pressKeyWithModifier( 'shift', 'Home' );
await editorPage.keyboard.press( 'Delete' );
await editorPage.keyboard.type( 'content 2' );

// Open the preview page.
await waitForPreviewNavigation( previewPage );

// Title in preview should match input.
previewTitle = await previewPage.$eval( '.entry-title', ( node ) => node.textContent );
expect( previewTitle ).toBe( 'title 2' );
previewContent = await previewPage.$eval( '.entry-content p', ( node ) => node.textContent );
expect( previewContent ).toBe( 'content 2' );

// Make sure the editor is active for the afterEach function.
await editorPage.bringToFront();
} );
} );
1 change: 1 addition & 0 deletions packages/edit-post/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

### Bug Fixes
- Fix 'save' keyboard shortcut not functioning in the Code Editor.
- Fix issue with preview not displaying unsaved changes when MetaBoxes are active.

## 3.1.7 (2019-01-03)

Expand Down
11 changes: 11 additions & 0 deletions packages/edit-post/src/store/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,17 @@ export function requestMetaBoxUpdates() {
};
}

/**
* Returns an action object used signal meta box updates have begun.
*
* @return {Object} Action object.
*/
export function metaBoxUpdatesStart() {
return {
type: 'META_BOX_UPDATES_START',
};
}

/**
* Returns an action object used signal a successful meta box update.
*
Expand Down
Loading