From f9efc9f1c7bccd6388a9398ee6f8ea08b23cb3d2 Mon Sep 17 00:00:00 2001 From: Chris Van Patten Date: Wed, 17 Oct 2018 22:11:35 -0400 Subject: [PATCH 001/121] Deprecate PanelColor components (#10391) * Deprecate PanelColor components * Update deprecation version numbers * Fix a test broken during the rebase --- docs/reference/deprecated.md | 2 ++ packages/components/CHANGELOG.md | 6 ++++++ packages/components/src/panel/color.js | 7 +++++++ packages/components/src/panel/test/color.js | 4 ++++ packages/editor/CHANGELOG.md | 6 ++++++ packages/editor/src/components/panel-color/index.js | 7 +++++++ 6 files changed, 32 insertions(+) diff --git a/docs/reference/deprecated.md b/docs/reference/deprecated.md index d0653f14fed93..d7203f2edba18 100644 --- a/docs/reference/deprecated.md +++ b/docs/reference/deprecated.md @@ -4,6 +4,8 @@ Gutenberg's deprecation policy is intended to support backwards-compatibility fo - `isEditorSidebarPanelOpened` selector (`core/edit-post`) has been removed. Please use `isEditorPanelEnabled` instead. - `toggleGeneralSidebarEditorPanel` action (`core/edit-post`) has been removed. Please use `toggleEditorPanelOpened` instead. +- `wp.components.PanelColor` component has been removed. Please use `wp.editor.PanelColorSettings` instead. +- `wp.editor.PanelColor` component has been removed. Please use `wp.editor.PanelColorSettings` instead. ## 4.2.0 diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index d74dfc694f8eb..2665f8e62ee0f 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -1,3 +1,9 @@ +## 4.2.0 (Unreleased) + +### Deprecation + +- `wp.components.PanelColor` has been deprecated in favor of `wp.editor.PanelColorSettings`. + ## 4.1.0 (2018-10-10) ### New Feature diff --git a/packages/components/src/panel/color.js b/packages/components/src/panel/color.js index 249585ae3b026..3c137e79eeeb6 100644 --- a/packages/components/src/panel/color.js +++ b/packages/components/src/panel/color.js @@ -1,6 +1,7 @@ /** * WordPress dependencies */ +import deprecated from '@wordpress/deprecated'; import { __, sprintf } from '@wordpress/i18n'; /** @@ -10,6 +11,12 @@ import PanelBody from './body'; import ColorIndicator from '../color-indicator'; function PanelColor( { colorValue, colorName, title, ...props } ) { + deprecated( 'wp.components.PanelColor', { + version: '4.3', + alternative: 'wp.editor.PanelColorSettings', + plugin: 'Gutenberg', + } ); + // translators: %s: The name of the color e.g: "vivid red" or color hex code if name is not available e.g: "#f00". const currentColorLabel = sprintf( __( '(current color: %s)' ), colorName || colorValue ); return ( diff --git a/packages/components/src/panel/test/color.js b/packages/components/src/panel/test/color.js index c3ca26962db60..31c00562daaee 100644 --- a/packages/components/src/panel/test/color.js +++ b/packages/components/src/panel/test/color.js @@ -13,5 +13,9 @@ describe( 'PanelColor', () => { const wrapper = shallow( ); expect( wrapper ).toMatchSnapshot(); + + expect( console ).toHaveWarnedWith( + 'wp.components.PanelColor is deprecated and will be removed from Gutenberg in 4.3. Please use wp.editor.PanelColorSettings instead.' + ); } ); } ); diff --git a/packages/editor/CHANGELOG.md b/packages/editor/CHANGELOG.md index 4b518f3801b40..d82d8b209de0a 100644 --- a/packages/editor/CHANGELOG.md +++ b/packages/editor/CHANGELOG.md @@ -1,3 +1,9 @@ +## 4.1.0 (Unreleased) + +### Deprecations + +- `wp.editor.PanelColor` has been deprecated in favor of `wp.editor.PanelColorSettings`. + ## 4.0.0 (2018-09-30) ### Breaking Changes diff --git a/packages/editor/src/components/panel-color/index.js b/packages/editor/src/components/panel-color/index.js index 5ad46d0d86c1f..327384a127653 100644 --- a/packages/editor/src/components/panel-color/index.js +++ b/packages/editor/src/components/panel-color/index.js @@ -8,6 +8,7 @@ import { omit } from 'lodash'; */ import { PanelColor as PanelColorComponent } from '@wordpress/components'; import { ifCondition, compose } from '@wordpress/compose'; +import deprecated from '@wordpress/deprecated'; /** * Internal dependencies @@ -17,6 +18,12 @@ import withColorContext from '../color-palette/with-color-context'; import { getColorObjectByColorValue } from '../colors'; function PanelColor( { colors, title, colorValue, initialOpen, ...props } ) { + deprecated( 'wp.editor.PanelColor', { + version: '4.3', + alternative: 'wp.editor.PanelColorSettings', + plugin: 'Gutenberg', + } ); + const colorObject = getColorObjectByColorValue( colors, colorValue ); const colorName = colorObject && colorObject.name; return ( From ca05c269d7d4e357ca1a9226c6d072993ded7044 Mon Sep 17 00:00:00 2001 From: Danilo Ercoli Date: Thu, 18 Oct 2018 06:51:25 +0200 Subject: [PATCH 002/121] Refactor `onSplit` and `insertBlockAfter` in RichText component, Para and Heading blocks for mobile, tryin gto stay closer to the web version. (#10690) --- .../block-library/src/heading/edit.native.js | 31 +++++------- .../src/paragraph/edit.native.js | 42 ++++++++++++++-- .../src/components/rich-text/index.native.js | 48 ++++++++++++++++++- 3 files changed, 96 insertions(+), 25 deletions(-) diff --git a/packages/block-library/src/heading/edit.native.js b/packages/block-library/src/heading/edit.native.js index 3d84600da25fd..8eba264968ca0 100644 --- a/packages/block-library/src/heading/edit.native.js +++ b/packages/block-library/src/heading/edit.native.js @@ -24,28 +24,11 @@ import './editor.scss'; const minHeight = 50; class HeadingEdit extends Component { - constructor() { - super( ...arguments ); - this.splitBlock = this.splitBlock.bind( this ); - } - - // eslint-disable-next-line no-unused-vars - splitBlock( htmlText, start, end ) { - const { - insertBlocksAfter, - } = this.props; - - if ( insertBlocksAfter ) { - const blocks = []; - blocks.push( createBlock( 'core/paragraph', { content: 'Test' } ) ); - insertBlocksAfter( blocks ); - } - } - render() { const { attributes, setAttributes, + insertBlocksAfter, } = this.props; const { @@ -73,7 +56,17 @@ class HeadingEdit extends Component { content: newParaBlock.attributes.content, } ); } } - onSplit={ this.splitBlock } + onSplit={ + insertBlocksAfter ? + ( before, after, ...blocks ) => { + setAttributes( { content: before } ); + insertBlocksAfter( [ + ...blocks, + createBlock( 'core/paragraph', { content: after } ), + ] ); + } : + undefined + } onContentSizeChange={ ( event ) => { setAttributes( { aztecHeight: event.aztecHeight } ); } } diff --git a/packages/block-library/src/paragraph/edit.native.js b/packages/block-library/src/paragraph/edit.native.js index 1b35bf84a1088..9fb79f45f8cdf 100644 --- a/packages/block-library/src/paragraph/edit.native.js +++ b/packages/block-library/src/paragraph/edit.native.js @@ -13,23 +13,55 @@ import { RichText } from '@wordpress/editor'; const minHeight = 50; +const name = 'core/paragraph'; + class ParagraphEdit extends Component { constructor() { super( ...arguments ); this.splitBlock = this.splitBlock.bind( this ); } - // eslint-disable-next-line no-unused-vars - splitBlock( htmlText, start, end ) { + /** + * Split handler for RichText value, namely when content is pasted or the + * user presses the Enter key. + * + * @param {?Array} before Optional before value, to be used as content + * in place of what exists currently for the + * block. If undefined, the block is deleted. + * @param {?Array} after Optional after value, to be appended in a new + * paragraph block to the set of blocks passed + * as spread. + * @param {...WPBlock} blocks Optional blocks inserted between the before + * and after value blocks. + */ + splitBlock( before, after, ...blocks ) { const { + attributes, insertBlocksAfter, + setAttributes, } = this.props; - if ( insertBlocksAfter ) { - const blocks = []; - blocks.push( createBlock( 'core/paragraph', { content: 'Test' } ) ); + if ( after !== null ) { + // Append "After" content as a new paragraph block to the end of + // any other blocks being inserted after the current paragraph. + const newBlock = createBlock( name, { content: after } ); + blocks.push( newBlock ); + } + + if ( blocks.length && insertBlocksAfter ) { insertBlocksAfter( blocks ); } + + const { content } = attributes; + if ( before === null ) { + // TODO : If before content is omitted, treat as intent to delete block. + // onReplace( [] ); + } else if ( content !== before ) { + // Only update content if it has in-fact changed. In case that user + // has created a new paragraph at end of an existing one, the value + // of before will be strictly equal to the current content. + setAttributes( { content: before } ); + } } render() { diff --git a/packages/editor/src/components/rich-text/index.native.js b/packages/editor/src/components/rich-text/index.native.js index 71d13f67761c2..8de0a2655d1f0 100644 --- a/packages/editor/src/components/rich-text/index.native.js +++ b/packages/editor/src/components/rich-text/index.native.js @@ -14,6 +14,11 @@ import { import { Component, RawHTML } from '@wordpress/element'; import { withInstanceId, compose } from '@wordpress/compose'; import { Toolbar } from '@wordpress/components'; +import { + create, + split, + toHTMLString, +} from '@wordpress/rich-text'; /** * Internal dependencies @@ -56,12 +61,53 @@ export class RichText extends Component { this.splitContent( htmlText, start, end ); } + /* + * Splits the content at the location of the selection. + * + * Replaces the content of the editor inside this element with the contents + * before the selection. Sends the elements after the selection to the `onSplit` + * handler. + * + */ splitContent( htmlText, start, end ) { const { onSplit } = this.props; + if ( ! onSplit ) { return; } - onSplit( htmlText, start, end ); + + const record = create( { + html: htmlText, + range: null, + multilineTag: false, + removeNode: null, + unwrapNode: null, + removeAttribute: null, + filterString: null, + } ); + + // TODO : Fix the index position in AztecNative for Android + let [ before, after ] = split( { start: start - 6, end: end - 6, ...record } ); + + // TODO : Handle here the cases when the split happens at the trailing or leading edge... + // See the web version for reference. + + if ( before ) { + before = this.valueToFormat( before ); + } + + if ( after ) { + after = this.valueToFormat( after ); + } + + onSplit( before, after ); + } + + valueToFormat( { formats, text } ) { + const value = toHTMLString( { formats, text }, this.multilineTag ); + // remove the outer p tags + const returningContentWithoutParaTag = value.replace( /

|<\/p>/gi, '' ); + return returningContentWithoutParaTag; } onActiveFormatsChange( formats ) { From 70583acc9d55bf71bb0b73c29d3e3f6381ce1eb2 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Thu, 18 Oct 2018 03:41:03 -0400 Subject: [PATCH 003/121] Blocks: Add direction attribute to paragraph block (#10663) --- packages/block-library/src/paragraph/edit.js | 31 ++++++++++++++++++- packages/block-library/src/paragraph/index.js | 6 ++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/packages/block-library/src/paragraph/edit.js b/packages/block-library/src/paragraph/edit.js index 6e77735fd016f..1290f5566d46b 100644 --- a/packages/block-library/src/paragraph/edit.js +++ b/packages/block-library/src/paragraph/edit.js @@ -6,7 +6,7 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { __ } from '@wordpress/i18n'; +import { __, _x } from '@wordpress/i18n'; import { Component, Fragment, @@ -14,6 +14,7 @@ import { import { PanelBody, ToggleControl, + Toolbar, withFallbackStyles, } from '@wordpress/components'; import { @@ -29,6 +30,7 @@ import { } from '@wordpress/editor'; import { createBlock } from '@wordpress/blocks'; import { compose } from '@wordpress/compose'; +import { withSelect } from '@wordpress/data'; const { getComputedStyle } = window; @@ -137,6 +139,7 @@ class ParagraphBlock extends Component { fallbackFontSize, fontSize, setFontSize, + isRTL, } = this.props; const { @@ -144,6 +147,7 @@ class ParagraphBlock extends Component { content, dropCap, placeholder, + direction, } = attributes; return ( @@ -155,6 +159,23 @@ class ParagraphBlock extends Component { setAttributes( { align: nextAlign } ); } } /> + { isRTL && ( + + ) } @@ -212,6 +233,7 @@ class ParagraphBlock extends Component { color: textColor.color, fontSize: fontSize.size ? fontSize.size + 'px' : undefined, textAlign: align, + direction, } } value={ content } onChange={ ( nextContent ) => { @@ -234,6 +256,13 @@ const ParagraphEdit = compose( [ withColors( 'backgroundColor', { textColor: 'color' } ), withFontSizes( 'fontSize' ), applyFallbackStyles, + withSelect( ( select ) => { + const { getEditorSettings } = select( 'core/editor' ); + + return { + isRTL: getEditorSettings().isRTL, + }; + } ), ] )( ParagraphBlock ); export default ParagraphEdit; diff --git a/packages/block-library/src/paragraph/index.js b/packages/block-library/src/paragraph/index.js index 1e1218c6d2ab5..25e83f1018c03 100644 --- a/packages/block-library/src/paragraph/index.js +++ b/packages/block-library/src/paragraph/index.js @@ -65,6 +65,10 @@ const schema = { customFontSize: { type: 'number', }, + direction: { + type: 'string', + enum: [ 'ltr', 'rtl' ], + }, }; export const name = 'core/paragraph'; @@ -230,6 +234,7 @@ export const settings = { customTextColor, fontSize, customFontSize, + direction, } = attributes; const textClass = getColorClassName( 'color', textColor ); @@ -258,6 +263,7 @@ export const settings = { style={ styles } className={ className ? className : undefined } value={ content } + dir={ direction } /> ); }, From b09e27f763d750599e2c037719c704ef62d1f4d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Wrede?= Date: Thu, 18 Oct 2018 09:44:55 +0200 Subject: [PATCH 004/121] bold permalink label (#10566) --- packages/editor/src/components/post-permalink/style.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/editor/src/components/post-permalink/style.scss b/packages/editor/src/components/post-permalink/style.scss index e882c2579958c..c35abcb009dfc 100644 --- a/packages/editor/src/components/post-permalink/style.scss +++ b/packages/editor/src/components/post-permalink/style.scss @@ -39,6 +39,7 @@ .editor-post-permalink__label { margin: 0 10px 0 5px; + font-weight: 600; } .editor-post-permalink__link { From 86605e4899c52fe994dc76b1acb54b4f17c299e4 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Thu, 18 Oct 2018 16:13:55 +0800 Subject: [PATCH 005/121] Fix autocomplete keyboard nav in link popover (#10716) * Fix autocomplete cursor key navigation * Avoid running onClickOutside logic for other non-onClickOutside events * Add e2e tests for keyboard interaction with link container --- .../format-toolbar/link-container.js | 14 ++- .../editor/src/components/url-input/index.js | 2 +- test/e2e/specs/links.test.js | 96 +++++++++++++++++-- 3 files changed, 99 insertions(+), 13 deletions(-) diff --git a/packages/editor/src/components/rich-text/format-toolbar/link-container.js b/packages/editor/src/components/rich-text/format-toolbar/link-container.js index 84cd17d31c41e..a070ae6e77bb2 100644 --- a/packages/editor/src/components/rich-text/format-toolbar/link-container.js +++ b/packages/editor/src/components/rich-text/format-toolbar/link-container.js @@ -99,6 +99,7 @@ class LinkContainer extends Component { this.onKeyDown = this.onKeyDown.bind( this ); this.onChangeInputValue = this.onChangeInputValue.bind( this ); this.setLinkTarget = this.setLinkTarget.bind( this ); + this.onClickOutside = this.onClickOutside.bind( this ); this.resetState = this.resetState.bind( this ); this.autocompleteRef = createRef(); @@ -175,15 +176,20 @@ class LinkContainer extends Component { event.preventDefault(); } - resetState( event ) { + onClickOutside( event ) { // The autocomplete suggestions list renders in a separate popover (in a portal), // so onClickOutside fails to detect that a click on a suggestion occured in the // LinkContainer. Detect clicks on autocomplete suggestions using a ref here, and - // return early if so. - if ( this.autocompleteRef.current && this.autocompleteRef.current.contains( event.target ) ) { + // return to avoid the popover being closed. + const autocompleteElement = this.autocompleteRef.current; + if ( autocompleteElement && autocompleteElement.contains( event.target ) ) { return; } + this.resetState(); + } + + resetState() { this.props.stopAddingLink(); this.setState( { editLink: false } ); } @@ -205,7 +211,7 @@ class LinkContainer extends Component { key={ `${ record.start }${ record.end }` /* Used to force rerender on selection change */ } > ( { expect( await getEditedPostContent() ).toMatchSnapshot(); } ); - // Test for regressions of https://github.com/WordPress/gutenberg/issues/10496. - it( 'allows autocomplete suggestions to be selected with the mouse', async () => { - const titleText = 'Unique post title'; - - // First create a post that we can search for using the link autocompletion. + const createPostWithTitle = async ( titleText ) => { + await newPost(); await page.type( '.editor-post-title__input', titleText ); await page.click( '.editor-post-publish-panel__toggle' ); @@ -273,8 +270,16 @@ describe( 'Links', () => { // Publish the post await page.click( '.editor-post-publish-button' ); + // Return the URL of the new post await page.waitForSelector( '.post-publish-panel__postpublish-post-address input' ); - const postURL = await page.evaluate( () => document.querySelector( '.post-publish-panel__postpublish-post-address input' ).value ); + return page.evaluate( () => document.querySelector( '.post-publish-panel__postpublish-post-address input' ).value ); + }; + + // Test for regressions of https://github.com/WordPress/gutenberg/issues/10496. + it( 'allows autocomplete suggestions to be selected with the mouse', async () => { + // First create a post that we can search for using the link autocompletion. + const titleText = 'Test post mouse'; + const postURL = await createPostWithTitle( titleText ); // Now create a new post and try to select the post created previously // from the autocomplete suggestions. @@ -297,11 +302,10 @@ describe( 'Links', () => { const firstSuggestion = autocompleteSuggestions[ 0 ]; // Expect that clicking on the autocomplete suggestion doesn't dismiss the link popover. - // and that the url input has a value. await firstSuggestion.click(); expect( await page.$( '.editor-url-popover' ) ).not.toBeNull(); - // Expect the url input value to have been updated with the post url + // Expect the url input value to have been updated with the post url. const inputValue = await page.evaluate( () => document.querySelector( '.editor-url-input input[aria-label="URL"]' ).value ); expect( inputValue ).toEqual( postURL ); @@ -311,4 +315,80 @@ describe( 'Links', () => { const linkHref = await page.evaluate( () => document.querySelector( '.editor-format-toolbar__link-container-value' ).href ); expect( linkHref ).toEqual( postURL ); } ); + + // Test for regressions of https://github.com/WordPress/gutenberg/issues/10496. + it( 'allows autocomplete suggestions to be navigated with the keyboard', async () => { + const titleText = 'Test post keyboard'; + const postURL = await createPostWithTitle( titleText ); + + await newPost(); + await clickBlockAppender(); + + // Now in a new post and try to create a link from an autocomplete suggestion using the keyboard. + await page.keyboard.type( 'This is Gutenberg' ); + await pressWithModifier( SELECT_WORD_MODIFIER_KEYS, 'ArrowLeft' ); + + // Press Cmd+K to insert a link + await pressWithModifier( META_KEY, 'K' ); + + // Wait for the URL field to auto-focus + await waitForAutoFocus(); + + await page.keyboard.type( titleText ); + await page.waitForSelector( '.editor-url-input__suggestion' ); + const autocompleteSuggestions = await page.$x( `//*[contains(@class, "editor-url-input__suggestion")]//button[contains(text(), '${ titleText }')]` ); + + // Expect there to be some autocomplete suggestions. + expect( autocompleteSuggestions.length ).toBeGreaterThan( 0 ); + + // Expect the the first suggestion to be selected when pressing the down arrow. + await page.keyboard.press( 'ArrowDown' ); + const isSelected = await page.evaluate( () => document.querySelector( '.editor-url-input__suggestion' ).getAttribute( 'aria-selected' ) ); + expect( isSelected ).toBe( 'true' ); + + // Expect the link to apply correctly when pressing Enter. + // Note - have avoided using snapshots here since the link url can't be determined ahead of time. + await page.keyboard.press( 'Enter' ); + const linkHref = await page.evaluate( () => document.querySelector( '.editor-format-toolbar__link-container-value' ).href ); + expect( linkHref ).toEqual( postURL ); + } ); + + it( 'allows use of escape key to dismiss the url popover', async () => { + const titleText = 'Test post escape'; + await createPostWithTitle( titleText ); + + await newPost(); + await clickBlockAppender(); + + // Now in a new post and try to create a link from an autocomplete suggestion using the keyboard. + await page.keyboard.type( 'This is Gutenberg' ); + await pressWithModifier( SELECT_WORD_MODIFIER_KEYS, 'ArrowLeft' ); + + // Press Cmd+K to insert a link + await pressWithModifier( META_KEY, 'K' ); + + // Wait for the URL field to auto-focus + await waitForAutoFocus(); + expect( await page.$( '.editor-url-popover' ) ).not.toBeNull(); + + // Trigger the autocomplete suggestion list and select the first suggestion. + await page.keyboard.type( titleText ); + await page.waitForSelector( '.editor-url-input__suggestion' ); + await page.keyboard.press( 'ArrowDown' ); + + // Expect the the escape key to dismiss the popover when the autocomplete suggestion list is open. + await page.keyboard.press( 'Escape' ); + expect( await page.$( '.editor-url-popover' ) ).toBeNull(); + + // Press Cmd+K to insert a link + await pressWithModifier( META_KEY, 'K' ); + + // Wait for the URL field to auto-focus + await waitForAutoFocus(); + expect( await page.$( '.editor-url-popover' ) ).not.toBeNull(); + + // Expect the the escape key to dismiss the popover normally. + await page.keyboard.press( 'Escape' ); + expect( await page.$( '.editor-url-popover' ) ).toBeNull(); + } ); } ); From 1dfae320ec3147ee3fc50674b66b37ed3f7a52a1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber Date: Thu, 18 Oct 2018 01:46:20 -0700 Subject: [PATCH 006/121] Update REST Search controller to use 'wp/v2' namespace (#10670) * Update REST Search controller to use 'wp/v2' namespace * Docs: Update REST API url --- lib/class-wp-rest-search-controller.php | 2 +- .../editor/src/components/url-input/README.md | 4 ++-- .../editor/src/components/url-input/index.js | 2 +- phpunit/class-rest-search-controller-test.php | 16 ++++++++-------- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/class-wp-rest-search-controller.php b/lib/class-wp-rest-search-controller.php index 2dca5b82abc2e..69776c5a7be34 100644 --- a/lib/class-wp-rest-search-controller.php +++ b/lib/class-wp-rest-search-controller.php @@ -62,7 +62,7 @@ class WP_REST_Search_Controller extends WP_REST_Controller { * handler instance must extend the `WP_REST_Search_Handler` class. */ public function __construct( array $search_handlers ) { - $this->namespace = 'gutenberg/v1'; + $this->namespace = 'wp/v2'; $this->rest_base = 'search'; foreach ( $search_handlers as $search_handler ) { diff --git a/packages/editor/src/components/url-input/README.md b/packages/editor/src/components/url-input/README.md index 4273b9978fcd9..19b67bf452b5e 100644 --- a/packages/editor/src/components/url-input/README.md +++ b/packages/editor/src/components/url-input/README.md @@ -22,7 +22,7 @@ Render a URL input button that pops up an input to search for and select a post "_links": { "self": [ { "embeddable": true, "href": "https://example.com/wp-json/wp/v2/pages/1" } ], "about": [ { "href": "https://example.com/wp-json/wp/v2/types/page" } ], - "collection": [ { "href": "https://example.com/wp-json/gutenberg/v1/search" } ] + "collection": [ { "href": "https://example.com/wp-json/wp/v2/search" } ] } } ``` @@ -120,7 +120,7 @@ Renders the URL input field used by the `URLInputButton` component. It can be us "_links": { "self": [ { "embeddable": true, "href": "https://example.com/wp-json/wp/v2/pages/1" } ], "about": [ { "href": "https://example.com/wp-json/wp/v2/types/page" } ], - "collection": [ { "href": "https://example.com/wp-json/gutenberg/v1/search" } ] + "collection": [ { "href": "https://example.com/wp-json/wp/v2/search" } ] } } ``` diff --git a/packages/editor/src/components/url-input/index.js b/packages/editor/src/components/url-input/index.js index b3d14eaeb9f10..23762991cddcf 100644 --- a/packages/editor/src/components/url-input/index.js +++ b/packages/editor/src/components/url-input/index.js @@ -86,7 +86,7 @@ class URLInput extends Component { } ); const request = apiFetch( { - path: addQueryArgs( '/gutenberg/v1/search', { + path: addQueryArgs( '/wp/v2/search', { search: value, per_page: 20, type: 'post', diff --git a/phpunit/class-rest-search-controller-test.php b/phpunit/class-rest-search-controller-test.php index 9bd8ab687f58c..26649037e8ff2 100644 --- a/phpunit/class-rest-search-controller-test.php +++ b/phpunit/class-rest-search-controller-test.php @@ -82,8 +82,8 @@ public static function wpTearDownAfterClass() { public function test_register_routes() { $routes = rest_get_server()->get_routes(); - $this->assertArrayHasKey( '/gutenberg/v1/search', $routes ); - $this->assertCount( 1, $routes['/gutenberg/v1/search'] ); + $this->assertArrayHasKey( '/wp/v2/search', $routes ); + $this->assertCount( 1, $routes['/wp/v2/search'] ); } /** @@ -291,7 +291,7 @@ public function test_get_items_search_for_foocontent() { */ public function test_get_item() { /** The search controller does not allow getting individual item content */ - $request = new WP_REST_Request( 'GET', '/gutenberg/v1/search' . self::$my_title_post_ids[0] ); + $request = new WP_REST_Request( 'GET', '/wp/v2/search' . self::$my_title_post_ids[0] ); $response = rest_get_server()->dispatch( $request ); $this->assertEquals( 404, $response->get_status() ); } @@ -301,7 +301,7 @@ public function test_get_item() { */ public function test_create_item() { /** The search controller does not allow creating content */ - $request = new WP_REST_Request( 'POST', '/gutenberg/v1/search' ); + $request = new WP_REST_Request( 'POST', '/wp/v2/search' ); $response = rest_get_server()->dispatch( $request ); $this->assertEquals( 404, $response->get_status() ); } @@ -311,7 +311,7 @@ public function test_create_item() { */ public function test_update_item() { /** The search controller does not allow upading content */ - $request = new WP_REST_Request( 'POST', '/gutenberg/v1/search' . self::$my_title_post_ids[0] ); + $request = new WP_REST_Request( 'POST', '/wp/v2/search' . self::$my_title_post_ids[0] ); $response = rest_get_server()->dispatch( $request ); $this->assertEquals( 404, $response->get_status() ); } @@ -321,7 +321,7 @@ public function test_update_item() { */ public function test_delete_item() { /** The search controller does not allow deleting content */ - $request = new WP_REST_Request( 'DELETE', '/gutenberg/v1/search' . self::$my_title_post_ids[0] ); + $request = new WP_REST_Request( 'DELETE', '/wp/v2/search' . self::$my_title_post_ids[0] ); $response = rest_get_server()->dispatch( $request ); $this->assertEquals( 404, $response->get_status() ); } @@ -377,7 +377,7 @@ public function test_prepare_item_limit_fields() { * Tests the item schema is correct. */ public function test_get_item_schema() { - $request = new WP_REST_Request( 'OPTIONS', '/gutenberg/v1/search' ); + $request = new WP_REST_Request( 'OPTIONS', '/wp/v2/search' ); $response = rest_get_server()->dispatch( $request ); $data = $response->get_data(); $properties = $data['schema']['properties']; @@ -510,7 +510,7 @@ private function do_request_with_params( $params = array(), $method = 'GET' ) { * Get a REST request object for given parameters. */ private function get_request( $params = array(), $method = 'GET' ) { - $request = new WP_REST_Request( $method, '/gutenberg/v1/search' ); + $request = new WP_REST_Request( $method, '/wp/v2/search' ); foreach ( $params as $param => $value ) { $request->set_param( $param, $value ); From a0e3ee5f31bc565cd36da0be6a911bc167d0d596 Mon Sep 17 00:00:00 2001 From: Joen Asmussen Date: Thu, 18 Oct 2018 11:02:40 +0200 Subject: [PATCH 007/121] Polish tertiary actions, switches, save state (#10552) * Polish Save Draft/Switch to Draft area * Use a Button for Trash button * Polish the toggles. --- packages/components/src/button/index.js | 2 + packages/components/src/button/style.scss | 24 ++++++++++++ .../components/src/form-toggle/style.scss | 26 ++++++------- .../components/src/toggle-control/style.scss | 10 ++++- .../src/components/header/style.scss | 1 - .../src/components/post-saved-state/index.js | 39 ++++++++++++++++--- .../components/post-saved-state/style.scss | 20 ++++++++-- .../test/__snapshots__/index.js.snap | 11 ++++++ .../components/post-saved-state/test/index.js | 6 ++- .../post-switch-to-draft-button/index.js | 2 +- .../editor/src/components/post-trash/index.js | 5 +-- .../src/components/post-trash/style.scss | 14 ++----- 12 files changed, 120 insertions(+), 40 deletions(-) diff --git a/packages/components/src/button/index.js b/packages/components/src/button/index.js index c04a9aa5276dd..3d6f9a2cb251c 100644 --- a/packages/components/src/button/index.js +++ b/packages/components/src/button/index.js @@ -15,6 +15,7 @@ export function Button( props, ref ) { isPrimary, isLarge, isSmall, + isTertiary, isToggled, isBusy, isDefault, @@ -31,6 +32,7 @@ export function Button( props, ref ) { 'is-primary': isPrimary, 'is-large': isLarge, 'is-small': isSmall, + 'is-tertiary': isTertiary, 'is-toggled': isToggled, 'is-busy': isBusy, 'is-link': isLink, diff --git a/packages/components/src/button/style.scss b/packages/components/src/button/style.scss index 23be7378bf4a6..6ee83ef41edca 100644 --- a/packages/components/src/button/style.scss +++ b/packages/components/src/button/style.scss @@ -191,6 +191,30 @@ padding: 0 8px 1px; font-size: 11px; } + + // Buttons that are text-based. + &.is-tertiary { + color: theme(outlines); + + .dashicon { + display: inline-block; + flex: 0 0 auto; + } + + // Ensure that even SVG icons that don't include the .dashicon class are colored. + svg { + fill: currentColor; + outline: none; + } + + &:active:focus:enabled { + box-shadow: none; + } + + &:not(:disabled):not([aria-disabled="true"]):not(.is-default):hover { + color: color(theme(outlines) shade(25%)); + } + } } @keyframes components-button__busy-animation { diff --git a/packages/components/src/form-toggle/style.scss b/packages/components/src/form-toggle/style.scss index 4a92b0f67fe32..fe66e3455adf0 100644 --- a/packages/components/src/form-toggle/style.scss +++ b/packages/components/src/form-toggle/style.scss @@ -5,7 +5,7 @@ $toggle-border-width: 2px; .components-form-toggle { position: relative; - // On/Off icon indicators + // On/Off icon indicators. .components-form-toggle__on, .components-form-toggle__off { position: absolute; @@ -19,10 +19,10 @@ $toggle-border-width: 2px; } .components-form-toggle__on { - left: $toggle-border-width * 3 + 2px; // indent 2px extra because icon is thinner + left: $toggle-border-width * 3 + 2px; // Indent 2px extra because icon is thinner. } - // unchecked state + // Unchecked state. .components-form-toggle__track { content: ""; display: inline-block; @@ -45,7 +45,7 @@ $toggle-border-width: 2px; border-radius: 50%; transition: 0.1s transform ease; background-color: $dark-gray-300; - border: 5px solid $dark-gray-300; // has explicit border to act as a fill in Windows High Contrast Mode + border: 5px solid $dark-gray-300; // Has explicit border to act as a fill in Windows High Contrast Mode. } &:hover { @@ -55,7 +55,7 @@ $toggle-border-width: 2px; .components-form-toggle__thumb { background-color: $dark-gray-500; - border: 5px solid $dark-gray-300; // has explicit border to act as a fill in Windows High Contrast Mode + border: 5px solid $dark-gray-300; // Has explicit border to act as a fill in Windows High Contrast Mode. } .components-form-toggle__off { @@ -67,7 +67,7 @@ $toggle-border-width: 2px; &.is-checked .components-form-toggle__track { background-color: theme(toggle); border: $toggle-border-width solid theme(toggle); - border: #{ $toggle-height / 2 } solid transparent; // expand the border to fake a solid in Windows High Contrast Mode + border: #{ $toggle-height / 2 } solid transparent; // Expand the border to fake a solid in Windows High Contrast Mode. } &__input:focus + .components-form-toggle__track { @@ -77,7 +77,7 @@ $toggle-border-width: 2px; &.is-checked { .components-form-toggle__thumb { background-color: $white; - border-width: 0; // zero out the border color to make the thumb invisible in Windows High Contrast Mode + border-width: 0; // Zero out the border color to make the thumb invisible in Windows High Contrast Mode. transform: translateX($toggle-width - ($toggle-border-width * 4) - ($toggle-height - ($toggle-border-width * 4))); } @@ -100,20 +100,20 @@ $toggle-border-width: 2px; z-index: z-index(".components-form-toggle__input"); } -// Ensure on indicator works in normal and Windows high contrast mode both +// Ensure on indicator works in normal and Windows high contrast mode both. .components-form-toggle .components-form-toggle__on { - // outlines show up in windows high contrast mode + // Outlines show up in windows high contrast mode. outline: $border-width solid transparent; outline-offset: -1px; - // this colors the indicator black, then inverts it for normal mode + // This colors the indicator black, then inverts it for normal mode. border: $border-width solid $black; - filter: invert(100%) contrast(500%); // this makes the icon white for normal mode, and it makes it dark blue in Windows High Contrast Mode + filter: invert(100%) contrast(500%); // This makes the icon white for normal mode, and it makes it dark blue in Windows High Contrast Mode. } @supports (-ms-high-contrast-adjust: auto) { - // Edge stacks outlines on top of the SVG itself, and when showing them in high contrast mode it means they get inverted again - // Therefore, show a different style for the on indicator only in Edge and IE11 + // Edge stacks outlines on top of the SVG itself, and when showing them in high contrast mode it means they get inverted again. + // Therefore, show a different style for the on indicator only in Edge and IE11. .components-form-toggle .components-form-toggle__on { filter: none; border: $border-width solid $white; diff --git a/packages/components/src/toggle-control/style.scss b/packages/components/src/toggle-control/style.scss index b425b7b571392..c9489553d6720 100644 --- a/packages/components/src/toggle-control/style.scss +++ b/packages/components/src/toggle-control/style.scss @@ -1,4 +1,12 @@ .components-toggle-control .components-base-control__field { display: flex; - justify-content: space-between; + margin-bottom: $grid-size-small * 3; + + .components-base-control__label { + order: 1; + } + + .components-form-toggle { + margin-right: $grid-size-large; + } } diff --git a/packages/edit-post/src/components/header/style.scss b/packages/edit-post/src/components/header/style.scss index bf3b689b56c43..a1f659231b077 100644 --- a/packages/edit-post/src/components/header/style.scss +++ b/packages/edit-post/src/components/header/style.scss @@ -94,7 +94,6 @@ background: $dark-gray-500; } - &.editor-post-switch-to-draft, &.editor-post-preview, &.editor-post-publish-button, &.editor-post-publish-panel__toggle { diff --git a/packages/editor/src/components/post-saved-state/index.js b/packages/editor/src/components/post-saved-state/index.js index dd822087b0581..21b047c5f1079 100644 --- a/packages/editor/src/components/post-saved-state/index.js +++ b/packages/editor/src/components/post-saved-state/index.js @@ -8,11 +8,12 @@ import { get } from 'lodash'; * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { Dashicon, IconButton } from '@wordpress/components'; +import { Dashicon, Button, IconButton } from '@wordpress/components'; import { Component } from '@wordpress/element'; import { withSelect, withDispatch } from '@wordpress/data'; import { displayShortcut } from '@wordpress/keycodes'; import { withSafeTimeout, compose } from '@wordpress/compose'; +import { withViewportMatch } from '@wordpress/viewport'; /** * Internal dependencies @@ -42,7 +43,19 @@ export class PostSavedState extends Component { } render() { - const { post, isNew, isScheduled, isPublished, isDirty, isSaving, isSaveable, onSave, isAutosaving, isPending } = this.props; + const { + post, + isNew, + isScheduled, + isPublished, + isDirty, + isSaving, + isSaveable, + onSave, + isAutosaving, + isPending, + isLargeViewport, + } = this.props; const { forceSavedMessage } = this.state; const hasPublishAction = get( post, [ '_links', 'wp:action-publish' ], false ); if ( isSaving ) { @@ -84,15 +97,28 @@ export class PostSavedState extends Component { return null; } + const label = isPending ? __( 'Save as Pending' ) : __( 'Save Draft' ); + if ( ! isLargeViewport ) { + return ( + + ); + } + return ( - - { isPending ? __( 'Save as Pending' ) : __( 'Save Draft' ) } - + { label } + ); } } @@ -126,4 +152,5 @@ export default compose( [ onSave: dispatch( 'core/editor' ).savePost, } ) ), withSafeTimeout, + withViewportMatch( { isLargeViewport: 'medium' } ), ] )( PostSavedState ); diff --git a/packages/editor/src/components/post-saved-state/style.scss b/packages/editor/src/components/post-saved-state/style.scss index 6823668be51a1..6ac4bc3fca945 100644 --- a/packages/editor/src/components/post-saved-state/style.scss +++ b/packages/editor/src/components/post-saved-state/style.scss @@ -1,7 +1,7 @@ .editor-post-saved-state { display: flex; align-items: center; - color: $dark-gray-500; + color: $light-gray-900; // Doesn't need to meet AA because button is disabled and it's supporting text. overflow: hidden; &.is-saving { @@ -14,11 +14,18 @@ } } +.editor-post-saved-state { + width: $icon-button-size - 8px; + + @include break-small() { + width: auto; + } +} + .editor-post-saved-state, .editor-post-save-draft { white-space: nowrap; padding: 8px 4px; - width: $icon-button-size - 8px; .dashicon { margin-right: 8px; @@ -26,7 +33,6 @@ @include break-small() { padding: 8px; - width: auto; text-indent: inherit; .dashicon { @@ -34,3 +40,11 @@ } } } + +.editor-post-save-draft { + @include break-small() { + .dashicon { + display: none; + } + } +} diff --git a/packages/editor/src/components/post-saved-state/test/__snapshots__/index.js.snap b/packages/editor/src/components/post-saved-state/test/__snapshots__/index.js.snap index afcc69e633bdc..a36dbb35124ef 100644 --- a/packages/editor/src/components/post-saved-state/test/__snapshots__/index.js.snap +++ b/packages/editor/src/components/post-saved-state/test/__snapshots__/index.js.snap @@ -1,3 +1,14 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`PostSavedState returns a switch to draft link if the post is published 1`] = ``; + +exports[`PostSavedState should return Save button if edits to be saved 1`] = ` +<[object Object] + className="editor-post-save-draft" + isTertiary={true} + onClick={[MockFunction]} + shortcut="Ctrl+S" +> + Save Draft + +`; diff --git a/packages/editor/src/components/post-saved-state/test/index.js b/packages/editor/src/components/post-saved-state/test/index.js index 2e49f2db8c061..25e60154997a2 100644 --- a/packages/editor/src/components/post-saved-state/test/index.js +++ b/packages/editor/src/components/post-saved-state/test/index.js @@ -60,10 +60,12 @@ describe( 'PostSavedState', () => { isDirty={ true } isSaving={ false } isSaveable={ true } - onSave={ saveSpy } /> + isLargeViewport + onSave={ saveSpy } + /> ); - expect( wrapper.name() ).toBe( 'IconButton' ); + expect( wrapper ).toMatchSnapshot(); wrapper.simulate( 'click' ); expect( saveSpy ).toHaveBeenCalled(); } ); diff --git a/packages/editor/src/components/post-switch-to-draft-button/index.js b/packages/editor/src/components/post-switch-to-draft-button/index.js index 93895cb831f54..155f5711cf5e8 100644 --- a/packages/editor/src/components/post-switch-to-draft-button/index.js +++ b/packages/editor/src/components/post-switch-to-draft-button/index.js @@ -27,9 +27,9 @@ function PostSwitchToDraftButton( { isSaving, isPublished, isScheduled, onClick return ( diff --git a/packages/editor/src/components/post-trash/index.js b/packages/editor/src/components/post-trash/index.js index 70567566bd3f6..119afd59d3a0d 100644 --- a/packages/editor/src/components/post-trash/index.js +++ b/packages/editor/src/components/post-trash/index.js @@ -2,7 +2,7 @@ * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { Button, Dashicon } from '@wordpress/components'; +import { Button } from '@wordpress/components'; import { withSelect, withDispatch } from '@wordpress/data'; import { compose } from '@wordpress/compose'; @@ -14,9 +14,8 @@ function PostTrash( { isNew, postId, postType, ...props } ) { const onClick = () => props.trashPost( postId, postType ); return ( - ); } diff --git a/packages/editor/src/components/post-trash/style.scss b/packages/editor/src/components/post-trash/style.scss index da058d224bcdb..2e0dfed15d7d3 100644 --- a/packages/editor/src/components/post-trash/style.scss +++ b/packages/editor/src/components/post-trash/style.scss @@ -1,16 +1,10 @@ .editor-post-trash.components-button { - margin-left: auto !important; - text-decoration: underline; - color: #a00; - - .dashicon { - display: inline-block; - vertical-align: middle; - margin: -3px -4px 0 10px; - } + width: 100%; + color: darken($alert-red, 10%); + justify-content: center; &:hover, &:focus { - color: #dc3232; + color: darken($alert-red, 15%); } } From 73ce8fd222e9655ce52406827e98697208c3cbbd Mon Sep 17 00:00:00 2001 From: Jorge Date: Thu, 18 Oct 2018 10:12:15 +0100 Subject: [PATCH 008/121] Fix: Font size default classes. (#10719) --- packages/block-library/src/style.scss | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/style.scss b/packages/block-library/src/style.scss index 8ca793de2c055..fc84d096ccca3 100644 --- a/packages/block-library/src/style.scss +++ b/packages/block-library/src/style.scss @@ -113,7 +113,12 @@ font-size: 13px; } -.has-regular-font-size { +.has-regular-font-size, // not used now, kept because of backward compatibility. +.has-normal-font-size { + font-size: 16px; +} + +.has-medium-font-size { font-size: 20px; } @@ -121,6 +126,7 @@ font-size: 36px; } -.has-larger-font-size { +.has-larger-font-size, // not used now, kept because of backward compatibility. +.has-huge-font-size, { font-size: 42px; } From 4ba27ff4d020d3fef4a2776e302f40a48bc826b4 Mon Sep 17 00:00:00 2001 From: Joen Asmussen Date: Thu, 18 Oct 2018 14:21:14 +0200 Subject: [PATCH 009/121] Columns Block: Make responsive, make editor and theme match (#10541) * Add basic responsiveness. * Refactor columns metrics. Level the playing field in editor and frontend. * Add space between colums. Fixes #7818. Fixes #6048. * Remove "beta" designation from columns block. * Columns block: Fix column width when editing * Column block: Improve padding for the first and last item in a row * Tests: Rename Columns block name also in e2e tests --- .../block-library/src/columns/editor.scss | 91 +++++++++++++++++-- packages/block-library/src/columns/index.js | 9 +- packages/block-library/src/columns/style.scss | 42 +++++++++ .../specs/block-hierarchy-navigation.test.js | 6 +- 4 files changed, 128 insertions(+), 20 deletions(-) diff --git a/packages/block-library/src/columns/editor.scss b/packages/block-library/src/columns/editor.scss index 7eda4c25be534..ebe614483c4a5 100644 --- a/packages/block-library/src/columns/editor.scss +++ b/packages/block-library/src/columns/editor.scss @@ -6,13 +6,6 @@ margin-left: 0; margin-right: 0; - &:first-child { - margin-left: -$block-padding; - } - &:last-child { - margin-right: -$block-padding; - } - // This max-width is used to constrain the main editor column, it should not cascade into columns .editor-block-list__block { max-width: none; @@ -47,14 +40,92 @@ > .editor-inner-blocks > .editor-block-list__layout { display: flex; + // Responsiveness: Allow wrapping on mobile. + flex-wrap: wrap; + + @include break-medium() { + flex-wrap: nowrap; + } + > [data-type="core/column"] { display: flex; flex-direction: column; flex: 1; - width: 0; - .editor-block-list__block-edit { - flex-basis: 100%; + // The Column block is a child of the Columns block and is mostly a passthrough container. + // Therefore it shouldn't add additional paddings and margins, so we reset these, and compensate for margins. + // @todo In the future, if a passthrough feature lands, it would be good to apply these rules to such an element in a more generic way. + margin-top: -$block-padding; + margin-bottom: -$block-padding; + + // On mobile, only a single column is shown, so match adjacent block paddings. + padding-left: 0; + padding-right: 0; + margin-left: -$block-padding; + margin-right: -$block-padding; + @include break-small () { + padding-left: $block-padding; + padding-right: $block-padding; + margin-right: inherit; + // Every .editor-block-list__block has auto-left/right margins, which centers columns. + // Since they aren't centered on the front-end, we explicitly set a zero left margin here. + margin-left: 0; + } + + @include break-small() { + > .editor-block-contextual-toolbar { + top: $block-toolbar-height - $border-width; + transform: translateY(-$block-toolbar-height - $border-width); + margin-left: -$block-padding - $block-padding - $border-width; + } + + > .editor-block-list__block-edit::before { + top: 0; + right: 0; + bottom: 0; + left: 0; + } + + > .editor-block-list__breadcrumb { + margin-right: -$block-padding - $border-width; + } + } + + // Responsiveness: Show at most one columns on mobile. + flex-basis: 100%; + + // Beyond mobile, allow 2 columns. + @include break-small() { + flex-basis: 50%; + flex-grow: 0; + } + + // Add space between columns. Themes can customize this if they wish to work differently. + // This has to match the same padding applied in style.scss. + // Only apply this beyond the mobile breakpoint, as there's only a single column on mobile. + @include break-small() { + > .editor-block-list__block-edit { + padding-left: $grid-size-large; + padding-right: $grid-size-large; + } + + &:nth-child(odd) > .editor-block-list__block-edit { + padding-left: 0; + } + + &:nth-child(even) > .editor-block-list__block-edit { + padding-right: 0; + } + } + + @include break-medium() { + &:not(:first-child) > .editor-block-list__block-edit { + padding-left: $grid-size-large; + } + + &:not(:last-child) > .editor-block-list__block-edit { + padding-right: $grid-size-large; + } } } } diff --git a/packages/block-library/src/columns/index.js b/packages/block-library/src/columns/index.js index 5474cfae1e07a..bf299fc3b5d90 100644 --- a/packages/block-library/src/columns/index.js +++ b/packages/block-library/src/columns/index.js @@ -8,7 +8,7 @@ import memoize from 'memize'; /** * WordPress dependencies */ -import { __, sprintf } from '@wordpress/i18n'; +import { __ } from '@wordpress/i18n'; import { PanelBody, RangeControl } from '@wordpress/components'; import { Fragment } from '@wordpress/element'; import { createBlock } from '@wordpress/blocks'; @@ -42,12 +42,7 @@ const getColumnsTemplate = memoize( ( columns ) => { export const name = 'core/columns'; export const settings = { - title: sprintf( - /* translators: Block title modifier */ - __( '%1$s (%2$s)' ), - __( 'Columns' ), - __( 'beta' ) - ), + title: __( 'Columns' ), icon: , diff --git a/packages/block-library/src/columns/style.scss b/packages/block-library/src/columns/style.scss index 9e234b17202da..6a7aed4971d8b 100644 --- a/packages/block-library/src/columns/style.scss +++ b/packages/block-library/src/columns/style.scss @@ -1,7 +1,49 @@ .wp-block-columns { display: flex; + + // Responsiveness: Allow wrapping on mobile. + flex-wrap: wrap; + + @include break-medium() { + flex-wrap: nowrap; + } } .wp-block-column { flex: 1; + margin-bottom: 1em; + + // Responsiveness: Show at most one columns on mobile. + flex-basis: 100%; + + // Beyond mobile, allow 2 columns. + @include break-small() { + flex-basis: 50%; + flex-grow: 0; + } + + // Add space between columns. Themes can customize this if they wish to work differently. + // Only apply this beyond the mobile breakpoint, as there's only a single column on mobile. + @include break-small() { + padding-left: $grid-size-large; + padding-right: $grid-size-large; + + &:nth-child(odd) { + padding-left: 0; + } + + &:nth-child(even) { + padding-right: 0; + } + } + + @include break-medium() { + &:not(:first-child) { + padding-left: $grid-size-large; + } + + &:not(:last-child) { + padding-right: $grid-size-large; + } + } } diff --git a/test/e2e/specs/block-hierarchy-navigation.test.js b/test/e2e/specs/block-hierarchy-navigation.test.js index adabb4349353c..4fa9d59f7c856 100644 --- a/test/e2e/specs/block-hierarchy-navigation.test.js +++ b/test/e2e/specs/block-hierarchy-navigation.test.js @@ -21,14 +21,14 @@ describe( 'Navigating the block hierarchy', () => { } ); it( 'should navigate using the block hierarchy dropdown menu', async () => { - await insertBlock( 'Columns (beta)' ); + await insertBlock( 'Columns' ); // Add a paragraph in the first column. await page.keyboard.type( 'First column' ); // Navigate to the columns blocks. await page.click( '[aria-label="Block Navigation"]' ); - const columnsBlockMenuItem = ( await page.$x( "//button[contains(@class,'editor-block-navigation__item') and contains(text(), 'Columns (beta)')]" ) )[ 0 ]; + const columnsBlockMenuItem = ( await page.$x( "//button[contains(@class,'editor-block-navigation__item') and contains(text(), 'Columns')]" ) )[ 0 ]; await columnsBlockMenuItem.click(); // Tweak the columns count. @@ -53,7 +53,7 @@ describe( 'Navigating the block hierarchy', () => { } ); it( 'should navigate block hierarchy using only the keyboard', async () => { - await insertBlock( 'Columns (beta)' ); + await insertBlock( 'Columns' ); // Add a paragraph in the first column. await page.keyboard.type( 'First column' ); From 7316f165f0582d62c2d10a6241187c915c2c9dfd Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 18 Oct 2018 13:55:34 +0100 Subject: [PATCH 010/121] Remove 4.1 deprecated features (#10732) --- docs/data/data-core-editor.md | 4 ---- packages/editor/CHANGELOG.md | 6 +++++- packages/editor/src/store/actions.js | 20 -------------------- packages/editor/src/store/effects.js | 13 ------------- 4 files changed, 5 insertions(+), 38 deletions(-) diff --git a/docs/data/data-core-editor.md b/docs/data/data-core-editor.md index fc156bf39b237..fd3e2fb5e376d 100644 --- a/docs/data/data-core-editor.md +++ b/docs/data/data-core-editor.md @@ -1545,10 +1545,6 @@ Returns an action object resetting the template validity. * isValid: template validity flag. -### checkTemplateValidity - -Returns an action object to check the template validity. - ### synchronizeTemplate Returns an action object synchronize the template with the list of blocks diff --git a/packages/editor/CHANGELOG.md b/packages/editor/CHANGELOG.md index d82d8b209de0a..239f2262b15ff 100644 --- a/packages/editor/CHANGELOG.md +++ b/packages/editor/CHANGELOG.md @@ -1,4 +1,8 @@ -## 4.1.0 (Unreleased) +## 5.0.0 (Unreleased) + +### Breaking Changes + +- The `checkTemplateValidity` action has been removed. Validity is verified automatically upon block reset. ### Deprecations diff --git a/packages/editor/src/store/actions.js b/packages/editor/src/store/actions.js index f8eb4cdb36ec8..2c36c35871b56 100644 --- a/packages/editor/src/store/actions.js +++ b/packages/editor/src/store/actions.js @@ -11,7 +11,6 @@ import { getDefaultBlockName, createBlock, } from '@wordpress/blocks'; -import deprecated from '@wordpress/deprecated'; /** * Returns an action object used in signalling that editor has initialized with @@ -368,25 +367,6 @@ export function setTemplateValidity( isValid ) { }; } -/** - * Returns an action object to check the template validity. - * - * @return {Object} Action object. - */ -export function checkTemplateValidity() { - // TODO: Hello future deprecation remover. Please ensure also to remove all - // references to CHECK_TEMPLATE_VALIDITY, notably its effect handler. - deprecated( 'checkTemplateValidity action (`core/editor`)', { - version: '4.1', - plugin: 'Gutenberg', - hint: 'Validity is verified automatically upon block reset.', - } ); - - return { - type: 'CHECK_TEMPLATE_VALIDITY', - }; -} - /** * Returns an action object synchronize the template with the list of blocks * diff --git a/packages/editor/src/store/effects.js b/packages/editor/src/store/effects.js index cfda318c49599..78bb1c2538db2 100644 --- a/packages/editor/src/store/effects.js +++ b/packages/editor/src/store/effects.js @@ -261,19 +261,6 @@ export default { return resetBlocks( updatedBlockList ); }, - CHECK_TEMPLATE_VALIDITY( action, { getState } ) { - const state = getState(); - const blocks = getBlocks( state ); - const template = getTemplate( state ); - const templateLock = getTemplateLock( state ); - const isValid = ( - ! template || - templateLock !== 'all' || - doBlocksMatchTemplate( blocks, template ) - ); - - return setTemplateValidity( isValid ); - }, FETCH_REUSABLE_BLOCKS: ( action, store ) => { fetchReusableBlocks( action, store ); }, From c3501c7bb70093495d9977cf37c3ef71112e9a38 Mon Sep 17 00:00:00 2001 From: Jorge Date: Thu, 18 Oct 2018 15:07:50 +0100 Subject: [PATCH 011/121] Rename cover image to cover; Add video in cover block; (#10659) ## Description This commit renames cover image block into cover and adds video support o cover. The approach used to rename the block is the same used for the move of core/text to core/paragraph. A change in api/parser.js. This approach may be seen as a temporary solution until a final approach to this use case exists, and we feel comfortable in exposing an API for this. Transformations were updated, and a video transform was added. ## How has this been tested? Verify the cover block still works as expected, containing the same functionality the existed in the cover image. Verify it is possible to set video as background in the cover block. --- assets/stylesheets/_z-index.scss | 2 + .../src/{cover-image => cover}/editor.scss | 3 +- .../src/{cover-image => cover}/index.js | 193 +++++++++++++++--- .../src/{cover-image => cover}/style.scss | 24 ++- .../test/__snapshots__/index.js.snap | 10 +- .../src/{cover-image => cover}/test/index.js | 2 +- packages/block-library/src/editor.scss | 2 +- packages/block-library/src/index.js | 4 +- packages/block-library/src/style.scss | 2 +- packages/blocks/src/api/parser.js | 5 + post-content.php | 6 +- .../fixtures/core__cover-image.html | 5 - .../fixtures/core__cover-image.json | 16 -- .../fixtures/core__cover-image.parsed.json | 17 -- .../core__cover-image.serialized.html | 3 - .../full-content/fixtures/core__cover.html | 5 + .../full-content/fixtures/core__cover.json | 17 ++ .../fixtures/core__cover.parsed.json | 17 ++ .../fixtures/core__cover.serialized.html | 3 + .../fixtures/core__cover__video-overlay.html | 6 + .../fixtures/core__cover__video-overlay.json | 18 ++ .../core__cover__video-overlay.parsed.json | 19 ++ ...core__cover__video-overlay.serialized.html | 3 + .../fixtures/core__cover__video.html | 6 + .../fixtures/core__cover__video.json | 17 ++ .../fixtures/core__cover__video.parsed.json | 18 ++ .../core__cover__video.serialized.html | 3 + 27 files changed, 341 insertions(+), 85 deletions(-) rename packages/block-library/src/{cover-image => cover}/editor.scss (93%) rename packages/block-library/src/{cover-image => cover}/index.js (61%) rename packages/block-library/src/{cover-image => cover}/style.scss (71%) rename packages/block-library/src/{cover-image => cover}/test/__snapshots__/index.js.snap (92%) rename packages/block-library/src/{cover-image => cover}/test/index.js (87%) delete mode 100644 test/integration/full-content/fixtures/core__cover-image.html delete mode 100644 test/integration/full-content/fixtures/core__cover-image.json delete mode 100644 test/integration/full-content/fixtures/core__cover-image.parsed.json delete mode 100644 test/integration/full-content/fixtures/core__cover-image.serialized.html create mode 100644 test/integration/full-content/fixtures/core__cover.html create mode 100644 test/integration/full-content/fixtures/core__cover.json create mode 100644 test/integration/full-content/fixtures/core__cover.parsed.json create mode 100644 test/integration/full-content/fixtures/core__cover.serialized.html create mode 100644 test/integration/full-content/fixtures/core__cover__video-overlay.html create mode 100644 test/integration/full-content/fixtures/core__cover__video-overlay.json create mode 100644 test/integration/full-content/fixtures/core__cover__video-overlay.parsed.json create mode 100644 test/integration/full-content/fixtures/core__cover__video-overlay.serialized.html create mode 100644 test/integration/full-content/fixtures/core__cover__video.html create mode 100644 test/integration/full-content/fixtures/core__cover__video.json create mode 100644 test/integration/full-content/fixtures/core__cover__video.parsed.json create mode 100644 test/integration/full-content/fixtures/core__cover__video.serialized.html diff --git a/assets/stylesheets/_z-index.scss b/assets/stylesheets/_z-index.scss index b9cd8c4032e0a..bcb054a4ea41b 100644 --- a/assets/stylesheets/_z-index.scss +++ b/assets/stylesheets/_z-index.scss @@ -29,6 +29,8 @@ $z-layers: ( ".edit-post-header": 30, ".block-library-button__inline-link .editor-url-input__suggestions": 6, // URL suggestions for button block above sibling inserter ".block-library-image__resize-handlers": 1, // Resize handlers above sibling inserter + ".wp-block-cover.has-background-dim::before": 1, // Overlay area inside block cover need to be higher than the video background. + ".wp-block-cover__video-background": 0, // Video background inside cover block. // Side UI active buttons ".editor-block-mover__control": 1, diff --git a/packages/block-library/src/cover-image/editor.scss b/packages/block-library/src/cover/editor.scss similarity index 93% rename from packages/block-library/src/cover-image/editor.scss rename to packages/block-library/src/cover/editor.scss index bc55badc130be..e69a8080342b1 100644 --- a/packages/block-library/src/cover-image/editor.scss +++ b/packages/block-library/src/cover/editor.scss @@ -1,4 +1,5 @@ -.wp-block-cover-image { +.wp-block-cover-image, +.wp-block-cover { .editor-rich-text__tinymce[data-is-empty="true"]::before { position: inherit; } diff --git a/packages/block-library/src/cover-image/index.js b/packages/block-library/src/cover/index.js similarity index 61% rename from packages/block-library/src/cover-image/index.js rename to packages/block-library/src/cover/index.js index 2d06ec2112283..9d9ef6f0f1c5e 100644 --- a/packages/block-library/src/cover-image/index.js +++ b/packages/block-library/src/cover/index.js @@ -58,16 +58,22 @@ const blockAttributes = { customOverlayColor: { type: 'string', }, + backgroundType: { + type: 'string', + default: 'image', + }, }; -export const name = 'core/cover-image'; +export const name = 'core/cover'; -const ALLOWED_MEDIA_TYPES = [ 'image' ]; +const ALLOWED_MEDIA_TYPES = [ 'image', 'video' ]; +const IMAGE_BACKGROUND_TYPE = 'image'; +const VIDEO_BACKGROUND_TYPE = 'video'; export const settings = { - title: __( 'Cover Image' ), + title: __( 'Cover' ), - description: __( 'Add a full-width image, and layer text over it — great for headers.' ), + description: __( 'Add a full-width image or video, and layer text over it — great for headers.' ), icon: , @@ -81,14 +87,14 @@ export const settings = { type: 'block', blocks: [ 'core/heading' ], transform: ( { content } ) => ( - createBlock( 'core/cover-image', { title: content } ) + createBlock( 'core/cover', { title: content } ) ), }, { type: 'block', blocks: [ 'core/image' ], transform: ( { caption, url, align, id } ) => ( - createBlock( 'core/cover-image', { + createBlock( 'core/cover', { title: caption, url, align, @@ -96,6 +102,19 @@ export const settings = { } ) ), }, + { + type: 'block', + blocks: [ 'core/video' ], + transform: ( { caption, src, align, id } ) => ( + createBlock( 'core/cover', { + title: caption, + url: src, + align, + id, + backgroundType: VIDEO_BACKGROUND_TYPE, + } ) + ), + }, ], to: [ { @@ -108,6 +127,9 @@ export const settings = { { type: 'block', blocks: [ 'core/image' ], + isMatch: ( { backgroundType, url } ) => { + return ! url || backgroundType === IMAGE_BACKGROUND_TYPE; + }, transform: ( { title, url, align, id } ) => ( createBlock( 'core/image', { caption: title, @@ -117,6 +139,21 @@ export const settings = { } ) ), }, + { + type: 'block', + blocks: [ 'core/video' ], + isMatch: ( { backgroundType, url } ) => { + return ! url || backgroundType === VIDEO_BACKGROUND_TYPE; + }, + transform: ( { title, url, align, id } ) => ( + createBlock( 'core/video', { + caption: title, + src: url, + id, + align, + } ) + ), + }, ], }, @@ -132,21 +169,57 @@ export const settings = { withNotices, ] )( ( { attributes, setAttributes, isSelected, className, noticeOperations, noticeUI, overlayColor, setOverlayColor } ) => { - const { url, title, align, contentAlign, id, hasParallax, dimRatio } = attributes; + const { + align, + backgroundType, + contentAlign, + dimRatio, + hasParallax, + id, + title, + url, + } = attributes; const updateAlignment = ( nextAlign ) => setAttributes( { align: nextAlign } ); - const onSelectImage = ( media ) => { + const onSelectMedia = ( media ) => { if ( ! media || ! media.url ) { setAttributes( { url: undefined, id: undefined } ); return; } - setAttributes( { url: media.url, id: media.id } ); + let mediaType; + // for media selections originated from a file upload. + if ( media.media_type ) { + if ( media.media_type === IMAGE_BACKGROUND_TYPE ) { + mediaType = IMAGE_BACKGROUND_TYPE; + } else { + // only images and videos are accepted so if the media_type is not an image we can assume it is a video. + // Videos contain the media type of 'file' in the object returned from the rest api. + mediaType = VIDEO_BACKGROUND_TYPE; + } + } else { // for media selections originated from existing files in the media library. + if ( + media.type !== IMAGE_BACKGROUND_TYPE && + media.type !== VIDEO_BACKGROUND_TYPE + ) { + return; + } + mediaType = media.type; + } + setAttributes( { + url: media.url, + id: media.id, + backgroundType: mediaType, + } ); }; const toggleParallax = () => setAttributes( { hasParallax: ! hasParallax } ); const setDimRatio = ( ratio ) => setAttributes( { dimRatio: ratio } ); const setTitle = ( newTitle ) => setAttributes( { title: newTitle } ); const style = { - ...backgroundImageStyles( url ), + ...( + backgroundType === IMAGE_BACKGROUND_TYPE ? + backgroundImageStyles( url ) : + {} + ), backgroundColor: overlayColor.color, }; @@ -177,13 +250,13 @@ export const settings = { /> ( @@ -195,12 +268,14 @@ export const settings = { { !! url && ( - - + + { IMAGE_BACKGROUND_TYPE === backgroundType && ( + + ) } - ) : __( 'Cover Image' ); + ) : __( 'Cover' ); return ( @@ -245,10 +320,11 @@ export const settings = { className={ className } labels={ { title: label, - name: __( 'an image' ), + /* translators: Fragment of the sentence: "Drag %s, upload a new one or select a file from your library." */ + name: __( 'an image or a video' ), } } - onSelect={ onSelectImage } - accept="image/*" + onSelect={ onSelectMedia } + accept="image/*,video/*" allowedTypes={ ALLOWED_MEDIA_TYPES } notices={ noticeUI } onError={ noticeOperations.createErrorNotice } @@ -265,10 +341,19 @@ export const settings = { style={ style } className={ classes } > + { VIDEO_BACKGROUND_TYPE === backgroundType && ( +

+ { ! RichText.isEmpty( title ) && ( + + ) } +
+ ); + }, + }, { attributes: { ...blockAttributes, title: { diff --git a/packages/block-library/src/cover-image/style.scss b/packages/block-library/src/cover/style.scss similarity index 71% rename from packages/block-library/src/cover-image/style.scss rename to packages/block-library/src/cover/style.scss index 723b35fdc52c7..00a3ab812ed25 100644 --- a/packages/block-library/src/cover-image/style.scss +++ b/packages/block-library/src/cover/style.scss @@ -1,4 +1,5 @@ -.wp-block-cover-image { +.wp-block-cover-image, +.wp-block-cover { position: relative; background-color: $black; background-size: cover; @@ -14,7 +15,8 @@ justify-content: flex-start; h2, - .wp-block-cover-image-text { + .wp-block-cover-image-text, + .wp-block-cover-text { margin-left: 0; text-align: left; } @@ -24,14 +26,16 @@ justify-content: flex-end; h2, - .wp-block-cover-image-text { + .wp-block-cover-image-text, + .wp-block-cover-text { margin-right: 0; text-align: right; } } h2, - .wp-block-cover-image-text { + .wp-block-cover-image-text, + .wp-block-cover-text { color: $white; font-size: 2em; line-height: 1.25; @@ -62,6 +66,7 @@ right: 0; background-color: inherit; opacity: 0.5; + z-index: z-index(".wp-block-cover.has-background-dim::before"); } @for $i from 1 through 10 { @@ -83,3 +88,14 @@ width: 100%; } } + +.wp-block-cover__video-background { + position: absolute; + top: 50%; + left: 50%; + transform: translateX(-50%) translateY(-50%); + width: 100%; + height: 100%; + z-index: z-index(".wp-block-cover__video-background"); + object-fit: fill; +} diff --git a/packages/block-library/src/cover-image/test/__snapshots__/index.js.snap b/packages/block-library/src/cover/test/__snapshots__/index.js.snap similarity index 92% rename from packages/block-library/src/cover-image/test/__snapshots__/index.js.snap rename to packages/block-library/src/cover/test/__snapshots__/index.js.snap index f6690fdae6fe9..d06c221b6e4ea 100644 --- a/packages/block-library/src/cover-image/test/__snapshots__/index.js.snap +++ b/packages/block-library/src/cover/test/__snapshots__/index.js.snap @@ -1,8 +1,8 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`core/cover-image block edit matches snapshot 1`] = ` +exports[`core/cover block edit matches snapshot 1`] = `
- Cover Image + Cover
- Drag an image, upload a new one or select a file from your library. + Drag an image or a video, upload a new one or select a file from your library.
diff --git a/packages/block-library/src/cover-image/test/index.js b/packages/block-library/src/cover/test/index.js similarity index 87% rename from packages/block-library/src/cover-image/test/index.js rename to packages/block-library/src/cover/test/index.js index ceb0bc9d5123c..a088404e7c41d 100644 --- a/packages/block-library/src/cover-image/test/index.js +++ b/packages/block-library/src/cover/test/index.js @@ -4,7 +4,7 @@ import { name, settings } from '../'; import { blockEditRender } from '../../test/helpers'; -describe( 'core/cover-image', () => { +describe( 'core/cover', () => { test( 'block edit matches snapshot', () => { const wrapper = blockEditRender( name, settings ); diff --git a/packages/block-library/src/editor.scss b/packages/block-library/src/editor.scss index 70aa75c35b7f0..58c8803144a31 100644 --- a/packages/block-library/src/editor.scss +++ b/packages/block-library/src/editor.scss @@ -4,7 +4,7 @@ @import "./categories/editor.scss"; @import "./code/editor.scss"; @import "./columns/editor.scss"; -@import "./cover-image/editor.scss"; +@import "./cover/editor.scss"; @import "./embed/editor.scss"; @import "./file/editor.scss"; @import "./classic/editor.scss"; diff --git a/packages/block-library/src/index.js b/packages/block-library/src/index.js index 470ad4aea9feb..01644d7bd20d6 100644 --- a/packages/block-library/src/index.js +++ b/packages/block-library/src/index.js @@ -24,7 +24,7 @@ import * as categories from './categories'; import * as code from './code'; import * as columns from './columns'; import * as column from './columns/column'; -import * as coverImage from './cover-image'; +import * as cover from './cover'; import * as embed from './embed'; import * as file from './file'; import * as html from './html'; @@ -69,7 +69,7 @@ export const registerCoreBlocks = () => { code, columns, column, - coverImage, + cover, embed, ...embed.common, ...embed.others, diff --git a/packages/block-library/src/style.scss b/packages/block-library/src/style.scss index fc84d096ccca3..0d18fe6895497 100644 --- a/packages/block-library/src/style.scss +++ b/packages/block-library/src/style.scss @@ -4,7 +4,7 @@ @import "./button/style.scss"; @import "./categories/style.scss"; @import "./columns/style.scss"; -@import "./cover-image/style.scss"; +@import "./cover/style.scss"; @import "./embed/style.scss"; @import "./file/style.scss"; @import "./gallery/style.scss"; diff --git a/packages/blocks/src/api/parser.js b/packages/blocks/src/api/parser.js index 496eb6ce81cb3..68cc6af5ca180 100644 --- a/packages/blocks/src/api/parser.js +++ b/packages/blocks/src/api/parser.js @@ -416,6 +416,11 @@ export function createBlockWithFallback( blockNode ) { // freeform content fallback. let name = originalName || freeformContentFallbackBlock; + // Convert 'core/cover-image' block in existing content to 'core/cover'. + if ( 'core/cover-image' === name ) { + name = 'core/cover'; + } + // Convert 'core/text' blocks in existing content to 'core/paragraph'. if ( 'core/text' === name || 'core/cover-text' === name ) { name = 'core/paragraph'; diff --git a/post-content.php b/post-content.php index 45ef6109a44d0..7dac5620a8efd 100644 --- a/post-content.php +++ b/post-content.php @@ -1,6 +1,6 @@ - -

- + +

+

pieces of content—somewhat similar to LEGO bricks—that you can move around and interact with. Move your cursor around and you’ll notice the different blocks light up with outlines and arrows. Press the arrows to reposition blocks quickly, without fearing about losing things in the process of copying and pasting.', 'gutenberg' ); ?>

diff --git a/test/integration/full-content/fixtures/core__cover-image.html b/test/integration/full-content/fixtures/core__cover-image.html deleted file mode 100644 index 86b5915701b0b..0000000000000 --- a/test/integration/full-content/fixtures/core__cover-image.html +++ /dev/null @@ -1,5 +0,0 @@ - -
-

Guten Berg!

-
- diff --git a/test/integration/full-content/fixtures/core__cover-image.json b/test/integration/full-content/fixtures/core__cover-image.json deleted file mode 100644 index 342a160d3e4de..0000000000000 --- a/test/integration/full-content/fixtures/core__cover-image.json +++ /dev/null @@ -1,16 +0,0 @@ -[ - { - "clientId": "_clientId_0", - "name": "core/cover-image", - "isValid": true, - "attributes": { - "title": "Guten Berg!", - "url": "https://cldup.com/uuUqE_dXzy.jpg", - "contentAlign": "center", - "hasParallax": false, - "dimRatio": 40 - }, - "innerBlocks": [], - "originalContent": "
\n

Guten Berg!

\n
" - } -] diff --git a/test/integration/full-content/fixtures/core__cover-image.parsed.json b/test/integration/full-content/fixtures/core__cover-image.parsed.json deleted file mode 100644 index 93bc4fbc8ddfd..0000000000000 --- a/test/integration/full-content/fixtures/core__cover-image.parsed.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "blockName": "core/cover-image", - "attrs": { - "url": "https://cldup.com/uuUqE_dXzy.jpg", - "dimRatio": 40 - }, - "innerBlocks": [], - "innerHTML": "\n
\n

Guten Berg!

\n
\n" - }, - { - "blockName": null, - "attrs": {}, - "innerBlocks": [], - "innerHTML": "\n" - } -] diff --git a/test/integration/full-content/fixtures/core__cover-image.serialized.html b/test/integration/full-content/fixtures/core__cover-image.serialized.html deleted file mode 100644 index d64692d60c8fe..0000000000000 --- a/test/integration/full-content/fixtures/core__cover-image.serialized.html +++ /dev/null @@ -1,3 +0,0 @@ - -

Guten Berg!

- diff --git a/test/integration/full-content/fixtures/core__cover.html b/test/integration/full-content/fixtures/core__cover.html new file mode 100644 index 0000000000000..ae26d922c2644 --- /dev/null +++ b/test/integration/full-content/fixtures/core__cover.html @@ -0,0 +1,5 @@ + +
+

Guten Berg!

+
+ diff --git a/test/integration/full-content/fixtures/core__cover.json b/test/integration/full-content/fixtures/core__cover.json new file mode 100644 index 0000000000000..dea09d92c11c8 --- /dev/null +++ b/test/integration/full-content/fixtures/core__cover.json @@ -0,0 +1,17 @@ +[ + { + "clientId": "_clientId_0", + "name": "core/cover", + "isValid": true, + "attributes": { + "title": "Guten Berg!", + "url": "https://cldup.com/uuUqE_dXzy.jpg", + "contentAlign": "center", + "hasParallax": false, + "dimRatio": 40, + "backgroundType": "image" + }, + "innerBlocks": [], + "originalContent": "
\n

Guten Berg!

\n
" + } +] diff --git a/test/integration/full-content/fixtures/core__cover.parsed.json b/test/integration/full-content/fixtures/core__cover.parsed.json new file mode 100644 index 0000000000000..ba371b9c5960f --- /dev/null +++ b/test/integration/full-content/fixtures/core__cover.parsed.json @@ -0,0 +1,17 @@ +[ + { + "blockName": "core/cover", + "attrs": { + "url": "https://cldup.com/uuUqE_dXzy.jpg", + "dimRatio": 40 + }, + "innerBlocks": [], + "innerHTML": "\n
\n

Guten Berg!

\n
\n" + }, + { + "blockName": null, + "attrs": {}, + "innerBlocks": [], + "innerHTML": "\n" + } +] diff --git a/test/integration/full-content/fixtures/core__cover.serialized.html b/test/integration/full-content/fixtures/core__cover.serialized.html new file mode 100644 index 0000000000000..a6d795bb56175 --- /dev/null +++ b/test/integration/full-content/fixtures/core__cover.serialized.html @@ -0,0 +1,3 @@ + +

Guten Berg!

+ diff --git a/test/integration/full-content/fixtures/core__cover__video-overlay.html b/test/integration/full-content/fixtures/core__cover__video-overlay.html new file mode 100644 index 0000000000000..2a3530954f29b --- /dev/null +++ b/test/integration/full-content/fixtures/core__cover__video-overlay.html @@ -0,0 +1,6 @@ + +
+ +

Guten Berg!

+
+ diff --git a/test/integration/full-content/fixtures/core__cover__video-overlay.json b/test/integration/full-content/fixtures/core__cover__video-overlay.json new file mode 100644 index 0000000000000..08f0de4eb4c15 --- /dev/null +++ b/test/integration/full-content/fixtures/core__cover__video-overlay.json @@ -0,0 +1,18 @@ +[ + { + "clientId": "_clientId_0", + "name": "core/cover", + "isValid": true, + "attributes": { + "title": "Guten Berg!", + "url": "data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE=", + "contentAlign": "center", + "hasParallax": false, + "dimRatio": 10, + "customOverlayColor": "#3615d9", + "backgroundType": "video" + }, + "innerBlocks": [], + "originalContent": "
\n\t\n\t

Guten Berg!

\n
" + } +] diff --git a/test/integration/full-content/fixtures/core__cover__video-overlay.parsed.json b/test/integration/full-content/fixtures/core__cover__video-overlay.parsed.json new file mode 100644 index 0000000000000..71dd6c0a0294a --- /dev/null +++ b/test/integration/full-content/fixtures/core__cover__video-overlay.parsed.json @@ -0,0 +1,19 @@ +[ + { + "blockName": "core/cover", + "attrs": { + "url": "data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE=", + "dimRatio": 10, + "customOverlayColor": "#3615d9", + "backgroundType": "video" + }, + "innerBlocks": [], + "innerHTML": "\n
\n\t\n\t

Guten Berg!

\n
\n" + }, + { + "blockName": null, + "attrs": {}, + "innerBlocks": [], + "innerHTML": "\n" + } +] diff --git a/test/integration/full-content/fixtures/core__cover__video-overlay.serialized.html b/test/integration/full-content/fixtures/core__cover__video-overlay.serialized.html new file mode 100644 index 0000000000000..14786a0f0d189 --- /dev/null +++ b/test/integration/full-content/fixtures/core__cover__video-overlay.serialized.html @@ -0,0 +1,3 @@ + +

Guten Berg!

+ diff --git a/test/integration/full-content/fixtures/core__cover__video.html b/test/integration/full-content/fixtures/core__cover__video.html new file mode 100644 index 0000000000000..0ab2fd73ccdf8 --- /dev/null +++ b/test/integration/full-content/fixtures/core__cover__video.html @@ -0,0 +1,6 @@ + +
+ +

Guten Berg!

+
+ diff --git a/test/integration/full-content/fixtures/core__cover__video.json b/test/integration/full-content/fixtures/core__cover__video.json new file mode 100644 index 0000000000000..1fa4d25d66cda --- /dev/null +++ b/test/integration/full-content/fixtures/core__cover__video.json @@ -0,0 +1,17 @@ +[ + { + "clientId": "_clientId_0", + "name": "core/cover", + "isValid": true, + "attributes": { + "title": "Guten Berg!", + "url": "data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE=", + "contentAlign": "center", + "hasParallax": false, + "dimRatio": 40, + "backgroundType": "video" + }, + "innerBlocks": [], + "originalContent": "
\n\t\n\t

Guten Berg!

\n
" + } +] diff --git a/test/integration/full-content/fixtures/core__cover__video.parsed.json b/test/integration/full-content/fixtures/core__cover__video.parsed.json new file mode 100644 index 0000000000000..218846a689b1f --- /dev/null +++ b/test/integration/full-content/fixtures/core__cover__video.parsed.json @@ -0,0 +1,18 @@ +[ + { + "blockName": "core/cover", + "attrs": { + "url": "data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE=", + "dimRatio": 40, + "backgroundType": "video" + }, + "innerBlocks": [], + "innerHTML": "\n
\n\t\n\t

Guten Berg!

\n
\n" + }, + { + "blockName": null, + "attrs": {}, + "innerBlocks": [], + "innerHTML": "\n" + } +] diff --git a/test/integration/full-content/fixtures/core__cover__video.serialized.html b/test/integration/full-content/fixtures/core__cover__video.serialized.html new file mode 100644 index 0000000000000..03398311e20f6 --- /dev/null +++ b/test/integration/full-content/fixtures/core__cover__video.serialized.html @@ -0,0 +1,3 @@ + +

Guten Berg!

+ From 1e823485d9dff26aac093058577daf2ed4702201 Mon Sep 17 00:00:00 2001 From: Danilo Ercoli Date: Thu, 18 Oct 2018 17:10:48 +0200 Subject: [PATCH 012/121] Handle the case when the split occurs at the trailing or leading edge of the field. (#10737) --- .../src/components/rich-text/index.native.js | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/packages/editor/src/components/rich-text/index.native.js b/packages/editor/src/components/rich-text/index.native.js index 8de0a2655d1f0..48a0ec86b1634 100644 --- a/packages/editor/src/components/rich-text/index.native.js +++ b/packages/editor/src/components/rich-text/index.native.js @@ -15,6 +15,7 @@ import { Component, RawHTML } from '@wordpress/element'; import { withInstanceId, compose } from '@wordpress/compose'; import { Toolbar } from '@wordpress/components'; import { + isEmpty, create, split, toHTMLString, @@ -87,10 +88,18 @@ export class RichText extends Component { } ); // TODO : Fix the index position in AztecNative for Android - let [ before, after ] = split( { start: start - 6, end: end - 6, ...record } ); - - // TODO : Handle here the cases when the split happens at the trailing or leading edge... - // See the web version for reference. + let [ before, after ] = split( { start, end, ...record } ); + + // In case split occurs at the trailing or leading edge of the field, + // assume that the before/after values respectively reflect the current + // 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 ) ) { + before = record; + } else if ( isEmpty( before ) ) { + after = record; + } if ( before ) { before = this.valueToFormat( before ); From f1d163a9bb457bc22c456dfafd4906eaada9a87c Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Thu, 18 Oct 2018 11:13:41 -0400 Subject: [PATCH 013/121] Writing Flow: Avoid horizontal writing flow navigation in native inputs (#9978) --- .../src/components/writing-flow/index.js | 30 +++++++++++ .../src/components/writing-flow/test/index.js | 51 +++++++++++++++++++ test/e2e/specs/writing-flow.test.js | 28 ++++++++++ 3 files changed, 109 insertions(+) create mode 100644 packages/editor/src/components/writing-flow/test/index.js diff --git a/packages/editor/src/components/writing-flow/index.js b/packages/editor/src/components/writing-flow/index.js index e13b81eaf6dfd..6f85e5ed1e8af 100644 --- a/packages/editor/src/components/writing-flow/index.js +++ b/packages/editor/src/components/writing-flow/index.js @@ -49,6 +49,29 @@ const isTabbableTextField = overEvery( [ focus.tabbable.isTabbableIndex, ] ); +/** + * Returns true if the element should consider edge navigation upon a keyboard + * event of the given directional key code, or false otherwise. + * + * @param {Element} element HTML element to test. + * @param {number} keyCode KeyboardEvent keyCode to test. + * @param {boolean} hasModifier Whether a modifier is pressed. + * + * @return {boolean} Whether element should consider edge navigation. + */ +export function isNavigationCandidate( element, keyCode, hasModifier ) { + const isVertical = ( keyCode === UP || keyCode === DOWN ); + + // Currently, all elements support unmodified vertical navigation. + if ( isVertical && ! hasModifier ) { + return true; + } + + // Native inputs should not navigate horizontally. + const { tagName } = element; + return tagName !== 'INPUT' && tagName !== 'TEXTAREA'; +} + class WritingFlow extends Component { constructor() { super( ...arguments ); @@ -209,6 +232,7 @@ class WritingFlow extends Component { const isVertical = isUp || isDown; const isNav = isHorizontal || isVertical; const isShift = event.shiftKey; + const hasModifier = isShift || event.ctrlKey || event.altKey || event.metaKey; const isNavEdge = isVertical ? isVerticalEdge : isHorizontalEdge; // This logic inside this condition needs to be checked before @@ -243,6 +267,12 @@ class WritingFlow extends Component { return; } + // Abort if our current target is not a candidate for navigation (e.g. + // preserve native input behaviors). + if ( ! isNavigationCandidate( target, keyCode, hasModifier ) ) { + return; + } + if ( ! isVertical ) { this.verticalRect = null; } else if ( ! this.verticalRect ) { diff --git a/packages/editor/src/components/writing-flow/test/index.js b/packages/editor/src/components/writing-flow/test/index.js new file mode 100644 index 0000000000000..88ff30f107a72 --- /dev/null +++ b/packages/editor/src/components/writing-flow/test/index.js @@ -0,0 +1,51 @@ +/** + * WordPress dependencies + */ +import { UP, DOWN, LEFT, RIGHT } from '@wordpress/keycodes'; + +/** + * Internal dependencies + */ +import { isNavigationCandidate } from '../'; + +describe( 'isNavigationCandidate', () => { + let elements; + beforeAll( () => { + elements = {}; + elements.input = document.createElement( 'input' ); + elements.contentEditable = document.createElement( 'p' ); + elements.contentEditable.contentEditable = true; + } ); + + it( 'should return true if vertically navigating input without modifier', () => { + [ UP, DOWN ].forEach( ( keyCode ) => { + const result = isNavigationCandidate( elements.input, keyCode, false ); + + expect( result ).toBe( true ); + } ); + } ); + + it( 'should return false if vertically navigating input with modifier', () => { + [ UP, DOWN ].forEach( ( keyCode ) => { + const result = isNavigationCandidate( elements.input, keyCode, true ); + + expect( result ).toBe( false ); + } ); + } ); + + it( 'should return false if horizontally navigating input', () => { + [ LEFT, RIGHT ].forEach( ( keyCode ) => { + const result = isNavigationCandidate( elements.input, keyCode, false ); + + expect( result ).toBe( false ); + } ); + } ); + + it( 'should return true if horizontally navigating non-input', () => { + [ LEFT, RIGHT ].forEach( ( keyCode ) => { + const result = isNavigationCandidate( elements.contentEditable, keyCode, false ); + + expect( result ).toBe( true ); + } ); + } ); +} ); diff --git a/test/e2e/specs/writing-flow.test.js b/test/e2e/specs/writing-flow.test.js index 2d484b958b416..67c91280ba410 100644 --- a/test/e2e/specs/writing-flow.test.js +++ b/test/e2e/specs/writing-flow.test.js @@ -195,4 +195,32 @@ describe( 'adding blocks', () => { await pressWithModifier( 'Shift', 'Enter' ); expect( await getEditedPostContent() ).toMatchSnapshot(); } ); + + it( 'should navigate native inputs vertically, not horizontally', async () => { + // See: https://github.com/WordPress/gutenberg/issues/9626 + + // Title is within the editor's writing flow, and is a
"`; +exports[`Using Plugins API Sidebar Should open plugins sidebar using More Menu item and render content 1`] = `"
Sidebar title plugin
"`; diff --git a/test/e2e/specs/links.test.js b/test/e2e/specs/links.test.js index 0bd1859b00249..23546f8c72045 100644 --- a/test/e2e/specs/links.test.js +++ b/test/e2e/specs/links.test.js @@ -192,17 +192,14 @@ describe( 'Links', () => { expect( await getEditedPostContent() ).toMatchSnapshot(); } ); - const toggleFixedToolbar = async ( b ) => { - await page.click( '.edit-post-more-menu button' ); - const button = ( await page.$x( "//button[contains(text(), 'Unified Toolbar')]" ) )[ 0 ]; - const buttonClassNameProperty = await button.getProperty( 'className' ); - const buttonClassName = await buttonClassNameProperty.jsonValue(); - const isSelected = buttonClassName.indexOf( 'is-selected' ) !== -1; - if ( isSelected !== b ) { - await button.click(); - } else { - await page.click( '.edit-post-more-menu button' ); - } + const toggleFixedToolbar = async ( isFixed ) => { + await page.evaluate( ( _isFixed ) => { + const { select, dispatch } = wp.data; + const isCurrentlyFixed = select( 'core/edit-post' ).isFeatureActive( 'fixedToolbar' ); + if ( isCurrentlyFixed !== _isFixed ) { + dispatch( 'core/edit-post' ).toggleFeature( 'fixedToolbar' ); + } + }, isFixed ); }; it( 'allows Left to be pressed during creation when the toolbar is fixed to top', async () => { From 611fe3152108e5dd46f525ad033665e928c3ce62 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Fri, 19 Oct 2018 15:23:45 -0400 Subject: [PATCH 032/121] REST API: Use posts endpoint for reusable blocks (#10751) * REST API: Use posts endpoint for reusable blocks * REST: Restore WP_REST_Blocks_Controller for permissions check * Reusable Blocks: Enable post listing edit * Reusable Blocks: Trash on delete action * List Reusable Blocks: Provide context to post request * Reusable Blocks: Verify edit capability on export action * List Reusable Blocks: Import as published --- gutenberg.php | 9 +- lib/class-wp-rest-blocks-controller.php | 87 ---------- lib/register.php | 5 +- .../src/store/effects/reusable-blocks.js | 31 ++-- .../src/store/effects/test/reusable-blocks.js | 18 +- .../list-reusable-blocks/src/utils/export.js | 11 +- .../list-reusable-blocks/src/utils/import.js | 1 + phpunit/class-rest-blocks-controller-test.php | 164 +----------------- 8 files changed, 50 insertions(+), 276 deletions(-) diff --git a/gutenberg.php b/gutenberg.php index 024bb9f2cd8be..d68b92c18237b 100644 --- a/gutenberg.php +++ b/gutenberg.php @@ -266,8 +266,15 @@ function gutenberg_add_edit_link( $actions, $post ) { $title = _draft_or_post_title( $post->ID ); if ( 'wp_block' === $post->post_type ) { - unset( $actions['edit'] ); unset( $actions['inline hide-if-no-js'] ); + + // Export uses block raw content, which is only returned from the post + // REST endpoint via `context=edit`, requiring edit capability. + $post_type = get_post_type_object( $post->post_type ); + if ( ! current_user_can( $post_type->cap->edit_post, $post->ID ) ) { + return $actions; + } + $actions['export'] = sprintf( '', $post->ID, diff --git a/lib/class-wp-rest-blocks-controller.php b/lib/class-wp-rest-blocks-controller.php index 75f69afe91759..9689820c7494b 100644 --- a/lib/class-wp-rest-blocks-controller.php +++ b/lib/class-wp-rest-blocks-controller.php @@ -33,91 +33,4 @@ public function check_read_permission( $post ) { return parent::check_read_permission( $post ); } - - /** - * Handle a DELETE request. - * - * @since 1.10.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. - */ - public function delete_item( $request ) { - // Always hard-delete a block. - $request->set_param( 'force', true ); - - return parent::delete_item( $request ); - } - - /** - * Given an update or create request, build the post object that is saved to - * the database. - * - * @since 1.10.0 - * - * @param WP_REST_Request $request Request object. - * @return stdClass|WP_Error Post object or WP_Error. - */ - public function prepare_item_for_database( $request ) { - $prepared_post = parent::prepare_item_for_database( $request ); - - // Force blocks to always be published. - $prepared_post->post_status = 'publish'; - - return $prepared_post; - } - - /** - * Given a block from the database, build the array that is returned from an - * API response. - * - * @since 1.10.0 - * - * @param WP_Post $post Post object that backs the block. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response Response object. - */ - public function prepare_item_for_response( $post, $request ) { - $data = array( - 'id' => $post->ID, - 'title' => $post->post_title, - 'content' => $post->post_content, - ); - - $response = rest_ensure_response( $data ); - - return apply_filters( "rest_prepare_{$this->post_type}", $response, $post, $request ); - } - - /** - * Builds the block's schema, conforming to JSON Schema. - * - * @since 1.10.0 - * - * @return array Item schema data. - */ - public function get_item_schema() { - return array( - '$schema' => 'http://json-schema.org/schema#', - 'title' => $this->post_type, - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the block.', 'gutenberg' ), - 'type' => 'integer', - 'readonly' => true, - ), - 'title' => array( - 'description' => __( 'The block’s title.', 'gutenberg' ), - 'type' => 'string', - 'required' => true, - ), - 'content' => array( - 'description' => __( 'The block’s HTML content.', 'gutenberg' ), - 'type' => 'string', - 'required' => true, - ), - ), - ); - } } diff --git a/lib/register.php b/lib/register.php index 89ee8411fb262..0401af2f8a7c7 100644 --- a/lib/register.php +++ b/lib/register.php @@ -461,7 +461,10 @@ function gutenberg_register_post_types() { 'create_posts' => 'create_blocks', ), 'map_meta_cap' => true, - 'supports' => false, + 'supports' => array( + 'title', + 'editor', + ), ) ); diff --git a/packages/editor/src/store/effects/reusable-blocks.js b/packages/editor/src/store/effects/reusable-blocks.js index d1cb383469328..a895d9eae615f 100644 --- a/packages/editor/src/store/effects/reusable-blocks.js +++ b/packages/editor/src/store/effects/reusable-blocks.js @@ -36,6 +36,7 @@ import { getBlocks, getBlocksByClientId, } from '../selectors'; +import { getPostRawValue } from '../reducer'; /** * Module Constants @@ -61,26 +62,25 @@ export const fetchReusableBlocks = async ( action, store ) => { let result; if ( id ) { - result = apiFetch( { path: `/wp/v2/${ postType.rest_base }/${ id }` } ); + result = apiFetch( { path: `/wp/v2/${ postType.rest_base }/${ id }?context=edit` } ); } else { - result = apiFetch( { path: `/wp/v2/${ postType.rest_base }?per_page=-1` } ); + result = apiFetch( { path: `/wp/v2/${ postType.rest_base }?per_page=-1&context=edit` } ); } try { const reusableBlockOrBlocks = await result; dispatch( receiveReusableBlocksAction( map( castArray( reusableBlockOrBlocks ), - ( reusableBlock ) => { - const parsedBlocks = parse( reusableBlock.content ); - if ( parsedBlocks.length === 1 ) { - return { - reusableBlock, - parsedBlock: parsedBlocks[ 0 ], - }; - } + ( post ) => { + const parsedBlocks = parse( post.content.raw ); return { - reusableBlock, - parsedBlock: createBlock( 'core/template', {}, parsedBlocks ), + reusableBlock: { + id: post.id, + title: getPostRawValue( post.title ), + }, + parsedBlock: parsedBlocks.length === 1 ? + parsedBlocks[ 0 ] : + createBlock( 'core/template', {}, parsedBlocks ), }; } ) ) ); @@ -119,7 +119,7 @@ export const saveReusableBlocks = async ( action, store ) => { const reusableBlock = getBlock( state, clientId ); const content = serialize( reusableBlock.name === 'core/template' ? reusableBlock.innerBlocks : reusableBlock ); - const data = isTemporary ? { title, content } : { id, title, content }; + const data = isTemporary ? { title, content, status: 'publish' } : { id, title, content, status: 'publish' }; const path = isTemporary ? `/wp/v2/${ postType.rest_base }` : `/wp/v2/${ postType.rest_base }/${ id }`; const method = isTemporary ? 'POST' : 'PUT'; @@ -184,7 +184,10 @@ export const deleteReusableBlocks = async ( action, store ) => { ] ) ); try { - await apiFetch( { path: `/wp/v2/${ postType.rest_base }/${ id }`, method: 'DELETE' } ); + await apiFetch( { + path: `/wp/v2/${ postType.rest_base }/${ id }`, + method: 'DELETE', + } ); dispatch( { type: 'DELETE_REUSABLE_BLOCK_SUCCESS', id, diff --git a/packages/editor/src/store/effects/test/reusable-blocks.js b/packages/editor/src/store/effects/test/reusable-blocks.js index 2ff4081a650a7..dcfe687f74412 100644 --- a/packages/editor/src/store/effects/test/reusable-blocks.js +++ b/packages/editor/src/store/effects/test/reusable-blocks.js @@ -70,8 +70,12 @@ describe( 'reusable blocks effects', () => { const blockPromise = Promise.resolve( [ { id: 123, - title: 'My cool block', - content: '', + title: { + raw: 'My cool block', + }, + content: { + raw: '', + }, }, ] ); const postTypePromise = Promise.resolve( { @@ -97,7 +101,6 @@ describe( 'reusable blocks effects', () => { reusableBlock: { id: 123, title: 'My cool block', - content: '', }, parsedBlock: expect.objectContaining( { name: 'core/test-block', @@ -115,8 +118,12 @@ describe( 'reusable blocks effects', () => { it( 'should fetch a single reusable block', async () => { const blockPromise = Promise.resolve( { id: 123, - title: 'My cool block', - content: '', + title: { + raw: 'My cool block', + }, + content: { + raw: '', + }, } ); const postTypePromise = Promise.resolve( { slug: 'wp_block', rest_base: 'blocks', @@ -141,7 +148,6 @@ describe( 'reusable blocks effects', () => { reusableBlock: { id: 123, title: 'My cool block', - content: '', }, parsedBlock: expect.objectContaining( { name: 'core/test-block', diff --git a/packages/list-reusable-blocks/src/utils/export.js b/packages/list-reusable-blocks/src/utils/export.js index e3ca3b8b07788..a0d75bd427c1e 100644 --- a/packages/list-reusable-blocks/src/utils/export.js +++ b/packages/list-reusable-blocks/src/utils/export.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { pick, kebabCase } from 'lodash'; +import { kebabCase } from 'lodash'; /** * WordPress dependencies @@ -20,12 +20,15 @@ import { download } from './file'; */ async function exportReusableBlock( id ) { const postType = await apiFetch( { path: `/wp/v2/types/wp_block` } ); - const reusableBlock = await apiFetch( { path: `/wp/v2/${ postType.rest_base }/${ id }` } ); + const post = await apiFetch( { path: `/wp/v2/${ postType.rest_base }/${ id }?context=edit` } ); + const title = post.title.raw; + const content = post.content.raw; const fileContent = JSON.stringify( { __file: 'wp_block', - ...pick( reusableBlock, [ 'title', 'content' ] ), + title, + content, }, null, 2 ); - const fileName = kebabCase( reusableBlock.title ) + '.json'; + const fileName = kebabCase( title ) + '.json'; download( fileName, fileContent, 'application/json' ); } diff --git a/packages/list-reusable-blocks/src/utils/import.js b/packages/list-reusable-blocks/src/utils/import.js index 6bf0204895284..e885cbb6b2b24 100644 --- a/packages/list-reusable-blocks/src/utils/import.js +++ b/packages/list-reusable-blocks/src/utils/import.js @@ -42,6 +42,7 @@ async function importReusableBlock( file ) { data: { title: parsedContent.title, content: parsedContent.content, + status: 'publish', }, method: 'POST', } ); diff --git a/phpunit/class-rest-blocks-controller-test.php b/phpunit/class-rest-blocks-controller-test.php index 7b92f200a2afc..a5c58c6f49805 100644 --- a/phpunit/class-rest-blocks-controller-test.php +++ b/phpunit/class-rest-blocks-controller-test.php @@ -8,7 +8,7 @@ /** * Tests for WP_REST_Blocks_Controller. */ -class REST_Blocks_Controller_Test extends WP_Test_REST_Controller_Testcase { +class REST_Blocks_Controller_Test extends WP_UnitTestCase { /** * Our fake block's post ID. @@ -55,161 +55,6 @@ public static function wpTearDownAfterClass() { self::delete_user( self::$user_id ); } - /** - * Check that our routes get set up properly. - */ - public function test_register_routes() { - $routes = rest_get_server()->get_routes(); - - $this->assertArrayHasKey( '/wp/v2/blocks', $routes ); - $this->assertCount( 2, $routes['/wp/v2/blocks'] ); - $this->assertArrayHasKey( '/wp/v2/blocks/(?P[\d]+)', $routes ); - $this->assertCount( 3, $routes['/wp/v2/blocks/(?P[\d]+)'] ); - } - - /** - * Check that we can GET a collection of blocks. - */ - public function test_get_items() { - wp_set_current_user( self::$user_id ); - - $request = new WP_REST_Request( 'GET', '/wp/v2/blocks' ); - $response = rest_get_server()->dispatch( $request ); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( - array( - array( - 'id' => self::$post_id, - 'title' => 'My cool block', - 'content' => '

Hello!

', - ), - ), - $response->get_data() - ); - } - - /** - * Check that we can GET a single block. - */ - public function test_get_item() { - wp_set_current_user( self::$user_id ); - - $request = new WP_REST_Request( 'GET', '/wp/v2/blocks/' . self::$post_id ); - $response = rest_get_server()->dispatch( $request ); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( - array( - 'id' => self::$post_id, - 'title' => 'My cool block', - 'content' => '

Hello!

', - ), - $response->get_data() - ); - } - - /** - * Check that we can POST to create a new block. - */ - public function test_create_item() { - wp_set_current_user( self::$user_id ); - - $request = new WP_REST_Request( 'POST', '/wp/v2/blocks/' . self::$post_id ); - $request->set_body_params( - array( - 'title' => 'New cool block', - 'content' => '

Wow!

', - ) - ); - - $response = rest_get_server()->dispatch( $request ); - - $this->assertEquals( 200, $response->get_status() ); - - $data = $response->get_data(); - - $this->assertArrayHasKey( 'id', $data ); - $this->assertArrayHasKey( 'title', $data ); - $this->assertArrayHasKey( 'content', $data ); - - $this->assertEquals( self::$post_id, $data['id'] ); - $this->assertEquals( 'New cool block', $data['title'] ); - $this->assertEquals( '

Wow!

', $data['content'] ); - } - - /** - * Check that we can PUT to update a block. - */ - public function test_update_item() { - wp_set_current_user( self::$user_id ); - - $request = new WP_REST_Request( 'PUT', '/wp/v2/blocks/' . self::$post_id ); - $request->set_body_params( - array( - 'title' => 'Updated cool block', - 'content' => '

Nice!

', - ) - ); - - $response = rest_get_server()->dispatch( $request ); - - $this->assertEquals( 200, $response->get_status() ); - - $data = $response->get_data(); - - $this->assertArrayHasKey( 'id', $data ); - $this->assertArrayHasKey( 'title', $data ); - $this->assertArrayHasKey( 'content', $data ); - - $this->assertEquals( self::$post_id, $data['id'] ); - $this->assertEquals( 'Updated cool block', $data['title'] ); - $this->assertEquals( '

Nice!

', $data['content'] ); - } - - /** - * Check that we can DELETE a block. - */ - public function test_delete_item() { - wp_set_current_user( self::$user_id ); - - $request = new WP_REST_Request( 'DELETE', '/wp/v2/blocks/' . self::$post_id ); - - $response = rest_get_server()->dispatch( $request ); - - $this->assertEquals( 200, $response->get_status() ); - - $data = $response->get_data(); - - $this->assertArrayHasKey( 'deleted', $data ); - $this->assertArrayHasKey( 'previous', $data ); - - $this->assertTrue( $data['deleted'] ); - - $this->assertArrayHasKey( 'id', $data['previous'] ); - $this->assertArrayHasKey( 'title', $data['previous'] ); - $this->assertArrayHasKey( 'content', $data['previous'] ); - - $this->assertEquals( self::$post_id, $data['previous']['id'] ); - $this->assertEquals( 'My cool block', $data['previous']['title'] ); - $this->assertEquals( '

Hello!

', $data['previous']['content'] ); - } - - /** - * Check that we have defined a JSON schema. - */ - public function test_get_item_schema() { - $request = new WP_REST_Request( 'OPTIONS', '/wp/v2/blocks' ); - $response = rest_get_server()->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 3, count( $properties ) ); - $this->assertArrayHasKey( 'id', $properties ); - $this->assertArrayHasKey( 'title', $properties ); - $this->assertArrayHasKey( 'content', $properties ); - } - /** * Test cases for test_capabilities(). */ @@ -331,11 +176,4 @@ public function test_capabilities( $action, $role, $expected_status ) { self::delete_user( $user_id ); } } - - public function test_context_param() { - $this->markTestSkipped( 'Controller doesn\'t implement get_context_param().' ); - } - public function test_prepare_item() { - $this->markTestSkipped( 'Controller doesn\'t implement prepare_item().' ); - } } From 5a546b0bdb1109ca2dbf84d7236652bce30a32dd Mon Sep 17 00:00:00 2001 From: Arnaud Banvillet Date: Fri, 19 Oct 2018 22:41:54 +0200 Subject: [PATCH 033/121] Docs: Fix deprecated-blocks example (#10717) ## Description I changed a small error in the deprecated-blocks documentation ## How has this been tested? I looked in my Github repo if the markdown file preview was ok ## Types of changes Typo in documentation --- docs/block-api/deprecated-blocks.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/block-api/deprecated-blocks.md b/docs/block-api/deprecated-blocks.md index 7c977089b926a..99d84d0cf0ed5 100644 --- a/docs/block-api/deprecated-blocks.md +++ b/docs/block-api/deprecated-blocks.md @@ -112,7 +112,7 @@ registerBlockType( 'gutenberg/block-with-deprecated-version', { }, save: function( props ) { - return el( 'div', {}, props.attributes.text ); + return el( 'div', {}, props.attributes.content ); }, deprecated: [ @@ -153,7 +153,7 @@ registerBlockType( 'gutenberg/block-with-deprecated-version', { }, save( props ) { - return
{ props.attributes.text }
; + return
{ props.attributes.content }
; }, deprecated: [ From a30a4f0188a632d27fa89755f9d185d8130eefcf Mon Sep 17 00:00:00 2001 From: Matias Ventura Date: Fri, 19 Oct 2018 23:43:23 +0200 Subject: [PATCH 034/121] Update plugin version to 4.1 RC1. (#10749) --- gutenberg.php | 2 +- package-lock.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gutenberg.php b/gutenberg.php index d68b92c18237b..fdc1cf2ab1767 100644 --- a/gutenberg.php +++ b/gutenberg.php @@ -3,7 +3,7 @@ * Plugin Name: Gutenberg * Plugin URI: https://github.com/WordPress/gutenberg * Description: Printing since 1440. This is the development plugin for the new block editor in core. - * Version: 4.0.0 + * Version: 4.1.0-rc.1 * Author: Gutenberg Team * * @package gutenberg diff --git a/package-lock.json b/package-lock.json index ab5506def2374..1867236d23dc4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "4.0.0", + "version": "4.1.0-rc.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 10fd5c336e2ea..7368a6e70f24c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "4.0.0", + "version": "4.1.0-rc.1", "private": true, "description": "A new WordPress editor experience", "repository": "git+https://github.com/WordPress/gutenberg.git", From 4549bbc565b4eb9fa88ea31356132a74f06443e9 Mon Sep 17 00:00:00 2001 From: Matthew Riley MacPherson Date: Fri, 19 Oct 2018 22:47:18 +0100 Subject: [PATCH 035/121] Oops, forgot to update these to master --- docs/reference/release.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reference/release.md b/docs/reference/release.md index 4e8de1edd8692..e909ab5281aab 100644 --- a/docs/reference/release.md +++ b/docs/reference/release.md @@ -47,7 +47,7 @@ Creating a release candidate involves: 1. [Create a new release on GitHub](https://github.com/WordPress/gutenberg/releases/new). 2. If you were releasing the `5.0.0` release candidate, label it `v5.0.0-rc.1`. 3. The GitHub release screen should look like this: -[![GitHub Release Screenshot](https://raw.githubusercontent.com/WordPress/gutenberg/docs/more-release-docs-tweaks/docs/reference/release-screenshot.png)](https://raw.githubusercontent.com/WordPress/gutenberg/docs/more-release-docs-tweaks/docs/reference/release-screenshot.png) +[![GitHub Release Screenshot](https://raw.githubusercontent.com/WordPress/gutenberg/master/docs/reference/release-screenshot.png)](https://raw.githubusercontent.com/WordPress/gutenberg/master/docs/reference/release-screenshot.png) 4. Creative emojis related to a key feature in this release are encouraged. Emojis are fun! 5. Publish the release. From 3e9ae4b54e10449867c04b1ef91f2ffdbd806f57 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Fri, 19 Oct 2018 23:03:45 +0100 Subject: [PATCH 036/121] Update the published packages changelog + revert lerna changelog config (#10819) --- lerna.json | 1 - packages/blob/CHANGELOG.md | 2 ++ packages/block-library/CHANGELOG.md | 2 ++ packages/blocks/CHANGELOG.md | 2 ++ packages/components/CHANGELOG.md | 2 ++ packages/compose/CHANGELOG.md | 2 ++ packages/core-data/CHANGELOG.md | 2 ++ packages/data/CHANGELOG.md | 2 ++ packages/dom/CHANGELOG.md | 2 ++ packages/edit-post/CHANGELOG.md | 2 ++ packages/editor/CHANGELOG.md | 2 ++ packages/element/CHANGELOG.md | 2 ++ packages/escape-html/CHANGELOG.md | 2 +- packages/list-reusable-blocks/CHANGELOG.md | 2 ++ packages/nux/CHANGELOG.md | 2 ++ packages/plugins/CHANGELOG.md | 2 ++ packages/redux-routine/CHANGELOG.md | 2 +- packages/rich-text/CHANGELOG.md | 2 +- packages/viewport/CHANGELOG.md | 2 ++ 19 files changed, 33 insertions(+), 4 deletions(-) diff --git a/lerna.json b/lerna.json index fd005a960f1e6..431f4dec535da 100644 --- a/lerna.json +++ b/lerna.json @@ -6,7 +6,6 @@ }, "ignoreChanges": [ "**/benchmark/*.js", - "**/CHANGELOG.md", "**/test/**" ], "packages": [ diff --git a/packages/blob/CHANGELOG.md b/packages/blob/CHANGELOG.md index 5a0b5f114d7c3..b9d1a7dcbb94a 100644 --- a/packages/blob/CHANGELOG.md +++ b/packages/blob/CHANGELOG.md @@ -4,6 +4,8 @@ - Added a new `isBlobURL` function. +## 2.0.3 (2018-10-18) + ## 2.0.0 (2018-09-05) ### Breaking Change diff --git a/packages/block-library/CHANGELOG.md b/packages/block-library/CHANGELOG.md index ea310dd99d548..4a92aa3faf1fa 100644 --- a/packages/block-library/CHANGELOG.md +++ b/packages/block-library/CHANGELOG.md @@ -1,3 +1,5 @@ +## 2.1.2 (2018-10-18) + ## 2.1.0 (2018-10-10) ### New Features diff --git a/packages/blocks/CHANGELOG.md b/packages/blocks/CHANGELOG.md index 7227e8d2887e3..03bf9e20e3842 100644 --- a/packages/blocks/CHANGELOG.md +++ b/packages/blocks/CHANGELOG.md @@ -1,3 +1,5 @@ +## 4.0.3 (2018-10-18) + ## 4.0.0 (2018-09-30) ### Breaking Changes diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 59ae8b21f3865..69844765bb221 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -13,6 +13,8 @@ - `PanelColor` has been deprecated in favor of `wp.editor.PanelColorSettings`. +## 4.1.2 (2018-10-18) + ## 4.1.0 (2018-10-10) ### New Feature diff --git a/packages/compose/CHANGELOG.md b/packages/compose/CHANGELOG.md index a49cefcd0d75c..5f9b733622058 100644 --- a/packages/compose/CHANGELOG.md +++ b/packages/compose/CHANGELOG.md @@ -1,3 +1,5 @@ +## 2.0.4 (2018-10-18) + ## 2.0.0 (2018-09-05) ### Breaking Change diff --git a/packages/core-data/CHANGELOG.md b/packages/core-data/CHANGELOG.md index f9a01b5abef62..ca3a1f13ab58e 100644 --- a/packages/core-data/CHANGELOG.md +++ b/packages/core-data/CHANGELOG.md @@ -1,3 +1,5 @@ +## 2.0.4 (2018-10-18) + ## 2.0.0 (2018-09-05) ### Breaking Change diff --git a/packages/data/CHANGELOG.md b/packages/data/CHANGELOG.md index a531cb243ae7f..f2c5f3a71b507 100644 --- a/packages/data/CHANGELOG.md +++ b/packages/data/CHANGELOG.md @@ -1,3 +1,5 @@ +## 2.1.3 (2018-10-18) + ## 2.1.0 (2018-09-30) ## New Features diff --git a/packages/dom/CHANGELOG.md b/packages/dom/CHANGELOG.md index a49cefcd0d75c..79111040fa8e2 100644 --- a/packages/dom/CHANGELOG.md +++ b/packages/dom/CHANGELOG.md @@ -1,3 +1,5 @@ +## 2.0.3 (2018-10-18) + ## 2.0.0 (2018-09-05) ### Breaking Change diff --git a/packages/edit-post/CHANGELOG.md b/packages/edit-post/CHANGELOG.md index a0d14dd84bb07..c4da9c026a1b0 100644 --- a/packages/edit-post/CHANGELOG.md +++ b/packages/edit-post/CHANGELOG.md @@ -1,3 +1,5 @@ +## 1.0.2 (2018-10-18) + ## 1.0.0 (2018-10-10) ### New Features diff --git a/packages/editor/CHANGELOG.md b/packages/editor/CHANGELOG.md index 251dd2ac549eb..226d41d72bc20 100644 --- a/packages/editor/CHANGELOG.md +++ b/packages/editor/CHANGELOG.md @@ -12,6 +12,8 @@ - Added `onClose` prop to `URLPopover` component. +## 4.0.3 (2018-10-18) + ## 4.0.0 (2018-09-30) ### Breaking Changes diff --git a/packages/element/CHANGELOG.md b/packages/element/CHANGELOG.md index d59d78cbf2c93..6c355b4be4fe2 100644 --- a/packages/element/CHANGELOG.md +++ b/packages/element/CHANGELOG.md @@ -1,3 +1,5 @@ +## 2.1.3 (2018-10-18) + ## 2.1.0 (2018-09-30) - New API method `isEmptyElement` was introduced ([9861](https://github.com/WordPress/gutenberg/pull/9681/)). diff --git a/packages/escape-html/CHANGELOG.md b/packages/escape-html/CHANGELOG.md index 16c97e5a1bf32..4df1fd5bec719 100644 --- a/packages/escape-html/CHANGELOG.md +++ b/packages/escape-html/CHANGELOG.md @@ -1,3 +1,3 @@ -## 1.0.0 (Unreleased) +## 1.0.0 (2018-10-18) - Initial release. diff --git a/packages/list-reusable-blocks/CHANGELOG.md b/packages/list-reusable-blocks/CHANGELOG.md index d33808d32e30d..8a9a831a1f6ca 100644 --- a/packages/list-reusable-blocks/CHANGELOG.md +++ b/packages/list-reusable-blocks/CHANGELOG.md @@ -1,3 +1,5 @@ +## 1.1.2 (2018-10-18) + ## 1.1.0 (2018-10-10) ### New Features diff --git a/packages/nux/CHANGELOG.md b/packages/nux/CHANGELOG.md index a49cefcd0d75c..5f9b733622058 100644 --- a/packages/nux/CHANGELOG.md +++ b/packages/nux/CHANGELOG.md @@ -1,3 +1,5 @@ +## 2.0.4 (2018-10-18) + ## 2.0.0 (2018-09-05) ### Breaking Change diff --git a/packages/plugins/CHANGELOG.md b/packages/plugins/CHANGELOG.md index a49cefcd0d75c..5f9b733622058 100644 --- a/packages/plugins/CHANGELOG.md +++ b/packages/plugins/CHANGELOG.md @@ -1,3 +1,5 @@ +## 2.0.4 (2018-10-18) + ## 2.0.0 (2018-09-05) ### Breaking Change diff --git a/packages/redux-routine/CHANGELOG.md b/packages/redux-routine/CHANGELOG.md index b1935b639e224..6ca66d38b1887 100644 --- a/packages/redux-routine/CHANGELOG.md +++ b/packages/redux-routine/CHANGELOG.md @@ -1,4 +1,4 @@ -## 3.0.1 (Unreleased) +## 3.0.2 (2018-10-18) ### Bug Fix diff --git a/packages/rich-text/CHANGELOG.md b/packages/rich-text/CHANGELOG.md index 16c97e5a1bf32..4df1fd5bec719 100644 --- a/packages/rich-text/CHANGELOG.md +++ b/packages/rich-text/CHANGELOG.md @@ -1,3 +1,3 @@ -## 1.0.0 (Unreleased) +## 1.0.0 (2018-10-18) - Initial release. diff --git a/packages/viewport/CHANGELOG.md b/packages/viewport/CHANGELOG.md index a49cefcd0d75c..5f9b733622058 100644 --- a/packages/viewport/CHANGELOG.md +++ b/packages/viewport/CHANGELOG.md @@ -1,3 +1,5 @@ +## 2.0.4 (2018-10-18) + ## 2.0.0 (2018-09-05) ### Breaking Change From c74dd9f9f939caac7fdbd1c0053a3213b9b106b3 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Fri, 19 Oct 2018 23:16:58 +0100 Subject: [PATCH 037/121] chore(release): publish - @wordpress/blob@2.1.0 - @wordpress/block-library@2.1.3 - @wordpress/blocks@4.0.4 - @wordpress/components@4.2.0 - @wordpress/compose@2.0.5 - @wordpress/core-data@2.0.5 - @wordpress/data@2.1.4 - @wordpress/dom@2.0.4 - @wordpress/edit-post@1.0.3 - @wordpress/editor@5.0.0 - @wordpress/element@2.1.4 - @wordpress/escape-html@1.0.1 - @wordpress/list-reusable-blocks@1.1.3 - @wordpress/nux@2.0.5 - @wordpress/plugins@2.0.5 - @wordpress/redux-routine@3.0.3 - @wordpress/rich-text@1.0.1 - @wordpress/viewport@2.0.5 --- packages/blob/package.json | 2 +- packages/block-library/package.json | 2 +- packages/blocks/package.json | 2 +- packages/components/package.json | 4 ++-- packages/compose/package.json | 2 +- packages/core-data/package.json | 2 +- packages/data/package.json | 2 +- packages/dom/package.json | 2 +- packages/edit-post/package.json | 2 +- packages/editor/package.json | 2 +- packages/element/package.json | 2 +- packages/escape-html/package.json | 2 +- packages/list-reusable-blocks/package.json | 2 +- packages/nux/package.json | 2 +- packages/plugins/package.json | 2 +- packages/redux-routine/package.json | 2 +- packages/rich-text/package.json | 2 +- packages/viewport/package.json | 2 +- 18 files changed, 19 insertions(+), 19 deletions(-) diff --git a/packages/blob/package.json b/packages/blob/package.json index 96d2a91adf7c2..01119602f55ed 100644 --- a/packages/blob/package.json +++ b/packages/blob/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/blob", - "version": "2.0.3", + "version": "2.1.0", "description": "Blob utilities for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-library/package.json b/packages/block-library/package.json index 9c341a7bdba46..01308b546811a 100644 --- a/packages/block-library/package.json +++ b/packages/block-library/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-library", - "version": "2.1.2", + "version": "2.1.3", "description": "Block library for the WordPress editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/blocks/package.json b/packages/blocks/package.json index c5fa238e71e95..8ca13799999ae 100644 --- a/packages/blocks/package.json +++ b/packages/blocks/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/blocks", - "version": "4.0.3", + "version": "4.0.4", "description": "Block API for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/components/package.json b/packages/components/package.json index 018c38ea6e525..6494611c19583 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/components", - "version": "4.1.2", + "version": "4.2.0", "description": "UI components for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", @@ -54,4 +54,4 @@ "publishConfig": { "access": "public" } -} \ No newline at end of file +} diff --git a/packages/compose/package.json b/packages/compose/package.json index 373e1c89670df..4c18d608cbbc0 100644 --- a/packages/compose/package.json +++ b/packages/compose/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/compose", - "version": "2.0.4", + "version": "2.0.5", "description": "WordPress higher-order components (HOCs).", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/core-data/package.json b/packages/core-data/package.json index ea3a6f3a3a68b..a829391c5bce3 100644 --- a/packages/core-data/package.json +++ b/packages/core-data/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/core-data", - "version": "2.0.4", + "version": "2.0.5", "description": "Access to and manipulation of core WordPress entities.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/data/package.json b/packages/data/package.json index 8722e382ff181..df149b29db0fa 100644 --- a/packages/data/package.json +++ b/packages/data/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/data", - "version": "2.1.3", + "version": "2.1.4", "description": "Data module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/dom/package.json b/packages/dom/package.json index c7ce330d00476..38177cbfd2f96 100644 --- a/packages/dom/package.json +++ b/packages/dom/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/dom", - "version": "2.0.3", + "version": "2.0.4", "description": "DOM utilities module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/edit-post/package.json b/packages/edit-post/package.json index 5b28c7ed722c2..24efc07ffab98 100644 --- a/packages/edit-post/package.json +++ b/packages/edit-post/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/edit-post", - "version": "1.0.2", + "version": "1.0.3", "description": "Edit Post module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/editor/package.json b/packages/editor/package.json index c12006a29c91c..db733a7e241f7 100644 --- a/packages/editor/package.json +++ b/packages/editor/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/editor", - "version": "4.0.3", + "version": "5.0.0", "description": "Building blocks for WordPress editors.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/element/package.json b/packages/element/package.json index 794f849472349..e134526ddcd98 100644 --- a/packages/element/package.json +++ b/packages/element/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/element", - "version": "2.1.3", + "version": "2.1.4", "description": "Element React module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/escape-html/package.json b/packages/escape-html/package.json index 60fed031e42e6..c70aee37a4b3b 100644 --- a/packages/escape-html/package.json +++ b/packages/escape-html/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/escape-html", - "version": "1.0.0", + "version": "1.0.1", "description": "Escape HTML utils.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/list-reusable-blocks/package.json b/packages/list-reusable-blocks/package.json index 24a7a700cb9b1..983d41d36e116 100644 --- a/packages/list-reusable-blocks/package.json +++ b/packages/list-reusable-blocks/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/list-reusable-blocks", - "version": "1.1.2", + "version": "1.1.3", "description": "Adding Export/Import support to the reusable blocks listing.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/nux/package.json b/packages/nux/package.json index 6dbef6da3f9bc..44d6b23e156cb 100644 --- a/packages/nux/package.json +++ b/packages/nux/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/nux", - "version": "2.0.4", + "version": "2.0.5", "description": "NUX (New User eXperience) module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/plugins/package.json b/packages/plugins/package.json index 536a14bc429ff..660e34226a926 100644 --- a/packages/plugins/package.json +++ b/packages/plugins/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/plugins", - "version": "2.0.4", + "version": "2.0.5", "description": "Plugins module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/redux-routine/package.json b/packages/redux-routine/package.json index 094392c4b9c82..5eef2653d0782 100644 --- a/packages/redux-routine/package.json +++ b/packages/redux-routine/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/redux-routine", - "version": "3.0.2", + "version": "3.0.3", "description": "Redux middleware for generator coroutines.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/rich-text/package.json b/packages/rich-text/package.json index fe9ce5ca2f756..8280b49dd6076 100644 --- a/packages/rich-text/package.json +++ b/packages/rich-text/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/rich-text", - "version": "1.0.0", + "version": "1.0.1", "description": "Rich text value and manipulation API.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/viewport/package.json b/packages/viewport/package.json index 2096919ddc81f..7b12efc24aea5 100644 --- a/packages/viewport/package.json +++ b/packages/viewport/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/viewport", - "version": "2.0.4", + "version": "2.0.5", "description": "Viewport module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", From a9a17c9060e18b4589dff8341d5ff7052cb11806 Mon Sep 17 00:00:00 2001 From: Stephen Edgar Date: Sat, 20 Oct 2018 19:32:46 +1100 Subject: [PATCH 038/121] Revert 123811df9613cdf9dae3e9ec8372166b1b3a42e4 (#10823) --- lerna.json | 1 + 1 file changed, 1 insertion(+) diff --git a/lerna.json b/lerna.json index 431f4dec535da..fd005a960f1e6 100644 --- a/lerna.json +++ b/lerna.json @@ -6,6 +6,7 @@ }, "ignoreChanges": [ "**/benchmark/*.js", + "**/CHANGELOG.md", "**/test/**" ], "packages": [ From ba7c5b59f1c6593d09e01d25e1287aa1dcf6700e Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Sat, 20 Oct 2018 17:59:55 +0100 Subject: [PATCH 039/121] Fix importing react-dates styles into the components package stylesheet (#10831) --- packages/components/src/date-time/style.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/src/date-time/style.scss b/packages/components/src/date-time/style.scss index 6718ea8a63b43..f2930c10241b3 100644 --- a/packages/components/src/date-time/style.scss +++ b/packages/components/src/date-time/style.scss @@ -1,5 +1,5 @@ // We can't reference this package with ~ because of how Lerna handles packages. 😩 -@import "../../node_modules/react-dates/lib/css/_datepicker.css"; +@import "node_modules/react-dates/lib/css/_datepicker"; .components-datetime { .components-datetime__calendar-help { From cc498251b94b5010345afa663ffabaa431c4740c Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Sat, 20 Oct 2018 18:15:00 +0100 Subject: [PATCH 040/121] Fix fullscreen mode (#10830) * Fix fullscreen mode * Add e2e test for fullscreen mode --- .../components/header/writing-menu/index.js | 2 +- test/e2e/specs/fullscreen-mode.test.js | 27 +++++++++++++++++++ test/e2e/support/utils.js | 3 +-- 3 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 test/e2e/specs/fullscreen-mode.test.js diff --git a/packages/edit-post/src/components/header/writing-menu/index.js b/packages/edit-post/src/components/header/writing-menu/index.js index f99d0be3c67d3..3b2ff3e47f5f3 100644 --- a/packages/edit-post/src/components/header/writing-menu/index.js +++ b/packages/edit-post/src/components/header/writing-menu/index.js @@ -26,7 +26,7 @@ function WritingMenu( { onClose } ) { info={ __( 'Focus on one block at a time' ) } onToggle={ onClose } /> diff --git a/test/e2e/specs/fullscreen-mode.test.js b/test/e2e/specs/fullscreen-mode.test.js new file mode 100644 index 0000000000000..9b697516d51d0 --- /dev/null +++ b/test/e2e/specs/fullscreen-mode.test.js @@ -0,0 +1,27 @@ +/** + * Internal dependencies + */ +import { + newPost, + clickOnMoreMenuItem, +} from '../support/utils'; + +describe( 'Fullscreen Mode', () => { + beforeAll( async () => { + await newPost(); + } ); + + it( 'should open the fullscreen mode from the more menu', async () => { + await clickOnMoreMenuItem( 'Fullscreen Mode' ); + + const isFullscreenEnabled = await page.$eval( 'body', ( body ) => { + return body.classList.contains( 'is-fullscreen-mode' ); + } ); + + expect( isFullscreenEnabled ).toBe( true ); + + const fullscreenToolbar = await page.$( '.edit-post-fullscreen-mode-close__toolbar' ); + + expect( fullscreenToolbar ).not.toBeNull(); + } ); +} ); diff --git a/test/e2e/support/utils.js b/test/e2e/support/utils.js index a7a7c9510ae70..3853d143635be 100644 --- a/test/e2e/support/utils.js +++ b/test/e2e/support/utils.js @@ -307,8 +307,7 @@ export async function pressWithModifier( modifiers, key ) { */ export async function clickOnMoreMenuItem( buttonLabel ) { await expect( page ).toClick( '.edit-post-more-menu [aria-label="More"]' ); - const itemButton = ( await page.$x( `//button[contains(text(), '${ buttonLabel }')]` ) )[ 0 ]; - await itemButton.click( 'button' ); + await page.click( `.edit-post-more-menu__content button[aria-label="${ buttonLabel }"]` ); } /** From 37f5398aa09cc3e81789a495c9f93767186542d5 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Sat, 20 Oct 2018 18:15:31 +0100 Subject: [PATCH 041/121] Update changelog for the last packages release (#10836) --- packages/blob/CHANGELOG.md | 2 +- packages/block-library/CHANGELOG.md | 2 ++ packages/blocks/CHANGELOG.md | 2 ++ packages/components/CHANGELOG.md | 8 +++++++- packages/compose/CHANGELOG.md | 2 ++ packages/core-data/CHANGELOG.md | 2 ++ packages/data/CHANGELOG.md | 2 ++ packages/dom/CHANGELOG.md | 2 ++ packages/edit-post/CHANGELOG.md | 8 ++++++++ packages/editor/CHANGELOG.md | 2 +- packages/element/CHANGELOG.md | 2 ++ packages/escape-html/CHANGELOG.md | 2 ++ packages/list-reusable-blocks/CHANGELOG.md | 2 ++ packages/nux/CHANGELOG.md | 2 ++ packages/plugins/CHANGELOG.md | 2 ++ packages/redux-routine/CHANGELOG.md | 2 ++ packages/rich-text/CHANGELOG.md | 2 ++ packages/viewport/CHANGELOG.md | 2 ++ 18 files changed, 45 insertions(+), 3 deletions(-) diff --git a/packages/blob/CHANGELOG.md b/packages/blob/CHANGELOG.md index b9d1a7dcbb94a..1288967c3cfdb 100644 --- a/packages/blob/CHANGELOG.md +++ b/packages/blob/CHANGELOG.md @@ -1,4 +1,4 @@ -## 2.1.0 (Unreleased) +## 2.1.0 (2018-10-19) ### New Features diff --git a/packages/block-library/CHANGELOG.md b/packages/block-library/CHANGELOG.md index 4a92aa3faf1fa..6fe1fd0ef7ce1 100644 --- a/packages/block-library/CHANGELOG.md +++ b/packages/block-library/CHANGELOG.md @@ -1,3 +1,5 @@ +## 2.1.3 (2018-10-19) + ## 2.1.2 (2018-10-18) ## 2.1.0 (2018-10-10) diff --git a/packages/blocks/CHANGELOG.md b/packages/blocks/CHANGELOG.md index 03bf9e20e3842..08b2e25271ecd 100644 --- a/packages/blocks/CHANGELOG.md +++ b/packages/blocks/CHANGELOG.md @@ -1,3 +1,5 @@ +## 4.0.4 (2018-10-19) + ## 4.0.3 (2018-10-18) ## 4.0.0 (2018-09-30) diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 69844765bb221..bf670914795e0 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -1,4 +1,10 @@ -## 4.2.0 (Unreleased) +## 4.2.1 (Unreleased) + +### Bug Fix + +- Fix importing `react-dates` stylesheet in production. + +## 4.2.0 (2018-10-19) ### New Feature diff --git a/packages/compose/CHANGELOG.md b/packages/compose/CHANGELOG.md index 5f9b733622058..9b4bad0bd4aa5 100644 --- a/packages/compose/CHANGELOG.md +++ b/packages/compose/CHANGELOG.md @@ -1,3 +1,5 @@ +## 2.0.5 (2018-10-19) + ## 2.0.4 (2018-10-18) ## 2.0.0 (2018-09-05) diff --git a/packages/core-data/CHANGELOG.md b/packages/core-data/CHANGELOG.md index ca3a1f13ab58e..30bfdf415a54a 100644 --- a/packages/core-data/CHANGELOG.md +++ b/packages/core-data/CHANGELOG.md @@ -1,3 +1,5 @@ +## 2.0.5 (2018-10-19) + ## 2.0.4 (2018-10-18) ## 2.0.0 (2018-09-05) diff --git a/packages/data/CHANGELOG.md b/packages/data/CHANGELOG.md index f2c5f3a71b507..5bb376f526d34 100644 --- a/packages/data/CHANGELOG.md +++ b/packages/data/CHANGELOG.md @@ -1,3 +1,5 @@ +## 2.1.4 (2018-10-19) + ## 2.1.3 (2018-10-18) ## 2.1.0 (2018-09-30) diff --git a/packages/dom/CHANGELOG.md b/packages/dom/CHANGELOG.md index 79111040fa8e2..8a0d841d17433 100644 --- a/packages/dom/CHANGELOG.md +++ b/packages/dom/CHANGELOG.md @@ -1,3 +1,5 @@ +## 2.0.4 (2018-10-19) + ## 2.0.3 (2018-10-18) ## 2.0.0 (2018-09-05) diff --git a/packages/edit-post/CHANGELOG.md b/packages/edit-post/CHANGELOG.md index c4da9c026a1b0..2db3d57d70ba1 100644 --- a/packages/edit-post/CHANGELOG.md +++ b/packages/edit-post/CHANGELOG.md @@ -1,3 +1,11 @@ +## 1.0.4 (Unreleased) + +## Bug Fixes + +- Fix fullscreen mode toggle. + +## 1.0.3 (2018-10-19) + ## 1.0.2 (2018-10-18) ## 1.0.0 (2018-10-10) diff --git a/packages/editor/CHANGELOG.md b/packages/editor/CHANGELOG.md index 226d41d72bc20..691851a6bf4ef 100644 --- a/packages/editor/CHANGELOG.md +++ b/packages/editor/CHANGELOG.md @@ -1,4 +1,4 @@ -## 5.0.0 (Unreleased) +## 5.0.0 (2018-10-19) ### Breaking Changes diff --git a/packages/element/CHANGELOG.md b/packages/element/CHANGELOG.md index 6c355b4be4fe2..7010a1b87680d 100644 --- a/packages/element/CHANGELOG.md +++ b/packages/element/CHANGELOG.md @@ -1,3 +1,5 @@ +## 2.1.4 (2018-10-19) + ## 2.1.3 (2018-10-18) ## 2.1.0 (2018-09-30) diff --git a/packages/escape-html/CHANGELOG.md b/packages/escape-html/CHANGELOG.md index 4df1fd5bec719..e780b87752277 100644 --- a/packages/escape-html/CHANGELOG.md +++ b/packages/escape-html/CHANGELOG.md @@ -1,3 +1,5 @@ +## 1.0.1 (2018-10-19) + ## 1.0.0 (2018-10-18) - Initial release. diff --git a/packages/list-reusable-blocks/CHANGELOG.md b/packages/list-reusable-blocks/CHANGELOG.md index 8a9a831a1f6ca..7e54897866ced 100644 --- a/packages/list-reusable-blocks/CHANGELOG.md +++ b/packages/list-reusable-blocks/CHANGELOG.md @@ -1,3 +1,5 @@ +## 1.1.3 (2018-10-19) + ## 1.1.2 (2018-10-18) ## 1.1.0 (2018-10-10) diff --git a/packages/nux/CHANGELOG.md b/packages/nux/CHANGELOG.md index 5f9b733622058..9b4bad0bd4aa5 100644 --- a/packages/nux/CHANGELOG.md +++ b/packages/nux/CHANGELOG.md @@ -1,3 +1,5 @@ +## 2.0.5 (2018-10-19) + ## 2.0.4 (2018-10-18) ## 2.0.0 (2018-09-05) diff --git a/packages/plugins/CHANGELOG.md b/packages/plugins/CHANGELOG.md index 5f9b733622058..9b4bad0bd4aa5 100644 --- a/packages/plugins/CHANGELOG.md +++ b/packages/plugins/CHANGELOG.md @@ -1,3 +1,5 @@ +## 2.0.5 (2018-10-19) + ## 2.0.4 (2018-10-18) ## 2.0.0 (2018-09-05) diff --git a/packages/redux-routine/CHANGELOG.md b/packages/redux-routine/CHANGELOG.md index 6ca66d38b1887..7e64304c2f2c3 100644 --- a/packages/redux-routine/CHANGELOG.md +++ b/packages/redux-routine/CHANGELOG.md @@ -1,3 +1,5 @@ +## 3.0.3 (2018-10-19) + ## 3.0.2 (2018-10-18) ### Bug Fix diff --git a/packages/rich-text/CHANGELOG.md b/packages/rich-text/CHANGELOG.md index 4df1fd5bec719..e780b87752277 100644 --- a/packages/rich-text/CHANGELOG.md +++ b/packages/rich-text/CHANGELOG.md @@ -1,3 +1,5 @@ +## 1.0.1 (2018-10-19) + ## 1.0.0 (2018-10-18) - Initial release. diff --git a/packages/viewport/CHANGELOG.md b/packages/viewport/CHANGELOG.md index 5f9b733622058..9b4bad0bd4aa5 100644 --- a/packages/viewport/CHANGELOG.md +++ b/packages/viewport/CHANGELOG.md @@ -1,3 +1,5 @@ +## 2.0.5 (2018-10-19) + ## 2.0.4 (2018-10-18) ## 2.0.0 (2018-09-05) From 9b2fe92e1aac68d77a7ee57b0fef1a9f8f3066ad Mon Sep 17 00:00:00 2001 From: Miguel Fonseca Date: Sat, 20 Oct 2018 18:24:02 +0100 Subject: [PATCH 042/121] Rename PHP functions to prevent conflict w/ core (#10826) These functions (e.g. `get_block_categories`) are declared in the plugin before their counterparts in core, which means that guarding the plugin's function declarations with if ( ! function_exists( 'foo' ) ) { doesn't make a difference, and the collisions will result in server fatals. --- lib/client-assets.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/client-assets.php b/lib/client-assets.php index e7d0a88b1efce..7f1e3b48938bb 100644 --- a/lib/client-assets.php +++ b/lib/client-assets.php @@ -1233,7 +1233,7 @@ function gutenberg_capture_code_editor_settings( $settings ) { * @param WP_Post $post Post object. * @return WP_Post|boolean The post autosave. False if none found. */ -function get_autosave_newer_than_post_save( $post ) { +function gutenberg_get_autosave_newer_than_post_save( $post ) { // Add autosave data if it is newer and changed. $autosave = wp_get_post_autosave( $post->ID ); @@ -1262,7 +1262,7 @@ function get_autosave_newer_than_post_save( $post ) { * @param WP_Post $post Post object. * @return Object[] Block categories. */ -function get_block_categories( $post ) { +function gutenberg_get_block_categories( $post ) { $default_categories = array( array( 'slug' => 'common', @@ -1381,7 +1381,7 @@ function gutenberg_editor_scripts_and_styles( $hook ) { wp_add_inline_script( 'wp-blocks', - sprintf( 'wp.blocks.setCategories( %s );', wp_json_encode( get_block_categories( $post ) ) ), + sprintf( 'wp.blocks.setCategories( %s );', wp_json_encode( gutenberg_get_block_categories( $post ) ) ), 'after' ); @@ -1587,7 +1587,7 @@ function gutenberg_editor_scripts_and_styles( $hook ) { ), ); - $post_autosave = get_autosave_newer_than_post_save( $post ); + $post_autosave = gutenberg_get_autosave_newer_than_post_save( $post ); if ( $post_autosave ) { $editor_settings['autosave'] = array( 'editLink' => add_query_arg( 'gutenberg', true, get_edit_post_link( $post_autosave->ID ) ), @@ -1669,11 +1669,11 @@ function gutenberg_editor_scripts_and_styles( $hook ) { * * @param string $hook Screen name. */ -function wp_load_list_reusable_blocks( $hook ) { +function gutenberg_load_list_reusable_blocks( $hook ) { $is_reusable_blocks_list_page = 'edit.php' === $hook && isset( $_GET['post_type'] ) && 'wp_block' === $_GET['post_type']; if ( $is_reusable_blocks_list_page ) { wp_enqueue_script( 'wp-list-reusable-blocks' ); wp_enqueue_style( 'wp-list-reusable-blocks' ); } } -add_action( 'admin_enqueue_scripts', 'wp_load_list_reusable_blocks' ); +add_action( 'admin_enqueue_scripts', 'gutenberg_load_list_reusable_blocks' ); From 0aa4ffaec61778215750dd220250ab0e3a91806f Mon Sep 17 00:00:00 2001 From: Presskopp Date: Sun, 21 Oct 2018 15:57:07 +0200 Subject: [PATCH 043/121] Update rest-api.php (#10840) add missing 'to' in string "not allowed _ make" --- lib/rest-api.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rest-api.php b/lib/rest-api.php index c3ff18e708c16..7506f45484ee7 100644 --- a/lib/rest-api.php +++ b/lib/rest-api.php @@ -325,7 +325,7 @@ function gutenberg_handle_early_callback_checks( $response, $handler, $request ) } if ( $request['per_page'] < 0 ) { if ( ! $can_unbounded_query ) { - return new WP_Error( 'rest_forbidden_per_page', __( 'Sorry, you are not allowed make unbounded queries.', 'gutenberg' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'rest_forbidden_per_page', __( 'Sorry, you are not allowed to make unbounded queries.', 'gutenberg' ), array( 'status' => rest_authorization_required_code() ) ); } } } From 313a9a2803f9dd9ed0162b7c590e5852803e6b14 Mon Sep 17 00:00:00 2001 From: Jb Audras Date: Sun, 21 Oct 2018 17:12:29 +0200 Subject: [PATCH 044/121] Remove closing tag from i18n string (#10849) --- packages/components/src/date-time/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/src/date-time/index.js b/packages/components/src/date-time/index.js index 9ee8eaa527f54..caf0be2778dfa 100644 --- a/packages/components/src/date-time/index.js +++ b/packages/components/src/date-time/index.js @@ -78,7 +78,7 @@ export class DateTimePicker extends Component {
  • ↑/↓ { ' ' /* JSX removes whitespace, but a space is required for screen readers. */ } - { __( 'Move backward (up) and forward (down) by one week.
  • ' ) } + { __( 'Move backward (up) and forward (down) by one week.' ) }
  • { __( 'PgUp/PgDn' ) } From 89964ea72b9f4b18a94163587f9a01197ec44159 Mon Sep 17 00:00:00 2001 From: Dominik Schilling Date: Sun, 21 Oct 2018 17:12:58 +0200 Subject: [PATCH 045/121] Avoid PHP notices due to non-available meta boxes (#10850) --- lib/meta-box-partial-page.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/meta-box-partial-page.php b/lib/meta-box-partial-page.php index ad1a6805d327e..925450720f7f9 100644 --- a/lib/meta-box-partial-page.php +++ b/lib/meta-box-partial-page.php @@ -318,9 +318,13 @@ function the_gutenberg_metaboxes() { foreach ( $locations as $location ) { $meta_boxes_per_location[ $location ] = array(); foreach ( $priorities as $priority ) { - $meta_boxes = (array) $wp_meta_boxes[ $current_screen->id ][ $location ][ $priority ]; - foreach ( $meta_boxes as $meta_box ) { - if ( ! empty( $meta_box['title'] ) ) { + if ( isset( $wp_meta_boxes[ $current_screen->id ][ $location ][ $priority ] ) ) { + $meta_boxes = (array) $wp_meta_boxes[ $current_screen->id ][ $location ][ $priority ]; + foreach ( $meta_boxes as $meta_box ) { + if ( false == $meta_box || ! $meta_box['title'] ) { + continue; + } + $meta_boxes_per_location[ $location ][] = array( 'id' => $meta_box['id'], 'title' => $meta_box['title'], From b3edc7150b04a1b2e89a15a60bc3a5504a794f40 Mon Sep 17 00:00:00 2001 From: Andrea Fercia Date: Sun, 21 Oct 2018 17:19:44 +0200 Subject: [PATCH 046/121] Improve the Toggle Control elements DOM order for better accessibility. (#10870) --- packages/components/src/toggle-control/index.js | 9 +++++++-- packages/components/src/toggle-control/style.scss | 9 +++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/components/src/toggle-control/index.js b/packages/components/src/toggle-control/index.js index 413516232fd0f..29d558d6b80c6 100644 --- a/packages/components/src/toggle-control/index.js +++ b/packages/components/src/toggle-control/index.js @@ -13,7 +13,7 @@ import { withInstanceId } from '@wordpress/compose'; * Internal dependencies */ import FormToggle from '../form-toggle'; -import BaseControl from './../base-control'; +import BaseControl from '../base-control'; class ToggleControl extends Component { constructor() { @@ -40,7 +40,6 @@ class ToggleControl extends Component { return ( + ); } diff --git a/packages/components/src/toggle-control/style.scss b/packages/components/src/toggle-control/style.scss index c9489553d6720..e4b3e89b3ab49 100644 --- a/packages/components/src/toggle-control/style.scss +++ b/packages/components/src/toggle-control/style.scss @@ -2,11 +2,12 @@ display: flex; margin-bottom: $grid-size-small * 3; - .components-base-control__label { - order: 1; - } - .components-form-toggle { margin-right: $grid-size-large; } + + .components-toggle-control__label { + display: block; + margin-bottom: 4px; + } } From a8fe865af07812949e5ef97505668e5587c8aefb Mon Sep 17 00:00:00 2001 From: Andrea Fercia Date: Sun, 21 Oct 2018 17:20:34 +0200 Subject: [PATCH 047/121] Set correct media type for video poster image and manage focus. (#10864) --- packages/block-library/src/video/edit.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/video/edit.js b/packages/block-library/src/video/edit.js index 1d9b7b195a2eb..56a587b1c4851 100644 --- a/packages/block-library/src/video/edit.js +++ b/packages/block-library/src/video/edit.js @@ -25,6 +25,7 @@ import { import { getBlobByURL, isBlobURL } from '@wordpress/blob'; const ALLOWED_MEDIA_TYPES = [ 'video' ]; +const VIDEO_POSTER_ALLOWED_MEDIA_TYPES = [ 'image' ]; class VideoEdit extends Component { constructor() { @@ -36,6 +37,7 @@ class VideoEdit extends Component { }; this.videoPlayer = createRef(); + this.posterImageButton = createRef(); this.toggleAttribute = this.toggleAttribute.bind( this ); this.onSelectURL = this.onSelectURL.bind( this ); this.onSelectPoster = this.onSelectPoster.bind( this ); @@ -96,6 +98,9 @@ class VideoEdit extends Component { onRemovePoster() { const { setAttributes } = this.props; setAttributes( { poster: '' } ); + + // Move focus back to the Media Upload button. + this.posterImageButton.current.focus(); } render() { @@ -200,9 +205,13 @@ class VideoEdit extends Component { ( - ) } From dee3dcf49028717b4af3164e3096bfe747c41ed2 Mon Sep 17 00:00:00 2001 From: K Adam White Date: Sun, 21 Oct 2018 13:12:16 -0400 Subject: [PATCH 048/121] Implement fetchAllMiddleware to handle per_page=-1 through pagination (#10762) --- lib/client-assets.php | 2 +- lib/rest-api.php | 148 ------------------ package-lock.json | 3 +- packages/api-fetch/CHANGELOG.md | 4 + packages/api-fetch/package.json | 3 +- packages/api-fetch/src/index.js | 13 +- .../src/middlewares/fetch-all-middleware.js | 93 +++++++++++ .../middlewares/test/fetch-all-middleware.js | 51 ++++++ .../hooks/components/media-upload/index.js | 2 +- phpunit/class-gutenberg-rest-api-test.php | 38 +---- 10 files changed, 166 insertions(+), 191 deletions(-) create mode 100644 packages/api-fetch/src/middlewares/fetch-all-middleware.js create mode 100644 packages/api-fetch/src/middlewares/test/fetch-all-middleware.js diff --git a/lib/client-assets.php b/lib/client-assets.php index 7f1e3b48938bb..b9b2f10037262 100644 --- a/lib/client-assets.php +++ b/lib/client-assets.php @@ -231,7 +231,7 @@ function gutenberg_register_scripts_and_styles() { gutenberg_override_script( 'wp-api-fetch', gutenberg_url( 'build/api-fetch/index.js' ), - array( 'wp-polyfill', 'wp-hooks', 'wp-i18n' ), + array( 'wp-polyfill', 'wp-hooks', 'wp-i18n', 'wp-url' ), filemtime( gutenberg_dir_path() . 'build/api-fetch/index.js' ), true ); diff --git a/lib/rest-api.php b/lib/rest-api.php index 7506f45484ee7..35f4af5c52e77 100644 --- a/lib/rest-api.php +++ b/lib/rest-api.php @@ -290,158 +290,10 @@ function gutenberg_register_post_prepare_functions( $post_type ) { add_filter( "rest_prepare_{$post_type}", 'gutenberg_add_permalink_template_to_posts', 10, 3 ); add_filter( "rest_prepare_{$post_type}", 'gutenberg_add_block_format_to_post_content', 10, 3 ); add_filter( "rest_prepare_{$post_type}", 'gutenberg_add_target_schema_to_links', 10, 3 ); - add_filter( "rest_{$post_type}_collection_params", 'gutenberg_filter_post_collection_parameters', 10, 2 ); - add_filter( "rest_{$post_type}_query", 'gutenberg_filter_post_query_arguments', 10, 2 ); return $post_type; } add_filter( 'registered_post_type', 'gutenberg_register_post_prepare_functions' ); -/** - * Whenever a taxonomy is registered, ensure we're hooked into its WP REST API response. - * - * @param string $taxonomy The newly registered taxonomy. - */ -function gutenberg_register_taxonomy_prepare_functions( $taxonomy ) { - add_filter( "rest_{$taxonomy}_collection_params", 'gutenberg_filter_term_collection_parameters', 10, 2 ); - add_filter( "rest_{$taxonomy}_query", 'gutenberg_filter_term_query_arguments', 10, 2 ); -} -add_filter( 'registered_taxonomy', 'gutenberg_register_taxonomy_prepare_functions' ); - -/** - * Handle any necessary checks early. - * - * @param WP_HTTP_Response $response Result to send to the client. Usually a WP_REST_Response. - * @param WP_REST_Server $handler ResponseHandler instance (usually WP_REST_Server). - * @param WP_REST_Request $request Request used to generate the response. - */ -function gutenberg_handle_early_callback_checks( $response, $handler, $request ) { - if ( 0 === strpos( $request->get_route(), '/wp/v2/' ) ) { - $can_unbounded_query = false; - $types = get_post_types( array( 'show_in_rest' => true ), 'objects' ); - foreach ( $types as $type ) { - if ( current_user_can( $type->cap->edit_posts ) ) { - $can_unbounded_query = true; - } - } - if ( $request['per_page'] < 0 ) { - if ( ! $can_unbounded_query ) { - return new WP_Error( 'rest_forbidden_per_page', __( 'Sorry, you are not allowed to make unbounded queries.', 'gutenberg' ), array( 'status' => rest_authorization_required_code() ) ); - } - } - } - return $response; -} -add_filter( 'rest_request_before_callbacks', 'gutenberg_handle_early_callback_checks', 10, 3 ); - -/** - * Include additional query parameters on the posts query endpoint. - * - * @see https://core.trac.wordpress.org/ticket/43998 - * - * @param array $query_params JSON Schema-formatted collection parameters. - * @param WP_Post_Type $post_type Post type object being accessed. - * @return array - */ -function gutenberg_filter_post_collection_parameters( $query_params, $post_type ) { - if ( - isset( $query_params['per_page'] ) && - ( $post_type->hierarchical || 'wp_block' === $post_type->name ) - ) { - // Change from '1' to '-1', which means unlimited. - $query_params['per_page']['minimum'] = -1; - // Default sanitize callback is 'absint', which won't work in our case. - $query_params['per_page']['sanitize_callback'] = 'rest_sanitize_request_arg'; - } - return $query_params; -} - -/** - * Filter post collection query parameters to include specific behavior. - * - * @see https://core.trac.wordpress.org/ticket/43998 - * - * @param array $prepared_args Array of arguments for WP_Query. - * @param WP_REST_Request $request The current request. - * @return array - */ -function gutenberg_filter_post_query_arguments( $prepared_args, $request ) { - if ( - is_post_type_hierarchical( $prepared_args['post_type'] ) || - 'wp_block' === $prepared_args['post_type'] - ) { - // Avoid triggering 'rest_post_invalid_page_number' error - // which will need to be addressed in https://core.trac.wordpress.org/ticket/43998. - if ( -1 === $prepared_args['posts_per_page'] ) { - $prepared_args['posts_per_page'] = 100000; - } - } - return $prepared_args; -} - -/** - * Include additional query parameters on the terms query endpoint. - * - * @see https://core.trac.wordpress.org/ticket/43998 - * - * @param array $query_params JSON Schema-formatted collection parameters. - * @param object $taxonomy Taxonomy being accessed. - * @return array - */ -function gutenberg_filter_term_collection_parameters( $query_params, $taxonomy ) { - if ( $taxonomy->show_in_rest - && ( false === $taxonomy->rest_controller_class - || 'WP_REST_Terms_Controller' === $taxonomy->rest_controller_class ) - && isset( $query_params['per_page'] ) ) { - // Change from '1' to '-1', which means unlimited. - $query_params['per_page']['minimum'] = -1; - // Default sanitize callback is 'absint', which won't work in our case. - $query_params['per_page']['sanitize_callback'] = 'rest_sanitize_request_arg'; - } - return $query_params; -} - -/** - * Filter term collection query parameters to include specific behavior. - * - * @see https://core.trac.wordpress.org/ticket/43998 - * - * @param array $prepared_args Array of arguments for WP_Term_Query. - * @param WP_REST_Request $request The current request. - * @return array - */ -function gutenberg_filter_term_query_arguments( $prepared_args, $request ) { - // Can't check the actual taxonomy here because it's not - // passed through in $prepared_args (or the filter generally). - if ( 0 === strpos( $request->get_route(), '/wp/v2/' ) ) { - if ( -1 === $prepared_args['number'] ) { - // This should be unset( $prepared_args['number'] ) - // but WP_REST_Terms Controller needs to be updated to support - // unbounded queries. - // Will be addressed in https://core.trac.wordpress.org/ticket/43998. - $prepared_args['number'] = 100000; - } - } - return $prepared_args; -} - -/** - * Include additional query parameters on the user query endpoint. - * - * @see https://core.trac.wordpress.org/ticket/43998 - * - * @param array $query_params JSON Schema-formatted collection parameters. - * @return array - */ -function gutenberg_filter_user_collection_parameters( $query_params ) { - if ( isset( $query_params['per_page'] ) ) { - // Change from '1' to '-1', which means unlimited. - $query_params['per_page']['minimum'] = -1; - // Default sanitize callback is 'absint', which won't work in our case. - $query_params['per_page']['sanitize_callback'] = 'rest_sanitize_request_arg'; - } - return $query_params; -} -add_filter( 'rest_user_collection_params', 'gutenberg_filter_user_collection_parameters' ); /** * Silence PHP Warnings and Errors in JSON requests diff --git a/package-lock.json b/package-lock.json index 1867236d23dc4..179915339a81b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2007,7 +2007,8 @@ "requires": { "@babel/runtime": "^7.0.0", "@wordpress/hooks": "file:packages/hooks", - "@wordpress/i18n": "file:packages/i18n" + "@wordpress/i18n": "file:packages/i18n", + "@wordpress/url": "file:packages/url" } }, "@wordpress/autop": { diff --git a/packages/api-fetch/CHANGELOG.md b/packages/api-fetch/CHANGELOG.md index a49cefcd0d75c..7d53f6aa2222f 100644 --- a/packages/api-fetch/CHANGELOG.md +++ b/packages/api-fetch/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.1.0 (Unreleased) + +- Support `per_page=-1` paginated requests. + ## 2.0.0 (2018-09-05) ### Breaking Change diff --git a/packages/api-fetch/package.json b/packages/api-fetch/package.json index ed66f99b0444e..bf5ed7b10f8f0 100644 --- a/packages/api-fetch/package.json +++ b/packages/api-fetch/package.json @@ -23,7 +23,8 @@ "dependencies": { "@babel/runtime": "^7.0.0", "@wordpress/hooks": "file:../hooks", - "@wordpress/i18n": "file:../i18n" + "@wordpress/i18n": "file:../i18n", + "@wordpress/url": "file:../url" }, "publishConfig": { "access": "public" diff --git a/packages/api-fetch/src/index.js b/packages/api-fetch/src/index.js index a2ebeeff37a9a..b028fef611e4b 100644 --- a/packages/api-fetch/src/index.js +++ b/packages/api-fetch/src/index.js @@ -9,6 +9,7 @@ import { __ } from '@wordpress/i18n'; import createNonceMiddleware from './middlewares/nonce'; import createRootURLMiddleware from './middlewares/root-url'; import createPreloadingMiddleware from './middlewares/preloading'; +import fetchAllMiddleware from './middlewares/fetch-all-middleware'; import namespaceEndpointMiddleware from './middlewares/namespace-endpoint'; import httpV1Middleware from './middlewares/http-v1'; @@ -105,16 +106,19 @@ function apiFetch( options ) { const steps = [ raw, + fetchAllMiddleware, httpV1Middleware, namespaceEndpointMiddleware, ...middlewares, - ]; - const next = ( nextOptions ) => { - const nextMiddleware = steps.pop(); + ].reverse(); + + const runMiddleware = ( index ) => ( nextOptions ) => { + const nextMiddleware = steps[ index ]; + const next = runMiddleware( index + 1 ); return nextMiddleware( nextOptions, next ); }; - return next( options ); + return runMiddleware( 0 )( options ); } apiFetch.use = registerMiddleware; @@ -122,5 +126,6 @@ apiFetch.use = registerMiddleware; apiFetch.createNonceMiddleware = createNonceMiddleware; apiFetch.createPreloadingMiddleware = createPreloadingMiddleware; apiFetch.createRootURLMiddleware = createRootURLMiddleware; +apiFetch.fetchAllMiddleware = fetchAllMiddleware; export default apiFetch; diff --git a/packages/api-fetch/src/middlewares/fetch-all-middleware.js b/packages/api-fetch/src/middlewares/fetch-all-middleware.js new file mode 100644 index 0000000000000..5bc17b5413d32 --- /dev/null +++ b/packages/api-fetch/src/middlewares/fetch-all-middleware.js @@ -0,0 +1,93 @@ +/** + * WordPress dependencies + */ +import { addQueryArgs } from '@wordpress/url'; + +// Apply query arguments to both URL and Path, whichever is present. +const modifyQuery = ( { path, url, ...options }, queryArgs ) => ( { + ...options, + url: url && addQueryArgs( url, queryArgs ), + path: path && addQueryArgs( path, queryArgs ), +} ); + +// Duplicates parsing functionality from apiFetch. +const parseResponse = ( response ) => response.json ? + response.json() : + Promise.reject( response ); + +const parseLinkHeader = ( linkHeader ) => { + if ( ! linkHeader ) { + return {}; + } + const match = linkHeader.match( /<([^>]+)>; rel="next"/ ); + return match ? { + next: match[ 1 ], + } : {}; +}; + +const getNextPageUrl = ( response ) => { + const { next } = parseLinkHeader( response.headers.get( 'link' ) ); + return next; +}; + +const requestContainsUnboundedQuery = ( options ) => { + const pathIsUnbounded = options.path && options.path.indexOf( 'per_page=-1' ) !== -1; + const urlIsUnbounded = options.url && options.url.indexOf( 'per_page=-1' ) !== -1; + return pathIsUnbounded || urlIsUnbounded; +}; + +// The REST API enforces an upper limit on the per_page option. To handle large +// collections, apiFetch consumers can pass `per_page=-1`; this middleware will +// then recursively assemble a full response array from all available pages. +const fetchAllMiddleware = async ( options, next ) => { + if ( options.parse === false ) { + // If a consumer has opted out of parsing, do not apply middleware. + return next( options ); + } + if ( ! requestContainsUnboundedQuery( options ) ) { + // If neither url nor path is requesting all items, do not apply middleware. + return next( options ); + } + + // Retrieve requested page of results. + const response = await next( { + ...modifyQuery( options, { + per_page: 100, + } ), + // Ensure headers are returned for page 1. + parse: false, + } ); + + const results = await parseResponse( response ); + + if ( ! Array.isArray( results ) ) { + // We have no reliable way of merging non-array results. + return results; + } + + let nextPage = getNextPageUrl( response ); + + if ( ! nextPage ) { + // There are no further pages to request. + return results; + } + + // Iteratively fetch all remaining pages until no "next" header is found. + let mergedResults = [].concat( results ); + while ( nextPage ) { + const nextResponse = await next( { + ...options, + // Ensure the URL for the next page is used instead of any provided path. + path: undefined, + url: nextPage, + // Ensure we still get headers so we can identify the next page. + parse: false, + } ); + const nextResults = await parseResponse( nextResponse ); + mergedResults = mergedResults.concat( nextResults ); + nextPage = getNextPageUrl( nextResponse ); + } + return mergedResults; +}; + +export default fetchAllMiddleware; diff --git a/packages/api-fetch/src/middlewares/test/fetch-all-middleware.js b/packages/api-fetch/src/middlewares/test/fetch-all-middleware.js new file mode 100644 index 0000000000000..c002790ead45c --- /dev/null +++ b/packages/api-fetch/src/middlewares/test/fetch-all-middleware.js @@ -0,0 +1,51 @@ +/** + * Internal dependencies + */ +import fetchAllMiddleware from '../fetch-all-middleware'; + +describe( 'Fetch All Middleware', async () => { + it( 'should defer with the same options to the next middleware', async () => { + expect.hasAssertions(); + const originalOptions = { path: '/posts' }; + const next = ( options ) => { + expect( options ).toBe( originalOptions ); + return Promise.resolve( 'ok' ); + }; + + await fetchAllMiddleware( originalOptions, next ); + } ); + + it( 'should paginate the request', async () => { + expect.hasAssertions(); + const originalOptions = { url: '/posts?per_page=-1' }; + let counter = 1; + const next = ( options ) => { + if ( counter === 1 ) { + expect( options.url ).toBe( '/posts?per_page=100' ); + } else { + expect( options.url ).toBe( '/posts?per_page=100&page=2' ); + } + const response = Promise.resolve( { + status: 200, + headers: { + get() { + return options.url === '/posts?per_page=100' ? + '; rel="next"' : + ''; + }, + }, + json() { + return Promise.resolve( [ 'item' ] ); + }, + } ); + + counter++; + + return response; + }; + + const result = await fetchAllMiddleware( originalOptions, next ); + + expect( result ).toEqual( [ 'item', 'item' ] ); + } ); +} ); diff --git a/packages/edit-post/src/hooks/components/media-upload/index.js b/packages/edit-post/src/hooks/components/media-upload/index.js index 72e223ce66bd5..f950d34d628ee 100644 --- a/packages/edit-post/src/hooks/components/media-upload/index.js +++ b/packages/edit-post/src/hooks/components/media-upload/index.js @@ -67,8 +67,8 @@ const getAttachmentsCollection = ( ids ) => { return wp.media.query( { order: 'ASC', orderby: 'post__in', - per_page: -1, post__in: ids, + per_page: 100, query: true, type: 'image', } ); diff --git a/phpunit/class-gutenberg-rest-api-test.php b/phpunit/class-gutenberg-rest-api-test.php index 6dc323d6179bd..293dc7fed3526 100644 --- a/phpunit/class-gutenberg-rest-api-test.php +++ b/phpunit/class-gutenberg-rest-api-test.php @@ -381,17 +381,7 @@ public function test_get_items_unbounded_per_page() { $request = new WP_REST_Request( 'GET', '/wp/v2/users' ); $request->set_param( 'per_page', '-1' ); $response = rest_get_server()->dispatch( $request ); - $this->assertEquals( 200, $response->get_status() ); - } - - public function test_get_items_unbounded_per_page_unauthorized() { - wp_set_current_user( $this->subscriber ); - $request = new WP_REST_Request( 'GET', '/wp/v2/users' ); - $request->set_param( 'per_page', '-1' ); - $response = rest_get_server()->dispatch( $request ); - $this->assertEquals( 403, $response->get_status() ); - $data = $response->get_data(); - $this->assertEquals( 'rest_forbidden_per_page', $data['code'] ); + $this->assertEquals( 400, $response->get_status() ); } public function test_get_categories_unbounded_per_page() { @@ -400,18 +390,7 @@ public function test_get_categories_unbounded_per_page() { $request = new WP_REST_Request( 'GET', '/wp/v2/categories' ); $request->set_param( 'per_page', '-1' ); $response = rest_get_server()->dispatch( $request ); - $this->assertEquals( 200, $response->get_status() ); - } - - public function test_get_categories_unbounded_per_page_unauthorized() { - wp_set_current_user( $this->subscriber ); - $this->factory->category->create(); - $request = new WP_REST_Request( 'GET', '/wp/v2/categories' ); - $request->set_param( 'per_page', '-1' ); - $response = rest_get_server()->dispatch( $request ); - $this->assertEquals( 403, $response->get_status() ); - $data = $response->get_data(); - $this->assertEquals( 'rest_forbidden_per_page', $data['code'] ); + $this->assertEquals( 400, $response->get_status() ); } public function test_get_pages_unbounded_per_page() { @@ -420,18 +399,7 @@ public function test_get_pages_unbounded_per_page() { $request = new WP_REST_Request( 'GET', '/wp/v2/pages' ); $request->set_param( 'per_page', '-1' ); $response = rest_get_server()->dispatch( $request ); - $this->assertEquals( 200, $response->get_status() ); - } - - public function test_get_pages_unbounded_per_page_unauthorized() { - wp_set_current_user( $this->subscriber ); - $this->factory->post->create( array( 'post_type' => 'page' ) ); - $request = new WP_REST_Request( 'GET', '/wp/v2/pages' ); - $request->set_param( 'per_page', '-1' ); - $response = rest_get_server()->dispatch( $request ); - $this->assertEquals( 403, $response->get_status() ); - $data = $response->get_data(); - $this->assertEquals( 'rest_forbidden_per_page', $data['code'] ); + $this->assertEquals( 400, $response->get_status() ); } public function test_get_post_links_predecessor_version() { From 3edce55557aef08d024011429237570b4ef945f5 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 22 Oct 2018 12:57:15 +0100 Subject: [PATCH 049/121] Update plugin version to 4.1 RC2. (#10893) --- gutenberg.php | 2 +- package-lock.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gutenberg.php b/gutenberg.php index fdc1cf2ab1767..e285a33310e81 100644 --- a/gutenberg.php +++ b/gutenberg.php @@ -3,7 +3,7 @@ * Plugin Name: Gutenberg * Plugin URI: https://github.com/WordPress/gutenberg * Description: Printing since 1440. This is the development plugin for the new block editor in core. - * Version: 4.1.0-rc.1 + * Version: 4.1.0-rc.2 * Author: Gutenberg Team * * @package gutenberg diff --git a/package-lock.json b/package-lock.json index 179915339a81b..31155db7a32f1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "4.1.0-rc.1", + "version": "4.1.0-rc.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 7368a6e70f24c..333b9e3c2b3a2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "4.1.0-rc.1", + "version": "4.1.0-rc.2", "private": true, "description": "A new WordPress editor experience", "repository": "git+https://github.com/WordPress/gutenberg.git", From 08476d7fc1533357dca48ad8fb185cd76096c41d Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Mon, 22 Oct 2018 14:31:52 +0200 Subject: [PATCH 050/121] chore(release): publish - @wordpress/api-fetch@2.1.0 - @wordpress/block-library@2.1.4 - @wordpress/components@4.2.1 - @wordpress/core-data@2.0.6 - @wordpress/edit-post@1.0.4 - @wordpress/editor@5.0.1 - @wordpress/list-reusable-blocks@1.1.4 - @wordpress/nux@2.0.6 --- packages/api-fetch/package.json | 2 +- packages/block-library/package.json | 2 +- packages/components/package.json | 2 +- packages/core-data/package.json | 2 +- packages/edit-post/package.json | 2 +- packages/editor/package.json | 2 +- packages/list-reusable-blocks/package.json | 2 +- packages/nux/package.json | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/api-fetch/package.json b/packages/api-fetch/package.json index bf5ed7b10f8f0..b4982c12e4f40 100644 --- a/packages/api-fetch/package.json +++ b/packages/api-fetch/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/api-fetch", - "version": "2.0.2", + "version": "2.1.0", "description": "Utility to make WordPress REST API requests.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-library/package.json b/packages/block-library/package.json index 01308b546811a..5136152d21551 100644 --- a/packages/block-library/package.json +++ b/packages/block-library/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-library", - "version": "2.1.3", + "version": "2.1.4", "description": "Block library for the WordPress editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/components/package.json b/packages/components/package.json index 6494611c19583..881d5b7b335e8 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/components", - "version": "4.2.0", + "version": "4.2.1", "description": "UI components for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/core-data/package.json b/packages/core-data/package.json index a829391c5bce3..2bdcb67dd005a 100644 --- a/packages/core-data/package.json +++ b/packages/core-data/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/core-data", - "version": "2.0.5", + "version": "2.0.6", "description": "Access to and manipulation of core WordPress entities.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/edit-post/package.json b/packages/edit-post/package.json index 24efc07ffab98..0b5bd5d6d68f8 100644 --- a/packages/edit-post/package.json +++ b/packages/edit-post/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/edit-post", - "version": "1.0.3", + "version": "1.0.4", "description": "Edit Post module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/editor/package.json b/packages/editor/package.json index db733a7e241f7..17ee77c6683f4 100644 --- a/packages/editor/package.json +++ b/packages/editor/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/editor", - "version": "5.0.0", + "version": "5.0.1", "description": "Building blocks for WordPress editors.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/list-reusable-blocks/package.json b/packages/list-reusable-blocks/package.json index 983d41d36e116..3249cbef1c7d7 100644 --- a/packages/list-reusable-blocks/package.json +++ b/packages/list-reusable-blocks/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/list-reusable-blocks", - "version": "1.1.3", + "version": "1.1.4", "description": "Adding Export/Import support to the reusable blocks listing.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/nux/package.json b/packages/nux/package.json index 44d6b23e156cb..6077e082a7b77 100644 --- a/packages/nux/package.json +++ b/packages/nux/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/nux", - "version": "2.0.5", + "version": "2.0.6", "description": "NUX (New User eXperience) module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", From 1cd604df7e9017e0dbe3ab64897ac3af35ca35c5 Mon Sep 17 00:00:00 2001 From: Gary Pendergast Date: Mon, 22 Oct 2018 23:35:17 +1100 Subject: [PATCH 051/121] Update Package Changelogs (#10887) * Update package changelogs * Bump the changelog date, because it's now Monday for everybody. --- packages/api-fetch/CHANGELOG.md | 2 +- packages/block-library/CHANGELOG.md | 6 ++++++ packages/components/CHANGELOG.md | 2 +- packages/core-data/CHANGELOG.md | 2 ++ packages/edit-post/CHANGELOG.md | 2 +- packages/editor/CHANGELOG.md | 2 ++ packages/list-reusable-blocks/CHANGELOG.md | 2 ++ packages/nux/CHANGELOG.md | 2 ++ 8 files changed, 17 insertions(+), 3 deletions(-) diff --git a/packages/api-fetch/CHANGELOG.md b/packages/api-fetch/CHANGELOG.md index 7d53f6aa2222f..e253b64d5bf19 100644 --- a/packages/api-fetch/CHANGELOG.md +++ b/packages/api-fetch/CHANGELOG.md @@ -1,4 +1,4 @@ -## 2.1.0 (Unreleased) +## 2.1.0 (2018-10-22) - Support `per_page=-1` paginated requests. diff --git a/packages/block-library/CHANGELOG.md b/packages/block-library/CHANGELOG.md index 6fe1fd0ef7ce1..a28fed6c42a21 100644 --- a/packages/block-library/CHANGELOG.md +++ b/packages/block-library/CHANGELOG.md @@ -1,3 +1,9 @@ +## 2.1.4 (2018-10-22) + +### Bug Fixes + +- Video Block: Set correct media types for the poster image. + ## 2.1.3 (2018-10-19) ## 2.1.2 (2018-10-18) diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index bf670914795e0..1eef1646bf3a0 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -1,4 +1,4 @@ -## 4.2.1 (Unreleased) +## 4.2.1 (2018-10-22) ### Bug Fix diff --git a/packages/core-data/CHANGELOG.md b/packages/core-data/CHANGELOG.md index 30bfdf415a54a..efb7fe6c22c47 100644 --- a/packages/core-data/CHANGELOG.md +++ b/packages/core-data/CHANGELOG.md @@ -1,3 +1,5 @@ +## 2.0.6 (2018-10-22) + ## 2.0.5 (2018-10-19) ## 2.0.4 (2018-10-18) diff --git a/packages/edit-post/CHANGELOG.md b/packages/edit-post/CHANGELOG.md index 2db3d57d70ba1..7cecf41a7060a 100644 --- a/packages/edit-post/CHANGELOG.md +++ b/packages/edit-post/CHANGELOG.md @@ -1,4 +1,4 @@ -## 1.0.4 (Unreleased) +## 1.0.4 (2018-10-22) ## Bug Fixes diff --git a/packages/editor/CHANGELOG.md b/packages/editor/CHANGELOG.md index 691851a6bf4ef..3f7d1d3b46697 100644 --- a/packages/editor/CHANGELOG.md +++ b/packages/editor/CHANGELOG.md @@ -1,3 +1,5 @@ +## 5.0.1 (2018-10-22) + ## 5.0.0 (2018-10-19) ### Breaking Changes diff --git a/packages/list-reusable-blocks/CHANGELOG.md b/packages/list-reusable-blocks/CHANGELOG.md index 7e54897866ced..6234aa478b9ab 100644 --- a/packages/list-reusable-blocks/CHANGELOG.md +++ b/packages/list-reusable-blocks/CHANGELOG.md @@ -1,3 +1,5 @@ +## 1.1.4 (2018-10-22) + ## 1.1.3 (2018-10-19) ## 1.1.2 (2018-10-18) diff --git a/packages/nux/CHANGELOG.md b/packages/nux/CHANGELOG.md index 9b4bad0bd4aa5..393798e3eece1 100644 --- a/packages/nux/CHANGELOG.md +++ b/packages/nux/CHANGELOG.md @@ -1,3 +1,5 @@ +## 2.0.6 (2018-10-22) + ## 2.0.5 (2018-10-19) ## 2.0.4 (2018-10-18) From 80e782c8bfae780137f0ac4d69ddf2302aed2930 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Tue, 23 Oct 2018 02:07:06 -0400 Subject: [PATCH 052/121] Components: Avoid SlotFill props destructuring (#10921) --- packages/components/src/slot-fill/index.js | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/packages/components/src/slot-fill/index.js b/packages/components/src/slot-fill/index.js index c14f7adafc879..bec51806039a6 100644 --- a/packages/components/src/slot-fill/index.js +++ b/packages/components/src/slot-fill/index.js @@ -10,18 +10,10 @@ export { Fill }; export { Provider }; export function createSlotFill( name ) { - const FillComponent = ( { children, ...props } ) => ( - - { children } - - ); + const FillComponent = ( props ) => ; FillComponent.displayName = name + 'Fill'; - const SlotComponent = ( { children, ...props } ) => ( - - { children } - - ); + const SlotComponent = ( props ) => ; SlotComponent.displayName = name + 'Slot'; return { From 898f2f7aa67939140b0c89c70fbb8dde6f5be1e2 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Tue, 23 Oct 2018 08:12:49 +0200 Subject: [PATCH 053/121] Add some new url helper functions (#10885) * Add some new url helper functions See #10879. * Document new functions in readme * Improve docs * Add another test for removeQueryArgs() --- packages/url/CHANGELOG.md | 8 ++++ packages/url/README.md | 9 +++++ packages/url/src/index.js | 51 +++++++++++++++++++++-- packages/url/src/test/index.test.js | 63 +++++++++++++++++++++++++++++ 4 files changed, 128 insertions(+), 3 deletions(-) diff --git a/packages/url/CHANGELOG.md b/packages/url/CHANGELOG.md index e0f2f033c4af9..0b1dfb761ff72 100644 --- a/packages/url/CHANGELOG.md +++ b/packages/url/CHANGELOG.md @@ -1,3 +1,11 @@ +## 2.2.0 (Unreleased) + +### Features + +- Added `getQueryArg`. +- Added `hasQueryArg`. +- Added `removeQueryArgs`. + ## 2.1.0 (2018-10-16) ### Features diff --git a/packages/url/README.md b/packages/url/README.md index 6c15661232755..26f54fbaff57f 100644 --- a/packages/url/README.md +++ b/packages/url/README.md @@ -25,6 +25,15 @@ const newURL = addQueryArgs( 'https://google.com', { q: 'test' } ); // https:// // Prepends 'http://' to URLs that are probably mean to have them const actualURL = prependHTTP( 'wordpress.org' ); // http://wordpress.org + +// Gets a single query arg from the given URL. +const foo = getQueryArg( 'https://wordpress.org?foo=bar&bar=baz', 'foo' ); // bar + +// Checks whether a URL contains a given query arg. +const hasBar = hasQueryArg( 'https://wordpress.org?foo=bar&bar=baz', 'bar' ); // true + +// Removes one or more query args from the given URL. +const newUrl = removeQueryArgs( 'https://wordpress.org?foo=bar&bar=baz&baz=foobar', 'foo', 'bar' ); // https://wordpress.org?baz=foobar ```

    Code is Poetry.

    diff --git a/packages/url/src/index.js b/packages/url/src/index.js index 4538ee2040bbc..98cd123cfc666 100644 --- a/packages/url/src/index.js +++ b/packages/url/src/index.js @@ -21,10 +21,10 @@ export function isURL( url ) { /** * Appends arguments to the query string of the url * - * @param {string} url URL - * @param {Object} args Query Args + * @param {string} url URL + * @param {Object} args Query Args * - * @return {string} Updated URL + * @return {string} Updated URL */ export function addQueryArgs( url, args ) { const queryStringIndex = url.indexOf( '?' ); @@ -34,6 +34,51 @@ export function addQueryArgs( url, args ) { return baseUrl + '?' + stringify( { ...query, ...args } ); } +/** + * Returns a single query argument of the url + * + * @param {string} url URL + * @param {string} arg Query arg name + * + * @return {Array|string} Query arg value. + */ +export function getQueryArg( url, arg ) { + const queryStringIndex = url.indexOf( '?' ); + const query = queryStringIndex !== -1 ? parse( url.substr( queryStringIndex + 1 ) ) : {}; + + return query[ arg ]; +} + +/** + * Determines whether the URL contains a given query arg. + * + * @param {string} url URL + * @param {string} arg Query arg name + * + * @return {boolean} Whether or not the URL contains the query aeg. + */ +export function hasQueryArg( url, arg ) { + return getQueryArg( url, arg ) !== undefined; +} + +/** + * Removes arguments from the query string of the url + * + * @param {string} url URL + * @param {...string} args Query Args + * + * @return {string} Updated URL + */ +export function removeQueryArgs( url, ...args ) { + const queryStringIndex = url.indexOf( '?' ); + const query = queryStringIndex !== -1 ? parse( url.substr( queryStringIndex + 1 ) ) : {}; + const baseUrl = queryStringIndex !== -1 ? url.substr( 0, queryStringIndex ) : url; + + args.forEach( ( arg ) => delete query[ arg ] ); + + return baseUrl + '?' + stringify( query ); +} + /** * Prepends "http://" to a url, if it looks like something that is meant to be a TLD. * diff --git a/packages/url/src/test/index.test.js b/packages/url/src/test/index.test.js index 7815a1cae68ed..46548528f3bc1 100644 --- a/packages/url/src/test/index.test.js +++ b/packages/url/src/test/index.test.js @@ -9,6 +9,9 @@ import { every } from 'lodash'; import { isURL, addQueryArgs, + getQueryArg, + hasQueryArg, + removeQueryArgs, prependHTTP, safeDecodeURI, } from '../'; @@ -69,6 +72,66 @@ describe( 'addQueryArgs', () => { } ); } ); +describe( 'getQueryArg', () => { + it( 'should get the value of an existing query arg', () => { + const url = 'https://andalouses.example/beach?foo=bar&bar=baz'; + + expect( getQueryArg( url, 'foo' ) ).toBe( 'bar' ); + } ); + + it( 'should not return a value of an unknown query arg', () => { + const url = 'https://andalouses.example/beach?foo=bar&bar=baz'; + + expect( getQueryArg( url, 'baz' ) ).toBeUndefined(); + } ); + + it( 'should get the value of an arry query arg', () => { + const url = 'https://andalouses.example/beach?foo[]=bar&foo[]=baz'; + + expect( getQueryArg( url, 'foo' ) ).toEqual( [ 'bar', 'baz' ] ); + } ); +} ); + +describe( 'hasQueryArg', () => { + it( 'should return true for an existing query arg', () => { + const url = 'https://andalouses.example/beach?foo=bar&bar=baz'; + + expect( hasQueryArg( url, 'foo' ) ).toBeTruthy(); + } ); + + it( 'should return false for an unknown query arg', () => { + const url = 'https://andalouses.example/beach?foo=bar&bar=baz'; + + expect( hasQueryArg( url, 'baz' ) ).toBeFalsy(); + } ); + + it( 'should return true for an arry query arg', () => { + const url = 'https://andalouses.example/beach?foo[]=bar&foo[]=baz'; + + expect( hasQueryArg( url, 'foo' ) ).toBeTruthy(); + } ); +} ); + +describe( 'removeQueryArgs', () => { + it( 'should not change URL not containing query args', () => { + const url = 'https://andalouses.example/beach?foo=bar&bar=baz'; + + expect( removeQueryArgs( url, 'baz', 'test' ) ).toEqual( url ); + } ); + + it( 'should remove existing query args', () => { + const url = 'https://andalouses.example/beach?foo=bar&baz=foo&bar=baz'; + + expect( removeQueryArgs( url, 'foo', 'bar' ) ).toEqual( 'https://andalouses.example/beach?baz=foo' ); + } ); + + it( 'should remove array query arg', () => { + const url = 'https://andalouses.example/beach?foo[]=bar&foo[]=baz&bar=foobar'; + + expect( removeQueryArgs( url, 'foo' ) ).toEqual( 'https://andalouses.example/beach?bar=foobar' ); + } ); +} ); + describe( 'prependHTTP', () => { it( 'should prepend http to a domain', () => { const url = 'wordpress.org'; From 2da4f0ce224ca6193f40be5939e4d129d00cc447 Mon Sep 17 00:00:00 2001 From: Danilo Ercoli Date: Tue, 23 Oct 2018 08:52:39 +0200 Subject: [PATCH 054/121] Remove the root tags returned by Aztec by using the correct tag reference (#10797) --- .../src/components/rich-text/index.native.js | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/packages/editor/src/components/rich-text/index.native.js b/packages/editor/src/components/rich-text/index.native.js index 48a0ec86b1634..7ec958136f8f5 100644 --- a/packages/editor/src/components/rich-text/index.native.js +++ b/packages/editor/src/components/rich-text/index.native.js @@ -114,9 +114,8 @@ export class RichText extends Component { valueToFormat( { formats, text } ) { const value = toHTMLString( { formats, text }, this.multilineTag ); - // remove the outer p tags - const returningContentWithoutParaTag = value.replace( /

    |<\/p>/gi, '' ); - return returningContentWithoutParaTag; + // remove the outer root tags + return this.removeRootTagsProduceByAztec( value ); } onActiveFormatsChange( formats ) { @@ -133,6 +132,18 @@ export class RichText extends Component { selectedNodeId: this.state.selectedNodeId + 1, } ); } + + /* + * Cleans up any root tags produced by aztec. + * TODO: This should be removed on a later version when aztec doesn't return the top tag of the text being edited + */ + + removeRootTagsProduceByAztec( html ) { + const openingTagRegexp = RegExp( '^<' + this.props.tagName + '>', 'gim' ); + const closingTagRegexp = RegExp( '$', 'gim' ); + return html.replace( openingTagRegexp, '' ).replace( closingTagRegexp, '' ); + } + /** * Handles any case where the content of the AztecRN instance has changed. */ @@ -143,11 +154,7 @@ export class RichText extends Component { clearTimeout( this.currentTimer ); } this.lastEventCount = event.nativeEvent.eventCount; - // The following method just cleans up any root tags produced by aztec and replaces them with a br tag - // This should be removed on a later version when aztec doesn't return the top tag of the text being edited - const openingTagRegexp = RegExp( '^<' + this.props.tagName + '>', 'gim' ); - const closingTagRegexp = RegExp( '$', 'gim' ); - const contentWithoutRootTag = event.nativeEvent.text.replace( openingTagRegexp, '' ).replace( closingTagRegexp, '' ); + const contentWithoutRootTag = this.removeRootTagsProduceByAztec( event.nativeEvent.text ); this.lastContent = contentWithoutRootTag; // Set a time to call the onChange prop if nothing changes in the next second this.currentTimer = setTimeout( function() { From 61798e98fb37dfd7ee1ef5edab3c29f0fe0d8e1a Mon Sep 17 00:00:00 2001 From: Ben Lowery Date: Tue, 23 Oct 2018 03:11:05 -0400 Subject: [PATCH 055/121] Update react-click-outside to 3.0 (#10748) * Update react-click-outside to 3.0 * update package-lock --- package-lock.json | 22 ++++++++++++---------- packages/components/package.json | 2 +- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index 31155db7a32f1..8a6d80fac0540 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2142,7 +2142,7 @@ "moment": "^2.22.1", "mousetrap": "^1.6.2", "re-resizable": "^4.7.1", - "react-click-outside": "^2.3.1", + "react-click-outside": "^3.0.0", "react-dates": "^17.1.1", "rememo": "^3.0.0", "tinycolor2": "^1.4.1", @@ -9820,11 +9820,6 @@ "minimalistic-crypto-utils": "^1.0.1" } }, - "hoist-non-react-statics": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz", - "integrity": "sha1-qkSM8JhtVcxAdzsXF0t90GbLfPs=" - }, "home-or-tmp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", @@ -17102,11 +17097,18 @@ } }, "react-click-outside": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/react-click-outside/-/react-click-outside-2.3.1.tgz", - "integrity": "sha1-MYc3698IGko7zUaCVmNnTL6YNus=", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/react-click-outside/-/react-click-outside-3.0.1.tgz", + "integrity": "sha512-d0KWFvBt+esoZUF15rL2UBB7jkeAqLU8L/Ny35oLK6fW6mIbOv/ChD+ExF4sR9PD26kVx+9hNfD0FTIqRZEyRQ==", "requires": { - "hoist-non-react-statics": "^1.2.0" + "hoist-non-react-statics": "^2.1.1" + }, + "dependencies": { + "hoist-non-react-statics": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz", + "integrity": "sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw==" + } } }, "react-dates": { diff --git a/packages/components/package.json b/packages/components/package.json index 881d5b7b335e8..0ad6b90441d9e 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -41,7 +41,7 @@ "moment": "^2.22.1", "mousetrap": "^1.6.2", "re-resizable": "^4.7.1", - "react-click-outside": "^2.3.1", + "react-click-outside": "^3.0.0", "react-dates": "^17.1.1", "rememo": "^3.0.0", "tinycolor2": "^1.4.1", From 74214c0757f645e287ad6d48016697383733e7eb Mon Sep 17 00:00:00 2001 From: Jorge Date: Tue, 23 Oct 2018 10:17:30 +0100 Subject: [PATCH 056/121] Fix: Show resizer on "Media & Text" block on unified toolbar mode (#10913) ## Description Fixes: https://github.com/WordPress/gutenberg/issues/10895 On unified toolbar mode, it was not possible to resize the media on Media & Text block. During the elaboration of https://github.com/WordPress/gutenberg/pull/9416 this bug was addressed but I think during subsequent rebases and changes more concretely the usage of our abstracted Resizable box we had a regression. This PR applies exactly the same fix that was applied in spacer block to the Media & Text block. ## How has this been tested? I checked it is possible to resize the media in Media & Text block in all modes including the unified toolbar. --- packages/block-library/src/media-text/edit.js | 2 ++ packages/block-library/src/media-text/editor.scss | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/media-text/edit.js b/packages/block-library/src/media-text/edit.js index 7570b2cc7b053..8187d51c7e4b8 100644 --- a/packages/block-library/src/media-text/edit.js +++ b/packages/block-library/src/media-text/edit.js @@ -104,6 +104,7 @@ class MediaTextEdit extends Component { attributes, className, backgroundColor, + isSelected, setAttributes, setBackgroundColor, } = this.props; @@ -111,6 +112,7 @@ class MediaTextEdit extends Component { const temporaryMediaWidth = this.state.mediaWidth; const classNames = classnames( className, { 'has-media-on-the-right': 'right' === mediaPosition, + 'is-selected': isSelected, [ backgroundColor.class ]: backgroundColor.class, } ); const widthString = `${ temporaryMediaWidth || mediaWidth }%`; diff --git a/packages/block-library/src/media-text/editor.scss b/packages/block-library/src/media-text/editor.scss index b0eccc5aace15..41c38c97758da 100644 --- a/packages/block-library/src/media-text/editor.scss +++ b/packages/block-library/src/media-text/editor.scss @@ -51,8 +51,7 @@ figure.block-library-media-text__media-container { display: none; } -.editor-block-list__block.is-selected, -.editor-block-list__block.is-focused { +.wp-block-media-text.is-selected { .editor-media-container__resizer .components-resizable-box__handle { display: block; } From 68b454c43ad73da04d01173a4b64fe25c09d68fd Mon Sep 17 00:00:00 2001 From: Joen Asmussen Date: Tue, 23 Oct 2018 11:19:58 +0200 Subject: [PATCH 057/121] Try WordPress logo animation for preview (#10896) * Try WordPress logo animation for preview This adds a WordPress logo that paints itself when you click preview. Labelled "Try" because it still needs a few thoughts. We might need to speed up the animation because most previews are super fast and you barely see the animation. * Clean up CSS, add vendor prefixes * Tweak the changelog --- packages/editor/CHANGELOG.md | 6 ++- .../components/post-preview-button/index.js | 42 ++++++++++++++++++- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/packages/editor/CHANGELOG.md b/packages/editor/CHANGELOG.md index 3f7d1d3b46697..a57ac48e8f0f9 100644 --- a/packages/editor/CHANGELOG.md +++ b/packages/editor/CHANGELOG.md @@ -1,5 +1,9 @@ ## 5.0.1 (2018-10-22) +### Polish + +- Add animated logo to preview interstitial screen. + ## 5.0.0 (2018-10-19) ### Breaking Changes @@ -52,7 +56,7 @@ - `isFetchingSharedBlock` selector has been removed. Use `isFetchingReusableBlock` instead. - `getSharedBlocks` selector has been removed. Use `getReusableBlocks` instead. - `editorMediaUpload` has been removed. Use `mediaUpload` instead. -- Change how required built-ins are polyfilled with Babel 7 ([#9171](https://github.com/WordPress/gutenberg/pull/9171)). If you're using an environment that has limited or no support for ES2015+ such as lower versions of IE then using [core-js](https://github.com/zloirock/core-js) or [@babel/polyfill](https://babeljs.io/docs/en/next/babel-polyfill) will add support for these methods. +- Change how required built-ins are polyfilled with Babel 7 ([#9171](https://github.com/WordPress/gutenberg/pull/9171)). If you're using an environment that has limited or no support for ES2015+ such as lower versions of IE then using [core-js](https://github.com/zloirock/core-js) or [@babel/polyfill](https://babeljs.io/docs/en/next/babel-polyfill) will add support for these methods. - `wp.editor.DocumentTitle` component has been removed. - `getDocumentTitle` selector (`core/editor`) has been removed. diff --git a/packages/editor/src/components/post-preview-button/index.js b/packages/editor/src/components/post-preview-button/index.js index 1a2494dca98f9..6d4f594195114 100644 --- a/packages/editor/src/components/post-preview-button/index.js +++ b/packages/editor/src/components/post-preview-button/index.js @@ -90,8 +90,11 @@ export class PostPreviewButton extends Component { const markup = `

    -

    Please wait…

    -

    Generating preview.

    + + + + +

    Generating preview...